diff --git a/fluxer_api/src/Schema.ts b/fluxer_api/src/Schema.ts index e06b69a6..33c6f44a 100644 --- a/fluxer_api/src/Schema.ts +++ b/fluxer_api/src/Schema.ts @@ -215,29 +215,35 @@ export const GlobalNameType = z return !lowerValue.includes('system message'); }, 'Global name cannot contain "system message"'); -export const URLType = z - .string() - .transform(normalizeString) - .refine((value) => value.length >= 1 && value.length <= 2048, 'URL length must be between 1 and 2048 characters') - .refine((value) => { - if (!value.startsWith('http://') && !value.startsWith('https://')) { - return false; - } - try { - const url = new URL(value); - return PROTOCOLS.includes(url.protocol.slice(0, -1)); - } catch { - return false; - } - }, 'Invalid URL format') - .refine( - (value) => - validator.isURL(value, { - ...URL_VALIDATOR_OPTIONS, - require_tld: Config.nodeEnv !== 'development', - }), - 'Invalid URL format', - ); +const createUrlSchema = (allowFragments: boolean) => { + return z + .string() + .transform(normalizeString) + .refine((value) => value.length >= 1 && value.length <= 2048, 'URL length must be between 1 and 2048 characters') + .refine((value) => { + if (!value.startsWith('http://') && !value.startsWith('https://')) { + return false; + } + try { + const url = new URL(value); + return PROTOCOLS.includes(url.protocol.slice(0, -1)); + } catch { + return false; + } + }, 'Invalid URL format') + .refine( + (value) => + validator.isURL(value, { + ...URL_VALIDATOR_OPTIONS, + allow_fragments: allowFragments, + require_tld: Config.nodeEnv !== 'development', + }), + 'Invalid URL format', + ); +}; + +export const URLType = createUrlSchema(false); +export const URLWithFragmentType = createUrlSchema(true); export const AttachmentURLType = z .string() diff --git a/fluxer_api/src/webhook/transformers/GitHubTypes.ts b/fluxer_api/src/webhook/transformers/GitHubTypes.ts index 5705d327..0ef318e4 100644 --- a/fluxer_api/src/webhook/transformers/GitHubTypes.ts +++ b/fluxer_api/src/webhook/transformers/GitHubTypes.ts @@ -17,7 +17,7 @@ * along with Fluxer. If not, see . */ -import {createStringType, Int32Type, URLType, z} from '~/Schema'; +import {createStringType, Int32Type, Int64Type, URLType, URLWithFragmentType, z} from '~/Schema'; const GitHubUser = z.object({ id: Int32Type, @@ -63,8 +63,8 @@ const GitHubCheckRun = z.object({ }); const GitHubComment = z.object({ - id: Int32Type, - html_url: URLType, + id: Int64Type, + html_url: URLWithFragmentType, user: GitHubUser, commit_id: createStringType(0, 152133).nullish(), body: createStringType(0, 152133), @@ -81,13 +81,13 @@ const GitHubDiscussion = z.object({ title: createStringType(0, 152133), number: Int32Type, html_url: URLType, - answer_html_url: URLType.nullish(), + answer_html_url: URLWithFragmentType.nullish(), body: createStringType(0, 152133).nullish(), user: GitHubUser, }); const GitHubIssue = z.object({ - id: Int32Type, + id: Int64Type, number: Int32Type, html_url: URLType, user: GitHubUser,