init
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
import {
|
||||
CanActivate,
|
||||
ExecutionContext,
|
||||
Injectable,
|
||||
UnauthorizedException,
|
||||
} from '@nestjs/common';
|
||||
import { JwtService } from '@nestjs/jwt';
|
||||
import { CLIENT_APP_ACTOR_MAP, ClientApp } from '@dukang/shared-types';
|
||||
|
||||
export interface AuthUser {
|
||||
actorType: string;
|
||||
actorId: bigint;
|
||||
clientApp: ClientApp;
|
||||
sub: string;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class JwtAuthGuard implements CanActivate {
|
||||
constructor(protected readonly jwtService: JwtService) {}
|
||||
|
||||
canActivate(context: ExecutionContext): boolean {
|
||||
const req = context.switchToHttp().getRequest();
|
||||
const auth = req.headers.authorization as string | undefined;
|
||||
if (!auth?.startsWith('Bearer ')) {
|
||||
throw new UnauthorizedException('Missing token');
|
||||
}
|
||||
try {
|
||||
const payload = this.jwtService.verify(auth.slice(7));
|
||||
const clientApp = req.headers['x-client-app'] as ClientApp;
|
||||
if (!clientApp || payload.clientApp !== clientApp) {
|
||||
throw new UnauthorizedException('Invalid client app');
|
||||
}
|
||||
const expectedActor = CLIENT_APP_ACTOR_MAP[clientApp];
|
||||
if (payload.actorType !== expectedActor) {
|
||||
throw new UnauthorizedException('Actor mismatch');
|
||||
}
|
||||
req.user = {
|
||||
actorType: payload.actorType,
|
||||
actorId: BigInt(payload.actorId),
|
||||
clientApp,
|
||||
sub: payload.sub,
|
||||
} satisfies AuthUser;
|
||||
return true;
|
||||
} catch (err) {
|
||||
if (err instanceof UnauthorizedException) throw err;
|
||||
throw new UnauthorizedException('Invalid token');
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user