(llm-first): context budget, validation, and eval harness, orchestration general-prompt

This commit is contained in:
MaKarin
2026-04-03 14:17:21 +03:00
parent 79c9589658
commit c42a88dff6
189 changed files with 15538 additions and 9109 deletions

View File

@@ -1,129 +1,96 @@
import { Injectable, Logger, UnauthorizedException } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { createRemoteJWKSet, jwtVerify } from 'jose';
import { RuntimeEnvironment } from '../config/env.validation';
import {
AuthenticatedUser,
KeycloakJwtPayload,
} from './interfaces/authenticated-user.interface';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { createRemoteJWKSet, jwtVerify, type JWTPayload } from 'jose';
export interface AuthenticatedUser {
sub: string;
username?: string;
email?: string;
name?: string;
realmRoles: string[];
payload: JWTPayload;
}
@Injectable()
export class AuthService {
private readonly logger = new Logger(AuthService.name);
private readonly issuerUrl: string;
private readonly audience: string;
private readonly explicitJwksUrl?: string;
private readonly KEYCLOAK_ISSUER_URL =
process.env.KEYCLOAK_ISSUER_URL ?? 'https://sso.greact.ru/realms/toir';
private jwksResolverPromise: Promise<ReturnType<typeof createRemoteJWKSet>> | null =
private readonly KEYCLOAK_AUDIENCE =
process.env.KEYCLOAK_AUDIENCE ?? 'toir-backend';
private readonly KEYCLOAK_JWKS_URL = process.env.KEYCLOAK_JWKS_URL;
private jwksPromise: Promise<ReturnType<typeof createRemoteJWKSet>> | null =
null;
private jwksResolver: ReturnType<typeof createRemoteJWKSet> | null = null;
constructor(
private readonly configService: ConfigService<RuntimeEnvironment, true>,
) {
this.issuerUrl = this.configService.getOrThrow('KEYCLOAK_ISSUER_URL');
this.audience = this.configService.getOrThrow('KEYCLOAK_AUDIENCE');
this.explicitJwksUrl = this.configService.get('KEYCLOAK_JWKS_URL');
}
async verifyAccessToken(token: string): Promise<AuthenticatedUser> {
async verifyBearerToken(token: string): Promise<AuthenticatedUser> {
try {
const jwksResolver = await this.getJwksResolver();
const { payload } = await jwtVerify(token, jwksResolver, {
issuer: this.issuerUrl,
audience: this.audience,
const JWKS = await this.resolveJwks();
const { payload } = await jwtVerify(token, JWKS, {
issuer: this.KEYCLOAK_ISSUER_URL,
audience: this.KEYCLOAK_AUDIENCE,
});
return this.mapPayloadToUser(payload as KeycloakJwtPayload);
const realmAccess = payload.realm_access as
| { roles?: unknown }
| undefined;
const realmRoles = Array.isArray(realmAccess?.roles)
? realmAccess.roles.filter(
(role): role is string => typeof role === 'string',
)
: [];
return {
sub: String(payload.sub ?? ''),
username:
typeof payload.preferred_username === 'string'
? payload.preferred_username
: undefined,
email: typeof payload.email === 'string' ? payload.email : undefined,
name: typeof payload.name === 'string' ? payload.name : undefined,
realmRoles,
payload,
};
} catch (error) {
this.logger.warn(
`JWT verification failed: ${error instanceof Error ? error.message : 'Unknown error'}`,
throw new UnauthorizedException(
error instanceof Error ? error.message : 'Invalid access token',
);
throw new UnauthorizedException('Invalid or expired access token');
}
}
private mapPayloadToUser(payload: KeycloakJwtPayload): AuthenticatedUser {
if (!payload.sub) {
throw new UnauthorizedException('Token subject is missing');
}
const roles = Array.isArray(payload.realm_access?.roles)
? payload.realm_access.roles.filter(
(role): role is string => typeof role === 'string',
)
: [];
return {
sub: payload.sub,
username: payload.preferred_username,
name: payload.name,
email: payload.email,
roles,
claims: payload,
};
}
private async getJwksResolver() {
if (this.jwksResolver) {
return this.jwksResolver;
}
if (!this.jwksResolverPromise) {
this.jwksResolverPromise = this.createJwksResolver()
.then((resolver) => {
this.jwksResolver = resolver;
return resolver;
})
.finally(() => {
this.jwksResolverPromise = null;
});
}
return this.jwksResolverPromise;
}
private async createJwksResolver() {
const jwksUrl = await this.resolveJwksUrl();
this.logger.log(`Using JWKS URL: ${jwksUrl}`);
return createRemoteJWKSet(new URL(jwksUrl));
}
private async resolveJwksUrl(): Promise<string> {
if (this.explicitJwksUrl) {
return this.explicitJwksUrl;
}
const issuer = this.issuerUrl.replace(/\/+$/, '');
const discoveryUrl = `${issuer}/.well-known/openid-configuration`;
try {
const discoveryResponse = await fetch(discoveryUrl, {
headers: {
Accept: 'application/json',
},
});
if (discoveryResponse.ok) {
const discoveryDocument = (await discoveryResponse.json()) as {
jwks_uri?: string;
};
if (
typeof discoveryDocument.jwks_uri === 'string' &&
discoveryDocument.jwks_uri.trim().length > 0
) {
return discoveryDocument.jwks_uri;
private async resolveJwks(): Promise<ReturnType<typeof createRemoteJWKSet>> {
if (!this.jwksPromise) {
this.jwksPromise = (async () => {
if (this.KEYCLOAK_JWKS_URL) {
return createRemoteJWKSet(new URL(this.KEYCLOAK_JWKS_URL));
}
}
} catch (error) {
this.logger.warn(
`OIDC discovery failed at ${discoveryUrl}: ${error instanceof Error ? error.message : 'Unknown error'}`,
);
const discoveryUrl = new URL(
`${this.KEYCLOAK_ISSUER_URL}/.well-known/openid-configuration`,
);
try {
const response = await fetch(discoveryUrl);
if (response.ok) {
const discovery = (await response.json()) as {
jwks_uri?: unknown;
};
if (typeof discovery.jwks_uri === 'string') {
return createRemoteJWKSet(new URL(discovery.jwks_uri));
}
}
} catch {
// Fall through to the Keycloak certs endpoint.
}
return createRemoteJWKSet(
new URL(
`${this.KEYCLOAK_ISSUER_URL}/protocol/openid-connect/certs`,
),
);
})();
}
return `${issuer}/protocol/openid-connect/certs`;
return this.jwksPromise;
}
}