@pikku/core 0.12.4 → 0.12.6
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/CHANGELOG.md +21 -1
- package/dist/dev/hot-reload.d.ts +10 -0
- package/dist/dev/hot-reload.js +158 -0
- package/dist/middleware-runner.d.ts +1 -0
- package/dist/middleware-runner.js +5 -0
- package/dist/permissions.d.ts +1 -0
- package/dist/permissions.js +5 -0
- package/dist/services/content-service.d.ts +2 -0
- package/dist/services/in-memory-workflow-service.d.ts +1 -0
- package/dist/services/in-memory-workflow-service.js +16 -11
- package/dist/services/workflow-service.d.ts +1 -0
- package/dist/wirings/ai-agent/ai-agent-prepare.js +16 -1
- package/dist/wirings/channel/channel-middleware-runner.d.ts +1 -0
- package/dist/wirings/channel/channel-middleware-runner.js +5 -0
- package/dist/wirings/http/http-runner.js +1 -1
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +6 -0
- package/dist/wirings/workflow/pikku-workflow-service.js +51 -16
- package/dist/wirings/workflow/workflow.types.d.ts +2 -0
- package/package.json +5 -3
- package/src/crypto-utils.test.ts +214 -0
- package/src/crypto-utils.ts +213 -0
- package/src/dev/hot-reload.test.ts +484 -0
- package/src/dev/hot-reload.ts +212 -0
- package/src/errors/error-handler.ts +62 -0
- package/src/errors/error.test.ts +195 -0
- package/src/errors/errors.ts +374 -0
- package/src/errors/index.ts +2 -0
- package/src/factory-functions.test.ts +109 -0
- package/src/function/function-runner.test.ts +536 -0
- package/src/function/function-runner.ts +365 -0
- package/src/function/functions.types.ts +304 -0
- package/src/function/index.ts +5 -0
- package/src/handle-error.test.ts +424 -0
- package/src/handle-error.ts +69 -0
- package/src/index.ts +118 -0
- package/src/internal.ts +6 -0
- package/src/middleware/auth-apikey.test.ts +363 -0
- package/src/middleware/auth-apikey.ts +47 -0
- package/src/middleware/auth-bearer.test.ts +450 -0
- package/src/middleware/auth-bearer.ts +72 -0
- package/src/middleware/auth-cookie.test.ts +528 -0
- package/src/middleware/auth-cookie.ts +80 -0
- package/src/middleware/cors.test.ts +424 -0
- package/src/middleware/cors.ts +104 -0
- package/src/middleware/index.ts +5 -0
- package/src/middleware/remote-auth.test.ts +488 -0
- package/src/middleware/remote-auth.ts +68 -0
- package/src/middleware/timeout.ts +15 -0
- package/src/middleware-runner.test.ts +418 -0
- package/src/middleware-runner.ts +240 -0
- package/src/permissions.test.ts +434 -0
- package/src/permissions.ts +327 -0
- package/src/pikku-request.ts +23 -0
- package/src/pikku-response.ts +5 -0
- package/src/pikku-state.test.ts +224 -0
- package/src/pikku-state.ts +216 -0
- package/src/run-tests-script.test.ts +49 -0
- package/src/schema.test.ts +249 -0
- package/src/schema.ts +151 -0
- package/src/services/ai-agent-runner-service.ts +41 -0
- package/src/services/ai-run-state-service.ts +20 -0
- package/src/services/ai-storage-service.ts +39 -0
- package/src/services/content-service.ts +81 -0
- package/src/services/deployment-service.ts +22 -0
- package/src/services/gateway-service.ts +20 -0
- package/src/services/gopass-secrets.ts +98 -0
- package/src/services/in-memory-ai-run-state-service.ts +73 -0
- package/src/services/in-memory-trigger-service.ts +64 -0
- package/src/services/in-memory-workflow-service.test.ts +351 -0
- package/src/services/in-memory-workflow-service.ts +512 -0
- package/src/services/index.ts +56 -0
- package/src/services/jwt-service.ts +30 -0
- package/src/services/local-content.ts +120 -0
- package/src/services/local-gateway-service.ts +62 -0
- package/src/services/local-secrets.test.ts +80 -0
- package/src/services/local-secrets.ts +94 -0
- package/src/services/local-variables.test.ts +61 -0
- package/src/services/local-variables.ts +39 -0
- package/src/services/logger-console.test.ts +118 -0
- package/src/services/logger-console.ts +98 -0
- package/src/services/logger.ts +57 -0
- package/src/services/scheduler-service.ts +86 -0
- package/src/services/schema-service.ts +33 -0
- package/src/services/scoped-secret-service.test.ts +74 -0
- package/src/services/scoped-secret-service.ts +41 -0
- package/src/services/secret-service.ts +38 -0
- package/src/services/trigger-service.ts +17 -0
- package/src/services/typed-secret-service.test.ts +93 -0
- package/src/services/typed-secret-service.ts +70 -0
- package/src/services/typed-variables-service.test.ts +73 -0
- package/src/services/typed-variables-service.ts +81 -0
- package/src/services/user-session-service.test.ts +113 -0
- package/src/services/user-session-service.ts +86 -0
- package/src/services/variables-service.ts +11 -0
- package/src/services/workflow-service.ts +96 -0
- package/src/testing/index.ts +2 -0
- package/src/testing/service-tests.ts +873 -0
- package/src/time-utils.test.ts +56 -0
- package/src/time-utils.ts +107 -0
- package/src/types/core.types.ts +478 -0
- package/src/types/state.types.ts +188 -0
- package/src/utils/hash.test.ts +68 -0
- package/src/utils/hash.ts +26 -0
- package/src/utils.test.ts +350 -0
- package/src/utils.ts +129 -0
- package/src/version.test.ts +80 -0
- package/src/version.ts +25 -0
- package/src/wirings/ai-agent/agent-dynamic-workflow.ts +469 -0
- package/src/wirings/ai-agent/ai-agent-helpers.test.ts +152 -0
- package/src/wirings/ai-agent/ai-agent-helpers.ts +76 -0
- package/src/wirings/ai-agent/ai-agent-memory.ts +310 -0
- package/src/wirings/ai-agent/ai-agent-model-config.test.ts +115 -0
- package/src/wirings/ai-agent/ai-agent-model-config.ts +43 -0
- package/src/wirings/ai-agent/ai-agent-prepare.ts +659 -0
- package/src/wirings/ai-agent/ai-agent-registry.test.ts +37 -0
- package/src/wirings/ai-agent/ai-agent-registry.ts +82 -0
- package/src/wirings/ai-agent/ai-agent-runner.test.ts +319 -0
- package/src/wirings/ai-agent/ai-agent-runner.ts +773 -0
- package/src/wirings/ai-agent/ai-agent-stream.test.ts +859 -0
- package/src/wirings/ai-agent/ai-agent-stream.ts +1153 -0
- package/src/wirings/ai-agent/ai-agent.types.ts +382 -0
- package/src/wirings/ai-agent/index.ts +37 -0
- package/src/wirings/channel/channel-common.ts +90 -0
- package/src/wirings/channel/channel-handler.ts +250 -0
- package/src/wirings/channel/channel-middleware-runner.ts +126 -0
- package/src/wirings/channel/channel-runner.ts +166 -0
- package/src/wirings/channel/channel-store.ts +29 -0
- package/src/wirings/channel/channel.types.ts +172 -0
- package/src/wirings/channel/define-channel-routes.ts +25 -0
- package/src/wirings/channel/eventhub-service.ts +34 -0
- package/src/wirings/channel/eventhub-store.ts +13 -0
- package/src/wirings/channel/index.ts +24 -0
- package/src/wirings/channel/local/index.ts +3 -0
- package/src/wirings/channel/local/local-channel-handler.ts +81 -0
- package/src/wirings/channel/local/local-channel-runner.test.ts +215 -0
- package/src/wirings/channel/local/local-channel-runner.ts +210 -0
- package/src/wirings/channel/local/local-eventhub-service.test.ts +95 -0
- package/src/wirings/channel/local/local-eventhub-service.ts +101 -0
- package/src/wirings/channel/log-channels.ts +20 -0
- package/src/wirings/channel/pikku-abstract-channel-handler.test.ts +54 -0
- package/src/wirings/channel/pikku-abstract-channel-handler.ts +45 -0
- package/src/wirings/channel/serverless/index.ts +5 -0
- package/src/wirings/channel/serverless/serverless-channel-runner.ts +289 -0
- package/src/wirings/cli/channel/cli-channel-runner.ts +136 -0
- package/src/wirings/cli/channel/index.ts +1 -0
- package/src/wirings/cli/cli-runner.test.ts +403 -0
- package/src/wirings/cli/cli-runner.ts +529 -0
- package/src/wirings/cli/cli.types.ts +358 -0
- package/src/wirings/cli/command-parser.test.ts +445 -0
- package/src/wirings/cli/command-parser.ts +504 -0
- package/src/wirings/cli/define-cli-commands.ts +24 -0
- package/src/wirings/cli/index.ts +19 -0
- package/src/wirings/gateway/gateway-runner.test.ts +474 -0
- package/src/wirings/gateway/gateway-runner.ts +411 -0
- package/src/wirings/gateway/gateway.types.ts +149 -0
- package/src/wirings/gateway/index.ts +13 -0
- package/src/wirings/http/http-routes.test.ts +322 -0
- package/src/wirings/http/http-routes.ts +197 -0
- package/src/wirings/http/http-runner.test.ts +144 -0
- package/src/wirings/http/http-runner.ts +588 -0
- package/src/wirings/http/http.types.ts +369 -0
- package/src/wirings/http/index.ts +28 -0
- package/src/wirings/http/log-http-routes.ts +22 -0
- package/src/wirings/http/pikku-fetch-http-request.test.ts +237 -0
- package/src/wirings/http/pikku-fetch-http-request.ts +170 -0
- package/src/wirings/http/pikku-fetch-http-response.test.ts +82 -0
- package/src/wirings/http/pikku-fetch-http-response.ts +147 -0
- package/src/wirings/http/routers/http-router.ts +13 -0
- package/src/wirings/http/routers/path-to-regex.test.ts +319 -0
- package/src/wirings/http/routers/path-to-regex.ts +126 -0
- package/src/wirings/http/web-request.test.ts +236 -0
- package/src/wirings/http/web-request.ts +104 -0
- package/src/wirings/mcp/index.ts +27 -0
- package/src/wirings/mcp/mcp-endpoint-registry.test.ts +389 -0
- package/src/wirings/mcp/mcp-endpoint-registry.ts +159 -0
- package/src/wirings/mcp/mcp-runner.ts +323 -0
- package/src/wirings/mcp/mcp.types.ts +216 -0
- package/src/wirings/node/index.ts +2 -0
- package/src/wirings/node/node.types.ts +23 -0
- package/src/wirings/oauth2/index.ts +3 -0
- package/src/wirings/oauth2/oauth2-client.test.ts +929 -0
- package/src/wirings/oauth2/oauth2-client.ts +335 -0
- package/src/wirings/oauth2/oauth2.types.ts +69 -0
- package/src/wirings/oauth2/wire-oauth2-credential.ts +23 -0
- package/src/wirings/queue/index.ts +31 -0
- package/src/wirings/queue/queue-runner.test.ts +710 -0
- package/src/wirings/queue/queue-runner.ts +192 -0
- package/src/wirings/queue/queue.types.ts +189 -0
- package/src/wirings/queue/register-queue-helper.ts +60 -0
- package/src/wirings/queue/validate-worker-config.test.ts +108 -0
- package/src/wirings/queue/validate-worker-config.ts +116 -0
- package/src/wirings/rpc/index.ts +4 -0
- package/src/wirings/rpc/rpc-runner.ts +460 -0
- package/src/wirings/rpc/rpc-types.ts +56 -0
- package/src/wirings/rpc/wire-addon.ts +21 -0
- package/src/wirings/scheduler/index.ts +11 -0
- package/src/wirings/scheduler/log-schedulers.ts +20 -0
- package/src/wirings/scheduler/scheduler-runner.test.ts +660 -0
- package/src/wirings/scheduler/scheduler-runner.ts +133 -0
- package/src/wirings/scheduler/scheduler.types.ts +53 -0
- package/src/wirings/secret/index.ts +9 -0
- package/src/wirings/secret/secret.types.ts +32 -0
- package/src/wirings/secret/validate-secret-definitions.test.ts +140 -0
- package/src/wirings/secret/validate-secret-definitions.ts +82 -0
- package/src/wirings/trigger/index.ts +10 -0
- package/src/wirings/trigger/pikku-trigger-service.ts +112 -0
- package/src/wirings/trigger/trigger-runner.test.ts +79 -0
- package/src/wirings/trigger/trigger-runner.ts +135 -0
- package/src/wirings/trigger/trigger.types.ts +178 -0
- package/src/wirings/variable/index.ts +8 -0
- package/src/wirings/variable/validate-variable-definitions.test.ts +91 -0
- package/src/wirings/variable/validate-variable-definitions.ts +69 -0
- package/src/wirings/variable/variable.types.ts +22 -0
- package/src/wirings/workflow/dsl/index.ts +31 -0
- package/src/wirings/workflow/dsl/workflow-dsl.types.ts +320 -0
- package/src/wirings/workflow/dsl/workflow-runner.ts +28 -0
- package/src/wirings/workflow/graph/graph-node.ts +222 -0
- package/src/wirings/workflow/graph/graph-runner.test.ts +487 -0
- package/src/wirings/workflow/graph/graph-runner.ts +816 -0
- package/src/wirings/workflow/graph/graph-validation.test.ts +170 -0
- package/src/wirings/workflow/graph/graph-validation.ts +237 -0
- package/src/wirings/workflow/graph/index.ts +19 -0
- package/src/wirings/workflow/graph/template.test.ts +49 -0
- package/src/wirings/workflow/graph/template.ts +42 -0
- package/src/wirings/workflow/graph/wire-workflow-graph.ts +29 -0
- package/src/wirings/workflow/graph/workflow-graph.types.ts +104 -0
- package/src/wirings/workflow/index.ts +82 -0
- package/src/wirings/workflow/pikku-workflow-service.test.ts +200 -0
- package/src/wirings/workflow/pikku-workflow-service.ts +1229 -0
- package/src/wirings/workflow/workflow-helpers.test.ts +129 -0
- package/src/wirings/workflow/workflow-helpers.ts +79 -0
- package/src/wirings/workflow/workflow.types.ts +276 -0
- package/tsconfig.json +14 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/lcov.info +0 -18891
|
@@ -0,0 +1,434 @@
|
|
|
1
|
+
import { describe, test, beforeEach } from 'node:test'
|
|
2
|
+
import * as assert from 'node:assert'
|
|
3
|
+
import { addPermission, runPermissions } from './permissions.js'
|
|
4
|
+
import { pikkuState, resetPikkuState } from './pikku-state.js'
|
|
5
|
+
import type { CoreServices, CoreUserSession } from './types/core.types.js'
|
|
6
|
+
import type {
|
|
7
|
+
CorePermissionGroup,
|
|
8
|
+
CorePikkuPermission,
|
|
9
|
+
} from './function/functions.types.js'
|
|
10
|
+
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
resetPikkuState()
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
// Test helper to get permissions for tags (not exported from core to keep it lean)
|
|
16
|
+
const getPermissionsForTags = (
|
|
17
|
+
tags?: string[]
|
|
18
|
+
): (CorePermissionGroup | CorePikkuPermission)[] => {
|
|
19
|
+
if (!tags || tags.length === 0) {
|
|
20
|
+
return []
|
|
21
|
+
}
|
|
22
|
+
const permissionsStore = pikkuState(null, 'permissions', 'tagGroup')
|
|
23
|
+
const result: (CorePermissionGroup | CorePikkuPermission)[] = []
|
|
24
|
+
for (const tag of new Set(tags)) {
|
|
25
|
+
const tagPermissions = permissionsStore[tag]
|
|
26
|
+
if (tagPermissions) {
|
|
27
|
+
if (Array.isArray(tagPermissions)) {
|
|
28
|
+
result.push(...tagPermissions)
|
|
29
|
+
} else {
|
|
30
|
+
result.push(tagPermissions)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return result
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const mockServices: CoreServices = {
|
|
38
|
+
logger: {
|
|
39
|
+
info: () => {},
|
|
40
|
+
warn: () => {},
|
|
41
|
+
error: () => {},
|
|
42
|
+
debug: () => {},
|
|
43
|
+
},
|
|
44
|
+
} as any
|
|
45
|
+
|
|
46
|
+
const mockSession: CoreUserSession = {
|
|
47
|
+
userId: 'test-user',
|
|
48
|
+
} as any
|
|
49
|
+
|
|
50
|
+
describe('addPermission', () => {
|
|
51
|
+
test('should add single permission for a tag', () => {
|
|
52
|
+
const mockPermission = async () => true
|
|
53
|
+
|
|
54
|
+
addPermission('testTag', [mockPermission])
|
|
55
|
+
|
|
56
|
+
const permissions = getPermissionsForTags(['testTag'])
|
|
57
|
+
assert.equal(permissions.length, 1)
|
|
58
|
+
assert.equal(permissions[0], mockPermission)
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
test('should add multiple permissions for a tag', () => {
|
|
62
|
+
const mockPermission1 = async () => true
|
|
63
|
+
const mockPermission2 = async () => false
|
|
64
|
+
|
|
65
|
+
addPermission('multiTestTag', [mockPermission1, mockPermission2])
|
|
66
|
+
|
|
67
|
+
const permissions = getPermissionsForTags(['multiTestTag'])
|
|
68
|
+
assert.equal(permissions.length, 2)
|
|
69
|
+
assert.equal(permissions[0], mockPermission1)
|
|
70
|
+
assert.equal(permissions[1], mockPermission2)
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
test('should add permission group object for a tag', () => {
|
|
74
|
+
const mockPermissionGroup: CorePermissionGroup = {
|
|
75
|
+
permissions: [async () => true, async () => false],
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
addPermission('groupTestTag', mockPermissionGroup)
|
|
79
|
+
|
|
80
|
+
const permissions = getPermissionsForTags(['groupTestTag'])
|
|
81
|
+
assert.equal(permissions.length, 1)
|
|
82
|
+
assert.equal(permissions[0], mockPermissionGroup)
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
test('should apply parent tag permission to namespaced tag via runPermissions', async () => {
|
|
86
|
+
const billingPermission = async () => true
|
|
87
|
+
|
|
88
|
+
addPermission('billing', [billingPermission])
|
|
89
|
+
|
|
90
|
+
await runPermissions('rpc', Math.random().toString(), {
|
|
91
|
+
wireInheritedPermissions: [{ type: 'tag', tag: 'billing:write' }],
|
|
92
|
+
services: mockServices,
|
|
93
|
+
wire: {},
|
|
94
|
+
data: {},
|
|
95
|
+
})
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
test('should apply both parent and exact tag permissions', async () => {
|
|
99
|
+
const executionOrder: string[] = []
|
|
100
|
+
const billingPermission = async () => {
|
|
101
|
+
executionOrder.push('billing')
|
|
102
|
+
return true
|
|
103
|
+
}
|
|
104
|
+
const billingReadPermission = async () => {
|
|
105
|
+
executionOrder.push('billing:read')
|
|
106
|
+
return true
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
addPermission('billing', [billingPermission])
|
|
110
|
+
addPermission('billing:read', [billingReadPermission])
|
|
111
|
+
|
|
112
|
+
await runPermissions('rpc', Math.random().toString(), {
|
|
113
|
+
wireInheritedPermissions: [{ type: 'tag', tag: 'billing:read' }],
|
|
114
|
+
services: mockServices,
|
|
115
|
+
wire: {},
|
|
116
|
+
data: {},
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
assert.deepEqual(executionOrder, ['billing:read'])
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
test('should resolve multi-level namespace permissions', async () => {
|
|
123
|
+
const executionOrder: string[] = []
|
|
124
|
+
const billingPermission = async () => {
|
|
125
|
+
executionOrder.push('billing')
|
|
126
|
+
return false
|
|
127
|
+
}
|
|
128
|
+
const billingReadPermission = async () => {
|
|
129
|
+
executionOrder.push('billing:read')
|
|
130
|
+
return false
|
|
131
|
+
}
|
|
132
|
+
const billingReadAdminPermission = async () => {
|
|
133
|
+
executionOrder.push('billing:read:admin')
|
|
134
|
+
return true
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
addPermission('billing', [billingPermission])
|
|
138
|
+
addPermission('billing:read', [billingReadPermission])
|
|
139
|
+
addPermission('billing:read:admin', [billingReadAdminPermission])
|
|
140
|
+
|
|
141
|
+
await runPermissions('rpc', Math.random().toString(), {
|
|
142
|
+
wireInheritedPermissions: [{ type: 'tag', tag: 'billing:read:admin' }],
|
|
143
|
+
services: mockServices,
|
|
144
|
+
wire: {},
|
|
145
|
+
data: {},
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
assert.deepEqual(executionOrder, ['billing:read:admin'])
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
test('should apply parent tag permission via funcInheritedPermissions', async () => {
|
|
152
|
+
const billingPermission = async () => true
|
|
153
|
+
|
|
154
|
+
addPermission('billing', [billingPermission])
|
|
155
|
+
|
|
156
|
+
await runPermissions('rpc', Math.random().toString(), {
|
|
157
|
+
funcInheritedPermissions: [{ type: 'tag', tag: 'billing:delete' }],
|
|
158
|
+
services: mockServices,
|
|
159
|
+
wire: {},
|
|
160
|
+
data: {},
|
|
161
|
+
})
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
test('should throw error when tag already exists', () => {
|
|
165
|
+
const mockPermission = async () => true
|
|
166
|
+
|
|
167
|
+
addPermission('duplicateTag', [mockPermission])
|
|
168
|
+
|
|
169
|
+
assert.throws(
|
|
170
|
+
() => {
|
|
171
|
+
addPermission('duplicateTag', [mockPermission])
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
message:
|
|
175
|
+
"Permissions for tag 'duplicateTag' already exist. Use a different tag or remove the existing permissions first.",
|
|
176
|
+
}
|
|
177
|
+
)
|
|
178
|
+
})
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
describe('runPermissions', () => {
|
|
182
|
+
test('should pass when no permissions are defined', async () => {
|
|
183
|
+
// Should not throw
|
|
184
|
+
await runPermissions('rpc', Math.random().toString(), {
|
|
185
|
+
services: mockServices,
|
|
186
|
+
wire: {},
|
|
187
|
+
data: {},
|
|
188
|
+
})
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
test('should execute wiring tag permissions first', async () => {
|
|
192
|
+
const executionOrder: string[] = []
|
|
193
|
+
const wiringTagPermission = async () => {
|
|
194
|
+
executionOrder.push('wiringTag')
|
|
195
|
+
return true
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
addPermission('wiringTag', [wiringTagPermission])
|
|
199
|
+
|
|
200
|
+
await runPermissions('rpc', Math.random().toString(), {
|
|
201
|
+
wireInheritedPermissions: [{ type: 'tag', tag: 'wiringTag' }],
|
|
202
|
+
services: mockServices,
|
|
203
|
+
wire: {},
|
|
204
|
+
data: {},
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
assert.deepEqual(executionOrder, ['wiringTag'])
|
|
208
|
+
})
|
|
209
|
+
|
|
210
|
+
test('should execute all permission levels in correct order', async () => {
|
|
211
|
+
const executionOrder: string[] = []
|
|
212
|
+
|
|
213
|
+
const wiringTagPermission = async () => {
|
|
214
|
+
executionOrder.push('wiringTag')
|
|
215
|
+
return true
|
|
216
|
+
}
|
|
217
|
+
const funcTagPermission = async () => {
|
|
218
|
+
executionOrder.push('funcTag')
|
|
219
|
+
return true
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
addPermission('wiringTag', [wiringTagPermission])
|
|
223
|
+
addPermission('funcTag', [funcTagPermission])
|
|
224
|
+
|
|
225
|
+
const wirePermissions: CorePermissionGroup = {
|
|
226
|
+
permissions: [
|
|
227
|
+
async () => {
|
|
228
|
+
executionOrder.push('wiringPermission')
|
|
229
|
+
return true
|
|
230
|
+
},
|
|
231
|
+
],
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const funcPermissions: CorePermissionGroup = {
|
|
235
|
+
permissions: [
|
|
236
|
+
async () => {
|
|
237
|
+
executionOrder.push('funcPermission')
|
|
238
|
+
return true
|
|
239
|
+
},
|
|
240
|
+
],
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
await runPermissions('rpc', Math.random().toString(), {
|
|
244
|
+
wireInheritedPermissions: [{ type: 'tag', tag: 'wiringTag' }],
|
|
245
|
+
wirePermissions,
|
|
246
|
+
funcInheritedPermissions: [{ type: 'tag', tag: 'funcTag' }],
|
|
247
|
+
funcPermissions,
|
|
248
|
+
services: mockServices,
|
|
249
|
+
wire: {},
|
|
250
|
+
data: {},
|
|
251
|
+
})
|
|
252
|
+
|
|
253
|
+
// Order: wireInheritedPermissions (wiringTag) only (short-circuit on first passing group)
|
|
254
|
+
assert.deepEqual(executionOrder, ['wiringTag'])
|
|
255
|
+
})
|
|
256
|
+
|
|
257
|
+
test('should implement "at least one must pass" logic for tag permissions', async () => {
|
|
258
|
+
const failingPermission = async () => false
|
|
259
|
+
const passingPermission = async () => true
|
|
260
|
+
|
|
261
|
+
addPermission('atLeastOneTestTag', [failingPermission, passingPermission])
|
|
262
|
+
|
|
263
|
+
// Should not throw because at least one permission passes
|
|
264
|
+
await runPermissions('rpc', Math.random().toString(), {
|
|
265
|
+
wireInheritedPermissions: [{ type: 'tag', tag: 'atLeastOneTestTag' }],
|
|
266
|
+
services: mockServices,
|
|
267
|
+
wire: {},
|
|
268
|
+
data: {},
|
|
269
|
+
})
|
|
270
|
+
})
|
|
271
|
+
|
|
272
|
+
test('should throw error when all wiring tag permissions fail', async () => {
|
|
273
|
+
const failingPermission1 = async () => false
|
|
274
|
+
const failingPermission2 = async () => false
|
|
275
|
+
|
|
276
|
+
addPermission('allFailTestTag', [failingPermission1, failingPermission2])
|
|
277
|
+
|
|
278
|
+
await assert.rejects(
|
|
279
|
+
runPermissions('rpc', Math.random().toString(), {
|
|
280
|
+
wireInheritedPermissions: [{ type: 'tag', tag: 'allFailTestTag' }],
|
|
281
|
+
services: mockServices,
|
|
282
|
+
wire: {},
|
|
283
|
+
data: {},
|
|
284
|
+
}),
|
|
285
|
+
{
|
|
286
|
+
message: 'Permission denied',
|
|
287
|
+
}
|
|
288
|
+
)
|
|
289
|
+
})
|
|
290
|
+
|
|
291
|
+
test('should throw error when wiring permissions fail', async () => {
|
|
292
|
+
const wirePermissions: CorePermissionGroup = {
|
|
293
|
+
permissions: [async () => false],
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
await assert.rejects(
|
|
297
|
+
runPermissions('rpc', Math.random().toString(), {
|
|
298
|
+
wirePermissions,
|
|
299
|
+
services: mockServices,
|
|
300
|
+
wire: {},
|
|
301
|
+
data: {},
|
|
302
|
+
}),
|
|
303
|
+
{
|
|
304
|
+
message: 'Permission denied',
|
|
305
|
+
}
|
|
306
|
+
)
|
|
307
|
+
})
|
|
308
|
+
|
|
309
|
+
test('should throw error when all function tag permissions fail', async () => {
|
|
310
|
+
const failingPermission = async () => false
|
|
311
|
+
|
|
312
|
+
addPermission('funcTag', [failingPermission])
|
|
313
|
+
|
|
314
|
+
await assert.rejects(
|
|
315
|
+
runPermissions('rpc', Math.random().toString(), {
|
|
316
|
+
funcInheritedPermissions: [{ type: 'tag', tag: 'funcTag' }],
|
|
317
|
+
services: mockServices,
|
|
318
|
+
wire: {},
|
|
319
|
+
data: {},
|
|
320
|
+
}),
|
|
321
|
+
{
|
|
322
|
+
message: 'Permission denied',
|
|
323
|
+
}
|
|
324
|
+
)
|
|
325
|
+
})
|
|
326
|
+
|
|
327
|
+
test('should throw error when function permissions fail', async () => {
|
|
328
|
+
const funcPermissions: CorePermissionGroup = {
|
|
329
|
+
permissions: [async () => false],
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
await assert.rejects(
|
|
333
|
+
runPermissions('rpc', Math.random().toString(), {
|
|
334
|
+
funcPermissions,
|
|
335
|
+
services: mockServices,
|
|
336
|
+
wire: {},
|
|
337
|
+
data: {},
|
|
338
|
+
}),
|
|
339
|
+
{
|
|
340
|
+
message: 'Permission denied',
|
|
341
|
+
}
|
|
342
|
+
)
|
|
343
|
+
})
|
|
344
|
+
|
|
345
|
+
test('should evaluate all permissions and pass if at least one succeeds', async () => {
|
|
346
|
+
const executionOrder: string[] = []
|
|
347
|
+
|
|
348
|
+
const failingWiringTagPermission = async () => {
|
|
349
|
+
executionOrder.push('wiringTag')
|
|
350
|
+
return false
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
addPermission('failingWiringTag', [failingWiringTagPermission])
|
|
354
|
+
|
|
355
|
+
const wirePermissions: CorePermissionGroup = {
|
|
356
|
+
permissions: [
|
|
357
|
+
async () => {
|
|
358
|
+
executionOrder.push('wiringPermission')
|
|
359
|
+
return true
|
|
360
|
+
},
|
|
361
|
+
],
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// Should NOT throw because at least one permission (wirePermissions) passes
|
|
365
|
+
await runPermissions('rpc', Math.random().toString(), {
|
|
366
|
+
wireInheritedPermissions: [{ type: 'tag', tag: 'failingWiringTag' }],
|
|
367
|
+
wirePermissions,
|
|
368
|
+
services: mockServices,
|
|
369
|
+
wire: {},
|
|
370
|
+
data: {},
|
|
371
|
+
})
|
|
372
|
+
|
|
373
|
+
// Both permissions should be evaluated
|
|
374
|
+
assert.deepEqual(executionOrder, ['wiringTag', 'wiringPermission'])
|
|
375
|
+
})
|
|
376
|
+
|
|
377
|
+
test('should handle array permissions in tag-based permissions', async () => {
|
|
378
|
+
const arrayPermission = [async () => true, async () => false]
|
|
379
|
+
|
|
380
|
+
addPermission('arrayTestTag', arrayPermission)
|
|
381
|
+
|
|
382
|
+
// Should not throw because verifyPermissions handles array properly
|
|
383
|
+
await runPermissions('rpc', Math.random().toString(), {
|
|
384
|
+
wireInheritedPermissions: [{ type: 'tag', tag: 'arrayTestTag' }],
|
|
385
|
+
services: mockServices,
|
|
386
|
+
wire: {},
|
|
387
|
+
data: {},
|
|
388
|
+
})
|
|
389
|
+
})
|
|
390
|
+
|
|
391
|
+
test('should handle permission group objects in tag-based permissions', async () => {
|
|
392
|
+
const permissionGroup: CorePermissionGroup = {
|
|
393
|
+
permissions: [async () => true],
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
addPermission('objectTestTag', permissionGroup)
|
|
397
|
+
|
|
398
|
+
// Should not throw because verifyPermissions handles objects properly
|
|
399
|
+
await runPermissions('rpc', Math.random().toString(), {
|
|
400
|
+
wireInheritedPermissions: [{ type: 'tag', tag: 'objectTestTag' }],
|
|
401
|
+
services: mockServices,
|
|
402
|
+
wire: {},
|
|
403
|
+
data: {},
|
|
404
|
+
})
|
|
405
|
+
})
|
|
406
|
+
|
|
407
|
+
test('should pass correct parameters to permission functions', async () => {
|
|
408
|
+
let receivedServices: any
|
|
409
|
+
let receivedWire: any
|
|
410
|
+
let receivedData: any
|
|
411
|
+
|
|
412
|
+
const testPermission = async (services: any, data: any, wire: any) => {
|
|
413
|
+
receivedServices = services
|
|
414
|
+
receivedData = data
|
|
415
|
+
receivedWire = wire
|
|
416
|
+
return true
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
const testData = { test: 'data' }
|
|
420
|
+
|
|
421
|
+
addPermission('paramTestTag', [testPermission])
|
|
422
|
+
|
|
423
|
+
await runPermissions('rpc', Math.random().toString(), {
|
|
424
|
+
wireInheritedPermissions: [{ type: 'tag', tag: 'paramTestTag' }],
|
|
425
|
+
services: mockServices,
|
|
426
|
+
wire: {},
|
|
427
|
+
data: testData,
|
|
428
|
+
})
|
|
429
|
+
|
|
430
|
+
assert.equal(receivedServices, mockServices)
|
|
431
|
+
assert.equal(receivedData, testData)
|
|
432
|
+
assert.deepEqual(receivedWire, {})
|
|
433
|
+
})
|
|
434
|
+
})
|