Files
gridpilot.gg/apps/website/lib/auth/InMemoryAuthService.ts
2025-12-14 18:11:59 +01:00

112 lines
4.2 KiB
TypeScript

import type { AuthService, AuthSession, SignupParams, LoginParams } from './AuthService';
import type { AuthCallbackCommandDTO } from '@gridpilot/identity/application/dto/AuthCallbackCommandDTO';
import type { StartAuthCommandDTO } from '@gridpilot/identity/application/dto/StartAuthCommandDTO';
import { StartAuthUseCase } from '@gridpilot/identity/application/use-cases/StartAuthUseCase';
import { GetCurrentUserSessionUseCase } from '@gridpilot/identity/application/use-cases/GetCurrentUserSessionUseCase';
import { HandleAuthCallbackUseCase } from '@gridpilot/identity/application/use-cases/HandleAuthCallbackUseCase';
import { LogoutUseCase } from '@gridpilot/identity/application/use-cases/LogoutUseCase';
import { SignupWithEmailUseCase } from '@gridpilot/identity/application/use-cases/SignupWithEmailUseCase';
import { LoginWithEmailUseCase } from '@gridpilot/identity/application/use-cases/LoginWithEmailUseCase';
import { CookieIdentitySessionAdapter } from '@gridpilot/identity/infrastructure/session/CookieIdentitySessionAdapter';
import { IracingDemoIdentityProviderAdapter } from '@gridpilot/identity/infrastructure/providers/IracingDemoIdentityProviderAdapter';
import { InMemoryUserRepository } from '@gridpilot/identity/infrastructure/repositories/InMemoryUserRepository';
import type { IUserRepository } from '@gridpilot/identity/domain/repositories/IUserRepository';
import type { ILogger } from '@gridpilot/shared/logging/ILogger';
// Singleton user repository to persist across requests (in-memory demo)
let userRepositoryInstance: IUserRepository | null = null;
function getUserRepository(logger: ILogger): IUserRepository {
if (!userRepositoryInstance) {
userRepositoryInstance = new InMemoryUserRepository(logger);
}
return userRepositoryInstance;
}
export class InMemoryAuthService implements AuthService {
private readonly logger: ILogger;
constructor(logger: ILogger) {
this.logger = logger;
}
async getCurrentSession(): Promise<AuthSession | null> {
const sessionPort = new CookieIdentitySessionAdapter();
const useCase = new GetCurrentUserSessionUseCase(sessionPort);
return useCase.execute();
}
async signupWithEmail(params: SignupParams): Promise<AuthSession> {
const userRepository = getUserRepository();
const sessionPort = new CookieIdentitySessionAdapter();
const useCase = new SignupWithEmailUseCase(userRepository, sessionPort);
const result = await useCase.execute({
email: params.email,
password: params.password,
displayName: params.displayName,
});
return result.session;
}
async loginWithEmail(params: LoginParams): Promise<AuthSession> {
const userRepository = getUserRepository();
const sessionPort = new CookieIdentitySessionAdapter();
const useCase = new LoginWithEmailUseCase(userRepository, sessionPort);
return useCase.execute({
email: params.email,
password: params.password,
});
}
async startIracingAuthRedirect(
returnTo?: string,
): Promise<{ redirectUrl: string; state: string }> {
const provider = new IracingDemoIdentityProviderAdapter();
const useCase = new StartAuthUseCase(provider);
const command: StartAuthCommandDTO = returnTo
? {
provider: 'IRACING_DEMO',
returnTo,
}
: {
provider: 'IRACING_DEMO',
};
return useCase.execute(command);
}
async loginWithIracingCallback(params: {
code: string;
state: string;
returnTo?: string;
}): Promise<AuthSession> {
const provider = new IracingDemoIdentityProviderAdapter();
const sessionPort = new CookieIdentitySessionAdapter();
const useCase = new HandleAuthCallbackUseCase(provider, sessionPort);
const command: AuthCallbackCommandDTO = params.returnTo
? {
provider: 'IRACING_DEMO',
code: params.code,
state: params.state,
returnTo: params.returnTo,
}
: {
provider: 'IRACING_DEMO',
code: params.code,
state: params.state,
};
return useCase.execute(command);
}
async logout(): Promise<void> {
const sessionPort = new CookieIdentitySessionAdapter();
const useCase = new LogoutUseCase(sessionPort);
await useCase.execute();
}
}