@thunderid/node 1.10.0 → 1.12.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,5 +1,5 @@
1
- import fetch, { Headers, Request, Response } from "cross-fetch";
2
- import { BackchannelLogoutConstants, InvalidLogoutTokenError, ThunderIDAPIError, ThunderIDAuthException, ThunderIDJavaScriptClient, ThunderIDRuntimeError, addGroupMembers, addRoleAssignments, applyGatewayConfiguration, createAction, createAgent, createAgentType, createApplication, createApplicationSharingPolicy, createConfigurationVersion, createConnection, createDesignTheme, createFlow, createGateway, createGatewaySecret, createGatewayVariable, createGroup, createLayout, createNotificationTemplate, createOrganizationUnit, createResource, createResourceServer, createRole, createSecret, createUser, createUserByPath, createUserSharingPolicy, createVariable, deleteAction, deleteAgent, deleteAgentType, deleteApplication, deleteApplicationSharingPolicy, deleteConnection, deleteDesignTheme, deleteFlow, deleteGateway, deleteGatewaySecret, deleteGatewayVariable, deleteGroup, deleteImportedConfiguration, deleteLayout, deleteNotificationTemplate, deleteOrganizationUnit, deleteOrganizationUnitByPath, deleteResource, deleteResourceServer, deleteRole, deleteSecret, deleteTranslation, deleteTranslations, deleteUser, deleteUserSharingPolicy, deleteVariable, exportConfiguration, getAction, getActions, getAgent, getAgentGroups, getAgentRoles, getAgentType, getAgentTypes, getAgents, getApplication, getApplicationOverlayRules, getApplicationSharingPolicies, getApplicationSharingPolicy, getApplications, getConfigurationVersion, getConfigurationVersions, getConnection, getConnectionUsages, getConnections, getConnectionsMeta, getDesignTheme, getDesignThemeUsages, getDesignThemes, getFlow, getFlowUsages, getFlowVersion, getFlowVersions, getFlows, getGateway, getGatewayAppliedConfiguration, getGatewayAppliedVersion, getGatewayConfigurationDiff, getGatewaySecret, getGatewaySecrets, getGatewayVariable, getGatewayVariables, getGateways, getGroup, getGroupMembers, getGroups, getLanguages, getLayout, getLayoutUsages, getLayouts, getNotificationTemplate, getNotificationTemplates, getOrganizationUnit, getOrganizationUnitByPath, getOrganizationUnitChildren, getOrganizationUnitGroups, getOrganizationUnitRoles, getOrganizationUnitUsers, getOrganizationUnits, getResource, getResourceServer, getResourceServers, getResources, getRole, getRoleAssignments, getRoles, getSecret, getSecrets, getServerConfig, getServerConfigs, getUser, getUserGroups, getUserOverlayRules, getUserSharingPolicies, getUserSharingPolicy, getUserTypes, getUsers, getUsersByPath, getVariable, getVariables, getVendorPrefix, importConfiguration, logger, previewCimdDocument, regenerateClientSecret, regenerateFlowSecret, removeGroupMembers, removeRoleAssignments, resolveDesign, resolveResourceEndpoint, resolveTranslation, resolveTranslations, restoreFlowVersion, revertGatewayConfiguration, setTranslation, setTranslations, suspendAgent, suspendApplication, suspendUser, unlockAgent, unlockUser, unsuspendAgent, unsuspendApplication, unsuspendUser, updateAction, updateAgent, updateAgentType, updateApplication, updateApplicationSharingPolicy, updateConnection, updateDesignTheme, updateFlow, updateGateway, updateGatewaySecret, updateGatewayVariable, updateGroup, updateLayout, updateMeCredentials, updateNotificationTemplate, updateOrganizationUnit, updateOrganizationUnitByPath, updateResource, updateResourceServer, updateRole, updateSecret, updateServerConfig, updateUser, updateUserSharingPolicy, updateVariable } from "@thunderid/javascript";
1
+ import fetch$1, { Headers, Request, Response } from "cross-fetch";
2
+ import { BackchannelLogoutConstants, InvalidLogoutTokenError, OrganizationUnitSwitchErrorCodes, ThunderIDAPIError, ThunderIDAuthException, ThunderIDJavaScriptClient, ThunderIDRuntimeError, addGroupMembers, addRoleAssignments, applyGatewayConfiguration, createAction, createAgent, createAgentType, createApplication, createApplicationSharingPolicy, createAuthorizationDetailType, createConfigurationVersion, createConnection, createCredentialConfiguration, createDesignTheme, createFlow, createFlowSharingPolicy, createGateway, createGatewaySecret, createGatewayVariable, createGroup, createGroupByPath, createLayout, createNotificationTemplate, createOrganizationUnit, createPresentationDefinition, createProject, createResource, createResourceServer, createRole, createRoleSharingPolicy, createSecret, createUser, createUserByPath, createUserSharingPolicy, createVariable, deleteAction, deleteAgent, deleteAgentType, deleteApplication, deleteApplicationSharingPolicy, deleteAuthorizationDetailType, deleteClientRegistration, deleteConnection, deleteCredentialConfiguration, deleteDesignTheme, deleteFlow, deleteFlowSharingPolicy, deleteGateway, deleteGatewaySecret, deleteGatewayVariable, deleteGroup, deleteImportedConfiguration, deleteLayout, deleteNotificationTemplate, deleteOrganizationUnit, deleteOrganizationUnitByPath, deletePresentationDefinition, deleteProject, deleteResource, deleteResourceServer, deleteRole, deleteRoleSharingPolicy, deleteSecret, deleteTranslation, deleteTranslations, deleteUser, deleteUserSharingPolicy, deleteVariable, executeEmbeddedSelfFlow, exportConfiguration, getAction, getActions, getAgent, getAgentGroups, getAgentRoles, getAgentType, getAgentTypes, getAgents, getApplication, getApplicationOverlayRules, getApplicationSharingPolicies, getApplicationSharingPolicy, getApplications, getAuthorizationDetailType, getAuthorizationDetailTypes, getClientRegistration, getConfigurationVersion, getConfigurationVersions, getConnection, getConnectionUsages, getConnections, getConnectionsMeta, getCredentialConfiguration, getCredentialConfigurations, getDesignTheme, getDesignThemeUsages, getDesignThemes, getFlow, getFlowOverlayRules, getFlowSharingPolicies, getFlowSharingPolicy, getFlowUsages, getFlowVariables, getFlowVersion, getFlowVersions, getFlows, getGateway, getGatewayAppliedConfiguration, getGatewayAppliedVersion, getGatewayConfigurationDiff, getGatewayMaster, getGatewayMasterHistory, getGatewayMasterResource, getGatewaySecret, getGatewaySecrets, getGatewayVariable, getGatewayVariables, getGateways, getGroup, getGroupMembers, getGroups, getGroupsByPath, getLanguages, getLayout, getLayoutUsages, getLayouts, getNotificationTemplate, getNotificationTemplates, getOrganizationUnit, getOrganizationUnitByPath, getOrganizationUnitChildren, getOrganizationUnitGroups, getOrganizationUnitRoles, getOrganizationUnitUsers, getOrganizationUnits, getPresentationDefinition, getPresentationDefinitions, getProject, getProjects, getResource, getResourceServer, getResourceServers, getResources, getRole, getRoleAssignments, getRoleOverlayRules, getRoleSharingPolicies, getRoleSharingPolicy, getRoles, getSecret, getSecrets, getServerConfig, getServerConfigs, getUser, getUserGroups, getUserOverlayRules, getUserSharingPolicies, getUserSharingPolicy, getUserTypes, getUsers, getUsersByPath, getVariable, getVariables, getVendorPrefix, importConfiguration, logger, previewCimdDocument, regenerateClientSecret, regenerateFlowSecret, registerClient, removeGroupMembers, removeRoleAssignments, resolveDesign, resolveResourceEndpoint, resolveTranslation, resolveTranslations, restoreFlowVersion, revertGatewayConfiguration, setTranslation, setTranslations, suspendAgent, suspendApplication, suspendUser, unlockAgent, unlockUser, unsuspendAgent, unsuspendApplication, unsuspendUser, updateAction, updateAgent, updateAgentType, updateApplication, updateApplicationSharingPolicy, updateAuthorizationDetailType, updateClientRegistration, updateConnection, updateCredentialConfiguration, updateDesignTheme, updateFlow, updateFlowSharingPolicy, updateFlowVariables, updateGateway, updateGatewaySecret, updateGatewayVariable, updateGroup, updateLayout, updateMeCredentials, updateNotificationTemplate, updateOrganizationUnit, updateOrganizationUnitByPath, updatePresentationDefinition, updateProject, updateResource, updateResourceServer, updateRole, updateRoleSharingPolicy, updateSecret, updateServerConfig, updateUser, updateUserSharingPolicy, updateVariable } from "@thunderid/javascript";
3
3
  import cache from "memory-cache";
