@bleedingdev/modern-js-bff-core 3.5.0-ultramodern.3 → 3.5.0-ultramodern.31
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.
- package/dist/cjs/adapter-kit/index.js +6 -2
- package/dist/cjs/adapter-kit/parity-scenarios/cross-project-denial.js +55 -0
- package/dist/cjs/adapter-kit/parity-scenarios/envelope.js +128 -0
- package/dist/cjs/adapter-kit/parity-scenarios/operation-context.js +158 -0
- package/dist/cjs/adapter-kit/parity-scenarios/schema.js +109 -0
- package/dist/cjs/adapter-kit/parity-scenarios/shared.js +71 -0
- package/dist/cjs/adapter-kit/parity.js +24 -367
- package/dist/cjs/security/crossProjectPolicy.js +123 -62
- package/dist/esm/adapter-kit/index.mjs +6 -2
- package/dist/esm/adapter-kit/parity-scenarios/cross-project-denial.mjs +17 -0
- package/dist/esm/adapter-kit/parity-scenarios/envelope.mjs +90 -0
- package/dist/esm/adapter-kit/parity-scenarios/operation-context.mjs +117 -0
- package/dist/esm/adapter-kit/parity-scenarios/schema.mjs +71 -0
- package/dist/esm/adapter-kit/parity-scenarios/shared.mjs +21 -0
- package/dist/esm/adapter-kit/parity.mjs +17 -360
- package/dist/esm/security/crossProjectPolicy.mjs +123 -62
- package/dist/esm-node/adapter-kit/index.mjs +6 -2
- package/dist/esm-node/adapter-kit/parity-scenarios/cross-project-denial.mjs +18 -0
- package/dist/esm-node/adapter-kit/parity-scenarios/envelope.mjs +91 -0
- package/dist/esm-node/adapter-kit/parity-scenarios/operation-context.mjs +118 -0
- package/dist/esm-node/adapter-kit/parity-scenarios/schema.mjs +72 -0
- package/dist/esm-node/adapter-kit/parity-scenarios/shared.mjs +22 -0
- package/dist/esm-node/adapter-kit/parity.mjs +17 -360
- package/dist/esm-node/security/crossProjectPolicy.mjs +123 -62
- package/dist/types/adapter-kit/index.d.ts +2 -2
- package/dist/types/adapter-kit/parity-scenarios/cross-project-denial.d.ts +2 -0
- package/dist/types/adapter-kit/parity-scenarios/envelope.d.ts +2 -0
- package/dist/types/adapter-kit/parity-scenarios/operation-context.d.ts +3 -0
- package/dist/types/adapter-kit/parity-scenarios/schema.d.ts +2 -0
- package/dist/types/adapter-kit/parity-scenarios/shared.d.ts +32 -0
- package/dist/types/adapter-kit/parity.d.ts +10 -70
- package/dist/types/security/crossProjectPolicy.d.ts +11 -8
- package/package.json +4 -4
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import "node:module";
|
|
2
|
+
const createEnvelopeParityScenarios = ()=>[
|
|
3
|
+
{
|
|
4
|
+
name: 'plain handler returns object payload',
|
|
5
|
+
policy: false,
|
|
6
|
+
request: {
|
|
7
|
+
method: 'get',
|
|
8
|
+
path: '/hello'
|
|
9
|
+
},
|
|
10
|
+
expected: {
|
|
11
|
+
kind: 'payload',
|
|
12
|
+
status: 200,
|
|
13
|
+
payload: {
|
|
14
|
+
message: 'hello'
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
name: 'plain handler returns scalar payload',
|
|
20
|
+
policy: false,
|
|
21
|
+
request: {
|
|
22
|
+
method: 'post',
|
|
23
|
+
path: '/hello'
|
|
24
|
+
},
|
|
25
|
+
expected: {
|
|
26
|
+
kind: 'payload',
|
|
27
|
+
status: 200,
|
|
28
|
+
payload: 'hello'
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: 'plain handler returning undefined',
|
|
33
|
+
policy: false,
|
|
34
|
+
request: {
|
|
35
|
+
method: 'get',
|
|
36
|
+
path: '/nothing'
|
|
37
|
+
},
|
|
38
|
+
expected: {
|
|
39
|
+
kind: 'payload',
|
|
40
|
+
status: 404,
|
|
41
|
+
payload: '404 Not Found'
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
name: 'plain handler receives data, query and cookies',
|
|
46
|
+
policy: false,
|
|
47
|
+
request: {
|
|
48
|
+
method: 'post',
|
|
49
|
+
path: '/echo?q=z',
|
|
50
|
+
headers: {
|
|
51
|
+
'content-type': 'application/json',
|
|
52
|
+
cookie: 'id=666'
|
|
53
|
+
},
|
|
54
|
+
body: {
|
|
55
|
+
a: 1
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
expected: {
|
|
59
|
+
kind: 'payload',
|
|
60
|
+
status: 200,
|
|
61
|
+
payload: {
|
|
62
|
+
data: {
|
|
63
|
+
a: 1
|
|
64
|
+
},
|
|
65
|
+
query: {
|
|
66
|
+
q: 'z'
|
|
67
|
+
},
|
|
68
|
+
cookie: 'id=666'
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name: 'plain handler receives positional route params',
|
|
74
|
+
policy: false,
|
|
75
|
+
request: {
|
|
76
|
+
method: 'get',
|
|
77
|
+
path: '/items/123?q=x'
|
|
78
|
+
},
|
|
79
|
+
expected: {
|
|
80
|
+
kind: 'payload',
|
|
81
|
+
status: 200,
|
|
82
|
+
payload: {
|
|
83
|
+
id: '123',
|
|
84
|
+
query: {
|
|
85
|
+
q: 'x'
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
];
|
|
91
|
+
export { createEnvelopeParityScenarios };
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import "node:module";
|
|
2
|
+
import { PARITY_PRODUCER_REQUEST_ID, deniedScenario, detailHeader } from "./shared.mjs";
|
|
3
|
+
const createOperationContextSuccessScenarios = ({ helloContract, validEnvelope, validOperationId })=>[
|
|
4
|
+
{
|
|
5
|
+
name: 'policy pass with full operation context',
|
|
6
|
+
policy: true,
|
|
7
|
+
request: {
|
|
8
|
+
method: 'get',
|
|
9
|
+
path: '/hello',
|
|
10
|
+
headers: {
|
|
11
|
+
'x-modernjs-bff-envelope': validEnvelope,
|
|
12
|
+
'x-operation-id': validOperationId,
|
|
13
|
+
'x-modernjs-bff-operation-context': detailHeader({
|
|
14
|
+
requestId: PARITY_PRODUCER_REQUEST_ID,
|
|
15
|
+
method: 'GET',
|
|
16
|
+
routePath: '/hello',
|
|
17
|
+
schemaHash: helloContract.schemaHash,
|
|
18
|
+
operationVersion: helloContract.operationVersion
|
|
19
|
+
})
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
expected: {
|
|
23
|
+
kind: 'payload',
|
|
24
|
+
status: 200,
|
|
25
|
+
payload: {
|
|
26
|
+
message: 'hello'
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
];
|
|
31
|
+
const createOperationContextDenialScenarios = ({ helloContract, validEnvelope, validOperationId })=>[
|
|
32
|
+
deniedScenario('policy denies missing operation context', 'missing_operation_context', {
|
|
33
|
+
'x-modernjs-bff-envelope': validEnvelope
|
|
34
|
+
}),
|
|
35
|
+
deniedScenario('policy denies operation context mismatch', 'operation_context_mismatch', {
|
|
36
|
+
'x-modernjs-bff-envelope': validEnvelope,
|
|
37
|
+
'x-operation-id': 'someone-else:parity'
|
|
38
|
+
}),
|
|
39
|
+
deniedScenario('policy denies missing operation context details', 'missing_operation_context_details', {
|
|
40
|
+
'x-modernjs-bff-envelope': validEnvelope,
|
|
41
|
+
'x-operation-id': validOperationId
|
|
42
|
+
}),
|
|
43
|
+
deniedScenario('policy denies JSON-array operation context details', 'invalid_operation_context_details', {
|
|
44
|
+
'x-modernjs-bff-envelope': validEnvelope,
|
|
45
|
+
'x-operation-id': validOperationId,
|
|
46
|
+
'x-modernjs-bff-operation-context': '[]'
|
|
47
|
+
}),
|
|
48
|
+
deniedScenario('policy denies invalid operation context details', 'invalid_operation_context_details', {
|
|
49
|
+
'x-modernjs-bff-envelope': validEnvelope,
|
|
50
|
+
'x-operation-id': validOperationId,
|
|
51
|
+
'x-modernjs-bff-operation-context': 'not-json'
|
|
52
|
+
}),
|
|
53
|
+
deniedScenario('policy denies detail requestId mismatch', 'operation_context_details_request_id_mismatch', {
|
|
54
|
+
'x-modernjs-bff-envelope': validEnvelope,
|
|
55
|
+
'x-operation-id': validOperationId,
|
|
56
|
+
'x-modernjs-bff-operation-context': detailHeader({
|
|
57
|
+
requestId: 'crm.producer-b',
|
|
58
|
+
method: 'GET',
|
|
59
|
+
routePath: '/hello',
|
|
60
|
+
schemaHash: helloContract.schemaHash,
|
|
61
|
+
operationVersion: helloContract.operationVersion
|
|
62
|
+
})
|
|
63
|
+
}),
|
|
64
|
+
deniedScenario('policy denies missing operation schema hash', 'missing_operation_schema_hash', {
|
|
65
|
+
'x-modernjs-bff-envelope': validEnvelope,
|
|
66
|
+
'x-operation-id': validOperationId,
|
|
67
|
+
'x-modernjs-bff-operation-context': detailHeader({
|
|
68
|
+
requestId: PARITY_PRODUCER_REQUEST_ID,
|
|
69
|
+
method: 'GET',
|
|
70
|
+
routePath: '/hello',
|
|
71
|
+
operationVersion: helloContract.operationVersion
|
|
72
|
+
})
|
|
73
|
+
}),
|
|
74
|
+
deniedScenario('policy denies missing operation version', 'missing_operation_version', {
|
|
75
|
+
'x-modernjs-bff-envelope': validEnvelope,
|
|
76
|
+
'x-operation-id': validOperationId,
|
|
77
|
+
'x-modernjs-bff-operation-context': detailHeader({
|
|
78
|
+
requestId: PARITY_PRODUCER_REQUEST_ID,
|
|
79
|
+
method: 'GET',
|
|
80
|
+
routePath: '/hello',
|
|
81
|
+
schemaHash: helloContract.schemaHash
|
|
82
|
+
})
|
|
83
|
+
}),
|
|
84
|
+
deniedScenario('policy denies unknown operation contract', 'unknown_operation_contract', {
|
|
85
|
+
'x-modernjs-bff-envelope': validEnvelope,
|
|
86
|
+
'x-operation-id': validOperationId,
|
|
87
|
+
'x-modernjs-bff-operation-context': detailHeader({
|
|
88
|
+
requestId: PARITY_PRODUCER_REQUEST_ID,
|
|
89
|
+
method: 'GET',
|
|
90
|
+
routePath: '/does-not-exist',
|
|
91
|
+
schemaHash: helloContract.schemaHash,
|
|
92
|
+
operationVersion: helloContract.operationVersion
|
|
93
|
+
})
|
|
94
|
+
}),
|
|
95
|
+
deniedScenario('policy denies operation schema hash mismatch', 'operation_schema_hash_mismatch', {
|
|
96
|
+
'x-modernjs-bff-envelope': validEnvelope,
|
|
97
|
+
'x-operation-id': validOperationId,
|
|
98
|
+
'x-modernjs-bff-operation-context': detailHeader({
|
|
99
|
+
requestId: PARITY_PRODUCER_REQUEST_ID,
|
|
100
|
+
method: 'GET',
|
|
101
|
+
routePath: '/hello',
|
|
102
|
+
schemaHash: 'deadbeef',
|
|
103
|
+
operationVersion: helloContract.operationVersion
|
|
104
|
+
})
|
|
105
|
+
}),
|
|
106
|
+
deniedScenario('policy denies operation version mismatch', 'operation_version_mismatch', {
|
|
107
|
+
'x-modernjs-bff-envelope': validEnvelope,
|
|
108
|
+
'x-operation-id': validOperationId,
|
|
109
|
+
'x-modernjs-bff-operation-context': detailHeader({
|
|
110
|
+
requestId: PARITY_PRODUCER_REQUEST_ID,
|
|
111
|
+
method: 'GET',
|
|
112
|
+
routePath: '/hello',
|
|
113
|
+
schemaHash: helloContract.schemaHash,
|
|
114
|
+
operationVersion: helloContract.operationVersion + 1
|
|
115
|
+
})
|
|
116
|
+
})
|
|
117
|
+
];
|
|
118
|
+
export { createOperationContextDenialScenarios, createOperationContextSuccessScenarios };
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import "node:module";
|
|
2
|
+
const createSchemaParityScenarios = ()=>[
|
|
3
|
+
{
|
|
4
|
+
name: 'schema handler success',
|
|
5
|
+
policy: false,
|
|
6
|
+
request: {
|
|
7
|
+
method: 'patch',
|
|
8
|
+
path: '/schema',
|
|
9
|
+
headers: {
|
|
10
|
+
'content-type': 'application/json'
|
|
11
|
+
},
|
|
12
|
+
body: {
|
|
13
|
+
id: 777
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
expected: {
|
|
17
|
+
kind: 'payload',
|
|
18
|
+
status: 200,
|
|
19
|
+
payload: {
|
|
20
|
+
type: 'HandleSuccess',
|
|
21
|
+
value: {
|
|
22
|
+
id: 777
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: 'schema handler input validation error',
|
|
29
|
+
policy: false,
|
|
30
|
+
request: {
|
|
31
|
+
method: 'patch',
|
|
32
|
+
path: '/schema',
|
|
33
|
+
headers: {
|
|
34
|
+
'content-type': 'application/json'
|
|
35
|
+
},
|
|
36
|
+
body: {
|
|
37
|
+
id: 'aaa'
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
expected: {
|
|
41
|
+
kind: 'payload',
|
|
42
|
+
status: 200,
|
|
43
|
+
payload: {
|
|
44
|
+
type: 'InputValidationError',
|
|
45
|
+
message: 'invalid input'
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: 'schema handler output validation error',
|
|
51
|
+
policy: false,
|
|
52
|
+
request: {
|
|
53
|
+
method: 'patch',
|
|
54
|
+
path: '/schema',
|
|
55
|
+
headers: {
|
|
56
|
+
'content-type': 'application/json'
|
|
57
|
+
},
|
|
58
|
+
body: {
|
|
59
|
+
id: 'boom'
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
expected: {
|
|
63
|
+
kind: 'payload',
|
|
64
|
+
status: 200,
|
|
65
|
+
payload: {
|
|
66
|
+
type: 'OutputValidationError',
|
|
67
|
+
message: 'invalid output'
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
];
|
|
72
|
+
export { createSchemaParityScenarios };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import "node:module";
|
|
2
|
+
const PARITY_REQUEST_ID = 'crm';
|
|
3
|
+
const PARITY_PRODUCER_REQUEST_ID = 'crm.producer-a';
|
|
4
|
+
const envelopeHeader = (requestId)=>JSON.stringify(void 0 === requestId ? {} : {
|
|
5
|
+
requestId
|
|
6
|
+
});
|
|
7
|
+
const detailHeader = (details)=>JSON.stringify(details);
|
|
8
|
+
const deniedScenario = (name, reason, headers)=>({
|
|
9
|
+
name,
|
|
10
|
+
policy: true,
|
|
11
|
+
request: {
|
|
12
|
+
method: 'get',
|
|
13
|
+
path: '/hello',
|
|
14
|
+
headers
|
|
15
|
+
},
|
|
16
|
+
expected: {
|
|
17
|
+
kind: 'denied',
|
|
18
|
+
status: 403,
|
|
19
|
+
reason
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
export { PARITY_PRODUCER_REQUEST_ID, PARITY_REQUEST_ID, deniedScenario, detailHeader, envelopeHeader };
|