mirror of
https://github.com/supabase/supabase.git
synced 2026-10-06 01:45:10 +03:00
Joshen/depr 253 tighten field validation for bucket name and table name (#40739)
* Update validation for analytics bucket name * Update comment * Update bucket name validation for vector buckets
This commit is contained in:
1 parent
25cd2af2a5
commit
31a026e6f0
4 files changed
+104
-13
No files matched your search
+52
-6
@@ -38,17 +38,21 @@ import {
|
||||
} from 'ui'
|
||||
import { Admonition } from 'ui-patterns'
|
||||
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
|
||||
import { inverseValidBucketNameRegex, validBucketNameRegex } from '../CreateBucketModal.utils'
|
||||
import { BUCKET_TYPES } from '../Storage.constants'
|
||||
import { useIcebergWrapperExtension } from './AnalyticsBucketDetails/useIcebergWrapper'
|
||||
import {
|
||||
reservedPrefixes,
|
||||
reservedSuffixes,
|
||||
validBucketNameRegex,
|
||||
} from './CreateAnalyticsBucketModal.utils'
|
||||
|
||||
const FormSchema = z
|
||||
.object({
|
||||
name: z
|
||||
.string()
|
||||
.trim()
|
||||
.min(1, 'Please provide a name for your bucket')
|
||||
.max(100, 'Bucket name should be below 100 characters')
|
||||
.min(3, 'Bucket name should be at least 3 characters')
|
||||
.max(63, 'Bucket name should be up to 63 characters')
|
||||
.refine(
|
||||
(value) => !value.endsWith(' '),
|
||||
'The name of the bucket cannot end with a whitespace'
|
||||
@@ -59,9 +63,51 @@ const FormSchema = z
|
||||
),
|
||||
})
|
||||
.superRefine((data, ctx) => {
|
||||
if (reservedPrefixes.test(data.name)) {
|
||||
const [match] = data.name.match(reservedPrefixes) ?? []
|
||||
return ctx.addIssue({
|
||||
path: ['name'],
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Bucket name cannot start with "${match}"`,
|
||||
})
|
||||
}
|
||||
|
||||
if (reservedSuffixes.test(data.name)) {
|
||||
const [match] = data.name.match(reservedSuffixes) ?? []
|
||||
return ctx.addIssue({
|
||||
path: ['name'],
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Bucket name cannot end with "${match}"`,
|
||||
})
|
||||
}
|
||||
|
||||
if (/[A-Z]/.test(data.name)) {
|
||||
return ctx.addIssue({
|
||||
path: ['name'],
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: 'Bucket name can only be lowercase characters',
|
||||
})
|
||||
}
|
||||
|
||||
if (!validBucketNameRegex.test(data.name)) {
|
||||
const [match] = data.name.match(inverseValidBucketNameRegex) ?? []
|
||||
ctx.addIssue({
|
||||
if (!/^[a-z0-9]/.test(data.name)) {
|
||||
return ctx.addIssue({
|
||||
path: ['name'],
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: 'Bucket name must start with a lowercase letter or number.',
|
||||
})
|
||||
}
|
||||
|
||||
if (!/[a-z0-9]$/.test(data.name)) {
|
||||
return ctx.addIssue({
|
||||
path: ['name'],
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: 'Bucket name must end with a lowercase letter or number.',
|
||||
})
|
||||
}
|
||||
|
||||
const [match] = data.name.match(/[^a-z0-9-]/) ?? []
|
||||
return ctx.addIssue({
|
||||
path: ['name'],
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: !!match
|
||||
@@ -238,7 +284,7 @@ export const CreateAnalyticsBucketModal = ({
|
||||
name="name"
|
||||
label="Bucket name"
|
||||
labelOptional="Cannot be changed after creation"
|
||||
description="Must be between 3–63 characters. Only lowercase letters, numbers, dots, and hyphens are allowed."
|
||||
description="Must be between 3–63 characters. Only lowercase letters, numbers, and hyphens are allowed."
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<Input_Shadcn_
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Rules: https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-tables-buckets-naming.html?i
|
||||
* Bucket names must be between 3 and 63 characters long.
|
||||
* Bucket names can consist only of lowercase letters, numbers, and hyphens (-).
|
||||
* Bucket names must begin and end with a letter or number.
|
||||
* Bucket names must not contain any underscores (_) or periods (.).
|
||||
* Bucket names must not start with any of the following reserved prefixes:
|
||||
xn--, sthree-, amzn-s3-demo-, aws
|
||||
* Bucket names must not end with any of the following reserved suffixes:
|
||||
-s3alias, --ol-s3, --x-s3, --table-s3
|
||||
*/
|
||||
export const reservedPrefixes = /^(?:xn--|sthree-|amzn-s3-demo-|aws)/
|
||||
export const reservedSuffixes = /(?:-s3alias|--ol-s3|--x-s3|--table-s3)$/
|
||||
export const validBucketNameRegex = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/
|
||||
+31
-7
@@ -1,11 +1,11 @@
|
||||
import { zodResolver } from '@hookform/resolvers/zod'
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { Plus } from 'lucide-react'
|
||||
import { parseAsBoolean, useQueryState } from 'nuqs'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { SubmitHandler, useForm } from 'react-hook-form'
|
||||
import { toast } from 'sonner'
|
||||
import z from 'zod'
|
||||
import { parseAsBoolean, useQueryState } from 'nuqs'
|
||||
|
||||
import { useParams } from 'common'
|
||||
import { ButtonTooltip } from 'components/ui/ButtonTooltip'
|
||||
@@ -36,7 +36,7 @@ import {
|
||||
} from 'ui'
|
||||
import { Admonition } from 'ui-patterns/admonition'
|
||||
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
|
||||
import { inverseValidBucketNameRegex, validBucketNameRegex } from '../CreateBucketModal.utils'
|
||||
import { validVectorBucketName } from './CreateVectorBucketDialog.utils'
|
||||
import { useS3VectorsWrapperExtension } from './useS3VectorsWrapper'
|
||||
import { getVectorBucketFDWSchemaName } from './VectorBuckets.utils'
|
||||
|
||||
@@ -44,12 +44,36 @@ const FormSchema = z.object({
|
||||
name: z
|
||||
.string()
|
||||
.trim()
|
||||
.min(1, 'Please provide a name for your bucket')
|
||||
.max(100, 'Bucket name should be below 100 characters')
|
||||
.min(3, 'Bucket name should be at least 3 characters')
|
||||
.max(63, 'Bucket name should be up to 63 characters')
|
||||
.superRefine((name, ctx) => {
|
||||
if (!validBucketNameRegex.test(name)) {
|
||||
const [match] = name.match(inverseValidBucketNameRegex) ?? []
|
||||
ctx.addIssue({
|
||||
if (!validVectorBucketName.test(name)) {
|
||||
if (/[A-Z]/.test(name)) {
|
||||
return ctx.addIssue({
|
||||
path: [],
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: 'Bucket name can only be lowercase characters',
|
||||
})
|
||||
}
|
||||
|
||||
if (!/^[a-z0-9]/.test(name)) {
|
||||
return ctx.addIssue({
|
||||
path: [],
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: 'Bucket name must start with a lowercase letter or number.',
|
||||
})
|
||||
}
|
||||
|
||||
if (!/[a-z0-9]$/.test(name)) {
|
||||
return ctx.addIssue({
|
||||
path: [],
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: 'Bucket name must end with a lowercase letter or number.',
|
||||
})
|
||||
}
|
||||
|
||||
const [match] = name.match(/[^a-z0-9-]/) ?? []
|
||||
return ctx.addIssue({
|
||||
path: [],
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: !!match
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* Rules: https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-vectors-buckets-naming.html?icmpid=docs_amazons3_console
|
||||
* Vector bucket names must be between 3 and 63 characters long.
|
||||
* Vector bucket names can consist only of lowercase letters (a-z), numbers (0-9), and hyphens (-).
|
||||
* Vector bucket names must begin and end with a letter or number.
|
||||
*/
|
||||
export const validVectorBucketName = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/
|
||||
Reference in new issue
Block a user