feat: implement authentication service

Add auth service that wraps Playwright service for user authentication.
Includes login/logout functionality and session management.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Misaka
2026-02-28 22:38:55 +08:00
parent cfc2fe7f7d
commit 00f4e40505
2 changed files with 86 additions and 0 deletions

View File

@@ -0,0 +1,10 @@
export interface AuthResult {
success: boolean;
message?: string;
}
export interface SessionInfo {
username: string;
isLoggedIn: boolean;
loginTime: Date;
}

View File

@@ -0,0 +1,76 @@
import { PlaywrightService } from './playwright.service';
import { Credentials, LoginResult } from '../models/playwright.types';
import { AuthResult, SessionInfo } from '../models/auth.types';
import { LoggerService } from './logger.service';
export class AuthService {
private currentSession?: LoginResult;
private sessionInfo?: SessionInfo;
constructor(private playwrightService: PlaywrightService) {}
async login(credentials: Credentials): Promise<AuthResult> {
try {
LoggerService.info(`Logging in user: ${credentials.username}`);
const session = await this.playwrightService.login(credentials);
this.currentSession = session;
this.sessionInfo = {
username: credentials.username,
isLoggedIn: true,
loginTime: new Date(),
};
LoggerService.info('Login successful');
return { success: true, message: 'Login successful' };
} catch (error) {
LoggerService.error('Login failed', error);
// Ensure cleanup on failed login
await this.playwrightService.closeBrowser().catch(cleanupError => {
LoggerService.error('Failed to cleanup after failed login', cleanupError);
});
this.currentSession = undefined;
this.sessionInfo = undefined;
return {
success: false,
message: error instanceof Error ? error.message : 'Unknown error',
};
}
}
async logout(): Promise<void> {
if (!this.currentSession) {
return; // Already logged out
}
try {
LoggerService.info('Logging out...');
await this.playwrightService.closeBrowser();
LoggerService.info('Logout successful');
} catch (error) {
LoggerService.error('Logout failed', error);
throw new Error(`Logout failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
} finally {
// Always clear state
this.currentSession = undefined;
this.sessionInfo = undefined;
}
}
getSessionInfo(): SessionInfo | undefined {
return this.sessionInfo;
}
isLoggedIn(): boolean {
return this.sessionInfo?.isLoggedIn ?? false;
}
async destroy(): Promise<void> {
await this.logout().catch(err =>
LoggerService.error('Failed to logout during destroy', err)
);
}
}