From d78fbb060a0d0f4bad2acc3d9f528c6a2bdae1ac Mon Sep 17 00:00:00 2001 From: Gero Posmyk-Leinemann Date: Mon, 20 Oct 2025 12:40:39 +0000 Subject: [PATCH] [CLC-2041] Block signups for Classic PAYG sunset Block new user signups when Classic PAYG sunset is enabled: - Add isUserSignupBlockedBySunset() function in featureflags.ts - Checks if sunset is enabled for the installation - Exempts dedicated installations - Blocks all signups (new users don't have orgs/roles yet) - Add signup blocking in generic-auth-provider.ts callback - Check before createNewUser() is called - Redirect blocked signups to https://app.ona.com/login - Log blocked signup attempts This complements the existing login and workspace operation blocks from CLC-2032, closing the signup path that was previously unblocked. Co-authored-by: Ona --- .../server/src/auth/generic-auth-provider.ts | 8 ++++++++ components/server/src/util/featureflags.ts | 16 ++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/components/server/src/auth/generic-auth-provider.ts b/components/server/src/auth/generic-auth-provider.ts index 22cf40dd013108..f6a08dfb7a0ae4 100644 --- a/components/server/src/auth/generic-auth-provider.ts +++ b/components/server/src/auth/generic-auth-provider.ts @@ -37,6 +37,7 @@ import { SignInJWT } from "./jwt"; import { UserService } from "../user/user-service"; import { reportLoginCompleted } from "../prometheus-metrics"; import { TrustedValue } from "@gitpod/gitpod-protocol/lib/util/scrubbing"; +import { isUserSignupBlockedBySunset } from "../util/featureflags"; /** * This is a generic implementation of OAuth2-based AuthProvider. @@ -431,6 +432,13 @@ export abstract class GenericAuthProvider implements AuthProvider { }; if (VerifyResult.WithIdentity.is(flowContext)) { + // Check if signup is blocked by Classic PAYG sunset + if (await isUserSignupBlockedBySunset("anonymous", this.config.isDedicatedInstallation)) { + log.info(context, `(${strategyName}) Signup blocked by Classic PAYG sunset`, logPayload); + response.redirect(302, "https://app.ona.com/login"); + return; + } + log.info(context, `(${strategyName}) Creating new user and completing login.`, logPayload); // There is no current session, we need to create a new user because this // identity does not yet exist. diff --git a/components/server/src/util/featureflags.ts b/components/server/src/util/featureflags.ts index 67df69bd1e6682..80837abc367039 100644 --- a/components/server/src/util/featureflags.ts +++ b/components/server/src/util/featureflags.ts @@ -85,3 +85,19 @@ export async function isUserLoginBlockedBySunset(user: User, isDedicatedInstalla // Installation-owned users (no organizationId) are blocked return true; } + +export async function isUserSignupBlockedBySunset(userId: string, isDedicatedInstallation: boolean): Promise { + // Dedicated installations are never blocked + if (isDedicatedInstallation) { + return false; + } + + const config = await getClassicPaygSunsetConfig(userId); + + if (!config.enabled) { + return false; + } + + // New users don't have roles/permissions or organizations yet, so we block all signups + return true; +}