@jskit-ai/auth-core 0.1.157 → 0.1.159

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/package.json CHANGED
@@ -1,21 +1,23 @@
1
1
  {
2
2
  "name": "@jskit-ai/auth-core",
3
- "version": "0.1.157",
3
+ "version": "0.1.159",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "test": "node --test"
7
7
  },
8
8
  "exports": {
9
- "./server/providers/AccessCoreServiceProvider": "./src/server/providers/AccessCoreServiceProvider.js",
10
- "./server/providers/FastifyAuthPolicyServiceProvider": "./src/server/providers/FastifyAuthPolicyServiceProvider.js",
11
- "./server/providers/AuthActionsServiceProvider": "./src/server/providers/AuthActionsServiceProvider.js",
9
+ "./server/providers/AuthAccessProvider": "./src/server/providers/AuthAccessProvider.js",
10
+ "./server/providers/AuthExtensionsProvider": "./src/server/providers/AuthExtensionsProvider.js",
11
+ "./server/providers/AuthFeature": "./src/server/providers/AuthFeature.js",
12
+ "./server/providers/AuthPolicyProvider": "./src/server/providers/AuthPolicyProvider.js",
12
13
  "./server/actions/auth.contributor": "./src/server/actions/auth.contributor.js",
13
- "./server/services/authSessionEventsService": "./src/server/services/authSessionEventsService.js",
14
+ "./server/authExtensions": "./src/server/authExtensions.js",
14
15
  "./server/authPolicyContextResolverRegistry": "./src/server/authPolicyContextResolverRegistry.js",
15
16
  "./server/authServiceDecoratorRegistry": "./src/server/authServiceDecoratorRegistry.js",
16
17
  "./server/authActor": "./src/server/authActor.js",
17
18
  "./server/booleanFlag": "./src/server/booleanFlag.js",
18
19
  "./server/devAuth": "./src/server/devAuth.js",
20
+ "./server/deferredAuthService": "./src/server/deferredAuthService.js",
19
21
  "./server/unsupportedOperation": "./src/server/unsupportedOperation.js",
20
22
  "./server/utils": "./src/server/utils.js",
21
23
  "./server/validators": "./src/server/validators.js",
@@ -59,7 +61,7 @@
59
61
  "@fastify/cookie": "^11.0.2",
60
62
  "@fastify/csrf-protection": "^7.1.0",
61
63
  "@fastify/rate-limit": "^10.3.0",
62
- "@jskit-ai/kernel": "0.1.159",
64
+ "@jskit-ai/kernel": "0.1.161",
63
65
  "json-rest-schema": "^1.0.17"
64
66
  },
65
67
  "jskit": {
@@ -67,25 +69,35 @@
67
69
  "capabilities": {
68
70
  "provides": [
69
71
  "auth.access",
72
+ "auth.extensions",
70
73
  "auth.policy"
71
74
  ],
72
- "requires": []
75
+ "requires": [
76
+ "runtime.actions",
77
+ "runtime.env",
78
+ "runtime.fastify",
79
+ "runtime.http"
80
+ ]
73
81
  },
74
82
  "runtime": {
75
83
  "server": {
76
- "providerEntrypoint": "src/server/providers/AccessCoreServiceProvider.js",
84
+ "providerEntrypoint": "src/server/providers/AuthAccessProvider.js",
77
85
  "providers": [
78
86
  {
79
- "entrypoint": "src/server/providers/AccessCoreServiceProvider.js",
80
- "export": "AccessCoreServiceProvider"
87
+ "entrypoint": "src/server/providers/AuthAccessProvider.js",
88
+ "export": "AuthAccessProvider"
81
89
  },
82
90
  {
83
- "entrypoint": "src/server/providers/AuthActionsServiceProvider.js",
84
- "export": "AuthActionsServiceProvider"
91
+ "entrypoint": "src/server/providers/AuthExtensionsProvider.js",
92
+ "export": "AuthExtensionsProvider"
85
93
  },
86
94
  {
87
- "entrypoint": "src/server/providers/FastifyAuthPolicyServiceProvider.js",
88
- "export": "FastifyAuthPolicyServiceProvider"
95
+ "entrypoint": "src/server/providers/AuthFeature.js",
96
+ "export": "AuthFeature"
97
+ },
98
+ {
99
+ "entrypoint": "src/server/providers/AuthPolicyProvider.js",
100
+ "export": "AuthPolicyProvider"
89
101
  }
90
102
  ]
91
103
  },
@@ -94,10 +106,6 @@
94
106
  {
95
107
  "entrypoint": "src/client/providers/AccessCoreClientProvider.js",
96
108
  "export": "AccessCoreClientProvider"
97
- },
98
- {
99
- "entrypoint": "src/client/providers/FastifyAuthPolicyClientProvider.js",
100
- "export": "FastifyAuthPolicyClientProvider"
101
109
  }
102
110
  ]
103
111
  }
