From 7195b3bd97024effc859d6eae4fc643d83807e88 Mon Sep 17 00:00:00 2001 From: Andreas Fitzek Date: Fri, 11 Jul 2025 18:06:42 +0200 Subject: [PATCH] chore(core): Adapt OIDC to match SAML behavior for signup (#17234) --- .../cli/src/sso.ee/oidc/oidc.service.ee.ts | 18 +++++++++++++----- .../integration/oidc/oidc.service.ee.test.ts | 12 ++++++++---- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/packages/cli/src/sso.ee/oidc/oidc.service.ee.ts b/packages/cli/src/sso.ee/oidc/oidc.service.ee.ts index 57f3435687..dd842418b4 100644 --- a/packages/cli/src/sso.ee/oidc/oidc.service.ee.ts +++ b/packages/cli/src/sso.ee/oidc/oidc.service.ee.ts @@ -104,10 +104,6 @@ export class OidcService { throw new BadRequestError('An email is required'); } - if (!userInfo.email_verified) { - throw new BadRequestError('Email needs to be verified'); - } - const openidUser = await this.authIdentityRepository.findOne({ where: { providerId: claims.sub, providerType: 'oidc' }, relations: ['user'], @@ -120,7 +116,19 @@ export class OidcService { const foundUser = await this.userRepository.findOneBy({ email: userInfo.email }); if (foundUser) { - throw new BadRequestError('User already exist with that email.'); + this.logger.debug( + `OIDC login: User with email ${userInfo.email} already exists, linking OIDC identity.`, + ); + // If the user already exists, we just add the OIDC identity to the user + const id = this.authIdentityRepository.create({ + providerId: claims.sub, + providerType: 'oidc', + userId: foundUser.id, + }); + + await this.authIdentityRepository.save(id); + + return foundUser; } return await this.userRepository.manager.transaction(async (trx) => { diff --git a/packages/cli/test/integration/oidc/oidc.service.ee.test.ts b/packages/cli/test/integration/oidc/oidc.service.ee.test.ts index e56fdc8be2..27be7434de 100644 --- a/packages/cli/test/integration/oidc/oidc.service.ee.test.ts +++ b/packages/cli/test/integration/oidc/oidc.service.ee.test.ts @@ -248,7 +248,7 @@ describe('OIDC service', () => { expect(user.id).toEqual(createdUser.id); }); - it('should throw `BadRequestError` if user already exists out of OIDC system', async () => { + it('should sign up the user if user already exists out of OIDC system', async () => { const callbackUrl = new URL( 'http://localhost:5678/rest/sso/oidc/callback?code=valid-code&state=valid-state', ); @@ -279,10 +279,12 @@ describe('OIDC service', () => { email: 'user1@example.com', }); - await expect(oidcService.loginUser(callbackUrl)).rejects.toThrowError(BadRequestError); + const user = await oidcService.loginUser(callbackUrl); + expect(user).toBeDefined(); + expect(user.email).toEqual('user1@example.com'); }); - it('should throw `BadRequestError` if OIDC Idp does not have email verified', async () => { + it('should sign in user if OIDC Idp does not have email verified', async () => { const callbackUrl = new URL( 'http://localhost:5678/rest/sso/oidc/callback?code=valid-code&state=valid-state', ); @@ -313,7 +315,9 @@ describe('OIDC service', () => { email: 'user3@example.com', }); - await expect(oidcService.loginUser(callbackUrl)).rejects.toThrowError(BadRequestError); + const user = await oidcService.loginUser(callbackUrl); + expect(user).toBeDefined(); + expect(user.email).toEqual('user3@example.com'); }); it('should throw `BadRequestError` if OIDC Idp does not provide an email', async () => {