Skip to content

Commit 90a36fe

Browse files
committed
fix: 🐛 fix schema naming and tests
1 parent 1f9ffb3 commit 90a36fe

File tree

4 files changed

+118
-4
lines changed

4 files changed

+118
-4
lines changed

src/csp.types.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,14 +232,18 @@ export const directiveValuesByCategory = {
232232
'Hostname': 'string',
233233
'Protocol': hostProtocolScheme,
234234
},
235-
compose: (args: Record<string,string>) =>
235+
compose: (args: {
236+
'Port': number,
237+
'Hostname': string,
238+
'Protocol': HostProtocolSchemes,
239+
}) =>
236240
<HostSource>`${args?.['Protocol'] || ''}${args?.['Hostname'] || ''}${args?.['Port'] ? ':' + args?.['Port'] : ''}`,
237241
},
238242
],
239243
schemeSource,
240244
cryptoSource: [
241245
{
242-
displayName: 'Hostname/URL Source',
246+
displayName: 'Crypto Nonce/Hash Source',
243247
consumes: {
244248
'Hash': 'string',
245249
'Algorithm': validCrypto,

src/globals.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@ type HostSource = `${HostSchemes}${HostNameScheme}${PortScheme}`
55
type HttpDelineators = '/' | '?' | '#' | '\\'
66
type OptionalPath = `${HttpDelineators}${string}` | ''
77
declare type UrlString = `${HostSource}${OptionalPath}`;
8+
9+
declare type Obj = Record<string | number | symbol,unknown>

src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export const directiveNamesList = <(keyof typeof directiveMap)[]>Object.keys(dir
88
type DirectiveName = keyof typeof directiveMap;
99
type DirectiveValue = typeof directiveMap[DirectiveName]
1010
type DirectiveMapPair = [DirectiveName,DirectiveValue]
11-
type CategoryValue = typeof directiveValuesByCategory[DirectiveValue[number]]
11+
type CategoryValue = FlatArray<(typeof directiveValuesByCategory[DirectiveValue[number]]),1>
1212
type DirectiveResult = {
1313
values: Partial<CategoryValue>[]
1414
categories: DirectiveValue
@@ -17,7 +17,7 @@ export const DirectiveMap = new Map<DirectiveName,DirectiveResult>(Object.entrie
1717
const [k,v] = <DirectiveMapPair>dPair;
1818
return [k,{
1919
get values (): Partial<CategoryValue>[] {
20-
return this.categories.map((category) => directiveValuesByCategory[category]).flat(0);
20+
return this.categories.map((category) => directiveValuesByCategory[category]).flat(1);
2121
},
2222
categories: v,
2323
}];

tests/mapping.test.ts

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import { DirectiveMap } from '../src/index.js';
2+
3+
function isObject (obj: unknown): obj is Record<PropertyKey,unknown> {
4+
return Object.prototype.toString.call(obj) === '[object Object]';
5+
}
6+
function hasOwnProperty<T> (obj: T, prop: PropertyKey): prop is keyof T {
7+
return Object.prototype.hasOwnProperty.call(obj, prop);
8+
}
9+
10+
describe('DirectiveMap.get()',() => {
11+
describe('Dynamic Options',() => {
12+
it('Handles Hostname/URL Source',() => {
13+
const src = DirectiveMap.get('child-src');
14+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
15+
const start: any = undefined;
16+
const result = src?.values.reduce((_,v) => {
17+
if (
18+
isObject(v) &&
19+
hasOwnProperty(v,'displayName') &&
20+
v.displayName === 'Hostname/URL Source'
21+
) {
22+
return v?.compose?.({
23+
'Hostname': 'example.com',
24+
'Port': 443,
25+
'Protocol':'https://',
26+
});
27+
}
28+
return _;
29+
},start);
30+
expect(result).toBe('https://example.com:443');
31+
});
32+
it('Crypto Nonce/Hash Source',() => {
33+
const src = DirectiveMap.get('child-src');
34+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
35+
const start: any = undefined;
36+
const result = src?.values.reduce((_,v) => {
37+
if (
38+
isObject(v) &&
39+
hasOwnProperty(v,'displayName') &&
40+
v.displayName === 'Crypto Nonce/Hash Source'
41+
) {
42+
return v?.compose?.({
43+
'Algorithm':'sha256',
44+
'Hash':'SomeBase64String',
45+
});
46+
}
47+
return _;
48+
},start);
49+
expect(result).toBe('sha256-SomeBase64String');
50+
});
51+
it('Handles URI Source',() => {
52+
const src = DirectiveMap.get('child-src');
53+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
54+
const start: any = undefined;
55+
const result = src?.values.reduce((_,v) => {
56+
if (
57+
isObject(v) &&
58+
hasOwnProperty(v,'displayName') &&
59+
v.displayName === 'URI Source'
60+
) {
61+
return v?.compose?.({
62+
'Beginning Delineator':'/',
63+
'Remaining Path':'send/reports/to',
64+
});
65+
}
66+
return _;
67+
},start);
68+
expect(result).toBe('/send/reports/to');
69+
});
70+
it('Handles Plugin MIME Type Source',() => {
71+
const src = DirectiveMap.get('child-src');
72+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
73+
const start: any = undefined;
74+
const result = src?.values.reduce((_,v) => {
75+
if (
76+
isObject(v) &&
77+
hasOwnProperty(v,'displayName') &&
78+
v.displayName === 'Plugin MIME Type Source'
79+
) {
80+
return v?.compose?.({
81+
'MIME Category':'application',
82+
'MIME Implementation':'xml',
83+
});
84+
}
85+
return _;
86+
},start);
87+
expect(result).toBe('application/xml');
88+
});
89+
it('Handles Any String',() => {
90+
const src = DirectiveMap.get('child-src');
91+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
92+
const start: any = undefined;
93+
const result = src?.values.reduce((_,v) => {
94+
if (
95+
isObject(v) &&
96+
hasOwnProperty(v,'displayName') &&
97+
v.displayName === 'Any String'
98+
) {
99+
return v?.compose?.({
100+
'String':'hello world',
101+
});
102+
}
103+
return _;
104+
},start);
105+
expect(result).toBe('hello world');
106+
});
107+
});
108+
});

0 commit comments

Comments
 (0)