59 lines
1.6 KiB
TypeScript
59 lines
1.6 KiB
TypeScript
import { cookies } from 'next/headers';
|
|
import { randomUUID } from 'crypto';
|
|
import type { AuthenticatedUserDTO } from '../../application/dto/AuthenticatedUserDTO';
|
|
import type { AuthSessionDTO } from '../../application/dto/AuthSessionDTO';
|
|
import type { IdentitySessionPort } from '../../application/ports/IdentitySessionPort';
|
|
|
|
const SESSION_COOKIE = 'gp_demo_session';
|
|
|
|
function parseCookieValue(raw: string | undefined): AuthSessionDTO | null {
|
|
if (!raw) return null;
|
|
try {
|
|
const parsed = JSON.parse(raw) as AuthSessionDTO;
|
|
if (!parsed.expiresAt || Date.now() > parsed.expiresAt) {
|
|
return null;
|
|
}
|
|
return parsed;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
function serializeSession(session: AuthSessionDTO): string {
|
|
return JSON.stringify(session);
|
|
}
|
|
|
|
export class CookieIdentitySessionAdapter implements IdentitySessionPort {
|
|
async getCurrentSession(): Promise<AuthSessionDTO | null> {
|
|
const store = await cookies();
|
|
const raw = store.get(SESSION_COOKIE)?.value;
|
|
return parseCookieValue(raw);
|
|
}
|
|
|
|
async createSession(user: AuthenticatedUserDTO): Promise<AuthSessionDTO> {
|
|
const now = Date.now();
|
|
const expiresAt = now + 24 * 60 * 60 * 1000;
|
|
|
|
const session: AuthSessionDTO = {
|
|
user,
|
|
issuedAt: now,
|
|
expiresAt,
|
|
token: randomUUID(),
|
|
};
|
|
|
|
const store = await cookies();
|
|
store.set(SESSION_COOKIE, serializeSession(session), {
|
|
httpOnly: true,
|
|
sameSite: 'lax',
|
|
path: '/',
|
|
secure: process.env.NODE_ENV === 'production',
|
|
});
|
|
|
|
return session;
|
|
}
|
|
|
|
async clearSession(): Promise<void> {
|
|
const store = await cookies();
|
|
store.delete(SESSION_COOKIE);
|
|
}
|
|
} |