@voltro/protocol 0.83.1 → 0.85.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 +1191 -0
- package/THIRD-PARTY-NOTICES.md +1 -57
- package/dist/apikey.d.ts +32 -34
- package/dist/index.d.ts +1276 -1349
- package/dist/index.js +1022 -733
- package/dist/inspect.d.ts +88 -88
- package/dist/inspect.js +103 -53
- package/dist/jwt.d.ts +32 -34
- package/dist/rest.d.ts +72 -57
- package/dist/rest.js +287 -208
- package/dist/{restFormat-EZ8k9ZcQ.js → restFormat-BlgTLxm1.js} +108 -114
- package/dist/{scopes-Di756ENh.js → scopes-ClywBij8.js} +167 -137
- package/dist/session.d.ts +90 -96
- package/dist/session.js +1 -1
- package/package.json +4 -8
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import { Context as e, Effect as t, Schema as n } from "effect";
|
|
2
|
-
import { RpcMiddleware as
|
|
1
|
+
import { Context as e, Effect as t, Schema as n, Struct as r } from "effect";
|
|
2
|
+
import { RpcMiddleware as i } from "effect/rpc";
|
|
3
3
|
//#region src/tenantSelection.ts
|
|
4
|
-
var
|
|
4
|
+
var a = (e) => e.type === "user" || e.type === "apiKey" || e.type === "serviceAccount", o = class extends n.TaggedError()("TenantSelectionRefused", {
|
|
5
5
|
subjectType: n.String,
|
|
6
6
|
subjectId: n.NullOr(n.String),
|
|
7
7
|
tenantId: n.String,
|
|
8
|
-
reason: n.
|
|
9
|
-
}) {},
|
|
10
|
-
if (!
|
|
8
|
+
reason: n.Literals(["not-a-member", "subject-has-no-tenant"])
|
|
9
|
+
}) {}, s = (e, t, n) => {
|
|
10
|
+
if (!a(e)) throw new o({
|
|
11
11
|
subjectType: e.type,
|
|
12
12
|
subjectId: e.id,
|
|
13
13
|
tenantId: t,
|
|
14
14
|
reason: "subject-has-no-tenant"
|
|
15
15
|
});
|
|
16
|
-
if (!n.some((e) => e.tenantId === t)) throw new
|
|
16
|
+
if (!n.some((e) => e.tenantId === t)) throw new o({
|
|
17
17
|
subjectType: e.type,
|
|
18
18
|
subjectId: e.id,
|
|
19
19
|
tenantId: t,
|
|
@@ -30,51 +30,62 @@ var i = (e) => e.type === "user" || e.type === "apiKey" || e.type === "serviceAc
|
|
|
30
30
|
})
|
|
31
31
|
}
|
|
32
32
|
};
|
|
33
|
-
},
|
|
34
|
-
key: n.String,
|
|
35
|
-
value: n.Unknown
|
|
36
|
-
}), c = n.optional(n.Array(n.String)), l = n.Struct({
|
|
33
|
+
}, c = n.Record(n.String, n.Unknown), l = n.optional(n.Array(n.String)), u = n.Struct({
|
|
37
34
|
type: n.Literal("user"),
|
|
38
35
|
id: n.String,
|
|
39
36
|
tenantId: n.String,
|
|
40
|
-
scopes:
|
|
41
|
-
metadata: n.optional(
|
|
42
|
-
}),
|
|
37
|
+
scopes: l,
|
|
38
|
+
metadata: n.optional(c)
|
|
39
|
+
}), d = n.Struct({
|
|
43
40
|
type: n.Literal("apiKey"),
|
|
44
41
|
id: n.String,
|
|
45
42
|
tenantId: n.String,
|
|
46
|
-
scopes:
|
|
47
|
-
metadata: n.optional(
|
|
48
|
-
}),
|
|
43
|
+
scopes: l,
|
|
44
|
+
metadata: n.optional(c)
|
|
45
|
+
}), f = n.Struct({
|
|
49
46
|
type: n.Literal("serviceAccount"),
|
|
50
47
|
id: n.String,
|
|
51
48
|
tenantId: n.String,
|
|
52
|
-
auditActorId: n.
|
|
53
|
-
scopes:
|
|
54
|
-
metadata: n.optional(
|
|
55
|
-
}),
|
|
49
|
+
auditActorId: n.optionalKey(n.NullOr(n.String)),
|
|
50
|
+
scopes: l,
|
|
51
|
+
metadata: n.optional(c)
|
|
52
|
+
}), p = n.Struct({
|
|
56
53
|
type: n.Literal("anonymous"),
|
|
57
54
|
id: n.Null,
|
|
58
55
|
tenantId: n.NullOr(n.String),
|
|
59
56
|
credentialRejected: n.optional(n.String)
|
|
60
|
-
}),
|
|
57
|
+
}), m = n.Struct({
|
|
61
58
|
type: n.Literal("system"),
|
|
62
59
|
id: n.String,
|
|
63
60
|
tenantId: n.Null,
|
|
64
|
-
scopes:
|
|
65
|
-
metadata: n.optional(
|
|
66
|
-
}),
|
|
61
|
+
scopes: l,
|
|
62
|
+
metadata: n.optional(c)
|
|
63
|
+
}), h = n.Struct({
|
|
67
64
|
type: n.Literal("service"),
|
|
68
65
|
id: n.String,
|
|
69
66
|
service: n.String,
|
|
70
67
|
tenantId: n.Null,
|
|
71
|
-
scopes:
|
|
72
|
-
metadata: n.optional(
|
|
73
|
-
}), ee = n.Union(
|
|
68
|
+
scopes: l,
|
|
69
|
+
metadata: n.optional(c)
|
|
70
|
+
}), ee = n.Union([
|
|
71
|
+
u,
|
|
72
|
+
d,
|
|
73
|
+
f,
|
|
74
|
+
p,
|
|
75
|
+
m,
|
|
76
|
+
h
|
|
77
|
+
]), te = n.Union([
|
|
78
|
+
u.mapFields(r.omit(["scopes"])),
|
|
79
|
+
d.mapFields(r.omit(["scopes"])),
|
|
80
|
+
f.mapFields(r.omit(["scopes"])),
|
|
81
|
+
p,
|
|
82
|
+
m.mapFields(r.omit(["scopes"])),
|
|
83
|
+
h.mapFields(r.omit(["scopes"]))
|
|
84
|
+
]), ne = (e) => {
|
|
74
85
|
if (e.type === "anonymous") return e;
|
|
75
86
|
let { scopes: t, ...n } = e;
|
|
76
87
|
return n;
|
|
77
|
-
},
|
|
88
|
+
}, g = (e) => e.scopes ?? [], _ = (e, t) => ({
|
|
78
89
|
type: "anonymous",
|
|
79
90
|
id: null,
|
|
80
91
|
tenantId: e,
|
|
@@ -90,35 +101,36 @@ var i = (e) => e.type === "user" || e.type === "apiKey" || e.type === "serviceAc
|
|
|
90
101
|
service: e,
|
|
91
102
|
tenantId: null,
|
|
92
103
|
scopes: []
|
|
93
|
-
}), ae = (e) => e.type === "service", oe = (e) => e.type === "system" || e.type === "service",
|
|
104
|
+
}), ae = (e) => e.type === "service", oe = (e) => e.type === "system" || e.type === "service", v = (e) => {
|
|
94
105
|
if (e.type === "system") return null;
|
|
95
106
|
if (e.type === "serviceAccount" && e.auditActorId !== void 0) return e.auditActorId;
|
|
96
107
|
if (e.type !== "apiKey") return e.id;
|
|
97
108
|
let t = e.metadata?.userId;
|
|
98
109
|
return typeof t == "string" && t !== "" ? t : e.id;
|
|
99
|
-
},
|
|
110
|
+
}, se = (e, t) => {
|
|
100
111
|
let n = e;
|
|
101
112
|
return {
|
|
102
113
|
type: "serviceAccount",
|
|
103
114
|
id: e.id ?? "system",
|
|
104
115
|
tenantId: t,
|
|
105
|
-
auditActorId:
|
|
106
|
-
scopes:
|
|
116
|
+
auditActorId: v(e),
|
|
117
|
+
scopes: g(e),
|
|
107
118
|
...n.metadata === void 0 ? {} : { metadata: n.metadata }
|
|
108
119
|
};
|
|
109
|
-
},
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
}
|
|
120
|
+
}, ce = (e) => e.type === "system", le = "impersonation", ue = (e) => e.metadata?.impersonation ?? null, de = class extends e.Service()("@voltro/Subject") {}, fe = class extends e.Service()("@voltro/ConnectionInfo") {}, y = class extends n.TaggedError()("Unauthenticated", { reason: n.optional(n.String) }) {
|
|
121
|
+
get message() {
|
|
122
|
+
return this.reason ?? "Unauthenticated";
|
|
123
|
+
}
|
|
124
|
+
}, pe = class extends i.Service()("@voltro/AuthMiddleware", { error: y }) {}, me = class extends i.Service()("@voltro/ConnectionInfoMiddleware") {}, he = (e) => typeof e.mountRoutes == "function", ge = (e) => Array.isArray(e) ? {
|
|
113
125
|
kind: "grant",
|
|
114
126
|
scopes: e
|
|
115
|
-
} : e,
|
|
116
|
-
if (t.kind === "vetoed") throw new
|
|
127
|
+
} : e, b = (e, t) => {
|
|
128
|
+
if (t.kind === "vetoed") throw new y({ reason: `${t.code}: ${t.message}` });
|
|
117
129
|
if (e.type === "anonymous") return {
|
|
118
130
|
subject: e,
|
|
119
131
|
removed: []
|
|
120
132
|
};
|
|
121
|
-
let n =
|
|
133
|
+
let n = g(e);
|
|
122
134
|
if (t.kind === "grant") {
|
|
123
135
|
if (t.scopes.length === 0) return {
|
|
124
136
|
subject: e,
|
|
@@ -141,14 +153,14 @@ var i = (e) => e.type === "user" || e.type === "apiKey" || e.type === "serviceAc
|
|
|
141
153
|
},
|
|
142
154
|
removed: i
|
|
143
155
|
};
|
|
144
|
-
},
|
|
156
|
+
}, _e = 3e4, ve = 1e4, x = (e) => `${e.type}\u0000${e.tenantId ?? ""}\u0000${e.id ?? ""}`, ye = () => {
|
|
145
157
|
if (typeof process > "u") return;
|
|
146
158
|
let e = process.env.VOLTRO_AUTH_SCOPE_CACHE_TTL_MS;
|
|
147
159
|
if (e === void 0 || e === "") return;
|
|
148
160
|
let t = Number(e);
|
|
149
161
|
return Number.isFinite(t) && t >= 0 ? t : void 0;
|
|
150
|
-
},
|
|
151
|
-
let t = e.ttlMs ??
|
|
162
|
+
}, S = (e = {}) => {
|
|
163
|
+
let t = e.ttlMs ?? ye() ?? 3e4, n = e.maxEntries ?? 1e4, r = e.now ?? Date.now, i = /* @__PURE__ */ new Map(), a = () => {
|
|
152
164
|
if (i.size <= n) return;
|
|
153
165
|
let e = r();
|
|
154
166
|
for (let [t, n] of i) n.freshUntil <= e && i.delete(t);
|
|
@@ -184,17 +196,17 @@ var i = (e) => e.type === "user" || e.type === "apiKey" || e.type === "serviceAc
|
|
|
184
196
|
};
|
|
185
197
|
}
|
|
186
198
|
};
|
|
187
|
-
},
|
|
199
|
+
}, be = (e) => typeof e.resolve == "function", xe = (e) => {
|
|
188
200
|
let t = e.authorization ?? e.Authorization;
|
|
189
201
|
if (t !== void 0) return /^Bearer\s+(.+)$/i.exec(t.trim())?.[1]?.trim();
|
|
190
|
-
},
|
|
191
|
-
if (!
|
|
192
|
-
let
|
|
202
|
+
}, Se = async (e, t, n, r) => {
|
|
203
|
+
if (!a(e)) return e;
|
|
204
|
+
let i = {
|
|
193
205
|
type: e.type,
|
|
194
206
|
id: e.id
|
|
195
207
|
}, c;
|
|
196
208
|
try {
|
|
197
|
-
c = await n.store.read(
|
|
209
|
+
c = await n.store.read(i);
|
|
198
210
|
} catch (e) {
|
|
199
211
|
throw r(`tenant selection unavailable: ${e instanceof Error ? e.message : String(e)}`);
|
|
200
212
|
}
|
|
@@ -206,62 +218,62 @@ var i = (e) => e.type === "user" || e.type === "apiKey" || e.type === "serviceAc
|
|
|
206
218
|
throw r(`memberships unavailable: ${e instanceof Error ? e.message : String(e)}`);
|
|
207
219
|
}
|
|
208
220
|
try {
|
|
209
|
-
return
|
|
221
|
+
return s(e, c, l);
|
|
210
222
|
} catch (t) {
|
|
211
|
-
if (!(t instanceof
|
|
223
|
+
if (!(t instanceof o)) throw t;
|
|
212
224
|
try {
|
|
213
|
-
await n.store.clear(
|
|
225
|
+
await n.store.clear(i);
|
|
214
226
|
} catch (e) {
|
|
215
227
|
throw r(`tenant selection unavailable: ${e instanceof Error ? e.message : String(e)}`);
|
|
216
228
|
}
|
|
217
229
|
return e;
|
|
218
230
|
}
|
|
219
|
-
},
|
|
220
|
-
let n =
|
|
231
|
+
}, C = (e, t) => {
|
|
232
|
+
let n = xe(t);
|
|
221
233
|
if (n === void 0) return e;
|
|
222
234
|
let r = e.filter((e) => e.claimsBearerPrefix !== void 0 && e.claimsBearerPrefix !== "" && n.startsWith(e.claimsBearerPrefix));
|
|
223
235
|
if (r.length === 0) return e;
|
|
224
236
|
let i = new Set(r);
|
|
225
237
|
return [...r, ...e.filter((e) => !i.has(e))];
|
|
226
|
-
},
|
|
227
|
-
if (e === "refuse") throw new
|
|
238
|
+
}, Ce = (e, t) => {
|
|
239
|
+
if (e === "refuse") throw new y({ reason: "anonymous callers are refused" });
|
|
228
240
|
if (e === "no-tenant") return "";
|
|
229
241
|
if (e === "header") {
|
|
230
|
-
if (t === void 0 || t === "") throw new
|
|
242
|
+
if (t === void 0 || t === "") throw new y({ reason: "tenant required (x-tenant header missing)" });
|
|
231
243
|
return t;
|
|
232
244
|
}
|
|
233
245
|
return "tenantId" in e ? e.tenantId : t !== void 0 && t !== "" ? t : e.headerOrTenant;
|
|
234
|
-
},
|
|
246
|
+
}, w = (e, t) => {
|
|
235
247
|
let n = t?.resolveScopes, r = t?.subjectGuards ?? [];
|
|
236
248
|
if (t?.memberships === void 0 != (t?.tenantSelection === void 0)) throw Error("composeAuthStrategies: `memberships` and `tenantSelection` come together — a tenant selection is verified against the memberships and read from the store; configure both or neither.");
|
|
237
249
|
let i = t?.memberships !== void 0 && t.tenantSelection !== void 0 ? {
|
|
238
250
|
memberships: t.memberships,
|
|
239
251
|
store: t.tenantSelection
|
|
240
|
-
} : void 0, a = n !== void 0 || r.length > 0, o = !a || t?.scopeCache === !1 ? null : t?.scopeCache !== void 0 &&
|
|
252
|
+
} : void 0, a = n !== void 0 || r.length > 0, o = !a || t?.scopeCache === !1 ? null : t?.scopeCache !== void 0 && be(t.scopeCache) ? t.scopeCache : S(t?.scopeCache ?? {});
|
|
241
253
|
return async (s) => {
|
|
242
254
|
let c = t?.getStore?.(), l = c === void 0 ? s : {
|
|
243
255
|
...s,
|
|
244
256
|
store: c
|
|
245
257
|
}, u;
|
|
246
|
-
for (let s of
|
|
258
|
+
for (let s of C(e, l.headers)) {
|
|
247
259
|
let e = await s.resolve(l);
|
|
248
260
|
if (e.kind === "matched") {
|
|
249
261
|
if (e.subject.type === "service") return { subject: {
|
|
250
262
|
...e.subject,
|
|
251
263
|
scopes: []
|
|
252
264
|
} };
|
|
253
|
-
let c = i === void 0 ? e.subject : await
|
|
265
|
+
let c = i === void 0 ? e.subject : await Se(e.subject, l, i, (e) => (t?.onStrategyFailed?.({
|
|
254
266
|
strategyId: s.id,
|
|
255
267
|
reason: e
|
|
256
|
-
}), new
|
|
268
|
+
}), new y({ reason: e }))), u = c;
|
|
257
269
|
if (a) {
|
|
258
270
|
let e = async () => {
|
|
259
271
|
let e = n === void 0 ? {
|
|
260
272
|
kind: "grant",
|
|
261
273
|
scopes: []
|
|
262
|
-
} :
|
|
274
|
+
} : ge(await n(c, l));
|
|
263
275
|
if (e.kind === "unavailable" || r.length === 0) return e;
|
|
264
|
-
let t =
|
|
276
|
+
let t = b(c, e).subject, i = {
|
|
265
277
|
origin: "request",
|
|
266
278
|
headers: l.headers,
|
|
267
279
|
clientId: l.clientId,
|
|
@@ -279,22 +291,22 @@ var i = (e) => e.type === "user" || e.type === "apiKey" || e.type === "serviceAc
|
|
|
279
291
|
}, { decision: i, fresh: a } = o === null ? {
|
|
280
292
|
decision: await e(),
|
|
281
293
|
fresh: !0
|
|
282
|
-
} : await o.resolve(
|
|
294
|
+
} : await o.resolve(x(c), e);
|
|
283
295
|
if (i.kind === "vetoed") {
|
|
284
296
|
let e = `${i.code}: ${i.message}`;
|
|
285
297
|
throw t?.onStrategyFailed?.({
|
|
286
298
|
strategyId: s.id,
|
|
287
299
|
reason: e
|
|
288
|
-
}), new
|
|
300
|
+
}), new y({ reason: e });
|
|
289
301
|
}
|
|
290
302
|
if (i.kind === "unavailable") {
|
|
291
303
|
let e = `scope resolution unavailable: ${i.reason}`;
|
|
292
304
|
throw t?.onStrategyFailed?.({
|
|
293
305
|
strategyId: s.id,
|
|
294
306
|
reason: e
|
|
295
|
-
}), new
|
|
307
|
+
}), new y({ reason: e });
|
|
296
308
|
}
|
|
297
|
-
let d =
|
|
309
|
+
let d = b(c, i);
|
|
298
310
|
a && d.removed.length > 0 && t?.onScopesNarrowed?.({
|
|
299
311
|
strategyId: s.id,
|
|
300
312
|
subjectType: c.type,
|
|
@@ -323,63 +335,63 @@ var i = (e) => e.type === "user" || e.type === "apiKey" || e.type === "serviceAc
|
|
|
323
335
|
credentialRejected: u
|
|
324
336
|
} : e };
|
|
325
337
|
}
|
|
326
|
-
if (u !== void 0) throw new
|
|
327
|
-
return { subject:
|
|
338
|
+
if (u !== void 0) throw new y({ reason: `credential rejected: ${u}` });
|
|
339
|
+
return { subject: _(Ce(t?.anonymous ?? "no-tenant", l.headers["x-tenant"])) };
|
|
328
340
|
};
|
|
329
|
-
},
|
|
330
|
-
if (e.type === "anonymous") throw new
|
|
331
|
-
},
|
|
341
|
+
}, T = (e, t) => {
|
|
342
|
+
if (e.type === "anonymous") throw new y(t === void 0 ? {} : { reason: t });
|
|
343
|
+
}, E = "admin:full", D = "apikeys:issue:self", O = "apikeys:issue:org", k = "apikeys:issue:other", A = "devices:manage", j = class extends n.TaggedError()("ScopeError", {
|
|
332
344
|
required: n.String,
|
|
333
345
|
message: n.String
|
|
334
|
-
}) {},
|
|
346
|
+
}) {}, M = class extends n.TaggedError()("NoSuchResource", {
|
|
335
347
|
resourceType: n.NullOr(n.String),
|
|
336
348
|
resourceId: n.String,
|
|
337
349
|
message: n.String
|
|
338
|
-
}) {},
|
|
339
|
-
typeof e == "object" && e &&
|
|
340
|
-
},
|
|
350
|
+
}) {}, N = (e) => "scopes" in e && e.scopes ? e.scopes : [], P = /* @__PURE__ */ new WeakMap(), we = (e, t) => {
|
|
351
|
+
typeof e == "object" && e && P.set(e, t);
|
|
352
|
+
}, F = (e) => {
|
|
341
353
|
if (typeof e == "object" && e) {
|
|
342
|
-
let t =
|
|
354
|
+
let t = P.get(e);
|
|
343
355
|
if (t) return t;
|
|
344
356
|
}
|
|
345
|
-
return
|
|
346
|
-
},
|
|
347
|
-
let n = L(e);
|
|
348
|
-
return n.includes("admin:full") || n.includes(t);
|
|
349
|
-
}, Se = (e, t) => {
|
|
357
|
+
return N(e);
|
|
358
|
+
}, I = (e, t) => {
|
|
350
359
|
let n = F(e);
|
|
351
360
|
return n.includes("admin:full") || n.includes(t);
|
|
352
|
-
},
|
|
361
|
+
}, Te = (e, t) => {
|
|
362
|
+
let n = N(e);
|
|
363
|
+
return n.includes("admin:full") || n.includes(t);
|
|
364
|
+
}, Ee = (e, n) => I(e, n) ? t.void : t.fail(new j({
|
|
353
365
|
required: n,
|
|
354
366
|
message: `missing required scope '${n}'`
|
|
355
|
-
})),
|
|
367
|
+
})), L = (e, t) => {
|
|
356
368
|
let n;
|
|
357
369
|
try {
|
|
358
370
|
n = typeof e.action == "function" ? e.action(t) : e.action;
|
|
359
371
|
} catch {
|
|
360
|
-
throw new
|
|
372
|
+
throw new j({
|
|
361
373
|
required: e.resourceType,
|
|
362
374
|
message: "policy action selector failed"
|
|
363
375
|
});
|
|
364
376
|
}
|
|
365
|
-
if (typeof n != "string" || n.trim() === "") throw new
|
|
377
|
+
if (typeof n != "string" || n.trim() === "") throw new j({
|
|
366
378
|
required: e.resourceType,
|
|
367
379
|
message: "policy action selector returned no action"
|
|
368
380
|
});
|
|
369
381
|
return n;
|
|
370
|
-
},
|
|
371
|
-
let n =
|
|
372
|
-
if (e.type === "service") return n !== void 0 && n.includes(e.service) ? null : new
|
|
382
|
+
}, R = (e) => (typeof e.action == "string" || typeof e.action == "function") && typeof e.resourceType == "string", De = (e) => e !== void 0 && e.some((e) => R(e) || typeof e.resource == "function"), z = (e) => typeof e.open == "string", B = (e) => Array.isArray(e.service), Oe = (e) => ({ service: [...e] }), V = (e) => e?.find(B)?.service, H = (e, t) => {
|
|
383
|
+
let n = V(t);
|
|
384
|
+
if (e.type === "service") return n !== void 0 && n.includes(e.service) ? null : new j({
|
|
373
385
|
required: "service-procedure",
|
|
374
386
|
message: n === void 0 ? `service '${e.service}' may only call procedures that declare it in \`service: { callers }\`` : `service '${e.service}' is not among this procedure's callers [${n.join(", ")}]`
|
|
375
387
|
});
|
|
376
|
-
if (n !== void 0) return
|
|
388
|
+
if (n !== void 0) return Y(e, new j({
|
|
377
389
|
required: `service:${n.join("|")}`,
|
|
378
390
|
message: `this procedure is callable only by the service${n.length === 1 ? "" : "s"} [${n.join(", ")}]`
|
|
379
391
|
}));
|
|
380
|
-
},
|
|
381
|
-
|
|
382
|
-
},
|
|
392
|
+
}, U = (e) => e.authenticated === !0, ke = (e) => ({ open: e }), W = (e) => typeof e == "string" ? [e] : e, G, Ae = (e) => {
|
|
393
|
+
G = e;
|
|
394
|
+
}, je = (e) => G === void 0 ? e.filter((e) => (e.guards ?? []).some((e) => !R(e) && e.resource !== void 0)).map((e) => e.tag) : [], Me = (e) => [
|
|
383
395
|
`${e.length} procedure${e.length === 1 ? "" : "s"} declare a per-resource guard that nothing enforces:`,
|
|
384
396
|
...e.slice(0, 10).map((e) => ` ${e}`),
|
|
385
397
|
...e.length > 10 ? [` … and ${e.length - 10} more`] : [],
|
|
@@ -393,59 +405,77 @@ var i = (e) => e.type === "user" || e.type === "apiKey" || e.type === "serviceAc
|
|
|
393
405
|
" • setResourceScopeResolver((req) => Effect<boolean>) — answers \"does this",
|
|
394
406
|
" subject hold `req.scope` on `req.resource`\" from your own tables.",
|
|
395
407
|
" • Drop the `resource` extractor if a global scope check is what you meant."
|
|
396
|
-
].join("\n"),
|
|
397
|
-
|
|
398
|
-
},
|
|
408
|
+
].join("\n"), Ne = () => G, K, q = (e) => {
|
|
409
|
+
K = e;
|
|
410
|
+
}, Pe = () => K, J = (e) => new j({
|
|
399
411
|
required: "access-decision",
|
|
400
412
|
message: `${e ?? "this procedure"} declares no access decision: it has neither \`guards:\` nor \`openAccess:\`, and the app runs with \`security.defaultDeny\`. Add the scope(s) a caller must hold (\`guards: [{ scope: '…' }]\`), or declare it open on purpose with \`openAccess: '<why anyone may call this>'\`.`
|
|
401
|
-
}),
|
|
413
|
+
}), Y = (e, t) => {
|
|
402
414
|
let n = e.credentialRejected;
|
|
403
|
-
return n === void 0 ? t : new
|
|
415
|
+
return n === void 0 ? t : new y({ reason: `${n} — the request carried a credential and it was REJECTED, so this caller resolved to anonymous. The guard then refused (${t.message}); the scope is not the problem. Re-authenticate and retry.` });
|
|
416
|
+
}, X = (e) => {
|
|
417
|
+
let t = Array.isArray(e), n = Object.getPrototypeOf(e);
|
|
418
|
+
if (t ? n !== Array.prototype : n !== Object.prototype && n !== null) return !1;
|
|
419
|
+
for (let n of Reflect.ownKeys(e)) if (t && (typeof n != "string" || n !== "length" && !/^(0|[1-9][0-9]*)$/.test(n)) || !("value" in Object.getOwnPropertyDescriptor(e, n))) return !1;
|
|
420
|
+
return !0;
|
|
421
|
+
}, Z = (e, t) => {
|
|
422
|
+
let n, r = 0, i, a = 0, o;
|
|
423
|
+
return (s) => {
|
|
424
|
+
let c = F(e);
|
|
425
|
+
return (c !== n || c.length !== r) && (n = c, r = c.length, i = void 0, a = 0, o = void 0), i === void 0 && c.length >= 32 && ++a > 1 && (o ??= X(c) && X(e) && X(t) && t.every((e) => X(e) && (!("scope" in e) || typeof e.scope == "string" || X(e.scope))), o && (i = new Set(c))), i === void 0 ? c.includes("admin:full") || c.includes(s) : i.has("admin:full") || i.has(s);
|
|
426
|
+
};
|
|
404
427
|
}, Q = (e, t, n) => {
|
|
405
|
-
let r =
|
|
428
|
+
let r = H(e, t);
|
|
406
429
|
if (r !== void 0) return r;
|
|
407
|
-
if (!t || t.length === 0) return n?.defaultDeny === !0 ?
|
|
430
|
+
if (!t || t.length === 0) return n?.defaultDeny === !0 ? J(n.procedure) : null;
|
|
431
|
+
let i = 0, a;
|
|
408
432
|
for (let n of t) {
|
|
409
|
-
if (
|
|
410
|
-
if (
|
|
433
|
+
if (z(n) || B(n)) continue;
|
|
434
|
+
if (U(n)) {
|
|
411
435
|
if (e.id !== null && e.id !== void 0) continue;
|
|
412
|
-
return
|
|
436
|
+
return Y(e, new j({
|
|
413
437
|
required: "authenticated",
|
|
414
438
|
message: "this procedure requires an authenticated caller"
|
|
415
439
|
}));
|
|
416
440
|
}
|
|
417
|
-
if (
|
|
418
|
-
if (
|
|
419
|
-
return
|
|
441
|
+
if (R(n)) {
|
|
442
|
+
if (i++, a === void 0 && (t.length >= 512 || i >= 512) && (a = Z(e, t)), a === void 0 ? I(e, "admin:full") : a("admin:full")) continue;
|
|
443
|
+
return Y(e, new j({
|
|
420
444
|
required: `${n.resourceType}:${n.action}`,
|
|
421
445
|
message: `relationship guard '${n.action}' on '${n.resourceType}' cannot be checked synchronously`
|
|
422
446
|
}));
|
|
423
447
|
}
|
|
424
|
-
let
|
|
425
|
-
if (
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
448
|
+
let r = W(n.scope);
|
|
449
|
+
if (r.length === 0) continue;
|
|
450
|
+
i += r.length, a === void 0 && (t.length >= 512 || i >= 512) && (a = Z(e, t));
|
|
451
|
+
let o = n.mode ?? "all", s;
|
|
452
|
+
if (o === "any") {
|
|
453
|
+
if (a === void 0 ? r.some((t) => I(e, t)) : r.some(a)) continue;
|
|
454
|
+
s = r[0];
|
|
455
|
+
} else {
|
|
456
|
+
let t = a === void 0 ? r.find((t) => !I(e, t)) : r.find((e) => !a(e));
|
|
457
|
+
if (t === void 0) continue;
|
|
458
|
+
s = t;
|
|
433
459
|
}
|
|
460
|
+
return Y(e, new j({
|
|
461
|
+
required: s,
|
|
462
|
+
message: o === "any" ? `missing all of required scopes [${r.join(", ")}]` : `missing required scope '${s}'`
|
|
463
|
+
}));
|
|
434
464
|
}
|
|
435
465
|
return null;
|
|
436
|
-
},
|
|
466
|
+
}, Fe = (e, n, r) => {
|
|
437
467
|
let i;
|
|
438
468
|
try {
|
|
439
|
-
i =
|
|
469
|
+
i = L(n, r);
|
|
440
470
|
} catch (e) {
|
|
441
471
|
return t.succeed(e);
|
|
442
472
|
}
|
|
443
|
-
let a = (e) => new
|
|
473
|
+
let a = (e) => new j({
|
|
444
474
|
required: `${n.resourceType}:${i}`,
|
|
445
475
|
message: e
|
|
446
476
|
});
|
|
447
|
-
if (
|
|
448
|
-
let o =
|
|
477
|
+
if (I(e, "admin:full")) return t.succeed(null);
|
|
478
|
+
let o = K;
|
|
449
479
|
if (o === void 0) return t.succeed(a(`no policy resolver registered — cannot authorize '${i}' on '${n.resourceType}'`));
|
|
450
480
|
let s = n.resource(r);
|
|
451
481
|
return s === void 0 || s === "" ? t.succeed(a(`input does not identify a '${n.resourceType}' to authorize`)) : t.suspend(() => o({
|
|
@@ -453,36 +483,36 @@ var i = (e) => e.type === "user" || e.type === "apiKey" || e.type === "serviceAc
|
|
|
453
483
|
action: i,
|
|
454
484
|
resourceType: n.resourceType,
|
|
455
485
|
resourceId: s
|
|
456
|
-
})).pipe(t.
|
|
457
|
-
}, $ = (e, t, n, r, i) => t === !0 ? null : t === "missing" && e.id !== null && e.id !== void 0 ? new
|
|
486
|
+
})).pipe(t.catchCause(() => t.succeed(!1)), t.map((t) => $(e, t, n.resourceType, s, () => a(`no '${i}' relation on ${n.resourceType}:${s}`))));
|
|
487
|
+
}, $ = (e, t, n, r, i) => t === !0 ? null : t === "missing" && e.id !== null && e.id !== void 0 ? new M({
|
|
458
488
|
resourceType: n,
|
|
459
489
|
resourceId: r,
|
|
460
490
|
message: n === null ? `no such resource '${r}'` : `no such ${n} '${r}'`
|
|
461
|
-
}) : i(),
|
|
462
|
-
let a =
|
|
491
|
+
}) : i(), Ie = (e, n, r, i) => {
|
|
492
|
+
let a = H(e, n);
|
|
463
493
|
if (a !== void 0) return t.succeed(a);
|
|
464
494
|
if (!n || n.length === 0) return t.succeed(Q(e, n, i));
|
|
465
|
-
let o =
|
|
466
|
-
return !n.some(
|
|
495
|
+
let o = G;
|
|
496
|
+
return !n.some(R) && (!o || !n.some((e) => e.resource !== void 0)) ? t.succeed(Q(e, n, i)) : t.gen(function* () {
|
|
467
497
|
for (let i of n) {
|
|
468
|
-
if (
|
|
469
|
-
if (
|
|
498
|
+
if (z(i) || B(i)) continue;
|
|
499
|
+
if (U(i)) {
|
|
470
500
|
if (e.id !== null && e.id !== void 0) continue;
|
|
471
|
-
return
|
|
501
|
+
return Y(e, new j({
|
|
472
502
|
required: "authenticated",
|
|
473
503
|
message: "this procedure requires an authenticated caller"
|
|
474
504
|
}));
|
|
475
505
|
}
|
|
476
|
-
if (
|
|
477
|
-
let t = yield*
|
|
506
|
+
if (R(i)) {
|
|
507
|
+
let t = yield* Fe(e, i, r);
|
|
478
508
|
if (t) return t;
|
|
479
509
|
continue;
|
|
480
510
|
}
|
|
481
|
-
let n =
|
|
511
|
+
let n = W(i.scope);
|
|
482
512
|
if (n.length === 0) continue;
|
|
483
513
|
let a = i.resource ? i.resource(r) : void 0, s = [], c = !1;
|
|
484
514
|
for (let r of n) {
|
|
485
|
-
if (
|
|
515
|
+
if (I(e, r)) {
|
|
486
516
|
s.push(!0);
|
|
487
517
|
continue;
|
|
488
518
|
}
|
|
@@ -491,7 +521,7 @@ var i = (e) => e.type === "user" || e.type === "apiKey" || e.type === "serviceAc
|
|
|
491
521
|
subject: e,
|
|
492
522
|
scope: r,
|
|
493
523
|
resource: a
|
|
494
|
-
})).pipe(t.
|
|
524
|
+
})).pipe(t.catchCause(() => t.succeed(!1)));
|
|
495
525
|
n === "missing" && (c = !0), s.push(n === !0);
|
|
496
526
|
} else s.push(!1);
|
|
497
527
|
}
|
|
@@ -499,13 +529,13 @@ var i = (e) => e.type === "user" || e.type === "apiKey" || e.type === "serviceAc
|
|
|
499
529
|
if (!(l === "any" ? s.some(Boolean) : s.every(Boolean))) {
|
|
500
530
|
let t = l === "any" ? n[0] : n[n.findIndex((e, t) => !s[t])];
|
|
501
531
|
if (c && a !== void 0) {
|
|
502
|
-
let n = $(e, "missing", null, a, () => new
|
|
532
|
+
let n = $(e, "missing", null, a, () => new j({
|
|
503
533
|
required: t,
|
|
504
534
|
message: `missing required scope '${t}' on resource '${a}'`
|
|
505
535
|
}));
|
|
506
536
|
if (n !== null) return n;
|
|
507
537
|
}
|
|
508
|
-
return new
|
|
538
|
+
return new j({
|
|
509
539
|
required: t,
|
|
510
540
|
message: l === "any" ? `missing all of required scopes [${n.join(", ")}]` : `missing required scope '${t}'` + (a === void 0 ? "" : ` on resource '${a}'`)
|
|
511
541
|
});
|
|
@@ -515,4 +545,4 @@ var i = (e) => e.type === "user" || e.type === "apiKey" || e.type === "serviceAc
|
|
|
515
545
|
});
|
|
516
546
|
};
|
|
517
547
|
//#endregion
|
|
518
|
-
export {
|
|
548
|
+
export { x as $, Ae as A, de as B, ke as C, V as D, Oe as E, ve as F, w as G, _ as H, _e as I, ae as J, he as K, le as L, pe as M, fe as N, we as O, me as P, ue as Q, ee as R, J as S, L as T, b as U, y as V, T as W, S as X, ce as Y, C as Z, Te as _, A as a, o as at, R as b, Me as c, De as d, ie as et, F as f, I as g, Ne as h, D as i, se as it, N as j, q as k, Q as l, Pe as m, O as n, ne as nt, M as o, a as ot, je as p, oe as q, k as r, re as rt, j as s, s as st, E as t, v as tt, Ie as u, U as v, Ee as w, B as x, z as y, te as z };
|