@thunderid/node 1.11.0 → 1.12.1

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, executeEmbeddedSelfFlow, 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);
@@ -1667,8 +2098,11 @@ const MANAGEMENT_COLLECTIONS = {
1667
2098
  agentTypes: "agent-types",
1668
2099
  agents: "agents",
1669
2100
  applications: "applications",
2101
+ authorizationDetailTypes: "authorization-detail-types",
2102
+ clientRegistrations: "oauth2/dcr/register",
1670
2103
  configurationVersions: "configuration-versions",
1671
2104
  connections: "connections",
2105
+ credentialConfigurations: "openid4vci/credential-configurations",
1672
2106
  design: "design",
1673
2107
  export: "export",
1674
2108
  flows: "flows",
@@ -1678,6 +2112,8 @@ const MANAGEMENT_COLLECTIONS = {
1678
2112
  import: "import",
1679
2113
  notificationTemplates: "notification-templates",
1680
2114
  organizationUnits: "organization-units",
2115
+ presentationDefinitions: "openid4vp/presentation-definitions",
2116
+ projects: "projects",
1681
2117
  resourceServers: "resource-servers",
1682
2118
  roles: "roles",
1683
2119
  secrets: "secrets",
@@ -1742,11 +2178,11 @@ var getSessionCookieOptions_default = getSessionCookieOptions;
1742
2178
  //#endregion
1743
2179
  //#region src/index.ts
1744
2180
  if (!globalThis.fetch) {
1745
- globalThis.fetch = fetch;
2181
+ globalThis.fetch = fetch$1;
1746
2182
  globalThis.Headers = Headers;
1747
2183
  globalThis.Request = Request;
1748
2184
  globalThis.Response = Response;
1749
2185
  }
1750
2186
 
1751
2187
  //#endregion
1752
- 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 };
@@ -0,0 +1,112 @@
1
+ /**
2
+ * The subject of an access evaluation (AuthZEN): who acts.
3
+ */
4
+ export interface AccessSubject {
5
+ /**
6
+ * The subject identifier, such as a user ID.
7
+ */
8
+ id: string;
9
+ properties?: Record<string, unknown>;
10
+ /**
11
+ * The subject type, such as `user`. When omitted, the server skips subject type validation.
12
+ */
13
+ type?: string;
14
+ }
15
+ /**
16
+ * The resource of an access evaluation: a resource server identifier as `type`.
17
+ */
18
+ export interface AccessResource {
19
+ id?: string;
20
+ properties?: Record<string, unknown>;
21
+ /**
22
+ * The ThunderID resource server identifier, such as `https://api.example.com/booking`.
23
+ */
24
+ type: string;
25
+ }
26
+ /**
27
+ * The action of an access evaluation: a permission registered under the resource server.
28
+ */
29
+ export interface AccessAction {
30
+ /**
31
+ * The permission name, such as `booking:read`.
32
+ */
33
+ name: string;
34
+ properties?: Record<string, unknown>;
35
+ }
36
+ /**
37
+ * One access evaluation request.
38
+ */
39
+ export interface AccessEvaluationRequest {
40
+ action: AccessAction;
41
+ context?: Record<string, unknown>;
42
+ resource: AccessResource;
43
+ subject: AccessSubject;
44
+ }
45
+ /**
46
+ * A decision. A denial is a result, not an error: an unknown resource or an unregistered action comes
47
+ * back as `decision: false` with the reason in `context`.
48
+ */
49
+ export interface AccessEvaluationResponse {
50
+ context?: Record<string, unknown>;
51
+ decision: boolean;
52
+ }
53
+ /**
54
+ * A batch of evaluations. `defaults` (any of subject, action, resource and context) apply to every
55
+ * evaluation that does not set that member itself.
56
+ */
57
+ export interface AccessEvaluationsRequest {
58
+ defaults?: Partial<AccessEvaluationRequest>;
59
+ evaluations: Partial<AccessEvaluationRequest>[];
60
+ }
61
+ /**
62
+ * Asks which actions a subject may perform on a resource.
63
+ */
64
+ export interface AccessActionSearchRequest {
65
+ context?: Record<string, unknown>;
66
+ resource: AccessResource;
67
+ subject: AccessSubject;
68
+ }
69
+ /**
70
+ * The actions the subject may perform.
71
+ */
72
+ export interface AccessActionSearchResponse {
73
+ results: AccessAction[];
74
+ }
75
+ /**
76
+ * The server's AuthZEN policy decision point metadata, from `/.well-known/authzen-configuration`.
77
+ */
78
+ export interface AuthZENConfiguration {
79
+ access_evaluation_endpoint: string;
80
+ access_evaluations_endpoint?: string;
81
+ policy_decision_point: string;
82
+ search_action_endpoint?: string;
83
+ }
84
+ /**
85
+ * Where access evaluation requests go and how they are authorized.
86
+ */
87
+ export interface AccessEvaluationRequestConfig {
88
+ /**
89
+ * The server's base URL. Its `/.well-known/authzen-configuration` supplies the endpoints, and its
90
+ * `policy_decision_point` must match it exactly.
91
+ */
92
+ baseUrl: string;
93
+ /**
94
+ * Explicit endpoint overrides, each on the origin of `baseUrl`. When every endpoint an operation
95
+ * needs is set, the metadata is not fetched.
96
+ */
97
+ endpoints?: {
98
+ evaluation?: string;
99
+ evaluations?: string;
100
+ searchAction?: string;
101
+ };
102
+ /**
103
+ * Optional custom fetcher. Defaults to the global `fetch`.
104
+ */
105
+ fetcher?: (url: string, config: RequestInit) => Promise<Response>;
106
+ /**
107
+ * The server-level secret, sent in the `Direct-Auth-Secret` header. Never logged.
108
+ */
109
+ secret: string;
110
+ signal?: AbortSignal;
111
+ }
112
+ //# sourceMappingURL=access-evaluation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"access-evaluation.d.ts","sourceRoot":"","sources":["../../src/models/access-evaluation.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,QAAQ,EAAE,cAAc,CAAC;IACzB,OAAO,EAAE,aAAa,CAAC;CACxB;AAED;;;GAGG;AACH,MAAM,WAAW,wBAAwB;IACvC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAC5C,WAAW,EAAE,OAAO,CAAC,uBAAuB,CAAC,EAAE,CAAC;CACjD;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,QAAQ,EAAE,cAAc,CAAC;IACzB,OAAO,EAAE,aAAa,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,YAAY,EAAE,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,0BAA0B,EAAE,MAAM,CAAC;IACnC,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,6BAA6B;IAC5C;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,SAAS,CAAC,EAAE;QACV,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;IACF;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IAClE;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB"}