4
4
  import base64url from "base64url";
5
5
  import sha256 from "fast-sha256";
@@ -10,6 +10,149 @@ import { v4, validate, version } from "uuid";
10
10
 
11
11
  export * from "@thunderid/javascript"
12
12
 
13
+ //#region src/api/access/requestAccessApi.ts
14
+ const METADATA_FIELDS = {
15
+ evaluation: "access_evaluation_endpoint",
16
+ evaluations: "access_evaluations_endpoint",
17
+ searchAction: "search_action_endpoint"
18
+ };
19
+ const trimSlash = (value) => value.replace(/\/+$/, "");
20
+ /**
21
+ * Reads the AuthZEN metadata of the server at `baseUrl` and checks that its `policy_decision_point`
22
+ * names that server exactly (apart from a trailing slash).
23
+ */
24
+ const getAuthZENConfiguration = async (operation, { baseUrl, fetcher, signal }) => {
25
+ const fetchFn = fetcher ?? fetch;
26
+ let response;
27
+ try {
28
+ response = await fetchFn(`${trimSlash(baseUrl)}/.well-known/authzen-configuration`, {
29
+ headers: { Accept: "application/json" },
30
+ method: "GET",
31
+ signal
32
+ });
33
+ } catch (error) {
34
+ throw new ThunderIDAPIError(`Network or parsing error: ${error instanceof Error ? error.message : "Unknown error"}`, `${operation}-NetworkError-001`, "node", 0, "Network Error");
35
+ }
36
+ if (!response.ok) throw new ThunderIDAPIError(await response.text().catch(() => ""), `${operation}-MetadataError-001`, "node", response.status, response.statusText, "Reading the AuthZEN metadata failed");
37
+ const metadata = await response.json();
38
+ if (typeof metadata?.policy_decision_point !== "string" || trimSlash(metadata.policy_decision_point) !== trimSlash(baseUrl)) throw new ThunderIDAPIError("The policy_decision_point in the AuthZEN metadata does not match the configured server.", `${operation}-MetadataError-002`, "node");
39
+ return metadata;
40
+ };
41
+ /**
42
+ * Resolves an access endpoint: an explicit override, held to the origin of `baseUrl`, else the
43
+ * server's AuthZEN metadata.
44
+ */
45
+ const resolveEndpoint = async (operation, key, config) => {
46
+ const override = config.endpoints?.[key];
47
+ if (override) {
48
+ if (new URL(override).origin !== new URL(config.baseUrl).origin) throw new ThunderIDAPIError(`The ${key} endpoint override is not on the origin of baseUrl.`, `${operation}-ValidationError-002`, "node", 400);
49
+ return override;
50
+ }
51
+ const endpoint = (await getAuthZENConfiguration(operation, config))[METADATA_FIELDS[key]];
52
+ if (typeof endpoint !== "string" || endpoint === "") throw new ThunderIDAPIError(`The AuthZEN metadata names no ${METADATA_FIELDS[key]}.`, `${operation}-MetadataError-003`, "node");
53
+ return endpoint;
54
+ };
55
+ /**
56
+ * Posts an AuthZEN request with the `Direct-Auth-Secret` header. A `4xx` or `5xx` answer is an error
57
+ * with the server's `error` as the message; 401, 403 and 404 keep distinct codes.
58
+ */
59
+ const requestAccessApi = async (operation, key, config, body) => {
60
+ try {
61
+ new URL(config.baseUrl);
62
+ } catch (error) {
63
+ throw new ThunderIDAPIError(`Invalid URL provided. ${error instanceof Error ? error.message : String(error)}`, `${operation}-ValidationError-001`, "node", 400, "The provided `baseUrl` does not adhere to the URL schema.");
64
+ }
65
+ if (typeof config.secret !== "string" || config.secret === "") throw new ThunderIDAPIError("The Direct-Auth-Secret is required for access evaluation.", `${operation}-ValidationError-003`, "node", 400);
66
+ const endpoint = await resolveEndpoint(operation, key, config);
67
+ const fetchFn = config.fetcher ?? fetch;
68
+ let response;
69
+ try {
70
+ response = await fetchFn(endpoint, {
71
+ body: JSON.stringify(body),
72
+ headers: {
73
+ Accept: "application/json",
74
+ "Content-Type": "application/json",
75
+ "Direct-Auth-Secret": config.secret
76
+ },
77
+ method: "POST",
78
+ signal: config.signal
79
+ });
80
+ } catch (error) {
81
+ throw new ThunderIDAPIError(`Network or parsing error: ${error instanceof Error ? error.message : "Unknown error"}`, `${operation}-NetworkError-001`, "node", 0, "Network Error");
82
+ }
83
+ if (!response.ok) {
84
+ const text = await response.text().catch(() => "");
85
+ let message = text;
86
+ try {
87
+ const parsed = JSON.parse(text);
88
+ if (typeof parsed?.error === "string" && parsed.code === void 0) message = JSON.stringify({
89
+ code: parsed.error,
90
+ message: { defaultValue: parsed.error }
91
+ });
92
+ } catch {}
93
+ let reason = "ResponseError";
94
+ if (response.status === 401) reason = "UnauthorizedError";
95
+ if (response.status === 403) reason = "ForbiddenError";
96
+ if (response.status === 404) reason = "NotFoundError";
97
+ throw new ThunderIDAPIError(message, `${operation}-${reason}-001`, "node", response.status, response.statusText, "Access evaluation failed");
98
+ }
99
+ return await response.json();
100
+ };
101
+ var requestAccessApi_default = requestAccessApi;
102
+
103
+ //#endregion
104
+ //#region src/api/access/evaluateAccess.ts
105
+ /**
106
+ * Asks the server's AuthZEN policy decision point whether a subject may perform an action on a resource,
107
+ * at the `access_evaluation_endpoint` from `/.well-known/authzen-configuration`.
108
+ *
109
+ * Server-side only: it is authorized by the server-level secret in the `Direct-Auth-Secret` header,
110
+ * which a browser or mobile app cannot hold.
111
+ *
112
+ * A denial is a result: `{decision: false}`, with the reason in `context`. Only a transport failure or a
113
+ * 4xx/5xx answer throws.
114
+ *
115
+ * @example
116
+ * ```typescript
117
+ * const {decision} = await evaluateAccess(
118
+ * {subject: {type: 'user', id: userId}, resource: {type: 'https://api.example.com/booking'}, action: {name: 'booking:read'}},
119
+ * {baseUrl: 'https://localhost:8090', secret: process.env.THUNDERID_DIRECT_AUTH_SECRET!},
120
+ * );
121
+ * ```
122
+ */
123
+ const evaluateAccess = (request, config) => requestAccessApi_default("evaluateAccess", "evaluation", config, request);
124
+ var evaluateAccess_default = evaluateAccess;
125
+
126
+ //#endregion
127
+ //#region src/api/access/evaluateAccesses.ts
128
+ /**
129
+ * Evaluates a batch of access requests at the `access_evaluations_endpoint`, and returns one decision
130
+ * per evaluation, in order. `defaults` apply to every evaluation that does not set that member itself.
131
+ *
132
+ * Server-side only, like {@link evaluateAccess}. A denial is a result, not an error.
133
+ */
134
+ const evaluateAccesses = async ({ defaults, evaluations }, config) => {
135
+ return (await requestAccessApi_default("evaluateAccesses", "evaluations", config, { evaluations: (evaluations ?? []).map((evaluation) => ({
136
+ ...defaults,
137
+ ...evaluation
138
+ })) }))?.evaluations ?? [];
139
+ };
140
+ var evaluateAccesses_default = evaluateAccesses;
141
+
142
+ //#endregion
143
+ //#region src/api/access/searchActions.ts
144
+ /**
145
+ * Asks which actions a subject may perform on a resource, at the `search_action_endpoint`
146
+ * (`/access/v1/search/action`). Server-side only, like {@link evaluateAccess}.
147
+ *
148
+ * @returns The actions the subject may perform.
149
+ */
150
+ const searchActions = async (request, config) => {
151
+ return (await requestAccessApi_default("searchActions", "searchAction", config, request))?.results ?? [];
152
+ };
153
+ var searchActions_default = searchActions;
154
+
155
+ //#endregion
13
156
  //#region src/stores/MemoryCacheStore.ts
