@pikku/core 0.11.2 → 0.12.0
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 +33 -2
- package/dist/crypto-utils.d.ts +2 -0
- package/dist/crypto-utils.js +78 -0
- package/dist/errors/errors.d.ts +8 -0
- package/dist/errors/errors.js +16 -0
- package/dist/errors/index.d.ts +0 -1
- package/dist/errors/index.js +0 -1
- package/dist/function/function-runner.d.ts +7 -1
- package/dist/function/function-runner.js +82 -23
- package/dist/function/functions.types.d.ts +31 -87
- package/dist/function/functions.types.js +16 -46
- package/dist/function/index.d.ts +2 -2
- package/dist/function/index.js +1 -2
- package/dist/handle-error.js +1 -10
- package/dist/index.d.ts +28 -26
- package/dist/index.js +18 -29
- package/dist/middleware/auth-apikey.d.ts +2 -2
- package/dist/middleware/auth-apikey.js +3 -3
- package/dist/middleware/auth-bearer.d.ts +2 -2
- package/dist/middleware/auth-bearer.js +3 -6
- package/dist/middleware/auth-cookie.d.ts +2 -2
- package/dist/middleware/auth-cookie.js +6 -8
- package/dist/middleware/cors.d.ts +46 -0
- package/dist/middleware/cors.js +73 -0
- package/dist/middleware/index.d.ts +5 -3
- package/dist/middleware/index.js +5 -3
- package/dist/middleware/remote-auth.d.ts +5 -0
- package/dist/middleware/remote-auth.js +55 -0
- package/dist/middleware/timeout.d.ts +2 -2
- package/dist/middleware-runner.js +8 -10
- package/dist/permissions.js +11 -15
- package/dist/pikku-state.d.ts +1 -0
- package/dist/pikku-state.js +18 -8
- package/dist/schema.js +12 -11
- package/dist/services/ai-agent-runner-service.d.ts +24 -0
- package/dist/services/ai-agent-runner-service.js +1 -0
- package/dist/services/ai-run-state-service.d.ts +13 -0
- package/dist/services/ai-run-state-service.js +1 -0
- package/dist/services/ai-storage-service.d.ts +18 -0
- package/dist/services/ai-storage-service.js +1 -0
- package/dist/services/deployment-service.d.ts +19 -0
- package/dist/services/deployment-service.js +1 -0
- package/dist/services/gopass-secrets.d.ts +47 -0
- package/dist/services/gopass-secrets.js +94 -0
- package/dist/services/in-memory-trigger-service.d.ts +23 -0
- package/dist/services/in-memory-trigger-service.js +50 -0
- package/dist/services/in-memory-workflow-service.d.ts +59 -0
- package/dist/services/in-memory-workflow-service.js +287 -0
- package/dist/services/index.d.ts +25 -11
- package/dist/services/index.js +10 -13
- package/dist/services/local-secrets.d.ts +23 -0
- package/dist/services/local-secrets.js +45 -0
- package/dist/services/local-variables.d.ts +5 -0
- package/dist/services/local-variables.js +18 -0
- package/dist/services/scheduler-service.d.ts +21 -1
- package/dist/services/scheduler-service.js +14 -0
- package/dist/services/schema-service.d.ts +6 -0
- package/dist/services/scoped-secret-service.d.ts +16 -0
- package/dist/services/scoped-secret-service.js +35 -0
- package/dist/services/secret-service.d.ts +25 -4
- package/dist/services/trigger-service.d.ts +23 -0
- package/dist/services/trigger-service.js +1 -0
- package/dist/services/typed-secret-service.d.ts +30 -0
- package/dist/services/typed-secret-service.js +40 -0
- package/dist/services/typed-variables-service.d.ts +27 -0
- package/dist/services/typed-variables-service.js +46 -0
- package/dist/services/user-session-service.d.ts +13 -0
- package/dist/services/user-session-service.js +17 -0
- package/dist/services/variables-service.d.ts +5 -0
- package/dist/services/workflow-service.d.ts +9 -4
- package/dist/types/core.types.d.ts +48 -12
- package/dist/types/core.types.js +8 -1
- package/dist/types/state.types.d.ts +43 -51
- package/dist/utils.d.ts +3 -2
- package/dist/utils.js +15 -3
- package/dist/version.d.ts +6 -0
- package/dist/version.js +19 -0
- package/dist/wirings/ai-agent/ai-agent-memory.d.ts +29 -0
- package/dist/wirings/ai-agent/ai-agent-memory.js +199 -0
- package/dist/wirings/ai-agent/ai-agent-model-config.d.ts +9 -0
- package/dist/wirings/ai-agent/ai-agent-model-config.js +36 -0
- package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +60 -0
- package/dist/wirings/ai-agent/ai-agent-prepare.js +312 -0
- package/dist/wirings/ai-agent/ai-agent-registry.d.ts +15 -0
- package/dist/wirings/ai-agent/ai-agent-registry.js +47 -0
- package/dist/wirings/ai-agent/ai-agent-runner.d.ts +3 -0
- package/dist/wirings/ai-agent/ai-agent-runner.js +96 -0
- package/dist/wirings/ai-agent/ai-agent-stream.d.ts +11 -0
- package/dist/wirings/ai-agent/ai-agent-stream.js +503 -0
- package/dist/wirings/ai-agent/ai-agent.types.d.ts +254 -0
- package/dist/wirings/ai-agent/ai-agent.types.js +1 -0
- package/dist/wirings/ai-agent/index.d.ts +5 -0
- package/dist/wirings/ai-agent/index.js +4 -0
- package/dist/wirings/channel/channel-common.d.ts +7 -4
- package/dist/wirings/channel/channel-common.js +15 -8
- package/dist/wirings/channel/channel-handler.js +12 -3
- package/dist/wirings/channel/channel-middleware-runner.d.ts +9 -0
- package/dist/wirings/channel/channel-middleware-runner.js +73 -0
- package/dist/wirings/channel/channel-runner.js +7 -7
- package/dist/wirings/channel/channel.types.d.ts +5 -1
- package/dist/wirings/channel/define-channel-routes.d.ts +21 -0
- package/dist/wirings/channel/define-channel-routes.js +23 -0
- package/dist/wirings/channel/index.d.ts +10 -8
- package/dist/wirings/channel/index.js +7 -8
- package/dist/wirings/channel/local/index.d.ts +3 -3
- package/dist/wirings/channel/local/index.js +3 -3
- package/dist/wirings/channel/local/local-channel-runner.js +18 -6
- package/dist/wirings/channel/serverless/index.d.ts +1 -1
- package/dist/wirings/channel/serverless/index.js +1 -1
- package/dist/wirings/channel/serverless/serverless-channel-runner.js +15 -4
- package/dist/wirings/cli/channel/index.d.ts +1 -1
- package/dist/wirings/cli/channel/index.js +1 -1
- package/dist/wirings/cli/cli-runner.d.ts +1 -1
- package/dist/wirings/cli/cli-runner.js +12 -8
- package/dist/wirings/cli/cli.types.d.ts +6 -6
- package/dist/wirings/cli/define-cli-commands.d.ts +19 -0
- package/dist/wirings/cli/define-cli-commands.js +20 -0
- package/dist/wirings/cli/index.d.ts +2 -3
- package/dist/wirings/cli/index.js +1 -3
- package/dist/wirings/http/http-routes.d.ts +69 -0
- package/dist/wirings/http/http-routes.js +139 -0
- package/dist/wirings/http/http-runner.js +49 -23
- package/dist/wirings/http/http.types.d.ts +78 -38
- package/dist/wirings/http/index.d.ts +5 -4
- package/dist/wirings/http/index.js +4 -3
- package/dist/wirings/mcp/index.d.ts +4 -3
- package/dist/wirings/mcp/index.js +3 -3
- package/dist/wirings/mcp/mcp-runner.d.ts +1 -3
- package/dist/wirings/mcp/mcp-runner.js +25 -39
- package/dist/wirings/mcp/mcp.types.d.ts +3 -3
- package/dist/wirings/node/index.d.ts +2 -0
- package/dist/wirings/node/index.js +1 -0
- package/dist/wirings/node/node.types.d.ts +20 -0
- package/dist/wirings/node/node.types.js +1 -0
- package/dist/wirings/oauth2/index.d.ts +3 -0
- package/dist/wirings/oauth2/index.js +2 -0
- package/dist/wirings/oauth2/oauth2-client.d.ts +47 -0
- package/dist/wirings/oauth2/oauth2-client.js +267 -0
- package/dist/wirings/oauth2/oauth2.types.d.ts +65 -0
- package/dist/wirings/oauth2/oauth2.types.js +4 -0
- package/dist/wirings/oauth2/wire-oauth2-credential.d.ts +20 -0
- package/dist/wirings/oauth2/wire-oauth2-credential.js +21 -0
- package/dist/wirings/queue/index.d.ts +2 -2
- package/dist/wirings/queue/index.js +1 -1
- package/dist/wirings/queue/queue-runner.d.ts +7 -0
- package/dist/wirings/queue/queue-runner.js +17 -6
- package/dist/wirings/queue/queue.types.d.ts +8 -2
- package/dist/wirings/rpc/index.d.ts +1 -1
- package/dist/wirings/rpc/index.js +1 -1
- package/dist/wirings/rpc/rpc-runner.d.ts +33 -5
- package/dist/wirings/rpc/rpc-runner.js +134 -16
- package/dist/wirings/rpc/rpc-types.d.ts +8 -4
- package/dist/wirings/scheduler/index.d.ts +3 -3
- package/dist/wirings/scheduler/index.js +2 -3
- package/dist/wirings/scheduler/scheduler-runner.d.ts +5 -0
- package/dist/wirings/scheduler/scheduler-runner.js +23 -5
- package/dist/wirings/secret/index.d.ts +3 -0
- package/dist/wirings/secret/index.js +2 -0
- package/dist/wirings/secret/secret.types.d.ts +27 -0
- package/dist/wirings/secret/secret.types.js +1 -0
- package/dist/wirings/secret/validate-secret-definitions.d.ts +6 -0
- package/dist/wirings/secret/validate-secret-definitions.js +55 -0
- package/dist/wirings/trigger/index.d.ts +3 -2
- package/dist/wirings/trigger/index.js +2 -2
- package/dist/wirings/trigger/pikku-trigger-service.d.ts +26 -0
- package/dist/wirings/trigger/pikku-trigger-service.js +75 -0
- package/dist/wirings/trigger/trigger-runner.d.ts +21 -8
- package/dist/wirings/trigger/trigger-runner.js +46 -18
- package/dist/wirings/trigger/trigger.types.d.ts +99 -11
- package/dist/wirings/trigger/trigger.types.js +40 -1
- package/dist/wirings/variable/index.d.ts +3 -0
- package/dist/wirings/variable/index.js +2 -0
- package/dist/wirings/variable/validate-variable-definitions.d.ts +6 -0
- package/dist/wirings/variable/validate-variable-definitions.js +45 -0
- package/dist/wirings/variable/variable.types.d.ts +18 -0
- package/dist/wirings/variable/variable.types.js +1 -0
- package/dist/wirings/workflow/dsl/index.d.ts +1 -1
- package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +7 -1
- package/dist/wirings/workflow/dsl/workflow-runner.js +3 -2
- package/dist/wirings/workflow/graph/graph-node.d.ts +1 -6
- package/dist/wirings/workflow/graph/graph-runner.d.ts +5 -31
- package/dist/wirings/workflow/graph/graph-runner.js +384 -296
- package/dist/wirings/workflow/graph/index.d.ts +4 -3
- package/dist/wirings/workflow/graph/index.js +3 -3
- package/dist/wirings/workflow/graph/template.d.ts +15 -0
- package/dist/wirings/workflow/graph/template.js +27 -0
- package/dist/wirings/workflow/graph/wire-workflow-graph.d.ts +15 -0
- package/dist/wirings/workflow/graph/wire-workflow-graph.js +8 -0
- package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +0 -13
- package/dist/wirings/workflow/index.d.ts +6 -6
- package/dist/wirings/workflow/index.js +6 -4
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +28 -14
- package/dist/wirings/workflow/pikku-workflow-service.js +200 -56
- package/dist/wirings/workflow/workflow-helpers.d.ts +36 -0
- package/dist/wirings/workflow/workflow-helpers.js +38 -0
- package/dist/wirings/workflow/workflow-utils.d.ts +1 -23
- package/dist/wirings/workflow/workflow-utils.js +1 -66
- package/dist/wirings/workflow/workflow.types.d.ts +40 -93
- package/package.json +13 -15
- package/run-tests.sh +4 -1
- package/src/crypto-utils.ts +99 -0
- package/src/errors/errors.ts +17 -0
- package/src/errors/index.ts +0 -1
- package/src/factory-functions.test.ts +42 -2
- package/src/function/function-runner.test.ts +4 -11
- package/src/function/function-runner.ts +114 -29
- package/src/function/functions.types.ts +62 -132
- package/src/function/index.ts +5 -2
- package/src/handle-error.ts +2 -10
- package/src/index.ts +99 -25
- package/src/middleware/auth-apikey.test.ts +15 -12
- package/src/middleware/auth-apikey.ts +3 -3
- package/src/middleware/auth-bearer.test.ts +17 -14
- package/src/middleware/auth-bearer.ts +25 -27
- package/src/middleware/auth-cookie.test.ts +16 -13
- package/src/middleware/auth-cookie.ts +6 -8
- package/src/middleware/cors.ts +96 -0
- package/src/middleware/index.ts +5 -3
- package/src/middleware/remote-auth.ts +68 -0
- package/src/middleware-runner.test.ts +122 -0
- package/src/middleware-runner.ts +12 -12
- package/src/permissions.test.ts +81 -7
- package/src/permissions.ts +15 -17
- package/src/pikku-state.ts +20 -8
- package/src/run-tests-script.test.ts +49 -0
- package/src/schema.ts +18 -15
- package/src/services/ai-agent-runner-service.ts +29 -0
- package/src/services/ai-run-state-service.ts +20 -0
- package/src/services/ai-storage-service.ts +39 -0
- package/src/services/deployment-service.ts +22 -0
- package/src/services/gopass-secrets.ts +95 -0
- package/src/services/in-memory-trigger-service.ts +68 -0
- package/src/services/in-memory-workflow-service.ts +395 -0
- package/src/services/index.ts +49 -14
- package/src/services/local-secrets.ts +51 -0
- package/src/services/local-variables.ts +22 -0
- package/src/services/scheduler-service.ts +29 -1
- package/src/services/schema-service.ts +7 -0
- package/src/services/scoped-secret-service.ts +41 -0
- package/src/services/secret-service.ts +25 -4
- package/src/services/trigger-service.ts +38 -0
- package/src/services/typed-secret-service.ts +70 -0
- package/src/services/typed-variables-service.ts +81 -0
- package/src/services/user-session-service.ts +23 -0
- package/src/services/variables-service.ts +5 -0
- package/src/services/workflow-service.ts +22 -2
- package/src/types/core.types.ts +76 -11
- package/src/types/state.types.ts +37 -63
- package/src/utils.ts +20 -6
- package/src/version.test.ts +80 -0
- package/src/version.ts +25 -0
- package/src/wirings/ai-agent/ai-agent-memory.ts +300 -0
- package/src/wirings/ai-agent/ai-agent-model-config.ts +43 -0
- package/src/wirings/ai-agent/ai-agent-prepare.ts +470 -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 +75 -0
- package/src/wirings/ai-agent/ai-agent-runner.ts +137 -0
- package/src/wirings/ai-agent/ai-agent-stream.test.ts +246 -0
- package/src/wirings/ai-agent/ai-agent-stream.ts +774 -0
- package/src/wirings/ai-agent/ai-agent.types.ts +273 -0
- package/src/wirings/ai-agent/index.ts +28 -0
- package/src/wirings/channel/channel-common.ts +32 -19
- package/src/wirings/channel/channel-handler.ts +17 -4
- package/src/wirings/channel/channel-middleware-runner.ts +119 -0
- package/src/wirings/channel/channel-runner.ts +9 -10
- package/src/wirings/channel/channel.types.ts +17 -1
- package/src/wirings/channel/define-channel-routes.ts +25 -0
- package/src/wirings/channel/index.ts +23 -8
- package/src/wirings/channel/local/index.ts +3 -3
- package/src/wirings/channel/local/local-channel-runner.test.ts +44 -1
- package/src/wirings/channel/local/local-channel-runner.ts +22 -6
- package/src/wirings/channel/serverless/index.ts +5 -1
- package/src/wirings/channel/serverless/serverless-channel-runner.ts +20 -4
- package/src/wirings/cli/channel/index.ts +1 -1
- package/src/wirings/cli/cli-runner.test.ts +9 -9
- package/src/wirings/cli/cli-runner.ts +17 -10
- package/src/wirings/cli/cli.types.ts +11 -11
- package/src/wirings/cli/command-parser.test.ts +8 -8
- package/src/wirings/cli/define-cli-commands.ts +24 -0
- package/src/wirings/cli/index.ts +10 -4
- package/src/wirings/http/http-routes.test.ts +322 -0
- package/src/wirings/http/http-routes.ts +198 -0
- package/src/wirings/http/http-runner.test.ts +3 -3
- package/src/wirings/http/http-runner.ts +63 -29
- package/src/wirings/http/http.types.ts +121 -37
- package/src/wirings/http/index.ts +16 -4
- package/src/wirings/mcp/index.ts +27 -3
- package/src/wirings/mcp/mcp-endpoint-registry.test.ts +3 -3
- package/src/wirings/mcp/mcp-runner.ts +39 -50
- package/src/wirings/mcp/mcp.types.ts +3 -3
- 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 +14 -2
- package/src/wirings/queue/queue-runner.test.ts +97 -55
- package/src/wirings/queue/queue-runner.ts +33 -7
- package/src/wirings/queue/queue.types.ts +12 -2
- package/src/wirings/rpc/index.ts +1 -1
- package/src/wirings/rpc/rpc-runner.ts +187 -17
- package/src/wirings/rpc/rpc-types.ts +13 -4
- package/src/wirings/scheduler/index.ts +7 -4
- package/src/wirings/scheduler/scheduler-runner.test.ts +70 -26
- package/src/wirings/scheduler/scheduler-runner.ts +45 -5
- package/src/wirings/secret/index.ts +9 -0
- package/src/wirings/secret/secret.types.ts +32 -0
- package/src/wirings/secret/validate-secret-definitions.ts +82 -0
- package/src/wirings/trigger/index.ts +10 -2
- package/src/wirings/trigger/pikku-trigger-service.ts +134 -0
- package/src/wirings/trigger/trigger-runner.ts +80 -38
- package/src/wirings/trigger/trigger.types.ts +144 -22
- package/src/wirings/variable/index.ts +8 -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 +1 -0
- package/src/wirings/workflow/dsl/workflow-dsl.types.ts +9 -1
- package/src/wirings/workflow/dsl/workflow-runner.ts +4 -3
- package/src/wirings/workflow/graph/graph-node.ts +1 -6
- package/src/wirings/workflow/graph/graph-runner.test.ts +495 -0
- package/src/wirings/workflow/graph/graph-runner.ts +496 -374
- package/src/wirings/workflow/graph/index.ts +14 -3
- 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 +0 -22
- package/src/wirings/workflow/index.ts +21 -10
- package/src/wirings/workflow/pikku-workflow-service.test.ts +212 -0
- package/src/wirings/workflow/pikku-workflow-service.ts +285 -66
- package/src/wirings/workflow/workflow-helpers.ts +79 -0
- package/src/wirings/workflow/workflow-utils.ts +0 -120
- package/src/wirings/workflow/workflow.types.ts +45 -90
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/wirings/forge-node/forge-node.types.d.ts +0 -120
- package/dist/wirings/forge-node/forge-node.types.js +0 -38
- package/dist/wirings/forge-node/index.d.ts +0 -1
- package/dist/wirings/forge-node/index.js +0 -1
- package/dist/wirings/workflow/wire-workflow.d.ts +0 -42
- package/dist/wirings/workflow/wire-workflow.js +0 -53
- package/src/wirings/forge-node/forge-node.types.ts +0 -135
- package/src/wirings/forge-node/index.ts +0 -1
- package/src/wirings/workflow/wire-workflow.ts +0 -94
|
@@ -3,7 +3,10 @@ import assert from 'node:assert/strict'
|
|
|
3
3
|
import { authAPIKey } from './auth-apikey.js'
|
|
4
4
|
import { resetPikkuState } from '../pikku-state.js'
|
|
5
5
|
import { CoreUserSession } from '../types/core.types.js'
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
PikkuSessionService,
|
|
8
|
+
createMiddlewareSessionWireProps,
|
|
9
|
+
} from '../services/user-session-service.js'
|
|
7
10
|
|
|
8
11
|
beforeEach(() => {
|
|
9
12
|
resetPikkuState()
|
|
@@ -43,7 +46,7 @@ describe('authAPIKey middleware', () => {
|
|
|
43
46
|
request: createMockHTTPRequest({ 'x-api-key': 'my-api-key' }),
|
|
44
47
|
response: createMockHTTPResponse(),
|
|
45
48
|
},
|
|
46
|
-
|
|
49
|
+
...createMiddlewareSessionWireProps(SessionService),
|
|
47
50
|
} as any,
|
|
48
51
|
async () => {
|
|
49
52
|
nextCalled = true
|
|
@@ -75,7 +78,7 @@ describe('authAPIKey middleware', () => {
|
|
|
75
78
|
request: createMockHTTPRequest({}, { apiKey: 'query-api-key' }),
|
|
76
79
|
response: createMockHTTPResponse(),
|
|
77
80
|
},
|
|
78
|
-
|
|
81
|
+
...createMiddlewareSessionWireProps(SessionService),
|
|
79
82
|
} as any,
|
|
80
83
|
async () => {
|
|
81
84
|
nextCalled = true
|
|
@@ -111,7 +114,7 @@ describe('authAPIKey middleware', () => {
|
|
|
111
114
|
),
|
|
112
115
|
response: createMockHTTPResponse(),
|
|
113
116
|
},
|
|
114
|
-
|
|
117
|
+
...createMiddlewareSessionWireProps(SessionService),
|
|
115
118
|
} as any,
|
|
116
119
|
async () => {
|
|
117
120
|
nextCalled = true
|
|
@@ -143,7 +146,7 @@ describe('authAPIKey middleware', () => {
|
|
|
143
146
|
request: createMockHTTPRequest({}, { apiKey: 'query-fallback' }),
|
|
144
147
|
response: createMockHTTPResponse(),
|
|
145
148
|
},
|
|
146
|
-
|
|
149
|
+
...createMiddlewareSessionWireProps(SessionService),
|
|
147
150
|
} as any,
|
|
148
151
|
async () => {
|
|
149
152
|
nextCalled = true
|
|
@@ -171,7 +174,7 @@ describe('authAPIKey middleware', () => {
|
|
|
171
174
|
request: createMockHTTPRequest({}),
|
|
172
175
|
response: createMockHTTPResponse(),
|
|
173
176
|
},
|
|
174
|
-
|
|
177
|
+
...createMiddlewareSessionWireProps(SessionService),
|
|
175
178
|
} as any,
|
|
176
179
|
async () => {
|
|
177
180
|
nextCalled = true
|
|
@@ -199,7 +202,7 @@ describe('authAPIKey middleware', () => {
|
|
|
199
202
|
request: createMockHTTPRequest({ 'x-api-key': 'invalid-key' }),
|
|
200
203
|
response: createMockHTTPResponse(),
|
|
201
204
|
},
|
|
202
|
-
|
|
205
|
+
...createMiddlewareSessionWireProps(SessionService),
|
|
203
206
|
} as any,
|
|
204
207
|
async () => {
|
|
205
208
|
nextCalled = true
|
|
@@ -234,7 +237,7 @@ describe('authAPIKey middleware', () => {
|
|
|
234
237
|
request: createMockHTTPRequest({ 'x-api-key': 'some-key' }),
|
|
235
238
|
response: createMockHTTPResponse(),
|
|
236
239
|
},
|
|
237
|
-
|
|
240
|
+
...createMiddlewareSessionWireProps(SessionService),
|
|
238
241
|
} as any,
|
|
239
242
|
async () => {
|
|
240
243
|
nextCalled = true
|
|
@@ -258,7 +261,7 @@ describe('authAPIKey middleware', () => {
|
|
|
258
261
|
|
|
259
262
|
await middleware(
|
|
260
263
|
{ jwt: jwtService } as any,
|
|
261
|
-
{
|
|
264
|
+
{ ...createMiddlewareSessionWireProps(SessionService) } as any,
|
|
262
265
|
async () => {
|
|
263
266
|
nextCalled = true
|
|
264
267
|
}
|
|
@@ -281,7 +284,7 @@ describe('authAPIKey middleware', () => {
|
|
|
281
284
|
request: createMockHTTPRequest({ 'x-api-key': 'some-key' }),
|
|
282
285
|
response: createMockHTTPResponse(),
|
|
283
286
|
},
|
|
284
|
-
|
|
287
|
+
...createMiddlewareSessionWireProps(SessionService),
|
|
285
288
|
} as any,
|
|
286
289
|
async () => {
|
|
287
290
|
nextCalled = true
|
|
@@ -313,7 +316,7 @@ describe('authAPIKey middleware', () => {
|
|
|
313
316
|
request: createMockHTTPRequest({}, { apiKey: 'query-key' }),
|
|
314
317
|
response: createMockHTTPResponse(),
|
|
315
318
|
},
|
|
316
|
-
|
|
319
|
+
...createMiddlewareSessionWireProps(SessionService),
|
|
317
320
|
} as any,
|
|
318
321
|
async () => {
|
|
319
322
|
nextCalled = true
|
|
@@ -346,7 +349,7 @@ describe('authAPIKey middleware', () => {
|
|
|
346
349
|
request: createMockHTTPRequest({ 'x-api-key': 'header-key' }),
|
|
347
350
|
response: createMockHTTPResponse(),
|
|
348
351
|
},
|
|
349
|
-
|
|
352
|
+
...createMiddlewareSessionWireProps(SessionService),
|
|
350
353
|
} as any,
|
|
351
354
|
async () => {
|
|
352
355
|
nextCalled = true
|
|
@@ -21,8 +21,8 @@ export const authAPIKey = pikkuMiddlewareFactory<{
|
|
|
21
21
|
source: 'header' | 'query' | 'all'
|
|
22
22
|
}>(({ source }) =>
|
|
23
23
|
pikkuMiddleware(
|
|
24
|
-
async ({ jwt: jwtService }, { http, session
|
|
25
|
-
if (!http?.request || !
|
|
24
|
+
async ({ jwt: jwtService }, { http, setSession, session }, next) => {
|
|
25
|
+
if (!http?.request || !setSession || session) {
|
|
26
26
|
return next()
|
|
27
27
|
}
|
|
28
28
|
|
|
@@ -37,7 +37,7 @@ export const authAPIKey = pikkuMiddlewareFactory<{
|
|
|
37
37
|
if (apiKey && jwtService) {
|
|
38
38
|
const userSession = await jwtService.decode(apiKey)
|
|
39
39
|
if (userSession) {
|
|
40
|
-
|
|
40
|
+
setSession?.(userSession)
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
|
|
@@ -3,7 +3,10 @@ import assert from 'node:assert/strict'
|
|
|
3
3
|
import { authBearer } from './auth-bearer.js'
|
|
4
4
|
import { resetPikkuState } from '../pikku-state.js'
|
|
5
5
|
import { CoreUserSession } from '../types/core.types.js'
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
PikkuSessionService,
|
|
8
|
+
createMiddlewareSessionWireProps,
|
|
9
|
+
} from '../services/user-session-service.js'
|
|
7
10
|
import { InvalidSessionError } from '../errors/errors.js'
|
|
8
11
|
|
|
9
12
|
beforeEach(() => {
|
|
@@ -39,7 +42,7 @@ describe('authBearer middleware', () => {
|
|
|
39
42
|
await middleware(
|
|
40
43
|
{ jwt: jwtService } as any,
|
|
41
44
|
{
|
|
42
|
-
|
|
45
|
+
...createMiddlewareSessionWireProps(SessionService),
|
|
43
46
|
http: {
|
|
44
47
|
request: createMockHTTPRequest({
|
|
45
48
|
authorization: 'Bearer jwt-token',
|
|
@@ -73,7 +76,7 @@ describe('authBearer middleware', () => {
|
|
|
73
76
|
await middleware(
|
|
74
77
|
{ jwt: jwtService } as any,
|
|
75
78
|
{
|
|
76
|
-
|
|
79
|
+
...createMiddlewareSessionWireProps(SessionService),
|
|
77
80
|
http: {
|
|
78
81
|
request: createMockHTTPRequest({
|
|
79
82
|
Authorization: 'Bearer jwt-token-2',
|
|
@@ -116,7 +119,7 @@ describe('authBearer middleware', () => {
|
|
|
116
119
|
await middleware(
|
|
117
120
|
{ jwt: jwtService } as any,
|
|
118
121
|
{
|
|
119
|
-
|
|
122
|
+
...createMiddlewareSessionWireProps(SessionService),
|
|
120
123
|
http: {
|
|
121
124
|
request: createMockHTTPRequest({
|
|
122
125
|
authorization: 'Bearer my-static-token',
|
|
@@ -147,7 +150,7 @@ describe('authBearer middleware', () => {
|
|
|
147
150
|
await middleware(
|
|
148
151
|
{ jwt: jwtService } as any,
|
|
149
152
|
{
|
|
150
|
-
|
|
153
|
+
...createMiddlewareSessionWireProps(SessionService),
|
|
151
154
|
http: {
|
|
152
155
|
request: createMockHTTPRequest({
|
|
153
156
|
authorization: 'Basic some-token',
|
|
@@ -179,7 +182,7 @@ describe('authBearer middleware', () => {
|
|
|
179
182
|
await middleware(
|
|
180
183
|
{ jwt: jwtService } as any,
|
|
181
184
|
{
|
|
182
|
-
|
|
185
|
+
...createMiddlewareSessionWireProps(SessionService),
|
|
183
186
|
http: {
|
|
184
187
|
request: createMockHTTPRequest({
|
|
185
188
|
authorization: 'Bearer',
|
|
@@ -211,7 +214,7 @@ describe('authBearer middleware', () => {
|
|
|
211
214
|
await middleware(
|
|
212
215
|
{ jwt: jwtService } as any,
|
|
213
216
|
{
|
|
214
|
-
|
|
217
|
+
...createMiddlewareSessionWireProps(SessionService),
|
|
215
218
|
http: {
|
|
216
219
|
request: createMockHTTPRequest({
|
|
217
220
|
authorization: 'BearerToken',
|
|
@@ -242,7 +245,7 @@ describe('authBearer middleware', () => {
|
|
|
242
245
|
await middleware(
|
|
243
246
|
{ jwt: jwtService } as any,
|
|
244
247
|
{
|
|
245
|
-
|
|
248
|
+
...createMiddlewareSessionWireProps(SessionService),
|
|
246
249
|
http: {
|
|
247
250
|
request: createMockHTTPRequest({
|
|
248
251
|
authorization: 'Bearer invalid-token',
|
|
@@ -282,7 +285,7 @@ describe('authBearer middleware', () => {
|
|
|
282
285
|
await middleware(
|
|
283
286
|
{ jwt: jwtService } as any,
|
|
284
287
|
{
|
|
285
|
-
|
|
288
|
+
...createMiddlewareSessionWireProps(SessionService),
|
|
286
289
|
http: {
|
|
287
290
|
request: createMockHTTPRequest({
|
|
288
291
|
authorization: 'Bearer wrong-token',
|
|
@@ -319,7 +322,7 @@ describe('authBearer middleware', () => {
|
|
|
319
322
|
await middleware(
|
|
320
323
|
{ jwt: jwtService } as any,
|
|
321
324
|
{
|
|
322
|
-
|
|
325
|
+
...createMiddlewareSessionWireProps(SessionService),
|
|
323
326
|
http: {
|
|
324
327
|
request: createMockHTTPRequest({
|
|
325
328
|
authorization: 'Bearer some-token',
|
|
@@ -349,7 +352,7 @@ describe('authBearer middleware', () => {
|
|
|
349
352
|
|
|
350
353
|
await middleware(
|
|
351
354
|
{ jwt: jwtService } as any,
|
|
352
|
-
{
|
|
355
|
+
{ ...createMiddlewareSessionWireProps(SessionService) } as any,
|
|
353
356
|
async () => {
|
|
354
357
|
nextCalled = true
|
|
355
358
|
}
|
|
@@ -372,7 +375,7 @@ describe('authBearer middleware', () => {
|
|
|
372
375
|
await middleware(
|
|
373
376
|
{ jwt: jwtService } as any,
|
|
374
377
|
{
|
|
375
|
-
|
|
378
|
+
...createMiddlewareSessionWireProps(SessionService),
|
|
376
379
|
http: {
|
|
377
380
|
request: createMockHTTPRequest({}),
|
|
378
381
|
response: createMockHTTPResponse(),
|
|
@@ -396,7 +399,7 @@ describe('authBearer middleware', () => {
|
|
|
396
399
|
await middleware(
|
|
397
400
|
{ jwt: undefined } as any,
|
|
398
401
|
{
|
|
399
|
-
|
|
402
|
+
...createMiddlewareSessionWireProps(SessionService),
|
|
400
403
|
http: {
|
|
401
404
|
request: createMockHTTPRequest({
|
|
402
405
|
authorization: 'Bearer some-token',
|
|
@@ -428,7 +431,7 @@ describe('authBearer middleware', () => {
|
|
|
428
431
|
await middleware(
|
|
429
432
|
{ jwt: undefined } as any,
|
|
430
433
|
{
|
|
431
|
-
|
|
434
|
+
...createMiddlewareSessionWireProps(SessionService),
|
|
432
435
|
http: {
|
|
433
436
|
request: createMockHTTPRequest({
|
|
434
437
|
authorization: 'Bearer static-token',
|
|
@@ -40,38 +40,36 @@ export const authBearer = pikkuMiddlewareFactory<{
|
|
|
40
40
|
userSession: CoreUserSession
|
|
41
41
|
}
|
|
42
42
|
}>(({ token } = {}) =>
|
|
43
|
-
pikkuMiddleware(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
43
|
+
pikkuMiddleware(
|
|
44
|
+
async ({ jwt: jwtService }, { http, setSession, session }, next) => {
|
|
45
|
+
if (!http?.request || !setSession || session) {
|
|
46
|
+
return next()
|
|
47
|
+
}
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
const authHeader =
|
|
50
|
+
http.request.header('authorization') ||
|
|
51
|
+
http.request.header('Authorization')
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
53
|
+
if (authHeader) {
|
|
54
|
+
const [scheme, bearerToken] = authHeader.split(' ')
|
|
55
|
+
if (scheme !== 'Bearer' || !bearerToken) {
|
|
56
|
+
throw new InvalidSessionError()
|
|
57
|
+
}
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
let userSession: CoreUserSession | null = null
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
else if (jwtService && !token) {
|
|
67
|
-
userSession = await jwtService.decode(bearerToken)
|
|
68
|
-
}
|
|
61
|
+
if (token && bearerToken === token.value) {
|
|
62
|
+
userSession = token.userSession
|
|
63
|
+
} else if (jwtService && !token) {
|
|
64
|
+
userSession = await jwtService.decode(bearerToken)
|
|
65
|
+
}
|
|
69
66
|
|
|
70
|
-
|
|
71
|
-
|
|
67
|
+
if (userSession) {
|
|
68
|
+
setSession?.(userSession)
|
|
69
|
+
}
|
|
72
70
|
}
|
|
73
|
-
}
|
|
74
71
|
|
|
75
|
-
|
|
76
|
-
|
|
72
|
+
return next()
|
|
73
|
+
}
|
|
74
|
+
)
|
|
77
75
|
)
|
|
@@ -3,7 +3,10 @@ import assert from 'node:assert/strict'
|
|
|
3
3
|
import { authCookie } from './auth-cookie.js'
|
|
4
4
|
import { resetPikkuState } from '../pikku-state.js'
|
|
5
5
|
import { CoreUserSession } from '../types/core.types.js'
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
PikkuSessionService,
|
|
8
|
+
createMiddlewareSessionWireProps,
|
|
9
|
+
} from '../services/user-session-service.js'
|
|
7
10
|
|
|
8
11
|
beforeEach(() => {
|
|
9
12
|
resetPikkuState()
|
|
@@ -66,7 +69,7 @@ describe('authCookie middleware', () => {
|
|
|
66
69
|
logger: createMockLogger(),
|
|
67
70
|
} as any,
|
|
68
71
|
{
|
|
69
|
-
|
|
72
|
+
...createMiddlewareSessionWireProps(SessionService),
|
|
70
73
|
http: {
|
|
71
74
|
request: createMockHTTPRequest({ session: 'cookie-jwt-value' }),
|
|
72
75
|
response: mockResponse,
|
|
@@ -107,7 +110,7 @@ describe('authCookie middleware', () => {
|
|
|
107
110
|
logger: createMockLogger(),
|
|
108
111
|
} as any,
|
|
109
112
|
{
|
|
110
|
-
|
|
113
|
+
...createMiddlewareSessionWireProps(SessionService),
|
|
111
114
|
http: {
|
|
112
115
|
request: createMockHTTPRequest({}),
|
|
113
116
|
response: mockResponse,
|
|
@@ -151,7 +154,7 @@ describe('authCookie middleware', () => {
|
|
|
151
154
|
logger: createMockLogger(),
|
|
152
155
|
} as any,
|
|
153
156
|
{
|
|
154
|
-
|
|
157
|
+
...createMiddlewareSessionWireProps(SessionService),
|
|
155
158
|
http: {
|
|
156
159
|
request: createMockHTTPRequest({ session: 'existing-jwt' }),
|
|
157
160
|
response: mockResponse,
|
|
@@ -192,7 +195,7 @@ describe('authCookie middleware', () => {
|
|
|
192
195
|
logger: createMockLogger(),
|
|
193
196
|
} as any,
|
|
194
197
|
{
|
|
195
|
-
|
|
198
|
+
...createMiddlewareSessionWireProps(SessionService),
|
|
196
199
|
http: {
|
|
197
200
|
request: createMockHTTPRequest({}),
|
|
198
201
|
response: mockResponse,
|
|
@@ -230,7 +233,7 @@ describe('authCookie middleware', () => {
|
|
|
230
233
|
logger: createMockLogger(),
|
|
231
234
|
} as any,
|
|
232
235
|
{
|
|
233
|
-
|
|
236
|
+
...createMiddlewareSessionWireProps(SessionService),
|
|
234
237
|
http: {
|
|
235
238
|
request: createMockHTTPRequest({ session: 'invalid-jwt' }),
|
|
236
239
|
response: mockResponse,
|
|
@@ -274,7 +277,7 @@ describe('authCookie middleware', () => {
|
|
|
274
277
|
logger: createMockLogger(),
|
|
275
278
|
} as any,
|
|
276
279
|
{
|
|
277
|
-
|
|
280
|
+
...createMiddlewareSessionWireProps(SessionService),
|
|
278
281
|
http: {
|
|
279
282
|
request: createMockHTTPRequest({ session: 'some-jwt' }),
|
|
280
283
|
response: mockResponse,
|
|
@@ -309,7 +312,7 @@ describe('authCookie middleware', () => {
|
|
|
309
312
|
jwt: jwtService,
|
|
310
313
|
logger: createMockLogger(),
|
|
311
314
|
} as any,
|
|
312
|
-
{
|
|
315
|
+
{ ...createMiddlewareSessionWireProps(SessionService) } as any,
|
|
313
316
|
async () => {
|
|
314
317
|
nextCalled = true
|
|
315
318
|
}
|
|
@@ -337,7 +340,7 @@ describe('authCookie middleware', () => {
|
|
|
337
340
|
logger: createMockLogger(),
|
|
338
341
|
} as any,
|
|
339
342
|
{
|
|
340
|
-
|
|
343
|
+
...createMiddlewareSessionWireProps(SessionService),
|
|
341
344
|
http: {
|
|
342
345
|
request: createMockHTTPRequest({ session: 'some-jwt' }),
|
|
343
346
|
response: mockResponse,
|
|
@@ -371,7 +374,7 @@ describe('authCookie middleware', () => {
|
|
|
371
374
|
logger: mockLogger,
|
|
372
375
|
} as any,
|
|
373
376
|
{
|
|
374
|
-
|
|
377
|
+
...createMiddlewareSessionWireProps(SessionService),
|
|
375
378
|
http: {
|
|
376
379
|
request: createMockHTTPRequest({}),
|
|
377
380
|
response: mockResponse,
|
|
@@ -415,7 +418,7 @@ describe('authCookie middleware', () => {
|
|
|
415
418
|
logger: createMockLogger(),
|
|
416
419
|
} as any,
|
|
417
420
|
{
|
|
418
|
-
|
|
421
|
+
...createMiddlewareSessionWireProps(SessionService),
|
|
419
422
|
http: {
|
|
420
423
|
request: createMockHTTPRequest({}),
|
|
421
424
|
response: undefined,
|
|
@@ -456,7 +459,7 @@ describe('authCookie middleware', () => {
|
|
|
456
459
|
logger: createMockLogger(),
|
|
457
460
|
} as any,
|
|
458
461
|
{
|
|
459
|
-
|
|
462
|
+
...createMiddlewareSessionWireProps(SessionService),
|
|
460
463
|
http: {
|
|
461
464
|
request: createMockHTTPRequest({
|
|
462
465
|
my_custom_cookie: 'custom-cookie-value',
|
|
@@ -498,7 +501,7 @@ describe('authCookie middleware', () => {
|
|
|
498
501
|
logger: createMockLogger(),
|
|
499
502
|
} as any,
|
|
500
503
|
{
|
|
501
|
-
|
|
504
|
+
...createMiddlewareSessionWireProps(SessionService),
|
|
502
505
|
http: {
|
|
503
506
|
request: createMockHTTPRequest({}),
|
|
504
507
|
response: mockResponse,
|
|
@@ -41,35 +41,33 @@ export const authCookie = pikkuMiddlewareFactory<{
|
|
|
41
41
|
pikkuMiddleware(
|
|
42
42
|
async (
|
|
43
43
|
{ jwt: jwtService, logger },
|
|
44
|
-
{ http, session
|
|
44
|
+
{ http, setSession, getSession, session, hasSessionChanged },
|
|
45
45
|
next
|
|
46
46
|
) => {
|
|
47
|
-
if (!http?.request || !
|
|
47
|
+
if (!http?.request || !setSession || session) {
|
|
48
48
|
return next()
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
// Try to decode session from cookie
|
|
52
51
|
const cookieValue = http.request.cookie(name)
|
|
53
52
|
if (cookieValue && jwtService) {
|
|
54
53
|
const userSession = await jwtService.decode(cookieValue)
|
|
55
54
|
if (userSession) {
|
|
56
|
-
|
|
55
|
+
setSession?.(userSession)
|
|
57
56
|
}
|
|
58
57
|
}
|
|
59
58
|
|
|
60
59
|
await next()
|
|
61
60
|
|
|
62
|
-
// Set the cookie in the response if the session has changed
|
|
63
61
|
if (!http?.response) {
|
|
64
62
|
return
|
|
65
63
|
}
|
|
66
64
|
|
|
67
|
-
if (
|
|
68
|
-
const
|
|
65
|
+
if (hasSessionChanged?.()) {
|
|
66
|
+
const currentSession = await getSession?.()
|
|
69
67
|
if (jwtService) {
|
|
70
68
|
http.response.cookie(
|
|
71
69
|
name,
|
|
72
|
-
await jwtService.encode(expiresIn,
|
|
70
|
+
await jwtService.encode(expiresIn, currentSession),
|
|
73
71
|
{
|
|
74
72
|
...options,
|
|
75
73
|
expires: getRelativeTimeOffsetFromNow(expiresIn),
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { pikkuMiddleware, pikkuMiddlewareFactory } from '../types/core.types.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* CORS middleware that handles cross-origin requests including OPTIONS preflight.
|
|
5
|
+
*
|
|
6
|
+
* Sets appropriate CORS headers on all responses and short-circuits OPTIONS
|
|
7
|
+
* preflight requests with a 204 No Content response.
|
|
8
|
+
*
|
|
9
|
+
* @param options.origin - Allowed origin(s). Use `'*'` for any origin, a string for a single origin, or an array for multiple origins. Defaults to `'*'`.
|
|
10
|
+
* @param options.methods - Allowed HTTP methods. Defaults to common methods.
|
|
11
|
+
* @param options.headers - Allowed request headers. Defaults to common headers.
|
|
12
|
+
* @param options.credentials - Whether to allow credentials. Defaults to `false`.
|
|
13
|
+
* @param options.maxAge - Preflight cache duration in seconds. Defaults to `86400` (24 hours).
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* import { cors } from '@pikku/core/middleware'
|
|
18
|
+
*
|
|
19
|
+
* // Allow all origins
|
|
20
|
+
* addHTTPMiddleware('*', [cors()])
|
|
21
|
+
*
|
|
22
|
+
* // Specific origin with credentials
|
|
23
|
+
* addHTTPMiddleware('*', [
|
|
24
|
+
* cors({
|
|
25
|
+
* origin: 'https://app.example.com',
|
|
26
|
+
* credentials: true,
|
|
27
|
+
* })
|
|
28
|
+
* ])
|
|
29
|
+
*
|
|
30
|
+
* // Multiple origins
|
|
31
|
+
* addHTTPMiddleware('*', [
|
|
32
|
+
* cors({
|
|
33
|
+
* origin: ['https://app.example.com', 'https://admin.example.com'],
|
|
34
|
+
* })
|
|
35
|
+
* ])
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export const cors = pikkuMiddlewareFactory<{
|
|
39
|
+
origin?: string | string[]
|
|
40
|
+
methods?: string[]
|
|
41
|
+
headers?: string[]
|
|
42
|
+
credentials?: boolean
|
|
43
|
+
maxAge?: number
|
|
44
|
+
}>(
|
|
45
|
+
({
|
|
46
|
+
origin = '*',
|
|
47
|
+
methods = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
|
|
48
|
+
headers = ['Content-Type', 'Authorization', 'x-api-key'],
|
|
49
|
+
credentials = false,
|
|
50
|
+
maxAge = 86400,
|
|
51
|
+
} = {}) =>
|
|
52
|
+
pikkuMiddleware({
|
|
53
|
+
name: 'CORS',
|
|
54
|
+
description: 'Handles cross-origin requests including OPTIONS preflight',
|
|
55
|
+
func: async (_services, wires, next) => {
|
|
56
|
+
const request = wires.http?.request
|
|
57
|
+
const response = wires.http?.response
|
|
58
|
+
|
|
59
|
+
if (!request || !response) {
|
|
60
|
+
return next()
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const requestOrigin = request.header('origin')
|
|
64
|
+
|
|
65
|
+
let allowedOrigin: string
|
|
66
|
+
if (Array.isArray(origin)) {
|
|
67
|
+
allowedOrigin =
|
|
68
|
+
requestOrigin && origin.includes(requestOrigin)
|
|
69
|
+
? requestOrigin
|
|
70
|
+
: origin[0]
|
|
71
|
+
} else {
|
|
72
|
+
allowedOrigin = origin
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
response.header('Access-Control-Allow-Origin', allowedOrigin)
|
|
76
|
+
response.header('Access-Control-Allow-Methods', methods.join(', '))
|
|
77
|
+
response.header('Access-Control-Allow-Headers', headers.join(', '))
|
|
78
|
+
|
|
79
|
+
if (credentials) {
|
|
80
|
+
response.header('Access-Control-Allow-Credentials', 'true')
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (Array.isArray(origin)) {
|
|
84
|
+
response.header('Vary', 'Origin')
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (request.method() === 'options') {
|
|
88
|
+
response.header('Access-Control-Max-Age', String(maxAge))
|
|
89
|
+
response.status(204).json(undefined as any)
|
|
90
|
+
return
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return next()
|
|
94
|
+
},
|
|
95
|
+
})
|
|
96
|
+
)
|
package/src/middleware/index.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
3
|
-
export
|
|
1
|
+
export { authAPIKey } from './auth-apikey.js'
|
|
2
|
+
export { authCookie } from './auth-cookie.js'
|
|
3
|
+
export { authBearer } from './auth-bearer.js'
|
|
4
|
+
export { pikkuRemoteAuthMiddleware } from './remote-auth.js'
|
|
5
|
+
export { cors } from './cors.js'
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { UnauthorizedError } from '../errors/errors.js'
|
|
2
|
+
import { pikkuMiddleware } from '../types/core.types.js'
|
|
3
|
+
import { decryptJSON } from '../crypto-utils.js'
|
|
4
|
+
|
|
5
|
+
export const pikkuRemoteAuthMiddleware = pikkuMiddleware(
|
|
6
|
+
async ({ secrets, jwt }, { http, setSession }, next) => {
|
|
7
|
+
if (!http?.request || !secrets) {
|
|
8
|
+
return next()
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
let secret: string
|
|
12
|
+
try {
|
|
13
|
+
secret = await secrets.getSecret('PIKKU_REMOTE_SECRET')
|
|
14
|
+
} catch {
|
|
15
|
+
return next()
|
|
16
|
+
}
|
|
17
|
+
if (!jwt) {
|
|
18
|
+
throw new Error('PIKKU_REMOTE_SECRET set but JWT service missing')
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const authHeader =
|
|
22
|
+
http.request.header('authorization') ||
|
|
23
|
+
http.request.header('Authorization')
|
|
24
|
+
|
|
25
|
+
if (!authHeader) {
|
|
26
|
+
throw new UnauthorizedError()
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const [scheme, token] = authHeader.split(' ')
|
|
30
|
+
if (scheme !== 'Bearer' || !token) {
|
|
31
|
+
throw new UnauthorizedError()
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
let payload: any
|
|
35
|
+
try {
|
|
36
|
+
payload = await jwt.decode(token)
|
|
37
|
+
} catch {
|
|
38
|
+
throw new UnauthorizedError()
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (payload?.aud !== 'pikku-remote') {
|
|
42
|
+
throw new UnauthorizedError()
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (payload?.fn && http.request.path().startsWith('/rpc/')) {
|
|
46
|
+
const fn = decodeURIComponent(http.request.path().slice('/rpc/'.length))
|
|
47
|
+
if (fn && payload.fn !== fn) {
|
|
48
|
+
throw new UnauthorizedError()
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (payload?.session) {
|
|
53
|
+
try {
|
|
54
|
+
const decrypted = await decryptJSON<{ session?: unknown }>(
|
|
55
|
+
secret,
|
|
56
|
+
payload.session
|
|
57
|
+
)
|
|
58
|
+
if (decrypted?.session && setSession) {
|
|
59
|
+
await setSession(decrypted.session)
|
|
60
|
+
}
|
|
61
|
+
} catch {
|
|
62
|
+
throw new UnauthorizedError()
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return next()
|
|
67
|
+
}
|
|
68
|
+
)
|