From 0f8797504066dc7697cdf66d5424139f78713bdf Mon Sep 17 00:00:00 2001 From: static Date: Tue, 31 Dec 2024 05:00:03 +0900 Subject: [PATCH] =?UTF-8?q?Token=20Refresh/Upgrade=EC=99=80=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=EB=90=9C=20DB=20=EC=A0=9C=EC=95=BD=20=EC=9C=84?= =?UTF-8?q?=EB=B0=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/lib/modules/crypto.ts | 16 ++++++- src/lib/server/db/token.ts | 48 +++++++++++-------- .../(fullscreen)/key/generate/service.ts | 7 +-- 3 files changed, 48 insertions(+), 23 deletions(-) diff --git a/src/lib/modules/crypto.ts b/src/lib/modules/crypto.ts index a5ed99b..b188ca8 100644 --- a/src/lib/modules/crypto.ts +++ b/src/lib/modules/crypto.ts @@ -36,7 +36,7 @@ export const generateRSASigKeyPair = async () => { return keyPair; }; -export const makeRSAKeyNonextractable = async (key: CryptoKey, type: RSAKeyType) => { +export const makeRSAEncKeyNonextractable = async (key: CryptoKey, type: RSAKeyType) => { const { format, key: exportedKey } = await exportRSAKey(key, type); return await window.crypto.subtle.importKey( format, @@ -50,6 +50,20 @@ export const makeRSAKeyNonextractable = async (key: CryptoKey, type: RSAKeyType) ); }; +export const makeRSASigKeyNonextractable = async (key: CryptoKey, type: RSAKeyType) => { + const { format, key: exportedKey } = await exportRSAKey(key, type); + return await window.crypto.subtle.importKey( + format, + exportedKey, + { + name: "RSA-PSS", + hash: "SHA-256", + } satisfies RsaHashedImportParams, + false, + [type === "public" ? "verify" : "sign"], + ); +}; + const exportRSAKey = async (key: CryptoKey, type: RSAKeyType) => { const format = type === "public" ? ("spki" as const) : ("pkcs8" as const); return { diff --git a/src/lib/server/db/token.ts b/src/lib/server/db/token.ts index d93527f..61545e4 100644 --- a/src/lib/server/db/token.ts +++ b/src/lib/server/db/token.ts @@ -38,15 +38,20 @@ export const getRefreshToken = async (tokenId: string) => { }; export const rotateRefreshToken = async (oldTokenId: string, newTokenId: string) => { - const res = await db - .update(refreshToken) - .set({ - id: newTokenId, - expiresAt: expiresAt(), - }) - .where(eq(refreshToken.id, oldTokenId)) - .execute(); - return res.changes > 0; + return await db.transaction(async (tx) => { + await tx + .delete(tokenUpgradeChallenge) + .where(eq(tokenUpgradeChallenge.refreshTokenId, oldTokenId)); + const res = await db + .update(refreshToken) + .set({ + id: newTokenId, + expiresAt: expiresAt(), + }) + .where(eq(refreshToken.id, oldTokenId)) + .execute(); + return res.changes > 0; + }); }; export const upgradeRefreshToken = async ( @@ -54,16 +59,21 @@ export const upgradeRefreshToken = async ( newTokenId: string, clientId: number, ) => { - const res = await db - .update(refreshToken) - .set({ - id: newTokenId, - clientId, - expiresAt: expiresAt(), - }) - .where(eq(refreshToken.id, oldTokenId)) - .execute(); - return res.changes > 0; + return await db.transaction(async (tx) => { + await tx + .delete(tokenUpgradeChallenge) + .where(eq(tokenUpgradeChallenge.refreshTokenId, oldTokenId)); + const res = await tx + .update(refreshToken) + .set({ + id: newTokenId, + clientId, + expiresAt: expiresAt(), + }) + .where(eq(refreshToken.id, oldTokenId)) + .execute(); + return res.changes > 0; + }); }; export const revokeRefreshToken = async (tokenId: string) => { diff --git a/src/routes/(fullscreen)/key/generate/service.ts b/src/routes/(fullscreen)/key/generate/service.ts index c5aacf7..438a861 100644 --- a/src/routes/(fullscreen)/key/generate/service.ts +++ b/src/routes/(fullscreen)/key/generate/service.ts @@ -1,7 +1,8 @@ import { generateRSAEncKeyPair, generateRSASigKeyPair, - makeRSAKeyNonextractable, + makeRSAEncKeyNonextractable, + makeRSASigKeyNonextractable, exportRSAKeyToBase64, generateAESKey, makeAESKeyNonextractable, @@ -16,11 +17,11 @@ export const generateKeyPairs = async () => { keyPairsStore.set({ encKeyPair: { publicKey: encKeyPair.publicKey, - privateKey: await makeRSAKeyNonextractable(encKeyPair.privateKey, "private"), + privateKey: await makeRSAEncKeyNonextractable(encKeyPair.privateKey, "private"), }, sigKeyPair: { publicKey: sigKeyPair.publicKey, - privateKey: await makeRSAKeyNonextractable(sigKeyPair.privateKey, "private"), + privateKey: await makeRSASigKeyNonextractable(sigKeyPair.privateKey, "private"), }, });