리다이렉트 경로 처리, 파일 정보 변환, 상태 표시 UI 등 중복된 코드를 통합하고 모듈 간 순환 의존성 및 계층 위반 해소

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
staticandClaude Opus 5.5 committed 2026-10-12 08:51:07 +09:00
1 parent 9119c21881
commit 5b8621e524
96 files changed
+452 -548

No files matched your search

+10 -15
View File
@@ -1,8 +1,8 @@
import argon2 from "argon2";
import { ClientRepo, IntegrityError, SessionRepo, UserRepo } from "#lib/server/db/index.ts";
import { ClientRepo, SessionRepo, UserRepo } from "#lib/server/db/index.ts";
import env from "#lib/server/config.ts";
import { issueSessionId } from "#lib/server/crypto.ts";
import { AppError } from "#lib/server/errors.ts";
import { AppError, invalidSessionError } from "#lib/server/errors.ts";
import { createChallenge, verifyChallengeAnswer } from "./client.ts";
const MIN_PASSWORD_LENGTH = 8;
@@ -36,7 +36,7 @@ export const changePassword = async (
const user = await UserRepo.getUser(userId);
if (!user) {
throw new AppError("INTERNAL_SERVER_ERROR", "Invalid session id");
throw invalidSessionError();
} else if (!(await argon2.verify(user.password, oldPassword))) {
throw new AppError("FORBIDDEN", "Invalid password");
}
@@ -83,17 +83,12 @@ export const verifySessionUpgrade = async (
) => {
const challenge = await SessionRepo.consumeSessionUpgradeChallenge(challengeId, sessionId, ip);
const client = await verifyChallengeAnswer(challenge, answerSig);
await SessionRepo.upgradeSession(userId, sessionId, client.id, force);
};
try {
await SessionRepo.upgradeSession(userId, sessionId, client.id, force);
} catch (e) {
if (e instanceof IntegrityError) {
if (e.message === "Session not found") {
throw new AppError("INTERNAL_SERVER_ERROR", "Invalid challenge answer");
} else if (e.message === "Session already exists") {
throw new AppError("CONFLICT", "Already logged in");
}
}
throw e;
}
export const cleanupExpiredSessions = async () => {
await Promise.all([
SessionRepo.cleanupExpiredSessions(),
SessionRepo.cleanupExpiredSessionUpgradeChallenges(),
]);
};
+4
View File
@@ -74,3 +74,7 @@ export const verifyClient = async (
const client = await verifyChallengeAnswer(challenge, answerSig);
await ClientRepo.setUserClientStateToPending(userId, client.id);
};
export const cleanupExpiredChallenges = async () => {
await ClientRepo.cleanupExpiredUserClientChallenges();
};
+4 -3
View File
@@ -1,6 +1,7 @@
import { ClientRepo, HskRepo, MekRepo } from "#lib/server/db/index.ts";
import { verifySignature } from "#lib/server/crypto.ts";
import { AppError } from "#lib/server/errors.ts";
import { AppError, invalidSessionError } from "#lib/server/errors.ts";
import { serializeMasterKeyWrapped } from "#lib/shared/crypto/index.ts";
export const getClientMeks = async (userId: number, clientId: number) => {
return await MekRepo.getAllValidClientMeks(userId, clientId);
@@ -15,10 +16,10 @@ const verifyClientEncMekSig = async (
) => {
const userClient = await ClientRepo.getUserClientWithDetails(userId, clientId);
if (!userClient) {
throw new AppError("INTERNAL_SERVER_ERROR", "Invalid session id");
throw invalidSessionError();
}
const data = JSON.stringify({ version, key: encMek });
const data = serializeMasterKeyWrapped(encMek, version);
return verifySignature(Buffer.from(data), encMekSig, userClient.sigPubKey);
};
+2 -2
View File
@@ -1,10 +1,10 @@
import { UserRepo } from "#lib/server/db/index.ts";
import { AppError } from "#lib/server/errors.ts";
import { invalidSessionError } from "#lib/server/errors.ts";
export const getUser = async (userId: number) => {
const user = await UserRepo.getUser(userId);
if (!user) {
throw new AppError("INTERNAL_SERVER_ERROR", "Invalid session id");
throw invalidSessionError();
}
return user;
};