11
apps/builder/src/components/logos/KeycloakLogo.tsx
Normal file
11
apps/builder/src/components/logos/KeycloakLogo.tsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { IconProps, Icon } from '@chakra-ui/react'
|
||||||
|
|
||||||
|
export const KeycloackLogo = (props: IconProps) => (
|
||||||
|
<Icon viewBox="0 0 1024 1024" {...props}>
|
||||||
|
<circle cx="512" cy="512" r="512" fill="#008aaa" />
|
||||||
|
<path
|
||||||
|
d="M786.2 395.5h-80.6c-1.5 0-3-.8-3.7-2.1l-64.7-112.2c-.8-1.3-2.2-2.1-3.8-2.1h-264c-1.5 0-3 .8-3.7 2.1l-67.3 116.4-64.8 112.2c-.7 1.3-.7 2.9 0 4.3l64.8 112.2 67.2 116.5c.7 1.3 2.2 2.2 3.7 2.1h264.1c1.5 0 3-.8 3.8-2.1L702 630.6c.7-1.3 2.2-2.2 3.7-2.1h80.6c2.7 0 4.8-2.2 4.8-4.8V400.4c-.1-2.7-2.3-4.9-4.9-4.9zM477.5 630.6l-20.3 35c-.3.5-.8 1-1.3 1.3-.6.3-1.2.5-1.9.5h-40.3c-1.4 0-2.7-.7-3.3-2l-60.1-104.3-5.9-10.3-21.6-36.9c-.3-.5-.5-1.1-.4-1.8 0-.6.2-1.3.5-1.8l21.7-37.6 65.9-114c.7-1.2 2-2 3.3-2H454c.7 0 1.4.2 2.1.5.5.3 1 .7 1.3 1.3l20.3 35.2c.6 1.2.5 2.7-.2 3.8l-65.1 112.8c-.3.5-.4 1.1-.4 1.6 0 .6.2 1.1.4 1.6l65.1 112.7c.9 1.5.8 3.1 0 4.4zm202.1-116.7L658 550.8l-5.9 10.3L592 665.4c-.7 1.2-1.9 2-3.3 2h-40.3c-.7 0-1.3-.2-1.9-.5-.5-.3-1-.7-1.3-1.3l-20.3-35c-.9-1.3-.9-2.9-.1-4.2l65.1-112.7c.3-.5.4-1.1.4-1.6 0-.6-.2-1.1-.4-1.6l-65.1-112.8c-.7-1.2-.8-2.6-.2-3.8l20.3-35.2c.3-.5.8-1 1.3-1.3.6-.4 1.3-.5 2.1-.5h40.4c1.4 0 2.7.7 3.3 2l65.9 114 21.7 37.6c.3.6.5 1.2.5 1.8 0 .4-.2 1-.5 1.6z"
|
||||||
|
fill="#fff"
|
||||||
|
/>
|
||||||
|
</Icon>
|
||||||
|
)
|
@ -16,6 +16,7 @@ import { AzureAdLogo } from '@/components/logos/AzureAdLogo'
|
|||||||
import { FacebookLogo } from '@/components/logos/FacebookLogo'
|
import { FacebookLogo } from '@/components/logos/FacebookLogo'
|
||||||
import { GitlabLogo } from '@/components/logos/GitlabLogo'
|
import { GitlabLogo } from '@/components/logos/GitlabLogo'
|
||||||
import { useTranslate } from '@tolgee/react'
|
import { useTranslate } from '@tolgee/react'
|
||||||
|
import { KeycloackLogo } from '@/components/logos/KeycloakLogo'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
providers:
|
providers:
|
||||||
@ -52,6 +53,8 @@ export const SocialLoginButtons = ({ providers }: Props) => {
|
|||||||
|
|
||||||
const handleCustomOAuthClick = () => handleSignIn('custom-oauth')
|
const handleCustomOAuthClick = () => handleSignIn('custom-oauth')
|
||||||
|
|
||||||
|
const handleKeyCloackClick = () => handleSignIn('keycloak')
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack>
|
<Stack>
|
||||||
{providers?.github && (
|
{providers?.github && (
|
||||||
@ -142,6 +145,20 @@ export const SocialLoginButtons = ({ providers }: Props) => {
|
|||||||
})}
|
})}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
{providers?.keycloak && (
|
||||||
|
<Button
|
||||||
|
leftIcon={<KeycloackLogo />}
|
||||||
|
onClick={handleKeyCloackClick}
|
||||||
|
data-testid="keycloak"
|
||||||
|
isLoading={
|
||||||
|
['loading', 'authenticated'].includes(status) ||
|
||||||
|
authLoading === 'keycloak'
|
||||||
|
}
|
||||||
|
variant="outline"
|
||||||
|
>
|
||||||
|
{t('auth.socialLogin.keycloakButton.label')}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
</Stack>
|
</Stack>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -60,6 +60,7 @@
|
|||||||
"auth.socialLogin.githubButton.label": "Mit GitHub fortfahren",
|
"auth.socialLogin.githubButton.label": "Mit GitHub fortfahren",
|
||||||
"auth.socialLogin.gitlabButton.label": "Mit {gitlabProviderName} fortfahren",
|
"auth.socialLogin.gitlabButton.label": "Mit {gitlabProviderName} fortfahren",
|
||||||
"auth.socialLogin.googleButton.label": "Mit Google fortfahren",
|
"auth.socialLogin.googleButton.label": "Mit Google fortfahren",
|
||||||
|
"auth.socialLogin.keycloakButton.label": "Mit Keycloak fortfahren",
|
||||||
"back": "Zurück",
|
"back": "Zurück",
|
||||||
"billing.billingPortalButton.label": "Abrechnungsportal",
|
"billing.billingPortalButton.label": "Abrechnungsportal",
|
||||||
"billing.contribution.link": "Erfahre mehr.",
|
"billing.contribution.link": "Erfahre mehr.",
|
||||||
|
@ -61,6 +61,7 @@
|
|||||||
"auth.socialLogin.githubButton.label": "Continue with GitHub",
|
"auth.socialLogin.githubButton.label": "Continue with GitHub",
|
||||||
"auth.socialLogin.gitlabButton.label": "Continue with {gitlabProviderName}",
|
"auth.socialLogin.gitlabButton.label": "Continue with {gitlabProviderName}",
|
||||||
"auth.socialLogin.googleButton.label": "Continue with Google",
|
"auth.socialLogin.googleButton.label": "Continue with Google",
|
||||||
|
"auth.socialLogin.keycloakButton.label": "Continue with Keycloak",
|
||||||
"back": "Back",
|
"back": "Back",
|
||||||
"billing.billingPortalButton.label": "Billing portal",
|
"billing.billingPortalButton.label": "Billing portal",
|
||||||
"billing.contribution.link": "Learn more.",
|
"billing.contribution.link": "Learn more.",
|
||||||
|
@ -60,6 +60,7 @@
|
|||||||
"auth.socialLogin.githubButton.label": "Continuar con GitHub",
|
"auth.socialLogin.githubButton.label": "Continuar con GitHub",
|
||||||
"auth.socialLogin.gitlabButton.label": "Continuar con {gitlabProviderName}",
|
"auth.socialLogin.gitlabButton.label": "Continuar con {gitlabProviderName}",
|
||||||
"auth.socialLogin.googleButton.label": "Continuar con Google",
|
"auth.socialLogin.googleButton.label": "Continuar con Google",
|
||||||
|
"auth.socialLogin.keycloakButton.label": "Continuar con Keycloak",
|
||||||
"back": "Volver",
|
"back": "Volver",
|
||||||
"billing.billingPortalButton.label": "Portal de facturación",
|
"billing.billingPortalButton.label": "Portal de facturación",
|
||||||
"billing.contribution.link": "Más información.",
|
"billing.contribution.link": "Más información.",
|
||||||
|
@ -61,6 +61,7 @@
|
|||||||
"auth.socialLogin.githubButton.label": "Continuer avec GitHub",
|
"auth.socialLogin.githubButton.label": "Continuer avec GitHub",
|
||||||
"auth.socialLogin.gitlabButton.label": "Continuer avec {gitlabProviderName}",
|
"auth.socialLogin.gitlabButton.label": "Continuer avec {gitlabProviderName}",
|
||||||
"auth.socialLogin.googleButton.label": "Continuer avec Google",
|
"auth.socialLogin.googleButton.label": "Continuer avec Google",
|
||||||
|
"auth.socialLogin.keycloakButton.label": "Continuer avec Keycloak",
|
||||||
"back": "Retour",
|
"back": "Retour",
|
||||||
"billing.billingPortalButton.label": "Portail de facturation",
|
"billing.billingPortalButton.label": "Portail de facturation",
|
||||||
"billing.contribution.link": "En savoir plus.",
|
"billing.contribution.link": "En savoir plus.",
|
||||||
|
@ -61,6 +61,7 @@
|
|||||||
"auth.socialLogin.githubButton.label": "Continua con GitHub",
|
"auth.socialLogin.githubButton.label": "Continua con GitHub",
|
||||||
"auth.socialLogin.gitlabButton.label": "Continuare con {gitlabProviderName}",
|
"auth.socialLogin.gitlabButton.label": "Continuare con {gitlabProviderName}",
|
||||||
"auth.socialLogin.googleButton.label": "Continua con Google",
|
"auth.socialLogin.googleButton.label": "Continua con Google",
|
||||||
|
"auth.socialLogin.keycloakButton.label": "Continua con Keycloak",
|
||||||
"back": "Indietro",
|
"back": "Indietro",
|
||||||
"billing.billingPortalButton.label": "Portale di fatturazione",
|
"billing.billingPortalButton.label": "Portale di fatturazione",
|
||||||
"billing.contribution.link": "Per saperne di più.",
|
"billing.contribution.link": "Per saperne di più.",
|
||||||
|
@ -61,6 +61,7 @@
|
|||||||
"auth.socialLogin.githubButton.label": "Continuar com GitHub",
|
"auth.socialLogin.githubButton.label": "Continuar com GitHub",
|
||||||
"auth.socialLogin.gitlabButton.label": "Continuar com {gitlabProviderName}",
|
"auth.socialLogin.gitlabButton.label": "Continuar com {gitlabProviderName}",
|
||||||
"auth.socialLogin.googleButton.label": "Continuar com Google",
|
"auth.socialLogin.googleButton.label": "Continuar com Google",
|
||||||
|
"auth.socialLogin.keycloakButton.label": "Continuar com Keycloak",
|
||||||
"back": "Voltar",
|
"back": "Voltar",
|
||||||
"billing.billingPortalButton.label": "Portal de cobrança",
|
"billing.billingPortalButton.label": "Portal de cobrança",
|
||||||
"billing.contribution.link": "Saiba mais.",
|
"billing.contribution.link": "Saiba mais.",
|
||||||
|
@ -61,6 +61,7 @@
|
|||||||
"auth.socialLogin.githubButton.label": "Continuar com GitHub",
|
"auth.socialLogin.githubButton.label": "Continuar com GitHub",
|
||||||
"auth.socialLogin.gitlabButton.label": "Continuar com {gitlabProviderName}",
|
"auth.socialLogin.gitlabButton.label": "Continuar com {gitlabProviderName}",
|
||||||
"auth.socialLogin.googleButton.label": "Continuar com Google",
|
"auth.socialLogin.googleButton.label": "Continuar com Google",
|
||||||
|
"auth.socialLogin.keycloakButton.label": "Continuar com Keycloak",
|
||||||
"back": "Voltar",
|
"back": "Voltar",
|
||||||
"billing.billingPortalButton.label": "Portal de facturação",
|
"billing.billingPortalButton.label": "Portal de facturação",
|
||||||
"billing.contribution.link": "Saiba mais.",
|
"billing.contribution.link": "Saiba mais.",
|
||||||
|
@ -60,6 +60,7 @@
|
|||||||
"auth.socialLogin.githubButton.label": "Continuați cu GitHub",
|
"auth.socialLogin.githubButton.label": "Continuați cu GitHub",
|
||||||
"auth.socialLogin.gitlabButton.label": "Continuați cu {customProviderName}",
|
"auth.socialLogin.gitlabButton.label": "Continuați cu {customProviderName}",
|
||||||
"auth.socialLogin.googleButton.label": "Continuați cu Google",
|
"auth.socialLogin.googleButton.label": "Continuați cu Google",
|
||||||
|
"auth.socialLogin.keycloakButton.label": "Continuați cu Keycloak",
|
||||||
"back": "Înapoi",
|
"back": "Înapoi",
|
||||||
"billing.billingPortalButton.label": "Portalul de facturare",
|
"billing.billingPortalButton.label": "Portalul de facturare",
|
||||||
"billing.contribution.link": "Află mai multe.",
|
"billing.contribution.link": "Află mai multe.",
|
||||||
|
@ -5,6 +5,7 @@ import GitlabProvider from 'next-auth/providers/gitlab'
|
|||||||
import GoogleProvider from 'next-auth/providers/google'
|
import GoogleProvider from 'next-auth/providers/google'
|
||||||
import FacebookProvider from 'next-auth/providers/facebook'
|
import FacebookProvider from 'next-auth/providers/facebook'
|
||||||
import AzureADProvider from 'next-auth/providers/azure-ad'
|
import AzureADProvider from 'next-auth/providers/azure-ad'
|
||||||
|
import KeycloakProvider from 'next-auth/providers/keycloak'
|
||||||
import prisma from '@typebot.io/lib/prisma'
|
import prisma from '@typebot.io/lib/prisma'
|
||||||
import { Provider } from 'next-auth/providers'
|
import { Provider } from 'next-auth/providers'
|
||||||
import { NextApiRequest, NextApiResponse } from 'next'
|
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) {
|
if (env.CUSTOM_OAUTH_WELL_KNOWN_URL) {
|
||||||
providers.push({
|
providers.push({
|
||||||
id: 'custom-oauth',
|
id: 'custom-oauth',
|
||||||
|
@ -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_CLIENT_SECRET | | Application client secret. Can be obtained from Azure Portal. |
|
||||||
| AZURE_AD_TENANT_ID | | Azure Tenant ID |
|
| 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)
|
## Custom OAuth Provider (Auth)
|
||||||
|
|
||||||
| Parameter | Default | Description |
|
| Parameter | Default | Description |
|
||||||
|
10
packages/env/env.ts
vendored
10
packages/env/env.ts
vendored
@ -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({
|
export const env = createEnv({
|
||||||
server: {
|
server: {
|
||||||
...baseEnv.server,
|
...baseEnv.server,
|
||||||
@ -422,6 +431,7 @@ export const env = createEnv({
|
|||||||
...customOAuthEnv.server,
|
...customOAuthEnv.server,
|
||||||
...sentryEnv.server,
|
...sentryEnv.server,
|
||||||
...telemetryEnv.server,
|
...telemetryEnv.server,
|
||||||
|
...keycloakEnv.server
|
||||||
},
|
},
|
||||||
client: {
|
client: {
|
||||||
...baseEnv.client,
|
...baseEnv.client,
|
||||||
|
Reference in New Issue
Block a user