@@ -11,12 +11,12 @@ export class JwtGuard extends AuthGuard('jwt') {
|
|||||||
return super.canActivate(context);
|
return super.canActivate(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleRequest(err: any, user: any, info: any) {
|
handleRequest(err: any, user: any, info: any, context?: any) {
|
||||||
if (err || !user) {
|
if (err || !user) {
|
||||||
this.logger.debug(`JwtGuard handleRequest failed. err=${err} user=${!!user} info=${JSON.stringify(info)}`);
|
this.logger.debug(`JwtGuard handleRequest failed. err=${err} user=${!!user} info=${JSON.stringify(info)}`);
|
||||||
} else {
|
} else {
|
||||||
this.logger.debug(`JwtGuard handleRequest success user=${JSON.stringify(user)}`);
|
this.logger.debug(`JwtGuard handleRequest success user=${JSON.stringify(user)}`);
|
||||||
}
|
}
|
||||||
return super.handleRequest(err, user, info);
|
return super.handleRequest(err, user, info, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,12 +11,12 @@ export class RefreshGuard extends AuthGuard('refresh') {
|
|||||||
return super.canActivate(context);
|
return super.canActivate(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleRequest(err: any, user: any, info: any) {
|
handleRequest(err: any, user: any, info: any, context?: any) {
|
||||||
if (err || !user) {
|
if (err || !user) {
|
||||||
this.logger.debug(`RefreshGuard handleRequest failed. err=${err} user=${!!user} info=${JSON.stringify(info)}`);
|
this.logger.debug(`RefreshGuard handleRequest failed. err=${err} user=${!!user} info=${JSON.stringify(info)}`);
|
||||||
} else {
|
} else {
|
||||||
this.logger.debug(`RefreshGuard handleRequest success userId=${user.id} authInfo=${JSON.stringify(info)}`);
|
this.logger.debug(`RefreshGuard handleRequest success userId=${user.id} authInfo=${JSON.stringify(info)}`);
|
||||||
}
|
}
|
||||||
return super.handleRequest(err, user, info);
|
return super.handleRequest(err, user, info, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ import { Controller, Get, Post, Query, Res, Req, Body, HttpCode, HttpStatus, Log
|
|||||||
import { ApiTags, ApiOperation } from '@nestjs/swagger';
|
import { ApiTags, ApiOperation } from '@nestjs/swagger';
|
||||||
import { AuthService } from './auth.service';
|
import { AuthService } from './auth.service';
|
||||||
import { Response, Request } from 'express';
|
import { Response, Request } from 'express';
|
||||||
import { JwtGuard } from '../../../core/auth/guards/jwt.guard';
|
import { JwtGuard } from '../../core/auth/guards/jwt.guard';
|
||||||
import { RefreshGuard } from '../../../core/auth/guards/refresh.guard';
|
import { RefreshGuard } from '../../core/auth/guards/refresh.guard';
|
||||||
import { ConfigService } from '@nestjs/config';
|
import { ConfigService } from '@nestjs/config';
|
||||||
|
|
||||||
@ApiTags('Auth')
|
@ApiTags('Auth')
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ import { IUser } from '../identity/domain/repositories/user.interface';
|
|||||||
import { PrismaService } from '../../shared/prisma.service';
|
import { PrismaService } from '../../shared/prisma.service';
|
||||||
import { RedisPkceStore } from './pkce/redis-pkce.store';
|
import { RedisPkceStore } from './pkce/redis-pkce.store';
|
||||||
import { InMemoryRefreshStore } from './refresh/inmemory-refresh.store';
|
import { InMemoryRefreshStore } from './refresh/inmemory-refresh.store';
|
||||||
import { Issuer, generators, Client, TokenSet } from 'openid-client';
|
// dynamic require to avoid TypeScript typing issues with installed openid-client
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
|
const OpenIDClient = require('openid-client');
|
||||||
import crypto from 'crypto';
|
import crypto from 'crypto';
|
||||||
|
|
||||||
const logger = new Logger('AuthService');
|
const logger = new Logger('AuthService');
|
||||||
@@ -23,14 +25,14 @@ export class AuthService {
|
|||||||
private readonly refreshStore: InMemoryRefreshStore,
|
private readonly refreshStore: InMemoryRefreshStore,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
private issuer: Issuer<Client> | null = null;
|
private issuer: any | null = null;
|
||||||
private client: Client | null = null;
|
private client: any | null = null;
|
||||||
|
|
||||||
private async getIssuer() {
|
private async getIssuer() {
|
||||||
if (this.issuer) return this.issuer;
|
if (this.issuer) return this.issuer;
|
||||||
const issuerUrl = this.config.get<string>('AUTHENTIK_ISSUER');
|
const issuerUrl = this.config.get<string>('AUTHENTIK_ISSUER');
|
||||||
if (!issuerUrl) throw new Error('AUTHENTIK_ISSUER not configured');
|
if (!issuerUrl) throw new Error('AUTHENTIK_ISSUER not configured');
|
||||||
this.issuer = await Issuer.discover(issuerUrl);
|
this.issuer = await OpenIDClient.Issuer.discover(issuerUrl);
|
||||||
return this.issuer;
|
return this.issuer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,9 +55,9 @@ export class AuthService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const state = crypto.randomUUID();
|
const state = crypto.randomUUID();
|
||||||
const code_verifier = generators.codeVerifier();
|
const code_verifier = OpenIDClient.generators.codeVerifier();
|
||||||
const code_challenge = await generators.codeChallenge(code_verifier);
|
const code_challenge = await OpenIDClient.generators.codeChallenge(code_verifier);
|
||||||
const nonce = generators.nonce();
|
const nonce = OpenIDClient.generators.nonce();
|
||||||
|
|
||||||
// save PKCE session keyed by state
|
// save PKCE session keyed by state
|
||||||
await this.pkceStore.save(state, { code_verifier, nonce, returnTo }, 300);
|
await this.pkceStore.save(state, { code_verifier, nonce, returnTo }, 300);
|
||||||
@@ -84,7 +86,7 @@ export class AuthService {
|
|||||||
if (!redirectUri) throw new Error('AUTHENTIK_REDIRECT_URI is not configured');
|
if (!redirectUri) throw new Error('AUTHENTIK_REDIRECT_URI is not configured');
|
||||||
|
|
||||||
// Exchange code for tokens. Provide explicit checks: state, nonce and code_verifier.
|
// Exchange code for tokens. Provide explicit checks: state, nonce and code_verifier.
|
||||||
let tokenSet: TokenSet;
|
let tokenSet: any;
|
||||||
try {
|
try {
|
||||||
tokenSet = await client.callback(
|
tokenSet = await client.callback(
|
||||||
redirectUri,
|
redirectUri,
|
||||||
|
|||||||
Reference in New Issue
Block a user