@thunderid/node 1.3.1 → 1.5.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.
@@ -1,5 +1,6 @@
1
1
  import { BackchannelLogoutResult, ExtendedAuthorizeRequestUrlParams, IdToken, ManagedFlowListResponse, ManagedUserListResponse, ManagedUserTypeListResponse, OIDCEndpoints, Storage, ThunderIDJavaScriptClient, TokenExchangeRequestConfig, TokenResponse, User } from '@thunderid/javascript';
2
2
  import { ThunderIDNodeConfig } from './models/config';
3
+ import { ThunderIDNodeManagementClient } from './models/management';
3
4
  declare class ThunderIDNodeClient<T extends ThunderIDNodeConfig = ThunderIDNodeConfig> extends ThunderIDJavaScriptClient<T> {
4
5
  private _nodeInstanceId;
5
6
  private _handledLogoutTokens;
@@ -74,6 +75,38 @@ declare class ThunderIDNodeClient<T extends ThunderIDNodeConfig = ThunderIDNodeC
74
75
  * `userId`. The access token stays on the server.
75
76
  */
76
77
  private managementRequestConfig;
78
+ /**
79
+ * Returns the management operations (users, groups, roles, agents, and their sub-resources) bound
80
+ * to the session identified by `sessionId`.
81
+ *
82
+ * Every request is authorized with that session's access token, read at the time of each call; the
83
+ * token is never copied onto the returned object or exposed to the caller. Whether a call succeeds
84
+ * is the server's decision: the token needs the permissions the server requires for that resource.
85
+ *
86
+ * The collection URL comes from, in order: the `url` passed to the call, then `endpoints.<resource>`
87
+ * in the configuration, then `{baseUrl}/{collection}`.
88
+ *
89
+ * @param sessionId - The session whose access token authorizes the requests.
90
+ * @returns The session-bound management client.
91
+ * @throws {ThunderIDRuntimeError} `NODE-MANAGEMENT-RC-NF01`, from an operation, when the session
92
+ * has no access token. Raised before any request is sent.
93
+ * @throws {ThunderIDAPIError} From an operation, when the server rejects the request. HTTP 403 and
94
+ * 404 surface as `<operation>-ForbiddenError-001` and `<operation>-NotFoundError-001`.
95
+ *
96
+ * @example
97
+ * ```typescript
98
+ * const admin = client.management(sessionId);
99
+ * const {users, totalResults} = await admin.users.list({limit: 20});
100
+ * await admin.groups.addMembers(groupId, [{id: users[0].id, type: 'user'}]);
101
+ * ```
102
+ */
103
+ management(sessionId?: string): ThunderIDNodeManagementClient;
104
+ /**
105
+ * The URL inputs and bearer token for a management request made through {@link management}. Unlike
106
+ * {@link managementRequestConfig}, a session without an access token is refused here rather than
107
+ * sent to the server with an empty credential.
108
+ */
109
+ private sessionManagementRequestConfig;
77
110
  /**
78
111
  * Retrieves one page of the user directory on behalf of the session identified by `userId`.
79
112
  *
@@ -1 +1 @@
1
- {"version":3,"file":"ThunderIDNodeClient.d.ts","sourceRoot":"","sources":["../src/ThunderIDNodeClient.ts"],"names":[],"mappings":"AAGA,OAAO,EAGL,uBAAuB,EACvB,iCAAiC,EAIjC,OAAO,EAIP,uBAAuB,EACvB,uBAAuB,EACvB,2BAA2B,EAC3B,aAAa,EAGb,OAAO,EAEP,yBAAyB,EACzB,0BAA0B,EAC1B,aAAa,EAEb,IAAI,EACL,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAC,mBAAmB,EAAC,MAAM,iBAAiB,CAAC;AAKpD,cAAM,mBAAmB,CAAC,CAAC,SAAS,mBAAmB,GAAG,mBAAmB,CAAE,SAAQ,yBAAyB,CAAC,CAAC,CAAC;IACjH,OAAO,CAAC,eAAe,CAAK;IAG5B,OAAO,CAAC,oBAAoB,CAAkD;IAG9E,OAAO,CAAC,kBAAkB,CAGtB;gBAEe,UAAU,SAAI;IAKX,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAMhE,aAAa,IAAI,MAAM;IAIjB,MAAM,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC;IAsE9C,YAAY,CAChC,aAAa,CAAC,EAAE,iCAAiC,EACjD,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,CAAC;IAcI,OAAO,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAe9D;;;;;;;;;;;;;OAaG;IACU,uBAAuB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAsD3F;;;;;OAKG;YACW,aAAa;IAYX,YAAY,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI;cAI7B,iBAAiB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK7E;;;OAGG;YACW,YAAY;YAYZ,kBAAkB;IAgBhC;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAezB,OAAO,CAAC,eAAe;IAIvB;;;;OAIG;IACmB,UAAU,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAkC7C,UAAU,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAalE;;;OAGG;IACmB,kBAAkB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAsBlE,iBAAiB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,OAAO,CAAC;IAO/D,iBAAiB,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAItE,cAAc,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIhD,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvC,0BAA0B,IAAI,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IAI7D,aAAa,CACjC,MAAM,EAAE,0BAA0B,EAClC,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,aAAa,GAAG,QAAQ,GAAG,IAAI,CAAC;IAI3C;;;OAGG;IACU,qBAAqB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAcnG;;;OAGG;YACW,uBAAuB;IAerC;;;;OAIG;IACU,QAAQ,CACnB,OAAO,GAAE;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAM,EACtF,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,uBAAuB,CAAC;IAInC;;;;OAIG;IACU,QAAQ,CACnB,OAAO,GAAE;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAM,EACxF,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,uBAAuB,CAAC;IAInC;;;;OAIG;IACU,YAAY,CACvB,OAAO,GAAE;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAM,EACrE,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,2BAA2B,CAAC;CAGxC;AAED,eAAe,mBAAmB,CAAC"}
1
+ {"version":3,"file":"ThunderIDNodeClient.d.ts","sourceRoot":"","sources":["../src/ThunderIDNodeClient.ts"],"names":[],"mappings":"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"}
@@ -58,6 +58,202 @@ var MemoryCacheStore = class {
58
58
  };
59
59
  var MemoryCacheStore_default = MemoryCacheStore;
60
60
 
61
+ //#endregion
62
+ //#region src/utils/createManagementClient.ts
63
+ /**
64
+ * Rejects a missing or blank resource identifier before any request is made. The core API functions
65
+ * reject a blank string, but an `undefined` identifier would otherwise address the whole collection,
66
+ * which for a delete or update is never what the caller meant. Uses the same code the core raises.
67
+ */
68
+ const requireId = (id, operation) => {
69
+ if (typeof id !== "string" || id.trim() === "") throw new __thunderid_javascript.ThunderIDAPIError("A resource identifier is required.", `${operation}-ValidationError-002`, "node", 400, "The provided resource identifier is empty.");
70
+ return id;
71
+ };
72
+ /**
73
+ * Builds the server-side management client for one session.
74
+ *
75
+ * Each operation resolves its request config through `resolve` at call time, so the access token is
76
+ * read fresh for every request and never held by the returned object.
77
+ *
78
+ * @param resolve - Supplies the base URL, collection URL, and `Authorization` header for a request.
79
+ * @returns The session-bound management operations.
80
+ */
81
+ const createManagementClient = (resolve) => {
82
+ const config = async (key, { fetcher, signal, url } = {}) => ({
83
+ ...fetcher ? { fetcher } : {},
84
+ ...signal ? { signal } : {},
85
+ ...await resolve(key, url)
86
+ });
87
+ return {
88
+ agentTypes: { list: async ({ limit, offset,...options } = {}) => (0, __thunderid_javascript.getAgentTypes)({
89
+ limit,
90
+ offset,
91
+ ...await config("agentTypes", options)
92
+ }) },
93
+ agents: {
94
+ create: async (payload, options) => (0, __thunderid_javascript.createAgent)({
95
+ payload,
96
+ ...await config("agents", options)
97
+ }),
98
+ delete: async (agentId, options) => (0, __thunderid_javascript.deleteAgent)({
99
+ agentId: requireId(agentId, "deleteAgent"),
100
+ ...await config("agents", options)
101
+ }),
102
+ get: async (agentId, options) => (0, __thunderid_javascript.getAgent)({
103
+ agentId: requireId(agentId, "getAgent"),
104
+ ...await config("agents", options)
105
+ }),
106
+ list: async ({ filter, limit, offset,...options } = {}) => (0, __thunderid_javascript.getAgents)({
107
+ filter,
108
+ limit,
109
+ offset,
110
+ ...await config("agents", options)
111
+ }),
112
+ listGroups: async (agentId, { limit, offset,...options } = {}) => (0, __thunderid_javascript.getAgentGroups)({
113
+ agentId: requireId(agentId, "getAgentGroups"),
114
+ limit,
115
+ offset,
116
+ ...await config("agents", options)
117
+ }),
118
+ listRoles: async (agentId, { limit, offset,...options } = {}) => (0, __thunderid_javascript.getAgentRoles)({
119
+ agentId: requireId(agentId, "getAgentRoles"),
120
+ limit,
121
+ offset,
122
+ ...await config("agents", options)
123
+ }),
124
+ update: async (agentId, payload, options) => (0, __thunderid_javascript.updateAgent)({
125
+ agentId: requireId(agentId, "updateAgent"),
126
+ payload,
127
+ ...await config("agents", options)
128
+ })
129
+ },
130
+ flows: { list: async ({ flowType, limit, offset,...options } = {}) => (0, __thunderid_javascript.getFlows)({
131
+ flowType,
132
+ limit,
133
+ offset,
134
+ ...await config("flows", options)
135
+ }) },
136
+ groups: {
137
+ addMembers: async (groupId, members, options) => (0, __thunderid_javascript.addGroupMembers)({
138
+ groupId: requireId(groupId, "addGroupMembers"),
139
+ members,
140
+ ...await config("groups", options)
141
+ }),
142
+ create: async (payload, options) => (0, __thunderid_javascript.createGroup)({
143
+ payload,
144
+ ...await config("groups", options)
145
+ }),
146
+ delete: async (groupId, options) => (0, __thunderid_javascript.deleteGroup)({
147
+ groupId: requireId(groupId, "deleteGroup"),
148
+ ...await config("groups", options)
149
+ }),
150
+ get: async (groupId, options) => (0, __thunderid_javascript.getGroup)({
151
+ groupId: requireId(groupId, "getGroup"),
152
+ ...await config("groups", options)
153
+ }),
154
+ list: async ({ limit, offset,...options } = {}) => (0, __thunderid_javascript.getGroups)({
155
+ limit,
156
+ offset,
157
+ ...await config("groups", options)
158
+ }),
159
+ listMembers: async (groupId, { limit, offset,...options } = {}) => (0, __thunderid_javascript.getGroupMembers)({
160
+ groupId: requireId(groupId, "getGroupMembers"),
161
+ limit,
162
+ offset,
163
+ ...await config("groups", options)
164
+ }),
165
+ removeMembers: async (groupId, members, options) => (0, __thunderid_javascript.removeGroupMembers)({
166
+ groupId: requireId(groupId, "removeGroupMembers"),
167
+ members,
168
+ ...await config("groups", options)
169
+ }),
170
+ update: async (groupId, payload, options) => (0, __thunderid_javascript.updateGroup)({
171
+ groupId: requireId(groupId, "updateGroup"),
172
+ payload,
173
+ ...await config("groups", options)
174
+ })
175
+ },
176
+ roles: {
177
+ addAssignments: async (roleId, assignments, options) => (0, __thunderid_javascript.addRoleAssignments)({
178
+ assignments,
179
+ roleId: requireId(roleId, "addRoleAssignments"),
180
+ ...await config("roles", options)
181
+ }),
182
+ create: async (payload, options) => (0, __thunderid_javascript.createRole)({
183
+ payload,
184
+ ...await config("roles", options)
185
+ }),
186
+ delete: async (roleId, options) => (0, __thunderid_javascript.deleteRole)({
187
+ roleId: requireId(roleId, "deleteRole"),
188
+ ...await config("roles", options)
189
+ }),
190
+ get: async (roleId, options) => (0, __thunderid_javascript.getRole)({
191
+ roleId: requireId(roleId, "getRole"),
192
+ ...await config("roles", options)
193
+ }),
194
+ list: async ({ limit, offset,...options } = {}) => (0, __thunderid_javascript.getRoles)({
195
+ limit,
196
+ offset,
197
+ ...await config("roles", options)
198
+ }),
199
+ listAssignments: async (roleId, { limit, offset, type,...options } = {}) => (0, __thunderid_javascript.getRoleAssignments)({
200
+ limit,
201
+ offset,
202
+ roleId: requireId(roleId, "getRoleAssignments"),
203
+ type,
204
+ ...await config("roles", options)
205
+ }),
206
+ removeAssignments: async (roleId, assignments, options) => (0, __thunderid_javascript.removeRoleAssignments)({
207
+ assignments,
208
+ roleId: requireId(roleId, "removeRoleAssignments"),
209
+ ...await config("roles", options)
210
+ }),
211
+ update: async (roleId, payload, options) => (0, __thunderid_javascript.updateRole)({
212
+ payload,
213
+ roleId: requireId(roleId, "updateRole"),
214
+ ...await config("roles", options)
215
+ })
216
+ },
217
+ userTypes: { list: async ({ limit, offset,...options } = {}) => (0, __thunderid_javascript.getUserTypes)({
218
+ limit,
219
+ offset,
220
+ ...await config("userTypes", options)
221
+ }) },
222
+ users: {
223
+ create: async (payload, options) => (0, __thunderid_javascript.createUser)({
224
+ payload,
225
+ ...await config("users", options)
226
+ }),
227
+ delete: async (userId, options) => (0, __thunderid_javascript.deleteUser)({
228
+ userId: requireId(userId, "deleteUser"),
229
+ ...await config("users", options)
230
+ }),
231
+ get: async (userId, options) => (0, __thunderid_javascript.getUser)({
232
+ userId: requireId(userId, "getUser"),
233
+ ...await config("users", options)
234
+ }),
235
+ list: async ({ filter, limit, offset,...options } = {}) => (0, __thunderid_javascript.getUsers)({
236
+ filter,
237
+ limit,
238
+ offset,
239
+ ...await config("users", options)
240
+ }),
241
+ listGroups: async (userId, { limit, offset,...options } = {}) => (0, __thunderid_javascript.getUserGroups)({
242
+ limit,
243
+ offset,
244
+ userId: requireId(userId, "getUserGroups"),
245
+ ...await config("users", options)
246
+ }),
247
+ update: async (userId, payload, options) => (0, __thunderid_javascript.updateUser)({
248
+ payload,
249
+ userId: requireId(userId, "updateUser"),
250
+ ...await config("users", options)
251
+ })
252
+ }
253
+ };
254
+ };
255
+ var createManagementClient_default = createManagementClient;
256
+
61
257
  //#endregion
62
258
  //#region src/utils/NodeCryptoUtils.ts
63
259
  /**
@@ -437,6 +633,49 @@ var ThunderIDNodeClient = class extends __thunderid_javascript.ThunderIDJavaScri
437
633
  };
438
634
  }
439
635
  /**
636
+ * Returns the management operations (users, groups, roles, agents, and their sub-resources) bound
637
+ * to the session identified by `sessionId`.
638
+ *
639
+ * Every request is authorized with that session's access token, read at the time of each call; the
640
+ * token is never copied onto the returned object or exposed to the caller. Whether a call succeeds
641
+ * is the server's decision: the token needs the permissions the server requires for that resource.
642
+ *
643
+ * The collection URL comes from, in order: the `url` passed to the call, then `endpoints.<resource>`
644
+ * in the configuration, then `{baseUrl}/{collection}`.
645
+ *
646
+ * @param sessionId - The session whose access token authorizes the requests.
647
+ * @returns The session-bound management client.
648
+ * @throws {ThunderIDRuntimeError} `NODE-MANAGEMENT-RC-NF01`, from an operation, when the session
649
+ * has no access token. Raised before any request is sent.
650
+ * @throws {ThunderIDAPIError} From an operation, when the server rejects the request. HTTP 403 and
651
+ * 404 surface as `<operation>-ForbiddenError-001` and `<operation>-NotFoundError-001`.
652
+ *
653
+ * @example
654
+ * ```typescript
655
+ * const admin = client.management(sessionId);
656
+ * const {users, totalResults} = await admin.users.list({limit: 20});
657
+ * await admin.groups.addMembers(groupId, [{id: users[0].id, type: 'user'}]);
658
+ * ```
659
+ */
660
+ management(sessionId) {
661
+ return createManagementClient_default((key, explicitUrl) => this.sessionManagementRequestConfig(key, sessionId, explicitUrl));
662
+ }
663
+ /**
664
+ * The URL inputs and bearer token for a management request made through {@link management}. Unlike
665
+ * {@link managementRequestConfig}, a session without an access token is refused here rather than
666
+ * sent to the server with an empty credential.
667
+ */
668
+ async sessionManagementRequestConfig(key, sessionId, explicitUrl) {
669
+ const configData = await this.getStorageManager().getConfigData();
670
+ const accessToken = await this.getAccessToken(sessionId);
671
+ if (!accessToken) throw new __thunderid_javascript.ThunderIDRuntimeError("No access token is available for the session. Sign in before calling a management operation.", "NODE-MANAGEMENT-RC-NF01", "node");
672
+ return {
673
+ baseUrl: configData?.baseUrl,
674
+ headers: { Authorization: `Bearer ${accessToken}` },
675
+ url: (0, __thunderid_javascript.resolveResourceEndpoint)(key, configData, explicitUrl)
676
+ };
677
+ }
678
+ /**
440
679
  * Retrieves one page of the user directory on behalf of the session identified by `userId`.
441
680
  *
442
681
  * Makes a single request and does not follow `links`. The access token stays on the server.
@@ -715,6 +954,64 @@ var LoggedOutSessions_default = LoggedOutSessions;
715
954
  const generateSessionId = () => (/* @__PURE__ */ new Date()).getTime().toString(36) + Math.random().toString(36).substring(2);
