From c2e82d8299730662de5f3a109228b4bed29871cf Mon Sep 17 00:00:00 2001 From: Ahmet Kilinc Date: Sat, 20 Dec 2025 03:55:43 +0000 Subject: [PATCH] fix? --- app/api/git/[...path]/route.ts | 51 +++++++++++++++++----------------- bun.lock | 1 + package.json | 1 + 3 files changed, 27 insertions(+), 26 deletions(-) diff --git a/app/api/git/[...path]/route.ts b/app/api/git/[...path]/route.ts index ad2c25a..111e7e4 100644 --- a/app/api/git/[...path]/route.ts +++ b/app/api/git/[...path]/route.ts @@ -4,36 +4,35 @@ import { users, repositories, accounts } from "@/db/schema"; import { eq, and } from "drizzle-orm"; import git from "isomorphic-git"; import { createR2Fs, getRepoPrefix } from "@/lib/r2-fs"; -import { scrypt, timingSafeEqual } from "crypto"; +import { scryptAsync } from "@noble/hashes/scrypt.js"; +import { hexToBytes } from "@noble/hashes/utils.js"; + +function constantTimeEqual(a: Uint8Array, b: Uint8Array): boolean { + if (a.length !== b.length) return false; + let result = 0; + for (let i = 0; i < a.length; i++) { + result |= a[i] ^ b[i]; + } + return result === 0; +} async function verifyPassword(password: string, hash: string): Promise { - return new Promise((resolve) => { - try { - const [, params, salt, key] = hash.split("$"); - if (!params || !salt || !key) { - resolve(false); - return; - } + try { + const [salt, key] = hash.split(":"); + if (!salt || !key) return false; - const paramsObj: Record = {}; - params.split(",").forEach((p) => { - const [k, v] = p.split("="); - paramsObj[k] = parseInt(v, 10); - }); + const derivedKey = await scryptAsync(password.normalize("NFKC"), salt, { + N: 16384, + r: 16, + p: 1, + dkLen: 64, + }); - const keyBuffer = Buffer.from(key, "base64"); - - scrypt(password, salt, keyBuffer.length, { N: paramsObj.n || 16384, r: paramsObj.r || 8, p: paramsObj.p || 1 }, (err, derivedKey) => { - if (err) { - resolve(false); - return; - } - resolve(timingSafeEqual(keyBuffer, derivedKey)); - }); - } catch { - resolve(false); - } - }); + return constantTimeEqual(derivedKey, hexToBytes(key)); + } catch (err) { + console.error("[Git Auth] Password verify error:", err); + return false; + } } async function authenticateUser(authHeader: string | null): Promise<{ id: string; username: string } | null> { diff --git a/bun.lock b/bun.lock index f84fc7c..8fe45c6 100644 --- a/bun.lock +++ b/bun.lock @@ -7,6 +7,7 @@ "dependencies": { "@aws-sdk/client-s3": "^3.956.0", "@hookform/resolvers": "^5.2.2", + "@noble/hashes": "^2.0.1", "@radix-ui/react-avatar": "^1.1.11", "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-dropdown-menu": "^2.1.16", diff --git a/package.json b/package.json index 28efe72..216fe13 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "dependencies": { "@aws-sdk/client-s3": "^3.956.0", "@hookform/resolvers": "^5.2.2", + "@noble/hashes": "^2.0.1", "@radix-ui/react-avatar": "^1.1.11", "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-dropdown-menu": "^2.1.16",