mirror of
https://github.com/supabase/supabase.git
synced 2026-10-19 08:09:11 +03:00
Clean up auth related feature flags
This commit is contained in:
1 parent
6e25cd693a
commit
310fac3f4d
5 files changed
+105
-195
No files matched your search
+77
-102
@@ -1,7 +1,5 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
|
||||
import { useParams } from 'common'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { useEffect, useState } from 'react'
|
||||
import {
|
||||
AlertDescription_Shadcn_,
|
||||
@@ -18,6 +16,7 @@ import {
|
||||
} from 'ui'
|
||||
import { boolean, number, object, string } from 'yup'
|
||||
|
||||
import { Markdown } from 'components/interfaces/Markdown'
|
||||
import {
|
||||
FormActions,
|
||||
FormHeader,
|
||||
@@ -30,8 +29,7 @@ import UpgradeToPro from 'components/ui/UpgradeToPro'
|
||||
import { useAuthConfigQuery } from 'data/auth/auth-config-query'
|
||||
import { useAuthConfigUpdateMutation } from 'data/auth/auth-config-update-mutation'
|
||||
import { useOrgSubscriptionQuery } from 'data/subscriptions/org-subscription-query'
|
||||
import { useCheckPermissions, useFlag, useSelectedOrganization, useStore } from 'hooks'
|
||||
import { Markdown } from 'components/interfaces/Markdown'
|
||||
import { useCheckPermissions, useSelectedOrganization, useStore } from 'hooks'
|
||||
import FormField from '../AuthProvidersForm/FormField'
|
||||
|
||||
// Use a const string to represent no chars option. Represented as empty string on the backend side.
|
||||
@@ -75,7 +73,7 @@ function HoursOrNeverText({ value }: { value: number }) {
|
||||
|
||||
const formId = 'auth-config-basic-settings'
|
||||
|
||||
const BasicAuthSettingsForm = observer(() => {
|
||||
const BasicAuthSettingsForm = () => {
|
||||
const { ui } = useStore()
|
||||
const { ref: projectRef } = useParams()
|
||||
const {
|
||||
@@ -96,9 +94,6 @@ const BasicAuthSettingsForm = observer(() => {
|
||||
})
|
||||
|
||||
const isProPlanAndUp = isSuccessSubscription && subscription?.plan?.id !== 'free'
|
||||
const singlePerUserReleased = useFlag('authSingleSessionPerUserReleased')
|
||||
const passwordStrengthReleased = useFlag('authPasswordStrengthReleased')
|
||||
const hibpReleased = useFlag('authHIBPReleased')
|
||||
|
||||
const INITIAL_VALUES = {
|
||||
DISABLE_SIGNUP: !authConfig?.DISABLE_SIGNUP,
|
||||
@@ -109,25 +104,11 @@ const BasicAuthSettingsForm = observer(() => {
|
||||
SECURITY_CAPTCHA_PROVIDER: authConfig?.SECURITY_CAPTCHA_PROVIDER || 'hcaptcha',
|
||||
SESSIONS_TIMEBOX: authConfig?.SESSIONS_TIMEBOX || 0,
|
||||
SESSIONS_INACTIVITY_TIMEOUT: authConfig?.SESSIONS_INACTIVITY_TIMEOUT || 0,
|
||||
...(singlePerUserReleased
|
||||
? {
|
||||
SESSIONS_SINGLE_PER_USER: authConfig?.SESSIONS_SINGLE_PER_USER || false,
|
||||
}
|
||||
: null),
|
||||
|
||||
...(passwordStrengthReleased
|
||||
? {
|
||||
PASSWORD_MIN_LENGTH: authConfig?.PASSWORD_MIN_LENGTH || 6,
|
||||
PASSWORD_REQUIRED_CHARACTERS:
|
||||
authConfig?.PASSWORD_REQUIRED_CHARACTERS || NO_REQUIRED_CHARACTERS,
|
||||
|
||||
...(hibpReleased
|
||||
? {
|
||||
PASSWORD_HIBP_ENABLED: authConfig?.PASSWORD_HIBP_ENABLED || false,
|
||||
}
|
||||
: null),
|
||||
}
|
||||
: null),
|
||||
SESSIONS_SINGLE_PER_USER: authConfig?.SESSIONS_SINGLE_PER_USER || false,
|
||||
PASSWORD_MIN_LENGTH: authConfig?.PASSWORD_MIN_LENGTH || 6,
|
||||
PASSWORD_REQUIRED_CHARACTERS:
|
||||
authConfig?.PASSWORD_REQUIRED_CHARACTERS || NO_REQUIRED_CHARACTERS,
|
||||
PASSWORD_HIBP_ENABLED: authConfig?.PASSWORD_HIBP_ENABLED || false,
|
||||
}
|
||||
|
||||
const onSubmit = (values: any, { resetForm }: any) => {
|
||||
@@ -173,6 +154,7 @@ const BasicAuthSettingsForm = observer(() => {
|
||||
{({ handleReset, resetForm, values, initialValues }: any) => {
|
||||
const hasChanges = JSON.stringify(values) !== JSON.stringify(initialValues)
|
||||
// Form is reset once remote data is loaded in store
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
useEffect(() => {
|
||||
if (isSuccess) resetForm({ values: INITIAL_VALUES, initialValues: INITIAL_VALUES })
|
||||
}, [isSuccess])
|
||||
@@ -228,70 +210,65 @@ const BasicAuthSettingsForm = observer(() => {
|
||||
/>
|
||||
</FormSectionContent>
|
||||
</FormSection>
|
||||
{passwordStrengthReleased && (
|
||||
<>
|
||||
<FormSection header={<FormSectionLabel>Passwords</FormSectionLabel>}>
|
||||
<FormSectionContent loading={isLoading}>
|
||||
<InputNumber
|
||||
id="PASSWORD_MIN_LENGTH"
|
||||
size="small"
|
||||
label="Minimum password length"
|
||||
descriptionText="Passwords shorter than this value will be rejected as weak. Minimum 6, recommended 8 or more."
|
||||
actions={<span className="mr-3 text-foreground-lighter">characters</span>}
|
||||
disabled={!canUpdateConfig}
|
||||
/>
|
||||
<FormField
|
||||
name="PASSWORD_REQUIRED_CHARACTERS"
|
||||
properties={{
|
||||
type: 'select',
|
||||
title: 'Password Requirements',
|
||||
description:
|
||||
'Passwords that do not have at least one of each will be rejected as weak.',
|
||||
enum: [
|
||||
{
|
||||
label: 'No required characters (default)',
|
||||
value: NO_REQUIRED_CHARACTERS,
|
||||
},
|
||||
{
|
||||
label: 'Letters and digits',
|
||||
value: LETTERS_AND_DIGITS,
|
||||
},
|
||||
{
|
||||
label: 'Lowercase, uppercase letters and digits',
|
||||
value: LOWER_UPPER_DIGITS,
|
||||
},
|
||||
{
|
||||
label:
|
||||
'Lowercase, uppercase letters, digits and symbols (recommended)',
|
||||
value: LOWER_UPPER_DIGITS_SYMBOLS,
|
||||
},
|
||||
],
|
||||
}}
|
||||
formValues={values}
|
||||
/>
|
||||
{isProPlanAndUp ? (
|
||||
<></>
|
||||
) : (
|
||||
<UpgradeToPro
|
||||
primaryText="Upgrade to Pro"
|
||||
secondaryText="Leaked password protection available on Pro plans and up."
|
||||
projectRef={projectRef!}
|
||||
organizationSlug={organization!.slug}
|
||||
/>
|
||||
)}
|
||||
<Toggle
|
||||
id="PASSWORD_HIBP_ENABLED"
|
||||
size="small"
|
||||
label="Prevent use of leaked passwords"
|
||||
afterLabel=" (recommended)"
|
||||
layout="flex"
|
||||
descriptionText="Rejects the use of known or easy to guess passwords on sign up or password change. Powered by the HaveIBeenPwned.org Pwned Passwords API."
|
||||
disabled={!canUpdateConfig || !isProPlanAndUp}
|
||||
/>
|
||||
</FormSectionContent>
|
||||
</FormSection>
|
||||
</>
|
||||
)}
|
||||
<FormSection header={<FormSectionLabel>Passwords</FormSectionLabel>}>
|
||||
<FormSectionContent loading={isLoading}>
|
||||
<InputNumber
|
||||
id="PASSWORD_MIN_LENGTH"
|
||||
size="small"
|
||||
label="Minimum password length"
|
||||
descriptionText="Passwords shorter than this value will be rejected as weak. Minimum 6, recommended 8 or more."
|
||||
actions={<span className="mr-3 text-foreground-lighter">characters</span>}
|
||||
disabled={!canUpdateConfig}
|
||||
/>
|
||||
<FormField
|
||||
name="PASSWORD_REQUIRED_CHARACTERS"
|
||||
properties={{
|
||||
type: 'select',
|
||||
title: 'Password Requirements',
|
||||
description:
|
||||
'Passwords that do not have at least one of each will be rejected as weak.',
|
||||
enum: [
|
||||
{
|
||||
label: 'No required characters (default)',
|
||||
value: NO_REQUIRED_CHARACTERS,
|
||||
},
|
||||
{
|
||||
label: 'Letters and digits',
|
||||
value: LETTERS_AND_DIGITS,
|
||||
},
|
||||
{
|
||||
label: 'Lowercase, uppercase letters and digits',
|
||||
value: LOWER_UPPER_DIGITS,
|
||||
},
|
||||
{
|
||||
label: 'Lowercase, uppercase letters, digits and symbols (recommended)',
|
||||
value: LOWER_UPPER_DIGITS_SYMBOLS,
|
||||
},
|
||||
],
|
||||
}}
|
||||
formValues={values}
|
||||
/>
|
||||
{isProPlanAndUp ? (
|
||||
<></>
|
||||
) : (
|
||||
<UpgradeToPro
|
||||
primaryText="Upgrade to Pro"
|
||||
secondaryText="Leaked password protection available on Pro plans and up."
|
||||
projectRef={projectRef!}
|
||||
organizationSlug={organization!.slug}
|
||||
/>
|
||||
)}
|
||||
<Toggle
|
||||
id="PASSWORD_HIBP_ENABLED"
|
||||
size="small"
|
||||
label="Prevent use of leaked passwords"
|
||||
afterLabel=" (recommended)"
|
||||
layout="flex"
|
||||
descriptionText="Rejects the use of known or easy to guess passwords on sign up or password change. Powered by the HaveIBeenPwned.org Pwned Passwords API."
|
||||
disabled={!canUpdateConfig || !isProPlanAndUp}
|
||||
/>
|
||||
</FormSectionContent>
|
||||
</FormSection>
|
||||
<FormSection header={<FormSectionLabel>User Sessions</FormSectionLabel>}>
|
||||
<FormSectionContent loading={isLoading}>
|
||||
{isProPlanAndUp ? (
|
||||
@@ -304,16 +281,14 @@ const BasicAuthSettingsForm = observer(() => {
|
||||
organizationSlug={organization!.slug}
|
||||
/>
|
||||
)}
|
||||
{singlePerUserReleased && (
|
||||
<Toggle
|
||||
id="SESSIONS_SINGLE_PER_USER"
|
||||
size="small"
|
||||
label="Enforce single session per user"
|
||||
layout="flex"
|
||||
descriptionText="If enabled, all but a user's most recently active session will be terminated."
|
||||
disabled={!canUpdateConfig || !isProPlanAndUp}
|
||||
/>
|
||||
)}
|
||||
<Toggle
|
||||
id="SESSIONS_SINGLE_PER_USER"
|
||||
size="small"
|
||||
label="Enforce single session per user"
|
||||
layout="flex"
|
||||
descriptionText="If enabled, all but a user's most recently active session will be terminated."
|
||||
disabled={!canUpdateConfig || !isProPlanAndUp}
|
||||
/>
|
||||
<InputNumber
|
||||
id="SESSIONS_TIMEBOX"
|
||||
size="small"
|
||||
@@ -398,6 +373,6 @@ const BasicAuthSettingsForm = observer(() => {
|
||||
}}
|
||||
</Form>
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
export default BasicAuthSettingsForm
|
||||
@@ -21,8 +21,7 @@ import {
|
||||
} from 'components/ui/Forms'
|
||||
import { useAuthConfigQuery } from 'data/auth/auth-config-query'
|
||||
import { useAuthConfigUpdateMutation } from 'data/auth/auth-config-update-mutation'
|
||||
import { useCheckPermissions, useFlag, useStore } from 'hooks'
|
||||
|
||||
import { useCheckPermissions, useStore } from 'hooks'
|
||||
import SchemaFunctionSelector from './SchemaFunctionSelector'
|
||||
|
||||
const schema = object({
|
||||
@@ -43,19 +42,12 @@ const BasicHooksConfig = () => {
|
||||
isSuccess,
|
||||
} = useAuthConfigQuery({ projectRef })
|
||||
const { mutate: updateAuthConfig, isLoading: isUpdatingConfig } = useAuthConfigUpdateMutation()
|
||||
|
||||
const customizeAccessTokenReleased = useFlag('authHooksCustomizeAccessToken')
|
||||
|
||||
const canUpdateConfig = useCheckPermissions(PermissionAction.UPDATE, 'custom_config_gotrue')
|
||||
|
||||
// TODO: Remove as any once these properties are defined in Auth Config types
|
||||
const INITIAL_VALUES = {
|
||||
...(customizeAccessTokenReleased
|
||||
? {
|
||||
HOOK_CUSTOM_ACCESS_TOKEN_ENABLED: authConfig?.HOOK_CUSTOM_ACCESS_TOKEN_ENABLED || false,
|
||||
HOOK_CUSTOM_ACCESS_TOKEN_URI: authConfig?.HOOK_CUSTOM_ACCESS_TOKEN_URI || '',
|
||||
}
|
||||
: null),
|
||||
HOOK_CUSTOM_ACCESS_TOKEN_ENABLED: authConfig?.HOOK_CUSTOM_ACCESS_TOKEN_ENABLED || false,
|
||||
HOOK_CUSTOM_ACCESS_TOKEN_URI: authConfig?.HOOK_CUSTOM_ACCESS_TOKEN_URI || '',
|
||||
}
|
||||
|
||||
const onSubmit = (values: any, { resetForm }: any) => {
|
||||
@@ -142,23 +134,15 @@ const BasicHooksConfig = () => {
|
||||
descriptionText="Select the function to be called by Supabase Auth each time a new JWT is created. It should return the claims you wish to be present in the JWT."
|
||||
values={values}
|
||||
setFieldValue={setFieldValue}
|
||||
disabled={!canUpdateConfig || !customizeAccessTokenReleased}
|
||||
disabled={!canUpdateConfig}
|
||||
/>
|
||||
{!customizeAccessTokenReleased && (
|
||||
<Alert_Shadcn_ variant="default">
|
||||
<AlertTitle_Shadcn_>Coming soon!</AlertTitle_Shadcn_>
|
||||
<AlertDescription_Shadcn_>
|
||||
This hook is not available yet on your project.
|
||||
</AlertDescription_Shadcn_>
|
||||
</Alert_Shadcn_>
|
||||
)}
|
||||
{values.HOOK_CUSTOM_ACCESS_TOKEN_URI && (
|
||||
<Toggle
|
||||
id="HOOK_CUSTOM_ACCESS_TOKEN_ENABLED"
|
||||
size="medium"
|
||||
label="Enable hook"
|
||||
layout="flex"
|
||||
disabled={!canUpdateConfig || !customizeAccessTokenReleased}
|
||||
disabled={!canUpdateConfig}
|
||||
/>
|
||||
)}
|
||||
</FormSectionContent>
|
||||
|
||||
@@ -23,8 +23,7 @@ import UpgradeToPro from 'components/ui/UpgradeToPro'
|
||||
import { useAuthConfigQuery } from 'data/auth/auth-config-query'
|
||||
import { useAuthConfigUpdateMutation } from 'data/auth/auth-config-update-mutation'
|
||||
import { useOrgSubscriptionQuery } from 'data/subscriptions/org-subscription-query'
|
||||
import { useCheckPermissions, useFlag, useSelectedOrganization, useStore } from 'hooks'
|
||||
|
||||
import { useCheckPermissions, useSelectedOrganization, useStore } from 'hooks'
|
||||
import SchemaFunctionSelector from './SchemaFunctionSelector'
|
||||
|
||||
const schema = object({
|
||||
@@ -47,10 +46,7 @@ const EnterpriseHooksConfig = () => {
|
||||
isSuccess,
|
||||
} = useAuthConfigQuery({ projectRef })
|
||||
const { mutate: updateAuthConfig, isLoading: isUpdatingConfig } = useAuthConfigUpdateMutation()
|
||||
|
||||
const canUpdateConfig = useCheckPermissions(PermissionAction.UPDATE, 'custom_config_gotrue')
|
||||
const mfaVerificationAttemptReleased = useFlag('authHookMFAVerification')
|
||||
const passwordVerificationAttemptReleased = useFlag('authHookPasswordVerification')
|
||||
|
||||
const organization = useSelectedOrganization()
|
||||
const { data: subscription, isSuccess: isSuccessSubscription } = useOrgSubscriptionQuery({
|
||||
@@ -61,22 +57,14 @@ const EnterpriseHooksConfig = () => {
|
||||
isSuccessSubscription && subscription?.plan?.id !== 'free' && subscription?.plan?.id !== 'pro'
|
||||
|
||||
const INITIAL_VALUES = {
|
||||
...(mfaVerificationAttemptReleased
|
||||
? {
|
||||
HOOK_MFA_VERIFICATION_ATTEMPT_ENABLED:
|
||||
authConfig?.HOOK_MFA_VERIFICATION_ATTEMPT_ENABLED || false,
|
||||
HOOK_MFA_VERIFICATION_ATTEMPT_URI: authConfig?.HOOK_MFA_VERIFICATION_ATTEMPT_URI || '',
|
||||
}
|
||||
: null),
|
||||
...(passwordVerificationAttemptReleased
|
||||
? {
|
||||
// remove as any when the types are merged in
|
||||
HOOK_PASSWORD_VERIFICATION_ATTEMPT_ENABLED:
|
||||
(authConfig as any)?.HOOK_PASSWORD_VERIFICATION_ATTEMPT_ENABLED || false,
|
||||
HOOK_PASSWORD_VERIFICATION_ATTEMPT_URI:
|
||||
(authConfig as any)?.HOOK_PASSWORD_VERIFICATION_ATTEMPT_URI || '',
|
||||
}
|
||||
: null),
|
||||
HOOK_MFA_VERIFICATION_ATTEMPT_ENABLED:
|
||||
authConfig?.HOOK_MFA_VERIFICATION_ATTEMPT_ENABLED || false,
|
||||
HOOK_MFA_VERIFICATION_ATTEMPT_URI: authConfig?.HOOK_MFA_VERIFICATION_ATTEMPT_URI || '',
|
||||
// remove as any when the types are merged in
|
||||
HOOK_PASSWORD_VERIFICATION_ATTEMPT_ENABLED:
|
||||
(authConfig as any)?.HOOK_PASSWORD_VERIFICATION_ATTEMPT_ENABLED || false,
|
||||
HOOK_PASSWORD_VERIFICATION_ATTEMPT_URI:
|
||||
(authConfig as any)?.HOOK_PASSWORD_VERIFICATION_ATTEMPT_URI || '',
|
||||
}
|
||||
|
||||
const onSubmit = (values: any, { resetForm }: any) => {
|
||||
@@ -172,31 +160,15 @@ const EnterpriseHooksConfig = () => {
|
||||
descriptionText="Select the function to be called by Supabase Auth each time a user tries to verify an MFA factor. Return a decision on whether to reject the attempt and future ones, or to allow the user to keep trying."
|
||||
values={values}
|
||||
setFieldValue={setFieldValue}
|
||||
disabled={
|
||||
!canUpdateConfig ||
|
||||
!isTeamsEnterprisePlan ||
|
||||
!mfaVerificationAttemptReleased
|
||||
}
|
||||
disabled={!canUpdateConfig || !isTeamsEnterprisePlan}
|
||||
/>
|
||||
{!mfaVerificationAttemptReleased && (
|
||||
<Alert_Shadcn_ variant="default">
|
||||
<AlertTitle_Shadcn_>Coming soon!</AlertTitle_Shadcn_>
|
||||
<AlertDescription_Shadcn_>
|
||||
This hook is not available yet on your project.
|
||||
</AlertDescription_Shadcn_>
|
||||
</Alert_Shadcn_>
|
||||
)}
|
||||
{values.HOOK_MFA_VERIFICATION_ATTEMPT_URI && (
|
||||
<Toggle
|
||||
id="HOOK_MFA_VERIFICATION_ATTEMPT_ENABLED"
|
||||
size="small"
|
||||
label="Enable hook"
|
||||
layout="flex"
|
||||
disabled={
|
||||
!canUpdateConfig ||
|
||||
!isTeamsEnterprisePlan ||
|
||||
!mfaVerificationAttemptReleased
|
||||
}
|
||||
disabled={!canUpdateConfig || !isTeamsEnterprisePlan}
|
||||
/>
|
||||
)}
|
||||
</FormSectionContent>
|
||||
@@ -212,31 +184,15 @@ const EnterpriseHooksConfig = () => {
|
||||
descriptionText="Select the function to be called by Supabase Auth each time a user tries to sign in with a password. Return a decision whether to allow the user to reject the attempt, or to allow the user to keep trying."
|
||||
values={values}
|
||||
setFieldValue={setFieldValue}
|
||||
disabled={
|
||||
!canUpdateConfig ||
|
||||
!isTeamsEnterprisePlan ||
|
||||
!passwordVerificationAttemptReleased
|
||||
}
|
||||
disabled={!canUpdateConfig || !isTeamsEnterprisePlan}
|
||||
/>
|
||||
{!passwordVerificationAttemptReleased && (
|
||||
<Alert_Shadcn_ variant="default">
|
||||
<AlertTitle_Shadcn_>Coming soon!</AlertTitle_Shadcn_>
|
||||
<AlertDescription_Shadcn_>
|
||||
This hook is not available yet on your project.
|
||||
</AlertDescription_Shadcn_>
|
||||
</Alert_Shadcn_>
|
||||
)}
|
||||
{values.HOOK_PASSWORD_VERIFICATION_ATTEMPT_URI && (
|
||||
<Toggle
|
||||
id="HOOK_PASSWORD_VERIFICATION_ATTEMPT_ENABLED"
|
||||
size="small"
|
||||
label="Enable hook"
|
||||
layout="flex"
|
||||
disabled={
|
||||
!canUpdateConfig ||
|
||||
!isTeamsEnterprisePlan ||
|
||||
!passwordVerificationAttemptReleased
|
||||
}
|
||||
disabled={!canUpdateConfig || !isTeamsEnterprisePlan}
|
||||
/>
|
||||
)}
|
||||
</FormSectionContent>
|
||||
|
||||
@@ -5,7 +5,7 @@ import { PropsWithChildren } from 'react'
|
||||
import { useIsColumnLevelPrivilegesEnabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext'
|
||||
import ProductMenu from 'components/ui/ProductMenu'
|
||||
import { useAuthConfigPrefetch } from 'data/auth/auth-config-query'
|
||||
import { useFlag, withAuth } from 'hooks'
|
||||
import { withAuth } from 'hooks'
|
||||
import ProjectLayout from '../'
|
||||
import { generateAuthMenu } from './AuthLayout.utils'
|
||||
|
||||
@@ -15,7 +15,6 @@ export interface AuthLayoutProps {
|
||||
|
||||
const AuthLayout = ({ title, children }: PropsWithChildren<AuthLayoutProps>) => {
|
||||
const { ref: projectRef = 'default' } = useParams()
|
||||
const hooksReleased = useFlag('authHooksReleased')
|
||||
const columnLevelPrivileges = useIsColumnLevelPrivilegesEnabled()
|
||||
|
||||
useAuthConfigPrefetch({ projectRef })
|
||||
@@ -30,7 +29,7 @@ const AuthLayout = ({ title, children }: PropsWithChildren<AuthLayoutProps>) =>
|
||||
productMenu={
|
||||
<ProductMenu
|
||||
page={page}
|
||||
menu={generateAuthMenu(projectRef ?? 'default', { hooksReleased, columnLevelPrivileges })}
|
||||
menu={generateAuthMenu(projectRef ?? 'default', { columnLevelPrivileges })}
|
||||
/>
|
||||
}
|
||||
isBlocking={false}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { IS_PLATFORM } from 'lib/constants'
|
||||
|
||||
export const generateAuthMenu = (
|
||||
ref: string,
|
||||
options: { hooksReleased?: boolean; columnLevelPrivileges?: boolean } = {}
|
||||
options: { columnLevelPrivileges?: boolean } = {}
|
||||
): ProductMenuGroup[] => {
|
||||
return [
|
||||
{
|
||||
@@ -56,17 +56,13 @@ export const generateAuthMenu = (
|
||||
url: `/project/${ref}/auth/url-configuration`,
|
||||
items: [],
|
||||
},
|
||||
...(options?.hooksReleased
|
||||
? [
|
||||
{
|
||||
name: 'Hooks',
|
||||
key: 'hooks',
|
||||
url: `/project/${ref}/auth/hooks`,
|
||||
items: [],
|
||||
label: 'BETA',
|
||||
},
|
||||
]
|
||||
: []),
|
||||
{
|
||||
name: 'Hooks',
|
||||
key: 'hooks',
|
||||
url: `/project/${ref}/auth/hooks`,
|
||||
items: [],
|
||||
label: 'BETA',
|
||||
},
|
||||
]
|
||||
: []),
|
||||
],
|
||||
|
||||
Reference in new issue
Block a user