mirror of
https://github.com/supabase/supabase.git
synced 2026-10-07 18:35:07 +03:00
* migrate some www components to tokens * consolidate InteractiveShimmerCard to Panel component * update tokens in blog * update tokens in careers page * update tokens in customers section * update tokens in open-source section * update tokens in Realtime page * update tokens in Storage and Vector * update tokens in SplitCodeBlockCarousel * update tokens in PGCharts * remove unused css files * update tokens in Card * update tokens in Pricing page * clean up priving page imports * remove hardcoded theme vars * migrate first half of defaultTheme.ts to tokens * migrate second half of defaultTheme.ts to tokens * improve inputs * add foreground to text-light and text-lighter * add foreground to text-light and text-lighter * migrate docs components with styling tokens * migrate docs components with styling tokens * fix broken Repos component * fix broken classes in blog * update tokens on Button and other components * update tokens on IconPanel * update studio main layout base styling tokens * update tokens across studio, docs and www * update tokens across studio, docs and www * update ui/Panel to styling tokens * update ExampleProject and TableEditorMenu tokens * www vector page tokens * update studio UI tokens * update other studio UI tokens * update more studio UI tokens * change tokens here, change tokens there * finish updating colors with tokens variables * add gui sandbox for theme experimentation * use common package for www, docs and studio and fix Command K tokens * provide light mode default tokens options * fix conflict leftover * update loading line * fix className typo * fix prettier * update themeSandbox preset default values * fix text-background0 * prettier * update warningBanner with warning color * switch all border-border with border-default * improve border-secondary and foreground-muted in light mode * force ring color on toggle * fix button bg color and border-muted light token * fix input bg color * fix dark button hover * fix homepage product card * fix code-hike table header colors * button dark border * remove tabIndex leftover from homepage main ctas --------- Co-authored-by: Kevin Grüneberg <k.grueneberg1994@gmail.com> Co-authored-by: Jonathan Summers-Muir <MildTomato@users.noreply.github.com>
211 lines
7.3 KiB
TypeScript
211 lines
7.3 KiB
TypeScript
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
|
import { observer } from 'mobx-react-lite'
|
|
import { useEffect, useState } from 'react'
|
|
import {
|
|
AlertDescription_Shadcn_,
|
|
AlertTitle_Shadcn_,
|
|
Alert_Shadcn_,
|
|
Button,
|
|
Form,
|
|
IconAlertCircle,
|
|
IconEye,
|
|
IconEyeOff,
|
|
Input,
|
|
InputNumber,
|
|
Radio,
|
|
Toggle,
|
|
} from 'ui'
|
|
import { boolean, number, object, string } from 'yup'
|
|
|
|
import { useParams } from 'common'
|
|
import {
|
|
FormActions,
|
|
FormHeader,
|
|
FormPanel,
|
|
FormSection,
|
|
FormSectionContent,
|
|
FormSectionLabel,
|
|
} from 'components/ui/Forms'
|
|
import { useAuthConfigQuery } from 'data/auth/auth-config-query'
|
|
import { useAuthConfigUpdateMutation } from 'data/auth/auth-config-update-mutation'
|
|
import { useCheckPermissions, useStore } from 'hooks'
|
|
|
|
const schema = object({
|
|
DISABLE_SIGNUP: boolean().required(),
|
|
SITE_URL: string().required('Must have a Site URL'),
|
|
SECURITY_CAPTCHA_ENABLED: boolean().required(),
|
|
SECURITY_CAPTCHA_SECRET: string().when('SECURITY_CAPTCHA_ENABLED', {
|
|
is: true,
|
|
then: string().required('Must have a Captcha secret'),
|
|
}),
|
|
SECURITY_CAPTCHA_PROVIDER: string().when('SECURITY_CAPTCHA_ENABLED', {
|
|
is: true,
|
|
then: string()
|
|
.oneOf(['hcaptcha', 'turnstile'])
|
|
.required('Captcha provider must be either hcaptcha or turnstile'),
|
|
}),
|
|
})
|
|
|
|
const BasicAuthSettingsForm = observer(() => {
|
|
const { ui } = useStore()
|
|
const { ref: projectRef } = useParams()
|
|
const {
|
|
data: authConfig,
|
|
error: authConfigError,
|
|
isLoading,
|
|
isError,
|
|
isSuccess,
|
|
} = useAuthConfigQuery({ projectRef })
|
|
const { mutate: updateAuthConfig, isLoading: isUpdatingConfig } = useAuthConfigUpdateMutation()
|
|
|
|
const formId = 'auth-config-basic-settings'
|
|
const [hidden, setHidden] = useState(true)
|
|
const canUpdateConfig = useCheckPermissions(PermissionAction.UPDATE, 'custom_config_gotrue')
|
|
|
|
const INITIAL_VALUES = {
|
|
DISABLE_SIGNUP: !authConfig?.DISABLE_SIGNUP,
|
|
SITE_URL: authConfig?.SITE_URL,
|
|
SECURITY_CAPTCHA_ENABLED: authConfig?.SECURITY_CAPTCHA_ENABLED || false,
|
|
SECURITY_CAPTCHA_SECRET: authConfig?.SECURITY_CAPTCHA_SECRET || '',
|
|
SECURITY_CAPTCHA_PROVIDER: authConfig?.SECURITY_CAPTCHA_PROVIDER || 'hcaptcha',
|
|
}
|
|
|
|
const onSubmit = (values: any, { resetForm }: any) => {
|
|
const payload = { ...values }
|
|
payload.DISABLE_SIGNUP = !values.DISABLE_SIGNUP
|
|
|
|
updateAuthConfig(
|
|
{ projectRef: projectRef!, config: payload },
|
|
{
|
|
onError: (error) => {
|
|
ui.setNotification({
|
|
category: 'error',
|
|
message: `Failed to update settings: ${error?.message}`,
|
|
})
|
|
},
|
|
onSuccess: () => {
|
|
ui.setNotification({
|
|
category: 'success',
|
|
message: `Successfully updated settings`,
|
|
})
|
|
resetForm({ values: values, initialValues: values })
|
|
},
|
|
}
|
|
)
|
|
}
|
|
|
|
if (isError) {
|
|
return (
|
|
<Alert_Shadcn_ variant="destructive">
|
|
<IconAlertCircle strokeWidth={2} />
|
|
<AlertTitle_Shadcn_>Failed to retrieve auth configuration</AlertTitle_Shadcn_>
|
|
<AlertDescription_Shadcn_>{authConfigError.message}</AlertDescription_Shadcn_>
|
|
</Alert_Shadcn_>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<Form id={formId} initialValues={INITIAL_VALUES} onSubmit={onSubmit} validationSchema={schema}>
|
|
{({ handleReset, resetForm, values, initialValues }: any) => {
|
|
const hasChanges = JSON.stringify(values) !== JSON.stringify(initialValues)
|
|
|
|
// Form is reset once remote data is loaded in store
|
|
useEffect(() => {
|
|
if (isSuccess) resetForm({ values: INITIAL_VALUES, initialValues: INITIAL_VALUES })
|
|
}, [isSuccess])
|
|
|
|
return (
|
|
<>
|
|
<FormHeader
|
|
title="Auth Settings"
|
|
description="Configure security and user session settings."
|
|
/>
|
|
<FormPanel
|
|
disabled={true}
|
|
footer={
|
|
<div className="flex py-4 px-8">
|
|
<FormActions
|
|
form={formId}
|
|
isSubmitting={isUpdatingConfig}
|
|
hasChanges={hasChanges}
|
|
handleReset={handleReset}
|
|
disabled={!canUpdateConfig}
|
|
helper={
|
|
!canUpdateConfig
|
|
? 'You need additional permissions to update authentication settings'
|
|
: undefined
|
|
}
|
|
/>
|
|
</div>
|
|
}
|
|
>
|
|
<FormSection header={<FormSectionLabel>User Signups</FormSectionLabel>}>
|
|
<FormSectionContent loading={isLoading}>
|
|
<Toggle
|
|
id="DISABLE_SIGNUP"
|
|
size="small"
|
|
label="Allow new users to sign up"
|
|
layout="flex"
|
|
descriptionText="If this is disabled, new users will not be able to sign up to your application."
|
|
disabled={!canUpdateConfig}
|
|
/>
|
|
</FormSectionContent>
|
|
</FormSection>
|
|
<div className="border-t border-muted"></div>
|
|
<FormSection header={<FormSectionLabel>Bot and Abuse Protection</FormSectionLabel>}>
|
|
<FormSectionContent loading={isLoading}>
|
|
<Toggle
|
|
id="SECURITY_CAPTCHA_ENABLED"
|
|
size="small"
|
|
label="Enable Captcha protection"
|
|
layout="flex"
|
|
descriptionText="Protect authentication endpoints from bots and abuse."
|
|
disabled={!canUpdateConfig}
|
|
/>
|
|
{values.SECURITY_CAPTCHA_ENABLED && (
|
|
<>
|
|
<Radio.Group
|
|
id="SECURITY_CAPTCHA_PROVIDER"
|
|
name="SECURITY_CAPTCHA_PROVIDER"
|
|
label="Choose Captcha Provider"
|
|
>
|
|
<Radio
|
|
label="hCaptcha"
|
|
value="hcaptcha"
|
|
checked={values.SECURITY_CAPTCHA_PROVIDER === 'hcaptcha'}
|
|
/>
|
|
<Radio
|
|
label="Turnstile by Cloudflare"
|
|
value="turnstile"
|
|
checked={values.SECURITY_CAPTCHA_PROVIDER === 'turnstile'}
|
|
/>
|
|
</Radio.Group>
|
|
<Input
|
|
id="SECURITY_CAPTCHA_SECRET"
|
|
type={hidden ? 'password' : 'text'}
|
|
size="small"
|
|
label="Captcha secret"
|
|
descriptionText="Obtain this secret from the provider."
|
|
disabled={!canUpdateConfig}
|
|
actions={
|
|
<Button
|
|
icon={hidden ? <IconEye /> : <IconEyeOff />}
|
|
type="default"
|
|
onClick={() => setHidden(!hidden)}
|
|
/>
|
|
}
|
|
/>
|
|
</>
|
|
)}
|
|
</FormSectionContent>
|
|
</FormSection>
|
|
</FormPanel>
|
|
</>
|
|
)
|
|
}}
|
|
</Form>
|
|
)
|
|
})
|
|
|
|
export default BasicAuthSettingsForm
|