14
157
  /**
15
158
  * In-memory key-value store backed by `memory-cache`.
@@ -211,6 +354,49 @@ const createManagementClient = (resolve) => {
211
354
  ...await config("applications", options)
212
355
  })
213
356
  },
357
+ authorizationDetailTypes: {
358
+ create: async (payload, options) => createAuthorizationDetailType({
359
+ payload,
360
+ ...await config("authorizationDetailTypes", options)
361
+ }),
362
+ delete: async (authorizationDetailTypeId, options) => deleteAuthorizationDetailType({
363
+ authorizationDetailTypeId: requireId(authorizationDetailTypeId, "deleteAuthorizationDetailType"),
364
+ ...await config("authorizationDetailTypes", options)
365
+ }),
366
+ get: async (authorizationDetailTypeId, options) => getAuthorizationDetailType({
367
+ authorizationDetailTypeId: requireId(authorizationDetailTypeId, "getAuthorizationDetailType"),
368
+ ...await config("authorizationDetailTypes", options)
369
+ }),
370
+ list: async ({ limit, offset,...options } = {}) => getAuthorizationDetailTypes({
371
+ limit,
372
+ offset,
373
+ ...await config("authorizationDetailTypes", options)
374
+ }),
375
+ update: async (authorizationDetailTypeId, payload, options) => updateAuthorizationDetailType({
376
+ authorizationDetailTypeId: requireId(authorizationDetailTypeId, "updateAuthorizationDetailType"),
377
+ payload,
378
+ ...await config("authorizationDetailTypes", options)
379
+ })
380
+ },
381
+ clientRegistrations: {
382
+ delete: async (clientId, options) => deleteClientRegistration({
383
+ clientId: requireId(clientId, "deleteClientRegistration"),
384
+ ...await config("clientRegistrations", options)
385
+ }),
386
+ get: async (clientId, options) => getClientRegistration({
387
+ clientId: requireId(clientId, "getClientRegistration"),
388
+ ...await config("clientRegistrations", options)
389
+ }),
390
+ register: async (payload, options) => registerClient({
391
+ payload,
392
+ ...await config("clientRegistrations", options)
393
+ }),
394
+ update: async (clientId, payload, options) => updateClientRegistration({
395
+ clientId: requireId(clientId, "updateClientRegistration"),
396
+ payload,
397
+ ...await config("clientRegistrations", options)
398
+ })
399
+ },
214
400
  configuration: {
215
401
  captureVersion: async (payload, options) => createConfigurationVersion({
216
402
  payload,
@@ -276,6 +462,26 @@ const createManagementClient = (resolve) => {
276
462
  ...await config("connections", options)
277
463
  })
278
464
  },
465
+ credentialConfigurations: {
466
+ create: async (payload, options) => createCredentialConfiguration({
467
+ payload,
468
+ ...await config("credentialConfigurations", options)
469
+ }),
470
+ delete: async (configurationId, options) => deleteCredentialConfiguration({
471
+ configurationId: requireId(configurationId, "deleteCredentialConfiguration"),
472
+ ...await config("credentialConfigurations", options)
473
+ }),
474
+ get: async (configurationId, options) => getCredentialConfiguration({
475
+ configurationId: requireId(configurationId, "getCredentialConfiguration"),
476
+ ...await config("credentialConfigurations", options)
477
+ }),
478
+ list: async (options) => getCredentialConfigurations(await config("credentialConfigurations", options)),
479
+ update: async (configurationId, payload, options) => updateCredentialConfiguration({
480
+ configurationId: requireId(configurationId, "updateCredentialConfiguration"),
481
+ payload,
482
+ ...await config("credentialConfigurations", options)
483
+ })
484
+ },
279
485
  design: {
280
486
  createLayout: async (payload, options) => createLayout({
281
487
  payload,
@@ -380,6 +586,49 @@ const createManagementClient = (resolve) => {
380
586
  flowId: requireId(flowId, "updateFlow"),
381
587
  payload,
382
588
  ...await config("flows", options)
589
+ }),
590
+ createSharingPolicy: async (flowId, payload, options) => createFlowSharingPolicy({
591
+ payload,
592
+ flowId: requireId(flowId, "createFlowSharingPolicy"),
593
+ ...await config("flows", options)
594
+ }),
595
+ deleteSharingPolicy: async (flowId, policyId, options) => deleteFlowSharingPolicy({
596
+ flowId: requireId(flowId, "deleteFlowSharingPolicy"),
597
+ policyId: requireId(policyId, "deleteFlowSharingPolicy"),
598
+ ...await config("flows", options)
599
+ }),
600
+ getOverlayRules: async (flowId, ouId, options) => getFlowOverlayRules({
601
+ flowId: requireId(flowId, "getFlowOverlayRules"),
602
+ ouId: requireId(ouId, "getFlowOverlayRules"),
603
+ ...await config("flows", options)
604
+ }),
605
+ getSharingPolicy: async (flowId, policyId, options) => getFlowSharingPolicy({
606
+ flowId: requireId(flowId, "getFlowSharingPolicy"),
607
+ policyId: requireId(policyId, "getFlowSharingPolicy"),
608
+ ...await config("flows", options)
609
+ }),
610
+ listSharingPolicies: async (flowId, { limit, offset,...options } = {}) => getFlowSharingPolicies({
611
+ flowId: requireId(flowId, "getFlowSharingPolicies"),
612
+ limit,
613
+ offset,
614
+ ...await config("flows", options)
615
+ }),
616
+ updateSharingPolicy: async (flowId, policyId, payload, options) => updateFlowSharingPolicy({
617
+ payload,
618
+ policyId: requireId(policyId, "updateFlowSharingPolicy"),
619
+ flowId: requireId(flowId, "updateFlowSharingPolicy"),
620
+ ...await config("flows", options)
621
+ }),
622
+ getVariables: async (flowId, ouId, options) => getFlowVariables({
623
+ flowId: requireId(flowId, "getFlowVariables"),
624
+ ouId: requireId(ouId, "getFlowVariables"),
625
+ ...await config("flows", options)
626
+ }),
627
+ updateVariables: async (flowId, ouId, variables, options) => updateFlowVariables({
628
+ flowId: requireId(flowId, "updateFlowVariables"),
629
+ ouId: requireId(ouId, "updateFlowVariables"),
630
+ variables,
631
+ ...await config("flows", options)
383
632
  })
384
633
  },
385
634
  gateways: {
@@ -433,6 +682,20 @@ const createManagementClient = (resolve) => {
433
682
  version: version$1,
434
683
  ...await config("gateways", options)
435
684
  }),
685
+ getMaster: async (gatewayId, options) => getGatewayMaster({
686
+ gatewayId: requireId(gatewayId, "getGatewayMaster"),
687
+ ...await config("gateways", options)
688
+ }),
689
+ getMasterHistory: async (gatewayId, options) => getGatewayMasterHistory({
690
+ gatewayId: requireId(gatewayId, "getGatewayMasterHistory"),
691
+ ...await config("gateways", options)
692
+ }),
693
+ getMasterResource: async (gatewayId, resourceType, resourceId, options) => getGatewayMasterResource({
694
+ gatewayId: requireId(gatewayId, "getGatewayMasterResource"),
695
+ resourceId: requireId(resourceId, "getGatewayMasterResource"),
696
+ resourceType: requireId(resourceType, "getGatewayMasterResource"),
697
+ ...await config("gateways", options)
698
+ }),
436
699
  getSecret: async (gatewayId, name, options) => getGatewaySecret({
437
700
  gatewayId: requireId(gatewayId, "getGatewaySecret"),
438
701
  name: requireId(name, "getGatewaySecret"),
@@ -493,6 +756,11 @@ const createManagementClient = (resolve) => {
493
756
  payload,
494
757
  ...await config("groups", options)
495
758
  }),
759
+ createByPath: async (path, payload, options) => createGroupByPath({
760
+ path,
761
+ payload,
762
+ ...await config("groups", options)
763
+ }),
496
764
  delete: async (groupId, options) => deleteGroup({
497
765
  groupId: requireId(groupId, "deleteGroup"),
498
766
  ...await config("groups", options)
@@ -506,6 +774,12 @@ const createManagementClient = (resolve) => {
506
774
  offset,
507
775
  ...await config("groups", options)
508
776
  }),
777
+ listByPath: async (path, { limit, offset,...options } = {}) => getGroupsByPath({
778
+ limit,
779
+ offset,
780
+ path,
781
+ ...await config("groups", options)
782
+ }),
509
783
  listMembers: async (groupId, { limit, offset,...options } = {}) => getGroupMembers({
510
784
  groupId: requireId(groupId, "getGroupMembers"),
511
785
  limit,
@@ -652,6 +926,50 @@ const createManagementClient = (resolve) => {
652
926
  ...await config("organizationUnits", options)
653
927
  })
654
928
  },
929
+ presentationDefinitions: {
930
+ create: async (payload, options) => createPresentationDefinition({
931
+ payload,
932
+ ...await config("presentationDefinitions", options)
933
+ }),
934
+ delete: async (definitionId, options) => deletePresentationDefinition({
935
+ definitionId: requireId(definitionId, "deletePresentationDefinition"),
936
+ ...await config("presentationDefinitions", options)
937
+ }),
938
+ get: async (definitionId, options) => getPresentationDefinition({
939
+ definitionId: requireId(definitionId, "getPresentationDefinition"),
940
+ ...await config("presentationDefinitions", options)
941
+ }),
942
+ list: async (options) => getPresentationDefinitions(await config("presentationDefinitions", options)),
943
+ update: async (definitionId, payload, options) => updatePresentationDefinition({
944
+ definitionId: requireId(definitionId, "updatePresentationDefinition"),
945
+ payload,
946
+ ...await config("presentationDefinitions", options)
947
+ })
948
+ },
949
+ projects: {
950
+ create: async (payload, options) => createProject({
951
+ payload,
952
+ ...await config("projects", options)
953
+ }),
954
+ delete: async (projectId, options) => deleteProject({
955
+ projectId: requireId(projectId, "deleteProject"),
956
+ ...await config("projects", options)
957
+ }),
958
+ get: async (projectId, options) => getProject({
959
+ projectId: requireId(projectId, "getProject"),
960
+ ...await config("projects", options)
961
+ }),
962
+ list: async ({ limit, offset,...options } = {}) => getProjects({
963
+ limit,
964
+ offset,
965
+ ...await config("projects", options)
966
+ }),
967
+ update: async (projectId, payload, options) => updateProject({
968
+ projectId: requireId(projectId, "updateProject"),
969
+ payload,
970
+ ...await config("projects", options)
971
+ })
972
+ },
655
973
  resourceServers: {
656
974
  create: async (payload, options) => createResourceServer({
657
975
  payload,
@@ -777,6 +1095,38 @@ const createManagementClient = (resolve) => {
777
1095
  payload,
778
1096
  roleId: requireId(roleId, "updateRole"),
779
1097
  ...await config("roles", options)
1098
+ }),
1099
+ createSharingPolicy: async (roleId, payload, options) => createRoleSharingPolicy({
1100
+ payload,
1101
+ roleId: requireId(roleId, "createRoleSharingPolicy"),
1102
+ ...await config("roles", options)
1103
+ }),
1104
+ deleteSharingPolicy: async (roleId, policyId, options) => deleteRoleSharingPolicy({
1105
+ roleId: requireId(roleId, "deleteRoleSharingPolicy"),
1106
+ policyId: requireId(policyId, "deleteRoleSharingPolicy"),
1107
+ ...await config("roles", options)
1108
+ }),
1109
+ getOverlayRules: async (roleId, ouId, options) => getRoleOverlayRules({
1110
+ roleId: requireId(roleId, "getRoleOverlayRules"),
1111
+ ouId: requireId(ouId, "getRoleOverlayRules"),
1112
+ ...await config("roles", options)
1113
+ }),
1114
+ getSharingPolicy: async (roleId, policyId, options) => getRoleSharingPolicy({
1115
+ roleId: requireId(roleId, "getRoleSharingPolicy"),
1116
+ policyId: requireId(policyId, "getRoleSharingPolicy"),
1117
+ ...await config("roles", options)
1118
+ }),
1119
+ listSharingPolicies: async (roleId, { limit, offset,...options } = {}) => getRoleSharingPolicies({
1120
+ roleId: requireId(roleId, "getRoleSharingPolicies"),
1121
+ limit,
1122
+ offset,
1123
+ ...await config("roles", options)
1124
+ }),
1125
+ updateSharingPolicy: async (roleId, policyId, payload, options) => updateRoleSharingPolicy({
1126
+ payload,
1127
+ policyId: requireId(policyId, "updateRoleSharingPolicy"),
1128
+ roleId: requireId(roleId, "updateRoleSharingPolicy"),
1129
+ ...await config("roles", options)
780
1130
  })
781
1131
  },
782
1132
  secrets: {
@@ -1072,7 +1422,7 @@ var ThunderIDNodeClient = class extends ThunderIDJavaScriptClient {
1072
1422
  async signIn(...args) {
1073
1423
  const [authURLCallback, userId, authorizationCode, state, signInConfig] = args;
1074
1424
  if (!userId) return Promise.reject(new ThunderIDAuthException("NODE-AUTH_CLIENT-SI-NF01", "No user ID was provided.", "Unable to sign in the user as no user ID was provided."));
1075
- if (await this.isSignedIn(userId)) {
1425
+ if (!Boolean(authorizationCode && state && await this.isOrganizationUnitBoundRequest(state, userId)) && await this.isSignedIn(userId)) {
1076
1426
  const sessionData$1 = await this.getStorageManager().getSessionData(userId);
1077
1427
  return Promise.resolve({
1078
1428
  accessToken: sessionData$1.access_token,
@@ -1117,6 +1467,87 @@ var ThunderIDNodeClient = class extends ThunderIDJavaScriptClient {
1117
1467
  if (!url) return Promise.reject(new ThunderIDAuthException("NODE-AUTH_CLIENT-GSIU-NF01", "Getting authorization URL failed.", "No authorization URL was returned."));
1118
1468
  return url;
1119
1469
  }
1470
+ /**
1471
+ * Starts a switch of the session `userId` to the organization unit `organizationUnitId`: builds the
1472
+ * unit's authorization URL (`{baseUrl}/ou/{ouId}/oauth2/authorize`) and hands it to `authURLCallback`
1473
+ * to redirect the user to. The server reuses the SSO session when the user can sign in there, so
1474
+ * normally no credentials are asked. Complete it with `signIn(callback, userId, code, state)` on the
1475
+ * callback: the code is redeemed at the unit's token endpoint and replaces the session's tokens.
1476
+ * Until then, and when the callback carries an error, the previous session stays as it was.
1477
+ *
1478
+ * @throws {ThunderIDAPIError} `switchOrganizationUnit-ValidationError-001` without a unit, a session or
1479
+ * a callback.
1480
+ */
1481
+ async switchOrganizationUnit(organizationUnitId, options = {}) {
1482
+ const { authURLCallback, userId,...rest } = options;
1483
+ const params = Object.fromEntries(Object.entries(rest).filter(([key]) => key !== "redirect"));
1484
+ if (typeof organizationUnitId !== "string" || organizationUnitId.trim() === "" || !userId) throw new ThunderIDAPIError("An organization unit identifier and a session are required.", OrganizationUnitSwitchErrorCodes.InvalidOrganizationUnit, "node", 400);
1485
+ if (typeof authURLCallback !== "function") throw new ThunderIDAPIError("An authURLCallback is required to send the user to the organization unit.", OrganizationUnitSwitchErrorCodes.InvalidOrganizationUnit, "node", 400);
1486
+ authURLCallback(await this.getSignInUrl({
1487
+ ...params,
1488
+ organizationUnitId
1489
+ }, userId));
1490
+ }
1491
+ /**
1492
+ * Starts a device authorization request (RFC 8628) for an input-constrained device or a CLI tool. Show
1493
+ * the user `userCode` and `verificationUri`; keep `deviceCode`, a credential, to yourself and pass it
1494
+ * to {@link pollDeviceAuthorization}. It is never logged.
1495
+ */
1496
+ async startDeviceAuthorization(options = {}) {
1497
+ return super.startDeviceAuthorization(options);
1498
+ }
1499
+ /**
1500
+ * Polls the token endpoint with the device code until the user approves, denies, or the code expires,
1501
+ * and stores the tokens for the session `userId` on approval.
1502
+ *
1503
+ * @throws {ThunderIDAPIError} `JS-AUTH_CORE-DEVICE2-HE03` when the server ends the request
1504
+ * (`access_denied`, `expired_token`), with the OAuth error in `serverError`.
1505
+ */
1506
+ async pollDeviceAuthorization(deviceCode, interval, options, userId) {
1507
+ const tokens = await super.pollDeviceAuthorization(deviceCode, interval, options, userId);
1508
+ if (userId) await this.indexSession(userId, await this.getStorageManager().getSessionData(userId));
1509
+ return tokens;
1510
+ }
1511
+ /**
1512
+ * Introspects a token (RFC 7662) at the server's introspection endpoint, authenticating as this client.
1513
+ * An inactive token is a result (`{active: false}`), not an error.
1514
+ */
1515
+ async introspectToken(token, tokenTypeHint) {
1516
+ return super.introspectToken(token, tokenTypeHint);
1517
+ }
1518
+ /**
1519
+ * The request configuration for access evaluation: the configured server, secret and overrides, with
1520
+ * a per-call secret taking precedence.
1521
+ */
1522
+ async accessEvaluationConfig(secret, signal) {
1523
+ const configData = await this.getStorageManager().getConfigData();
1524
+ const accessEvaluation = configData.accessEvaluation;
1525
+ return {
1526
+ baseUrl: configData?.baseUrl ?? "",
1527
+ endpoints: accessEvaluation?.endpoints,
1528
+ secret: secret ?? accessEvaluation?.secret ?? "",
1529
+ signal
1530
+ };
1531
+ }
1532
+ /**
1533
+ * Asks the server whether a subject may perform an action on a resource (AuthZEN). A denial is a result
1534
+ * (`decision: false`), not an error. Uses `accessEvaluation.secret`, or `options.secret`.
1535
+ */
1536
+ async evaluateAccess(request, options = {}) {
1537
+ return evaluateAccess_default(request, await this.accessEvaluationConfig(options.secret, options.signal));
1538
+ }
1539
+ /**
1540
+ * Evaluates a batch of access requests and returns one decision per evaluation, in order.
1541
+ */
1542
+ async evaluateAccesses(request, options = {}) {
1543
+ return evaluateAccesses_default(request, await this.accessEvaluationConfig(options.secret, options.signal));
1544
+ }
1545
+ /**
1546
+ * Asks which actions a subject may perform on a resource.
1547
+ */
1548
+ async searchActions(request, options = {}) {
1549
+ return searchActions_default(request, await this.accessEvaluationConfig(options.secret, options.signal));
1550
+ }
1120
1551
  async signOut(...args) {
1121
1552
  const userId = typeof args[0] === "string" ? args[0] : void 0;
1122
1553
  const signOutUrl = await this.getSignOutUrl(userId);
@@ -1310,6 +1741,20 @@ var ThunderIDNodeClient = class extends ThunderIDJavaScriptClient {
1310
1741
  });
