diff --git a/packages/auth/src/infrastructure/services/mock-authentication.service.ts b/packages/auth/src/infrastructure/services/mock-authentication.service.ts new file mode 100644 index 0000000..365d841 --- /dev/null +++ b/packages/auth/src/infrastructure/services/mock-authentication.service.ts @@ -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 = {}; + + constructor( + @inject(AUTH_SYMBOLS.IUsersRepository) + private _usersRepository: IUsersRepository, + ) {} + + generateUserId(): string { + return (Math.random() + 1).toString(36).substring(7); + } + + async hashPassword(password: string): Promise { + return `hashed_${password}`; + } + + async verifyPassword(hash: string, password: string): Promise { + 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: {} }, + }; + } +}