From 608dbdae70e272d1ed16dcca5dea35a33f7aae66 Mon Sep 17 00:00:00 2001 From: initstring <26131150+initstring@users.noreply.github.com> Date: Sat, 17 Jan 2026 19:45:42 +1100 Subject: [PATCH 1/2] Add GitHub and GitLab SSO support --- .env.example-dev | 5 +++++ deploy/docker/.env.example-prod | 5 +++++ docs/installation.md | 8 +++---- src/app/(public-routes)/auth/signin/page.tsx | 4 ++++ src/env.ts | 12 ++++++++++ src/features/shared/auth/sign-in-page.tsx | 10 ++++++++- src/server/auth/config.ts | 23 +++++++++++++++++++- 7 files changed, 61 insertions(+), 6 deletions(-) diff --git a/.env.example-dev b/.env.example-dev index a8cf9bb..47d888b 100644 --- a/.env.example-dev +++ b/.env.example-dev @@ -20,6 +20,11 @@ AUTH_TRUST_HOST=true # SSO Configuration #GOOGLE_CLIENT_ID= #GOOGLE_CLIENT_SECRET= +#GITHUB_CLIENT_ID= +#GITHUB_CLIENT_SECRET= +#GITLAB_CLIENT_ID= +#GITLAB_CLIENT_SECRET= +#GITLAB_ISSUER= #KEYCLOAK_CLIENT_ID= #KEYCLOAK_CLIENT_SECRET= #KEYCLOAK_ISSUER= diff --git a/deploy/docker/.env.example-prod b/deploy/docker/.env.example-prod index 15038b7..61597d2 100644 --- a/deploy/docker/.env.example-prod +++ b/deploy/docker/.env.example-prod @@ -15,6 +15,11 @@ ENABLE_DEMO_MODE=false # SSO Configuration #GOOGLE_CLIENT_ID= #GOOGLE_CLIENT_SECRET= +#GITHUB_CLIENT_ID= +#GITHUB_CLIENT_SECRET= +#GITLAB_CLIENT_ID= +#GITLAB_CLIENT_SECRET= +#GITLAB_ISSUER= #KEYCLOAK_CLIENT_ID= #KEYCLOAK_CLIENT_SECRET= #KEYCLOAK_ISSUER= diff --git a/docs/installation.md b/docs/installation.md index a83030e..f749f99 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -26,15 +26,15 @@ Minimum values to edit: ### Choose authentication mode -RTAP supports SSO or a demo login button. Supported SSO providers today are Google, Keycloak, and Okta. If you need another provider, open an issue and we can add it. +RTAP supports SSO or a demo login button. Supported SSO providers today are Google, GitHub, GitLab, Keycloak, and Okta. If you need another provider, open an issue and we can add it. -- **SSO (recommended):** configure your provider's details (like client ID/secret + issuer when required) using the variable names provided in the .env file. +- **SSO (recommended):** configure your provider's details (client ID/secret, plus issuer for Keycloak/Okta/GitLab self-managed) using the variable names provided in the .env file. - **Demo mode:** set `ENABLE_DEMO_MODE=true`. This exposes a “Sign in as Demo Admin” button and **anyone with access to the sign-in page can log in without an account**. Use only for isolated testing or demos. -For Google SSO, configure the following in the Google Cloud console: +For any SSO provider, configure the following in your identity provider console: - Authorized JavaScript origins: matches `AUTH_URL` from `.env`. -- Authorized redirect URIs: `AUTH_URL` + `/api/auth/callback/google`. +- Authorized redirect URIs: `AUTH_URL` + `/api/auth/callback/` (for example, `/api/auth/callback/github`). ### Start the containers diff --git a/src/app/(public-routes)/auth/signin/page.tsx b/src/app/(public-routes)/auth/signin/page.tsx index 24edb43..9ed6450 100644 --- a/src/app/(public-routes)/auth/signin/page.tsx +++ b/src/app/(public-routes)/auth/signin/page.tsx @@ -12,12 +12,16 @@ export default async function SignInPage(props: { searchParams?: Promise<{ callb const { callbackUrl = "/", error } = (await props.searchParams) ?? {}; const demoEnabled = env.ENABLE_DEMO_MODE === "true"; const googleEnabled = Boolean(env.GOOGLE_CLIENT_ID && env.GOOGLE_CLIENT_SECRET); + const githubEnabled = Boolean(env.GITHUB_CLIENT_ID && env.GITHUB_CLIENT_SECRET); + const gitlabEnabled = Boolean(env.GITLAB_CLIENT_ID && env.GITLAB_CLIENT_SECRET); const keycloakEnabled = Boolean(env.KEYCLOAK_CLIENT_ID && env.KEYCLOAK_CLIENT_SECRET && env.KEYCLOAK_ISSUER); const oktaEnabled = Boolean(env.OKTA_CLIENT_ID && env.OKTA_CLIENT_SECRET && env.OKTA_ISSUER); return ( = [ { id: "google", label: "Continue with Google" }, + { id: "github", label: "Continue with GitHub" }, + { id: "gitlab", label: "Continue with GitLab" }, { id: "keycloak", label: "Continue with Keycloak" }, { id: "okta", label: "Continue with Okta" }, ]; export default function SignInPageClient({ googleEnabled, + githubEnabled, + gitlabEnabled, keycloakEnabled, oktaEnabled, demoEnabled, @@ -79,6 +85,8 @@ export default function SignInPageClient({ const oauthEnabled: Record = { google: googleEnabled, + github: githubEnabled, + gitlab: gitlabEnabled, keycloak: keycloakEnabled, okta: oktaEnabled, }; diff --git a/src/server/auth/config.ts b/src/server/auth/config.ts index 834cef8..2ec3fce 100644 --- a/src/server/auth/config.ts +++ b/src/server/auth/config.ts @@ -1,6 +1,8 @@ import { type DefaultSession, type NextAuthConfig } from "next-auth"; import type { Adapter } from "next-auth/adapters"; import type { JWT as NextAuthJWT } from "next-auth/jwt"; +import GitHubProvider from "next-auth/providers/github"; +import GitLabProvider from "next-auth/providers/gitlab"; import GoogleProvider from "next-auth/providers/google"; import KeycloakProvider from "next-auth/providers/keycloak"; import OktaProvider from "next-auth/providers/okta"; @@ -42,7 +44,7 @@ declare module "@auth/core/adapters" { type AugmentedJWT = NextAuthJWT & { role?: UserRole }; const demoModeEnabled = env.ENABLE_DEMO_MODE === "true"; -const oauthProviders = new Set(["google", "keycloak", "okta"]); +const oauthProviders = new Set(["google", "github", "gitlab", "keycloak", "okta"]); const isRecord = (value: unknown): value is Record => typeof value === "object" && value !== null; @@ -205,6 +207,25 @@ export const authConfig = { }), ] : []), + ...(process.env.GITHUB_CLIENT_ID && process.env.GITHUB_CLIENT_SECRET + ? [ + GitHubProvider({ + clientId: process.env.GITHUB_CLIENT_ID, + clientSecret: process.env.GITHUB_CLIENT_SECRET, + allowDangerousEmailAccountLinking: true, + }), + ] + : []), + ...(process.env.GITLAB_CLIENT_ID && process.env.GITLAB_CLIENT_SECRET + ? [ + GitLabProvider({ + clientId: process.env.GITLAB_CLIENT_ID, + clientSecret: process.env.GITLAB_CLIENT_SECRET, + issuer: process.env.GITLAB_ISSUER, + allowDangerousEmailAccountLinking: true, + }), + ] + : []), ...(process.env.KEYCLOAK_CLIENT_ID && process.env.KEYCLOAK_CLIENT_SECRET && process.env.KEYCLOAK_ISSUER ? [ KeycloakProvider({ From d30cf24a26763d6cc6f79cd16a93e9839a7e8283 Mon Sep 17 00:00:00 2001 From: initstring <26131150+initstring@users.noreply.github.com> Date: Sat, 17 Jan 2026 20:00:37 +1100 Subject: [PATCH 2/2] Remove GitLab issuer configuration --- .env.example-dev | 1 - deploy/docker/.env.example-prod | 1 - docs/installation.md | 2 +- src/env.ts | 2 -- src/server/auth/config.ts | 1 - 5 files changed, 1 insertion(+), 6 deletions(-) diff --git a/.env.example-dev b/.env.example-dev index 47d888b..2f3229d 100644 --- a/.env.example-dev +++ b/.env.example-dev @@ -24,7 +24,6 @@ AUTH_TRUST_HOST=true #GITHUB_CLIENT_SECRET= #GITLAB_CLIENT_ID= #GITLAB_CLIENT_SECRET= -#GITLAB_ISSUER= #KEYCLOAK_CLIENT_ID= #KEYCLOAK_CLIENT_SECRET= #KEYCLOAK_ISSUER= diff --git a/deploy/docker/.env.example-prod b/deploy/docker/.env.example-prod index 61597d2..9d3bd39 100644 --- a/deploy/docker/.env.example-prod +++ b/deploy/docker/.env.example-prod @@ -19,7 +19,6 @@ ENABLE_DEMO_MODE=false #GITHUB_CLIENT_SECRET= #GITLAB_CLIENT_ID= #GITLAB_CLIENT_SECRET= -#GITLAB_ISSUER= #KEYCLOAK_CLIENT_ID= #KEYCLOAK_CLIENT_SECRET= #KEYCLOAK_ISSUER= diff --git a/docs/installation.md b/docs/installation.md index f749f99..f356344 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -28,7 +28,7 @@ Minimum values to edit: RTAP supports SSO or a demo login button. Supported SSO providers today are Google, GitHub, GitLab, Keycloak, and Okta. If you need another provider, open an issue and we can add it. -- **SSO (recommended):** configure your provider's details (client ID/secret, plus issuer for Keycloak/Okta/GitLab self-managed) using the variable names provided in the .env file. +- **SSO (recommended):** configure your provider's details (client ID/secret, plus issuer for Keycloak/Okta) using the variable names provided in the .env file. - **Demo mode:** set `ENABLE_DEMO_MODE=true`. This exposes a “Sign in as Demo Admin” button and **anyone with access to the sign-in page can log in without an account**. Use only for isolated testing or demos. For any SSO provider, configure the following in your identity provider console: diff --git a/src/env.ts b/src/env.ts index a80e0bf..4c79c2d 100644 --- a/src/env.ts +++ b/src/env.ts @@ -31,7 +31,6 @@ export const env = createEnv({ // Optional: GitLab OAuth client credentials (registers provider when present) GITLAB_CLIENT_ID: z.string().optional(), GITLAB_CLIENT_SECRET: z.string().optional(), - GITLAB_ISSUER: z.string().optional(), // Optional: Keycloak OAuth client credentials (registers provider when present) KEYCLOAK_CLIENT_ID: z.string().optional(), KEYCLOAK_CLIENT_SECRET: z.string().optional(), @@ -68,7 +67,6 @@ export const env = createEnv({ GITHUB_CLIENT_SECRET: process.env.GITHUB_CLIENT_SECRET, GITLAB_CLIENT_ID: process.env.GITLAB_CLIENT_ID, GITLAB_CLIENT_SECRET: process.env.GITLAB_CLIENT_SECRET, - GITLAB_ISSUER: process.env.GITLAB_ISSUER, KEYCLOAK_CLIENT_ID: process.env.KEYCLOAK_CLIENT_ID, KEYCLOAK_CLIENT_SECRET: process.env.KEYCLOAK_CLIENT_SECRET, KEYCLOAK_ISSUER: process.env.KEYCLOAK_ISSUER, diff --git a/src/server/auth/config.ts b/src/server/auth/config.ts index 2ec3fce..7768196 100644 --- a/src/server/auth/config.ts +++ b/src/server/auth/config.ts @@ -221,7 +221,6 @@ export const authConfig = { GitLabProvider({ clientId: process.env.GITLAB_CLIENT_ID, clientSecret: process.env.GITLAB_CLIENT_SECRET, - issuer: process.env.GITLAB_ISSUER, allowDangerousEmailAccountLinking: true, }), ]