@authyon/server 0.2.0-beta.21 → 0.2.0-beta.22
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/README.md +541 -506
- package/dist/{authorization-Soblu-A5.d.cts → authorization-BLENxur8.d.cts} +18 -4
- package/dist/{authorization-D8tznR96.d.ts → authorization-Clf0Jx-U.d.ts} +18 -4
- package/dist/{authyonServerClient-COrfN4o_.d.cts → authyonServerClient-CW46xIRD.d.cts} +167 -9
- package/dist/{authyonServerClient-COrfN4o_.d.ts → authyonServerClient-CW46xIRD.d.ts} +167 -9
- package/dist/bff.d.cts +1 -1
- package/dist/bff.d.ts +1 -1
- package/dist/{chunk-NKWQMYB3.js → chunk-WF26WYSX.js} +37 -7
- package/dist/index.cjs +123 -14
- package/dist/index.d.cts +54 -4
- package/dist/index.d.ts +54 -4
- package/dist/index.js +86 -8
- package/dist/next.cjs +11 -1
- package/dist/next.d.cts +2 -2
- package/dist/next.d.ts +2 -2
- package/dist/next.js +1 -1
- package/package.json +81 -81
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
// ../../internal/core/http/clientIp.ts
|
|
2
|
+
var CLIENT_IP_HEADER = "X-Authyon-Client-Ip";
|
|
2
3
|
function clientIpHeaders(context) {
|
|
3
4
|
if (!context?.clientIp) return {};
|
|
4
|
-
|
|
5
|
+
const ip = normalizeClientIp(context.clientIp);
|
|
6
|
+
return { "X-Forwarded-For": ip, [CLIENT_IP_HEADER]: ip };
|
|
5
7
|
}
|
|
6
8
|
function normalizeClientIp(value) {
|
|
7
9
|
let ip = value.trim();
|
|
@@ -222,12 +224,29 @@ function createAuthyonAbility(source = {}, options = {}) {
|
|
|
222
224
|
return new AuthyonAbility(createAuthyonRules(source, options), options.detectSubjectType);
|
|
223
225
|
}
|
|
224
226
|
function hasPermission(source, requiredPermission) {
|
|
225
|
-
const
|
|
226
|
-
if (!
|
|
227
|
-
return false;
|
|
228
|
-
}
|
|
227
|
+
const required = requiredPermission?.trim() ?? "";
|
|
228
|
+
if (!isWellFormedPermission(required)) return false;
|
|
229
229
|
const permissionSource = isPermissionList(source) ? { permissions: source } : source;
|
|
230
|
-
|
|
230
|
+
const granted = [
|
|
231
|
+
...permissionSource.permissions ?? [],
|
|
232
|
+
...permissionSource.scope?.split(/\s+/).filter(Boolean) ?? []
|
|
233
|
+
];
|
|
234
|
+
return granted.some((permission) => grants(permission.trim(), required));
|
|
235
|
+
}
|
|
236
|
+
function grants(granted, required) {
|
|
237
|
+
if (!isWellFormedPermission(granted)) return false;
|
|
238
|
+
if (isFullWildcard(granted)) return true;
|
|
239
|
+
const grantedSegments = granted.split(":");
|
|
240
|
+
const requiredSegments = required.split(":");
|
|
241
|
+
if (grantedSegments.length !== requiredSegments.length) return false;
|
|
242
|
+
return grantedSegments.every(
|
|
243
|
+
(segment, index) => segment === "*" || segment === requiredSegments[index]
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
function isWellFormedPermission(permission) {
|
|
247
|
+
if (!permission) return false;
|
|
248
|
+
const segments = permission.split(":");
|
|
249
|
+
return segments.length >= 2 && segments.every((segment) => segment.length > 0);
|
|
231
250
|
}
|
|
232
251
|
function hasPermissionGroup(source, group) {
|
|
233
252
|
const hasAll = (group.allOf ?? []).every((permission) => hasPermission(source, permission));
|
|
@@ -242,13 +261,23 @@ function createAuthyonRules(source = {}, options = {}) {
|
|
|
242
261
|
...source.permissions ?? [],
|
|
243
262
|
...source.scope?.split(/\s+/).filter(Boolean) ?? []
|
|
244
263
|
]);
|
|
245
|
-
const rules = [...permissions].map(
|
|
264
|
+
const rules = [...permissions].map(grantToRule).filter(isAbilityRule);
|
|
246
265
|
for (const role of /* @__PURE__ */ new Set([...source.roles ?? [], ...options.roles ?? []])) {
|
|
247
266
|
rules.push(...(options.roleRules?.[role] ?? []).map(cloneRule));
|
|
248
267
|
}
|
|
249
268
|
rules.push(...(options.rules ?? []).map(cloneRule));
|
|
250
269
|
return rules;
|
|
251
270
|
}
|
|
271
|
+
function grantToRule(permission) {
|
|
272
|
+
const normalized = permission.trim();
|
|
273
|
+
if (normalized && isFullWildcard(normalized)) {
|
|
274
|
+
return { action: "manage", subject: "all" };
|
|
275
|
+
}
|
|
276
|
+
return permissionToRule(normalized);
|
|
277
|
+
}
|
|
278
|
+
function isFullWildcard(permission) {
|
|
279
|
+
return permission.split(":").every((segment) => segment === "*");
|
|
280
|
+
}
|
|
252
281
|
function permissionToRule(permission) {
|
|
253
282
|
const normalized = permission.trim();
|
|
254
283
|
if (!normalized) return null;
|
|
@@ -467,6 +496,7 @@ function unauthenticated() {
|
|
|
467
496
|
}
|
|
468
497
|
|
|
469
498
|
export {
|
|
499
|
+
CLIENT_IP_HEADER,
|
|
470
500
|
clientIpHeaders,
|
|
471
501
|
normalizeClientIp,
|
|
472
502
|
TokenVerificationError,
|
package/dist/index.cjs
CHANGED
|
@@ -33,13 +33,16 @@ __export(index_exports, {
|
|
|
33
33
|
AuthyonError: () => AuthyonError,
|
|
34
34
|
AuthyonServerClient: () => AuthyonServerClient,
|
|
35
35
|
AuthyonServerClientBuilder: () => AuthyonServerClientBuilder,
|
|
36
|
+
CLIENT_IP_HEADER: () => CLIENT_IP_HEADER,
|
|
36
37
|
ErrorCodes: () => ErrorCodes,
|
|
37
38
|
FetchHttpAdapter: () => FetchHttpAdapter,
|
|
38
39
|
JwksTokenVerifier: () => JwksTokenVerifier,
|
|
39
40
|
LoggingHttpAdapter: () => LoggingHttpAdapter,
|
|
41
|
+
SubtenantPermissions: () => SubtenantPermissions,
|
|
40
42
|
TENANT_FILTER_MAX_DEPTH: () => TENANT_FILTER_MAX_DEPTH,
|
|
41
43
|
TENANT_FILTER_MAX_VALUES: () => TENANT_FILTER_MAX_VALUES,
|
|
42
44
|
TENANT_FILTER_MAX_VALUE_LENGTH: () => TENANT_FILTER_MAX_VALUE_LENGTH,
|
|
45
|
+
TenantPermissions: () => TenantPermissions,
|
|
43
46
|
TenantScopedClient: () => TenantScopedClient,
|
|
44
47
|
TokenVerificationError: () => TokenVerificationError,
|
|
45
48
|
UserScopedClient: () => UserScopedClient,
|
|
@@ -645,9 +648,11 @@ var JsonHttpClient = class {
|
|
|
645
648
|
};
|
|
646
649
|
|
|
647
650
|
// ../../internal/core/http/clientIp.ts
|
|
651
|
+
var CLIENT_IP_HEADER = "X-Authyon-Client-Ip";
|
|
648
652
|
function clientIpHeaders(context) {
|
|
649
653
|
if (!context?.clientIp) return {};
|
|
650
|
-
|
|
654
|
+
const ip = normalizeClientIp(context.clientIp);
|
|
655
|
+
return { "X-Forwarded-For": ip, [CLIENT_IP_HEADER]: ip };
|
|
651
656
|
}
|
|
652
657
|
function normalizeClientIp(value) {
|
|
653
658
|
let ip = value.trim();
|
|
@@ -802,6 +807,11 @@ function isRecord(value) {
|
|
|
802
807
|
}
|
|
803
808
|
|
|
804
809
|
// src/client/authyonServerClient.ts
|
|
810
|
+
var ROOT_PARENT_ID = "00000000-0000-0000-0000-000000000000";
|
|
811
|
+
function tenantListQuery({ parentId, ...rest }) {
|
|
812
|
+
if (parentId === void 0) return rest;
|
|
813
|
+
return { ...rest, parentId: parentId === null ? ROOT_PARENT_ID : parentId };
|
|
814
|
+
}
|
|
805
815
|
var _clientSecret;
|
|
806
816
|
var AuthyonServerClient = class {
|
|
807
817
|
constructor(options = {}) {
|
|
@@ -1044,15 +1054,47 @@ var AuthyonServerClient = class {
|
|
|
1044
1054
|
* });
|
|
1045
1055
|
* ```
|
|
1046
1056
|
*
|
|
1057
|
+
* `parentId` narrows the page to one level of the tree — `children()`
|
|
1058
|
+
* and `roots()` below are the same call with that one option set.
|
|
1059
|
+
*
|
|
1047
1060
|
* Against an Authyon API older than 2026-10-21 this route ignored
|
|
1048
1061
|
* skip/take/search and answered with a bare array; one older than
|
|
1049
|
-
* 2026-10-22 ignores `filter
|
|
1050
|
-
* rather than an error.
|
|
1062
|
+
* 2026-10-22 ignores `filter` and one older than 2026-10-31 ignores
|
|
1063
|
+
* `parentId`, which read as a page that is too wide rather than an error.
|
|
1064
|
+
*/
|
|
1065
|
+
list: (params = {}) => this.request("/env/tenants", { envBearer: true, query: tenantListQuery(params) }),
|
|
1066
|
+
/**
|
|
1067
|
+
* One page of a tenant's direct sub-tenants — `list()` with `parentId`.
|
|
1068
|
+
*
|
|
1069
|
+
* Only one level: a node's own children carry `childCount`, so a tree
|
|
1070
|
+
* view asks again where that is above zero instead of reading the whole
|
|
1071
|
+
* subtree to draw the first level of it.
|
|
1072
|
+
*/
|
|
1073
|
+
children: (parentTenantId, params = {}) => this.environment.tenants.list({ ...params, parentId: parentTenantId }),
|
|
1074
|
+
/**
|
|
1075
|
+
* One page of the environment's root tenants — `list()` with no parent.
|
|
1076
|
+
*
|
|
1077
|
+
* This is the first level of the tree, and the difference from `list()`
|
|
1078
|
+
* is worth keeping straight: `list()` returns every tenant at every
|
|
1079
|
+
* depth, which is what a flat picker wants and what a tree view must not
|
|
1080
|
+
* start from.
|
|
1081
|
+
*/
|
|
1082
|
+
roots: (params = {}) => this.environment.tenants.list({ ...params, parentId: null }),
|
|
1083
|
+
/**
|
|
1084
|
+
* POST /env/tenants — create a tenant in the environment.
|
|
1085
|
+
*
|
|
1086
|
+
* `parentTenantId` nests it under an existing tenant. The environment's
|
|
1087
|
+
* `maxTenantDepth` has to allow the level — it ships as `1`, roots only,
|
|
1088
|
+
* so this answers `tenant.depth.not_allowed` until an operator raises it
|
|
1089
|
+
* in the console.
|
|
1051
1090
|
*/
|
|
1052
|
-
list: (params = {}) => this.request("/env/tenants", { envBearer: true, query: params }),
|
|
1053
|
-
/** POST /env/tenants — create a tenant in the environment. */
|
|
1054
1091
|
create: (input) => this.request("/env/tenants", { method: "POST", envBearer: true, body: input }),
|
|
1055
|
-
/**
|
|
1092
|
+
/**
|
|
1093
|
+
* GET /env/tenants/{tenantId} — fetch a tenant by id.
|
|
1094
|
+
*
|
|
1095
|
+
* Returns `ancestors` as well, the chain above it root first, so a
|
|
1096
|
+
* breadcrumb costs this one call rather than one per level.
|
|
1097
|
+
*/
|
|
1056
1098
|
get: (tenantId) => this.request(`/env/tenants/${encodeURIComponent(tenantId)}`, { envBearer: true }),
|
|
1057
1099
|
/** PUT /env/tenants/{tenantId} — update a tenant. */
|
|
1058
1100
|
update: (tenantId, input) => this.request(`/env/tenants/${encodeURIComponent(tenantId)}`, {
|
|
@@ -1066,12 +1108,23 @@ var AuthyonServerClient = class {
|
|
|
1066
1108
|
envBearer: true,
|
|
1067
1109
|
body: input
|
|
1068
1110
|
}),
|
|
1069
|
-
/**
|
|
1111
|
+
/**
|
|
1112
|
+
* POST /env/tenants/{tenantId}/disable — disable without removing tenant
|
|
1113
|
+
* data.
|
|
1114
|
+
*
|
|
1115
|
+
* Disables the branch below it too. A sub-tenant left live under a
|
|
1116
|
+
* disabled parent would go on authenticating its users, which is the one
|
|
1117
|
+
* thing switching a tenant off is there to stop — so check `childCount`
|
|
1118
|
+
* before calling this on a node with children.
|
|
1119
|
+
*/
|
|
1070
1120
|
disable: (tenantId) => this.request(`/env/tenants/${encodeURIComponent(tenantId)}/disable`, {
|
|
1071
1121
|
method: "POST",
|
|
1072
1122
|
envBearer: true
|
|
1073
1123
|
}),
|
|
1074
|
-
/**
|
|
1124
|
+
/**
|
|
1125
|
+
* DELETE /env/tenants/{tenantId} — logically delete (disable) a tenant,
|
|
1126
|
+
* and the branch below it. Same handler as `disable()`.
|
|
1127
|
+
*/
|
|
1075
1128
|
delete: (tenantId) => this.request(`/env/tenants/${encodeURIComponent(tenantId)}`, {
|
|
1076
1129
|
method: "DELETE",
|
|
1077
1130
|
envBearer: true
|
|
@@ -1712,12 +1765,29 @@ function createAuthyonAbility(source = {}, options = {}) {
|
|
|
1712
1765
|
return new AuthyonAbility(createAuthyonRules(source, options), options.detectSubjectType);
|
|
1713
1766
|
}
|
|
1714
1767
|
function hasPermission(source, requiredPermission) {
|
|
1715
|
-
const
|
|
1716
|
-
if (!
|
|
1717
|
-
return false;
|
|
1718
|
-
}
|
|
1768
|
+
const required = requiredPermission?.trim() ?? "";
|
|
1769
|
+
if (!isWellFormedPermission(required)) return false;
|
|
1719
1770
|
const permissionSource = isPermissionList(source) ? { permissions: source } : source;
|
|
1720
|
-
|
|
1771
|
+
const granted = [
|
|
1772
|
+
...permissionSource.permissions ?? [],
|
|
1773
|
+
...permissionSource.scope?.split(/\s+/).filter(Boolean) ?? []
|
|
1774
|
+
];
|
|
1775
|
+
return granted.some((permission) => grants(permission.trim(), required));
|
|
1776
|
+
}
|
|
1777
|
+
function grants(granted, required) {
|
|
1778
|
+
if (!isWellFormedPermission(granted)) return false;
|
|
1779
|
+
if (isFullWildcard(granted)) return true;
|
|
1780
|
+
const grantedSegments = granted.split(":");
|
|
1781
|
+
const requiredSegments = required.split(":");
|
|
1782
|
+
if (grantedSegments.length !== requiredSegments.length) return false;
|
|
1783
|
+
return grantedSegments.every(
|
|
1784
|
+
(segment2, index) => segment2 === "*" || segment2 === requiredSegments[index]
|
|
1785
|
+
);
|
|
1786
|
+
}
|
|
1787
|
+
function isWellFormedPermission(permission) {
|
|
1788
|
+
if (!permission) return false;
|
|
1789
|
+
const segments = permission.split(":");
|
|
1790
|
+
return segments.length >= 2 && segments.every((segment2) => segment2.length > 0);
|
|
1721
1791
|
}
|
|
1722
1792
|
function hasPermissionGroup(source, group) {
|
|
1723
1793
|
const hasAll = (group.allOf ?? []).every((permission) => hasPermission(source, permission));
|
|
@@ -1732,13 +1802,23 @@ function createAuthyonRules(source = {}, options = {}) {
|
|
|
1732
1802
|
...source.permissions ?? [],
|
|
1733
1803
|
...source.scope?.split(/\s+/).filter(Boolean) ?? []
|
|
1734
1804
|
]);
|
|
1735
|
-
const rules = [...permissions].map(
|
|
1805
|
+
const rules = [...permissions].map(grantToRule).filter(isAbilityRule);
|
|
1736
1806
|
for (const role of /* @__PURE__ */ new Set([...source.roles ?? [], ...options.roles ?? []])) {
|
|
1737
1807
|
rules.push(...(options.roleRules?.[role] ?? []).map(cloneRule));
|
|
1738
1808
|
}
|
|
1739
1809
|
rules.push(...(options.rules ?? []).map(cloneRule));
|
|
1740
1810
|
return rules;
|
|
1741
1811
|
}
|
|
1812
|
+
function grantToRule(permission) {
|
|
1813
|
+
const normalized = permission.trim();
|
|
1814
|
+
if (normalized && isFullWildcard(normalized)) {
|
|
1815
|
+
return { action: "manage", subject: "all" };
|
|
1816
|
+
}
|
|
1817
|
+
return permissionToRule(normalized);
|
|
1818
|
+
}
|
|
1819
|
+
function isFullWildcard(permission) {
|
|
1820
|
+
return permission.split(":").every((segment2) => segment2 === "*");
|
|
1821
|
+
}
|
|
1742
1822
|
function permissionToRule(permission) {
|
|
1743
1823
|
const normalized = permission.trim();
|
|
1744
1824
|
if (!normalized) return null;
|
|
@@ -1955,6 +2035,32 @@ function unauthenticated() {
|
|
|
1955
2035
|
"A valid bearer token is required"
|
|
1956
2036
|
);
|
|
1957
2037
|
}
|
|
2038
|
+
|
|
2039
|
+
// ../../internal/core/authorization/tenantPermissions.ts
|
|
2040
|
+
var TenantPermissions = {
|
|
2041
|
+
/** Rename the tenant and change its settings. */
|
|
2042
|
+
SettingsManage: "tenants:settings:manage",
|
|
2043
|
+
/** Invite an address to the tenant. */
|
|
2044
|
+
MembersInvite: "tenants:members:invite",
|
|
2045
|
+
/** Remove a member from the tenant. */
|
|
2046
|
+
MembersRemove: "tenants:members:remove"
|
|
2047
|
+
};
|
|
2048
|
+
var SubtenantPermissions = {
|
|
2049
|
+
/** Read any tenant below one you belong to. */
|
|
2050
|
+
TreeRead: "subtenants:tree:read",
|
|
2051
|
+
/** Rename a tenant below yours, and add or remove its members. */
|
|
2052
|
+
TreeManage: "subtenants:tree:manage",
|
|
2053
|
+
/** Create a tenant underneath one you belong to. */
|
|
2054
|
+
TreeCreate: "subtenants:tree:create",
|
|
2055
|
+
/**
|
|
2056
|
+
* Make a tenant below yours the ACTIVE tenant of the session — acting inside
|
|
2057
|
+
* it rather than on it from outside. Deliberately not the same permission as
|
|
2058
|
+
* {@link SubtenantPermissions.TreeManage}: administering a sub-tenant through
|
|
2059
|
+
* the management endpoints and operating as that sub-tenant are different
|
|
2060
|
+
* powers, and granting the first should not hand over the second.
|
|
2061
|
+
*/
|
|
2062
|
+
TreeSwitch: "subtenants:tree:switch"
|
|
2063
|
+
};
|
|
1958
2064
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1959
2065
|
0 && (module.exports = {
|
|
1960
2066
|
AuthorizationError,
|
|
@@ -1963,13 +2069,16 @@ function unauthenticated() {
|
|
|
1963
2069
|
AuthyonError,
|
|
1964
2070
|
AuthyonServerClient,
|
|
1965
2071
|
AuthyonServerClientBuilder,
|
|
2072
|
+
CLIENT_IP_HEADER,
|
|
1966
2073
|
ErrorCodes,
|
|
1967
2074
|
FetchHttpAdapter,
|
|
1968
2075
|
JwksTokenVerifier,
|
|
1969
2076
|
LoggingHttpAdapter,
|
|
2077
|
+
SubtenantPermissions,
|
|
1970
2078
|
TENANT_FILTER_MAX_DEPTH,
|
|
1971
2079
|
TENANT_FILTER_MAX_VALUES,
|
|
1972
2080
|
TENANT_FILTER_MAX_VALUE_LENGTH,
|
|
2081
|
+
TenantPermissions,
|
|
1973
2082
|
TenantScopedClient,
|
|
1974
2083
|
TokenVerificationError,
|
|
1975
2084
|
UserScopedClient,
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { H as HttpAdapter, a as HttpLoggerOptions, A as AuthyonServerClient } from './authyonServerClient-
|
|
2
|
-
export { b as AcceptTenantInviteInput, c as AccessTokenSource, d as Approval, e as ApprovalAssurance, f as ApprovalPayload, g as ApprovalStatus, h as ApprovalWebAuthnOptions, i as AuditEvent, j as AuthyonJwksDiscoveryOptions, k as AuthyonJwtClaims, l as AuthyonServerClientOptions, C as ClientCredentials,
|
|
3
|
-
export { b as AbilityConditions, c as AbilityEvent, d as AbilityListener, e as AbilityRequirement, f as AbilityRule, A as AbilitySubject, g as AuthorizationContext, a as AuthorizationError, h as AuthorizationOptions, i as AuthyonAbility, j as AuthyonAbilityBuilder, k as AuthyonAbilityOptions, l as AuthyonPermissionSource, E as ExpressAuthorizationMiddlewareOptions, m as ExpressNext, n as ExpressRequestLike, o as ExpressResponseLike, P as PermissionGroup, R as RequestAuthorizationOptions, p as authorizeRequest, q as authorizeToken, r as createAuthorizationErrorResponse, s as createAuthyonAbility, t as createAuthyonRules, u as createExpressAuthorizationMiddleware, v as hasPermission, w as hasPermissionGroup } from './authorization-
|
|
1
|
+
import { H as HttpAdapter, a as HttpLoggerOptions, A as AuthyonServerClient } from './authyonServerClient-CW46xIRD.cjs';
|
|
2
|
+
export { b as AcceptTenantInviteInput, c as AccessTokenSource, d as Approval, e as ApprovalAssurance, f as ApprovalPayload, g as ApprovalStatus, h as ApprovalWebAuthnOptions, i as AuditEvent, j as AuthyonJwksDiscoveryOptions, k as AuthyonJwtClaims, l as AuthyonServerClientOptions, m as AuthyonTenantClaim, C as CLIENT_IP_HEADER, n as ClientCredentials, o as ClientRequestContext, p as ConfirmApprovalInput, q as ConsumedApproval, r as CreateApprovalInput, s as CreateCredentialInput, t as CreateOrganizationInput, u as CreatePermissionInput, v as CreateTenantCredentialInput, w as CreateUserInput, x as CredentialCreator, y as CredentialDetail, z as CredentialListOptions, B as CredentialPermissionsInput, E as EnvironmentUser, F as FetchHttpAdapter, D as HttpAdapterRequest, G as HttpLogEvent, I as HttpLogger, K as IntrospectResult, L as InviteTenantMemberInput, M as IssuePasswordResetInput, N as JsonWebKeySet, J as JwksTokenVerifier, O as JwksTokenVerifierOptions, P as LoggingHttpAdapter, Q as LoginActivity, R as OpenIdConfiguration, S as Organization, T as OtpCheckResult, U as Paged, V as PaginationOptions, W as PasswordResetCompleted, X as PasswordResetIssued, Y as PasswordResetPreview, Z as Permission, _ as PermissionsByRole, $ as ReservedPermissions, a0 as Role, a1 as RoleGrant, a2 as RoleInput, a3 as RoleList, a4 as RolePermissions, a5 as SafeJwtAlgorithm, a6 as SecurityMethods, a7 as SubjectApprovals, a8 as SubjectSecurity, a9 as TENANT_FILTER_MAX_DEPTH, aa as TENANT_FILTER_MAX_VALUES, ab as TENANT_FILTER_MAX_VALUE_LENGTH, ac as TenantAncestor, ad as TenantClientValidationResult, ae as TenantCredentialIssued, af as TenantCredentialSummary, ag as TenantFilterExpression, ah as TenantFilterValue, ai as TenantInvite, aj as TenantInviteAccepted, ak as TenantInviteInput, al as TenantInviteIssued, am as TenantInvitePreview, an as TenantInviteStatus, ao as TenantListOptions, ap as TenantMember, aq as TenantMemberPage, ar as TenantMembership, as as TenantScopedClient, at as TokenResult, au as TokenVerificationError, av as TokenVerificationErrorCode, aw as UpdateOrganizationInput, ax as User, ay as UserScopedClient, az as ValidateResult, aA as VerifiedAccessToken, aB as createClient, aC as normalizeClientIp, aD as tenantFilter } from './authyonServerClient-CW46xIRD.cjs';
|
|
3
|
+
export { b as AbilityConditions, c as AbilityEvent, d as AbilityListener, e as AbilityRequirement, f as AbilityRule, A as AbilitySubject, g as AuthorizationContext, a as AuthorizationError, h as AuthorizationOptions, i as AuthyonAbility, j as AuthyonAbilityBuilder, k as AuthyonAbilityOptions, l as AuthyonPermissionSource, E as ExpressAuthorizationMiddlewareOptions, m as ExpressNext, n as ExpressRequestLike, o as ExpressResponseLike, P as PermissionGroup, R as RequestAuthorizationOptions, p as authorizeRequest, q as authorizeToken, r as createAuthorizationErrorResponse, s as createAuthyonAbility, t as createAuthyonRules, u as createExpressAuthorizationMiddleware, v as hasPermission, w as hasPermissionGroup } from './authorization-BLENxur8.cjs';
|
|
4
4
|
import 'jose';
|
|
5
5
|
|
|
6
6
|
declare const ErrorCodes: {
|
|
@@ -94,4 +94,54 @@ declare class AuthyonServerClientBuilder {
|
|
|
94
94
|
build(): AuthyonServerClient;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
|
|
97
|
+
/**
|
|
98
|
+
* The permission values the tenant surface checks, as constants.
|
|
99
|
+
*
|
|
100
|
+
* They are strings on the wire and nothing forces you through here — the point
|
|
101
|
+
* is that a rename shows up as a type error instead of as a 403 nobody can
|
|
102
|
+
* explain. `tenants:settings:manage` is exactly that case: it used to be
|
|
103
|
+
* written `tenants:manage`, a two-segment value the API could not even store,
|
|
104
|
+
* so the endpoint requiring it refused every caller.
|
|
105
|
+
*/
|
|
106
|
+
declare const TenantPermissions: {
|
|
107
|
+
/** Rename the tenant and change its settings. */
|
|
108
|
+
readonly SettingsManage: "tenants:settings:manage";
|
|
109
|
+
/** Invite an address to the tenant. */
|
|
110
|
+
readonly MembersInvite: "tenants:members:invite";
|
|
111
|
+
/** Remove a member from the tenant. */
|
|
112
|
+
readonly MembersRemove: "tenants:members:remove";
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* What lets a member of one tenant reach the tenants beneath it.
|
|
116
|
+
*
|
|
117
|
+
* A separate domain, not a suffix on `tenants:…`, and the reason is worth
|
|
118
|
+
* knowing before you grant one: permissions match per segment, so naming these
|
|
119
|
+
* `tenants:tree:manage` would have handed every role already holding
|
|
120
|
+
* `tenants:*:*` power over the whole subtree the day the hierarchy shipped — a
|
|
121
|
+
* widening that appears in no diff. `subtenants:…` is only covered by `*:*:*`,
|
|
122
|
+
* which is explicit superuser.
|
|
123
|
+
*
|
|
124
|
+
* Reaching down is opt-in at every level: holding `tenants:settings:manage` on
|
|
125
|
+
* a parent grants nothing below it, and each of these is granted at the node
|
|
126
|
+
* the caller belongs to, never at the target.
|
|
127
|
+
*/
|
|
128
|
+
declare const SubtenantPermissions: {
|
|
129
|
+
/** Read any tenant below one you belong to. */
|
|
130
|
+
readonly TreeRead: "subtenants:tree:read";
|
|
131
|
+
/** Rename a tenant below yours, and add or remove its members. */
|
|
132
|
+
readonly TreeManage: "subtenants:tree:manage";
|
|
133
|
+
/** Create a tenant underneath one you belong to. */
|
|
134
|
+
readonly TreeCreate: "subtenants:tree:create";
|
|
135
|
+
/**
|
|
136
|
+
* Make a tenant below yours the ACTIVE tenant of the session — acting inside
|
|
137
|
+
* it rather than on it from outside. Deliberately not the same permission as
|
|
138
|
+
* {@link SubtenantPermissions.TreeManage}: administering a sub-tenant through
|
|
139
|
+
* the management endpoints and operating as that sub-tenant are different
|
|
140
|
+
* powers, and granting the first should not hand over the second.
|
|
141
|
+
*/
|
|
142
|
+
readonly TreeSwitch: "subtenants:tree:switch";
|
|
143
|
+
};
|
|
144
|
+
type TenantPermission = (typeof TenantPermissions)[keyof typeof TenantPermissions];
|
|
145
|
+
type SubtenantPermission = (typeof SubtenantPermissions)[keyof typeof SubtenantPermissions];
|
|
146
|
+
|
|
147
|
+
export { AuthyonError, type AuthyonErrorAction, type AuthyonErrorBody, type AuthyonErrorCategory, type AuthyonErrorInterpretation, AuthyonServerClient, AuthyonServerClientBuilder, ErrorCodes, HttpAdapter, HttpLoggerOptions, type KnownErrorCode, type SubtenantPermission, SubtenantPermissions, type TenantPermission, TenantPermissions };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { H as HttpAdapter, a as HttpLoggerOptions, A as AuthyonServerClient } from './authyonServerClient-
|
|
2
|
-
export { b as AcceptTenantInviteInput, c as AccessTokenSource, d as Approval, e as ApprovalAssurance, f as ApprovalPayload, g as ApprovalStatus, h as ApprovalWebAuthnOptions, i as AuditEvent, j as AuthyonJwksDiscoveryOptions, k as AuthyonJwtClaims, l as AuthyonServerClientOptions, C as ClientCredentials,
|
|
3
|
-
export { b as AbilityConditions, c as AbilityEvent, d as AbilityListener, e as AbilityRequirement, f as AbilityRule, A as AbilitySubject, g as AuthorizationContext, a as AuthorizationError, h as AuthorizationOptions, i as AuthyonAbility, j as AuthyonAbilityBuilder, k as AuthyonAbilityOptions, l as AuthyonPermissionSource, E as ExpressAuthorizationMiddlewareOptions, m as ExpressNext, n as ExpressRequestLike, o as ExpressResponseLike, P as PermissionGroup, R as RequestAuthorizationOptions, p as authorizeRequest, q as authorizeToken, r as createAuthorizationErrorResponse, s as createAuthyonAbility, t as createAuthyonRules, u as createExpressAuthorizationMiddleware, v as hasPermission, w as hasPermissionGroup } from './authorization-
|
|
1
|
+
import { H as HttpAdapter, a as HttpLoggerOptions, A as AuthyonServerClient } from './authyonServerClient-CW46xIRD.js';
|
|
2
|
+
export { b as AcceptTenantInviteInput, c as AccessTokenSource, d as Approval, e as ApprovalAssurance, f as ApprovalPayload, g as ApprovalStatus, h as ApprovalWebAuthnOptions, i as AuditEvent, j as AuthyonJwksDiscoveryOptions, k as AuthyonJwtClaims, l as AuthyonServerClientOptions, m as AuthyonTenantClaim, C as CLIENT_IP_HEADER, n as ClientCredentials, o as ClientRequestContext, p as ConfirmApprovalInput, q as ConsumedApproval, r as CreateApprovalInput, s as CreateCredentialInput, t as CreateOrganizationInput, u as CreatePermissionInput, v as CreateTenantCredentialInput, w as CreateUserInput, x as CredentialCreator, y as CredentialDetail, z as CredentialListOptions, B as CredentialPermissionsInput, E as EnvironmentUser, F as FetchHttpAdapter, D as HttpAdapterRequest, G as HttpLogEvent, I as HttpLogger, K as IntrospectResult, L as InviteTenantMemberInput, M as IssuePasswordResetInput, N as JsonWebKeySet, J as JwksTokenVerifier, O as JwksTokenVerifierOptions, P as LoggingHttpAdapter, Q as LoginActivity, R as OpenIdConfiguration, S as Organization, T as OtpCheckResult, U as Paged, V as PaginationOptions, W as PasswordResetCompleted, X as PasswordResetIssued, Y as PasswordResetPreview, Z as Permission, _ as PermissionsByRole, $ as ReservedPermissions, a0 as Role, a1 as RoleGrant, a2 as RoleInput, a3 as RoleList, a4 as RolePermissions, a5 as SafeJwtAlgorithm, a6 as SecurityMethods, a7 as SubjectApprovals, a8 as SubjectSecurity, a9 as TENANT_FILTER_MAX_DEPTH, aa as TENANT_FILTER_MAX_VALUES, ab as TENANT_FILTER_MAX_VALUE_LENGTH, ac as TenantAncestor, ad as TenantClientValidationResult, ae as TenantCredentialIssued, af as TenantCredentialSummary, ag as TenantFilterExpression, ah as TenantFilterValue, ai as TenantInvite, aj as TenantInviteAccepted, ak as TenantInviteInput, al as TenantInviteIssued, am as TenantInvitePreview, an as TenantInviteStatus, ao as TenantListOptions, ap as TenantMember, aq as TenantMemberPage, ar as TenantMembership, as as TenantScopedClient, at as TokenResult, au as TokenVerificationError, av as TokenVerificationErrorCode, aw as UpdateOrganizationInput, ax as User, ay as UserScopedClient, az as ValidateResult, aA as VerifiedAccessToken, aB as createClient, aC as normalizeClientIp, aD as tenantFilter } from './authyonServerClient-CW46xIRD.js';
|
|
3
|
+
export { b as AbilityConditions, c as AbilityEvent, d as AbilityListener, e as AbilityRequirement, f as AbilityRule, A as AbilitySubject, g as AuthorizationContext, a as AuthorizationError, h as AuthorizationOptions, i as AuthyonAbility, j as AuthyonAbilityBuilder, k as AuthyonAbilityOptions, l as AuthyonPermissionSource, E as ExpressAuthorizationMiddlewareOptions, m as ExpressNext, n as ExpressRequestLike, o as ExpressResponseLike, P as PermissionGroup, R as RequestAuthorizationOptions, p as authorizeRequest, q as authorizeToken, r as createAuthorizationErrorResponse, s as createAuthyonAbility, t as createAuthyonRules, u as createExpressAuthorizationMiddleware, v as hasPermission, w as hasPermissionGroup } from './authorization-Clf0Jx-U.js';
|
|
4
4
|
import 'jose';
|
|
5
5
|
|
|
6
6
|
declare const ErrorCodes: {
|
|
@@ -94,4 +94,54 @@ declare class AuthyonServerClientBuilder {
|
|
|
94
94
|
build(): AuthyonServerClient;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
|
|
97
|
+
/**
|
|
98
|
+
* The permission values the tenant surface checks, as constants.
|
|
99
|
+
*
|
|
100
|
+
* They are strings on the wire and nothing forces you through here — the point
|
|
101
|
+
* is that a rename shows up as a type error instead of as a 403 nobody can
|
|
102
|
+
* explain. `tenants:settings:manage` is exactly that case: it used to be
|
|
103
|
+
* written `tenants:manage`, a two-segment value the API could not even store,
|
|
104
|
+
* so the endpoint requiring it refused every caller.
|
|
105
|
+
*/
|
|
106
|
+
declare const TenantPermissions: {
|
|
107
|
+
/** Rename the tenant and change its settings. */
|
|
108
|
+
readonly SettingsManage: "tenants:settings:manage";
|
|
109
|
+
/** Invite an address to the tenant. */
|
|
110
|
+
readonly MembersInvite: "tenants:members:invite";
|
|
111
|
+
/** Remove a member from the tenant. */
|
|
112
|
+
readonly MembersRemove: "tenants:members:remove";
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* What lets a member of one tenant reach the tenants beneath it.
|
|
116
|
+
*
|
|
117
|
+
* A separate domain, not a suffix on `tenants:…`, and the reason is worth
|
|
118
|
+
* knowing before you grant one: permissions match per segment, so naming these
|
|
119
|
+
* `tenants:tree:manage` would have handed every role already holding
|
|
120
|
+
* `tenants:*:*` power over the whole subtree the day the hierarchy shipped — a
|
|
121
|
+
* widening that appears in no diff. `subtenants:…` is only covered by `*:*:*`,
|
|
122
|
+
* which is explicit superuser.
|
|
123
|
+
*
|
|
124
|
+
* Reaching down is opt-in at every level: holding `tenants:settings:manage` on
|
|
125
|
+
* a parent grants nothing below it, and each of these is granted at the node
|
|
126
|
+
* the caller belongs to, never at the target.
|
|
127
|
+
*/
|
|
128
|
+
declare const SubtenantPermissions: {
|
|
129
|
+
/** Read any tenant below one you belong to. */
|
|
130
|
+
readonly TreeRead: "subtenants:tree:read";
|
|
131
|
+
/** Rename a tenant below yours, and add or remove its members. */
|
|
132
|
+
readonly TreeManage: "subtenants:tree:manage";
|
|
133
|
+
/** Create a tenant underneath one you belong to. */
|
|
134
|
+
readonly TreeCreate: "subtenants:tree:create";
|
|
135
|
+
/**
|
|
136
|
+
* Make a tenant below yours the ACTIVE tenant of the session — acting inside
|
|
137
|
+
* it rather than on it from outside. Deliberately not the same permission as
|
|
138
|
+
* {@link SubtenantPermissions.TreeManage}: administering a sub-tenant through
|
|
139
|
+
* the management endpoints and operating as that sub-tenant are different
|
|
140
|
+
* powers, and granting the first should not hand over the second.
|
|
141
|
+
*/
|
|
142
|
+
readonly TreeSwitch: "subtenants:tree:switch";
|
|
143
|
+
};
|
|
144
|
+
type TenantPermission = (typeof TenantPermissions)[keyof typeof TenantPermissions];
|
|
145
|
+
type SubtenantPermission = (typeof SubtenantPermissions)[keyof typeof SubtenantPermissions];
|
|
146
|
+
|
|
147
|
+
export { AuthyonError, type AuthyonErrorAction, type AuthyonErrorBody, type AuthyonErrorCategory, type AuthyonErrorInterpretation, AuthyonServerClient, AuthyonServerClientBuilder, ErrorCodes, HttpAdapter, HttpLoggerOptions, type KnownErrorCode, type SubtenantPermission, SubtenantPermissions, type TenantPermission, TenantPermissions };
|
package/dist/index.js
CHANGED
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
AuthorizationError,
|
|
13
13
|
AuthyonAbility,
|
|
14
14
|
AuthyonAbilityBuilder,
|
|
15
|
+
CLIENT_IP_HEADER,
|
|
15
16
|
JwksTokenVerifier,
|
|
16
17
|
TokenVerificationError,
|
|
17
18
|
authorizeRequest,
|
|
@@ -24,7 +25,7 @@ import {
|
|
|
24
25
|
hasPermission,
|
|
25
26
|
hasPermissionGroup,
|
|
26
27
|
normalizeClientIp
|
|
27
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-WF26WYSX.js";
|
|
28
29
|
import {
|
|
29
30
|
__privateAdd,
|
|
30
31
|
__privateGet,
|
|
@@ -268,6 +269,11 @@ _token = new WeakMap();
|
|
|
268
269
|
_inFlight = new WeakMap();
|
|
269
270
|
|
|
270
271
|
// src/client/authyonServerClient.ts
|
|
272
|
+
var ROOT_PARENT_ID = "00000000-0000-0000-0000-000000000000";
|
|
273
|
+
function tenantListQuery({ parentId, ...rest }) {
|
|
274
|
+
if (parentId === void 0) return rest;
|
|
275
|
+
return { ...rest, parentId: parentId === null ? ROOT_PARENT_ID : parentId };
|
|
276
|
+
}
|
|
271
277
|
var _clientSecret;
|
|
272
278
|
var AuthyonServerClient = class {
|
|
273
279
|
constructor(options = {}) {
|
|
@@ -510,15 +516,47 @@ var AuthyonServerClient = class {
|
|
|
510
516
|
* });
|
|
511
517
|
* ```
|
|
512
518
|
*
|
|
519
|
+
* `parentId` narrows the page to one level of the tree — `children()`
|
|
520
|
+
* and `roots()` below are the same call with that one option set.
|
|
521
|
+
*
|
|
513
522
|
* Against an Authyon API older than 2026-10-21 this route ignored
|
|
514
523
|
* skip/take/search and answered with a bare array; one older than
|
|
515
|
-
* 2026-10-22 ignores `filter
|
|
516
|
-
* rather than an error.
|
|
524
|
+
* 2026-10-22 ignores `filter` and one older than 2026-10-31 ignores
|
|
525
|
+
* `parentId`, which read as a page that is too wide rather than an error.
|
|
526
|
+
*/
|
|
527
|
+
list: (params = {}) => this.request("/env/tenants", { envBearer: true, query: tenantListQuery(params) }),
|
|
528
|
+
/**
|
|
529
|
+
* One page of a tenant's direct sub-tenants — `list()` with `parentId`.
|
|
530
|
+
*
|
|
531
|
+
* Only one level: a node's own children carry `childCount`, so a tree
|
|
532
|
+
* view asks again where that is above zero instead of reading the whole
|
|
533
|
+
* subtree to draw the first level of it.
|
|
534
|
+
*/
|
|
535
|
+
children: (parentTenantId, params = {}) => this.environment.tenants.list({ ...params, parentId: parentTenantId }),
|
|
536
|
+
/**
|
|
537
|
+
* One page of the environment's root tenants — `list()` with no parent.
|
|
538
|
+
*
|
|
539
|
+
* This is the first level of the tree, and the difference from `list()`
|
|
540
|
+
* is worth keeping straight: `list()` returns every tenant at every
|
|
541
|
+
* depth, which is what a flat picker wants and what a tree view must not
|
|
542
|
+
* start from.
|
|
543
|
+
*/
|
|
544
|
+
roots: (params = {}) => this.environment.tenants.list({ ...params, parentId: null }),
|
|
545
|
+
/**
|
|
546
|
+
* POST /env/tenants — create a tenant in the environment.
|
|
547
|
+
*
|
|
548
|
+
* `parentTenantId` nests it under an existing tenant. The environment's
|
|
549
|
+
* `maxTenantDepth` has to allow the level — it ships as `1`, roots only,
|
|
550
|
+
* so this answers `tenant.depth.not_allowed` until an operator raises it
|
|
551
|
+
* in the console.
|
|
517
552
|
*/
|
|
518
|
-
list: (params = {}) => this.request("/env/tenants", { envBearer: true, query: params }),
|
|
519
|
-
/** POST /env/tenants — create a tenant in the environment. */
|
|
520
553
|
create: (input) => this.request("/env/tenants", { method: "POST", envBearer: true, body: input }),
|
|
521
|
-
/**
|
|
554
|
+
/**
|
|
555
|
+
* GET /env/tenants/{tenantId} — fetch a tenant by id.
|
|
556
|
+
*
|
|
557
|
+
* Returns `ancestors` as well, the chain above it root first, so a
|
|
558
|
+
* breadcrumb costs this one call rather than one per level.
|
|
559
|
+
*/
|
|
522
560
|
get: (tenantId) => this.request(`/env/tenants/${encodeURIComponent(tenantId)}`, { envBearer: true }),
|
|
523
561
|
/** PUT /env/tenants/{tenantId} — update a tenant. */
|
|
524
562
|
update: (tenantId, input) => this.request(`/env/tenants/${encodeURIComponent(tenantId)}`, {
|
|
@@ -532,12 +570,23 @@ var AuthyonServerClient = class {
|
|
|
532
570
|
envBearer: true,
|
|
533
571
|
body: input
|
|
534
572
|
}),
|
|
535
|
-
/**
|
|
573
|
+
/**
|
|
574
|
+
* POST /env/tenants/{tenantId}/disable — disable without removing tenant
|
|
575
|
+
* data.
|
|
576
|
+
*
|
|
577
|
+
* Disables the branch below it too. A sub-tenant left live under a
|
|
578
|
+
* disabled parent would go on authenticating its users, which is the one
|
|
579
|
+
* thing switching a tenant off is there to stop — so check `childCount`
|
|
580
|
+
* before calling this on a node with children.
|
|
581
|
+
*/
|
|
536
582
|
disable: (tenantId) => this.request(`/env/tenants/${encodeURIComponent(tenantId)}/disable`, {
|
|
537
583
|
method: "POST",
|
|
538
584
|
envBearer: true
|
|
539
585
|
}),
|
|
540
|
-
/**
|
|
586
|
+
/**
|
|
587
|
+
* DELETE /env/tenants/{tenantId} — logically delete (disable) a tenant,
|
|
588
|
+
* and the branch below it. Same handler as `disable()`.
|
|
589
|
+
*/
|
|
541
590
|
delete: (tenantId) => this.request(`/env/tenants/${encodeURIComponent(tenantId)}`, {
|
|
542
591
|
method: "DELETE",
|
|
543
592
|
envBearer: true
|
|
@@ -1114,6 +1163,32 @@ var tenantFilter = {
|
|
|
1114
1163
|
return `${assertPath(path2)}:exists`;
|
|
1115
1164
|
}
|
|
1116
1165
|
};
|
|
1166
|
+
|
|
1167
|
+
// ../../internal/core/authorization/tenantPermissions.ts
|
|
1168
|
+
var TenantPermissions = {
|
|
1169
|
+
/** Rename the tenant and change its settings. */
|
|
1170
|
+
SettingsManage: "tenants:settings:manage",
|
|
1171
|
+
/** Invite an address to the tenant. */
|
|
1172
|
+
MembersInvite: "tenants:members:invite",
|
|
1173
|
+
/** Remove a member from the tenant. */
|
|
1174
|
+
MembersRemove: "tenants:members:remove"
|
|
1175
|
+
};
|
|
1176
|
+
var SubtenantPermissions = {
|
|
1177
|
+
/** Read any tenant below one you belong to. */
|
|
1178
|
+
TreeRead: "subtenants:tree:read",
|
|
1179
|
+
/** Rename a tenant below yours, and add or remove its members. */
|
|
1180
|
+
TreeManage: "subtenants:tree:manage",
|
|
1181
|
+
/** Create a tenant underneath one you belong to. */
|
|
1182
|
+
TreeCreate: "subtenants:tree:create",
|
|
1183
|
+
/**
|
|
1184
|
+
* Make a tenant below yours the ACTIVE tenant of the session — acting inside
|
|
1185
|
+
* it rather than on it from outside. Deliberately not the same permission as
|
|
1186
|
+
* {@link SubtenantPermissions.TreeManage}: administering a sub-tenant through
|
|
1187
|
+
* the management endpoints and operating as that sub-tenant are different
|
|
1188
|
+
* powers, and granting the first should not hand over the second.
|
|
1189
|
+
*/
|
|
1190
|
+
TreeSwitch: "subtenants:tree:switch"
|
|
1191
|
+
};
|
|
1117
1192
|
export {
|
|
1118
1193
|
AuthorizationError,
|
|
1119
1194
|
AuthyonAbility,
|
|
@@ -1121,13 +1196,16 @@ export {
|
|
|
1121
1196
|
AuthyonError,
|
|
1122
1197
|
AuthyonServerClient,
|
|
1123
1198
|
AuthyonServerClientBuilder,
|
|
1199
|
+
CLIENT_IP_HEADER,
|
|
1124
1200
|
ErrorCodes,
|
|
1125
1201
|
FetchHttpAdapter,
|
|
1126
1202
|
JwksTokenVerifier,
|
|
1127
1203
|
LoggingHttpAdapter,
|
|
1204
|
+
SubtenantPermissions,
|
|
1128
1205
|
TENANT_FILTER_MAX_DEPTH,
|
|
1129
1206
|
TENANT_FILTER_MAX_VALUES,
|
|
1130
1207
|
TENANT_FILTER_MAX_VALUE_LENGTH,
|
|
1208
|
+
TenantPermissions,
|
|
1131
1209
|
TenantScopedClient,
|
|
1132
1210
|
TokenVerificationError,
|
|
1133
1211
|
UserScopedClient,
|
package/dist/next.cjs
CHANGED
|
@@ -75,13 +75,23 @@ function createAuthyonRules(source = {}, options = {}) {
|
|
|
75
75
|
...source.permissions ?? [],
|
|
76
76
|
...source.scope?.split(/\s+/).filter(Boolean) ?? []
|
|
77
77
|
]);
|
|
78
|
-
const rules = [...permissions].map(
|
|
78
|
+
const rules = [...permissions].map(grantToRule).filter(isAbilityRule);
|
|
79
79
|
for (const role of /* @__PURE__ */ new Set([...source.roles ?? [], ...options.roles ?? []])) {
|
|
80
80
|
rules.push(...(options.roleRules?.[role] ?? []).map(cloneRule));
|
|
81
81
|
}
|
|
82
82
|
rules.push(...(options.rules ?? []).map(cloneRule));
|
|
83
83
|
return rules;
|
|
84
84
|
}
|
|
85
|
+
function grantToRule(permission) {
|
|
86
|
+
const normalized = permission.trim();
|
|
87
|
+
if (normalized && isFullWildcard(normalized)) {
|
|
88
|
+
return { action: "manage", subject: "all" };
|
|
89
|
+
}
|
|
90
|
+
return permissionToRule(normalized);
|
|
91
|
+
}
|
|
92
|
+
function isFullWildcard(permission) {
|
|
93
|
+
return permission.split(":").every((segment) => segment === "*");
|
|
94
|
+
}
|
|
85
95
|
function permissionToRule(permission) {
|
|
86
96
|
const normalized = permission.trim();
|
|
87
97
|
if (!normalized) return null;
|
package/dist/next.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
-
import { R as RequestAuthorizationOptions, A as AbilitySubject, a as AuthorizationError } from './authorization-
|
|
3
|
-
import { A as AuthyonServerClient } from './authyonServerClient-
|
|
2
|
+
import { R as RequestAuthorizationOptions, A as AbilitySubject, a as AuthorizationError } from './authorization-BLENxur8.cjs';
|
|
3
|
+
import { A as AuthyonServerClient } from './authyonServerClient-CW46xIRD.cjs';
|
|
4
4
|
import 'jose';
|
|
5
5
|
|
|
6
6
|
interface ServerPermissionGuardFallbackContext {
|