@voltro/plugin-scim 0.85.0 → 0.87.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/dist/index.js CHANGED
@@ -1,503 +1,81 @@
1
- import { Effect as e } from "effect";
2
- import { definePlugin as t, pluginInstanceName as n, tsMs as r } from "@voltro/protocol";
3
- import { checkBearer as i } from "@voltro/protocol/session";
4
- import { boolean as a, eq as o, generateId as s, id as c, json as l, queryFor as u, table as d, text as f, timestamp as p } from "@voltro/database";
5
- //#region src/scim.ts
6
- var m = "urn:ietf:params:scim:schemas:core:2.0:User", h = "urn:ietf:params:scim:schemas:core:2.0:Group", g = "urn:ietf:params:scim:api:messages:2.0:ListResponse", _ = "urn:ietf:params:scim:api:messages:2.0:Error", v = (e) => new Date(e).toISOString(), y = (e, t) => {
7
- if (typeof e == "boolean") return e;
8
- if (typeof e == "number") return Number.isFinite(e) && e !== 0;
9
- if (typeof e == "string") {
10
- let t = e.trim().toLowerCase();
11
- if (t === "true" || t === "1") return !0;
12
- if (t === "false" || t === "0" || t === "") return !1;
13
- }
14
- return t;
15
- }, b = (e) => {
16
- let t = (e ?? "").trim();
17
- return (t.toLowerCase().startsWith("urn:") ? t.slice(t.lastIndexOf(":") + 1) : t).toLowerCase();
18
- }, x = (e, t) => ({
19
- schemas: [m],
20
- id: e.id,
21
- ...e.externalId ? { externalId: e.externalId } : {},
22
- userName: e.userName,
23
- name: {
24
- givenName: e.givenName ?? "",
25
- familyName: e.familyName ?? ""
26
- },
27
- ...e.email ? { emails: [{
28
- value: e.email,
29
- primary: !0
30
- }] } : {},
31
- active: e.active,
32
- meta: {
33
- resourceType: "User",
34
- created: v(e.createdAt),
35
- lastModified: v(e.updatedAt),
36
- location: `${t}/${e.id}`
37
- }
38
- }), S = (e) => {
39
- let t = e.name ?? {}, n = e.emails ?? [], r = n.find((e) => e.primary)?.value ?? n[0]?.value ?? null;
40
- return {
41
- userName: String(e.userName ?? ""),
42
- givenName: t.givenName ?? null,
43
- familyName: t.familyName ?? null,
44
- email: r,
45
- active: e.active === void 0 || e.active === null || y(e.active, !1),
46
- externalId: e.externalId ?? null
47
- };
48
- }, C = (e, t) => {
49
- let n = t.Operations ?? t.operations ?? [], r = { ...e };
50
- for (let e of n) {
51
- let t = (e.op ?? "").toLowerCase();
52
- if (t !== "replace" && t !== "add") continue;
53
- let n = b(e.path);
54
- if (n === "active") r = {
55
- ...r,
56
- active: y(e.value, !1)
57
- };
58
- else if (n === "username") r = {
59
- ...r,
60
- userName: String(e.value)
61
- };
62
- else if (n === "" && e.value && typeof e.value == "object") for (let [t, n] of Object.entries(e.value)) {
63
- let e = t.toLowerCase();
64
- e === "active" ? r = {
65
- ...r,
66
- active: y(n, !1)
67
- } : e === "username" && (r = {
68
- ...r,
69
- userName: String(n)
70
- });
71
- }
72
- }
73
- return r;
74
- }, w = (e, t) => ({
75
- schemas: [g],
76
- totalResults: t?.totalResults ?? e.length,
77
- startIndex: t?.startIndex ?? 1,
78
- itemsPerPage: e.length,
79
- Resources: e
80
- }), T = (e, t, n) => ({
81
- schemas: [_],
82
- status: String(e),
83
- ...n ? { scimType: n } : {},
84
- detail: t
85
- }), E = (e, t) => {
86
- if (!e) return { kind: "none" };
87
- let n = /^\s*([A-Za-z][A-Za-z0-9]*)\s+eq\s+"([^"]*)"\s*$/i.exec(e);
88
- if (!n) return { kind: "invalid" };
89
- let r = t.find((e) => e.toLowerCase() === n[1].toLowerCase());
90
- return r === void 0 ? { kind: "invalid" } : {
91
- kind: "filter",
92
- attribute: r,
93
- value: n[2]
94
- };
95
- }, D = (e) => {
96
- let t = Number(e.get("startIndex")), n = Number(e.get("count"));
97
- return {
98
- startIndex: Number.isSafeInteger(t) && t >= 1 ? t : 1,
99
- count: e.get("count") !== null && Number.isSafeInteger(n) && n >= 0 ? n : null
100
- };
101
- }, O = (e, t) => {
102
- let n = t.Operations ?? t.operations ?? [], r = (e) => (Array.isArray(e) ? e : e === void 0 ? [] : [e]).map((e) => String(e?.value ?? e)).filter((e) => e !== "" && e !== "undefined"), i = e;
103
- for (let e of n) {
104
- let t = (e.op ?? "").toLowerCase(), n = e.path ?? "", a = /^members\[value\s+eq\s+"([^"]*)"\]$/i.exec(n);
105
- if (t === "add" && n.toLowerCase() === "members") {
106
- let t = r(e.value), n = t.length > 4 ? new Set(i.members) : void 0, a = t.filter((e) => !(n === void 0 ? i.members.includes(e) : n.has(e)));
107
- i = {
108
- ...i,
109
- members: [...i.members, ...a]
110
- };
111
- } else if (t === "remove" && a) i = {
112
- ...i,
113
- members: i.members.filter((e) => e !== a[1])
114
- };
115
- else if (t === "remove" && n.toLowerCase() === "members") {
116
- let t = new Set(r(e.value));
117
- i = {
118
- ...i,
119
- members: t.size === 0 ? [] : i.members.filter((e) => !t.has(e))
120
- };
121
- } else if (t === "replace" && n.toLowerCase() === "members") i = {
122
- ...i,
123
- members: [...r(e.value)]
124
- };
125
- else if (t === "replace" && n === "displayName") i = {
126
- ...i,
127
- displayName: String(e.value)
128
- };
129
- else if (t === "replace" && n === "" && e.value && typeof e.value == "object") {
130
- let t = e.value;
131
- "displayName" in t && (i = {
132
- ...i,
133
- displayName: String(t.displayName)
134
- }), "members" in t && (i = {
135
- ...i,
136
- members: [...r(t.members)]
137
- });
138
- }
139
- }
140
- return i;
141
- }, k = (e) => ({
142
- schemas: ["urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig"],
143
- documentationUri: "https://voltro.dev",
144
- patch: { supported: !0 },
145
- bulk: {
146
- supported: !1,
147
- maxOperations: 0,
148
- maxPayloadSize: 0
149
- },
150
- filter: {
151
- supported: !0,
152
- maxResults: 200
153
- },
154
- changePassword: { supported: !1 },
155
- sort: { supported: !1 },
156
- etag: { supported: !1 },
157
- authenticationSchemes: [{
158
- type: "oauthbearertoken",
159
- name: "Bearer token",
160
- description: "Static bearer token configured in the IdP SCIM settings"
161
- }],
162
- meta: {
163
- resourceType: "ServiceProviderConfig",
164
- location: e
165
- }
166
- }), A = (e, t = {}) => ({
167
- name: e,
168
- type: "string",
169
- multiValued: !1,
170
- required: !1,
171
- caseExact: !1,
172
- mutability: "readWrite",
173
- returned: "default",
174
- uniqueness: "none",
175
- ...t
176
- }), j = (e) => [{
177
- schemas: ["urn:ietf:params:scim:schemas:core:2.0:Schema"],
178
- id: m,
179
- name: "User",
180
- description: "SCIM core User",
181
- attributes: [
182
- A("userName", {
183
- required: !0,
184
- uniqueness: "server"
185
- }),
186
- A("name", {
187
- type: "complex",
188
- subAttributes: [A("givenName"), A("familyName")]
189
- }),
190
- A("emails", {
191
- type: "complex",
192
- multiValued: !0,
193
- subAttributes: [A("value"), A("primary", { type: "boolean" })]
194
- }),
195
- A("active", { type: "boolean" }),
196
- A("externalId")
197
- ],
198
- meta: {
199
- resourceType: "Schema",
200
- location: `${e}/${m}`
201
- }
202
- }, {
203
- schemas: ["urn:ietf:params:scim:schemas:core:2.0:Schema"],
204
- id: h,
205
- name: "Group",
206
- description: "SCIM core Group",
207
- attributes: [
208
- A("displayName", { required: !0 }),
209
- A("members", {
210
- type: "complex",
211
- multiValued: !0,
212
- subAttributes: [A("value")]
213
- }),
214
- A("externalId")
215
- ],
216
- meta: {
217
- resourceType: "Schema",
218
- location: `${e}/${h}`
219
- }
220
- }], M = (e) => [{
221
- schemas: ["urn:ietf:params:scim:schemas:core:2.0:ResourceType"],
222
- id: "User",
223
- name: "User",
224
- endpoint: "/Users",
225
- schema: m,
226
- meta: {
227
- resourceType: "ResourceType",
228
- location: `${e}/ResourceTypes/User`
229
- }
230
- }, {
231
- schemas: ["urn:ietf:params:scim:schemas:core:2.0:ResourceType"],
232
- id: "Group",
233
- name: "Group",
234
- endpoint: "/Groups",
235
- schema: h,
236
- meta: {
237
- resourceType: "ResourceType",
238
- location: `${e}/ResourceTypes/Group`
239
- }
240
- }], N = d("_voltro_scim_users", {
241
- id: c({ prefix: "scimuser" }),
242
- userName: f(),
243
- givenName: f().nullable(),
244
- familyName: f().nullable(),
245
- email: f().nullable(),
246
- active: a().default(!0),
247
- externalId: f().nullable(),
248
- createdAt: p().default("now"),
249
- updatedAt: p().default("now").onUpdate("now")
250
- }).renamedFrom("scim_users").unique("byScimUserName", ["userName"]), P = d("_voltro_scim_groups", {
251
- id: c({ prefix: "scimgroup" }),
252
- displayName: f(),
253
- externalId: f().nullable(),
254
- members: l().nullable(),
255
- createdAt: p().default("now"),
256
- updatedAt: p().default("now").onUpdate("now")
257
- }).renamedFrom("scim_groups"), F = (e) => {
258
- if (!Number.isSafeInteger(e.startIndex) || e.startIndex < 1 || !Number.isSafeInteger(e.count) || e.count < 0) throw RangeError("SCIM pages require a positive startIndex and a non-negative count, both safe integers");
259
- }, I = (e, t) => t === null || e[t.attribute] === t.value, L = (e = Date.now) => {
260
- let t = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map(), r = 0, i = 0, a = (e) => `${e}_${++r}`, o = (e) => {
261
- let t = -1, n = [];
262
- return (r, a) => {
263
- F(a), t !== i && (n = [...e.keys()].sort(), t = i);
264
- let o = [], s = 0;
265
- for (let t of n) {
266
- let n = e.get(t);
267
- I(n, r) && (s >= a.startIndex - 1 && o.length < a.count && o.push(n), s++);
268
- }
269
- return {
270
- rows: o,
271
- totalResults: s
272
- };
273
- };
274
- }, s = o(t), c = o(n);
275
- return {
276
- listUsers: async (e) => [...t.values()].filter((t) => I(t, e)),
277
- pageUsers: async (e, t) => s(e, t),
278
- getUser: async (e) => t.get(e) ?? null,
279
- createUser: async (n) => {
280
- let r = {
281
- ...n,
282
- id: a("user"),
283
- createdAt: e(),
284
- updatedAt: e()
285
- };
286
- return t.set(r.id, r), i++, r;
287
- },
288
- putUser: async (n, r) => {
289
- if (!t.has(n)) return null;
290
- let i = {
291
- ...r,
292
- id: n,
293
- updatedAt: e()
294
- };
295
- return t.set(n, i), i;
296
- },
297
- deleteUser: async (e) => {
298
- let n = t.delete(e);
299
- return n && i++, n;
300
- },
301
- listGroups: async (e) => [...n.values()].filter((t) => I(t, e)),
302
- pageGroups: async (e, t) => c(e, t),
303
- getGroup: async (e) => n.get(e) ?? null,
304
- createGroup: async (t) => {
305
- let r = {
306
- ...t,
307
- id: a("group"),
308
- createdAt: e(),
309
- updatedAt: e()
310
- };
311
- return n.set(r.id, r), i++, r;
312
- },
313
- putGroup: async (t, r) => {
314
- if (!n.has(t)) return null;
315
- let i = {
316
- ...r,
317
- id: t,
318
- updatedAt: e()
319
- };
320
- return n.set(t, i), i;
321
- },
322
- deleteGroup: async (e) => {
323
- let t = n.delete(e);
324
- return t && i++, t;
325
- }
326
- };
327
- }, R = (e) => {
328
- let t = async (t, n) => {
329
- let r = u(t);
330
- return e.query((n ? r.where(n) : r).descriptor);
331
- }, n = (e) => ({
332
- id: String(e.id),
333
- userName: String(e.userName),
334
- givenName: e.givenName ?? null,
335
- familyName: e.familyName ?? null,
336
- email: e.email ?? null,
337
- active: !!e.active,
338
- externalId: e.externalId ?? null,
339
- createdAt: r(e.createdAt),
340
- updatedAt: r(e.updatedAt)
341
- }), i = (e) => ({
342
- id: String(e.id),
343
- displayName: String(e.displayName),
344
- externalId: e.externalId ?? null,
345
- members: e.members ?? [],
346
- createdAt: r(e.createdAt),
347
- updatedAt: r(e.updatedAt)
348
- }), a = async (t, n, r, i) => {
349
- F(r);
350
- let a = u(t), s = n === null ? a : a.where(o(n.attribute, n.value)), [c, l] = await Promise.all([e.query(s.count().descriptor), r.count === 0 ? Promise.resolve([]) : e.query(s.orderBy("id", "asc").offset(r.startIndex - 1).limit(r.count).descriptor)]);
351
- return {
352
- rows: l.map(i),
353
- totalResults: Number(c[0]?.count ?? 0)
354
- };
355
- };
356
- return {
357
- listUsers: async (e) => (await t(N, e ? o(e.attribute, e.value) : void 0)).map(n),
358
- pageUsers: (e, t) => a(N, e, t, n),
359
- getUser: async (e) => {
360
- let r = await t(N, o("id", e));
361
- return r[0] ? n(r[0]) : null;
362
- },
363
- createUser: async (t) => {
364
- let n = s({
365
- kind: "typeid",
366
- prefix: "scimuser"
367
- }, "_voltro_scim_users"), r = /* @__PURE__ */ new Date(), i = {
368
- id: n,
369
- ...t,
370
- createdAt: r,
371
- updatedAt: r
372
- };
373
- return await e.insert("_voltro_scim_users", i), {
374
- ...t,
375
- id: n,
376
- createdAt: r.getTime(),
377
- updatedAt: r.getTime()
378
- };
379
- },
380
- putUser: async (n, r) => (await t(N, o("id", n)))[0] ? (await e.update("_voltro_scim_users", n, {
381
- userName: r.userName,
382
- givenName: r.givenName,
383
- familyName: r.familyName,
384
- email: r.email,
385
- active: r.active,
386
- externalId: r.externalId,
387
- updatedAt: /* @__PURE__ */ new Date()
388
- }), {
389
- ...r,
390
- id: n,
391
- updatedAt: Date.now()
392
- }) : null,
393
- deleteUser: async (n) => (await t(N, o("id", n)))[0] ? (await e.delete("_voltro_scim_users", n), !0) : !1,
394
- listGroups: async (e) => (await t(P, e ? o(e.attribute, e.value) : void 0)).map(i),
395
- pageGroups: (e, t) => a(P, e, t, i),
396
- getGroup: async (e) => {
397
- let n = await t(P, o("id", e));
398
- return n[0] ? i(n[0]) : null;
399
- },
400
- createGroup: async (t) => {
401
- let n = s({
402
- kind: "typeid",
403
- prefix: "scimgroup"
404
- }, "_voltro_scim_groups"), r = /* @__PURE__ */ new Date(), i = {
405
- id: n,
406
- ...t,
407
- createdAt: r,
408
- updatedAt: r
409
- };
410
- return await e.insert("_voltro_scim_groups", i), {
411
- ...t,
412
- id: n,
413
- createdAt: r.getTime(),
414
- updatedAt: r.getTime()
415
- };
416
- },
417
- putGroup: async (n, r) => (await t(P, o("id", n)))[0] ? (await e.update("_voltro_scim_groups", n, {
418
- displayName: r.displayName,
419
- externalId: r.externalId,
420
- members: r.members,
421
- updatedAt: /* @__PURE__ */ new Date()
422
- }), {
423
- ...r,
424
- id: n,
425
- updatedAt: Date.now()
426
- }) : null,
427
- deleteGroup: async (n) => (await t(P, o("id", n)))[0] ? (await e.delete("_voltro_scim_groups", n), !0) : !1
428
- };
429
- }, z = (e, t) => ({
1
+ import { SCIM_ERROR_SCHEMA as e, SCIM_GROUP_SCHEMA as t, SCIM_LIST_SCHEMA as n, SCIM_USER_SCHEMA as r, applyScimGroupPatch as i, applyScimPatch as a, fromScimUser as o, parsePagination as s, parseScimFilter as c, resourceTypes as l, scimError as u, scimList as d, scimSchemas as f, serviceProviderConfig as p, toScimUser as m } from "./scim.js";
2
+ import { dataStoreScimStore as h, memoryScimStore as g, scimGroupsTable as _, scimUsersTable as v } from "./store.js";
3
+ import { Effect as y } from "effect";
4
+ import { definePlugin as b, pluginInstanceName as x } from "@voltro/protocol";
5
+ import { checkBearer as S } from "@voltro/protocol/session";
6
+ //#region src/index.ts
7
+ var C = (e, t) => ({
430
8
  status: e,
431
9
  body: JSON.stringify(t),
432
10
  contentType: "application/scim+json"
433
- }), B = (e) => {
11
+ }), w = (e) => {
434
12
  try {
435
13
  return JSON.parse(new TextDecoder().decode(e.rawBody) || "{}");
436
14
  } catch {
437
15
  return {};
438
16
  }
439
- }, V = () => z(400, T(400, "unsupported filter — only `<attribute> eq \"value\"` on the indexed attributes", "invalidFilter")), H = async (e, t, n) => (await e.listUsers({
17
+ }, T = () => C(400, u(400, "unsupported filter — only `<attribute> eq \"value\"` on the indexed attributes", "invalidFilter")), E = async (e, t, n) => (await e.listUsers({
440
18
  attribute: "userName",
441
19
  value: t
442
- })).some((e) => e.id !== n), U = (e) => z(409, T(409, `a user with userName '${e}' already exists`, "uniqueness")), W = async (e, t, n, r) => {
443
- if (!i(r.headers, t)) return z(401, T(401, "invalid or missing bearer token"));
444
- let [, a, o] = r.path.slice(n.length).replace(/\/+$/, "").split("/"), s = r.method.toUpperCase(), c = new URLSearchParams(r.query), l = `${n}/Users`;
445
- if (s === "GET" && !o) {
446
- if (a === "ServiceProviderConfig") return z(200, k(`${n}/ServiceProviderConfig`));
447
- if (a === "Schemas") return z(200, w(j(`${n}/Schemas`)));
448
- if (a === "ResourceTypes") return z(200, w(M(n)));
20
+ })).some((e) => e.id !== n), D = (e) => C(409, u(409, `a user with userName '${e}' already exists`, "uniqueness")), O = async (e, t, n, r) => {
21
+ if (!S(r.headers, t)) return C(401, u(401, "invalid or missing bearer token"));
22
+ let [, h, g] = r.path.slice(n.length).replace(/\/+$/, "").split("/"), _ = r.method.toUpperCase(), v = new URLSearchParams(r.query), y = `${n}/Users`;
23
+ if (_ === "GET" && !g) {
24
+ if (h === "ServiceProviderConfig") return C(200, p(`${n}/ServiceProviderConfig`));
25
+ if (h === "Schemas") return C(200, d(f(`${n}/Schemas`)));
26
+ if (h === "ResourceTypes") return C(200, d(l(n)));
449
27
  }
450
- if (a === "Users") {
451
- if (s === "GET" && !o) {
452
- let t = E(c.get("filter"), ["userName", "externalId"]);
453
- if (t.kind === "invalid") return V();
454
- let { startIndex: n, count: r } = D(c), i = await e.pageUsers(t.kind === "filter" ? t : null, {
28
+ if (h === "Users") {
29
+ if (_ === "GET" && !g) {
30
+ let t = c(v.get("filter"), ["userName", "externalId"]);
31
+ if (t.kind === "invalid") return T();
32
+ let { startIndex: n, count: r } = s(v), i = await e.pageUsers(t.kind === "filter" ? t : null, {
455
33
  startIndex: n,
456
34
  count: Math.min(r ?? 100, 1e3)
457
35
  });
458
- return z(200, w(i.rows.map((e) => x(e, l)), {
36
+ return C(200, d(i.rows.map((e) => m(e, y)), {
459
37
  totalResults: i.totalResults,
460
38
  startIndex: n
461
39
  }));
462
40
  }
463
- if (s === "GET" && o) {
464
- let t = await e.getUser(o);
465
- return t ? z(200, x(t, l)) : z(404, T(404, "user not found"));
41
+ if (_ === "GET" && g) {
42
+ let t = await e.getUser(g);
43
+ return t ? C(200, m(t, y)) : C(404, u(404, "user not found"));
466
44
  }
467
- if (s === "POST" && !o) {
468
- let t = S(B(r));
469
- if (t.userName === "") return z(400, T(400, "userName is required", "invalidValue"));
470
- if (await H(e, t.userName)) return U(t.userName);
45
+ if (_ === "POST" && !g) {
46
+ let t = o(w(r));
47
+ if (t.userName === "") return C(400, u(400, "userName is required", "invalidValue"));
48
+ if (await E(e, t.userName)) return D(t.userName);
471
49
  try {
472
- return z(201, x(await e.createUser(t), l));
50
+ return C(201, m(await e.createUser(t), y));
473
51
  } catch (n) {
474
- if (await H(e, t.userName)) return U(t.userName);
52
+ if (await E(e, t.userName)) return D(t.userName);
475
53
  throw n;
476
54
  }
477
55
  }
478
- if (s === "PUT" && o) {
479
- let t = await e.getUser(o);
480
- if (!t) return z(404, T(404, "user not found"));
56
+ if (_ === "PUT" && g) {
57
+ let t = await e.getUser(g);
58
+ if (!t) return C(404, u(404, "user not found"));
481
59
  let n = {
482
60
  ...t,
483
- ...S(B(r))
61
+ ...o(w(r))
484
62
  };
485
- if (await H(e, n.userName, o)) return U(n.userName);
486
- let i = await e.putUser(o, n);
487
- return i ? z(200, x(i, l)) : z(404, T(404, "user not found"));
63
+ if (await E(e, n.userName, g)) return D(n.userName);
64
+ let i = await e.putUser(g, n);
65
+ return i ? C(200, m(i, y)) : C(404, u(404, "user not found"));
488
66
  }
489
- if (s === "PATCH" && o) {
490
- let t = await e.getUser(o);
491
- if (!t) return z(404, T(404, "user not found"));
492
- let n = C(t, B(r));
493
- if (n.userName !== t.userName && await H(e, n.userName, o)) return U(n.userName);
494
- let i = await e.putUser(o, n);
495
- return i ? z(200, x(i, l)) : z(404, T(404, "user not found"));
67
+ if (_ === "PATCH" && g) {
68
+ let t = await e.getUser(g);
69
+ if (!t) return C(404, u(404, "user not found"));
70
+ let n = a(t, w(r));
71
+ if (n.userName !== t.userName && await E(e, n.userName, g)) return D(n.userName);
72
+ let i = await e.putUser(g, n);
73
+ return i ? C(200, m(i, y)) : C(404, u(404, "user not found"));
496
74
  }
497
- if (s === "DELETE" && o) return await e.deleteUser(o) ? { status: 204 } : z(404, T(404, "user not found"));
75
+ if (_ === "DELETE" && g) return await e.deleteUser(g) ? { status: 204 } : C(404, u(404, "user not found"));
498
76
  }
499
- if (a === "Groups") {
500
- let t = `${n}/Groups`, i = (e) => ({
77
+ if (h === "Groups") {
78
+ let t = `${n}/Groups`, a = (e) => ({
501
79
  schemas: ["urn:ietf:params:scim:schemas:core:2.0:Group"],
502
80
  id: e.id,
503
81
  displayName: e.displayName,
@@ -508,76 +86,76 @@ var m = "urn:ietf:params:scim:schemas:core:2.0:User", h = "urn:ietf:params:scim:
508
86
  location: `${t}/${e.id}`
509
87
  }
510
88
  });
511
- if (s === "GET" && !o) {
512
- let t = E(c.get("filter"), ["displayName", "externalId"]);
513
- if (t.kind === "invalid") return V();
514
- let { startIndex: n, count: r } = D(c), a = await e.pageGroups(t.kind === "filter" ? t : null, {
89
+ if (_ === "GET" && !g) {
90
+ let t = c(v.get("filter"), ["displayName", "externalId"]);
91
+ if (t.kind === "invalid") return T();
92
+ let { startIndex: n, count: r } = s(v), i = await e.pageGroups(t.kind === "filter" ? t : null, {
515
93
  startIndex: n,
516
94
  count: Math.min(r ?? 100, 1e3)
517
95
  });
518
- return z(200, w(a.rows.map(i), {
519
- totalResults: a.totalResults,
96
+ return C(200, d(i.rows.map(a), {
97
+ totalResults: i.totalResults,
520
98
  startIndex: n
521
99
  }));
522
100
  }
523
- if (s === "GET" && o) {
524
- let t = await e.getGroup(o);
525
- return t ? z(200, i(t)) : z(404, T(404, "group not found"));
101
+ if (_ === "GET" && g) {
102
+ let t = await e.getGroup(g);
103
+ return t ? C(200, a(t)) : C(404, u(404, "group not found"));
526
104
  }
527
- if (s === "POST" && !o) {
528
- let t = B(r), n = (t.members ?? []).map((e) => String(e.value)).filter(Boolean);
529
- return z(201, i(await e.createGroup({
105
+ if (_ === "POST" && !g) {
106
+ let t = w(r), n = (t.members ?? []).map((e) => String(e.value)).filter(Boolean);
107
+ return C(201, a(await e.createGroup({
530
108
  displayName: String(t.displayName ?? ""),
531
109
  externalId: t.externalId ?? null,
532
110
  members: n
533
111
  })));
534
112
  }
535
- if (s === "PUT" && o) {
536
- let t = await e.getGroup(o);
537
- if (!t) return z(404, T(404, "group not found"));
538
- let n = B(r), a = (n.members ?? []).map((e) => String(e.value)).filter(Boolean), s = await e.putGroup(o, {
113
+ if (_ === "PUT" && g) {
114
+ let t = await e.getGroup(g);
115
+ if (!t) return C(404, u(404, "group not found"));
116
+ let n = w(r), i = (n.members ?? []).map((e) => String(e.value)).filter(Boolean), o = await e.putGroup(g, {
539
117
  ...t,
540
118
  displayName: String(n.displayName ?? t.displayName),
541
119
  externalId: n.externalId ?? t.externalId,
542
- members: a
120
+ members: i
543
121
  });
544
- return s ? z(200, i(s)) : z(404, T(404, "group not found"));
122
+ return o ? C(200, a(o)) : C(404, u(404, "group not found"));
545
123
  }
546
- if (s === "PATCH" && o) {
547
- let t = await e.getGroup(o);
548
- if (!t) return z(404, T(404, "group not found"));
549
- let n = await e.putGroup(o, O(t, B(r)));
550
- return n ? z(200, i(n)) : z(404, T(404, "group not found"));
124
+ if (_ === "PATCH" && g) {
125
+ let t = await e.getGroup(g);
126
+ if (!t) return C(404, u(404, "group not found"));
127
+ let n = await e.putGroup(g, i(t, w(r)));
128
+ return n ? C(200, a(n)) : C(404, u(404, "group not found"));
551
129
  }
552
- if (s === "DELETE" && o) return await e.deleteGroup(o) ? { status: 204 } : z(404, T(404, "group not found"));
130
+ if (_ === "DELETE" && g) return await e.deleteGroup(g) ? { status: 204 } : C(404, u(404, "group not found"));
553
131
  }
554
- return z(404, T(404, "unsupported SCIM endpoint"));
555
- }, G = "@voltro/plugin-scim", K = (r) => {
556
- if (r.token.trim() === "") throw Error("scimPlugin({ token }) requires a non-empty bearer token — got an empty string. SCIM exposes the full user + group directory and can deactivate accounts, so it is never mounted ungated. Set the environment variable your IdP presents (e.g. SCIM_TOKEN) and pass it through, or remove scimPlugin() from the plugin list.");
557
- let i = r.basePath ?? "/scim/v2", a = n({
558
- base: G,
559
- alias: r.alias,
560
- instance: r.name
561
- }), o;
562
- return t({
563
- name: a,
564
- baseName: G,
132
+ return C(404, u(404, "unsupported SCIM endpoint"));
133
+ }, k = "@voltro/plugin-scim", A = (e) => {
134
+ if (e.token.trim() === "") throw Error("scimPlugin({ token }) requires a non-empty bearer token — got an empty string. SCIM exposes the full user + group directory and can deactivate accounts, so it is never mounted ungated. Set the environment variable your IdP presents (e.g. SCIM_TOKEN) and pass it through, or remove scimPlugin() from the plugin list.");
135
+ let t = e.basePath ?? "/scim/v2", n = x({
136
+ base: k,
137
+ alias: e.alias,
138
+ instance: e.name
139
+ }), r;
140
+ return b({
141
+ name: n,
142
+ baseName: k,
565
143
  description: "SCIM 2.0 Users + Groups provisioning endpoints.",
566
144
  permissions: ["store:write"],
567
- extendSchema: { tables: [N, P] },
145
+ extendSchema: { tables: [v, _] },
568
146
  httpRoutes: [{
569
147
  method: "*",
570
- path: i,
148
+ path: t,
571
149
  originGuard: "exempt",
572
- handle: async (e) => o ? W(o, r.token, i, e) : z(503, T(503, "scim store not bound"))
150
+ handle: async (n) => r ? O(r, e.token, t, n) : C(503, u(503, "scim store not bound"))
573
151
  }],
574
152
  bindDataStore: (e) => {
575
- o = R(e);
153
+ r = h(e);
576
154
  },
577
- onActivate: (t) => e.sync(() => {
578
- t.logger.info("scim active", { basePath: i });
155
+ onActivate: (e) => y.sync(() => {
156
+ e.logger.info("scim active", { basePath: t });
579
157
  })
580
158
  });
581
159
  };
582
160
  //#endregion
583
- export { _ as SCIM_ERROR_SCHEMA, h as SCIM_GROUP_SCHEMA, g as SCIM_LIST_SCHEMA, m as SCIM_USER_SCHEMA, O as applyScimGroupPatch, C as applyScimPatch, R as dataStoreScimStore, S as fromScimUser, W as handleScim, W as handleScimRequest, L as memoryScimStore, D as parsePagination, E as parseScimFilter, M as resourceTypes, T as scimError, w as scimList, K as scimPlugin, j as scimSchemas, k as serviceProviderConfig, x as toScimUser };
161
+ export { e as SCIM_ERROR_SCHEMA, t as SCIM_GROUP_SCHEMA, n as SCIM_LIST_SCHEMA, r as SCIM_USER_SCHEMA, i as applyScimGroupPatch, a as applyScimPatch, h as dataStoreScimStore, o as fromScimUser, O as handleScim, O as handleScimRequest, g as memoryScimStore, s as parsePagination, c as parseScimFilter, l as resourceTypes, u as scimError, _ as scimGroupsTable, d as scimList, A as scimPlugin, f as scimSchemas, v as scimUsersTable, p as serviceProviderConfig, m as toScimUser };