From 0d20b4a3377e806ecc6576f27b1ccbf8584610d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20=C5=81oboda?= <47437867+loboda4450@users.noreply.github.com> Date: Thu, 26 Feb 2026 14:31:19 +0100 Subject: [PATCH] Enable SSO signups (#152) * feat: enableSingleSignOnSignUp support * chore: simplify return statement * chore: linted * feat: verbose error on not enabled SSO sign up * chore: update config key to match others * chore: add key to config sample * chore: apply suggestions from code review Co-authored-by: BrunoBernardino --------- Co-authored-by: BrunoBernardino --- bewcloud.config.sample.ts | 1 + lib/config.ts | 12 ++++-------- lib/models/oidc.ts | 6 +++++- lib/types.ts | 2 ++ 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/bewcloud.config.sample.ts b/bewcloud.config.sample.ts index b2b86c8..67e44b6 100644 --- a/bewcloud.config.sample.ts +++ b/bewcloud.config.sample.ts @@ -11,6 +11,7 @@ const config: PartialDeep = { // allowedCookieDomains: ['example.com', 'example.net'], // Can be set to allow more than the baseUrl's domain for session cookies // skipCookieDomainSecurity: true, // If true, the cookie domain will not be strictly set and checked against. This skipping slightly reduces security, but is usually necessary for reverse proxies like Cloudflare Tunnel // enableSingleSignOn: false, // If true, single sign-on will be enabled + // allowSignupsViaSingleSignOn: false, // If true, signups via single sign-on will be allowed, overriding allowSignups // singleSignOnUrl: '', // The Discovery URL (AKA Issuer) of the identity/single sign-on provider // singleSignOnEmailAttribute: 'email', // The attribute to prefer as email of the identity/single sign-on provider // singleSignOnScopes: ['openid', 'email'], // The scopes to request from the identity/single sign-on provider diff --git a/lib/config.ts b/lib/config.ts index f9b1f33..42c4cc6 100644 --- a/lib/config.ts +++ b/lib/config.ts @@ -16,6 +16,7 @@ export class AppConfig { allowedCookieDomains: [], skipCookieDomainSecurity: false, enableSingleSignOn: false, + allowSignupsViaSingleSignOn: false, singleSignOnUrl: '', singleSignOnEmailAttribute: 'email', singleSignOnScopes: ['openid', 'email'], @@ -117,18 +118,13 @@ export class AppConfig { return this.config; } - static async isSignupAllowed(): Promise { + static async isSignupAllowed({ viaSingleSignOn = false }: { viaSingleSignOn?: boolean } = {}): Promise { await this.loadConfig(); - const areSignupsAllowed = this.config.auth.allowSignups; - + const areSignupsAllowed = viaSingleSignOn && !this.config.auth.allowSignups ? this.config.auth.allowSingleSignOnSignups : this.config.auth.allowSignups; const areThereAdmins = await UserModel.isThereAnAdmin(); - if (areSignupsAllowed || !areThereAdmins) { - return true; - } - - return false; + return areSignupsAllowed || !areThereAdmins; } static async isAppEnabled(app: OptionalApp): Promise { diff --git a/lib/models/oidc.ts b/lib/models/oidc.ts index 3010aef..fb09070 100644 --- a/lib/models/oidc.ts +++ b/lib/models/oidc.ts @@ -169,7 +169,7 @@ export class OidcModel { throw new Error(`Missing user/${emailAttribute}`); } - const isSignupAllowed = await AppConfig.isSignupAllowed(); + const isSignupAllowed = await AppConfig.isSignupAllowed({ viaSingleSignOn: true }); const isThereAnAdmin = await UserModel.isThereAnAdmin(); // Confirm the user exists (or signup if allowed) @@ -181,6 +181,10 @@ export class OidcModel { } if (!user) { + if (!config.auth.allowSignupsViaSingleSignOn) { + throw new Error('Sign up via SSO is not allowed!'); + } + throw new Error('There was a problem signing up or logging in!'); } diff --git a/lib/types.ts b/lib/types.ts index 65961d1..e05306c 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -159,6 +159,8 @@ export interface Config { skipCookieDomainSecurity: boolean; /** If true, single sign-on will be enabled */ enableSingleSignOn: boolean; + /** If true, signups via single sign-on will be allowed, overriding allowSignups */ + allowSignupsViaSingleSignOn: boolean; /** The Discovery URL (AKA Issuer) of the identity/single sign-on provider */ singleSignOnUrl: string; /** The attribute to prefer as email of the identity/single sign-on provider */