@@ -107,7 +115,7 @@
107
115
  "surfaces": [
108
116
  {
109
117
  "subpath": "./client",
110
- "summary": "Exports client auth access APIs plus AccessCoreClientProvider/FastifyAuthPolicyClientProvider."
118
+ "summary": "Exports the client auth access API and its capability provider."
111
119
  },
112
120
  {
113
121
  "subpath": "./server",
@@ -118,33 +126,10 @@
118
126
  "summary": "Exports shared auth client helpers (createApi and runAuthSignOutFlow), with structured subpaths at ./shared/authApi and ./shared/signOutFlow."
119
127
  }
120
128
  ],
121
- "containerTokens": {
122
- "server": [
123
- "auth.access",
124
- "auth.session.events.service"
125
- ],
126
- "client": [
127
- "auth.access.client"
128
- ]
129
- }
129
+ "clientCapabilities": [
130
+ "auth.access.client"
131
+ ]
130
132
  }
131
- },
132
- "mutations": {
133
- "dependencies": {
134
- "runtime": {
135
- "@jskit-ai/kernel": "0.1.159",
136
- "@fastify/cookie": "^11.0.2",
137
- "@fastify/csrf-protection": "^7.1.0",
138
- "@fastify/rate-limit": "^10.3.0"
139
- },
140
- "dev": {}
141
- },
142
- "packageJson": {
143
- "scripts": {}
144
- },
145
- "procfile": {},
146
- "files": [],
147
- "text": []
148
133
  }
149
134
  }
150
135
  }
@@ -1,2 +1 @@
1
1
  export { AccessCoreClientProvider } from "./providers/AccessCoreClientProvider.js";
2
- export { FastifyAuthPolicyClientProvider } from "./providers/FastifyAuthPolicyClientProvider.js";
@@ -1,3 +1,4 @@
1
+ import { defineProvider } from "@jskit-ai/kernel/shared/capabilities";
1
2
  import { createApi as createAuthApi } from "../authApi.js";
2
3
  import { runAuthSignOutFlow } from "../signOutFlow.js";
3
4
 
@@ -6,18 +7,16 @@ const CLIENT_API = Object.freeze({
6
7
  runAuthSignOutFlow
7
8
  });
8
9
 
