Skip to content

Commit be03157

Browse files
authored
Merge pull request #6497 from Shopify/10-09-add_strict_validations_for_uids
Add strict validations for UIDs
2 parents 3f41579 + 6c79dbc commit be03157

File tree

2 files changed

+66
-2
lines changed

2 files changed

+66
-2
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import {BaseSchema, MAX_UID_LENGTH} from './schemas.js'
2+
import {describe, expect, test} from 'vitest'
3+
4+
const validUIDTestCases = [
5+
['valid-uid-123', 'UID with alphanumeric characters and hyphens'],
6+
['validuid', 'UID with only letters'],
7+
['123456', 'UID with only numbers'],
8+
['valid-uid-with-many-hyphens', 'UID with multiple hyphens in the middle'],
9+
['valid_uid', 'UID with underscore'],
10+
['valid.uid', 'UID with dot'],
11+
['valid()uid', 'UID with parentheses'],
12+
['valid{}uid', 'UID with curly braces'],
13+
['valid$uid', 'UID with dollar sign'],
14+
['a'.repeat(MAX_UID_LENGTH), 'UID at maximum length'],
15+
]
16+
17+
const invalidUIDTestCases = [
18+
['', "UID can't be empty"],
19+
[' ', "UID can't be empty"],
20+
['a'.repeat(MAX_UID_LENGTH + 1), `UID can't exceed ${MAX_UID_LENGTH} characters`],
21+
['a'.repeat(MAX_UID_LENGTH + 50), `UID can't exceed ${MAX_UID_LENGTH} characters`],
22+
['invalid uid', 'UID can only contain alphanumeric characters and hyphens'],
23+
['invalid@uid!', 'UID can only contain alphanumeric characters and hyphens'],
24+
['invalid/uid', 'UID can only contain alphanumeric characters and hyphens'],
25+
['-invalid-uid', "UID can't start or end with a hyphen"],
26+
['invalid-uid-', "UID can't start or end with a hyphen"],
27+
['-invalid-uid-', "UID can't start or end with a hyphen"],
28+
['-', "UID can't start or end with a hyphen"],
29+
['-----', "UID can't start or end with a hyphen"],
30+
]
31+
32+
describe('UIDSchema', () => {
33+
describe('valid UIDs', () => {
34+
test.each(validUIDTestCases)('accepts %s (%s)', (uid) => {
35+
const result = BaseSchema.safeParse({uid})
36+
expect(result.success).toBe(true)
37+
})
38+
39+
test('trims whitespace from UID', () => {
40+
const result = BaseSchema.safeParse({uid: ' valid-uid '})
41+
expect(result.success).toBe(true)
42+
if (result.success) {
43+
expect(result.data.uid).toBe('valid-uid')
44+
}
45+
})
46+
})
47+
48+
describe('invalid UIDs', () => {
49+
test.each(invalidUIDTestCases)('rejects "%s" with error: %s', (uid, expectedError) => {
50+
const result = BaseSchema.safeParse({uid})
51+
expect(result.success).toBe(false)
52+
if (!result.success) {
53+
expect(result.error.issues[0]?.message).toBe(expectedError)
54+
}
55+
})
56+
})
57+
})

packages/app/src/cli/models/extensions/schemas.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,20 @@ const HandleSchema = zod
8888
.max(MAX_EXTENSION_HANDLE_LENGTH, `Handle can't exceed ${MAX_EXTENSION_HANDLE_LENGTH} characters`)
8989
.regex(/^[a-zA-Z0-9-]*$/, 'Handle can only contain alphanumeric characters and hyphens')
9090
.refine((handle) => !handle.startsWith('-') && !handle.endsWith('-'), "Handle can't start or end with a hyphen")
91-
.refine((handle) => [...handle].some((char) => char !== '-'), "Handle can't be all hyphens")
91+
92+
const UIDSchema = zod
93+
.string()
94+
.trim()
95+
.nonempty("UID can't be empty")
96+
.max(MAX_UID_LENGTH, `UID can't exceed ${MAX_UID_LENGTH} characters`)
97+
.regex(/^[a-zA-Z0-9-${}.()_`]*$/, 'UID can only contain alphanumeric characters and hyphens')
98+
.refine((uid) => !uid.startsWith('-') && !uid.endsWith('-'), "UID can't start or end with a hyphen")
9299

93100
export const BaseSchema = zod.object({
94101
name: zod.string().optional(),
95102
type: zod.string().optional(),
96103
handle: HandleSchema.optional(),
97-
uid: zod.string().optional(),
104+
uid: UIDSchema.optional(),
98105
description: zod.string().optional(),
99106
api_version: ApiVersionSchema.optional(),
100107
extension_points: zod.any().optional(),

0 commit comments

Comments
 (0)