From ee9ca4fa0b640b1fcf4955b6659960de8e0b3294 Mon Sep 17 00:00:00 2001 From: Ivan Vasilov Date: Wed, 11 Dec 2024 05:26:24 +0100 Subject: [PATCH 1/6] fix: Change the users infinite query to use like instead of ilike (#31048) Change the users infinite query to use like instead of ilike. --- apps/studio/data/auth/users-infinite-query.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/studio/data/auth/users-infinite-query.ts b/apps/studio/data/auth/users-infinite-query.ts index 01f817eea5717..dfba22c23a445 100644 --- a/apps/studio/data/auth/users-infinite-query.ts +++ b/apps/studio/data/auth/users-infinite-query.ts @@ -45,7 +45,7 @@ export const getUsersSQL = ({ if (hasValidKeywords) { conditions.push( - `id::text ilike '%${keywords}%' or email ilike '%${keywords}%' or phone ilike '%${keywords}%'` + `id::text like '%${keywords}%' or email like '%${keywords}%' or phone like '%${keywords}%'` ) } From ff3522f856d4533ea0918c136c6081ac2352db76 Mon Sep 17 00:00:00 2001 From: Monica Khoury <99693443+monicakh@users.noreply.github.com> Date: Wed, 11 Dec 2024 06:56:10 +0200 Subject: [PATCH 2/6] chore: Remove auth email warning for org members (#31043) * chore: Remove auth email warning for org members * Edit auth warning on Settings page * Clean up * Add comment * More clean up --------- Co-authored-by: Joshen Lim --- .../EmailRateLimitsAlert.tsx | 36 ++++++++---------- .../Auth/EmailTemplates/EmailTemplates.tsx | 8 +++- .../layouts/ProjectLayout/ProjectLayout.tsx | 2 +- ...sourceExhaustionWarningBanner.constants.ts | 33 ---------------- .../ResourceExhaustionWarningBanner.tsx | 38 ++----------------- apps/studio/lib/constants/index.ts | 2 - 6 files changed, 26 insertions(+), 93 deletions(-) diff --git a/apps/studio/components/interfaces/Auth/EmailRateLimitsAlert/EmailRateLimitsAlert.tsx b/apps/studio/components/interfaces/Auth/EmailRateLimitsAlert/EmailRateLimitsAlert.tsx index 843ce6f9e746d..4eb4b01e371c7 100644 --- a/apps/studio/components/interfaces/Auth/EmailRateLimitsAlert/EmailRateLimitsAlert.tsx +++ b/apps/studio/components/interfaces/Auth/EmailRateLimitsAlert/EmailRateLimitsAlert.tsx @@ -1,11 +1,16 @@ import Link from 'next/link' import { useParams } from 'common' -import { AlertDescription_Shadcn_, AlertTitle_Shadcn_, Alert_Shadcn_, WarningIcon } from 'ui' +import { + AlertDescription_Shadcn_, + AlertTitle_Shadcn_, + Alert_Shadcn_, + Button, + WarningIcon, +} from 'ui' export function EmailRateLimitsAlert() { - const { ref: projectRef } = useParams() - const after20240926 = Date.now() >= new Date('20240926T00:00:00Z').getTime() + const { ref } = useParams() return ( @@ -14,30 +19,21 @@ export function EmailRateLimitsAlert() { You're using the built-in email service. The service has rate limits and it's not meant to be used for production apps. Check the{' '} + {/* [Refactor] Swap for InlineLink component once https://github.com/supabase/supabase/pull/30494 is in */} documentation {' '} - for an up-to-date information on the current rate limits.{' '} - - Set up a custom SMTP server now. - - - - {after20240926 - ? 'To fight abuse, Auth email messages are restricted ' - : 'On 26th September: To fight abuse, Auth email messages will be restricted '} - to your project's organization members. For example, if your organization has 3 members with - addresses: person-a@example.com, person-b@example.com and{' '} - person-c@example.com, messages will be{' '} - sent to those addresses only. Set up custom SMTP to send to any user. + for an up-to-date information on the current rate limits. + ) diff --git a/apps/studio/components/interfaces/Auth/EmailTemplates/EmailTemplates.tsx b/apps/studio/components/interfaces/Auth/EmailTemplates/EmailTemplates.tsx index 9bced7ff31652..80d6ba89f5dd7 100644 --- a/apps/studio/components/interfaces/Auth/EmailTemplates/EmailTemplates.tsx +++ b/apps/studio/components/interfaces/Auth/EmailTemplates/EmailTemplates.tsx @@ -5,7 +5,7 @@ import { FormHeader } from 'components/ui/Forms/FormHeader' import { FormPanel } from 'components/ui/Forms/FormPanel' import { GenericSkeletonLoader } from 'components/ui/ShimmeringLoader' import { useAuthConfigQuery } from 'data/auth/auth-config-query' -import { Tabs, Tabs_Shadcn_, TabsContent_Shadcn_, TabsList_Shadcn_, TabsTrigger_Shadcn_ } from 'ui' +import { Tabs_Shadcn_, TabsContent_Shadcn_, TabsList_Shadcn_, TabsTrigger_Shadcn_ } from 'ui' import { TEMPLATES_SCHEMAS } from '../AuthTemplatesValidation' import EmailRateLimitsAlert from '../EmailRateLimitsAlert' import TemplateEditor from './TemplateEditor' @@ -39,7 +39,11 @@ const EmailTemplates = () => { {isError && ( )} - {isLoading && } + {isLoading && ( +
+ +
+ )} {isSuccess && ( diff --git a/apps/studio/components/layouts/ProjectLayout/ProjectLayout.tsx b/apps/studio/components/layouts/ProjectLayout/ProjectLayout.tsx index c01542b6a4b77..594c92f1aee2f 100644 --- a/apps/studio/components/layouts/ProjectLayout/ProjectLayout.tsx +++ b/apps/studio/components/layouts/ProjectLayout/ProjectLayout.tsx @@ -7,7 +7,7 @@ import ProjectAPIDocs from 'components/interfaces/ProjectAPIDocs/ProjectAPIDocs' import { AIAssistantPanel } from 'components/ui/AIAssistantPanel/AIAssistantPanel' import AISettingsModal from 'components/ui/AISettingsModal' import { Loading } from 'components/ui/Loading' -import ResourceExhaustionWarningBanner from 'components/ui/ResourceExhaustionWarningBanner/ResourceExhaustionWarningBanner' +import { ResourceExhaustionWarningBanner } from 'components/ui/ResourceExhaustionWarningBanner/ResourceExhaustionWarningBanner' import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization' import { useSelectedProject } from 'hooks/misc/useSelectedProject' import { withAuth } from 'hooks/misc/withAuth' diff --git a/apps/studio/components/ui/ResourceExhaustionWarningBanner/ResourceExhaustionWarningBanner.constants.ts b/apps/studio/components/ui/ResourceExhaustionWarningBanner/ResourceExhaustionWarningBanner.constants.ts index fc10cb7651234..e1fe17b52da78 100644 --- a/apps/studio/components/ui/ResourceExhaustionWarningBanner/ResourceExhaustionWarningBanner.constants.ts +++ b/apps/studio/components/ui/ResourceExhaustionWarningBanner/ResourceExhaustionWarningBanner.constants.ts @@ -5,7 +5,6 @@ interface ResourceWarningMessage { bannerContent: { warning: { title: string; description: string } critical: { title?: string; description?: string } - allowDismissable?: boolean } cardContent: { warning: { title: string; description: string } @@ -213,36 +212,4 @@ export const RESOURCE_WARNING_MESSAGES: Record = buttonText: 'Check usage', metric: null, }, - // [Joshen] We can remove this once auth team gives the signal to - auth_restricted_email_sending: { - restrictToRoutes: ['/project/[ref]/auth', '/project/[ref]/settings/auth'], // project home, auth, settings - bannerContent: { - warning: { - title: "Authentication emails are only sent to organization members' email addresses", - description: - 'Set up a custom SMTP provider to handle flows like password reset which require sending emails to any user', - }, - critical: { - title: "Authentication emails are only sent to organization members' email addresses", - description: - 'Set up a custom SMTP provider to handle flows like password reset which require sending emails to any user', - }, - allowDismissable: true, - }, - cardContent: { - warning: { - title: 'Auth emails are restricted', - description: - "Your project can only send Auth emails to your organization's members. Set up a custom SMTP provider to send Auth emails to any user", - }, - critical: { - title: 'Auth emails are restricted', - description: - "Your project can only send Auth emails to your organization's members. Set up a custom SMTP provider to send Auth emails to any user.", - }, - }, - docsUrl: 'https://github.com/orgs/supabase/discussions/29370', - buttonText: 'Set up custom SMTP now', - metric: 'auth_restricted_email_sending', - }, } diff --git a/apps/studio/components/ui/ResourceExhaustionWarningBanner/ResourceExhaustionWarningBanner.tsx b/apps/studio/components/ui/ResourceExhaustionWarningBanner/ResourceExhaustionWarningBanner.tsx index bf79befa70428..583872abb201a 100644 --- a/apps/studio/components/ui/ResourceExhaustionWarningBanner/ResourceExhaustionWarningBanner.tsx +++ b/apps/studio/components/ui/ResourceExhaustionWarningBanner/ResourceExhaustionWarningBanner.tsx @@ -1,4 +1,4 @@ -import { AlertTriangle, ExternalLink, X } from 'lucide-react' +import { AlertTriangle, ExternalLink } from 'lucide-react' import Link from 'next/link' import { useRouter } from 'next/router' @@ -7,10 +7,8 @@ import { useResourceWarningsQuery } from 'data/usage/resource-warnings-query' import { AlertDescription_Shadcn_, AlertTitle_Shadcn_, Alert_Shadcn_, Button, cn } from 'ui' import { RESOURCE_WARNING_MESSAGES } from './ResourceExhaustionWarningBanner.constants' import { getWarningContent } from './ResourceExhaustionWarningBanner.utils' -import { useLocalStorageQuery } from 'hooks/misc/useLocalStorage' -import { LOCAL_STORAGE_KEYS } from 'lib/constants' -const ResourceExhaustionWarningBanner = () => { +export const ResourceExhaustionWarningBanner = () => { const { ref } = useParams() const router = useRouter() const { data: resourceWarnings } = useResourceWarningsQuery() @@ -18,11 +16,6 @@ const ResourceExhaustionWarningBanner = () => { (warning) => warning.project === ref ) - const [bannerAcknowledged, setBannerAcknowledged] = useLocalStorageQuery( - LOCAL_STORAGE_KEYS.AUTH_EMAIL_WARNING_BANNER_ACKNOWLEDGE(ref ?? ''), - false - ) - // [Joshen] Read only takes higher precedence over multiple resource warnings const activeWarnings = projectResourceWarnings !== undefined @@ -85,10 +78,6 @@ const ResourceExhaustionWarningBanner = () => { default: (metric: string) => `/project/[ref]/settings/[infra-path]#${metric}`, } - const isDismissable = - RESOURCE_WARNING_MESSAGES[metric as keyof typeof RESOURCE_WARNING_MESSAGES]?.bannerContent - .allowDismissable ?? false - const getCorrectionUrl = (metric: string | undefined | null) => { const variant = metric === undefined ? 'undefined' : metric === null ? 'null' : metric const url = @@ -137,21 +126,12 @@ const ResourceExhaustionWarningBanner = () => { return isMatch }) - // [Joshen] Only certain warnings should be dismissable, in this case for now, - // only the auth email banner should be, everything else should not be dismissable - const dismissBanner = () => { - setBannerAcknowledged(true) - } - if ( hasNoWarnings || hasNoWarningContent || onUsageOrInfraAndNotInReadOnlyMode || onDatabaseSettingsAndInReadOnlyMode || - !isVisible || - (router.pathname.includes('/auth/') && - !!projectResourceWarnings?.auth_restricted_email_sending && - bannerAcknowledged) + !isVisible ) { return null } @@ -182,19 +162,7 @@ const ResourceExhaustionWarningBanner = () => { {buttonText ?? 'Check'} )} - {isDismissable && ( - - )} ) } - -export default ResourceExhaustionWarningBanner diff --git a/apps/studio/lib/constants/index.ts b/apps/studio/lib/constants/index.ts index 874cda2f4b259..b43f1305c8f77 100644 --- a/apps/studio/lib/constants/index.ts +++ b/apps/studio/lib/constants/index.ts @@ -73,8 +73,6 @@ export const LOCAL_STORAGE_KEYS = { AUTH_SMTP_CHANGES_WARNING: 'auth-smtp-changes-warning-dismissed', AUTH_USERS_COLUMNS_CONFIGURATION: (ref: string) => `supabase-auth-users-columns-${ref}`, - AUTH_EMAIL_WARNING_BANNER_ACKNOWLEDGE: (ref: string) => - `supabase-auth-email-warning-banner-${ref}`, } export const OPT_IN_TAGS = { From 397b787eb5863c05e16123e5a456910c086040ea Mon Sep 17 00:00:00 2001 From: Etienne Stalmans Date: Wed, 11 Dec 2024 08:53:40 +0100 Subject: [PATCH 3/6] feat: add project settings option to mark compliance projects (#30494) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: add project settings option to mark compliance projects Projects within organizations with the HIPAA add-on can be mark as "sensitive". These projects will have additional security advisor checks applied and other compliance related guardrails. * prettier * change hipaa check * prettier fix * Update apps/studio/components/interfaces/Settings/General/ComplianceConfig/ProjectComplianceMode.tsx Co-authored-by: Kevin Grüneberg * fix: prettier * Address all feedback * Address refactor * prep to use new docs link --------- Co-authored-by: Kevin Grüneberg Co-authored-by: Joshen Lim --- .../ProjectComplianceMode.tsx | 124 ++++++++++++++++++ .../interfaces/Settings/General/index.ts | 1 + apps/studio/components/ui/InlineLink.tsx | 23 ++++ .../project-compliance-config-mutation.ts | 58 ++++++++ apps/studio/pages/project/[ref]/index.tsx | 11 +- .../pages/project/[ref]/settings/general.tsx | 12 ++ packages/api-types/types/api.d.ts | 22 +++- 7 files changed, 236 insertions(+), 15 deletions(-) create mode 100644 apps/studio/components/interfaces/Settings/General/ComplianceConfig/ProjectComplianceMode.tsx create mode 100644 apps/studio/components/ui/InlineLink.tsx create mode 100644 apps/studio/data/config/project-compliance-config-mutation.ts diff --git a/apps/studio/components/interfaces/Settings/General/ComplianceConfig/ProjectComplianceMode.tsx b/apps/studio/components/interfaces/Settings/General/ComplianceConfig/ProjectComplianceMode.tsx new file mode 100644 index 0000000000000..7883c3a316a3c --- /dev/null +++ b/apps/studio/components/interfaces/Settings/General/ComplianceConfig/ProjectComplianceMode.tsx @@ -0,0 +1,124 @@ +import { PermissionAction } from '@supabase/shared-types/out/constants' +import { Loader2 } from 'lucide-react' +import { useEffect, useState } from 'react' +import { toast } from 'sonner' + +import { useParams } from 'common' +import { useProjectContext } from 'components/layouts/ProjectLayout/ProjectContext' +import { DocsButton } from 'components/ui/DocsButton' +import { FormHeader } from 'components/ui/Forms/FormHeader' +import { FormPanel } from 'components/ui/Forms/FormPanel' +import { FormSection, FormSectionContent, FormSectionLabel } from 'components/ui/Forms/FormSection' +import { useComplianceConfigUpdateMutation } from 'data/config/project-compliance-config-mutation' +import { useProjectSettingsV2Query } from 'data/config/project-settings-v2-query' +import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' +import { Switch, TooltipContent_Shadcn_, TooltipTrigger_Shadcn_, Tooltip_Shadcn_ } from 'ui' +import AlertError from 'components/ui/AlertError' +import { InlineLink } from 'components/ui/InlineLink' + +const ComplianceConfig = () => { + const { ref } = useParams() + const { project } = useProjectContext() + const [isSensitive, setIsSensitive] = useState(false) + + const canUpdateComplianceConfig = useCheckPermissions(PermissionAction.UPDATE, 'projects', { + resource: { project_id: project?.id }, + }) + + const { + data: settings, + error, + isError, + isLoading, + isSuccess, + } = useProjectSettingsV2Query({ projectRef: ref }) + const initialIsSensitive = settings?.is_sensitive || false + + const { mutate: updateComplianceConfig, isLoading: isSubmitting } = + useComplianceConfigUpdateMutation({ + onSuccess: () => { + toast.success('Successfully updated project compliance configuration') + }, + onError: (error) => { + setIsSensitive(initialIsSensitive) + toast.error(`Failed to update project compliance configuration: ${error.message}`) + }, + }) + + const toggleIsSensitive = async () => { + if (!ref) return console.error('Project ref is required') + setIsSensitive(!isSensitive) + updateComplianceConfig({ projectRef: ref, isSensitive: !isSensitive }) + } + + useEffect(() => { + if (!isLoading) setIsSensitive(initialIsSensitive) + }, [isLoading]) + + return ( +
+
+ + +
+ + + Enable security warnings in the{' '} + + Security Advisor + {' '} + to enforce requirements for managing sensitive data +

+ } + > + Apply additional compliance controls to project + + } + > + +
+ {(isLoading || isSubmitting) && ( + + )} + {isError && ( + + )} + {isSuccess && ( + + + {/* [Joshen] Added div as tooltip is messing with data state property of toggle */} +
+ +
+
+ {!canUpdateComplianceConfig && ( + + You need additional permissions to update the compliance configuration for + your project + + )} +
+ )} +
+
+
+
+
+ ) +} + +export default ComplianceConfig diff --git a/apps/studio/components/interfaces/Settings/General/index.ts b/apps/studio/components/interfaces/Settings/General/index.ts index 904c124b6fd8a..bfc7871528a3f 100644 --- a/apps/studio/components/interfaces/Settings/General/index.ts +++ b/apps/studio/components/interfaces/Settings/General/index.ts @@ -4,3 +4,4 @@ export { default as DeleteProjectPanel } from './DeleteProjectPanel/DeleteProjec export { default as DeleteProjectButton } from './DeleteProjectPanel/DeleteProjectButton' export { default as TransferProjectButton } from './TransferProjectPanel/TransferProjectButton' export { default as TransferProjectPanel } from './TransferProjectPanel/TransferProjectPanel' +export { default as ComplianceConfig } from './ComplianceConfig/ProjectComplianceMode' diff --git a/apps/studio/components/ui/InlineLink.tsx b/apps/studio/components/ui/InlineLink.tsx new file mode 100644 index 0000000000000..b33d5981939f8 --- /dev/null +++ b/apps/studio/components/ui/InlineLink.tsx @@ -0,0 +1,23 @@ +import Link from 'next/link' +import { PropsWithChildren } from 'react' + +interface InlineLinkProps { + href: string +} + +export const InlineLink = ({ href, children }: PropsWithChildren) => { + const className = + 'underline transition underline-offset-2 decoration-foreground-lighter hover:decoration-foreground' + if (href.startsWith('http')) { + return ( + + {children} + + ) + } + return ( + + {children} + + ) +} diff --git a/apps/studio/data/config/project-compliance-config-mutation.ts b/apps/studio/data/config/project-compliance-config-mutation.ts new file mode 100644 index 0000000000000..89317a31cf624 --- /dev/null +++ b/apps/studio/data/config/project-compliance-config-mutation.ts @@ -0,0 +1,58 @@ +import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query' +import { toast } from 'sonner' + +import { handleError, patch } from 'data/fetchers' +import type { ResponseError } from 'types' +import { configKeys } from './keys' + +export type ComplianceConfigUpdateVariables = { + projectRef: string + isSensitive: boolean +} + +export async function updateComplianceConfig({ + projectRef, + isSensitive, +}: ComplianceConfigUpdateVariables) { + if (!projectRef) throw new Error('projectRef is required') + + const { data, error } = await patch('/platform/projects/{ref}/settings/sensitivity', { + params: { path: { ref: projectRef } }, + body: { is_sensitive: isSensitive }, + }) + + if (error) handleError(error) + return data +} + +type ComplianceConfigUpdateData = Awaited> + +export const useComplianceConfigUpdateMutation = ({ + onSuccess, + onError, + ...options +}: Omit< + UseMutationOptions, + 'mutationFn' +> = {}) => { + const queryClient = useQueryClient() + + return useMutation( + (vars) => updateComplianceConfig(vars), + { + async onSuccess(data, variables, context) { + const { projectRef } = variables + await queryClient.invalidateQueries(configKeys.settingsV2(projectRef)) + await onSuccess?.(data, variables, context) + }, + async onError(data, variables, context) { + if (onError === undefined) { + toast.error(`Failed to update project compliance configuration: ${data.message}`) + } else { + onError(data, variables, context) + } + }, + ...options, + } + ) +} diff --git a/apps/studio/pages/project/[ref]/index.tsx b/apps/studio/pages/project/[ref]/index.tsx index b30d2e4dce7af..a1ec371cf56ad 100644 --- a/apps/studio/pages/project/[ref]/index.tsx +++ b/apps/studio/pages/project/[ref]/index.tsx @@ -27,6 +27,7 @@ import { TooltipContent_Shadcn_, TooltipTrigger_Shadcn_, } from 'ui' +import { InlineLink } from 'components/ui/InlineLink' const Home: NextPageWithLayout = () => { const connectDialogUpdate = useFlag('connectDialogUpdate') @@ -65,15 +66,9 @@ const Home: NextPageWithLayout = () => { This project is using Postgres with OrioleDB which is currently in preview and not suitable for production workloads. View our{' '} - {/* [Refactor] Make this into a reusable component to use links inline */} - + documentation - {' '} + {' '} for all limitations. diff --git a/apps/studio/pages/project/[ref]/settings/general.tsx b/apps/studio/pages/project/[ref]/settings/general.tsx index c079b53140fb3..3bb917059edfc 100644 --- a/apps/studio/pages/project/[ref]/settings/general.tsx +++ b/apps/studio/pages/project/[ref]/settings/general.tsx @@ -1,4 +1,6 @@ +import { subscriptionHasHipaaAddon } from 'components/interfaces/Billing/Subscription/Subscription.utils' import { + ComplianceConfig, CustomDomainConfig, DeleteProjectPanel, General, @@ -7,14 +9,21 @@ import { import { useProjectContext } from 'components/layouts/ProjectLayout/ProjectContext' import SettingsLayout from 'components/layouts/ProjectSettingsLayout/SettingsLayout' import { ScaffoldContainer, ScaffoldHeader, ScaffoldTitle } from 'components/layouts/Scaffold' +import { useOrgSubscriptionQuery } from 'data/subscriptions/org-subscription-query' import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled' +import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization' import type { NextPageWithLayout } from 'types' const ProjectSettings: NextPageWithLayout = () => { const { project } = useProjectContext() + const selectedOrganization = useSelectedOrganization() + const isBranch = !!project?.parent_project_ref const { projectsTransfer: projectTransferEnabled } = useIsFeatureEnabled(['projects:transfer']) + const { data: subscription } = useOrgSubscriptionQuery({ orgSlug: selectedOrganization?.slug }) + const hasHipaaAddon = subscriptionHasHipaaAddon(subscription) + return ( <> @@ -26,6 +35,9 @@ const ProjectSettings: NextPageWithLayout = () => { {!isBranch ? ( <> + {/* this is only setable on compliance orgs, currently that means HIPAA orgs */} + {/* hasHipaaAddon */} + {true && } {projectTransferEnabled && } diff --git a/packages/api-types/types/api.d.ts b/packages/api-types/types/api.d.ts index 1e34bfb048ad9..3cb1c88ef2e87 100644 --- a/packages/api-types/types/api.d.ts +++ b/packages/api-types/types/api.d.ts @@ -5147,8 +5147,12 @@ export interface components { region: string service_api_keys?: components['schemas']['ProjectServiceApiKeyResponse'][] ssl_enforced: boolean + is_sensitive?: boolean status: string } + ProjectSensitivitySettingResponse: { + is_sensitive: boolean + } /** @enum {string} */ ProjectStatus: | 'ACTIVE_HEALTHY' @@ -6553,6 +6557,9 @@ export interface components { UpdateProjectBody: { name: string } + UpdateProjectSensitivityBody: { + is_sensitive: boolean + } UpdateProviderBody: { attribute_mapping?: components['schemas']['AttributeMapping'] domains?: string[] @@ -13694,29 +13701,30 @@ export interface operations { } } } - /** Updates the given project sensitivity */ - SensitivityController_updateProjectSensitivity: { + /** Update project's sensitivity settings */ + SettingsController_patchProjectSensitivity: { parameters: { path: { /** @description Project ref */ ref: string - } + } } requestBody: { content: { - 'application/json': components['schemas']['MarkSensitiveBody'] + 'application/json': components['schemas']['UpdateProjectSensitivityBody'] } } responses: { 200: { content: { - 'application/json': components['schemas']['ProjectSensitivityResponse'] + 'application/json': components['schemas']['ProjectSensitivitySettingResponse'] } } - 403: { + /** @description Failed to update project's sensitivity setting */ + 404: { content: never } - /** @description Failed to update project */ + /** @description Failed to update project's sensitivity setting */ 500: { content: never } From 03e9bca9d4c88d7de1bad2d411ed26bb99fe51d0 Mon Sep 17 00:00:00 2001 From: Etienne Stalmans Date: Wed, 11 Dec 2024 08:54:43 +0100 Subject: [PATCH 4/6] chore: add documentation for HIPAA projects (#31045) * chore: add documentation for HIPAA projects * add indexing * slightly less awkward wording --- .../NavigationMenu.constants.ts | 1 + .../guides/platform/hipaa-projects.mdx | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 apps/docs/content/guides/platform/hipaa-projects.mdx diff --git a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts index 481c0c944a65e..524457ab66370 100644 --- a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts +++ b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts @@ -2021,6 +2021,7 @@ export const platform: NavMenuConstant = { { name: 'Compute and Disk', url: '/guides/platform/compute-and-disk' }, { name: 'Database Size', url: '/guides/platform/database-size' }, { name: 'Fly Postgres', url: '/guides/platform/fly-postgres' }, + { name: 'HIPAA Projects', url: '/guides/platform/hipaa-projects' }, { name: 'Network Restrictions', url: '/guides/platform/network-restrictions', diff --git a/apps/docs/content/guides/platform/hipaa-projects.mdx b/apps/docs/content/guides/platform/hipaa-projects.mdx new file mode 100644 index 0000000000000..ae0c4b94b4fae --- /dev/null +++ b/apps/docs/content/guides/platform/hipaa-projects.mdx @@ -0,0 +1,28 @@ +--- +id: 'hipaa' +title: 'HIPAA Projects' +description: 'Projects that store or process Protected Health Information (PHI) and other sensitive data' +--- + +You can use Supabase to store and process Protected Health Information (PHI). If you want to start developing healthcare apps on Supabase, reach out to the Supabase team [here](https://forms.supabase.com/hipaa2) to sign the Business Associate Agreement (BAA). + + + +Organizations must have a signed BAA with Supabase and have the Health Insurance Portability and Accountability Act (HIPAA) add-on enabled when dealing with PHI. + + + +## Configuring a HIPAA Project + +When the HIPAA add-on is enabled on an organization, projects within the organization can be configured as _High Compliance_. This configuration can be found in the [General Project Settings page](https://supabase.com/dashboard/project/_/settings) of the dashboard. +Once enabled, additional security checks will be run against the project to ensure the deployed configuration is compliant. These checks are performed on a continual basis and security warnings will appear in the [Security Advisor](https://supabase.com/dashboard/project/_/advisors/security) if a non-compliant setting is detected. + +The required project configuration is outlined in the [shared responsibility model](https://supabase.com/docs/guides/deployment/shared-responsibility-model#managing-healthcare-data) for managing healthcare data. + +These include: + +- Enabling [Point in Time Recovery](/docs/guides/platform/backups#point-in-time-recovery) which requires at least a [small compute add-on](/docs/guides/platform/compute-add-ons). +- Turning on [SSL Enforcement](/docs/guides/platform/ssl-enforcement). +- Enabling [Network Restrictions](/docs/guides/platform/network-restrictions). + +Additional security checks and controls will be added as the security advisor is extended and additional security controls are made available. From dd6f87b756b23f02e2ddcce542314719b912cfaf Mon Sep 17 00:00:00 2001 From: Laurence Isla Date: Wed, 11 Dec 2024 03:50:26 -0500 Subject: [PATCH 5/6] Add Laurence Isla to humans.txt (#31057) --- apps/docs/public/humans.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/docs/public/humans.txt b/apps/docs/public/humans.txt index b631dfe115cde..73b7049235109 100644 --- a/apps/docs/public/humans.txt +++ b/apps/docs/public/humans.txt @@ -56,6 +56,7 @@ Kevin Brolly Kevin Grüneberg Lakshan Perera Laura C +Laurence Isla Long Hoang Łukasz Niemier Margarita Sandomirskaia From d4c928ca72dcae65cfd4b072b3c8a8aea06cd8dd Mon Sep 17 00:00:00 2001 From: Joel Lee Date: Wed, 11 Dec 2024 16:53:08 +0800 Subject: [PATCH 6/6] fix: add frequently asked questions to auth identity linking docs (#31016) * fix: add frequently asked questions to auth identity linking docs * fix: title case Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * fix: update auth linking * Update apps/docs/content/guides/auth/auth-identity-linking.mdx * fix: more docs formatting --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .../docs/content/guides/auth/auth-identity-linking.mdx | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/apps/docs/content/guides/auth/auth-identity-linking.mdx b/apps/docs/content/guides/auth/auth-identity-linking.mdx index ef12b12a45bf1..36c6dffcfd31e 100644 --- a/apps/docs/content/guides/auth/auth-identity-linking.mdx +++ b/apps/docs/content/guides/auth/auth-identity-linking.mdx @@ -172,3 +172,13 @@ if google_identity: + +## Frequently asked questions + +### How to add email/password login to an OAuth account? + +Call the `updateUser({ password: 'validpassword'})` to add email with password authentication to an account created with an OAuth provider (Google, GitHub, etc.). + +### Can you sign up with email if already using OAuth? + +If you try to create an email account after previously signing up with OAuth using the same email, you'll receive an obfuscated user response with no verification email sent. This prevents user enumeration attacks.