9
- class AccessCoreClientProvider {
10
- static id = "auth.access.client";
11
-
12
- register(app) {
13
- if (!app || typeof app.singleton !== "function") {
14
- throw new Error("AccessCoreClientProvider requires application singleton().");
15
- }
16
-
17
- app.singleton("auth.access.client", () => CLIENT_API);
10
+ const AccessCoreClientProvider = defineProvider({
11
+ id: "auth.access.client",
12
+ provides: {
13
+ auth: "auth.access.client"
14
+ },
15
+ setup() {
16
+ return {
17
+ auth: CLIENT_API
18
+ };
18
19
  }
19
-
20
- boot() {}
21
- }
20
+ });
22
21
 
23
22
  export { AccessCoreClientProvider };
@@ -45,7 +45,7 @@ function requireRequestContext(context, actionId) {
45
45
  throw new Error(`${actionId} requires request context.`);
46
46
  }
47
47
 
48
- const baseAuthActions = Object.freeze([
48
+ const authActionSpecifications = Object.freeze([
49
49
  {
50
50
  id: "auth.register",
51
51
  version: 1,
@@ -58,8 +58,8 @@ const baseAuthActions = Object.freeze([
58
58
  actionName: "auth.register"
59
59
  },
60
60
  observability: {},
61
- async execute(input, _context, deps) {
62
- return deps.authService.register(input);
61
+ async run(authService, input) {
62
+ return authService.register(input);
63
63
  }
64
64
  },
65
65
  {
@@ -74,8 +74,8 @@ const baseAuthActions = Object.freeze([
74
74
  actionName: "auth.register.confirmation.resend"
75
75
  },
76
76
  observability: {},
77
- async execute(input, _context, deps) {
78
- return deps.authService.resendRegisterConfirmation(input);
77
+ async run(authService, input) {
78
+ return authService.resendRegisterConfirmation(input);
79
79
  }
80
80
  },
81
81
  {
@@ -90,8 +90,8 @@ const baseAuthActions = Object.freeze([
90
90
  actionName: "auth.login.password"
91
91
  },
92
92
  observability: {},
93
- async execute(input, _context, deps) {
94
- return deps.authService.login(input);
93
+ async run(authService, input) {
94
+ return authService.login(input);
95
95
  }
96
96
  },
97
97
  {
@@ -106,8 +106,8 @@ const baseAuthActions = Object.freeze([
106
106
  actionName: "auth.login.otp.request"
107
107
  },
108
108
  observability: {},
109
- async execute(input, _context, deps) {
110
- return deps.authService.requestOtpLogin(input);
109
+ async run(authService, input) {
110
+ return authService.requestOtpLogin(input);
111
111
  }
112
112
  },
113
113
  {
@@ -122,8 +122,8 @@ const baseAuthActions = Object.freeze([
122
122
  actionName: "auth.login.otp.verify"
123
123
  },
124
124
  observability: {},
125
- async execute(input, _context, deps) {
126
- return deps.authService.verifyOtpLogin(input);
125
+ async run(authService, input) {
126
+ return authService.verifyOtpLogin(input);
127
127
  }
128
128
  },
129
129
  {
@@ -138,8 +138,8 @@ const baseAuthActions = Object.freeze([
138
138
  actionName: "auth.login.oauth.start"
139
139
  },
140
140
  observability: {},
141
- async execute(input, _context, deps) {
142
- return deps.authService.oauthStart(input);
141
+ async run(authService, input) {
142
+ return authService.oauthStart(input);
143
143
  }
144
144
  },
145
145
  {
@@ -154,8 +154,8 @@ const baseAuthActions = Object.freeze([
154
154
  actionName: "auth.login.oauth.complete"
155
155
  },
156
156
  observability: {},
157
- async execute(input, _context, deps) {
158
- return deps.authService.oauthComplete(input);
157
+ async run(authService, input) {
158
+ return authService.oauthComplete(input);
159
159
  }
160
160
  },
161
161
  {
@@ -170,8 +170,8 @@ const baseAuthActions = Object.freeze([
170
170
  actionName: "auth.dev.loginAs"
171
171
  },
172
172
  observability: {},
173
- async execute(input, context, deps) {
174
- return deps.authService.devLoginAs(
173
+ async run(authService, input, context) {
174
+ return authService.devLoginAs(
175
175
  requireRequestContext(context, "auth.dev.loginAs"),
176
176
  input
177
177
  );
@@ -189,8 +189,8 @@ const baseAuthActions = Object.freeze([
189
189
  actionName: "auth.password.reset.request"
190
190
  },
191
191
  observability: {},
192
- async execute(input, _context, deps) {
193
- return deps.authService.requestPasswordReset(input);
192
+ async run(authService, input) {
193
+ return authService.requestPasswordReset(input);
194
194
  }
195
195
  },
196
196
  {
@@ -205,8 +205,8 @@ const baseAuthActions = Object.freeze([
205
205
  actionName: "auth.password.recovery.complete"
206
206
  },
207
207
  observability: {},
208
- async execute(input, _context, deps) {
209
- return deps.authService.completePasswordRecovery(input);
208
+ async run(authService, input) {
209
+ return authService.completePasswordRecovery(input);
210
210
  }
211
211
  },
212
212
  {
@@ -221,8 +221,8 @@ const baseAuthActions = Object.freeze([
221
221
  actionName: "auth.password.reset"
222
222
  },
223
223
  observability: {},
224
- async execute(input, context, deps) {
225
- return deps.authService.resetPassword(requireRequestContext(context, "auth.password.reset"), input);
224
+ async run(authService, input, context) {
225
+ return authService.resetPassword(requireRequestContext(context, "auth.password.reset"), input);
226
226
  }
227
227
  },
228
228
  {
@@ -238,19 +238,13 @@ const baseAuthActions = Object.freeze([
238
238
  actionName: "auth.logout"
239
239
  },
240
240
  observability: {},
241
- async execute(_input, context, deps) {
241
+ async run(authService, _input, context) {
242
242
  let logoutResult = {
243
243
  ok: true,
244
244
  clearSession: true
245
245
  };
246
- if (deps.authService && typeof deps.authService.logout === "function") {
247
- logoutResult = await deps.authService.logout(requireRequestContext(context, "auth.logout"));
248
- }
249
-
250
- if (deps.authSessionEventsService && typeof deps.authSessionEventsService.notifySessionChanged === "function") {
251
- await deps.authSessionEventsService.notifySessionChanged({
252
- context
253
- });
246
+ if (typeof authService.logout === "function") {
247
+ logoutResult = await authService.logout(requireRequestContext(context, "auth.logout"));
254
248
  }
255
249
  return {
256
250
  ok: logoutResult?.ok !== false,
@@ -270,14 +264,23 @@ const baseAuthActions = Object.freeze([
270
264
  actionName: "auth.session.read"
271
265
  },
272
266
  observability: {},
273
- async execute(_input, context, deps) {
274
- return deps.authService.authenticateRequest(requireRequestContext(context, "auth.session.read"));
267
+ async run(authService, _input, context) {
268
+ return authService.authenticateRequest(requireRequestContext(context, "auth.session.read"));
275
269
  }
276
270
  }
277
271
  ]);
278
272
 
279
- function buildAuthActions() {
280
- return baseAuthActions;
273
+ function buildAuthActions({ authService } = {}) {
274
+ if (!authService || typeof authService !== "object") {
275
+ throw new TypeError("buildAuthActions requires authService.");
276
+ }
277
+ return Object.freeze(authActionSpecifications.map(({ run, surfacesFrom: _surfaceSource, ...definition }) => Object.freeze({
278
+ ...definition,
279
+ surfaces: ["*"],
280
+ execute(input, context) {
281
+ return run(authService, input, context);
282
+ }
283
+ })));
281
284
  }
282
285
 
283
- export { baseAuthActions, buildAuthActions, requireRequestContext };
286
+ export { authActionSpecifications, buildAuthActions, requireRequestContext };
@@ -0,0 +1,155 @@
1
+ import { normalizePermissionList } from "@jskit-ai/kernel/shared/support/permissions";
2
+
3
+ function normalizeOrderedExtension(value, { idField, method, label } = {}) {
4
+ if (!value || typeof value !== "object" || Array.isArray(value) || typeof value[method] !== "function") {
5
+ throw new TypeError(`${label} requires ${method}().`);
6
+ }
7
+ const id = String(value[idField] || "").trim();
8
+ if (!id) {
9
+ throw new TypeError(`${label} requires ${idField}.`);
10
+ }
11
+ return Object.freeze({
12
+ ...value,
13
+ [idField]: id,
14
+ order: Number.isFinite(value.order) ? Number(value.order) : 0,
15
+ [method]: value[method]
16
+ });
17
+ }
18
+
19
+ function ordered(values) {
20
+ return values
21
+ .map((value, index) => ({ value, index }))
22
+ .sort((left, right) => left.value.order - right.value.order || left.index - right.index)
23
+ .map(({ value }) => value);
24
+ }
25
+
26
+ function mergePolicyContexts(contexts = []) {
27
+ const merged = {};
28
+ const permissions = new Set();
29
+ for (const context of contexts) {
30
+ if (!context || typeof context !== "object" || Array.isArray(context)) continue;
31
+ for (const [key, value] of Object.entries(context)) {
32
+ if (key === "permissions") {
33
+ for (const permission of normalizePermissionList(value)) permissions.add(permission);
34
+ } else if (value !== undefined) {
35
+ merged[key] = value;
36
+ }
37
+ }
38
+ }
39
+ if (permissions.size > 0) merged.permissions = Object.freeze([...permissions]);
40
+ return Object.keys(merged).length > 0 ? Object.freeze(merged) : null;
41
+ }
42
+
43
+ function createAuthExtensions() {
44
+ const serviceDecorators = [];
45
+ const policyContextResolvers = [];
46
+ const profileProjectors = [];
47
+ const invitationContextResolvers = [];
48
+ const ids = new Set();
49
+ let sealed = false;
50
+
51
+ function register(collection, extension, options) {
52
+ if (sealed) throw new Error("Auth extension registration is closed after authentication starts.");
53
+ const normalized = normalizeOrderedExtension(extension, options);
54
+ const qualifiedId = `${options.label}:${normalized[options.idField]}`;
55
+ if (ids.has(qualifiedId)) throw new Error(`${options.label} "${normalized[options.idField]}" is duplicated.`);
56
+ ids.add(qualifiedId);
57
+ collection.push(normalized);
58
+ return api;
59
+ }
60
+
61
+ function registerServiceDecorator(extension) {
62
+ return register(serviceDecorators, extension, {
63
+ idField: "decoratorId",
64
+ method: "decorateAuthService",
65
+ label: "Auth service decorator"
66
+ });
67
+ }
68
+
69
+ function registerPolicyContextResolver(extension) {
70
+ return register(policyContextResolvers, extension, {
71
+ idField: "resolverId",
72
+ method: "resolveAuthPolicyContext",
73
+ label: "Auth policy context resolver"
74
+ });
75
+ }
76
+
77
+ function registerProfileProjector(extension) {
78
+ return register(profileProjectors, extension, {
79
+ idField: "projectorId",
80
+ method: "syncIdentityProfile",
81
+ label: "Auth profile projector"
82
+ });
83
+ }
84
+
85
+ function registerInvitationContextResolver(extension) {
86
+ return register(invitationContextResolvers, extension, {
87
+ idField: "resolverId",
88
+ method: "resolveInvitationContext",
89
+ label: "Auth invitation context resolver"
90
+ });
91
+ }
92
+
93
+ function resolveSingle(collection, label) {
94
+ sealed = true;
95
+ const entries = ordered(collection);
96
+ if (entries.length > 1) {
97
+ throw new Error(`${label} is ambiguous: ${entries.map((entry) => entry.projectorId || entry.resolverId).join(", ")}.`);
98
+ }
99
+ return entries[0] || null;
100
+ }
101
+
102
+ function resolveProfileProjector() {
103
+ return resolveSingle(profileProjectors, "Auth profile projector");
104
+ }
105
+
106
+ function resolveInvitationContextResolver() {
107
+ return resolveSingle(invitationContextResolvers, "Auth invitation context resolver");
108
+ }
109
+
110
+ function decorateService(authService) {
111
+ sealed = true;
112
+ let decorated = authService;
113
+ for (const decorator of ordered(serviceDecorators)) {
114
+ decorated = decorator.decorateAuthService(decorated);
115
+ if (!decorated || typeof decorated !== "object") {
116
+ throw new Error(`Auth service decorator "${decorator.decoratorId}" must return an auth service object.`);
117
+ }
118
+ }
119
+ return decorated;
120
+ }
121
+
122
+ async function resolvePolicyContext(input = {}) {
123
+ sealed = true;
124
+ const contexts = [];
125
+ for (const resolver of ordered(policyContextResolvers)) {
126
+ contexts.push(await resolver.resolveAuthPolicyContext(input));
127
+ }
128
+ return mergePolicyContexts(contexts);
129
+ }
130
+
131
+ function diagnostics() {
132
+ return Object.freeze({
133
+ sealed,
134
+ serviceDecoratorIds: Object.freeze(ordered(serviceDecorators).map((entry) => entry.decoratorId)),
135
+ policyContextResolverIds: Object.freeze(ordered(policyContextResolvers).map((entry) => entry.resolverId)),
136
+ profileProjectorIds: Object.freeze(ordered(profileProjectors).map((entry) => entry.projectorId)),
137
+ invitationContextResolverIds: Object.freeze(ordered(invitationContextResolvers).map((entry) => entry.resolverId))
138
+ });
139
+ }
140
+
141
+ const api = Object.freeze({
142
+ registerServiceDecorator,
143
+ registerPolicyContextResolver,
144
+ registerProfileProjector,
145
+ registerInvitationContextResolver,
146
+ decorateService,
147
+ resolvePolicyContext,
148
+ resolveProfileProjector,
149
+ resolveInvitationContextResolver,
150
+ diagnostics
151
+ });
152
+ return api;
153
+ }
154
+
155
+ export { createAuthExtensions, mergePolicyContexts };
@@ -1,130 +1,19 @@
1
- import { normalizePermissionList } from "@jskit-ai/kernel/shared/support/permissions";
2
- import { registerTaggedSingleton, resolveTaggedEntries } from "@jskit-ai/kernel/server/registries";
1
+ import { mergePolicyContexts } from "./authExtensions.js";
3
2
 
4
- const AUTH_POLICY_CONTEXT_RESOLVER_TAG = "jskit.auth.policy.context.resolvers";
5
-
6
- function normalizeAuthPolicyContextResolver(entry) {
7
- if (typeof entry === "function") {
8
- return Object.freeze({
9
- resolverId: String(entry.name || "anonymous"),
10
- order: 0,
11
- resolveAuthPolicyContext: entry
12
- });
13
- }
14
-
15
- if (!entry || typeof entry !== "object" || typeof entry.resolveAuthPolicyContext !== "function") {
16
- return null;
17
- }
18
-
19
- const resolverId = String(entry.resolverId || "anonymous");
20
- const order = Number.isFinite(entry.order) ? Number(entry.order) : 0;
21
-
22
- return Object.freeze({
23
- ...entry,
24
- resolverId,
25
- order,
26
- resolveAuthPolicyContext: entry.resolveAuthPolicyContext
27
- });
28
- }
29
-
30
- function registerAuthPolicyContextResolver(app, token, factory) {
31
- registerTaggedSingleton(app, token, factory, AUTH_POLICY_CONTEXT_RESOLVER_TAG, {
32
- context: "registerAuthPolicyContextResolver"
33
- });
34
- }
35
-
36
- function resolveAuthPolicyContextResolvers(scope) {
37
- return resolveTaggedEntries(scope, AUTH_POLICY_CONTEXT_RESOLVER_TAG)
38
- .map((entry, index) => ({
39
- resolver: normalizeAuthPolicyContextResolver(entry),
40
- index
41
- }))
42
- .filter((entry) => Boolean(entry.resolver))
43
- .sort((left, right) => {
44
- if (left.resolver.order !== right.resolver.order) {
45
- return left.resolver.order - right.resolver.order;
46
- }
47
-
48
- return left.index - right.index;
49
- })
50
- .map((entry) => entry.resolver);
51
- }
52
-
53
- function resolveComposedAuthPolicyContextResolver(scope) {
54
- return composeAuthPolicyContextResolvers(resolveAuthPolicyContextResolvers(scope));
55
- }
56
-
57
- function mergeAuthPolicyContexts(contexts = []) {
58
- const merged = {};
59
- let hasValues = false;
60
- const permissions = new Set();
61
-
62
- for (const context of Array.isArray(contexts) ? contexts : [contexts]) {
63
- if (!context || typeof context !== "object") {
64
- continue;
65
- }
66
-
67
- for (const [key, value] of Object.entries(context)) {
68
- if (key === "permissions") {
69
- for (const permission of normalizePermissionList(value)) {
70
- permissions.add(permission);
71
- }
72
- continue;
73
- }
74
-
75
- if (value === undefined) {
76
- continue;
77
- }
78
-
79
- merged[key] = value;
80
- hasValues = true;
81
- }
82
- }
83
-
84
- if (permissions.size > 0) {
85
- merged.permissions = Object.freeze([...permissions]);
86
- hasValues = true;
3
+ function registerAuthPolicyContextResolver(extensions, resolver) {
4
+ if (!extensions || typeof extensions.registerPolicyContextResolver !== "function") {
5
+ throw new TypeError("registerAuthPolicyContextResolver requires auth.extensions.");
87
6
  }
88
-
89
- return hasValues ? Object.freeze(merged) : null;
7
+ return extensions.registerPolicyContextResolver(resolver);
90
8
  }
91
9
 
92
- function composeAuthPolicyContextResolvers(resolvers = []) {
93
- const normalizedResolvers = (Array.isArray(resolvers) ? resolvers : [resolvers])
94
- .map((entry, index) => ({
95
- resolver: normalizeAuthPolicyContextResolver(entry),
96
- index
97
- }))
98
- .filter((entry) => Boolean(entry.resolver))
99
- .sort((left, right) => {
100
- if (left.resolver.order !== right.resolver.order) {
101
- return left.resolver.order - right.resolver.order;
102
- }
103
-
104
- return left.index - right.index;
105
- })
106
- .map((entry) => entry.resolver);
107
-
108
- if (normalizedResolvers.length < 1) {
109
- return null;
110
- }
111
-
112
- return async function resolveComposedAuthPolicyContext(input = {}) {
113
- const contexts = [];
114
-
115
- for (const resolver of normalizedResolvers) {
116
- contexts.push(await resolver.resolveAuthPolicyContext(input));
117
- }
118
-
119
- return mergeAuthPolicyContexts(contexts);
120
- };
10
+ function resolveComposedAuthPolicyContextResolver(extensions) {
11
+ if (!extensions || typeof extensions.resolvePolicyContext !== "function") return null;
12
+ return (input = {}) => extensions.resolvePolicyContext(input);
121
13
  }
122
14
 
123
15
  export {
124
- AUTH_POLICY_CONTEXT_RESOLVER_TAG,
125
16
  registerAuthPolicyContextResolver,
126
- resolveAuthPolicyContextResolvers,
127
17
  resolveComposedAuthPolicyContextResolver,
128
- mergeAuthPolicyContexts,
129
- composeAuthPolicyContextResolvers
18
+ mergePolicyContexts
130
19
  };