diff --git a/apps/builder/src/components/logos/KeycloakLogo.tsx b/apps/builder/src/components/logos/KeycloakLogo.tsx new file mode 100644 index 00000000000..bfa68202f0e --- /dev/null +++ b/apps/builder/src/components/logos/KeycloakLogo.tsx @@ -0,0 +1,11 @@ +import { IconProps, Icon } from '@chakra-ui/react' + +export const KeycloackLogo = (props: IconProps) => ( + + + + +) diff --git a/apps/builder/src/features/auth/components/SocialLoginButtons.tsx b/apps/builder/src/features/auth/components/SocialLoginButtons.tsx index 662398c8502..db627552a8b 100644 --- a/apps/builder/src/features/auth/components/SocialLoginButtons.tsx +++ b/apps/builder/src/features/auth/components/SocialLoginButtons.tsx @@ -16,6 +16,7 @@ import { AzureAdLogo } from '@/components/logos/AzureAdLogo' import { FacebookLogo } from '@/components/logos/FacebookLogo' import { GitlabLogo } from '@/components/logos/GitlabLogo' import { useTranslate } from '@tolgee/react' +import { KeycloackLogo } from '@/components/logos/KeycloakLogo' type Props = { providers: @@ -52,6 +53,8 @@ export const SocialLoginButtons = ({ providers }: Props) => { const handleCustomOAuthClick = () => handleSignIn('custom-oauth') + const handleKeyCloackClick = () => handleSignIn('keycloak') + return ( {providers?.github && ( @@ -142,6 +145,20 @@ export const SocialLoginButtons = ({ providers }: Props) => { })} )} + {providers?.keycloak && ( + + )} ) } diff --git a/apps/builder/src/i18n/de.json b/apps/builder/src/i18n/de.json index 6a91e876df2..b910a7606b8 100644 --- a/apps/builder/src/i18n/de.json +++ b/apps/builder/src/i18n/de.json @@ -60,6 +60,7 @@ "auth.socialLogin.githubButton.label": "Mit GitHub fortfahren", "auth.socialLogin.gitlabButton.label": "Mit {gitlabProviderName} fortfahren", "auth.socialLogin.googleButton.label": "Mit Google fortfahren", + "auth.socialLogin.keycloakButton.label": "Mit Keycloak fortfahren", "back": "Zurück", "billing.billingPortalButton.label": "Abrechnungsportal", "billing.contribution.link": "Erfahre mehr.", diff --git a/apps/builder/src/i18n/en.json b/apps/builder/src/i18n/en.json index 1d8e3ff093e..212ad7c1627 100644 --- a/apps/builder/src/i18n/en.json +++ b/apps/builder/src/i18n/en.json @@ -61,6 +61,7 @@ "auth.socialLogin.githubButton.label": "Continue with GitHub", "auth.socialLogin.gitlabButton.label": "Continue with {gitlabProviderName}", "auth.socialLogin.googleButton.label": "Continue with Google", + "auth.socialLogin.keycloakButton.label": "Continue with Keycloak", "back": "Back", "billing.billingPortalButton.label": "Billing portal", "billing.contribution.link": "Learn more.", diff --git a/apps/builder/src/i18n/es.json b/apps/builder/src/i18n/es.json index 0365655dcff..8c81d5f21b5 100644 --- a/apps/builder/src/i18n/es.json +++ b/apps/builder/src/i18n/es.json @@ -60,6 +60,7 @@ "auth.socialLogin.githubButton.label": "Continuar con GitHub", "auth.socialLogin.gitlabButton.label": "Continuar con {gitlabProviderName}", "auth.socialLogin.googleButton.label": "Continuar con Google", + "auth.socialLogin.keycloakButton.label": "Continuar con Keycloak", "back": "Volver", "billing.billingPortalButton.label": "Portal de facturación", "billing.contribution.link": "Más información.", diff --git a/apps/builder/src/i18n/fr.json b/apps/builder/src/i18n/fr.json index 8ab91662283..e670c1d591c 100644 --- a/apps/builder/src/i18n/fr.json +++ b/apps/builder/src/i18n/fr.json @@ -61,6 +61,7 @@ "auth.socialLogin.githubButton.label": "Continuer avec GitHub", "auth.socialLogin.gitlabButton.label": "Continuer avec {gitlabProviderName}", "auth.socialLogin.googleButton.label": "Continuer avec Google", + "auth.socialLogin.keycloakButton.label": "Continuer avec Keycloak", "back": "Retour", "billing.billingPortalButton.label": "Portail de facturation", "billing.contribution.link": "En savoir plus.", diff --git a/apps/builder/src/i18n/it.json b/apps/builder/src/i18n/it.json index e3ff66229da..406cff90e4d 100644 --- a/apps/builder/src/i18n/it.json +++ b/apps/builder/src/i18n/it.json @@ -61,6 +61,7 @@ "auth.socialLogin.githubButton.label": "Continua con GitHub", "auth.socialLogin.gitlabButton.label": "Continuare con {gitlabProviderName}", "auth.socialLogin.googleButton.label": "Continua con Google", + "auth.socialLogin.keycloakButton.label": "Continua con Keycloak", "back": "Indietro", "billing.billingPortalButton.label": "Portale di fatturazione", "billing.contribution.link": "Per saperne di più.", diff --git a/apps/builder/src/i18n/pt-BR.json b/apps/builder/src/i18n/pt-BR.json index db048e89a34..3c331443583 100644 --- a/apps/builder/src/i18n/pt-BR.json +++ b/apps/builder/src/i18n/pt-BR.json @@ -61,6 +61,7 @@ "auth.socialLogin.githubButton.label": "Continuar com GitHub", "auth.socialLogin.gitlabButton.label": "Continuar com {gitlabProviderName}", "auth.socialLogin.googleButton.label": "Continuar com Google", + "auth.socialLogin.keycloakButton.label": "Continuar com Keycloak", "back": "Voltar", "billing.billingPortalButton.label": "Portal de cobrança", "billing.contribution.link": "Saiba mais.", diff --git a/apps/builder/src/i18n/pt.json b/apps/builder/src/i18n/pt.json index 6878de5d545..f13001412a4 100644 --- a/apps/builder/src/i18n/pt.json +++ b/apps/builder/src/i18n/pt.json @@ -61,6 +61,7 @@ "auth.socialLogin.githubButton.label": "Continuar com GitHub", "auth.socialLogin.gitlabButton.label": "Continuar com {gitlabProviderName}", "auth.socialLogin.googleButton.label": "Continuar com Google", + "auth.socialLogin.keycloakButton.label": "Continuar com Keycloak", "back": "Voltar", "billing.billingPortalButton.label": "Portal de facturação", "billing.contribution.link": "Saiba mais.", diff --git a/apps/builder/src/i18n/ro.json b/apps/builder/src/i18n/ro.json index 8929a0e9617..25354f8596b 100644 --- a/apps/builder/src/i18n/ro.json +++ b/apps/builder/src/i18n/ro.json @@ -60,6 +60,7 @@ "auth.socialLogin.githubButton.label": "Continuați cu GitHub", "auth.socialLogin.gitlabButton.label": "Continuați cu {customProviderName}", "auth.socialLogin.googleButton.label": "Continuați cu Google", + "auth.socialLogin.keycloakButton.label": "Continuați cu Keycloak", "back": "Înapoi", "billing.billingPortalButton.label": "Portalul de facturare", "billing.contribution.link": "Află mai multe.", diff --git a/apps/builder/src/pages/api/auth/[...nextauth].ts b/apps/builder/src/pages/api/auth/[...nextauth].ts index f7f145200e8..09451fb318e 100644 --- a/apps/builder/src/pages/api/auth/[...nextauth].ts +++ b/apps/builder/src/pages/api/auth/[...nextauth].ts @@ -5,6 +5,7 @@ import GitlabProvider from 'next-auth/providers/gitlab' import GoogleProvider from 'next-auth/providers/google' import FacebookProvider from 'next-auth/providers/facebook' import AzureADProvider from 'next-auth/providers/azure-ad' +import KeycloakProvider from 'next-auth/providers/keycloak' import prisma from '@typebot.io/lib/prisma' import { Provider } from 'next-auth/providers' import { NextApiRequest, NextApiResponse } from 'next' @@ -102,6 +103,21 @@ if ( ) } +if ( + env.KEYCLOAK_CLIENT_ID && + env.KEYCLOAK_BASE_URL && + env.KEYCLOAK_CLIENT_SECRET && + env.KEYCLOAK_REALM +) { + providers.push( + KeycloakProvider({ + clientId: env.KEYCLOAK_CLIENT_ID, + clientSecret: env.KEYCLOAK_CLIENT_SECRET, + issuer: `${env.KEYCLOAK_BASE_URL}/${env.KEYCLOAK_REALM}`, + }) + ) +} + if (env.CUSTOM_OAUTH_WELL_KNOWN_URL) { providers.push({ id: 'custom-oauth', diff --git a/apps/docs/self-hosting/configuration.mdx b/apps/docs/self-hosting/configuration.mdx index 79187b53cdd..af1a9730cd3 100644 --- a/apps/docs/self-hosting/configuration.mdx +++ b/apps/docs/self-hosting/configuration.mdx @@ -169,6 +169,20 @@ The Authorization callback URL should be `$NEXTAUTH_URL/api/auth/callback/azure- | AZURE_AD_CLIENT_SECRET | | Application client secret. Can be obtained from Azure Portal. | | AZURE_AD_TENANT_ID | | Azure Tenant ID | +## Keycloak (Auth) + +Used for authenticating with Keycloak. +Follow the official Keycloak guide for creating OAuth2 applications [here](https://www.keycloak.org/). + +| Parameter | Default | Description | +| ------------------------ | ------------------ | ------------------------------------------------------------------------------------ | +| KEYCLOAK_CLIENT_ID | | Application client ID. | +| KEYCLOAK_CLIENT_SECRET | | Application secret | +| KEYCLOAK_REALM | | Your Keycloak Realm | +| KEYCLOAK_BASE_URL | | Base URL of the Keycloak instance | + + + ## Custom OAuth Provider (Auth) | Parameter | Default | Description | diff --git a/packages/env/env.ts b/packages/env/env.ts index e68a087a44a..df36c2d45a2 100644 --- a/packages/env/env.ts +++ b/packages/env/env.ts @@ -404,6 +404,15 @@ const tolgeeEnv = { }, } +const keycloakEnv = { + server: { + KEYCLOAK_CLIENT_ID: z.string().min(1).optional(), + KEYCLOAK_CLIENT_SECRET: z.string().min(1).optional(), + KEYCLOAK_REALM: z.string().min(1).optional(), + KEYCLOAK_BASE_URL: z.string().url().optional(), + }, +} + export const env = createEnv({ server: { ...baseEnv.server, @@ -422,6 +431,7 @@ export const env = createEnv({ ...customOAuthEnv.server, ...sentryEnv.server, ...telemetryEnv.server, + ...keycloakEnv.server }, client: { ...baseEnv.client,