feat(auth): add MockAuthenticationService with constructor-injected users repo

This commit is contained in:
2026-05-05 00:39:48 +02:00
parent 1becc23843
commit b8cfe0e1f2

View File

@@ -0,0 +1,73 @@
import "reflect-metadata";
import { inject, injectable } from "inversify";
import type { IAuthenticationService } from "../../application/services/authentication-service.interface";
import type { IUsersRepository } from "../../application/repositories/users-repository.interface";
import { UnauthenticatedError } from "../../entities/errors";
import { sessionSchema, type Session } from "../../entities/session";
import type { Cookie } from "../../entities/cookie";
import type { User } from "../../entities/user";
import { AUTH_SYMBOLS } from "../../di/symbols";
import { SESSION_COOKIE } from "../../config";
@injectable()
export class MockAuthenticationService implements IAuthenticationService {
private _sessions: Record<string, { session: Session; user: User }> = {};
constructor(
@inject(AUTH_SYMBOLS.IUsersRepository)
private _usersRepository: IUsersRepository,
) {}
generateUserId(): string {
return (Math.random() + 1).toString(36).substring(7);
}
async hashPassword(password: string): Promise<string> {
return `hashed_${password}`;
}
async verifyPassword(hash: string, password: string): Promise<boolean> {
return hash === `hashed_${password}`;
}
async validateSession(
sessionId: string,
): Promise<{ user: User; session: Session }> {
const result = this._sessions[sessionId];
if (!result) {
throw new UnauthenticatedError("Unauthenticated");
}
const user = await this._usersRepository.getUser(result.user.id);
if (!user) {
throw new UnauthenticatedError("Unauthenticated");
}
return { user, session: result.session };
}
async createSession(
user: User,
): Promise<{ session: Session; cookie: Cookie }> {
const session = sessionSchema.parse({
id: "session_" + user.id,
userId: user.id,
expiresAt: new Date(Date.now() + 86400000 * 7),
});
const cookie: Cookie = {
name: SESSION_COOKIE,
value: session.id,
attributes: {},
};
this._sessions[session.id] = { session, user };
return { session, cookie };
}
async invalidateSession(
sessionId: string,
): Promise<{ blankCookie: Cookie }> {
delete this._sessions[sessionId];
return {
blankCookie: { name: SESSION_COOKIE, value: "", attributes: {} },
};
}
}