1311
1742
  }
1312
1743
  /**
1744
+ * Executes one step of a `SELF` flow, such as self attribute verification, for the signed-in
1745
+ * user of the session identified by `userId`. The server takes the user from the access token, which
1746
+ * stays on the server; the caller sends no user identifier.
1747
+ */
1748
+ async executeEmbeddedSelfFlow(payload, userId) {
1749
+ const configData = await this.getStorageManager().getConfigData();
1750
+ return executeEmbeddedSelfFlow({
1751
+ baseUrl: configData?.baseUrl,
1752
+ headers: { Authorization: `Bearer ${await this.getAccessToken(userId)}` },
1753
+ payload,
1754
+ url: resolveResourceEndpoint("flowExecute", configData)
1755
+ });
1756
+ }
1757
+ /**
1313
1758
  * The URL inputs and bearer token for a management request made on behalf of the session identified by
1314
1759
  * `userId`. The access token stays on the server.
1315
1760
  */
@@ -1653,8 +2098,11 @@ const MANAGEMENT_COLLECTIONS = {
1653
2098
  agentTypes: "agent-types",
1654
2099
  agents: "agents",
1655
2100
  applications: "applications",
2101
+ authorizationDetailTypes: "authorization-detail-types",
2102
+ clientRegistrations: "oauth2/dcr/register",
1656
2103
  configurationVersions: "configuration-versions",
1657
2104
  connections: "connections",
2105
+ credentialConfigurations: "openid4vci/credential-configurations",
1658
2106
  design: "design",
1659
2107
  export: "export",
1660
2108
  flows: "flows",
@@ -1664,6 +2112,8 @@ const MANAGEMENT_COLLECTIONS = {
1664
2112
  import: "import",
1665
2113
  notificationTemplates: "notification-templates",
1666
2114
  organizationUnits: "organization-units",
2115
+ presentationDefinitions: "openid4vp/presentation-definitions",
2116
+ projects: "projects",
1667
2117
  resourceServers: "resource-servers",
1668
2118
  roles: "roles",
1669
2119
  secrets: "secrets",
@@ -1728,11 +2178,11 @@ var getSessionCookieOptions_default = getSessionCookieOptions;
1728
2178
  //#endregion
1729
2179
  //#region src/index.ts
1730
2180
  if (!globalThis.fetch) {
1731
- globalThis.fetch = fetch;
2181
+ globalThis.fetch = fetch$1;
1732
2182
  globalThis.Headers = Headers;
1733
2183
  globalThis.Request = Request;
1734
2184
  globalThis.Response = Response;
1735
2185
  }
1736
2186
 
1737
2187
  //#endregion
1738
- 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 };
2188
+ 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, evaluateAccess_default as evaluateAccess, evaluateAccesses_default as evaluateAccesses, generateSessionId_default as generateSessionId, getManagementCollectionUrls, getSessionCookieOptions_default as getSessionCookieOptions, matchManagementUrl, searchActions_default as searchActions };