716
955
  var generateSessionId_default = generateSessionId;
717
956
 
957
+ //#endregion
958
+ //#region src/utils/managementCollections.ts
959
+ /**
960
+ * The management collections a browser may reach through a server-side management relay, keyed by
961
+ * their `endpoints` override key, with the path each one has under `baseUrl`.
962
+ */
963
+ const MANAGEMENT_COLLECTIONS = {
964
+ agentTypes: "agent-types",
965
+ agents: "agents",
966
+ groups: "groups",
967
+ roles: "roles",
968
+ userTypes: "user-types",
969
+ users: "users"
970
+ };
971
+ const MANAGEMENT_COLLECTION_KEYS = Object.keys(MANAGEMENT_COLLECTIONS);
972
+ /**
973
+ * The collection URLs a management request may target for this configuration: each collection's
974
+ * `endpoints` override, or `{baseUrl}/{path}` and the organization-scoped `{baseUrl}/o/{path}`.
975
+ */
976
+ const getManagementCollectionUrls = (config) => {
977
+ const urls = [];
978
+ const baseUrl = config?.baseUrl?.replace(/\/+$/, "");
979
+ MANAGEMENT_COLLECTION_KEYS.forEach((key) => {
980
+ const override = (0, __thunderid_javascript.resolveResourceEndpoint)(key, config);
981
+ (override ? [override] : baseUrl ? [`${baseUrl}/${MANAGEMENT_COLLECTIONS[key]}`, `${baseUrl}/o/${MANAGEMENT_COLLECTIONS[key]}`] : []).forEach((candidate) => {
982
+ try {
983
+ urls.push(new URL(candidate.replace(/\/+$/, "")));
984
+ } catch {}
985
+ });
986
+ });
987
+ return urls;
988
+ };
989
+ /**
990
+ * Whether `target` addresses one of the management collections, or a resource or sub-resource under
991
+ * one. The comparison runs on the parsed URL, so dot segments are resolved before it, and an
992
+ * encoded slash, backslash or dot, which an upstream could decode into a different path, is refused.
993
+ *
994
+ * @param target - The absolute URL the browser asked for.
995
+ * @param collections - The allowed collection URLs, from {@link getManagementCollectionUrls}.
996
+ * @returns The parsed URL when it is allowed, otherwise `undefined`.
997
+ */
998
+ const matchManagementUrl = (target, collections) => {
999
+ if (typeof target !== "string" || target.length > 4096) return;
1000
+ let url;
1001
+ try {
1002
+ url = new URL(target);
1003
+ } catch {
1004
+ return;
1005
+ }
1006
+ if (url.protocol !== "https:" && url.protocol !== "http:" || url.username || url.password || url.hash) return;
1007
+ if (/%(2e|2f|5c)/i.test(url.pathname)) return;
1008
+ return collections.some((collection) => {
1009
+ if (collection.origin !== url.origin) return false;
1010
+ const base = collection.pathname.replace(/\/+$/, "");
1011
+ return url.pathname === base || url.pathname.startsWith(`${base}/`);
1012
+ }) ? url : void 0;
1013
+ };
1014
+
718
1015
  //#endregion
