first commit
This commit is contained in:
62
apps/api-gateway/src/session-auth.ts
Normal file
62
apps/api-gateway/src/session-auth.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import { ForbiddenException, UnauthorizedException } from '@nestjs/common';
|
||||
import { JwtService } from '@nestjs/jwt';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { extractBearerToken } from './auth-token';
|
||||
import { CoreGrpcService } from './core-grpc.service';
|
||||
|
||||
export interface AccessTokenPayload {
|
||||
sub: string;
|
||||
sessionId?: string;
|
||||
pinVerified?: boolean;
|
||||
isSuperAdmin?: boolean;
|
||||
}
|
||||
|
||||
export async function verifyAccessToken(jwt: JwtService, authorization?: string): Promise<AccessTokenPayload> {
|
||||
const token = extractBearerToken(authorization);
|
||||
|
||||
try {
|
||||
return await jwt.verifyAsync<AccessTokenPayload>(token, {
|
||||
secret: process.env.JWT_ACCESS_SECRET ?? 'docker-access-secret',
|
||||
issuer: 'id.lendry.ru'
|
||||
});
|
||||
} catch {
|
||||
throw new UnauthorizedException({
|
||||
statusCode: 401,
|
||||
message: 'Токен доступа недействителен или истёк',
|
||||
code: 'TOKEN_EXPIRED'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export async function assertSessionUnlocked(core: CoreGrpcService, payload: AccessTokenPayload) {
|
||||
if (!payload.sessionId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const validation = (await firstValueFrom(
|
||||
core.auth.ValidateSession({
|
||||
userId: payload.sub,
|
||||
sessionId: payload.sessionId,
|
||||
touchActivity: true
|
||||
})
|
||||
)) as { requiresPin: boolean; sessionId: string };
|
||||
|
||||
if (validation.requiresPin) {
|
||||
throw new ForbiddenException({
|
||||
statusCode: 403,
|
||||
message: 'Требуется подтверждение PIN-кода',
|
||||
code: 'PIN_REQUIRED',
|
||||
sessionId: validation.sessionId
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export async function resolveAuthorizedPayload(
|
||||
jwt: JwtService,
|
||||
core: CoreGrpcService,
|
||||
authorization?: string
|
||||
): Promise<AccessTokenPayload> {
|
||||
const payload = await verifyAccessToken(jwt, authorization);
|
||||
await assertSessionUnlocked(core, payload);
|
||||
return payload;
|
||||
}
|
||||
Reference in New Issue
Block a user