@growth-labs/conformance 0.2.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
package/dist/schema.js CHANGED
@@ -16,6 +16,7 @@ export const REQUIRED_NEGATIVE_FIXTURE_CODES = {
16
16
  'csp-wildcard-default-src': 'security.csp.default_src_wildcard',
17
17
  'csp-unsafe-eval': 'security.csp.unsafe_eval',
18
18
  'csp-inline-executable-without-nonce-or-hash': 'security.csp.inline_executable_without_nonce_or_hash',
19
+ 'csp-style-attr-inline-without-inventory': 'security.csp.style_attr_inline_inventory_missing',
19
20
  'conflicting-duplicate-security-header': 'security.header.conflicting_values',
20
21
  'missing-functional-probe-receipt': 'security.functional_probe.missing',
21
22
  'missing-csp-report-receipt': 'security.csp_report.missing',
@@ -83,10 +84,19 @@ export const cspReportReceiptSchema = z.object({
83
84
  endpoint: z.string().min(1).optional(),
84
85
  capabilityBoundary: z.string().min(1).optional(),
85
86
  });
87
+ export const inlineStyleAttributeInventorySchema = z.object({
88
+ commitSha: z.string().regex(/^[0-9a-f]{40}$/),
89
+ occurrenceCount: z.number().int().positive(),
90
+ evidence: z.object({
91
+ tool: z.string().regex(/^[a-z0-9][a-z0-9:@/._-]*$/i),
92
+ outputHash: z.string().regex(/^sha256:[0-9a-f]{64}$/),
93
+ }),
94
+ });
86
95
  export const securityReceiptsSchema = z
87
96
  .object({
88
97
  functionalProbes: z.array(securityFunctionalProbeReceiptSchema).default([]),
89
98
  cspReports: z.array(cspReportReceiptSchema).default([]),
99
+ inlineStyleAttributes: inlineStyleAttributeInventorySchema.optional(),
90
100
  })
91
101
  .default({ functionalProbes: [], cspReports: [] });
92
102
  export const buildEvidenceSchema = z.object({
@@ -97,10 +107,75 @@ export const buildEvidenceSchema = z.object({
97
107
  staticHeaderPolicy: z.boolean().default(false),
98
108
  ssrHeaderPolicy: z.boolean().default(false),
99
109
  });
110
+ const frameAncestorSourceSchema = z.string().superRefine((source, context) => {
111
+ if (source === "'none'" || source === "'self'" || source === 'https:')
112
+ return;
113
+ let parsed;
114
+ try {
115
+ parsed = new URL(source);
116
+ }
117
+ catch {
118
+ context.addIssue({
119
+ code: z.ZodIssueCode.custom,
120
+ message: "Expected 'none', 'self', https:, or an exact HTTPS origin.",
121
+ });
122
+ return;
123
+ }
124
+ if (parsed.protocol !== 'https:' ||
125
+ parsed.username !== '' ||
126
+ parsed.password !== '' ||
127
+ parsed.search !== '' ||
128
+ parsed.hash !== '' ||
129
+ source !== parsed.origin) {
130
+ context.addIssue({
131
+ code: z.ZodIssueCode.custom,
132
+ message: "Expected 'none', 'self', https:, or an exact HTTPS origin.",
133
+ });
134
+ }
135
+ });
136
+ const framePolicySchema = z
137
+ .object({
138
+ ancestors: z
139
+ .array(frameAncestorSourceSchema)
140
+ .min(1)
141
+ .refine((sources) => new Set(sources).size === sources.length, {
142
+ message: 'Frame ancestor sources must be unique.',
143
+ }),
144
+ legacyHeader: z.enum(['DENY', 'SAMEORIGIN', 'omit']),
145
+ })
146
+ .superRefine((policy, context) => {
147
+ if (policy.ancestors.includes("'none'") && policy.ancestors.length !== 1) {
148
+ context.addIssue({
149
+ code: z.ZodIssueCode.custom,
150
+ path: ['ancestors'],
151
+ message: "The 'none' frame ancestor cannot be combined with other sources.",
152
+ });
153
+ }
154
+ if (policy.legacyHeader === 'DENY' &&
155
+ (policy.ancestors.length !== 1 || policy.ancestors[0] !== "'none'")) {
156
+ context.addIssue({
157
+ code: z.ZodIssueCode.custom,
158
+ path: ['legacyHeader'],
159
+ message: "DENY is compatible only with frame-ancestors 'none'.",
160
+ });
161
+ }
162
+ if (policy.legacyHeader === 'SAMEORIGIN' &&
163
+ (policy.ancestors.length !== 1 || policy.ancestors[0] !== "'self'")) {
164
+ context.addIssue({
165
+ code: z.ZodIssueCode.custom,
166
+ path: ['legacyHeader'],
167
+ message: "SAMEORIGIN is compatible only with frame-ancestors 'self'.",
168
+ });
169
+ }
170
+ });
100
171
  export const conformanceExpectedSchema = z.object({
101
172
  canonicalUrl: z.string().url().optional(),
102
173
  schemaTypes: z.array(z.string().min(1)).default([]),
103
174
  discoverEligible: z.boolean().default(true),
175
+ framePolicy: framePolicySchema.default({
176
+ ancestors: ["'none'"],
177
+ legacyHeader: 'DENY',
178
+ }),
104
179
  });
105
180
  export const conformanceFixtureSchema = z.object({
106
181
  id: z.string().min(1),
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
@@ -93,6 +93,17 @@
93
93
  }
94
94
  }
95
95
  },
96
+ {
97
+ "name": "csp-style-attr-inline-without-inventory",
98
+ "expectedFailingCode": "security.csp.style_attr_inline_inventory_missing",
99
+ "patch": {
100
+ "response": {
101
+ "headers": {
102
+ "content-security-policy": "default-src 'self'; script-src 'self' 'nonce-fixture'; style-src 'self' 'nonce-fixture'; style-src-attr 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https:; object-src 'none'; base-uri 'self'; frame-ancestors 'none'; upgrade-insecure-requests"
103
+ }
104
+ }
105
+ }
106
+ },
96
107
  {
97
108
  "name": "conflicting-duplicate-security-header",
98
109
  "expectedFailingCode": "security.header.conflicting_values",
@@ -121,7 +121,7 @@
121
121
  "artifactId": "fixture-build-001",
122
122
  "generatedAt": "2026-07-15T23:30:00Z",
123
123
  "packageVersions": {
124
- "@growth-labs/conformance": "0.2.0",
124
+ "@growth-labs/conformance": "0.3.0",
125
125
  "@growth-labs/seo": "0.9.0"
126
126
  },
127
127
  "staticHeaderPolicy": true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@growth-labs/conformance",
3
- "version": "0.2.0",
3
+ "version": "0.3.1",
4
4
  "description": "Reusable fleet publication conformance harness for Growth Labs sites: headers, cache, metadata, structured data, images, publication surfaces, and evidence bundles.",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
@@ -32,9 +32,20 @@
32
32
  "dependencies": {
33
33
  "zod": "^3.25.0"
34
34
  },
35
+ "peerDependencies": {
36
+ "astro": "^7.1.0"
37
+ },
38
+ "peerDependenciesMeta": {
39
+ "astro": {
40
+ "optional": true
41
+ }
42
+ },
35
43
  "devDependencies": {
36
44
  "@cloudflare/workers-types": "^4.20260402.1",
45
+ "@types/node": "^25.5.0",
46
+ "astro": "7.1.0",
37
47
  "typescript": "^5.7.0",
48
+ "vite": "7.3.5",
38
49
  "vitest": "^4.1.8"
39
50
  },
40
51
  "scripts": {
package/src/index.ts CHANGED
@@ -1,4 +1,8 @@
1
1
  export {
2
+ type AstroCspConfig,
3
+ type AstroCspPolicyOptions,
4
+ type AstroCspResource,
5
+ buildAstroCspConfig,
2
6
  buildCacheControl,
3
7
  buildContentSecurityPolicy,
4
8
  buildSharedPublicationHeaders,
@@ -42,6 +46,8 @@ export {
42
46
  type HeaderMap,
43
47
  headerMapSchema,
44
48
  headerValueSchema,
49
+ type InlineStyleAttributeInventory,
50
+ inlineStyleAttributeInventorySchema,
45
51
  type PublicationSurfaceEvidence,
46
52
  parseConformanceFixture,
47
53
  publicationSurfaceSchema,
package/src/policy.ts CHANGED
@@ -1,4 +1,11 @@
1
- import type { Audience, HeaderMap, RenderMode } from './schema.js'
1
+ import type { AstroConfig } from 'astro'
2
+ import {
3
+ type Audience,
4
+ type HeaderMap,
5
+ type InlineStyleAttributeInventory,
6
+ inlineStyleAttributeInventorySchema,
7
+ type RenderMode,
8
+ } from './schema.js'
2
9
 
3
10
  export const REQUIRED_SECURITY_HEADERS = [
4
11
  'content-security-policy',
@@ -32,12 +39,42 @@ export interface HeaderPolicyOptions {
32
39
  nonce?: string
33
40
  cspReportUri?: string
34
41
  cspReportTo?: string
42
+ contentSecurityPolicy?: false | ContentSecurityPolicyOptions
35
43
  strictTransportSecurity?: StrictTransportSecurityOptions
36
44
  crossOriginOpenerPolicy?: CrossOriginOpenerPolicy
37
45
  crossOriginResourcePolicy?: CrossOriginResourcePolicy
38
46
  markdownTwinUrl?: string
39
47
  }
40
48
 
49
+ export interface AstroCspPolicyOptions {
50
+ scriptSources?: readonly string[]
51
+ styleSources?: readonly string[]
52
+ inlineStyleAttributes?: InlineStyleAttributeInventory
53
+ imgSources?: readonly string[]
54
+ fontSources?: readonly string[]
55
+ connectSources?: readonly string[]
56
+ mediaSources?: readonly string[]
57
+ frameSources?: readonly string[]
58
+ }
59
+
60
+ type AstroNativeCspConfig = Exclude<
61
+ NonNullable<NonNullable<AstroConfig['security']>['csp']>,
62
+ boolean
63
+ >
64
+
65
+ type AstroCspDirective = NonNullable<AstroNativeCspConfig['directives']>[number]
66
+
67
+ export type AstroCspResource = NonNullable<
68
+ NonNullable<AstroNativeCspConfig['styleDirective']>['resources']
69
+ >[number]
70
+
71
+ export interface AstroCspConfig {
72
+ algorithm: 'SHA-256'
73
+ directives: AstroCspDirective[]
74
+ scriptDirective: { resources: string[] }
75
+ styleDirective: { resources: AstroCspResource[] }
76
+ }
77
+
41
78
  export interface CachePolicyOptions {
42
79
  renderMode: RenderMode
43
80
  audience: Audience
@@ -47,11 +84,6 @@ export function buildSharedPublicationHeaders(
47
84
  options: HeaderPolicyOptions,
48
85
  ): Record<string, string> {
49
86
  const headers: Record<string, string> = {
50
- 'Content-Security-Policy': buildContentSecurityPolicy({
51
- nonce: options.nonce,
52
- reportUri: options.cspReportUri,
53
- reportTo: options.cspReportTo,
54
- }),
55
87
  'Strict-Transport-Security': buildStrictTransportSecurity(options.strictTransportSecurity),
56
88
  'Cross-Origin-Opener-Policy': options.crossOriginOpenerPolicy ?? 'same-origin',
57
89
  'Cross-Origin-Resource-Policy': options.crossOriginResourcePolicy ?? 'same-origin',
@@ -62,6 +94,15 @@ export function buildSharedPublicationHeaders(
62
94
  'accelerometer=(), camera=(), geolocation=(), gyroscope=(), microphone=(), payment=(), usb=()',
63
95
  'Cache-Control': buildCacheControl(options),
64
96
  }
97
+ if (options.contentSecurityPolicy !== false) {
98
+ headers['Content-Security-Policy'] = buildContentSecurityPolicy(
99
+ options.contentSecurityPolicy ?? {
100
+ nonce: options.nonce,
101
+ reportUri: options.cspReportUri,
102
+ reportTo: options.cspReportTo,
103
+ },
104
+ )
105
+ }
65
106
 
66
107
  if (options.markdownTwinUrl) {
67
108
  headers.Link = `<${options.markdownTwinUrl}>; rel="alternate"; type="text/markdown"`
@@ -70,6 +111,97 @@ export function buildSharedPublicationHeaders(
70
111
  return headers
71
112
  }
72
113
 
114
+ /**
115
+ * Build framework-owned CSP configuration for Astro 7.1+.
116
+ * Astro hashes every script and style it emits, while this helper keeps the
117
+ * consumer's external source inventory exact and fail-closed.
118
+ */
119
+ export function buildAstroCspConfig(options: AstroCspPolicyOptions = {}): AstroCspConfig {
120
+ const inlineStyleAttributes = options.inlineStyleAttributes
121
+ ? inlineStyleAttributeInventorySchema.parse(options.inlineStyleAttributes)
122
+ : undefined
123
+ const scriptSources = exactCspSources(options.scriptSources)
124
+ const styleSources = exactCspSources(options.styleSources)
125
+ const imgSources = exactCspSources(options.imgSources)
126
+ const fontSources = exactCspSources(options.fontSources)
127
+ const connectSources = exactCspSources(options.connectSources)
128
+ const mediaSources = exactCspSources(options.mediaSources)
129
+ const frameSources = exactCspSources(options.frameSources)
130
+
131
+ return {
132
+ algorithm: 'SHA-256',
133
+ directives: [
134
+ "default-src 'self'",
135
+ cspDirective('img-src', ["'self'", 'data:', 'blob:', ...imgSources]),
136
+ cspDirective('font-src', ["'self'", 'data:', ...fontSources]),
137
+ cspDirective('connect-src', ["'self'", ...connectSources]),
138
+ cspDirective('media-src', ["'self'", 'blob:', ...mediaSources]),
139
+ cspDirective('frame-src', ["'self'", ...frameSources]),
140
+ "object-src 'none'",
141
+ "base-uri 'self'",
142
+ "frame-ancestors 'none'",
143
+ "form-action 'self'",
144
+ 'upgrade-insecure-requests',
145
+ ],
146
+ scriptDirective: {
147
+ resources: uniqueCspSources(["'self'", ...scriptSources]),
148
+ },
149
+ styleDirective: {
150
+ resources: inlineStyleAttributes
151
+ ? [
152
+ ...uniqueCspSources(["'self'", ...styleSources]).map((resource) => ({
153
+ resource,
154
+ kind: 'element' as const,
155
+ })),
156
+ { resource: "'unsafe-inline'", kind: 'attribute' as const },
157
+ ]
158
+ : uniqueCspSources(["'self'", ...styleSources]),
159
+ },
160
+ } satisfies AstroNativeCspConfig
161
+ }
162
+
163
+ function uniqueCspSources(sources: readonly string[]): string[] {
164
+ return [...new Set(sources)]
165
+ }
166
+
167
+ function cspDirective(name: string, sources: readonly string[]): AstroCspDirective {
168
+ return `${name} ${[...new Set(sources)].join(' ')}` as AstroCspDirective
169
+ }
170
+
171
+ function exactCspSources(sources: readonly string[] | undefined): string[] {
172
+ return [...new Set(sources ?? [])].map((source) => {
173
+ const normalized = source.trim()
174
+ if (normalized === "'self'") return normalized
175
+ if (
176
+ normalized === '' ||
177
+ normalized.includes('*') ||
178
+ normalized === 'https:' ||
179
+ normalized === 'http:' ||
180
+ normalized.startsWith("'unsafe-")
181
+ ) {
182
+ throw new Error(`Astro CSP sources must be exact and cannot use ${source}`)
183
+ }
184
+
185
+ let parsed: URL
186
+ try {
187
+ parsed = new URL(normalized)
188
+ } catch {
189
+ throw new Error(`Astro CSP sources must be exact HTTPS/WSS origins: ${source}`)
190
+ }
191
+ if (
192
+ (parsed.protocol !== 'https:' && parsed.protocol !== 'wss:') ||
193
+ parsed.username !== '' ||
194
+ parsed.password !== '' ||
195
+ parsed.search !== '' ||
196
+ parsed.hash !== '' ||
197
+ (parsed.pathname !== '' && parsed.pathname !== '/')
198
+ ) {
199
+ throw new Error(`Astro CSP sources must be exact HTTPS/WSS origins: ${source}`)
200
+ }
201
+ return parsed.origin
202
+ })
203
+ }
204
+
73
205
  export function buildContentSecurityPolicy(input?: string | ContentSecurityPolicyOptions): string {
74
206
  const options = typeof input === 'string' ? { nonce: input } : (input ?? {})
75
207
  const scriptSources = ["'self'"]
package/src/runner.ts CHANGED
@@ -113,7 +113,10 @@ function checkSecurityHeaders(fixture: ConformanceFixture, html: string): Confor
113
113
  const headerEntries = collectHeaders(fixture.response.headers)
114
114
  const headers = normalizeHeaders(fixture.response.headers)
115
115
  const findings: ConformanceFinding[] = []
116
- const missingSecurityHeaders = REQUIRED_SECURITY_HEADERS.filter((name) => {
116
+ const requiredSecurityHeaders = REQUIRED_SECURITY_HEADERS.filter(
117
+ (name) => name !== 'x-frame-options' || fixture.expected.framePolicy.legacyHeader !== 'omit',
118
+ )
119
+ const missingSecurityHeaders = requiredSecurityHeaders.filter((name) => {
117
120
  const values = headerEntries[name] ?? []
118
121
  return !values.some((value) => value.trim().length > 0)
119
122
  })
@@ -161,7 +164,33 @@ function checkSecurityHeaders(fixture: ConformanceFixture, html: string): Confor
161
164
  }
162
165
 
163
166
  const csp = headers['content-security-policy']
164
- if (csp) findings.push(...validateContentSecurityPolicy(csp, html))
167
+ if (csp) findings.push(...validateContentSecurityPolicy(csp, html, fixture))
168
+
169
+ const xFrameOptions = headers['x-frame-options']
170
+ const expectedLegacyFrameHeader = fixture.expected.framePolicy.legacyHeader
171
+ if (expectedLegacyFrameHeader === 'omit' && xFrameOptions) {
172
+ findings.push({
173
+ code: 'security.frame_legacy_conflict',
174
+ severity: 'error',
175
+ message: 'X-Frame-Options conflicts with the declared embeddable frame-ancestors policy.',
176
+ path: 'response.headers.x-frame-options',
177
+ evidence: xFrameOptions,
178
+ remediation:
179
+ 'Omit the legacy header only on the explicitly declared embeddable route and retain the exact CSP frame-ancestors directive.',
180
+ })
181
+ } else if (
182
+ expectedLegacyFrameHeader !== 'omit' &&
183
+ xFrameOptions &&
184
+ xFrameOptions.toUpperCase() !== expectedLegacyFrameHeader
185
+ ) {
186
+ findings.push({
187
+ code: 'security.header.invalid',
188
+ severity: 'error',
189
+ message: `X-Frame-Options must be ${expectedLegacyFrameHeader} for this response class.`,
190
+ path: 'response.headers.x-frame-options',
191
+ evidence: xFrameOptions,
192
+ })
193
+ }
165
194
 
166
195
  const coop = headers['cross-origin-opener-policy']
167
196
  if (coop && !VALID_COOP_VALUES.has(coop.toLowerCase())) {
@@ -387,10 +416,37 @@ interface InlineExecutableScript {
387
416
  path: string
388
417
  }
389
418
 
390
- function validateContentSecurityPolicy(csp: string, html: string): ConformanceFinding[] {
419
+ function validateContentSecurityPolicy(
420
+ csp: string,
421
+ html: string,
422
+ fixture: ConformanceFixture,
423
+ ): ConformanceFinding[] {
391
424
  const findings: ConformanceFinding[] = []
392
425
  const { directives, findings: parseFindings } = parseContentSecurityPolicy(csp)
393
426
  findings.push(...parseFindings)
427
+ const frameAncestors = directives.get('frame-ancestors')
428
+ const expectedFrameAncestors = fixture.expected.framePolicy.ancestors
429
+ if (!frameAncestors) {
430
+ findings.push({
431
+ code: 'security.csp.frame_ancestors_missing',
432
+ severity: 'error',
433
+ message: 'Content-Security-Policy must declare frame-ancestors.',
434
+ path: 'response.headers.content-security-policy.frame-ancestors',
435
+ })
436
+ } else if (
437
+ normalizeCspSources(frameAncestors.sources) !== normalizeCspSources(expectedFrameAncestors)
438
+ ) {
439
+ findings.push({
440
+ code: 'security.csp.frame_ancestors_mismatch',
441
+ severity: 'error',
442
+ message:
443
+ 'Content-Security-Policy frame-ancestors does not match the declared response class.',
444
+ path: 'response.headers.content-security-policy.frame-ancestors',
445
+ evidence: frameAncestors.raw,
446
+ remediation:
447
+ 'Emit only the exact declared frame ancestors and keep embeddable routes explicitly bounded.',
448
+ })
449
+ }
394
450
 
395
451
  const defaultSources = lowerSources(directives.get('default-src')?.sources ?? [])
396
452
  if (defaultSources.includes('*')) {
@@ -425,6 +481,39 @@ function validateContentSecurityPolicy(csp: string, html: string): ConformanceFi
425
481
  const directive = directives.get(directiveName)
426
482
  if (!directive) continue
427
483
  if (lowerSources(directive.sources).includes("'unsafe-inline'")) {
484
+ if (directiveName === 'style-src-attr') {
485
+ const inventory = fixture.securityReceipts.inlineStyleAttributes
486
+ if (!inventory) {
487
+ findings.push({
488
+ code: 'security.csp.style_attr_inline_inventory_missing',
489
+ severity: 'error',
490
+ message:
491
+ "style-src-attr 'unsafe-inline' requires a commit-bound inline-style-attribute inventory receipt.",
492
+ path: 'securityReceipts.inlineStyleAttributes',
493
+ evidence: directive.raw,
494
+ remediation:
495
+ 'Remove the allowance or attach the exact consumer commit SHA, positive occurrence count, and scan evidence.',
496
+ })
497
+ continue
498
+ }
499
+
500
+ if (
501
+ !fixture.buildEvidence?.commitSha ||
502
+ fixture.buildEvidence.commitSha !== inventory.commitSha
503
+ ) {
504
+ findings.push({
505
+ code: 'security.csp.style_attr_inline_inventory_stale',
506
+ severity: 'error',
507
+ message:
508
+ 'The inline-style-attribute inventory must match the exact commit in build evidence.',
509
+ path: 'securityReceipts.inlineStyleAttributes.commitSha',
510
+ evidence: `inventory=${inventory.commitSha}; build=${fixture.buildEvidence?.commitSha ?? 'missing'}`,
511
+ remediation:
512
+ 'Rescan the exact build commit before retaining the style attribute allowance.',
513
+ })
514
+ }
515
+ continue
516
+ }
428
517
  findings.push({
429
518
  code: 'security.csp.unsafe_inline',
430
519
  severity: 'error',
@@ -535,7 +624,7 @@ function inlineExecutableScriptAllowed(script: InlineExecutableScript, sources:
535
624
  }
536
625
 
537
626
  function hashSourceMatchesInlineScript(source: string, content: string): boolean {
538
- const match = /^'(sha256|sha384|sha512)-([^']+)'$/i.exec(source)
627
+ const match = /^'(sha256|sha384|sha512)-([^']+)'$/.exec(source)
539
628
  if (!match) return false
540
629
  const algorithm = match[1]?.toLowerCase()
541
630
  const expected = match[2]