diff --git a/admin/src/app/app.ts b/admin/src/app/app.ts index 2a07864..426c9f9 100644 --- a/admin/src/app/app.ts +++ b/admin/src/app/app.ts @@ -17,12 +17,20 @@ export class App { constructor(private authService: AuthService, private router: Router) {} logout(): void { - // Make a best-effort to log out on the server, but always - // clean up the client-side session in the `finalize` block. - this.authService.serverSideLogout().pipe( - finalize(() => { + // Make a best-effort to log out on the server. + // The client-side logout will run regardless of whether this call + // succeeds or fails. + this.authService.serverSideLogout().subscribe({ + // The server call can succeed or fail, we don't care about the result, + // we just want to ensure the client is logged out. + next: () => { + console.info("server logged out") this.authService.clientSideLogout(); - }) - ).subscribe(); + }, + error: () => { + console.error("server failed to log out") + this.authService.clientSideLogout(); + }, + }); } } diff --git a/admin/src/app/auth/auth.service.ts b/admin/src/app/auth/auth.service.ts index 0475e0b..39e32ec 100644 --- a/admin/src/app/auth/auth.service.ts +++ b/admin/src/app/auth/auth.service.ts @@ -32,6 +32,7 @@ export class AuthService { * This is the definitive logout action from the user's perspective. */ clientSideLogout(): void { + console.info("clientSideLogout") this.removeTokens(); this.router.navigate(['/login']); } diff --git a/admin/src/app/auth/jwt.interceptor.ts b/admin/src/app/auth/jwt.interceptor.ts index 31ac8d3..fc00237 100644 --- a/admin/src/app/auth/jwt.interceptor.ts +++ b/admin/src/app/auth/jwt.interceptor.ts @@ -53,10 +53,9 @@ export class JwtInterceptor implements HttpInterceptor { this.isRefreshing = false; this.refreshTokenSubject.error(err); - // In a refresh failure, the user MUST be logged out. - // Call the synchronous client-side logout to avoid re-intercepting. - this.authService.clientSideLogout(); - + // The interceptor's job is done. It failed to refresh. + // It should NOT handle logout. It should just propagate the error. + // The calling service/component will be responsible for the user-facing action. return throwError(() => err); }) ); diff --git a/server/src/auth/auth.controller.ts b/server/src/auth/auth.controller.ts index 5e8c7ab..1f4fcbf 100644 --- a/server/src/auth/auth.controller.ts +++ b/server/src/auth/auth.controller.ts @@ -6,11 +6,11 @@ import { UseGuards, Req, } from '@nestjs/common'; -import AuthService from './auth.service'; import { LoginRequestDto } from './dto/login-request.dto'; import { JwtAuthGuard } from './jwt-auth.guard'; import { JwtRefreshAuthGuard } from './jwt-refresh-auth.guard'; import express from 'express'; +import { AuthService } from './auth.service'; @Controller('auth') export class AuthController { diff --git a/server/src/auth/auth.module.ts b/server/src/auth/auth.module.ts index 71ec5a6..58d1091 100644 --- a/server/src/auth/auth.module.ts +++ b/server/src/auth/auth.module.ts @@ -2,23 +2,27 @@ import { Module } from '@nestjs/common'; import { JwtModule } from '@nestjs/jwt'; import { PassportModule } from '@nestjs/passport'; import { UserModule } from '../user/user.module'; -import AuthService from './auth.service'; +import { AuthService } from './auth.service'; import { AuthController } from './auth.controller'; import { JwtStrategy } from './jwt.strategy'; import { ConfigModule, ConfigService } from '@nestjs/config'; import { JwtRefreshTokenStrategy } from './jwt-refresh.strategy'; +import { StringValue } from 'ms'; @Module({ imports: [ ConfigModule, UserModule, PassportModule, + // Restore the correct async registration for JwtModule JwtModule.registerAsync({ imports: [ConfigModule], inject: [ConfigService], useFactory: (configService: ConfigService) => ({ secret: configService.get('JWT_SECRET'), - signOptions: { expiresIn: '2m' }, + signOptions: { + expiresIn: configService.get('JWT_EXPIRATION_TIME'), + }, }), }), ], diff --git a/server/src/auth/auth.service.ts b/server/src/auth/auth.service.ts index fcbad3c..85cb3d2 100644 --- a/server/src/auth/auth.service.ts +++ b/server/src/auth/auth.service.ts @@ -8,7 +8,7 @@ import { ConfigService } from '@nestjs/config'; import type { StringValue } from 'ms'; @Injectable() -class AuthService { +export class AuthService { constructor( private userService: UserService, private jwtService: JwtService, @@ -109,5 +109,3 @@ class AuthService { }; } } - -export default AuthService;