FEAT: dynamic callback and issuer urls

This commit is contained in:
marcos-silva-rodrigues
2025-07-16 11:35:47 -03:00
parent 42a39ee891
commit cb66d4f6c0
5 changed files with 42 additions and 33 deletions
@@ -6,4 +6,5 @@ export class SsoSignInDto {
readonly clientId: string;
readonly clientSecret: string;
readonly issuerUrl: string;
readonly redirectUrls: string[];
}
@@ -27,7 +27,11 @@ import {
} from './dto/identity-provider.dto';
import { Request } from 'express';
import ErrorCodes from 'src/utils/errorCodes';
import { Authenticated, RequireModule, RequireSomePermission } from 'src/decorators/authentication.decorator';
import {
Authenticated,
RequireModule,
RequireSomePermission,
} from 'src/decorators/authentication.decorator';
import { PERMISSIONS_GROUPS } from 'src/authentication/permissions.enum';
@Controller('identity-providers')
@@ -119,15 +123,24 @@ export class IdentityProviderController {
...user,
});
return await this.identityProviderService.updateIdentityProviders(id, body, metadata);
return await this.identityProviderService.updateIdentityProviders(
id,
body,
metadata,
);
}
@Post('/callback')
@HttpCode(HttpStatus.OK)
async callbackIdp(@Req() req: Request, @Body() body: {
state: string,
code: string
}) {
async callbackIdp(
@Req() req: Request,
@Language() language: LanguageEnum,
@Body()
body: {
state: string;
code: string;
},
) {
this.logger.info('GET /identity-providers/callback');
const { code, state } = body;
@@ -141,7 +154,13 @@ export class IdentityProviderController {
throw new Error(ErrorCodes.IDENTITY_PROVIDER.INVALID_RESPONSE);
}
return await this.identityProviderService.getTokenByIdp(code, state);
const origin = req.headers['origin'] as string;
const langHeader = req.headers['dadosfera-lang'] as string;
const lang = langHeader.substring(0, 2) + langHeader.substring(2).toUpperCase();
const callbackUrl = process.env.ENV !== "prd" ? `${origin}/auth/callback` : `${origin}/${lang}/auth/callback`;
return await this.identityProviderService.getTokenByIdp(code, state, callbackUrl);
}
@Get('/links')
@@ -155,7 +174,10 @@ export class IdentityProviderController {
throw new Error(ErrorCodes.IDENTITY_PROVIDER.INVALID_HEADER);
}
const result = await this.identityProviderService.identityProvidersLinksPerDomain(frontDomain);
const result =
await this.identityProviderService.identityProvidersLinksPerDomain(
frontDomain,
);
return result;
}
@@ -171,5 +193,4 @@ export class IdentityProviderController {
url: redirectUrl,
};
}
}
@@ -49,14 +49,11 @@ export class IdentityProviderService implements OnModuleInit {
this.identityProviderService.FindIdentityProvider({ id }),
);
const redirectUri = this.getCallbackUrl();
const cognitoIssuerURL = this.getCognitoIssuerUrl();
const issuer = await Issuer.discover(cognitoIssuerURL);
const issuer = await Issuer.discover(idp.issuerUrl);
const client = new issuer.Client({
client_id: idp.clientId,
client_secret: idp.clientSecret,
redirect_uris: [redirectUri],
redirect_uris: idp.redirectUrls,
response_types: ['code'],
});
@@ -75,7 +72,8 @@ export class IdentityProviderService implements OnModuleInit {
state,
clientId: idp.clientId,
clientSecret: idp.clientSecret,
issuerUrl: cognitoIssuerURL,
issuerUrl: idp.issuerUrl,
redirectUrls: idp.redirectUrls,
});
const url = client.authorizationUrl({
@@ -90,29 +88,18 @@ export class IdentityProviderService implements OnModuleInit {
return idpUrl;
}
private getCallbackUrl() {
const AUTH_CALLBACK = process.env.AUTH_CALLBACK;
return AUTH_CALLBACK;
}
private getCognitoIssuerUrl() {
const COGNITO_ISSUER_URL = process.env.COGNITO_ISSUER_URL;
return COGNITO_ISSUER_URL;
}
async getTokenByIdp(code: string, state: string) {
async getTokenByIdp(code: string, state: string, callbackUrl: string) {
const ssoSign = await this.cacheService.get(state);
if (!ssoSign) {
throw new BadRequestException('SSO sign-in is expired or not found');
}
const callbackUrl = this.getCallbackUrl();
const issuer = await Issuer.discover(ssoSign.issuerUrl);
const client = new issuer.Client({
client_id: ssoSign.clientId,
client_secret: ssoSign.clientSecret,
redirect_uris: [callbackUrl],
redirect_uris: ssoSign.redirectUrls,
});
if (ssoSign === null) {