diff --git a/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreview.constants.tsx b/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreview.constants.tsx index 89c110dd04d69..613710619da27 100644 --- a/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreview.constants.tsx +++ b/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreview.constants.tsx @@ -3,8 +3,8 @@ import { LOCAL_STORAGE_KEYS } from 'common' export const FEATURE_PREVIEWS = [ { key: LOCAL_STORAGE_KEYS.UI_PREVIEW_SECURITY_NOTIFICATIONS, - name: 'Security notification templates', - discussionsUrl: undefined, + name: 'Security notification emails', + discussionsUrl: 'https://github.com/orgs/supabase/discussions/40349', isNew: true, isPlatformOnly: true, }, diff --git a/apps/studio/components/interfaces/App/FeaturePreview/SecurityNotificationsPreview.tsx b/apps/studio/components/interfaces/App/FeaturePreview/SecurityNotificationsPreview.tsx index 8857881dfa4fb..92254271ac741 100644 --- a/apps/studio/components/interfaces/App/FeaturePreview/SecurityNotificationsPreview.tsx +++ b/apps/studio/components/interfaces/App/FeaturePreview/SecurityNotificationsPreview.tsx @@ -3,11 +3,9 @@ import Image from 'next/image' import { useParams } from 'common' import { InlineLink } from 'components/ui/InlineLink' import { BASE_PATH } from 'lib/constants' -import { useIsSecurityNotificationsEnabled } from './FeaturePreviewContext' export const SecurityNotificationsPreview = () => { const { ref } = useParams() - const isSecurityNotificationsEnabled = useIsSecurityNotificationsEnabled() return (
@@ -21,11 +19,7 @@ export const SecurityNotificationsPreview = () => {

Try out our expanded set of{' '} - - email templates - {' '} + email templates{' '} with support for security-related notifications.

Enabling this preview will:

@@ -37,8 +31,7 @@ export const SecurityNotificationsPreview = () => {

These changes are necessary to support incoming security-related notification templates. Given that the list of our email templates is doubling in size, this change requires some - wider interface changes. Ones that we think make for a clearer experience overall. Win - win! + wider interface changes. Ones that we think make for a clearer experience overall.

diff --git a/apps/studio/components/interfaces/Auth/EmailRateLimitsAlert/EmailRateLimitsAlert.tsx b/apps/studio/components/interfaces/Auth/EmailRateLimitsAlert.tsx similarity index 95% rename from apps/studio/components/interfaces/Auth/EmailRateLimitsAlert/EmailRateLimitsAlert.tsx rename to apps/studio/components/interfaces/Auth/EmailRateLimitsAlert.tsx index 09ea5b0e90820..f2ebefc51a2e0 100644 --- a/apps/studio/components/interfaces/Auth/EmailRateLimitsAlert/EmailRateLimitsAlert.tsx +++ b/apps/studio/components/interfaces/Auth/EmailRateLimitsAlert.tsx @@ -6,7 +6,7 @@ import { DOCS_URL } from 'lib/constants' import { Button } from 'ui' import { Admonition } from 'ui-patterns/admonition' -export function EmailRateLimitsAlert() { +export const EmailRateLimitsAlert = () => { const { ref } = useParams() return ( diff --git a/apps/studio/components/interfaces/Auth/EmailRateLimitsAlert/index.tsx b/apps/studio/components/interfaces/Auth/EmailRateLimitsAlert/index.tsx deleted file mode 100644 index ab1bdb81f1779..0000000000000 --- a/apps/studio/components/interfaces/Auth/EmailRateLimitsAlert/index.tsx +++ /dev/null @@ -1,3 +0,0 @@ -import { EmailRateLimitsAlert } from './EmailRateLimitsAlert' - -export default EmailRateLimitsAlert diff --git a/apps/studio/components/interfaces/Auth/EmailTemplates/EmailTemplates.tsx b/apps/studio/components/interfaces/Auth/EmailTemplates/EmailTemplates.tsx index 433675f8bd351..fb159110cff80 100644 --- a/apps/studio/components/interfaces/Auth/EmailTemplates/EmailTemplates.tsx +++ b/apps/studio/components/interfaces/Auth/EmailTemplates/EmailTemplates.tsx @@ -1,21 +1,26 @@ import { zodResolver } from '@hookform/resolvers/zod' import { PermissionAction } from '@supabase/shared-types/out/constants' -import { ChevronRight } from 'lucide-react' +import { ChevronRight, ExternalLink, X } from 'lucide-react' import Link from 'next/link' import { useEffect } from 'react' import { useForm } from 'react-hook-form' import { toast } from 'sonner' import { z } from 'zod' -import { useParams } from 'common' +import { LOCAL_STORAGE_KEYS, useParams } from 'common' +import { FEATURE_PREVIEWS } from 'components/interfaces/App/FeaturePreview/FeaturePreview.constants' import { useIsSecurityNotificationsEnabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext' import { ScaffoldSection, ScaffoldSectionTitle } from 'components/layouts/Scaffold' import AlertError from 'components/ui/AlertError' +import { InlineLink } from 'components/ui/InlineLink' import { GenericSkeletonLoader } from 'components/ui/ShimmeringLoader' import { useAuthConfigQuery } from 'data/auth/auth-config-query' import { useAuthConfigUpdateMutation } from 'data/auth/auth-config-update-mutation' import { useAsyncCheckPermissions } from 'hooks/misc/useCheckPermissions' +import { useLocalStorageQuery } from 'hooks/misc/useLocalStorage' +import { DOCS_URL } from 'lib/constants' import { + Badge, Button, Card, CardContent, @@ -28,9 +33,13 @@ import { TabsContent_Shadcn_, TabsList_Shadcn_, TabsTrigger_Shadcn_, + Tooltip, + TooltipContent, + TooltipTrigger, } from 'ui' +import { Admonition } from 'ui-patterns' import { TEMPLATES_SCHEMAS } from '../AuthTemplatesValidation' -import EmailRateLimitsAlert from '../EmailRateLimitsAlert' +import { EmailRateLimitsAlert } from '../EmailRateLimitsAlert' import { slugifyTitle } from './EmailTemplates.utils' import { TemplateEditor } from './TemplateEditor' @@ -50,6 +59,10 @@ const NotificationsFormSchema = z.object({ ), }) +const SECURITY_NOTIFICATIONS_DISCUSSIONS_URL = FEATURE_PREVIEWS.find( + (f) => f.key === LOCAL_STORAGE_KEYS.UI_PREVIEW_SECURITY_NOTIFICATIONS +)?.discussionsUrl + export const EmailTemplates = () => { const { ref: projectRef } = useParams() const isSecurityNotificationsEnabled = useIsSecurityNotificationsEnabled() @@ -58,6 +71,11 @@ export const EmailTemplates = () => { 'custom_config_gotrue' ) + const [acknowledged, setAcknowledged] = useLocalStorageQuery( + LOCAL_STORAGE_KEYS.SECURITY_NOTIFICATIONS_ACKNOWLEDGED(projectRef ?? ''), + false + ) + const { data: authConfig, error: authConfigError, @@ -161,6 +179,60 @@ export const EmailTemplates = () => {
Security + {!acknowledged && ( + + + setAcknowledged(true)} + className="absolute top-3 right-3 opacity-30 hover:opacity-100 transition-opacity" + > + + + Dismiss + +
+
+
+ + NEW + +

+ Notify users about security-sensitive actions on their accounts +

+
+

+ We’ve expanded our email templates to handle security-sensitive actions. + The list of templates will continue to grow as our feature-set changes + {SECURITY_NOTIFICATIONS_DISCUSSIONS_URL && ( + <> + {' '} + and as we{' '} + + gather feedback + {' '} + from our community + + )} + . +

+
+ +
+
+ )} +
diff --git a/apps/studio/components/interfaces/SQLEditor/UtilityPanel/ChartConfig.tsx b/apps/studio/components/interfaces/SQLEditor/UtilityPanel/ChartConfig.tsx index 6dd29c18b8c7a..046673923f572 100644 --- a/apps/studio/components/interfaces/SQLEditor/UtilityPanel/ChartConfig.tsx +++ b/apps/studio/components/interfaces/SQLEditor/UtilityPanel/ChartConfig.tsx @@ -206,7 +206,7 @@ export const ChartConfig = ({ setAcknowledged(true)} - className="absolute top-3 right-3 opacity-0 group-hover:opacity-100 transition-opacity" + className="absolute top-3 right-3 opacity-30 group-hover:opacity-100 transition-opacity" > diff --git a/apps/studio/pages/project/[ref]/auth/templates/[templateId].tsx b/apps/studio/pages/project/[ref]/auth/templates/[templateId].tsx index 6342ab306e583..be89c68b8882f 100644 --- a/apps/studio/pages/project/[ref]/auth/templates/[templateId].tsx +++ b/apps/studio/pages/project/[ref]/auth/templates/[templateId].tsx @@ -234,7 +234,7 @@ const RedirectToTemplates = () => { {/* Only show title if there is an another section above */} {showConfigurationSection && ( - Contents + Content )} diff --git a/apps/studio/public/img/previews/security-notifications-preview.png b/apps/studio/public/img/previews/security-notifications-preview.png index 262ed16f4d957..26e6b0431c30c 100644 Binary files a/apps/studio/public/img/previews/security-notifications-preview.png and b/apps/studio/public/img/previews/security-notifications-preview.png differ diff --git a/packages/common/constants/local-storage.ts b/packages/common/constants/local-storage.ts index af70e1874ace9..2656fc7160317 100644 --- a/packages/common/constants/local-storage.ts +++ b/packages/common/constants/local-storage.ts @@ -40,6 +40,10 @@ export const LOCAL_STORAGE_KEYS = { SQL_EDITOR_SECTION_STATE: (ref: string) => `sql-editor-section-state-${ref}`, SQL_EDITOR_SORT: (ref: string) => `sql-editor-sort-${ref}`, + // Key to track if the user has acknowledged the security notifications preview + SECURITY_NOTIFICATIONS_ACKNOWLEDGED: (ref: string) => + `security-notifications-acknowledged-${ref}`, + LOG_EXPLORER_SPLIT_SIZE: 'supabase_log-explorer-split-size', GRAPHIQL_RLS_BYPASS_WARNING: 'graphiql-rls-bypass-warning-dismissed', CLS_DIFF_WARNING: 'cls-diff-warning-dismissed',