@owlmeans/server-auth 0.1.18-rc.4 → 0.1.18-rc.40
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/README.md +184 -38
- package/agent-meta/manifest.json +9 -2
- package/agent-meta/skills/server-auth/SKILL.md +101 -22
- package/agent-meta/skills/supervisor-auth/SKILL.md +128 -0
- package/build/actions/service.d.ts +6 -2
- package/build/actions/service.d.ts.map +1 -1
- package/build/actions/service.js +5 -4
- package/build/actions/service.js.map +1 -1
- package/build/entrypoints.d.ts +5 -0
- package/build/entrypoints.d.ts.map +1 -0
- package/build/entrypoints.js +9 -0
- package/build/entrypoints.js.map +1 -0
- package/build/index.d.ts +1 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +1 -1
- package/build/index.js.map +1 -1
- package/build/manager/actions/manager.d.ts +17 -5
- package/build/manager/actions/manager.d.ts.map +1 -1
- package/build/manager/actions/manager.js +7 -6
- package/build/manager/actions/manager.js.map +1 -1
- package/build/manager/context.d.ts.map +1 -1
- package/build/manager/context.js +0 -1
- package/build/manager/context.js.map +1 -1
- package/build/manager/entrypoints.d.ts +9 -0
- package/build/manager/entrypoints.d.ts.map +1 -0
- package/build/manager/entrypoints.js +24 -0
- package/build/manager/entrypoints.js.map +1 -0
- package/build/manager/exports.d.ts +1 -2
- package/build/manager/exports.d.ts.map +1 -1
- package/build/manager/exports.js +1 -2
- package/build/manager/exports.js.map +1 -1
- package/build/manager/index.d.ts +1 -1
- package/build/manager/index.d.ts.map +1 -1
- package/build/manager/index.js +1 -1
- package/build/manager/index.js.map +1 -1
- package/build/manager/main.js +2 -2
- package/build/manager/main.js.map +1 -1
- package/build/manager/model.d.ts.map +1 -1
- package/build/manager/model.js +26 -10
- package/build/manager/model.js.map +1 -1
- package/build/manager/plugins/basic-ed25519.js.map +1 -1
- package/build/manager/plugins/basic-rely.d.ts.map +1 -1
- package/build/manager/plugins/basic-rely.js +5 -5
- package/build/manager/plugins/basic-rely.js.map +1 -1
- package/build/manager/plugins/export.d.ts +1 -0
- package/build/manager/plugins/export.d.ts.map +1 -1
- package/build/manager/plugins/export.js +1 -0
- package/build/manager/plugins/export.js.map +1 -1
- package/build/manager/plugins/re-captcha.js +1 -1
- package/build/manager/plugins/re-captcha.js.map +1 -1
- package/build/manager/plugins/replay-policy.d.ts +8 -0
- package/build/manager/plugins/replay-policy.d.ts.map +1 -0
- package/build/manager/plugins/replay-policy.js +9 -0
- package/build/manager/plugins/replay-policy.js.map +1 -0
- package/build/manager/plugins/supervisor.js +3 -3
- package/build/manager/plugins/supervisor.js.map +1 -1
- package/build/manager/plugins/types.d.ts +6 -0
- package/build/manager/plugins/types.d.ts.map +1 -1
- package/build/manager/rely/flow.js +1 -1
- package/build/manager/rely/flow.js.map +1 -1
- package/build/manager/supervisor.d.ts +5 -5
- package/build/manager/supervisor.d.ts.map +1 -1
- package/build/manager/supervisor.js +4 -4
- package/build/manager/supervisor.js.map +1 -1
- package/build/model/rely/consumer.d.ts +3 -1
- package/build/model/rely/consumer.d.ts.map +1 -1
- package/build/model/rely/consumer.js.map +1 -1
- package/build/model/rely/provider.d.ts +3 -1
- package/build/model/rely/provider.d.ts.map +1 -1
- package/build/model/rely/provider.js.map +1 -1
- package/build/service.d.ts.map +1 -1
- package/build/service.js +116 -9
- package/build/service.js.map +1 -1
- package/package.json +28 -26
- package/src/actions/service.ts +9 -8
- package/src/entrypoints.ts +12 -0
- package/src/index.ts +1 -1
- package/src/manager/README.md +14 -18
- package/src/manager/actions/manager.ts +15 -13
- package/src/manager/context.ts +0 -2
- package/src/manager/entrypoints.ts +26 -0
- package/src/manager/exports.ts +1 -2
- package/src/manager/index.ts +1 -1
- package/src/manager/main.ts +2 -2
- package/src/manager/model.ts +28 -10
- package/src/manager/plugins/basic-ed25519.ts +2 -2
- package/src/manager/plugins/basic-rely.ts +7 -6
- package/src/manager/plugins/export.ts +1 -0
- package/src/manager/plugins/re-captcha.ts +3 -3
- package/src/manager/plugins/replay-policy.ts +7 -0
- package/src/manager/plugins/supervisor.ts +4 -4
- package/src/manager/plugins/types.ts +6 -0
- package/src/manager/rely/flow.ts +1 -1
- package/src/manager/supervisor.ts +6 -6
- package/src/model/rely/consumer.ts +3 -1
- package/src/model/rely/provider.ts +3 -1
- package/src/service.ts +114 -11
- package/tests/context.ts +3 -2
- package/tests/replay-policy.spec.ts +36 -0
- package/tests/supervisor.spec.ts +6 -4
- package/build/.gitkeep +0 -0
- package/build/manager/modules.d.ts +0 -2
- package/build/manager/modules.d.ts.map +0 -1
- package/build/manager/modules.js +0 -21
- package/build/manager/modules.js.map +0 -1
- package/build/modules.d.ts +0 -3
- package/build/modules.d.ts.map +0 -1
- package/build/modules.js +0 -11
- package/build/modules.js.map +0 -1
- package/src/manager/modules.ts +0 -29
- package/src/modules.ts +0 -17
|
@@ -4,7 +4,7 @@ import type { AppConfig, AppContext } from './types.js';
|
|
|
4
4
|
* What a `SupervisorUserResolver` returns: the identity the supervisor-minted
|
|
5
5
|
* token will represent. Only `userId` is required - the rest default sensibly.
|
|
6
6
|
*/
|
|
7
|
-
export interface SupervisorUserResolution extends Partial<Pick<AuthPayload, 'profileId' | '
|
|
7
|
+
export interface SupervisorUserResolution extends Partial<Pick<AuthPayload, 'profileId' | 'entitySlug' | 'role' | 'scopes'>> {
|
|
8
8
|
userId: string;
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
@@ -34,7 +34,7 @@ export interface SupervisorAuthOptions {
|
|
|
34
34
|
enabled?: boolean;
|
|
35
35
|
/**
|
|
36
36
|
* Also accept internal owlmeans `Ed25519BasicToken`s even when another guard
|
|
37
|
-
* (e.g. OIDC) is the primary guard on protected
|
|
37
|
+
* (e.g. OIDC) is the primary guard on protected entrypoints. Default: true.
|
|
38
38
|
*/
|
|
39
39
|
acceptInternalTokens?: boolean;
|
|
40
40
|
/** The internal-token guard to add as a coguard. Default: DEFAULT_GUARD ('auth'). */
|
|
@@ -42,12 +42,12 @@ export interface SupervisorAuthOptions {
|
|
|
42
42
|
}
|
|
43
43
|
/**
|
|
44
44
|
* Ensure the internal `Ed25519BasicToken` guard is accepted as a coguard on every
|
|
45
|
-
* already-guarded backend
|
|
45
|
+
* already-guarded backend entrypoint, so internal owlmeans tokens keep working even
|
|
46
46
|
* when another guard (e.g. OIDC) is the primary guard. The primary guard stays
|
|
47
47
|
* first; the internal guard is appended as a fallback (its `match` only fires for
|
|
48
48
|
* an `Ed25519BasicToken` authorization header).
|
|
49
49
|
*/
|
|
50
|
-
export declare const setupInternalTokenCoguard: (
|
|
50
|
+
export declare const setupInternalTokenCoguard: (entrypoints: Array<{
|
|
51
51
|
guards?: string[];
|
|
52
52
|
}>, guard?: string) => void;
|
|
53
53
|
/**
|
|
@@ -56,7 +56,7 @@ export declare const setupInternalTokenCoguard: (modules: Array<{
|
|
|
56
56
|
*
|
|
57
57
|
* It registers the supervisor auth plugin (verifies a front-end signature against
|
|
58
58
|
* the allowlisted trusted keys, then resolves/registers the target user) and -
|
|
59
|
-
* unless disabled - makes protected
|
|
59
|
+
* unless disabled - makes protected entrypoints also accept internal owlmeans tokens
|
|
60
60
|
* (requirement: understand internal tokens even when OIDC is the primary guard).
|
|
61
61
|
*/
|
|
62
62
|
export declare const appendSupervisorAuth: <C extends AppConfig, T extends AppContext<C>>(context: T, opts?: SupervisorAuthOptions) => T;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"supervisor.d.ts","sourceRoot":"","sources":["../../src/manager/supervisor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAEjD,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAIvD;;;GAGG;AACH,MAAM,WAAW,wBAAyB,SAAQ,OAAO,CAAC,IAAI,CAAC,WAAW,EACxE,WAAW,GAAG,
|
|
1
|
+
{"version":3,"file":"supervisor.d.ts","sourceRoot":"","sources":["../../src/manager/supervisor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAEjD,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAIvD;;;GAGG;AACH,MAAM,WAAW,wBAAyB,SAAQ,OAAO,CAAC,IAAI,CAAC,WAAW,EACxE,WAAW,GAAG,YAAY,GAAG,MAAM,GAAG,QAAQ,CAAC,CAAC;IAChD,MAAM,EAAE,MAAM,CAAA;CACf;AAED;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC,CAAC,CAAC,SAAS,SAAS,EAAE,CAAC,SAAS,UAAU,CAAC,CAAC,CAAC,EAC3C,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE;QAAE,QAAQ,EAAE,OAAO,CAAA;KAAE,GACtD,OAAO,CAAC,wBAAwB,CAAC,CAAA;CACrC;AAED,qDAAqD;AACrD,MAAM,WAAW,uBAAuB;IACtC,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,iBAAiB,EAAE,OAAO,CAAA;IAC1B,WAAW,CAAC,EAAE,sBAAsB,CAAA;CACrC;AAED,MAAM,WAAW,qBAAqB;IACpC,2FAA2F;IAC3F,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB,+EAA+E;IAC/E,WAAW,CAAC,EAAE,sBAAsB,CAAA;IACpC,+EAA+E;IAC/E,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,+FAA+F;IAC/F,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;OAGG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,qFAAqF;IACrF,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAOD;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,gBACvB,KAAK,CAAC;IAAE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,UAAS,MAAM,KACvD,IAMF,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,GAAI,CAAC,SAAS,SAAS,EAAE,CAAC,SAAS,UAAU,CAAC,CAAC,CAAC,WACtE,CAAC,SAAS,qBAAqB,KACvC,CAyBF,CAAA"}
|
|
@@ -6,13 +6,13 @@ const DEFAULT_SUPERVISORS = ['master', 'superuser'];
|
|
|
6
6
|
const isDevelopment = (context) => context.cfg.debug?.all === true || context.cfg.debug?.supervisor === true;
|
|
7
7
|
/**
|
|
8
8
|
* Ensure the internal `Ed25519BasicToken` guard is accepted as a coguard on every
|
|
9
|
-
* already-guarded backend
|
|
9
|
+
* already-guarded backend entrypoint, so internal owlmeans tokens keep working even
|
|
10
10
|
* when another guard (e.g. OIDC) is the primary guard. The primary guard stays
|
|
11
11
|
* first; the internal guard is appended as a fallback (its `match` only fires for
|
|
12
12
|
* an `Ed25519BasicToken` authorization header).
|
|
13
13
|
*/
|
|
14
|
-
export const setupInternalTokenCoguard = (
|
|
15
|
-
|
|
14
|
+
export const setupInternalTokenCoguard = (entrypoints, guard = DEFAULT_GUARD) => {
|
|
15
|
+
entrypoints.forEach(module => {
|
|
16
16
|
if (module.guards != null && module.guards.length > 0 && !module.guards.includes(guard)) {
|
|
17
17
|
module.guards.push(guard);
|
|
18
18
|
}
|
|
@@ -24,7 +24,7 @@ export const setupInternalTokenCoguard = (modules, guard = DEFAULT_GUARD) => {
|
|
|
24
24
|
*
|
|
25
25
|
* It registers the supervisor auth plugin (verifies a front-end signature against
|
|
26
26
|
* the allowlisted trusted keys, then resolves/registers the target user) and -
|
|
27
|
-
* unless disabled - makes protected
|
|
27
|
+
* unless disabled - makes protected entrypoints also accept internal owlmeans tokens
|
|
28
28
|
* (requirement: understand internal tokens even when OIDC is the primary guard).
|
|
29
29
|
*/
|
|
30
30
|
export const appendSupervisorAuth = (context, opts) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"supervisor.js","sourceRoot":"","sources":["../../src/manager/supervisor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAEnD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAErD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AA+C9D,MAAM,mBAAmB,GAAG,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAA;AAEnD,MAAM,aAAa,GAAG,CAAC,OAAqE,EAAW,EAAE,CACvG,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;AAE3E;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CACvC,
|
|
1
|
+
{"version":3,"file":"supervisor.js","sourceRoot":"","sources":["../../src/manager/supervisor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAEnD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAErD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AA+C9D,MAAM,mBAAmB,GAAG,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAA;AAEnD,MAAM,aAAa,GAAG,CAAC,OAAqE,EAAW,EAAE,CACvG,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;AAE3E;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CACvC,WAAyC,EAAE,KAAK,GAAW,aAAa,EAClE,EAAE;IACR,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;QAC3B,IAAI,MAAM,CAAC,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACxF,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAC3B,CAAC;IACH,CAAC,CAAC,CAAA;AACJ,CAAC,CAAA;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,OAAU,EAAE,IAA4B,EACrC,EAAE;IACL,MAAM,OAAO,GAAG,IAAI,EAAE,OAAO,IAAI,aAAa,CAAC,OAAO,CAAC,CAAA;IACvD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,MAAM,QAAQ,GAA4B;QACxC,WAAW,EAAE,IAAI,EAAE,WAAW,IAAI,mBAAmB;QACrD,iBAAiB,EAAE,IAAI,EAAE,iBAAiB,IAAI,IAAI;QAClD,WAAW,EAAE,IAAI,EAAE,WAAW;KAC/B,CAAA;IAED,cAAc,CACZ,kBAAkB,CAAC,UAAU,EAC7B,CAAC,GAAG,CAAC,EAAE,CAAC,oBAAoB,CAAC,GAAuC,EAAE,QAAQ,CAAC,CAAyC,CACzH,CAAA;IAED,IAAI,IAAI,EAAE,oBAAoB,KAAK,KAAK,EAAE,CAAC;QACzC,yBAAyB,CACvB,OAAO,CAAC,WAAW,EAA6C,EAChE,IAAI,EAAE,KAAK,IAAI,aAAa,CAC7B,CAAA;IACH,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { RelyToken } from '@owlmeans/auth';
|
|
2
|
+
import type { EnvelopeModel } from '@owlmeans/basic-envelope';
|
|
1
3
|
import type { RelyOptions } from './types.js';
|
|
2
|
-
export declare const makeConsumerRely: (opts?: RelyOptions) =>
|
|
4
|
+
export declare const makeConsumerRely: (opts?: RelyOptions) => EnvelopeModel<RelyToken>;
|
|
3
5
|
//# sourceMappingURL=consumer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"consumer.d.ts","sourceRoot":"","sources":["../../../src/model/rely/consumer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE7C,eAAO,MAAM,gBAAgB,UAAW,WAAW,
|
|
1
|
+
{"version":3,"file":"consumer.d.ts","sourceRoot":"","sources":["../../../src/model/rely/consumer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAC7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE7C,eAAO,MAAM,gBAAgB,UAAW,WAAW,KAAG,aAAa,CAAC,SAAS,CAO5E,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"consumer.js","sourceRoot":"","sources":["../../../src/model/rely/consumer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"consumer.js","sourceRoot":"","sources":["../../../src/model/rely/consumer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAKzC,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,IAAkB,EAA4B,EAAE;IAC/E,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,CAAA;IACjC,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,EAAE,CAAA;IAC3B,OAAO,GAAG,CAAC,GAAG,CAAA;IACd,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAEf,OAAO,KAAK,CAAA;AACd,CAAC,CAAA"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { RelyToken } from '@owlmeans/auth';
|
|
2
|
+
import type { EnvelopeModel } from '@owlmeans/basic-envelope';
|
|
1
3
|
import type { RelyOptions } from './types.js';
|
|
2
|
-
export declare const makeProviderRely: (opts?: RelyOptions) =>
|
|
4
|
+
export declare const makeProviderRely: (opts?: RelyOptions) => EnvelopeModel<RelyToken>;
|
|
3
5
|
//# sourceMappingURL=provider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/model/rely/provider.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE7C,eAAO,MAAM,gBAAgB,UAAW,WAAW,
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/model/rely/provider.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAC7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE7C,eAAO,MAAM,gBAAgB,UAAW,WAAW,KAAG,aAAa,CAAC,SAAS,CAI5E,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../../src/model/rely/provider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../../src/model/rely/provider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAKzC,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,IAAkB,EAA4B,EAAE;IAC/E,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,CAAA;IAEjC,OAAO,KAAK,CAAA;AACd,CAAC,CAAA"}
|
package/build/service.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAG3E,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAa,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAG3E,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAa,MAAM,YAAY,CAAA;AAoB3E,KAAK,MAAM,GAAG,YAAY,CAAA;AAG1B,eAAO,MAAM,eAAe,WAAW,MAAM,KAAmB,WAqL/D,CAAA;AAED,eAAO,MAAM,iBAAiB,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,aAAa,CAAC,CAAC,CAAC,OACvE,CAAC,UAAS,MAAM,KACpB,CAAC,GAAG,iBAiBN,CAAA"}
|
package/build/service.js
CHANGED
|
@@ -2,12 +2,61 @@ import { TRUSTED } from '@owlmeans/config';
|
|
|
2
2
|
import { AUTH_CACHE, AUTH_SRV_KEY, AUTHEN_TIMEFRAME, DEFAULT_ALIAS } from './consts.js';
|
|
3
3
|
import { assertContext, createService } from '@owlmeans/context';
|
|
4
4
|
import { EnvelopeKind, makeEnvelopeModel } from '@owlmeans/basic-envelope';
|
|
5
|
-
import { AuthenFailed, AuthorizationError, AuthroizationType } from '@owlmeans/auth';
|
|
5
|
+
import { AuthenFailed, AuthorizationError, AuthroizationType, AuthUnavailable } from '@owlmeans/auth';
|
|
6
6
|
import { createStaticResource } from '@owlmeans/static-resource';
|
|
7
7
|
import { trust, extractAuthToken } from '@owlmeans/auth-common/utils';
|
|
8
|
+
import { ENTITY_RESOLVER } from '@owlmeans/auth-common';
|
|
9
|
+
import { AUTH_IDENTITY_PROFILE } from '@owlmeans/server-auth-identity';
|
|
10
|
+
import { appendMemoryAuthSessionManager, AUTH_SESSION_MANAGER, AUTH_SESSION_TTL } from '@owlmeans/server-auth-session';
|
|
11
|
+
import { uuid } from '@owlmeans/basic-ids';
|
|
12
|
+
import { TOKEN_UPDATE } from '@owlmeans/auth-common';
|
|
8
13
|
export const makeAuthService = (alias = DEFAULT_ALIAS) => {
|
|
9
14
|
const location = `server-auth:${alias}`;
|
|
10
15
|
const cache = (context) => context.resource(AUTH_CACHE);
|
|
16
|
+
const sessions = (context) => context.hasService(AUTH_SESSION_MANAGER)
|
|
17
|
+
? context.service(AUTH_SESSION_MANAGER)
|
|
18
|
+
: null;
|
|
19
|
+
const entityIdFor = async (context, entitySlug) => {
|
|
20
|
+
if (entitySlug == null || entitySlug === '')
|
|
21
|
+
return null;
|
|
22
|
+
if (!context.hasService(ENTITY_RESOLVER))
|
|
23
|
+
return entitySlug;
|
|
24
|
+
const entity = await context.service(ENTITY_RESOLVER).resolve(entitySlug);
|
|
25
|
+
return entity?.id ?? null;
|
|
26
|
+
};
|
|
27
|
+
const refresh = async (context, auth, version) => {
|
|
28
|
+
const entityId = await entityIdFor(context, auth.entitySlug);
|
|
29
|
+
if (entityId == null || auth.profileId == null || !context.hasResource(AUTH_IDENTITY_PROFILE))
|
|
30
|
+
return null;
|
|
31
|
+
const profiles = context.resource(AUTH_IDENTITY_PROFILE);
|
|
32
|
+
let profile = null;
|
|
33
|
+
try {
|
|
34
|
+
profile = await profiles.load({ entityId, profileId: auth.profileId });
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// A missing profile is a definitive authentication refusal; a failed profile store is an
|
|
38
|
+
// availability dependency and must not look like a revoked browser session.
|
|
39
|
+
throw new AuthUnavailable('identity-profile');
|
|
40
|
+
}
|
|
41
|
+
if (profile == null || (profile.expiresAt != null && new Date(profile.expiresAt).getTime() <= Date.now()))
|
|
42
|
+
return null;
|
|
43
|
+
return {
|
|
44
|
+
...auth,
|
|
45
|
+
userId: profile.userId ?? auth.userId,
|
|
46
|
+
role: profile.role,
|
|
47
|
+
scopes: profile.scopes ?? [],
|
|
48
|
+
...(profile.permissions != null ? { permissions: profile.permissions } : {}),
|
|
49
|
+
authorizationVersion: version,
|
|
50
|
+
createdAt: new Date()
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
const sign = async (context, auth) => {
|
|
54
|
+
const trusted = await trust(context, TRUSTED, context.cfg.alias ?? context.cfg.service);
|
|
55
|
+
const ttl = auth.expiresAt == null ? AUTH_SESSION_TTL : Math.max(0, new Date(auth.expiresAt).getTime() - Date.now());
|
|
56
|
+
const authorization = await makeEnvelopeModel(AuthroizationType.Ed25519BasicToken)
|
|
57
|
+
.send(auth, ttl).sign(trusted.key, EnvelopeKind.Token);
|
|
58
|
+
return `${AuthroizationType.Ed25519BasicToken.toUpperCase()} ${authorization}`;
|
|
59
|
+
};
|
|
11
60
|
const service = createService(alias, {
|
|
12
61
|
match: async (req) => extractAuthToken(req, AuthroizationType.Ed25519BasicToken) != null,
|
|
13
62
|
handle: async (req, res) => {
|
|
@@ -21,7 +70,32 @@ export const makeAuthService = (alias = DEFAULT_ALIAS) => {
|
|
|
21
70
|
if (!await envelope.verify(trusted.key)) {
|
|
22
71
|
return false;
|
|
23
72
|
}
|
|
24
|
-
|
|
73
|
+
let auth = envelope.message();
|
|
74
|
+
const manager = sessions(context);
|
|
75
|
+
if (manager != null) {
|
|
76
|
+
if (auth.sessionId == null)
|
|
77
|
+
return false;
|
|
78
|
+
let decision;
|
|
79
|
+
try {
|
|
80
|
+
decision = await manager.inspect(auth.sessionId);
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
// Registry availability is a security dependency. A guard cannot authenticate through it.
|
|
84
|
+
throw new AuthUnavailable('session-registry');
|
|
85
|
+
}
|
|
86
|
+
if (decision.state !== 'active' && decision.state !== 'refresh')
|
|
87
|
+
return false;
|
|
88
|
+
if (decision.state === 'refresh') {
|
|
89
|
+
const refreshed = await refresh(context, auth, decision.version);
|
|
90
|
+
if (refreshed == null)
|
|
91
|
+
return false;
|
|
92
|
+
auth = refreshed;
|
|
93
|
+
const replacement = await sign(context, auth);
|
|
94
|
+
res.responseProvider?.header(TOKEN_UPDATE, replacement);
|
|
95
|
+
req.headers = { ...req.headers, authorization: replacement };
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
res.resolve(auth);
|
|
25
99
|
return true;
|
|
26
100
|
},
|
|
27
101
|
unpack: async (token) => {
|
|
@@ -32,7 +106,22 @@ export const makeAuthService = (alias = DEFAULT_ALIAS) => {
|
|
|
32
106
|
if (!await envelope.verify(trusted.key)) {
|
|
33
107
|
throw new AuthorizationError('unpack');
|
|
34
108
|
}
|
|
35
|
-
|
|
109
|
+
const auth = envelope.message();
|
|
110
|
+
const manager = sessions(context);
|
|
111
|
+
if (manager != null) {
|
|
112
|
+
if (auth.sessionId == null)
|
|
113
|
+
throw new AuthorizationError('session');
|
|
114
|
+
let decision;
|
|
115
|
+
try {
|
|
116
|
+
decision = await manager.inspect(auth.sessionId);
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
throw new AuthUnavailable('session-registry');
|
|
120
|
+
}
|
|
121
|
+
if (decision.state !== 'active')
|
|
122
|
+
throw new AuthorizationError('session');
|
|
123
|
+
}
|
|
124
|
+
return auth;
|
|
36
125
|
},
|
|
37
126
|
authenticated: async () => {
|
|
38
127
|
return null;
|
|
@@ -57,6 +146,8 @@ export const makeAuthService = (alias = DEFAULT_ALIAS) => {
|
|
|
57
146
|
throw new AuthenFailed();
|
|
58
147
|
}
|
|
59
148
|
// @TODO Move to a plugin
|
|
149
|
+
const issuedAt = Date.now();
|
|
150
|
+
const expiresAt = new Date(issuedAt + AUTH_SESSION_TTL);
|
|
60
151
|
const auth = {
|
|
61
152
|
token: credentials.challenge,
|
|
62
153
|
userId: credentials.userId,
|
|
@@ -65,14 +156,27 @@ export const makeAuthService = (alias = DEFAULT_ALIAS) => {
|
|
|
65
156
|
type: AuthroizationType.Ed25519BasicToken,
|
|
66
157
|
source: context.cfg.service,
|
|
67
158
|
profileId: credentials.profileId,
|
|
68
|
-
|
|
159
|
+
entitySlug: credentials.entitySlug,
|
|
69
160
|
isUser: true,
|
|
70
|
-
createdAt: new Date()
|
|
161
|
+
createdAt: new Date(issuedAt),
|
|
162
|
+
expiresAt,
|
|
163
|
+
sessionId: uuid(),
|
|
164
|
+
authorizationVersion: 1
|
|
71
165
|
};
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
166
|
+
const manager = sessions(context);
|
|
167
|
+
if (manager != null) {
|
|
168
|
+
const entityId = await entityIdFor(context, auth.entitySlug);
|
|
169
|
+
if (entityId == null || auth.profileId == null)
|
|
170
|
+
throw new AuthenFailed('session');
|
|
171
|
+
const decision = await manager.register({
|
|
172
|
+
id: auth.sessionId, kind: 'bearer', entityId, profileId: auth.profileId,
|
|
173
|
+
issuedAt, expiresAt: expiresAt.getTime()
|
|
174
|
+
});
|
|
175
|
+
if (decision.state !== 'active')
|
|
176
|
+
throw new AuthenFailed('session');
|
|
177
|
+
auth.authorizationVersion = decision.version;
|
|
178
|
+
}
|
|
179
|
+
return { token: await sign(context, auth) };
|
|
76
180
|
}
|
|
77
181
|
});
|
|
78
182
|
return service;
|
|
@@ -81,6 +185,9 @@ export const appendAuthService = (ctx, alias = DEFAULT_ALIAS) => {
|
|
|
81
185
|
if (!ctx.hasResource(AUTH_CACHE)) {
|
|
82
186
|
ctx.registerResource(createStaticResource(AUTH_CACHE));
|
|
83
187
|
}
|
|
188
|
+
// Every standalone server gets an expiring process-local registry. Scaled deployments replace
|
|
189
|
+
// it with appendRedisAuthSessionManager before calling this helper.
|
|
190
|
+
appendMemoryAuthSessionManager(ctx);
|
|
84
191
|
const service = makeAuthService(alias);
|
|
85
192
|
const context = ctx;
|
|
86
193
|
context.registerService(service);
|
package/build/service.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAC1C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAEvF,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAChE,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAE1E,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAC1C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAEvF,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAChE,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAE1E,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAGrG,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AAChE,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAA;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAEvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAA;AAEtE,OAAO,EACL,8BAA8B,EAAE,oBAAoB,EAAE,gBAAgB,EACvE,MAAM,+BAA+B,CAAA;AAEtC,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAA;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAKpD,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,KAAK,GAAW,aAAa,EAAe,EAAE;IAC5E,MAAM,QAAQ,GAAG,eAAe,KAAK,EAAE,CAAA;IAEvC,MAAM,KAAK,GAAG,CAAC,OAAgB,EAAuB,EAAE,CACtD,OAAO,CAAC,QAAQ,CAAsB,UAAU,CAAC,CAAA;IAEnD,MAAM,QAAQ,GAAG,CAAC,OAAgB,EAA6B,EAAE,CAC/D,OAAO,CAAC,UAAU,CAAC,oBAAoB,CAAC;QACtC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAqB,oBAAoB,CAAC;QAC3D,CAAC,CAAC,IAAI,CAAA;IAEV,MAAM,WAAW,GAAG,KAAK,EAAE,OAAgB,EAAE,UAA8B,EAA0B,EAAE;QACrG,IAAI,UAAU,IAAI,IAAI,IAAI,UAAU,KAAK,EAAE;YAAE,OAAO,IAAI,CAAA;QACxD,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC;YAAE,OAAO,UAAU,CAAA;QAC3D,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAwB,eAAe,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;QAChG,OAAO,MAAM,EAAE,EAAE,IAAI,IAAI,CAAA;IAC3B,CAAC,CAAA;IAED,MAAM,OAAO,GAAG,KAAK,EAAE,OAAgB,EAAE,IAAU,EAAE,OAAe,EAAwB,EAAE;QAC5F,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,CAAA;QAC5D,IAAI,QAAQ,IAAI,IAAI,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,qBAAqB,CAAC;YAAE,OAAO,IAAI,CAAA;QAC1G,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAA0B,qBAAqB,CAAC,CAAA;QACjF,IAAI,OAAO,GAA2B,IAAI,CAAA;QAC1C,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAA;QACxE,CAAC;QAAC,MAAM,CAAC;YACP,yFAAyF;YACzF,4EAA4E;YAC5E,MAAM,IAAI,eAAe,CAAC,kBAAkB,CAAC,CAAA;QAC/C,CAAC;QACD,IAAI,OAAO,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,IAAI,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YAAE,OAAO,IAAI,CAAA;QACtH,OAAO;YACL,GAAG,IAAI;YACP,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM;YACrC,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,EAAE;YAC5B,GAAG,CAAC,OAAO,CAAC,WAAW,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5E,oBAAoB,EAAE,OAAO;YAC7B,SAAS,EAAE,IAAI,IAAI,EAAE;SACtB,CAAA;IACH,CAAC,CAAA;IAED,MAAM,IAAI,GAAG,KAAK,EAAE,OAAgB,EAAE,IAAU,EAAmB,EAAE;QACnE,MAAM,OAAO,GAAG,MAAM,KAAK,CAAkB,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QACxG,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;QACpH,MAAM,aAAa,GAAG,MAAM,iBAAiB,CAAO,iBAAiB,CAAC,iBAAiB,CAAC;aACrF,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,YAAY,CAAC,KAAK,CAAC,CAAA;QACxD,OAAO,GAAG,iBAAiB,CAAC,iBAAiB,CAAC,WAAW,EAAE,IAAI,aAAa,EAAE,CAAA;IAChF,CAAC,CAAA;IAED,MAAM,OAAO,GAAgB,aAAa,CAAc,KAAK,EAAE;QAC7D,KAAK,EAAE,KAAK,EAAC,GAAG,EAAC,EAAE,CAAC,gBAAgB,CAAC,GAAG,EAAE,iBAAiB,CAAC,iBAAiB,CAAC,IAAI,IAAI;QAEtF,MAAM,EAAE,KAAK,EAAK,GAAoB,EAAE,GAA2B,EAAE,EAAE;YACrE,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,CAAC,GAAG,CAAY,CAAA;YACrD,MAAM,aAAa,GAAG,gBAAgB,CAAC,GAAG,EAAE,iBAAiB,CAAC,iBAAiB,CAAC,CAAA;YAChF,IAAI,aAAa,IAAI,IAAI,EAAE,CAAC;gBAC1B,OAAO,KAAU,CAAA;YACnB,CAAC;YAED,MAAM,QAAQ,GAAG,iBAAiB,CAAO,aAAa,EAAE,YAAY,CAAC,KAAK,CAAC,CAAA;YAE3E,MAAM,OAAO,GAAG,MAAM,KAAK,CAAkB,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;YACxG,IAAI,CAAC,MAAM,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBACxC,OAAO,KAAU,CAAA;YACnB,CAAC;YAED,IAAI,IAAI,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAA;YAC7B,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAA;YACjC,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;gBACpB,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI;oBAAE,OAAO,KAAU,CAAA;gBAC7C,IAAI,QAAQ,CAAA;gBACZ,IAAI,CAAC;oBACH,QAAQ,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;gBAClD,CAAC;gBAAC,MAAM,CAAC;oBACP,0FAA0F;oBAC1F,MAAM,IAAI,eAAe,CAAC,kBAAkB,CAAC,CAAA;gBAC/C,CAAC;gBACD,IAAI,QAAQ,CAAC,KAAK,KAAK,QAAQ,IAAI,QAAQ,CAAC,KAAK,KAAK,SAAS;oBAAE,OAAO,KAAU,CAAA;gBAClF,IAAI,QAAQ,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;oBACjC,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAA;oBAChE,IAAI,SAAS,IAAI,IAAI;wBAAE,OAAO,KAAU,CAAA;oBACxC,IAAI,GAAG,SAAS,CAAA;oBAChB,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;oBAC7C,GAAG,CAAC,gBAAgB,EAAE,MAAM,CAAC,YAAY,EAAE,WAAW,CAAC,CAAA;oBACvD,GAAG,CAAC,OAAO,GAAG,EAAE,GAAG,GAAG,CAAC,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,CAAA;gBAC9D,CAAC;YACH,CAAC;YAED,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;YAEjB,OAAO,IAAS,CAAA;QAClB,CAAC;QAED,MAAM,EAAE,KAAK,EAAC,KAAK,EAAC,EAAE;YACpB,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,EAAmB,CAAA;YACpD,MAAM,CAAC,EAAE,aAAa,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YAC1C,MAAM,QAAQ,GAAG,iBAAiB,CAAO,aAAa,EAAE,YAAY,CAAC,KAAK,CAAC,CAAA;YAE3E,MAAM,OAAO,GAAG,MAAM,KAAK,CAAkB,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;YACxG,IAAI,CAAC,MAAM,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBACxC,MAAM,IAAI,kBAAkB,CAAC,QAAQ,CAAC,CAAA;YACxC,CAAC;YACD,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAA;YAC/B,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAA;YACjC,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;gBACpB,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI;oBAAE,MAAM,IAAI,kBAAkB,CAAC,SAAS,CAAC,CAAA;gBACnE,IAAI,QAAQ,CAAA;gBACZ,IAAI,CAAC;oBACH,QAAQ,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;gBAClD,CAAC;gBAAC,MAAM,CAAC;oBACP,MAAM,IAAI,eAAe,CAAC,kBAAkB,CAAC,CAAA;gBAC/C,CAAC;gBACD,IAAI,QAAQ,CAAC,KAAK,KAAK,QAAQ;oBAAE,MAAM,IAAI,kBAAkB,CAAC,SAAS,CAAC,CAAA;YAC1E,CAAC;YACD,OAAO,IAAI,CAAA;QACb,CAAC;QAED,aAAa,EAAE,KAAK,IAAI,EAAE;YACxB,OAAO,IAAI,CAAA;QACb,CAAC;QAED,YAAY,EAAE,KAAK,EAAC,KAAK,EAAC,EAAE;YAC1B,MAAM,OAAO,GAAG,aAAa,CAAkB,OAAO,CAAC,GAAc,EAAE,QAAQ,CAAC,CAAA;YAChF,MAAM,QAAQ,GAAG,iBAAiB,CAAkB,KAAK,CAAC,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC,CAAA;YAEpF,MAAM,WAAW,GAAG,MAAM,KAAK,CAAkB,OAAO,EAAE,OAAO,EAAE,YAAY,CAAC,CAAA;YAChF,IAAI,CAAC,MAAM,QAAQ,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC5C,MAAM,IAAI,YAAY,EAAE,CAAA;YAC1B,CAAC;YAED,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAA;YACtC,MAAM,GAAG,GAAG,WAAW,CAAC,SAAS,CAAA;YAEjC,6EAA6E;YAE7E,IAAI,CAAC;gBACH,MAAM,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,gBAAgB,GAAG,IAAI,EAAE,CAAC,CAAA;YAC5E,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,IAAI,YAAY,EAAE,CAAA;YAC1B,CAAC;YAED,IAAI,WAAW,CAAC,UAAU,KAAK,WAAW,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;gBACnD,MAAM,IAAI,YAAY,EAAE,CAAA;YAC1B,CAAC;YAED,yBAAyB;YACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;YAC3B,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,QAAQ,GAAG,gBAAgB,CAAC,CAAA;YACvD,MAAM,IAAI,GAAS;gBACjB,KAAK,EAAE,WAAW,CAAC,SAAS;gBAC5B,MAAM,EAAE,WAAW,CAAC,MAAM;gBAC1B,MAAM,EAAE,WAAW,CAAC,MAAM;gBAC1B,IAAI,EAAE,WAAW,CAAC,IAAI;gBACtB,IAAI,EAAE,iBAAiB,CAAC,iBAAiB;gBACzC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,OAAO;gBAC3B,SAAS,EAAE,WAAW,CAAC,SAAS;gBAChC,UAAU,EAAE,WAAW,CAAC,UAAU;gBAClC,MAAM,EAAE,IAAI;gBACZ,SAAS,EAAE,IAAI,IAAI,CAAC,QAAQ,CAAC;gBAC7B,SAAS;gBACT,SAAS,EAAE,IAAI,EAAE;gBACjB,oBAAoB,EAAE,CAAC;aACxB,CAAA;YACD,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAA;YACjC,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;gBACpB,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,CAAA;gBAC5D,IAAI,QAAQ,IAAI,IAAI,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI;oBAAE,MAAM,IAAI,YAAY,CAAC,SAAS,CAAC,CAAA;gBACjF,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC;oBACtC,EAAE,EAAE,IAAI,CAAC,SAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS;oBACxE,QAAQ,EAAE,SAAS,EAAE,SAAS,CAAC,OAAO,EAAE;iBACzC,CAAC,CAAA;gBACF,IAAI,QAAQ,CAAC,KAAK,KAAK,QAAQ;oBAAE,MAAM,IAAI,YAAY,CAAC,SAAS,CAAC,CAAA;gBAClE,IAAI,CAAC,oBAAoB,GAAG,QAAQ,CAAC,OAAO,CAAA;YAC9C,CAAC;YAED,OAAO,EAAE,KAAK,EAAE,MAAM,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAA;QAC7C,CAAC;KACF,CAAC,CAAA;IAEF,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,GAAM,EAAE,KAAK,GAAW,aAAa,EACd,EAAE;IAEzB,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,UAAU,CAAC,EAAE,CAAC;QACjC,GAAG,CAAC,gBAAgB,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC,CAAA;IACxD,CAAC;IAED,8FAA8F;IAC9F,oEAAoE;IACpE,8BAA8B,CAAC,GAAG,CAAC,CAAA;IAEnC,MAAM,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,CAAA;IACtC,MAAM,OAAO,GAAG,GAA4B,CAAA;IAE5C,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,CAAA;IAChC,OAAO,CAAC,IAAI,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAE/C,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmeans/server-auth",
|
|
3
|
-
"version": "0.1.18-rc.
|
|
3
|
+
"version": "0.1.18-rc.40",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -37,29 +37,31 @@
|
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@noble/hashes": "^1.5.0",
|
|
40
|
-
"@owlmeans/api": "^0.1.18-rc.
|
|
41
|
-
"@owlmeans/api-config-server": "^0.1.18-rc.
|
|
42
|
-
"@owlmeans/auth": "^0.1.18-rc.
|
|
43
|
-
"@owlmeans/auth-common": "^0.1.18-rc.
|
|
44
|
-
"@owlmeans/basic-envelope": "^0.1.18-rc.
|
|
45
|
-
"@owlmeans/basic-ids": "^0.1.18-rc.
|
|
46
|
-
"@owlmeans/basic-keys": "^0.1.18-rc.
|
|
47
|
-
"@owlmeans/client-config": "^0.1.18-rc.
|
|
48
|
-
"@owlmeans/client-entrypoint": "^0.1.18-rc.
|
|
49
|
-
"@owlmeans/config": "^0.1.18-rc.
|
|
50
|
-
"@owlmeans/context": "^0.1.18-rc.
|
|
51
|
-
"@owlmeans/kluster": "^0.1.18-rc.
|
|
52
|
-
"@owlmeans/entrypoint": "^0.1.18-rc.
|
|
53
|
-
"@owlmeans/redis-resource": "^0.1.18-rc.
|
|
54
|
-
"@owlmeans/resource": "^0.1.18-rc.
|
|
55
|
-
"@owlmeans/route": "^0.1.18-rc.
|
|
56
|
-
"@owlmeans/server-api": "^0.1.18-rc.
|
|
57
|
-
"@owlmeans/server-
|
|
58
|
-
"@owlmeans/server-
|
|
59
|
-
"@owlmeans/server-
|
|
60
|
-
"@owlmeans/server-
|
|
61
|
-
"@owlmeans/
|
|
62
|
-
"@owlmeans/
|
|
40
|
+
"@owlmeans/api": "^0.1.18-rc.33",
|
|
41
|
+
"@owlmeans/api-config-server": "^0.1.18-rc.37",
|
|
42
|
+
"@owlmeans/auth": "^0.1.18-rc.31",
|
|
43
|
+
"@owlmeans/auth-common": "^0.1.18-rc.33",
|
|
44
|
+
"@owlmeans/basic-envelope": "^0.1.18-rc.32",
|
|
45
|
+
"@owlmeans/basic-ids": "^0.1.18-rc.30",
|
|
46
|
+
"@owlmeans/basic-keys": "^0.1.18-rc.34",
|
|
47
|
+
"@owlmeans/client-config": "^0.1.18-rc.33",
|
|
48
|
+
"@owlmeans/client-entrypoint": "^0.1.18-rc.33",
|
|
49
|
+
"@owlmeans/config": "^0.1.18-rc.33",
|
|
50
|
+
"@owlmeans/context": "^0.1.18-rc.29",
|
|
51
|
+
"@owlmeans/kluster": "^0.1.18-rc.32",
|
|
52
|
+
"@owlmeans/entrypoint": "^0.1.18-rc.32",
|
|
53
|
+
"@owlmeans/redis-resource": "^0.1.18-rc.32",
|
|
54
|
+
"@owlmeans/resource": "^0.1.18-rc.31",
|
|
55
|
+
"@owlmeans/route": "^0.1.18-rc.30",
|
|
56
|
+
"@owlmeans/server-api": "^0.1.18-rc.37",
|
|
57
|
+
"@owlmeans/server-auth-identity": "^0.1.18-rc.33",
|
|
58
|
+
"@owlmeans/server-auth-session": "^0.1.18-rc.4",
|
|
59
|
+
"@owlmeans/server-context": "^0.1.18-rc.32",
|
|
60
|
+
"@owlmeans/server-entrypoint": "^0.1.18-rc.31",
|
|
61
|
+
"@owlmeans/server-route": "^0.1.18-rc.29",
|
|
62
|
+
"@owlmeans/server-socket": "^0.1.18-rc.40",
|
|
63
|
+
"@owlmeans/socket": "^0.1.18-rc.29",
|
|
64
|
+
"@owlmeans/static-resource": "^0.1.18-rc.30",
|
|
63
65
|
"@scure/base": "^2.3.0"
|
|
64
66
|
},
|
|
65
67
|
"peerDependencies": {
|
|
@@ -67,8 +69,8 @@
|
|
|
67
69
|
},
|
|
68
70
|
"devDependencies": {
|
|
69
71
|
"@owlmeans/dep-config": "workspace:*",
|
|
70
|
-
"@owlmeans/test-auth": "^0.1.18-rc.
|
|
71
|
-
"@types/bun": "^1.
|
|
72
|
+
"@owlmeans/test-auth": "^0.1.18-rc.32",
|
|
73
|
+
"@types/bun": "^1.4.0",
|
|
72
74
|
"@types/node": "^26.1.0",
|
|
73
75
|
"nodemon": "^3.1.14",
|
|
74
76
|
"typescript": "^7.0.2"
|
package/src/actions/service.ts
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { handlers } from '@owlmeans/server-api'
|
|
2
|
+
import type { EntrypointProtocol } from '@owlmeans/entrypoint'
|
|
2
3
|
import type { AuthToken } from '@owlmeans/auth'
|
|
3
|
-
import { handleBody } from '@owlmeans/server-api'
|
|
4
4
|
import { AuthServiceAppend } from '../types.js'
|
|
5
5
|
import type { ServerConfig, ServerContext } from '@owlmeans/server-context'
|
|
6
6
|
import { assertContext } from '@owlmeans/context'
|
|
7
7
|
|
|
8
8
|
type Config = ServerConfig
|
|
9
9
|
type Context = ServerContext<Config> & AuthServiceAppend
|
|
10
|
+
const api = handlers<Context>()
|
|
10
11
|
|
|
11
|
-
export const authenticate:
|
|
12
|
-
async (
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
)
|
|
12
|
+
export const authenticate = (protocol: EntrypointProtocol<{ body: AuthToken }, AuthToken>) =>
|
|
13
|
+
api.request(protocol, async (request, context) => {
|
|
14
|
+
const ctx = assertContext(context, 'authenticate') as Context
|
|
15
|
+
|
|
16
|
+
return await ctx.auth().authenticate(request.body)
|
|
17
|
+
})
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
|
|
2
|
+
import { bind } from '@owlmeans/server-entrypoint'
|
|
3
|
+
import type { ServerProtocolEntrypoint } from '@owlmeans/server-entrypoint'
|
|
4
|
+
import { authProtocols } from '@owlmeans/auth-common'
|
|
5
|
+
import type { EntrypointProtocolDeclaration } from '@owlmeans/entrypoint'
|
|
6
|
+
import { authenticate } from './actions/service.js'
|
|
7
|
+
|
|
8
|
+
/** Server entrypoints required by the generic authentication service. */
|
|
9
|
+
export const entrypoints: ServerProtocolEntrypoint<EntrypointProtocolDeclaration>[] = [
|
|
10
|
+
bind(authProtocols.dispatcher),
|
|
11
|
+
bind(authProtocols.dispatcherAuthenticate, authenticate(authProtocols.dispatcherAuthenticate)),
|
|
12
|
+
]
|
package/src/index.ts
CHANGED
package/src/manager/README.md
CHANGED
|
@@ -27,18 +27,18 @@ A specialized guard service that enables authentication token relay between micr
|
|
|
27
27
|
- **Wallet DID Authentication**: Decentralized identity authentication support
|
|
28
28
|
- **Challenge Validation**: Anti-replay protection using challenge-response mechanisms
|
|
29
29
|
|
|
30
|
-
###
|
|
31
|
-
The manager is built on the OwlMeans
|
|
30
|
+
### Entrypoint-Based Architecture
|
|
31
|
+
The manager is built on the OwlMeans entrypoint system, providing:
|
|
32
32
|
- **Route Management**: Standardized API endpoints for authentication operations
|
|
33
|
-
- **Handler Registration**:
|
|
34
|
-
- **Guard Integration**: Automatic security enforcement at the
|
|
33
|
+
- **Handler Registration**: Protocol-backed request handlers for different authentication flows
|
|
34
|
+
- **Guard Integration**: Automatic security enforcement at the entrypoint level
|
|
35
35
|
|
|
36
36
|
## Installation
|
|
37
37
|
|
|
38
38
|
This manager app is part of the `@owlmeans/server-auth` package:
|
|
39
39
|
|
|
40
40
|
```bash
|
|
41
|
-
npm install @owlmeans/server-auth
|
|
41
|
+
npm install @owlmeans/server-auth@^0.1.18-rc.39
|
|
42
42
|
```
|
|
43
43
|
|
|
44
44
|
## API Reference
|
|
@@ -317,20 +317,16 @@ await authModel.rely(connection, authToken.auth)
|
|
|
317
317
|
|
|
318
318
|
### API Integration
|
|
319
319
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
// The manager automatically registers these API endpoints:
|
|
320
|
+
`main(context)` registers the manager's immutable `entrypoints` and starts the API server. For a
|
|
321
|
+
custom bootstrap, register the exported collection yourself; the manager's protocols are then
|
|
322
|
+
addressed through the same `context.entrypoint(protocol)` lookup as application endpoints.
|
|
324
323
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
// WebSocket /api/auth/rely - Authentication relay
|
|
324
|
+
```typescript
|
|
325
|
+
import { entrypoints, makeContext } from '@owlmeans/server-auth/manager'
|
|
328
326
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
console.log(`Method: ${module.route.method}`)
|
|
333
|
-
})
|
|
327
|
+
const context = makeContext(config)
|
|
328
|
+
context.registerEntrypoints(entrypoints)
|
|
329
|
+
await context.configure().init()
|
|
334
330
|
```
|
|
335
331
|
|
|
336
332
|
## API Endpoints
|
|
@@ -504,4 +500,4 @@ This manager app depends on:
|
|
|
504
500
|
- [`@owlmeans/server-auth`](../../../README.md) - Parent server authentication package
|
|
505
501
|
- [`@owlmeans/auth`](../../../auth/README.md) - Core authentication library
|
|
506
502
|
- [`@owlmeans/client-auth`](../../../client-auth/README.md) - Client-side authentication
|
|
507
|
-
- [`@owlmeans/context`](../../../context/README.md) - Context management system
|
|
503
|
+
- [`@owlmeans/context`](../../../context/README.md) - Context management system
|
|
@@ -1,23 +1,25 @@
|
|
|
1
|
-
import type { AllowanceRequest, AuthCredentials } from '@owlmeans/auth'
|
|
2
|
-
import {
|
|
1
|
+
import type { AllowanceRequest, AllowanceResponse, AuthCredentials, AuthToken } from '@owlmeans/auth'
|
|
2
|
+
import type { EntrypointProtocol } from '@owlmeans/entrypoint'
|
|
3
|
+
import { handlers } from '@owlmeans/server-api'
|
|
3
4
|
import { makeAuthModel } from '../model.js'
|
|
4
|
-
import type { RefedEntrypointHandler } from '@owlmeans/server-entrypoint'
|
|
5
5
|
import type { AppContext, AppConfig } from '../types.js'
|
|
6
|
-
import {
|
|
6
|
+
import { connection } from '@owlmeans/server-socket'
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
const api = handlers<AppContext<AppConfig>>()
|
|
9
|
+
|
|
10
|
+
export const authenticationInit = (protocol: EntrypointProtocol<{ body: AllowanceRequest }, AllowanceResponse>) =>
|
|
11
|
+
api.body(protocol, async (body, context) =>
|
|
12
|
+
await makeAuthModel(context).init(body)
|
|
11
13
|
)
|
|
12
14
|
|
|
13
|
-
export const authenticate:
|
|
14
|
-
async (
|
|
15
|
-
|
|
15
|
+
export const authenticate = (protocol: EntrypointProtocol<{ body: AuthCredentials }, AuthToken>) =>
|
|
16
|
+
api.body(protocol, async (body, context) =>
|
|
17
|
+
await makeAuthModel(context).authenticate(body)
|
|
16
18
|
)
|
|
17
19
|
|
|
18
|
-
export const rely:
|
|
20
|
+
export const rely = (protocol: EntrypointProtocol<{ query: Partial<AuthToken> }, undefined>) => connection(protocol,
|
|
19
21
|
// @TODO Request will contain information is there requrest
|
|
20
22
|
// privileged or not (privileged request implies auth provider)
|
|
21
|
-
async (conn,
|
|
22
|
-
await makeAuthModel(
|
|
23
|
+
async (conn, context, request) =>
|
|
24
|
+
await makeAuthModel(context as AppContext<AppConfig>).rely(conn, request.auth)
|
|
23
25
|
)
|
package/src/manager/context.ts
CHANGED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
|
|
2
|
+
import { MOD_RECAPTCHA } from '@owlmeans/auth'
|
|
3
|
+
import { authProtocols } from '@owlmeans/auth-common'
|
|
4
|
+
import { entrypoints as apiConfigBindings } from '@owlmeans/api-config-server'
|
|
5
|
+
import { bind } from '@owlmeans/server-entrypoint'
|
|
6
|
+
import { decorateEntrypoint, openProtocol } from '@owlmeans/entrypoint'
|
|
7
|
+
import * as actions from './actions/index.js'
|
|
8
|
+
import { backend, route, RouteMethod } from '@owlmeans/route'
|
|
9
|
+
import { DEFAULT_RELY } from './consts.js'
|
|
10
|
+
|
|
11
|
+
const relyProtocol = decorateEntrypoint(authProtocols.rely, { guards: DEFAULT_RELY })
|
|
12
|
+
const reCaptchaProtocol = openProtocol(route(MOD_RECAPTCHA, '/api/siteverify', backend({
|
|
13
|
+
host: 'https://www.google.com',
|
|
14
|
+
base: 'recaptcha',
|
|
15
|
+
secure: true,
|
|
16
|
+
}, RouteMethod.POST)))
|
|
17
|
+
|
|
18
|
+
/** Server entrypoints for the full authentication manager. */
|
|
19
|
+
export const entrypoints = [
|
|
20
|
+
bind(authProtocols.authen, undefined, { intermediate: true }),
|
|
21
|
+
bind(authProtocols.init, actions.authenticationInit(authProtocols.init)),
|
|
22
|
+
bind(authProtocols.authenticate, actions.authenticate(authProtocols.authenticate)),
|
|
23
|
+
bind(relyProtocol, actions.rely(relyProtocol)),
|
|
24
|
+
...apiConfigBindings,
|
|
25
|
+
bind(reCaptchaProtocol),
|
|
26
|
+
]
|
package/src/manager/exports.ts
CHANGED
|
@@ -5,8 +5,7 @@ export { addWebService } from '@owlmeans/client-config'
|
|
|
5
5
|
export { service, TRUSTED } from '@owlmeans/config'
|
|
6
6
|
export { AppType, assertContext } from '@owlmeans/context'
|
|
7
7
|
export { klusterize } from '@owlmeans/kluster'
|
|
8
|
-
export {
|
|
9
|
-
export { elevate as celevate, stab } from '@owlmeans/client-entrypoint'
|
|
8
|
+
export { stab } from '@owlmeans/client-entrypoint'
|
|
10
9
|
export type { RefedEntrypointHandler } from '@owlmeans/server-entrypoint'
|
|
11
10
|
export { handleIntermediate, handleBody, handleRequest, handleParams } from '@owlmeans/server-api'
|
|
12
11
|
export type { AbstractRequest, AbstractResponse } from '@owlmeans/entrypoint'
|