이미 클라이언트가 로그인된 상태에서 세션을 업그레이드하려는 경우 발생하던 500 오류 수정

This commit is contained in:
static
2025-07-08 19:38:49 +09:00
parent 983cb2cc57
commit 6e14b45656
3 changed files with 35 additions and 40 deletions

View File

@@ -5,31 +5,22 @@ import db from "./kysely";
export const createSession = async ( export const createSession = async (
userId: number, userId: number,
clientId: number | null,
sessionId: string, sessionId: string,
ip: string | null, ip: string | null,
agent: string | null, agent: string | null,
) => { ) => {
try { const now = new Date();
const now = new Date(); await db
await db .insertInto("session")
.insertInto("session") .values({
.values({ id: sessionId,
id: sessionId, user_id: userId,
user_id: userId, created_at: now,
client_id: clientId, last_used_at: now,
created_at: now, last_used_by_ip: ip || null,
last_used_at: now, last_used_by_agent: agent || null,
last_used_by_ip: ip || null, })
last_used_by_agent: agent || null, .execute();
})
.execute();
} catch (e) {
if (e instanceof pg.DatabaseError && e.code === "23505") {
throw new IntegrityError("Session already exists");
}
throw e;
}
}; };
export const refreshSession = async ( export const refreshSession = async (
@@ -56,14 +47,21 @@ export const refreshSession = async (
}; };
export const upgradeSession = async (sessionId: string, clientId: number) => { export const upgradeSession = async (sessionId: string, clientId: number) => {
const res = await db try {
.updateTable("session") const res = await db
.set({ client_id: clientId }) .updateTable("session")
.where("id", "=", sessionId) .set({ client_id: clientId })
.where("client_id", "is", null) .where("id", "=", sessionId)
.executeTakeFirst(); .where("client_id", "is", null)
if (res.numUpdatedRows === 0n) { .executeTakeFirst();
throw new IntegrityError("Session not found"); if (res.numUpdatedRows === 0n) {
throw new IntegrityError("Session not found");
}
} catch (e) {
if (e instanceof pg.DatabaseError && e.code === "23505") {
throw new IntegrityError("Session already exists");
}
throw e;
} }
}; };

View File

@@ -27,7 +27,7 @@ export class AuthenticationError extends Error {
export const startSession = async (userId: number, ip: string, userAgent: string) => { export const startSession = async (userId: number, ip: string, userAgent: string) => {
const { sessionId, sessionIdSigned } = await issueSessionId(32, env.session.secret); const { sessionId, sessionIdSigned } = await issueSessionId(32, env.session.secret);
await createSession(userId, null, sessionId, ip, userAgent); await createSession(userId, sessionId, ip, userAgent);
return sessionIdSigned; return sessionIdSigned;
}; };

View File

@@ -51,14 +51,7 @@ export const login = async (email: string, password: string, ip: string, userAge
error(401, "Invalid email or password"); error(401, "Invalid email or password");
} }
try { return { sessionIdSigned: await startSession(user.id, ip, userAgent) };
return { sessionIdSigned: await startSession(user.id, ip, userAgent) };
} catch (e) {
if (e instanceof IntegrityError && e.message === "Session already exists") {
error(403, "Already logged in");
}
throw e;
}
}; };
export const logout = async (sessionId: string) => { export const logout = async (sessionId: string) => {
@@ -115,8 +108,12 @@ export const verifySessionUpgradeChallenge = async (
try { try {
await upgradeSession(sessionId, client.id); await upgradeSession(sessionId, client.id);
} catch (e) { } catch (e) {
if (e instanceof IntegrityError && e.message === "Session not found") { if (e instanceof IntegrityError) {
error(500, "Invalid challenge answer"); if (e.message === "Session not found") {
error(500, "Invalid challenge answer");
} else if (e.message === "Session already exists") {
error(403, "Already logged in");
}
} }
throw e; throw e;
} }