This commit is contained in:
Bastian Wagner
2026-07-16 09:49:22 +02:00
commit 543e8273a7
157 changed files with 22761 additions and 0 deletions

View File

@@ -0,0 +1,69 @@
import { Controller, Get, Query, Redirect, Req, Res } from '@nestjs/common';
import type { Response } from 'express';
import type { AuthenticatedRequest } from './authenticated-request';
import { Public } from './guards/public.decorator';
import { AppConfigService } from '../config/config.service';
import { SensitiveRateLimit } from '../common/rate-limit/sensitive-rate-limit.decorator';
import { AuthService } from './auth.service';
@Controller('auth')
export class AuthController {
constructor(
private readonly auth: AuthService,
private readonly config: AppConfigService,
) {}
@Get('login')
@Public()
@SensitiveRateLimit()
@Redirect()
async login() {
return { url: await this.auth.createLoginUrl() };
}
@Get('callback')
@Public()
@SensitiveRateLimit()
async callback(
@Query('code') code: string,
@Query('state') state: string,
@Req() req: AuthenticatedRequest,
@Res() res: Response,
) {
const { session, csrfToken } = await this.auth.completeLogin(
code,
state,
req.get('user-agent'),
req.ip,
);
res.cookie(this.config.session.cookieName, session.id, {
httpOnly: true,
signed: true,
secure: this.config.isProduction,
sameSite: 'lax',
path: '/',
expires: session.absoluteExpiresAt,
});
res.cookie('csrf_token', csrfToken, {
httpOnly: false,
secure: this.config.isProduction,
sameSite: 'lax',
path: '/',
expires: session.absoluteExpiresAt,
});
res.redirect(this.config.frontendBaseUrl);
}
@Get('logout')
@Public()
@SensitiveRateLimit()
async logout(@Req() req: AuthenticatedRequest, @Res() res: Response) {
const sessionId = req.signedCookies?.[this.config.session.cookieName] as
| string
| undefined;
await this.auth.logout(sessionId);
res.clearCookie(this.config.session.cookieName, { path: '/' });
res.clearCookie('csrf_token', { path: '/' });
res.redirect(this.config.frontendBaseUrl);
}
}