| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 |
- import { Check } from 'lucide-react'
- import Image from 'next/image'
- import { Badge, Button } from 'ui'
- import { AWS_IDP_REGIONS } from './AwsRegionSelector'
- import {
- getIntegrationType,
- getIntegrationTypeIcon,
- getIntegrationTypeLabel,
- INTEGRATION_TYPES,
- } from './ThirdPartyAuthForm.utils'
- import { ThirdPartyAuthIntegration } from '@/data/third-party-auth/integrations-query'
- import { DOCS_URL } from '@/lib/constants'
- interface IntegrationCardProps {
- integration: ThirdPartyAuthIntegration
- canUpdateConfig: boolean
- onDelete: () => void
- }
- export const getIntegrationTypeDescription = (type: INTEGRATION_TYPES) => {
- switch (type) {
- case 'firebase':
- return (
- <>
- Allow users to use Briven with Firebase project. You'll need to setup RLS policies for
- all tables that you want to access with a Firebase JWT token. Additionally, you'll need to
- add custom code to set the <code>authenticated</code> role to all your present and future
- users. You can read more in the{' '}
- <a
- className="hover:decoration-brand underline hover:text-foreground transition"
- href={`${DOCS_URL}/guides/auth`}
- >
- documentation
- </a>
- .
- </>
- )
- case 'auth0':
- return (
- <>
- Allow users to use Briven with Auth0 project. Additional setup may be required. You can
- read more in the{' '}
- <a
- className="hover:decoration-brand underline hover:text-foreground transition"
- href={`${DOCS_URL}/guides/auth`}
- >
- documentation
- </a>
- .
- </>
- )
- case 'awsCognito':
- return (
- <>
- Allow users to use Briven with an Amazon Cognito. Additional setup may be required. You
- can read more in the{' '}
- <a
- className="hover:decoration-brand underline hover:text-foreground transition"
- href={`${DOCS_URL}/guides/auth/third-party/aws-cognito`}
- >
- documentation
- </a>
- .
- </>
- )
- case 'clerk':
- return (
- <>
- Allow users to use Briven with Clerk. Additional setup may be required. You can read
- more in the{' '}
- <a
- className="hover:decoration-brand underline hover:text-foreground transition"
- href={`${DOCS_URL}/guides/auth/third-party/clerk`}
- >
- documentation
- </a>
- .
- </>
- )
- case 'workos':
- return (
- <>
- Allow users to use Briven with WorkOS. Additional setup may be required. You can read
- more in the{' '}
- <a
- className="hover:decoration-brand underline hover:text-foreground transition"
- href={`${DOCS_URL}/guides/auth/third-party/workos`}
- >
- documentation
- </a>
- .
- </>
- )
- case 'custom':
- default:
- return 'Custom'
- }
- }
- export const IntegrationTypeContent = ({
- type,
- integration,
- }: {
- type: INTEGRATION_TYPES
- integration: ThirdPartyAuthIntegration
- }) => {
- switch (type) {
- case 'firebase': {
- const projectName =
- integration.oidc_issuer_url?.replace('https://securetoken.google.com/', '') || ''
- return (
- <div className="text-sm flex flex-row gap-x-4">
- <span className="text-foreground-light w-36">Firebase Project ID</span>
- <span className="text-foreground">{projectName}</span>
- </div>
- )
- }
- case 'auth0':
- const domainName =
- integration.oidc_issuer_url?.replace('https://', '').replace('.auth0.com', '') || ''
- return (
- <div className="text-sm flex flex-row gap-x-4">
- <span className="text-foreground-light w-36">Auth0 Domain Name</span>
- <span className="text-foreground">{domainName}</span>
- </div>
- )
- case 'awsCognito': {
- const region =
- integration.oidc_issuer_url?.split('.').filter((s) => AWS_IDP_REGIONS.includes(s))[0] || ''
- const userPoolId =
- integration.oidc_issuer_url?.split('/').filter((s) => s.startsWith(region || ''))[0] || ''
- return (
- <div className="text-sm flex flex-col gap-y-2">
- <div className="flex flex-row gap-x-4">
- <span className="text-foreground-light w-36">Region</span>
- <span className="text-foreground">{region}</span>
- </div>
- <div className="flex flex-row gap-x-4">
- <span className="text-foreground-light w-36">User Pool ID</span>
- <span className="text-foreground">{userPoolId}</span>
- </div>
- </div>
- )
- }
- case 'clerk':
- return (
- <div className="text-sm flex flex-row gap-x-4">
- <span className="text-foreground-light w-36">Domain</span>
- <span className="text-foreground">{integration?.oidc_issuer_url ?? ''}</span>
- </div>
- )
- case 'workos':
- return (
- <div className="text-sm flex flex-row gap-x-4">
- <span className="text-foreground-light w-36">Issuer URL</span>
- <span className="text-foreground">{integration?.oidc_issuer_url ?? ''}</span>
- </div>
- )
- case 'custom':
- default:
- return <>Custom</>
- }
- }
- export const IntegrationCard = ({
- integration,
- canUpdateConfig,
- onDelete,
- }: IntegrationCardProps) => {
- let type = getIntegrationType(integration)
- if (type === 'custom') {
- return null
- }
- return (
- <>
- <div className="bg-surface-100 border overflow-hidden shadow-sm px-5 py-4 flex flex-row first:rounded-t-md last:rounded-b-md space-x-4">
- <div className="py-1">
- <Image src={getIntegrationTypeIcon(type)} width={21} height={21} alt={`${type} icon`} />
- </div>
- <div className="flex min-w-0 flex-1 flex-col gap-y-4 overflow-y-auto">
- <div className="text-sm flex flex-col">
- <span className="text-foreground">{getIntegrationTypeLabel(type)}</span>
- <div className="text-foreground-lighter">{getIntegrationTypeDescription(type)}</div>
- </div>
- <IntegrationTypeContent type={type} integration={integration} />
- <div>
- {/* TODO: this should be a configure integration where it would show the sheet and the user can disable or delete the integration
- but there's no "edit integration" endpoing for now. */}
- <Button type="danger" disabled={!canUpdateConfig} onClick={() => onDelete()}>
- Delete integration
- </Button>
- </div>
- </div>
- <div className="shrink-0">
- {true ? (
- <Badge className="space-x-1" variant="success">
- <div className="h-3.5 w-3.5 bg-brand rounded-full flex justify-center items-center">
- <Check className="h-2 w-2 text-background-overlay" strokeWidth={6} />
- </div>
- <span>Enabled</span>
- </Badge>
- ) : (
- <Badge variant="warning">
- <span>Disabled</span>
- </Badge>
- )}
- </div>
- </div>
- </>
- )
- }
|