719
1016
  //#region src/utils/getSessionCookieOptions.ts
720
1017
  const getSessionCookieOptions = (options) => ({
@@ -738,13 +1035,18 @@ exports.CookieChunking = CookieChunking_default;
738
1035
  exports.CookieConfig = CookieConfig_default;
739
1036
  exports.InMemoryLogoutRecordStore = InMemoryLogoutRecordStore;
740
1037
  exports.LoggedOutSessions = LoggedOutSessions_default;
1038
+ exports.MANAGEMENT_COLLECTIONS = MANAGEMENT_COLLECTIONS;
1039
+ exports.MANAGEMENT_COLLECTION_KEYS = MANAGEMENT_COLLECTION_KEYS;
741
1040
  exports.MemoryCacheStore = MemoryCacheStore_default;
742
1041
  exports.NodeCryptoUtils = NodeCryptoUtils_default;
743
1042
  exports.SessionIndex = SessionIndex_default;
744
1043
  exports.SessionUtils = SessionUtils_default;
745
1044
  exports.ThunderIDNodeClient = ThunderIDNodeClient_default;
1045
+ exports.createManagementClient = createManagementClient_default;
746
1046
  exports.generateSessionId = generateSessionId_default;
1047
+ exports.getManagementCollectionUrls = getManagementCollectionUrls;
747
1048
  exports.getSessionCookieOptions = getSessionCookieOptions_default;
1049
+ exports.matchManagementUrl = matchManagementUrl;
748
1050
  Object.keys(__thunderid_javascript).forEach(function (k) {
749
1051
  if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
750
1052
  enumerable: true,
package/dist/index.d.ts CHANGED
@@ -5,6 +5,7 @@ export { default as ThunderIDNodeClient } from './ThunderIDNodeClient';
5
5
  export { default as CookieConfig } from './constants/CookieConfig';
6
6
  export type { ThunderIDNodeConfig, SessionCookieConfig } from './models/config';
7
7
  export type { default as AuthURLCallback } from './models/AuthURLCallback';
8
+ export type { ManagementCallOptions, ManagementGroupMemberInput, ManagementListOptions, ManagementRequestConfigResolver, ManagementResourceKey, ThunderIDNodeManagementClient, } from './models/management';
8
9
  export { default as MemoryCacheStore } from './stores/MemoryCacheStore';
9
10
  export { default as CookieChunking } from './utils/CookieChunking';
10
11
  export { default as NodeCryptoUtils } from './utils/NodeCryptoUtils';
@@ -14,6 +15,8 @@ export { default as LoggedOutSessions, InMemoryLogoutRecordStore } from './utils
14
15
  export type { LogoutRecordStore, PresentedSession } from './utils/LoggedOutSessions';
15
16
  export type { IndexedSessions, SessionBinding } from './utils/SessionIndex';
16
17
  export { default as generateSessionId } from './utils/generateSessionId';
18
+ export { default as createManagementClient } from './utils/createManagementClient';
19
+ export { MANAGEMENT_COLLECTIONS, MANAGEMENT_COLLECTION_KEYS, getManagementCollectionUrls, matchManagementUrl, type ManagementCollectionKey, } from './utils/managementCollections';
17
20
  export { default as getSessionCookieOptions } from './utils/getSessionCookieOptions';
18
21
  export * from '@thunderid/javascript';
19
22
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA;;GAEG;AAGH,OAAO,EAAC,OAAO,IAAI,mBAAmB,EAAC,MAAM,uBAAuB,CAAC;AAGrE,OAAO,EAAC,OAAO,IAAI,YAAY,EAAC,MAAM,0BAA0B,CAAC;AAGjE,YAAY,EAAC,mBAAmB,EAAE,mBAAmB,EAAC,MAAM,iBAAiB,CAAC;AAC9E,YAAY,EAAC,OAAO,IAAI,eAAe,EAAC,MAAM,0BAA0B,CAAC;AAGzE,OAAO,EAAC,OAAO,IAAI,gBAAgB,EAAC,MAAM,2BAA2B,CAAC;AAGtE,OAAO,EAAC,OAAO,IAAI,cAAc,EAAC,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAC,OAAO,IAAI,eAAe,EAAC,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAC,OAAO,IAAI,YAAY,EAAC,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAC,OAAO,IAAI,YAAY,EAAC,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAC,OAAO,IAAI,iBAAiB,EAAE,yBAAyB,EAAC,MAAM,2BAA2B,CAAC;AAClG,YAAY,EAAC,iBAAiB,EAAE,gBAAgB,EAAC,MAAM,2BAA2B,CAAC;AACnF,YAAY,EAAC,eAAe,EAAE,cAAc,EAAC,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAC,OAAO,IAAI,iBAAiB,EAAC,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAC,OAAO,IAAI,uBAAuB,EAAC,MAAM,iCAAiC,CAAC;AAGnF,cAAc,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA;;GAEG;AAGH,OAAO,EAAC,OAAO,IAAI,mBAAmB,EAAC,MAAM,uBAAuB,CAAC;AAGrE,OAAO,EAAC,OAAO,IAAI,YAAY,EAAC,MAAM,0BAA0B,CAAC;AAGjE,YAAY,EAAC,mBAAmB,EAAE,mBAAmB,EAAC,MAAM,iBAAiB,CAAC;AAC9E,YAAY,EAAC,OAAO,IAAI,eAAe,EAAC,MAAM,0BAA0B,CAAC;AACzE,YAAY,EACV,qBAAqB,EACrB,0BAA0B,EAC1B,qBAAqB,EACrB,+BAA+B,EAC/B,qBAAqB,EACrB,6BAA6B,GAC9B,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAC,OAAO,IAAI,gBAAgB,EAAC,MAAM,2BAA2B,CAAC;AAGtE,OAAO,EAAC,OAAO,IAAI,cAAc,EAAC,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAC,OAAO,IAAI,eAAe,EAAC,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAC,OAAO,IAAI,YAAY,EAAC,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAC,OAAO,IAAI,YAAY,EAAC,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAC,OAAO,IAAI,iBAAiB,EAAE,yBAAyB,EAAC,MAAM,2BAA2B,CAAC;AAClG,YAAY,EAAC,iBAAiB,EAAE,gBAAgB,EAAC,MAAM,2BAA2B,CAAC;AACnF,YAAY,EAAC,eAAe,EAAE,cAAc,EAAC,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAC,OAAO,IAAI,iBAAiB,EAAC,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAC,OAAO,IAAI,sBAAsB,EAAC,MAAM,gCAAgC,CAAC;AACjF,OAAO,EACL,sBAAsB,EACtB,0BAA0B,EAC1B,2BAA2B,EAC3B,kBAAkB,EAClB,KAAK,uBAAuB,GAC7B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAC,OAAO,IAAI,uBAAuB,EAAC,MAAM,iCAAiC,CAAC;AAGnF,cAAc,uBAAuB,CAAC"}
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import fetch, { Headers, Request, Response } from "cross-fetch";
2
- import { BackchannelLogoutConstants, InvalidLogoutTokenError, ThunderIDAuthException, ThunderIDJavaScriptClient, getFlows, getUserTypes, getUsers, getVendorPrefix, logger, resolveResourceEndpoint, updateMeCredentials } from "@thunderid/javascript";
2
+ import { BackchannelLogoutConstants, InvalidLogoutTokenError, ThunderIDAPIError, ThunderIDAuthException, ThunderIDJavaScriptClient, ThunderIDRuntimeError, addGroupMembers, addRoleAssignments, createAgent, createGroup, createRole, createUser, deleteAgent, deleteGroup, deleteRole, deleteUser, getAgent, getAgentGroups, getAgentRoles, getAgentTypes, getAgents, getFlows, getGroup, getGroupMembers, getGroups, getRole, getRoleAssignments, getRoles, getUser, getUserGroups, getUserTypes, getUsers, getVendorPrefix, logger, removeGroupMembers, removeRoleAssignments, resolveResourceEndpoint, updateAgent, updateGroup, updateMeCredentials, updateRole, updateUser } from "@thunderid/javascript";
3
3
  import cache from "memory-cache";
4
4
  import base64url from "base64url";
5
5
  import sha256 from "fast-sha256";
@@ -28,6 +28,202 @@ var MemoryCacheStore = class {
28
28
  };
29
29
  var MemoryCacheStore_default = MemoryCacheStore;
30
30
 
31
+ //#endregion
32
+ //#region src/utils/createManagementClient.ts
33
+ /**
34
+ * Rejects a missing or blank resource identifier before any request is made. The core API functions
35
+ * reject a blank string, but an `undefined` identifier would otherwise address the whole collection,
36
+ * which for a delete or update is never what the caller meant. Uses the same code the core raises.
37
+ */
38
+ const requireId = (id, operation) => {
39
+ if (typeof id !== "string" || id.trim() === "") throw new ThunderIDAPIError("A resource identifier is required.", `${operation}-ValidationError-002`, "node", 400, "The provided resource identifier is empty.");
40
+ return id;
41
+ };
42
+ /**
43
+ * Builds the server-side management client for one session.
44
+ *
45
+ * Each operation resolves its request config through `resolve` at call time, so the access token is
46
+ * read fresh for every request and never held by the returned object.
47
+ *
48
+ * @param resolve - Supplies the base URL, collection URL, and `Authorization` header for a request.
49
+ * @returns The session-bound management operations.
50
+ */
51
+ const createManagementClient = (resolve) => {
52
+ const config = async (key, { fetcher, signal, url } = {}) => ({
53
+ ...fetcher ? { fetcher } : {},
54
+ ...signal ? { signal } : {},
55
+ ...await resolve(key, url)
56
+ });
57
+ return {
58
+ agentTypes: { list: async ({ limit, offset,...options } = {}) => getAgentTypes({
59
+ limit,
60
+ offset,
61
+ ...await config("agentTypes", options)
62
+ }) },
63
+ agents: {
64
+ create: async (payload, options) => createAgent({
65
+ payload,
66
+ ...await config("agents", options)
67
+ }),
68
+ delete: async (agentId, options) => deleteAgent({
69
+ agentId: requireId(agentId, "deleteAgent"),
70
+ ...await config("agents", options)
71
+ }),
72
+ get: async (agentId, options) => getAgent({
73
+ agentId: requireId(agentId, "getAgent"),
74
+ ...await config("agents", options)
75
+ }),
76
+ list: async ({ filter, limit, offset,...options } = {}) => getAgents({
77
+ filter,
78
+ limit,
79
+ offset,
80
+ ...await config("agents", options)
81
+ }),
82
+ listGroups: async (agentId, { limit, offset,...options } = {}) => getAgentGroups({
83
+ agentId: requireId(agentId, "getAgentGroups"),
84
+ limit,
85
+ offset,
86
+ ...await config("agents", options)
87
+ }),
88
+ listRoles: async (agentId, { limit, offset,...options } = {}) => getAgentRoles({
89
+ agentId: requireId(agentId, "getAgentRoles"),
90
+ limit,
91
+ offset,
92
+ ...await config("agents", options)
93
+ }),
94
+ update: async (agentId, payload, options) => updateAgent({
95
+ agentId: requireId(agentId, "updateAgent"),
96
+ payload,
97
+ ...await config("agents", options)
98
+ })
99
+ },
100
+ flows: { list: async ({ flowType, limit, offset,...options } = {}) => getFlows({
101
+ flowType,
102
+ limit,
103
+ offset,
104
+ ...await config("flows", options)
105
+ }) },
106
+ groups: {
107
+ addMembers: async (groupId, members, options) => addGroupMembers({
108
+ groupId: requireId(groupId, "addGroupMembers"),
109
+ members,
110
+ ...await config("groups", options)
111
+ }),
112
+ create: async (payload, options) => createGroup({
113
+ payload,
114
+ ...await config("groups", options)
115
+ }),
116
+ delete: async (groupId, options) => deleteGroup({
117
+ groupId: requireId(groupId, "deleteGroup"),
118
+ ...await config("groups", options)
119
+ }),
120
+ get: async (groupId, options) => getGroup({
121
+ groupId: requireId(groupId, "getGroup"),
122
+ ...await config("groups", options)
123
+ }),
124
+ list: async ({ limit, offset,...options } = {}) => getGroups({
125
+ limit,
126
+ offset,
127
+ ...await config("groups", options)
128
+ }),
129
+ listMembers: async (groupId, { limit, offset,...options } = {}) => getGroupMembers({
130
+ groupId: requireId(groupId, "getGroupMembers"),
131
+ limit,
132
+ offset,
133
+ ...await config("groups", options)
134
+ }),
135
+ removeMembers: async (groupId, members, options) => removeGroupMembers({
136
+ groupId: requireId(groupId, "removeGroupMembers"),
137
+ members,
138
+ ...await config("groups", options)
139
+ }),
140
+ update: async (groupId, payload, options) => updateGroup({
141
+ groupId: requireId(groupId, "updateGroup"),
142
+ payload,
143
+ ...await config("groups", options)
144
+ })
145
+ },
146
+ roles: {
147
+ addAssignments: async (roleId, assignments, options) => addRoleAssignments({
148
+ assignments,
149
+ roleId: requireId(roleId, "addRoleAssignments"),
150
+ ...await config("roles", options)
151
+ }),
152
+ create: async (payload, options) => createRole({
153
+ payload,
154
+ ...await config("roles", options)
155
+ }),
156
+ delete: async (roleId, options) => deleteRole({
157
+ roleId: requireId(roleId, "deleteRole"),
158
+ ...await config("roles", options)
159
+ }),
160
+ get: async (roleId, options) => getRole({
161
+ roleId: requireId(roleId, "getRole"),
162
+ ...await config("roles", options)
163
+ }),
164
+ list: async ({ limit, offset,...options } = {}) => getRoles({
165
+ limit,
166
+ offset,
167
+ ...await config("roles", options)
168
+ }),
169
+ listAssignments: async (roleId, { limit, offset, type,...options } = {}) => getRoleAssignments({
170
+ limit,
171
+ offset,
172
+ roleId: requireId(roleId, "getRoleAssignments"),
173
+ type,
174
+ ...await config("roles", options)
175
+ }),
176
+ removeAssignments: async (roleId, assignments, options) => removeRoleAssignments({
177
+ assignments,
178
+ roleId: requireId(roleId, "removeRoleAssignments"),
179
+ ...await config("roles", options)
180
+ }),
181
+ update: async (roleId, payload, options) => updateRole({
182
+ payload,
183
+ roleId: requireId(roleId, "updateRole"),
184
+ ...await config("roles", options)
185
+ })
186
+ },
187
+ userTypes: { list: async ({ limit, offset,...options } = {}) => getUserTypes({
188
+ limit,
189
+ offset,
190
+ ...await config("userTypes", options)
191
+ }) },
192
+ users: {
193
+ create: async (payload, options) => createUser({
194
+ payload,
195
+ ...await config("users", options)
196
+ }),
197
+ delete: async (userId, options) => deleteUser({
198
+ userId: requireId(userId, "deleteUser"),
199
+ ...await config("users", options)
200
+ }),
201
+ get: async (userId, options) => getUser({
202
+ userId: requireId(userId, "getUser"),
203
+ ...await config("users", options)
204
+ }),
205
+ list: async ({ filter, limit, offset,...options } = {}) => getUsers({
206
+ filter,
207
+ limit,
208
+ offset,
209
+ ...await config("users", options)
210
+ }),
211
+ listGroups: async (userId, { limit, offset,...options } = {}) => getUserGroups({
212
+ limit,
213
+ offset,
214
+ userId: requireId(userId, "getUserGroups"),
215
+ ...await config("users", options)
216
+ }),
217
+ update: async (userId, payload, options) => updateUser({
218
+ payload,
219
+ userId: requireId(userId, "updateUser"),
220
+ ...await config("users", options)
221
+ })
222
+ }
223
+ };
224
+ };
225
+ var createManagementClient_default = createManagementClient;
226
+
31
227
  //#endregion
32
228
  //#region src/utils/NodeCryptoUtils.ts
33
229
  /**
@@ -407,6 +603,49 @@ var ThunderIDNodeClient = class extends ThunderIDJavaScriptClient {
407
603
  };
408
604
  }
409
605
  /**
606
+ * Returns the management operations (users, groups, roles, agents, and their sub-resources) bound
607
+ * to the session identified by `sessionId`.
608
+ *
609
+ * Every request is authorized with that session's access token, read at the time of each call; the
610
+ * token is never copied onto the returned object or exposed to the caller. Whether a call succeeds
611
+ * is the server's decision: the token needs the permissions the server requires for that resource.
612
+ *
613
+ * The collection URL comes from, in order: the `url` passed to the call, then `endpoints.<resource>`
614
+ * in the configuration, then `{baseUrl}/{collection}`.
615
+ *
616
+ * @param sessionId - The session whose access token authorizes the requests.
617
+ * @returns The session-bound management client.
618
+ * @throws {ThunderIDRuntimeError} `NODE-MANAGEMENT-RC-NF01`, from an operation, when the session
619
+ * has no access token. Raised before any request is sent.
620
+ * @throws {ThunderIDAPIError} From an operation, when the server rejects the request. HTTP 403 and
621
+ * 404 surface as `<operation>-ForbiddenError-001` and `<operation>-NotFoundError-001`.
622
+ *
623
+ * @example
624
+ * ```typescript
625
+ * const admin = client.management(sessionId);
626
+ * const {users, totalResults} = await admin.users.list({limit: 20});
627
+ * await admin.groups.addMembers(groupId, [{id: users[0].id, type: 'user'}]);
628
+ * ```
629
+ */
630
+ management(sessionId) {
631
+ return createManagementClient_default((key, explicitUrl) => this.sessionManagementRequestConfig(key, sessionId, explicitUrl));
632
+ }
633
+ /**
634
+ * The URL inputs and bearer token for a management request made through {@link management}. Unlike
635
+ * {@link managementRequestConfig}, a session without an access token is refused here rather than
636
+ * sent to the server with an empty credential.
637
+ */
638
+ async sessionManagementRequestConfig(key, sessionId, explicitUrl) {
639
+ const configData = await this.getStorageManager().getConfigData();
640
+ const accessToken = await this.getAccessToken(sessionId);
641
+ if (!accessToken) throw new ThunderIDRuntimeError("No access token is available for the session. Sign in before calling a management operation.", "NODE-MANAGEMENT-RC-NF01", "node");
642
+ return {
643
+ baseUrl: configData?.baseUrl,
644
+ headers: { Authorization: `Bearer ${accessToken}` },
645
+ url: resolveResourceEndpoint(key, configData, explicitUrl)
646
+ };
647
+ }
648
+ /**
410
649
  * Retrieves one page of the user directory on behalf of the session identified by `userId`.
411
650
  *
412
651
  * Makes a single request and does not follow `links`. The access token stays on the server.
@@ -685,6 +924,64 @@ var LoggedOutSessions_default = LoggedOutSessions;
685
924
  const generateSessionId = () => (/* @__PURE__ */ new Date()).getTime().toString(36) + Math.random().toString(36).substring(2);
686
925
  var generateSessionId_default = generateSessionId;
687
926
 
927
+ //#endregion
928
+ //#region src/utils/managementCollections.ts
929
+ /**
930
+ * The management collections a browser may reach through a server-side management relay, keyed by
931
+ * their `endpoints` override key, with the path each one has under `baseUrl`.
932
+ */
933
+ const MANAGEMENT_COLLECTIONS = {
934
+ agentTypes: "agent-types",
935
+ agents: "agents",
936
+ groups: "groups",
937
+ roles: "roles",
938
+ userTypes: "user-types",
939
+ users: "users"
940
+ };
941
+ const MANAGEMENT_COLLECTION_KEYS = Object.keys(MANAGEMENT_COLLECTIONS);
942
+ /**
943
+ * The collection URLs a management request may target for this configuration: each collection's
944
+ * `endpoints` override, or `{baseUrl}/{path}` and the organization-scoped `{baseUrl}/o/{path}`.
945
+ */
946
+ const getManagementCollectionUrls = (config) => {
947
+ const urls = [];
948
+ const baseUrl = config?.baseUrl?.replace(/\/+$/, "");
949
+ MANAGEMENT_COLLECTION_KEYS.forEach((key) => {
950
+ const override = resolveResourceEndpoint(key, config);
951
+ (override ? [override] : baseUrl ? [`${baseUrl}/${MANAGEMENT_COLLECTIONS[key]}`, `${baseUrl}/o/${MANAGEMENT_COLLECTIONS[key]}`] : []).forEach((candidate) => {
952
+ try {
953
+ urls.push(new URL(candidate.replace(/\/+$/, "")));
954
+ } catch {}
955
+ });
956
+ });
957
+ return urls;
958
+ };
959
+ /**
960
+ * Whether `target` addresses one of the management collections, or a resource or sub-resource under
961
+ * one. The comparison runs on the parsed URL, so dot segments are resolved before it, and an
962
+ * encoded slash, backslash or dot, which an upstream could decode into a different path, is refused.
963
+ *
964
+ * @param target - The absolute URL the browser asked for.
965
+ * @param collections - The allowed collection URLs, from {@link getManagementCollectionUrls}.
966
+ * @returns The parsed URL when it is allowed, otherwise `undefined`.
967
+ */
968
+ const matchManagementUrl = (target, collections) => {
969
+ if (typeof target !== "string" || target.length > 4096) return;
970
+ let url;
971
+ try {
972
+ url = new URL(target);
973
+ } catch {
974
+ return;
975
+ }
976
+ if (url.protocol !== "https:" && url.protocol !== "http:" || url.username || url.password || url.hash) return;
977
+ if (/%(2e|2f|5c)/i.test(url.pathname)) return;
978
+ return collections.some((collection) => {
979
+ if (collection.origin !== url.origin) return false;
980
+ const base = collection.pathname.replace(/\/+$/, "");
981
+ return url.pathname === base || url.pathname.startsWith(`${base}/`);
982
+ }) ? url : void 0;
983
+ };
984
+
688
985
  //#endregion
689
986
  //#region src/utils/getSessionCookieOptions.ts
690
987
  const getSessionCookieOptions = (options) => ({
@@ -704,4 +1001,4 @@ if (!globalThis.fetch) {
704
1001
  }
705
1002
 
706
1003
  //#endregion
707
- export { CookieChunking_default as CookieChunking, CookieConfig_default as CookieConfig, InMemoryLogoutRecordStore, LoggedOutSessions_default as LoggedOutSessions, MemoryCacheStore_default as MemoryCacheStore, NodeCryptoUtils_default as NodeCryptoUtils, SessionIndex_default as SessionIndex, SessionUtils_default as SessionUtils, ThunderIDNodeClient_default as ThunderIDNodeClient, generateSessionId_default as generateSessionId, getSessionCookieOptions_default as getSessionCookieOptions };
1004
+ export { CookieChunking_default as CookieChunking, CookieConfig_default as CookieConfig, InMemoryLogoutRecordStore, LoggedOutSessions_default as LoggedOutSessions, MANAGEMENT_COLLECTIONS, MANAGEMENT_COLLECTION_KEYS, MemoryCacheStore_default as MemoryCacheStore, NodeCryptoUtils_default as NodeCryptoUtils, SessionIndex_default as SessionIndex, SessionUtils_default as SessionUtils, ThunderIDNodeClient_default as ThunderIDNodeClient, createManagementClient_default as createManagementClient, generateSessionId_default as generateSessionId, getManagementCollectionUrls, getSessionCookieOptions_default as getSessionCookieOptions, matchManagementUrl };
@@ -0,0 +1,107 @@
1
+ import { Agent, AgentListResponse, AgentRoleListResponse, AgentTypeListResponse, ApiFetcher, ApiFilteringParams, CreateAgentRequest, CreateGroupRequest, CreateManagedUserRequest, CreateRoleRequest, Group, GroupListResponse, GroupMember, GroupMemberListResponse, ManagedFlowListResponse, ManagedUser, ManagedUserListResponse, ManagedUserTypeListResponse, ManagementRequestConfig, MembershipGroupListResponse, ResourceEndpointKey, Role, RoleAssigneeType, RoleAssignmentInput, RoleAssignmentListResponse, RoleListResponse, UpdateAgentRequest, UpdateGroupRequest, UpdateManagedUserRequest, UpdateRoleRequest } from '@thunderid/javascript';
2
+ /**
3
+ * The management resource collections the server-side management client addresses.
4
+ */
5
+ export type ManagementResourceKey = Extract<ResourceEndpointKey, 'agents' | 'agentTypes' | 'flows' | 'groups' | 'roles' | 'users' | 'userTypes'>;
6
+ /**
7
+ * Per-call options accepted by every management operation.
8
+ */
9
+ export interface ManagementCallOptions {
10
+ /**
11
+ * Transport for this call. Takes precedence over the SDK's default `fetch`. The SDK still sets the
12
+ * `Authorization` header; a fetcher cannot be used to drop or replace the session's bearer token.
13
+ */
14
+ fetcher?: ApiFetcher;
15
+ /**
16
+ * Aborts the request.
17
+ */
18
+ signal?: AbortSignal;
19
+ /**
20
+ * Explicit collection URL for this call. Takes precedence over a `config.endpoints` override, which
21
+ * takes precedence over `{baseUrl}/{collection}`. A single resource is addressed as this URL followed
22
+ * by its identifier.
23
+ */
24
+ url?: string;
25
+ }
26
+ /**
27
+ * Options for a paginated list.
28
+ */
29
+ export type ManagementListOptions = ManagementCallOptions & Pick<ApiFilteringParams, 'limit' | 'offset'>;
30
+ /**
31
+ * Member reference accepted when adding or removing group members.
32
+ */
33
+ export type ManagementGroupMemberInput = Pick<GroupMember, 'id' | 'type'>;
34
+ /**
35
+ * Resolves the URL inputs and bearer token for one management request. Implemented by
36
+ * `ThunderIDNodeClient`, which reads the access token of the bound session on every call.
37
+ *
38
+ * @param key - The resource collection the request targets.
39
+ * @param explicitUrl - A collection URL passed to the call, if any.
40
+ */
41
+ export type ManagementRequestConfigResolver = (key: ManagementResourceKey, explicitUrl?: string) => Promise<Pick<ManagementRequestConfig, 'baseUrl' | 'url'> & {
42
+ headers: {
43
+ Authorization: string;
44
+ };
45
+ }>;
46
+ /**
47
+ * Server-side management operations bound to one session. Every request is authorized with that
48
+ * session's access token, read at the time of the call, so the token is never copied, cached, or
49
+ * exposed to the caller.
50
+ *
51
+ * Resources returned here are server records (`ManagedUser`, `Group`, `Role`, `Agent`), never the
52
+ * signed-in user. Failures are raised as `ThunderIDAPIError`, with HTTP 403 and 404 carrying the
53
+ * `<operation>-ForbiddenError-001` and `<operation>-NotFoundError-001` codes.
54
+ */
55
+ export interface ThunderIDNodeManagementClient {
56
+ agentTypes: {
57
+ list(options?: ManagementListOptions): Promise<AgentTypeListResponse>;
58
+ };
59
+ agents: {
60
+ create(payload: CreateAgentRequest, options?: ManagementCallOptions): Promise<Agent>;
61
+ delete(agentId: string, options?: ManagementCallOptions): Promise<void>;
62
+ get(agentId: string, options?: ManagementCallOptions): Promise<Agent>;
63
+ list(options?: ManagementCallOptions & ApiFilteringParams): Promise<AgentListResponse>;
64
+ listGroups(agentId: string, options?: ManagementListOptions): Promise<MembershipGroupListResponse>;
65
+ listRoles(agentId: string, options?: ManagementListOptions): Promise<AgentRoleListResponse>;
66
+ update(agentId: string, payload: UpdateAgentRequest, options?: ManagementCallOptions): Promise<Agent>;
67
+ };
68
+ flows: {
69
+ list(options?: ManagementListOptions & {
70
+ flowType?: string;
71
+ }): Promise<ManagedFlowListResponse>;
72
+ };
73
+ groups: {
74
+ addMembers(groupId: string, members: ManagementGroupMemberInput[], options?: ManagementCallOptions): Promise<Group>;
75
+ create(payload: CreateGroupRequest, options?: ManagementCallOptions): Promise<Group>;
76
+ delete(groupId: string, options?: ManagementCallOptions): Promise<void>;
77
+ get(groupId: string, options?: ManagementCallOptions): Promise<Group>;
78
+ list(options?: ManagementListOptions): Promise<GroupListResponse>;
79
+ listMembers(groupId: string, options?: ManagementListOptions): Promise<GroupMemberListResponse>;
80
+ removeMembers(groupId: string, members: ManagementGroupMemberInput[], options?: ManagementCallOptions): Promise<Group>;
81
+ update(groupId: string, payload: UpdateGroupRequest, options?: ManagementCallOptions): Promise<Group>;
82
+ };
83
+ roles: {
84
+ addAssignments(roleId: string, assignments: RoleAssignmentInput[], options?: ManagementCallOptions): Promise<void>;
85
+ create(payload: CreateRoleRequest, options?: ManagementCallOptions): Promise<Role>;
86
+ delete(roleId: string, options?: ManagementCallOptions): Promise<void>;
87
+ get(roleId: string, options?: ManagementCallOptions): Promise<Role>;
88
+ list(options?: ManagementListOptions): Promise<RoleListResponse>;
89
+ listAssignments(roleId: string, options?: ManagementListOptions & {
90
+ type?: RoleAssigneeType;
91
+ }): Promise<RoleAssignmentListResponse>;
92
+ removeAssignments(roleId: string, assignments: RoleAssignmentInput[], options?: ManagementCallOptions): Promise<void>;
93
+ update(roleId: string, payload: UpdateRoleRequest, options?: ManagementCallOptions): Promise<Role>;
94
+ };
95
+ userTypes: {
96
+ list(options?: ManagementListOptions): Promise<ManagedUserTypeListResponse>;
97
+ };
98
+ users: {
99
+ create(payload: CreateManagedUserRequest, options?: ManagementCallOptions): Promise<ManagedUser>;
100
+ delete(userId: string, options?: ManagementCallOptions): Promise<void>;
101
+ get(userId: string, options?: ManagementCallOptions): Promise<ManagedUser>;
102
+ list(options?: ManagementCallOptions & ApiFilteringParams): Promise<ManagedUserListResponse>;
103
+ listGroups(userId: string, options?: ManagementListOptions): Promise<MembershipGroupListResponse>;
104
+ update(userId: string, payload: UpdateManagedUserRequest, options?: ManagementCallOptions): Promise<ManagedUser>;
105
+ };
106
+ }
107
+ //# sourceMappingURL=management.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"management.d.ts","sourceRoot":"","sources":["../../src/models/management.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { ManagementRequestConfigResolver, ThunderIDNodeManagementClient } from '../models/management';
2
+ /**
3
+ * Builds the server-side management client for one session.
4
+ *
5
+ * Each operation resolves its request config through `resolve` at call time, so the access token is
6
+ * read fresh for every request and never held by the returned object.
7
+ *
8
+ * @param resolve - Supplies the base URL, collection URL, and `Authorization` header for a request.
9
+ * @returns The session-bound management operations.
10
+ */
11
+ declare const createManagementClient: (resolve: ManagementRequestConfigResolver) => ThunderIDNodeManagementClient;
12
+ export default createManagementClient;
13
+ //# sourceMappingURL=createManagementClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createManagementClient.d.ts","sourceRoot":"","sources":["../../src/utils/createManagementClient.ts"],"names":[],"mappings":"AAuCA,OAAO,EAEL,+BAA+B,EAE/B,6BAA6B,EAC9B,MAAM,sBAAsB,CAAC;AAqB9B;;;;;;;;GAQG;AACH,QAAA,MAAM,sBAAsB,GAAI,SAAS,+BAA+B,KAAG,6BAiI1E,CAAC;AAEF,eAAe,sBAAsB,CAAC"}
@@ -0,0 +1,26 @@
1
+ import type { ResourceEndpointConfig, ResourceEndpointKey } from '@thunderid/javascript';
2
+ /**
3
+ * The management collections a browser may reach through a server-side management relay, keyed by
4
+ * their `endpoints` override key, with the path each one has under `baseUrl`.
5
+ */
6
+ export declare const MANAGEMENT_COLLECTIONS: Readonly<Record<Extract<ResourceEndpointKey, 'agents' | 'agentTypes' | 'groups' | 'roles' | 'users' | 'userTypes'>, string>>;
7
+ export type ManagementCollectionKey = keyof typeof MANAGEMENT_COLLECTIONS;
8
+ export declare const MANAGEMENT_COLLECTION_KEYS: ManagementCollectionKey[];
9
+ /**
10
+ * The collection URLs a management request may target for this configuration: each collection's
11
+ * `endpoints` override, or `{baseUrl}/{path}` and the organization-scoped `{baseUrl}/o/{path}`.
12
+ */
13
+ export declare const getManagementCollectionUrls: (config: (ResourceEndpointConfig & {
14
+ baseUrl?: string;
15
+ }) | undefined) => URL[];
16
+ /**
17
+ * Whether `target` addresses one of the management collections, or a resource or sub-resource under
18
+ * one. The comparison runs on the parsed URL, so dot segments are resolved before it, and an
19
+ * encoded slash, backslash or dot, which an upstream could decode into a different path, is refused.
20
+ *
21
+ * @param target - The absolute URL the browser asked for.
22
+ * @param collections - The allowed collection URLs, from {@link getManagementCollectionUrls}.
23
+ * @returns The parsed URL when it is allowed, otherwise `undefined`.
24
+ */
25
+ export declare const matchManagementUrl: (target: unknown, collections: URL[]) => URL | undefined;
26
+ //# sourceMappingURL=managementCollections.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"managementCollections.d.ts","sourceRoot":"","sources":["../../src/utils/managementCollections.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAC,sBAAsB,EAAE,mBAAmB,EAAC,MAAM,uBAAuB,CAAC;AAKvF;;;GAGG;AACH,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAC3C,MAAM,CAAC,OAAO,CAAC,mBAAmB,EAAE,QAAQ,GAAG,YAAY,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,WAAW,CAAC,EAAE,MAAM,CAAC,CAQnH,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG,MAAM,OAAO,sBAAsB,CAAC;AAE1E,eAAO,MAAM,0BAA0B,EAAE,uBAAuB,EAElC,CAAC;AAE/B;;;GAGG;AACH,eAAO,MAAM,2BAA2B,GACtC,QAAQ,CAAC,sBAAsB,GAAG;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAC,CAAC,GAAG,SAAS,KAChE,GAAG,EAsBL,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,GAAI,QAAQ,OAAO,EAAE,aAAa,GAAG,EAAE,KAAG,GAAG,GAAG,SAgC9E,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thunderid/node",
3
- "version": "1.3.1",
3
+ "version": "1.5.0",
4
4
  "description": "Node.js runtime SDK for ThunderID",
5
5
  "keywords": [
6
6
  "thunderid",
@@ -44,7 +44,7 @@
44
44
  "vitest": "4.1.11"
45
45
  },
46
46
  "dependencies": {
47
- "@thunderid/javascript": "^1.4.1",
47
+ "@thunderid/javascript": "^1.6.0",
48
48
  "base64url": "3.0.1",
49
49
  "cross-fetch": "4.1.0",
50
50
  "fast-sha256": "1.3.0",