feat(sso): fix saml + allow to use public invite with sso + fix invite page with multiple sso provider (#9963)

- Fix SAML issue
- Fix the wrong state on the Invite page when multiple SSO provider
exists
- Allow to signup with SSO and public invite link
- For OIDC, use the property upn to guess email for Microsoft and enable
oidc with a specific context in azure
- Improve error in OIDC flow when email not found
This commit is contained in:
Antoine Moreaux
2025-02-03 18:48:25 +01:00
committed by GitHub
parent 253a3eb83f
commit 47487f5d1c
14 changed files with 122 additions and 92 deletions

View File

@ -2,11 +2,16 @@
import { Field, InputType } from '@nestjs/graphql';
import { IsString } from 'class-validator';
import { IsOptional, IsString } from 'class-validator';
@InputType()
export class GetAuthorizationUrlInput {
@Field(() => String)
@IsString()
identityProviderId: string;
@Field(() => String, { nullable: true })
@IsString()
@IsOptional()
workspaceInviteHash?: string;
}

View File

@ -152,11 +152,18 @@ export class SSOService {
buildIssuerURL(
identityProvider: Pick<WorkspaceSSOIdentityProvider, 'id' | 'type'>,
searchParams?: Record<string, string | boolean>,
) {
const authorizationUrl = new URL(this.environmentService.get('SERVER_URL'));
authorizationUrl.pathname = `/auth/${identityProvider.type.toLowerCase()}/login/${identityProvider.id}`;
if (searchParams) {
Object.entries(searchParams).forEach(([key, value]) => {
authorizationUrl.searchParams.append(key, value.toString());
});
}
return authorizationUrl.toString();
}
@ -191,7 +198,10 @@ export class SSOService {
});
}
async getAuthorizationUrl(identityProviderId: string) {
async getAuthorizationUrl(
identityProviderId: string,
searchParams: Record<string, string | boolean>,
) {
const identityProvider =
(await this.workspaceSSOIdentityProviderRepository.findOne({
where: {
@ -208,7 +218,7 @@ export class SSOService {
return {
id: identityProvider.id,
authorizationURL: this.buildIssuerURL(identityProvider),
authorizationURL: this.buildIssuerURL(identityProvider, searchParams),
type: identityProvider.type,
};
}

View File

@ -3,6 +3,8 @@
import { UseGuards } from '@nestjs/common';
import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
import omit from 'lodash.omit';
import { EnterpriseFeaturesEnabledGuard } from 'src/engine/core-modules/auth/guards/enterprise-features-enabled.guard';
import { DeleteSsoInput } from 'src/engine/core-modules/sso/dtos/delete-sso.input';
import { DeleteSsoOutput } from 'src/engine/core-modules/sso/dtos/delete-sso.output';
@ -47,10 +49,11 @@ export class SSOResolver {
}
@Mutation(() => GetAuthorizationUrlOutput)
async getAuthorizationUrl(
@Args('input') { identityProviderId }: GetAuthorizationUrlInput,
) {
return this.sSOService.getAuthorizationUrl(identityProviderId);
async getAuthorizationUrl(@Args('input') params: GetAuthorizationUrlInput) {
return await this.sSOService.getAuthorizationUrl(
params.identityProviderId,
omit(params, ['identityProviderId']),
);
}
@UseGuards(WorkspaceAuthGuard, EnterpriseFeaturesEnabledGuard)