f2fc39f51c
apps/api/src/auth/types/auth-user.ts angelegt: AuthUser, AuthenticatedRequest, LocalAuthenticatedRequest, LoginUser, JwtPayload, UploadedFileLike. Jedes Feld traegt seine Herkunft als Kommentar. tenantId ist string, hergeleitet und nicht gewaehlt: die Spalte User.tenantId ist in schema.prisma Pflicht, beide Signierstellen schreiben genau sie, und der Bestand beschreibt dasselbe Objekt in SessionUser schon so. Der SUPER_ADMIN-Zweig in TenantGuard spricht nicht dagegen - der Waechter liest AuthUser gar nicht, und dass es den Zweig gibt, steht als null in AuthenticatedRequest.tenantId weiter im Typsystem. tenant.guard.ts bleibt unberuehrt. role ist die Aufzaehlung Role: schema.prisma deklariert die Spalte so, die SQL-Funktion auth_lookup_user_by_username gibt sie als "Role" zurueck. Die Handannotation role: string in AuthLookupUserByUsernameRow war eine zweite Fassung desselben Wertes und faellt damit weg. SessionUser und UploadedPng in bug-reports.service.ts sind jetzt Pick<> der neuen Typen statt eigener Beschreibungen. Fixtures in auth.controller.spec.ts ergaenzt: sie uebergaben einen Aufrufer ohne username und ohne mustChangePassword - eine Form, die JwtStrategy nie erzeugt. Testzahlen unveraendert. noExplicitAny in apps/api/src: 149 -> 137. type-check 4/4, lint 5/5, apps/api 72/1143, apps/web 73/531. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TPPB4ApQxzSU1rwV2Ffj9J
22 lines
790 B
TypeScript
22 lines
790 B
TypeScript
import { Injectable, UnauthorizedException } from '@nestjs/common';
|
|
import { PassportStrategy } from '@nestjs/passport';
|
|
import { Strategy } from 'passport-local';
|
|
import { AuthService } from '../auth.service';
|
|
import type { LoginUser } from '../types/auth-user';
|
|
|
|
@Injectable()
|
|
export class LocalStrategy extends PassportStrategy(Strategy) {
|
|
constructor(private authService: AuthService) {
|
|
super({ usernameField: 'username' });
|
|
}
|
|
|
|
async validate(username: string, password: string): Promise<LoginUser> {
|
|
const user = await this.authService.validateUser(username, password);
|
|
if (!user) {
|
|
// T-02-01: Generic error message - never reveal whether username or password is wrong
|
|
throw new UnauthorizedException('Invalid credentials');
|
|
}
|
|
return user;
|
|
}
|
|
}
|