mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
Swap useCheckPermissions with useAsyncCheckProjectPermissions Part 5 (#38552)
Update auth pages
This commit is contained in:
1 parent
8fb604c95b
commit
e955f69e2d
20 files changed
+423
-411
No files matched your search
+1
-3
@@ -41,7 +41,7 @@ const schema = object({
|
||||
SITE_URL: string().required('Must have a Site URL'),
|
||||
})
|
||||
|
||||
const BasicAuthSettingsForm = () => {
|
||||
export const BasicAuthSettingsForm = () => {
|
||||
const { ref: projectRef } = useParams()
|
||||
const showManualLinking = useIsFeatureEnabled('authentication:show_manual_linking')
|
||||
|
||||
@@ -333,5 +333,3 @@ const BasicAuthSettingsForm = () => {
|
||||
</ScaffoldSection>
|
||||
)
|
||||
}
|
||||
|
||||
export default BasicAuthSettingsForm
|
||||
@@ -7,7 +7,7 @@ import { TEMPLATES_SCHEMAS } from '../AuthTemplatesValidation'
|
||||
import EmailRateLimitsAlert from '../EmailRateLimitsAlert'
|
||||
import TemplateEditor from './TemplateEditor'
|
||||
|
||||
const EmailTemplates = () => {
|
||||
export const EmailTemplates = () => {
|
||||
const { ref: projectRef } = useParams()
|
||||
const {
|
||||
data: authConfig,
|
||||
@@ -68,5 +68,3 @@ const EmailTemplates = () => {
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default EmailTemplates
|
||||
@@ -3,7 +3,7 @@ import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useForm } from 'react-hook-form'
|
||||
import { toast } from 'sonner'
|
||||
import { number, object, string, boolean } from 'yup'
|
||||
import { boolean, number, object, string } from 'yup'
|
||||
|
||||
import { useParams } from 'common'
|
||||
import { ScaffoldSection, ScaffoldSectionTitle } from 'components/layouts/Scaffold'
|
||||
@@ -35,8 +35,8 @@ import {
|
||||
Switch,
|
||||
WarningIcon,
|
||||
} from 'ui'
|
||||
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
|
||||
import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal'
|
||||
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
|
||||
|
||||
function determineMFAStatus(verifyEnabled: boolean, enrollEnabled: boolean) {
|
||||
return verifyEnabled ? (enrollEnabled ? 'Enabled' : 'Verify Enabled') : 'Disabled'
|
||||
@@ -84,7 +84,7 @@ const securitySchema = object({
|
||||
MFA_ALLOW_LOW_AAL: boolean().required(),
|
||||
})
|
||||
|
||||
const MfaAuthSettingsForm = () => {
|
||||
export const MfaAuthSettingsForm = () => {
|
||||
const { ref: projectRef } = useParams()
|
||||
const { data: authConfig, error: authConfigError, isError } = useAuthConfigQuery({ projectRef })
|
||||
const { mutate: updateAuthConfig } = useAuthConfigUpdateMutation()
|
||||
@@ -572,5 +572,3 @@ const MfaAuthSettingsForm = () => {
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default MfaAuthSettingsForm
|
||||
+1
-3
@@ -67,7 +67,7 @@ const schema = object({
|
||||
PASSWORD_HIBP_ENABLED: boolean(),
|
||||
})
|
||||
|
||||
const ProtectionAuthSettingsForm = () => {
|
||||
export const ProtectionAuthSettingsForm = () => {
|
||||
const { ref: projectRef } = useParams()
|
||||
const { data: authConfig, error: authConfigError, isError } = useAuthConfigQuery({ projectRef })
|
||||
const { mutate: updateAuthConfig, isLoading: isUpdatingConfig } = useAuthConfigUpdateMutation({
|
||||
@@ -287,5 +287,3 @@ const ProtectionAuthSettingsForm = () => {
|
||||
</ScaffoldSection>
|
||||
)
|
||||
}
|
||||
|
||||
export default ProtectionAuthSettingsForm
|
||||
@@ -30,7 +30,7 @@ import {
|
||||
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
|
||||
import { isSmtpEnabled } from '../SmtpForm/SmtpForm.utils'
|
||||
|
||||
const RateLimits = () => {
|
||||
export const RateLimits = () => {
|
||||
const { ref: projectRef } = useParams()
|
||||
const { can: canUpdateConfig } = useAsyncCheckProjectPermissions(
|
||||
PermissionAction.UPDATE,
|
||||
@@ -505,5 +505,3 @@ const RateLimits = () => {
|
||||
</ScaffoldSection>
|
||||
)
|
||||
}
|
||||
|
||||
export default RateLimits
|
||||
+1
-3
@@ -59,7 +59,7 @@ const UserSessionsSchema = z.object({
|
||||
SESSIONS_SINGLE_PER_USER: z.boolean(),
|
||||
})
|
||||
|
||||
const SessionsAuthSettingsForm = () => {
|
||||
export const SessionsAuthSettingsForm = () => {
|
||||
const { ref: projectRef } = useParams()
|
||||
const { data: authConfig, error: authConfigError, isError } = useAuthConfigQuery({ projectRef })
|
||||
const { mutate: updateAuthConfig } = useAuthConfigUpdateMutation()
|
||||
@@ -370,5 +370,3 @@ const SessionsAuthSettingsForm = () => {
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default SessionsAuthSettingsForm
|
||||
@@ -8,7 +8,7 @@ import { toast } from 'sonner'
|
||||
import * as yup from 'yup'
|
||||
|
||||
import { useParams } from 'common'
|
||||
import { ScaffoldContainer, ScaffoldSection } from 'components/layouts/Scaffold'
|
||||
import { ScaffoldSection } from 'components/layouts/Scaffold'
|
||||
import NoPermission from 'components/ui/NoPermission'
|
||||
import { useAuthConfigQuery } from 'data/auth/auth-config-query'
|
||||
import { useAuthConfigUpdateMutation } from 'data/auth/auth-config-update-mutation'
|
||||
@@ -45,7 +45,7 @@ interface SmtpFormValues {
|
||||
ENABLE_SMTP: boolean
|
||||
}
|
||||
|
||||
const SmtpForm = () => {
|
||||
export const SmtpForm = () => {
|
||||
const { ref: projectRef } = useParams()
|
||||
const { data: authConfig, error: authConfigError, isError } = useAuthConfigQuery({ projectRef })
|
||||
const { mutate: updateAuthConfig, isLoading: isUpdatingConfig } = useAuthConfigUpdateMutation()
|
||||
@@ -192,285 +192,280 @@ const SmtpForm = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<ScaffoldContainer>
|
||||
<ScaffoldSection isFullWidth>
|
||||
<Form_Shadcn_ {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)}>
|
||||
<Card>
|
||||
<CardContent>
|
||||
<FormField_Shadcn_
|
||||
control={form.control}
|
||||
name="ENABLE_SMTP"
|
||||
render={({ field }) => (
|
||||
<FormItemLayout
|
||||
layout="flex-row-reverse"
|
||||
label="Enable Custom SMTP"
|
||||
description={
|
||||
<p className="max-w-full prose text-sm text-foreground-lighter">
|
||||
Emails will be sent using your custom SMTP provider. Email rate limits can
|
||||
be adjusted{' '}
|
||||
<Link
|
||||
className="underline"
|
||||
href={`/project/${projectRef}/auth/rate-limits`}
|
||||
>
|
||||
here
|
||||
</Link>
|
||||
.
|
||||
</p>
|
||||
}
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<Switch
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
disabled={!canUpdateConfig}
|
||||
/>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
)}
|
||||
/>
|
||||
|
||||
{enableSmtp && !isSmtpEnabled(form.getValues() as any) && (
|
||||
<div className="mt-4">
|
||||
<Alert_Shadcn_ variant="warning">
|
||||
<AlertTriangle strokeWidth={2} />
|
||||
<AlertTitle_Shadcn_>All fields below must be filled</AlertTitle_Shadcn_>
|
||||
<AlertDescription_Shadcn_>
|
||||
The following fields must be filled before custom SMTP can be properly
|
||||
enabled
|
||||
</AlertDescription_Shadcn_>
|
||||
</Alert_Shadcn_>
|
||||
</div>
|
||||
<ScaffoldSection isFullWidth>
|
||||
<Form_Shadcn_ {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)}>
|
||||
<Card>
|
||||
<CardContent>
|
||||
<FormField_Shadcn_
|
||||
control={form.control}
|
||||
name="ENABLE_SMTP"
|
||||
render={({ field }) => (
|
||||
<FormItemLayout
|
||||
layout="flex-row-reverse"
|
||||
label="Enable Custom SMTP"
|
||||
description={
|
||||
<p className="max-w-full prose text-sm text-foreground-lighter">
|
||||
Emails will be sent using your custom SMTP provider. Email rate limits can
|
||||
be adjusted{' '}
|
||||
<Link
|
||||
className="underline"
|
||||
href={`/project/${projectRef}/auth/rate-limits`}
|
||||
>
|
||||
here
|
||||
</Link>
|
||||
.
|
||||
</p>
|
||||
}
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<Switch
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
disabled={!canUpdateConfig}
|
||||
/>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
)}
|
||||
</CardContent>
|
||||
/>
|
||||
|
||||
{enableSmtp && (
|
||||
<>
|
||||
<CardContent className="py-6">
|
||||
<div className="grid grid-cols-12 gap-6">
|
||||
<div className="col-span-4">
|
||||
<h3 className="text-sm mb-1">Sender details</h3>
|
||||
<p className="text-sm text-foreground-lighter">
|
||||
Configure the sender information for your emails.
|
||||
</p>
|
||||
</div>
|
||||
<div className="col-span-8 space-y-4">
|
||||
<FormField_Shadcn_
|
||||
control={form.control}
|
||||
name="SMTP_ADMIN_EMAIL"
|
||||
render={({ field }) => (
|
||||
<FormItemLayout
|
||||
label="Sender email"
|
||||
description="This is the email address the emails are sent from"
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<Input_Shadcn_
|
||||
{...field}
|
||||
placeholder="noreply@yourdomain.com"
|
||||
disabled={!canUpdateConfig}
|
||||
/>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
)}
|
||||
/>
|
||||
{enableSmtp && !isSmtpEnabled(form.getValues() as any) && (
|
||||
<div className="mt-4">
|
||||
<Alert_Shadcn_ variant="warning">
|
||||
<AlertTriangle strokeWidth={2} />
|
||||
<AlertTitle_Shadcn_>All fields below must be filled</AlertTitle_Shadcn_>
|
||||
<AlertDescription_Shadcn_>
|
||||
The following fields must be filled before custom SMTP can be properly enabled
|
||||
</AlertDescription_Shadcn_>
|
||||
</Alert_Shadcn_>
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
|
||||
<FormField_Shadcn_
|
||||
control={form.control}
|
||||
name="SMTP_SENDER_NAME"
|
||||
render={({ field }) => (
|
||||
<FormItemLayout
|
||||
label="Sender name"
|
||||
description="Name displayed in the recipient's inbox"
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<Input_Shadcn_
|
||||
{...field}
|
||||
placeholder="The name shown on the email"
|
||||
disabled={!canUpdateConfig}
|
||||
/>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
{enableSmtp && (
|
||||
<>
|
||||
<CardContent className="py-6">
|
||||
<div className="grid grid-cols-12 gap-6">
|
||||
<div className="col-span-4">
|
||||
<h3 className="text-sm mb-1">Sender details</h3>
|
||||
<p className="text-sm text-foreground-lighter">
|
||||
Configure the sender information for your emails.
|
||||
</p>
|
||||
</div>
|
||||
</CardContent>
|
||||
|
||||
<CardContent className="py-6">
|
||||
<div className="grid grid-cols-12 gap-6">
|
||||
<div className="col-span-4">
|
||||
<h3 className="text-sm mb-1">SMTP Provider Settings</h3>
|
||||
<p className="text-sm text-foreground-lighter">
|
||||
Your SMTP Credentials will always be encrypted in our database.
|
||||
</p>
|
||||
</div>
|
||||
<div className="col-span-8 space-y-4">
|
||||
{form.watch('SMTP_HOST')?.endsWith('.gmail.com') && (
|
||||
<Alert_Shadcn_ variant="warning" className="mb-4">
|
||||
<AlertTriangle strokeWidth={2} />
|
||||
<AlertTitle_Shadcn_>Check your SMTP provider</AlertTitle_Shadcn_>
|
||||
<AlertDescription_Shadcn_>
|
||||
Not all SMTP providers are designed for the email sending required by
|
||||
Supabase Auth. It looks like the SMTP provider you entered is designed
|
||||
for sending personal email messages and not for sending transactional
|
||||
messages. Although you can ignore this warning, email deliverability
|
||||
may be impacted.
|
||||
</AlertDescription_Shadcn_>
|
||||
</Alert_Shadcn_>
|
||||
<div className="col-span-8 space-y-4">
|
||||
<FormField_Shadcn_
|
||||
control={form.control}
|
||||
name="SMTP_ADMIN_EMAIL"
|
||||
render={({ field }) => (
|
||||
<FormItemLayout
|
||||
label="Sender email"
|
||||
description="This is the email address the emails are sent from"
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<Input_Shadcn_
|
||||
{...field}
|
||||
placeholder="noreply@yourdomain.com"
|
||||
disabled={!canUpdateConfig}
|
||||
/>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField_Shadcn_
|
||||
control={form.control}
|
||||
name="SMTP_HOST"
|
||||
render={({ field }) => (
|
||||
<FormItemLayout
|
||||
label="Host"
|
||||
description="Hostname or IP address of your SMTP server."
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<Input_Shadcn_
|
||||
{...field}
|
||||
placeholder="your.smtp.host.com"
|
||||
disabled={!canUpdateConfig}
|
||||
/>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
)}
|
||||
/>
|
||||
<FormField_Shadcn_
|
||||
control={form.control}
|
||||
name="SMTP_SENDER_NAME"
|
||||
render={({ field }) => (
|
||||
<FormItemLayout
|
||||
label="Sender name"
|
||||
description="Name displayed in the recipient's inbox"
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<Input_Shadcn_
|
||||
{...field}
|
||||
placeholder="The name shown on the email"
|
||||
disabled={!canUpdateConfig}
|
||||
/>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
|
||||
<FormField_Shadcn_
|
||||
control={form.control}
|
||||
name="SMTP_PORT"
|
||||
render={({ field }) => (
|
||||
<FormItemLayout
|
||||
label="Port number"
|
||||
description={
|
||||
<>
|
||||
<span className="block">
|
||||
Port used by your SMTP server. Common ports include 25, 465, and
|
||||
587.{' '}
|
||||
</span>
|
||||
<span className="mt-2 block">
|
||||
Avoid using port 25 as modern SMTP email clients shouldn't use
|
||||
this port, it is traditionally blocked by residential ISPs and
|
||||
Cloud Hosting Providers, to curb the amount of spam.
|
||||
</span>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<CardContent className="py-6">
|
||||
<div className="grid grid-cols-12 gap-6">
|
||||
<div className="col-span-4">
|
||||
<h3 className="text-sm mb-1">SMTP Provider Settings</h3>
|
||||
<p className="text-sm text-foreground-lighter">
|
||||
Your SMTP Credentials will always be encrypted in our database.
|
||||
</p>
|
||||
</div>
|
||||
<div className="col-span-8 space-y-4">
|
||||
{form.watch('SMTP_HOST')?.endsWith('.gmail.com') && (
|
||||
<Alert_Shadcn_ variant="warning" className="mb-4">
|
||||
<AlertTriangle strokeWidth={2} />
|
||||
<AlertTitle_Shadcn_>Check your SMTP provider</AlertTitle_Shadcn_>
|
||||
<AlertDescription_Shadcn_>
|
||||
Not all SMTP providers are designed for the email sending required by
|
||||
Supabase Auth. It looks like the SMTP provider you entered is designed
|
||||
for sending personal email messages and not for sending transactional
|
||||
messages. Although you can ignore this warning, email deliverability may
|
||||
be impacted.
|
||||
</AlertDescription_Shadcn_>
|
||||
</Alert_Shadcn_>
|
||||
)}
|
||||
|
||||
<FormField_Shadcn_
|
||||
control={form.control}
|
||||
name="SMTP_HOST"
|
||||
render={({ field }) => (
|
||||
<FormItemLayout
|
||||
label="Host"
|
||||
description="Hostname or IP address of your SMTP server."
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<Input_Shadcn_
|
||||
{...field}
|
||||
placeholder="your.smtp.host.com"
|
||||
disabled={!canUpdateConfig}
|
||||
/>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField_Shadcn_
|
||||
control={form.control}
|
||||
name="SMTP_PORT"
|
||||
render={({ field }) => (
|
||||
<FormItemLayout
|
||||
label="Port number"
|
||||
description={
|
||||
<>
|
||||
<span className="block">
|
||||
Port used by your SMTP server. Common ports include 25, 465, and
|
||||
587.{' '}
|
||||
</span>
|
||||
<span className="mt-2 block">
|
||||
Avoid using port 25 as modern SMTP email clients shouldn't use
|
||||
this port, it is traditionally blocked by residential ISPs and
|
||||
Cloud Hosting Providers, to curb the amount of spam.
|
||||
</span>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<Input_Shadcn_
|
||||
type="number"
|
||||
value={field.value}
|
||||
onChange={(e) => field.onChange(Number(e.target.value))}
|
||||
placeholder="587"
|
||||
disabled={!canUpdateConfig}
|
||||
/>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField_Shadcn_
|
||||
control={form.control}
|
||||
name="SMTP_MAX_FREQUENCY"
|
||||
render={({ field }) => (
|
||||
<FormItemLayout
|
||||
label="Minimum interval between emails being sent"
|
||||
description="How long between each email can a new email be sent via your SMTP server."
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<PrePostTab postTab="seconds">
|
||||
<Input_Shadcn_
|
||||
type="number"
|
||||
value={field.value}
|
||||
onChange={(e) => field.onChange(Number(e.target.value))}
|
||||
placeholder="587"
|
||||
disabled={!canUpdateConfig}
|
||||
/>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
)}
|
||||
/>
|
||||
</PrePostTab>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField_Shadcn_
|
||||
control={form.control}
|
||||
name="SMTP_MAX_FREQUENCY"
|
||||
render={({ field }) => (
|
||||
<FormItemLayout
|
||||
label="Minimum interval between emails being sent"
|
||||
description="How long between each email can a new email be sent via your SMTP server."
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<PrePostTab postTab="seconds">
|
||||
<Input_Shadcn_
|
||||
type="number"
|
||||
value={field.value}
|
||||
onChange={(e) => field.onChange(Number(e.target.value))}
|
||||
disabled={!canUpdateConfig}
|
||||
<FormField_Shadcn_
|
||||
control={form.control}
|
||||
name="SMTP_USER"
|
||||
render={({ field }) => (
|
||||
<FormItemLayout
|
||||
label="Username"
|
||||
description="Username for your SMTP server"
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<Input_Shadcn_
|
||||
{...field}
|
||||
placeholder="SMTP Username"
|
||||
disabled={!canUpdateConfig}
|
||||
/>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField_Shadcn_
|
||||
control={form.control}
|
||||
name="SMTP_PASS"
|
||||
render={({ field }) => (
|
||||
<FormItemLayout
|
||||
label="Password"
|
||||
description="For security reasons, the password is write-only. Once saved, it cannot be retrieved or displayed."
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<PrePostTab
|
||||
postTab={
|
||||
<Button
|
||||
type="text"
|
||||
className="p-0"
|
||||
onClick={() => setHidden(!hidden)}
|
||||
icon={hidden ? <Eye /> : <EyeOff />}
|
||||
/>
|
||||
</PrePostTab>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField_Shadcn_
|
||||
control={form.control}
|
||||
name="SMTP_USER"
|
||||
render={({ field }) => (
|
||||
<FormItemLayout
|
||||
label="Username"
|
||||
description="Username for your SMTP server"
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
}
|
||||
>
|
||||
<Input_Shadcn_
|
||||
{...field}
|
||||
placeholder="SMTP Username"
|
||||
type={hidden ? 'password' : 'text'}
|
||||
placeholder={
|
||||
authConfig?.SMTP_PASS === null ? 'SMTP Password' : '••••••••'
|
||||
}
|
||||
disabled={!canUpdateConfig}
|
||||
/>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField_Shadcn_
|
||||
control={form.control}
|
||||
name="SMTP_PASS"
|
||||
render={({ field }) => (
|
||||
<FormItemLayout
|
||||
label="Password"
|
||||
description="For security reasons, the password is write-only. Once saved, it cannot be retrieved or displayed."
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<PrePostTab
|
||||
postTab={
|
||||
<Button
|
||||
type="text"
|
||||
className="p-0"
|
||||
onClick={() => setHidden(!hidden)}
|
||||
icon={hidden ? <Eye /> : <EyeOff />}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Input_Shadcn_
|
||||
{...field}
|
||||
type={hidden ? 'password' : 'text'}
|
||||
placeholder={
|
||||
authConfig?.SMTP_PASS === null ? 'SMTP Password' : '••••••••'
|
||||
}
|
||||
disabled={!canUpdateConfig}
|
||||
/>
|
||||
</PrePostTab>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</PrePostTab>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</CardContent>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</CardContent>
|
||||
</>
|
||||
)}
|
||||
|
||||
<CardFooter className="justify-end space-x-2">
|
||||
{form.formState.isDirty && (
|
||||
<Button type="default" onClick={() => form.reset()}>
|
||||
Cancel
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
type="primary"
|
||||
htmlType="submit"
|
||||
loading={isUpdatingConfig}
|
||||
disabled={!canUpdateConfig || !form.formState.isDirty}
|
||||
>
|
||||
Save changes
|
||||
<CardFooter className="justify-end space-x-2">
|
||||
{form.formState.isDirty && (
|
||||
<Button type="default" onClick={() => form.reset()}>
|
||||
Cancel
|
||||
</Button>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
</form>
|
||||
</Form_Shadcn_>
|
||||
</ScaffoldSection>
|
||||
</ScaffoldContainer>
|
||||
)}
|
||||
<Button
|
||||
type="primary"
|
||||
htmlType="submit"
|
||||
loading={isUpdatingConfig}
|
||||
disabled={!canUpdateConfig || !form.formState.isDirty}
|
||||
>
|
||||
Save changes
|
||||
</Button>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
</form>
|
||||
</Form_Shadcn_>
|
||||
</ScaffoldSection>
|
||||
)
|
||||
}
|
||||
|
||||
export default SmtpForm
|
||||
@@ -1,9 +0,0 @@
|
||||
export { AdvancedAuthSettingsForm } from './AdvancedAuthSettingsForm'
|
||||
export { AuthProvidersForm } from './AuthProvidersForm/AuthProvidersForm'
|
||||
export { default as BasicAuthSettingsForm } from './BasicAuthSettingsForm/BasicAuthSettingsForm'
|
||||
export { default as EmailTemplates } from './EmailTemplates/EmailTemplates'
|
||||
export { default as MfaAuthSettingsForm } from './MfaAuthSettingsForm/MfaAuthSettingsForm'
|
||||
export { default as ProtectionAuthSettingsForm } from './ProtectionAuthSettingsForm/ProtectionAuthSettingsForm'
|
||||
export { default as SessionsAuthSettingsForm } from './SessionsAuthSettingsForm/SessionsAuthSettingsForm'
|
||||
export { default as SmtpForm } from './SmtpForm/SmtpForm'
|
||||
export { ThirdPartyAuthForm } from './ThirdPartyAuthForm'
|
||||
@@ -9,7 +9,7 @@ import { ScaffoldContainer, ScaffoldSection } from 'components/layouts/Scaffold'
|
||||
import NoPermission from 'components/ui/NoPermission'
|
||||
import { GenericSkeletonLoader } from 'components/ui/ShimmeringLoader'
|
||||
import { UnknownInterface } from 'components/ui/UnknownInterface'
|
||||
import { useCheckPermissions, usePermissionsLoaded } from 'hooks/misc/useCheckPermissions'
|
||||
import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions'
|
||||
import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled'
|
||||
import type { NextPageWithLayout } from 'types'
|
||||
|
||||
@@ -17,35 +17,37 @@ const AdvancedPage: NextPageWithLayout = () => {
|
||||
const { ref } = useParams()
|
||||
const showAdvanced = useIsFeatureEnabled('authentication:advanced')
|
||||
|
||||
const isPermissionsLoaded = usePermissionsLoaded()
|
||||
const canReadAuthSettings = useCheckPermissions(PermissionAction.READ, 'custom_config_gotrue')
|
||||
const { can: canReadAuthSettings, isSuccess: isPermissionsLoaded } =
|
||||
useAsyncCheckProjectPermissions(PermissionAction.READ, 'custom_config_gotrue')
|
||||
|
||||
if (!showAdvanced) {
|
||||
return <UnknownInterface urlBack={`/project/${ref}/auth/users`} />
|
||||
}
|
||||
|
||||
if (isPermissionsLoaded && !canReadAuthSettings) {
|
||||
return <NoPermission isFullPage resourceText="access your project's authentication settings" />
|
||||
}
|
||||
|
||||
return (
|
||||
<PageLayout title="Advanced" subtitle="Configure advanced authentication server settings">
|
||||
{isPermissionsLoaded && !canReadAuthSettings ? (
|
||||
<NoPermission isFullPage resourceText="access your project's authentication settings" />
|
||||
<ScaffoldContainer>
|
||||
{!isPermissionsLoaded ? (
|
||||
<ScaffoldSection isFullWidth>
|
||||
<GenericSkeletonLoader />
|
||||
</ScaffoldSection>
|
||||
) : (
|
||||
<ScaffoldContainer>
|
||||
{!isPermissionsLoaded ? (
|
||||
<ScaffoldSection isFullWidth>
|
||||
<GenericSkeletonLoader />
|
||||
</ScaffoldSection>
|
||||
) : (
|
||||
<AdvancedAuthSettingsForm />
|
||||
)}
|
||||
</ScaffoldContainer>
|
||||
<AdvancedAuthSettingsForm />
|
||||
)}
|
||||
</PageLayout>
|
||||
</ScaffoldContainer>
|
||||
)
|
||||
}
|
||||
|
||||
AdvancedPage.getLayout = (page) => (
|
||||
<DefaultLayout>
|
||||
<AuthLayout>{page}</AuthLayout>
|
||||
<AuthLayout>
|
||||
<PageLayout title="Advanced" subtitle="Configure advanced authentication server settings">
|
||||
{page}
|
||||
</PageLayout>
|
||||
</AuthLayout>
|
||||
</DefaultLayout>
|
||||
)
|
||||
|
||||
|
||||
@@ -4,15 +4,16 @@ import { HooksListing } from 'components/interfaces/Auth/Hooks/HooksListing'
|
||||
import AuthLayout from 'components/layouts/AuthLayout/AuthLayout'
|
||||
import DefaultLayout from 'components/layouts/DefaultLayout'
|
||||
import { PageLayout } from 'components/layouts/PageLayout/PageLayout'
|
||||
import { ScaffoldContainer } from 'components/layouts/Scaffold'
|
||||
import NoPermission from 'components/ui/NoPermission'
|
||||
import { useCheckPermissions, usePermissionsLoaded } from 'hooks/misc/useCheckPermissions'
|
||||
import type { NextPageWithLayout } from 'types'
|
||||
import { ScaffoldContainer, ScaffoldSection } from 'components/layouts/Scaffold'
|
||||
import { DocsButton } from 'components/ui/DocsButton'
|
||||
import NoPermission from 'components/ui/NoPermission'
|
||||
import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions'
|
||||
import type { NextPageWithLayout } from 'types'
|
||||
import { GenericSkeletonLoader } from 'ui-patterns'
|
||||
|
||||
const Hooks: NextPageWithLayout = () => {
|
||||
const canReadAuthSettings = useCheckPermissions(PermissionAction.READ, 'custom_config_gotrue')
|
||||
const isPermissionsLoaded = usePermissionsLoaded()
|
||||
const { can: canReadAuthSettings, isSuccess: isPermissionsLoaded } =
|
||||
useAsyncCheckProjectPermissions(PermissionAction.READ, 'custom_config_gotrue')
|
||||
|
||||
if (isPermissionsLoaded && !canReadAuthSettings) {
|
||||
return <NoPermission isFullPage resourceText="access your project's auth hooks" />
|
||||
@@ -20,7 +21,13 @@ const Hooks: NextPageWithLayout = () => {
|
||||
|
||||
return (
|
||||
<ScaffoldContainer>
|
||||
<HooksListing />
|
||||
{!isPermissionsLoaded ? (
|
||||
<ScaffoldSection isFullWidth>
|
||||
<GenericSkeletonLoader />
|
||||
</ScaffoldSection>
|
||||
) : (
|
||||
<HooksListing />
|
||||
)}
|
||||
</ScaffoldContainer>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
|
||||
import { useParams } from 'common'
|
||||
import { MfaAuthSettingsForm } from 'components/interfaces/Auth'
|
||||
import { MfaAuthSettingsForm } from 'components/interfaces/Auth/MfaAuthSettingsForm/MfaAuthSettingsForm'
|
||||
import AuthLayout from 'components/layouts/AuthLayout/AuthLayout'
|
||||
import DefaultLayout from 'components/layouts/DefaultLayout'
|
||||
import { PageLayout } from 'components/layouts/PageLayout/PageLayout'
|
||||
@@ -9,7 +9,7 @@ import { ScaffoldContainer, ScaffoldSection } from 'components/layouts/Scaffold'
|
||||
import NoPermission from 'components/ui/NoPermission'
|
||||
import { GenericSkeletonLoader } from 'components/ui/ShimmeringLoader'
|
||||
import { UnknownInterface } from 'components/ui/UnknownInterface'
|
||||
import { useCheckPermissions, usePermissionsLoaded } from 'hooks/misc/useCheckPermissions'
|
||||
import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions'
|
||||
import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled'
|
||||
import type { NextPageWithLayout } from 'types'
|
||||
|
||||
@@ -17,38 +17,40 @@ const MfaPage: NextPageWithLayout = () => {
|
||||
const { ref } = useParams()
|
||||
const showMFA = useIsFeatureEnabled('authentication:multi_factor')
|
||||
|
||||
const isPermissionsLoaded = usePermissionsLoaded()
|
||||
const canReadAuthSettings = useCheckPermissions(PermissionAction.READ, 'custom_config_gotrue')
|
||||
const { can: canReadAuthSettings, isSuccess: isPermissionsLoaded } =
|
||||
useAsyncCheckProjectPermissions(PermissionAction.READ, 'custom_config_gotrue')
|
||||
|
||||
if (!showMFA) {
|
||||
return <UnknownInterface urlBack={`/project/${ref}/auth/users`} />
|
||||
}
|
||||
|
||||
if (isPermissionsLoaded && !canReadAuthSettings) {
|
||||
return <NoPermission isFullPage resourceText="access your project's authentication settings" />
|
||||
}
|
||||
|
||||
return (
|
||||
<PageLayout
|
||||
title="Multi-Factor Authentication (MFA)"
|
||||
subtitle="Requires users to provide additional verification factors to authenticate"
|
||||
>
|
||||
{isPermissionsLoaded && !canReadAuthSettings ? (
|
||||
<NoPermission isFullPage resourceText="access your project's authentication settings" />
|
||||
<ScaffoldContainer>
|
||||
{!isPermissionsLoaded ? (
|
||||
<ScaffoldSection isFullWidth>
|
||||
<GenericSkeletonLoader />
|
||||
</ScaffoldSection>
|
||||
) : (
|
||||
<ScaffoldContainer>
|
||||
{!isPermissionsLoaded ? (
|
||||
<ScaffoldSection isFullWidth>
|
||||
<GenericSkeletonLoader />
|
||||
</ScaffoldSection>
|
||||
) : (
|
||||
<MfaAuthSettingsForm />
|
||||
)}
|
||||
</ScaffoldContainer>
|
||||
<MfaAuthSettingsForm />
|
||||
)}
|
||||
</PageLayout>
|
||||
</ScaffoldContainer>
|
||||
)
|
||||
}
|
||||
|
||||
MfaPage.getLayout = (page) => (
|
||||
<DefaultLayout>
|
||||
<AuthLayout>{page}</AuthLayout>
|
||||
<AuthLayout>
|
||||
<PageLayout
|
||||
title="Multi-Factor Authentication (MFA)"
|
||||
subtitle="Requires users to provide additional verification factors to authenticate"
|
||||
>
|
||||
{page}
|
||||
</PageLayout>
|
||||
</AuthLayout>
|
||||
</DefaultLayout>
|
||||
)
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ import SchemaSelector from 'components/ui/SchemaSelector'
|
||||
import { GenericSkeletonLoader } from 'components/ui/ShimmeringLoader'
|
||||
import { useDatabasePoliciesQuery } from 'data/database-policies/database-policies-query'
|
||||
import { useTablesQuery } from 'data/tables/tables-query'
|
||||
import { useCheckPermissions, usePermissionsLoaded } from 'hooks/misc/useCheckPermissions'
|
||||
import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions'
|
||||
import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
|
||||
import { useUrlState } from 'hooks/ui/useUrlState'
|
||||
import { useIsProtectedSchema } from 'hooks/useProtectedSchemas'
|
||||
@@ -98,8 +98,10 @@ const AuthPoliciesPage: NextPageWithLayout = () => {
|
||||
})
|
||||
|
||||
const filteredTables = onFilterTables(tables ?? [], policies ?? [], searchString)
|
||||
const canReadPolicies = useCheckPermissions(PermissionAction.TENANT_SQL_ADMIN_READ, 'policies')
|
||||
const isPermissionsLoaded = usePermissionsLoaded()
|
||||
const { can: canReadPolicies, isSuccess: isPermissionsLoaded } = useAsyncCheckProjectPermissions(
|
||||
PermissionAction.TENANT_SQL_ADMIN_READ,
|
||||
'policies'
|
||||
)
|
||||
|
||||
if (isPermissionsLoaded && !canReadPolicies) {
|
||||
return <NoPermission isFullPage resourceText="view this project's RLS policies" />
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
|
||||
import { useParams } from 'common'
|
||||
import { ProtectionAuthSettingsForm } from 'components/interfaces/Auth'
|
||||
import { ProtectionAuthSettingsForm } from 'components/interfaces/Auth/ProtectionAuthSettingsForm/ProtectionAuthSettingsForm'
|
||||
import AuthLayout from 'components/layouts/AuthLayout/AuthLayout'
|
||||
import DefaultLayout from 'components/layouts/DefaultLayout'
|
||||
import { PageLayout } from 'components/layouts/PageLayout/PageLayout'
|
||||
@@ -9,7 +9,7 @@ import { ScaffoldContainer, ScaffoldSection } from 'components/layouts/Scaffold'
|
||||
import NoPermission from 'components/ui/NoPermission'
|
||||
import { GenericSkeletonLoader } from 'components/ui/ShimmeringLoader'
|
||||
import { UnknownInterface } from 'components/ui/UnknownInterface'
|
||||
import { useCheckPermissions, usePermissionsLoaded } from 'hooks/misc/useCheckPermissions'
|
||||
import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions'
|
||||
import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled'
|
||||
import type { NextPageWithLayout } from 'types'
|
||||
|
||||
@@ -17,38 +17,40 @@ const ProtectionPage: NextPageWithLayout = () => {
|
||||
const { ref } = useParams()
|
||||
const showAttackProtection = useIsFeatureEnabled('authentication:attack_protection')
|
||||
|
||||
const isPermissionsLoaded = usePermissionsLoaded()
|
||||
const canReadAuthSettings = useCheckPermissions(PermissionAction.READ, 'custom_config_gotrue')
|
||||
const { can: canReadAuthSettings, isSuccess: isPermissionsLoaded } =
|
||||
useAsyncCheckProjectPermissions(PermissionAction.READ, 'custom_config_gotrue')
|
||||
|
||||
if (!showAttackProtection) {
|
||||
return <UnknownInterface urlBack={`/project/${ref}/auth/users`} />
|
||||
}
|
||||
|
||||
if (isPermissionsLoaded && !canReadAuthSettings) {
|
||||
return <NoPermission isFullPage resourceText="access your project's auth provider settings" />
|
||||
}
|
||||
|
||||
return (
|
||||
<PageLayout
|
||||
title="Attack Protection"
|
||||
subtitle="Configure security settings to protect your project from attacks"
|
||||
>
|
||||
{isPermissionsLoaded && !canReadAuthSettings ? (
|
||||
<NoPermission isFullPage resourceText="access your project's auth provider settings" />
|
||||
<ScaffoldContainer>
|
||||
{!isPermissionsLoaded ? (
|
||||
<ScaffoldSection isFullWidth>
|
||||
<GenericSkeletonLoader />
|
||||
</ScaffoldSection>
|
||||
) : (
|
||||
<ScaffoldContainer>
|
||||
{!isPermissionsLoaded ? (
|
||||
<ScaffoldSection isFullWidth>
|
||||
<GenericSkeletonLoader />
|
||||
</ScaffoldSection>
|
||||
) : (
|
||||
<ProtectionAuthSettingsForm />
|
||||
)}
|
||||
</ScaffoldContainer>
|
||||
<ProtectionAuthSettingsForm />
|
||||
)}
|
||||
</PageLayout>
|
||||
</ScaffoldContainer>
|
||||
)
|
||||
}
|
||||
|
||||
ProtectionPage.getLayout = (page) => (
|
||||
<DefaultLayout>
|
||||
<AuthLayout>{page}</AuthLayout>
|
||||
<AuthLayout>
|
||||
<PageLayout
|
||||
title="Attack Protection"
|
||||
subtitle="Configure security settings to protect your project from attacks"
|
||||
>
|
||||
{page}
|
||||
</PageLayout>
|
||||
</AuthLayout>
|
||||
</DefaultLayout>
|
||||
)
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { AuthProvidersForm, BasicAuthSettingsForm } from 'components/interfaces/Auth'
|
||||
import { AuthProvidersForm } from 'components/interfaces/Auth/AuthProvidersForm/AuthProvidersForm'
|
||||
import { BasicAuthSettingsForm } from 'components/interfaces/Auth/BasicAuthSettingsForm/BasicAuthSettingsForm'
|
||||
import { AuthProvidersLayout } from 'components/layouts/AuthLayout/AuthProvidersLayout'
|
||||
import DefaultLayout from 'components/layouts/DefaultLayout'
|
||||
import { ScaffoldContainer } from 'components/layouts/Scaffold'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
|
||||
import { useParams } from 'common'
|
||||
import RateLimits from 'components/interfaces/Auth/RateLimits/RateLimits'
|
||||
import { RateLimits } from 'components/interfaces/Auth/RateLimits/RateLimits'
|
||||
import AuthLayout from 'components/layouts/AuthLayout/AuthLayout'
|
||||
import DefaultLayout from 'components/layouts/DefaultLayout'
|
||||
import { PageLayout } from 'components/layouts/PageLayout/PageLayout'
|
||||
@@ -10,7 +10,7 @@ import { DocsButton } from 'components/ui/DocsButton'
|
||||
import NoPermission from 'components/ui/NoPermission'
|
||||
import { GenericSkeletonLoader } from 'components/ui/ShimmeringLoader'
|
||||
import { UnknownInterface } from 'components/ui/UnknownInterface'
|
||||
import { useCheckPermissions, usePermissionsLoaded } from 'hooks/misc/useCheckPermissions'
|
||||
import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions'
|
||||
import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled'
|
||||
import type { NextPageWithLayout } from 'types'
|
||||
|
||||
@@ -18,41 +18,43 @@ const RateLimitsPage: NextPageWithLayout = () => {
|
||||
const { ref } = useParams()
|
||||
const showRateLimits = useIsFeatureEnabled('authentication:rate_limits')
|
||||
|
||||
const isPermissionsLoaded = usePermissionsLoaded()
|
||||
const canReadAuthSettings = useCheckPermissions(PermissionAction.READ, 'custom_config_gotrue')
|
||||
const { can: canReadAuthSettings, isSuccess: isPermissionsLoaded } =
|
||||
useAsyncCheckProjectPermissions(PermissionAction.READ, 'custom_config_gotrue')
|
||||
|
||||
if (!showRateLimits) {
|
||||
return <UnknownInterface urlBack={`/project/${ref}/auth/users`} />
|
||||
}
|
||||
|
||||
if (isPermissionsLoaded && !canReadAuthSettings) {
|
||||
return <NoPermission isFullPage resourceText="access your project's auth rate limit settings" />
|
||||
}
|
||||
|
||||
return (
|
||||
<PageLayout
|
||||
title="Rate Limits"
|
||||
subtitle="Safeguard against bursts of incoming traffic to prevent abuse and maximize stability"
|
||||
primaryActions={
|
||||
<DocsButton href="https://supabase.com/docs/guides/platform/going-into-prod#rate-limiting-resource-allocation--abuse-prevention" />
|
||||
}
|
||||
>
|
||||
{isPermissionsLoaded && !canReadAuthSettings ? (
|
||||
<NoPermission isFullPage resourceText="access your project's auth rate limit settings" />
|
||||
<ScaffoldContainer>
|
||||
{!isPermissionsLoaded ? (
|
||||
<ScaffoldSection isFullWidth>
|
||||
<GenericSkeletonLoader />
|
||||
</ScaffoldSection>
|
||||
) : (
|
||||
<ScaffoldContainer>
|
||||
{!isPermissionsLoaded ? (
|
||||
<ScaffoldSection isFullWidth>
|
||||
<GenericSkeletonLoader />
|
||||
</ScaffoldSection>
|
||||
) : (
|
||||
<RateLimits />
|
||||
)}
|
||||
</ScaffoldContainer>
|
||||
<RateLimits />
|
||||
)}
|
||||
</PageLayout>
|
||||
</ScaffoldContainer>
|
||||
)
|
||||
}
|
||||
|
||||
RateLimitsPage.getLayout = (page) => (
|
||||
<DefaultLayout>
|
||||
<AuthLayout>{page}</AuthLayout>
|
||||
<AuthLayout>
|
||||
<PageLayout
|
||||
title="Rate Limits"
|
||||
subtitle="Safeguard against bursts of incoming traffic to prevent abuse and maximize stability"
|
||||
primaryActions={
|
||||
<DocsButton href="https://supabase.com/docs/guides/platform/going-into-prod#rate-limiting-resource-allocation--abuse-prevention" />
|
||||
}
|
||||
>
|
||||
{page}
|
||||
</PageLayout>
|
||||
</AuthLayout>
|
||||
</DefaultLayout>
|
||||
)
|
||||
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
|
||||
import { SessionsAuthSettingsForm } from 'components/interfaces/Auth'
|
||||
import { SessionsAuthSettingsForm } from 'components/interfaces/Auth/SessionsAuthSettingsForm/SessionsAuthSettingsForm'
|
||||
import AuthLayout from 'components/layouts/AuthLayout/AuthLayout'
|
||||
import DefaultLayout from 'components/layouts/DefaultLayout'
|
||||
import { PageLayout } from 'components/layouts/PageLayout/PageLayout'
|
||||
import { ScaffoldContainer } from 'components/layouts/Scaffold'
|
||||
import { ScaffoldContainer, ScaffoldSection } from 'components/layouts/Scaffold'
|
||||
import NoPermission from 'components/ui/NoPermission'
|
||||
import { GenericSkeletonLoader } from 'components/ui/ShimmeringLoader'
|
||||
import { useCheckPermissions, usePermissionsLoaded } from 'hooks/misc/useCheckPermissions'
|
||||
import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions'
|
||||
import type { NextPageWithLayout } from 'types'
|
||||
|
||||
const SessionsPage: NextPageWithLayout = () => {
|
||||
const isPermissionsLoaded = usePermissionsLoaded()
|
||||
const canReadAuthSettings = useCheckPermissions(PermissionAction.READ, 'custom_config_gotrue')
|
||||
const { can: canReadAuthSettings, isSuccess: isPermissionsLoaded } =
|
||||
useAsyncCheckProjectPermissions(PermissionAction.READ, 'custom_config_gotrue')
|
||||
|
||||
if (isPermissionsLoaded && !canReadAuthSettings) {
|
||||
return <NoPermission isFullPage resourceText="access your project's authentication settings" />
|
||||
@@ -21,9 +21,9 @@ const SessionsPage: NextPageWithLayout = () => {
|
||||
return (
|
||||
<ScaffoldContainer>
|
||||
{!isPermissionsLoaded ? (
|
||||
<div className="mt-12">
|
||||
<ScaffoldSection isFullWidth>
|
||||
<GenericSkeletonLoader />
|
||||
</div>
|
||||
</ScaffoldSection>
|
||||
) : (
|
||||
<SessionsAuthSettingsForm />
|
||||
)}
|
||||
|
||||
@@ -1,21 +1,33 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
|
||||
import { SmtpForm } from 'components/interfaces/Auth'
|
||||
import { SmtpForm } from 'components/interfaces/Auth/SmtpForm/SmtpForm'
|
||||
import { AuthEmailsLayout } from 'components/layouts/AuthLayout/AuthEmailsLayout'
|
||||
import DefaultLayout from 'components/layouts/DefaultLayout'
|
||||
import { ScaffoldContainer, ScaffoldSection } from 'components/layouts/Scaffold'
|
||||
import NoPermission from 'components/ui/NoPermission'
|
||||
import { useCheckPermissions, usePermissionsLoaded } from 'hooks/misc/useCheckPermissions'
|
||||
import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions'
|
||||
import type { NextPageWithLayout } from 'types'
|
||||
import { GenericSkeletonLoader } from 'ui-patterns'
|
||||
|
||||
const SmtpPage: NextPageWithLayout = () => {
|
||||
const canReadAuthSettings = useCheckPermissions(PermissionAction.READ, 'custom_config_gotrue')
|
||||
const isPermissionsLoaded = usePermissionsLoaded()
|
||||
const { can: canReadAuthSettings, isSuccess: isPermissionsLoaded } =
|
||||
useAsyncCheckProjectPermissions(PermissionAction.READ, 'custom_config_gotrue')
|
||||
|
||||
if (isPermissionsLoaded && !canReadAuthSettings) {
|
||||
return <NoPermission isFullPage resourceText="access your project's email settings" />
|
||||
}
|
||||
|
||||
return <SmtpForm />
|
||||
return (
|
||||
<ScaffoldContainer>
|
||||
{!isPermissionsLoaded ? (
|
||||
<ScaffoldSection isFullWidth>
|
||||
<GenericSkeletonLoader />
|
||||
</ScaffoldSection>
|
||||
) : (
|
||||
<SmtpForm />
|
||||
)}
|
||||
</ScaffoldContainer>
|
||||
)
|
||||
}
|
||||
|
||||
SmtpPage.getLayout = (page) => (
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { EmailTemplates } from 'components/interfaces/Auth'
|
||||
|
||||
import { EmailTemplates } from 'components/interfaces/Auth/EmailTemplates/EmailTemplates'
|
||||
import { AuthEmailsLayout } from 'components/layouts/AuthLayout/AuthEmailsLayout'
|
||||
import DefaultLayout from 'components/layouts/DefaultLayout'
|
||||
import { ScaffoldContainer } from 'components/layouts/Scaffold'
|
||||
import { ScaffoldContainer, ScaffoldSection } from 'components/layouts/Scaffold'
|
||||
import NoPermission from 'components/ui/NoPermission'
|
||||
import { useCheckPermissions, usePermissionsLoaded } from 'hooks/misc/useCheckPermissions'
|
||||
import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions'
|
||||
import type { NextPageWithLayout } from 'types'
|
||||
import { GenericSkeletonLoader } from 'ui-patterns'
|
||||
|
||||
const TemplatesPage: NextPageWithLayout = () => {
|
||||
const canReadAuthSettings = useCheckPermissions(PermissionAction.READ, 'custom_config_gotrue')
|
||||
const isPermissionsLoaded = usePermissionsLoaded()
|
||||
const { can: canReadAuthSettings, isSuccess: isPermissionsLoaded } =
|
||||
useAsyncCheckProjectPermissions(PermissionAction.READ, 'custom_config_gotrue')
|
||||
|
||||
if (isPermissionsLoaded && !canReadAuthSettings) {
|
||||
return <NoPermission isFullPage resourceText="access your project's email settings" />
|
||||
@@ -17,7 +19,13 @@ const TemplatesPage: NextPageWithLayout = () => {
|
||||
|
||||
return (
|
||||
<ScaffoldContainer>
|
||||
<EmailTemplates />
|
||||
{!isPermissionsLoaded ? (
|
||||
<ScaffoldSection isFullWidth>
|
||||
<GenericSkeletonLoader />
|
||||
</ScaffoldSection>
|
||||
) : (
|
||||
<EmailTemplates />
|
||||
)}
|
||||
</ScaffoldContainer>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
|
||||
import { useParams } from 'common'
|
||||
import { ThirdPartyAuthForm } from 'components/interfaces/Auth'
|
||||
import { ThirdPartyAuthForm } from 'components/interfaces/Auth/ThirdPartyAuthForm'
|
||||
import AuthLayout from 'components/layouts/AuthLayout/AuthLayout'
|
||||
import { AuthProvidersLayout } from 'components/layouts/AuthLayout/AuthProvidersLayout'
|
||||
import DefaultLayout from 'components/layouts/DefaultLayout'
|
||||
import { ScaffoldContainer } from 'components/layouts/Scaffold'
|
||||
import NoPermission from 'components/ui/NoPermission'
|
||||
import { UnknownInterface } from 'components/ui/UnknownInterface'
|
||||
import { useCheckPermissions, usePermissionsLoaded } from 'hooks/misc/useCheckPermissions'
|
||||
import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions'
|
||||
import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled'
|
||||
import type { NextPageWithLayout } from 'types'
|
||||
|
||||
const ThirdPartyPage: NextPageWithLayout = () => {
|
||||
const { ref } = useParams()
|
||||
const canReadAuthSettings = useCheckPermissions(PermissionAction.READ, 'custom_config_gotrue')
|
||||
const isPermissionsLoaded = usePermissionsLoaded()
|
||||
const { can: canReadAuthSettings, isSuccess: isPermissionsLoaded } =
|
||||
useAsyncCheckProjectPermissions(PermissionAction.READ, 'custom_config_gotrue')
|
||||
|
||||
const showThirdPartyAuth = useIsFeatureEnabled('authentication:third_party_auth')
|
||||
|
||||
|
||||
@@ -5,15 +5,15 @@ import SiteUrl from 'components/interfaces/Auth/SiteUrl/SiteUrl'
|
||||
import AuthLayout from 'components/layouts/AuthLayout/AuthLayout'
|
||||
import DefaultLayout from 'components/layouts/DefaultLayout'
|
||||
import { PageLayout } from 'components/layouts/PageLayout/PageLayout'
|
||||
import { ScaffoldContainer } from 'components/layouts/Scaffold'
|
||||
import { ScaffoldContainer, ScaffoldSection } from 'components/layouts/Scaffold'
|
||||
import NoPermission from 'components/ui/NoPermission'
|
||||
import { GenericSkeletonLoader } from 'components/ui/ShimmeringLoader'
|
||||
import { useCheckPermissions, usePermissionsLoaded } from 'hooks/misc/useCheckPermissions'
|
||||
import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions'
|
||||
import type { NextPageWithLayout } from 'types'
|
||||
|
||||
const URLConfiguration: NextPageWithLayout = () => {
|
||||
const isPermissionsLoaded = usePermissionsLoaded()
|
||||
const canReadAuthSettings = useCheckPermissions(PermissionAction.READ, 'custom_config_gotrue')
|
||||
const { can: canReadAuthSettings, isSuccess: isPermissionsLoaded } =
|
||||
useAsyncCheckProjectPermissions(PermissionAction.READ, 'custom_config_gotrue')
|
||||
|
||||
if (isPermissionsLoaded && !canReadAuthSettings) {
|
||||
return <NoPermission isFullPage resourceText="access your project's authentication settings" />
|
||||
@@ -22,9 +22,9 @@ const URLConfiguration: NextPageWithLayout = () => {
|
||||
return (
|
||||
<ScaffoldContainer>
|
||||
{!isPermissionsLoaded ? (
|
||||
<div className="mt-12">
|
||||
<ScaffoldSection isFullWidth>
|
||||
<GenericSkeletonLoader />
|
||||
</div>
|
||||
</ScaffoldSection>
|
||||
) : (
|
||||
<>
|
||||
<SiteUrl />
|
||||
|
||||
Reference in new issue
Block a user