@authyon/server 0.2.0-beta.2 → 0.2.0-beta.3

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,32 +1,287 @@
1
+ var __typeError = (msg) => {
2
+ throw TypeError(msg);
3
+ };
4
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
5
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
6
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
7
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
8
+
9
+ // src/client/credentialManagement.ts
10
+ function segment(value) {
11
+ if (typeof value !== "string" || !value.trim() || value === "." || value === ".." || [...value].some((character) => character.charCodeAt(0) < 32 || character.charCodeAt(0) === 127)) {
12
+ throw new TypeError("Authyon: invalid route identifier.");
13
+ }
14
+ return encodeURIComponent(value);
15
+ }
16
+ function permissionsBody(input) {
17
+ if (input.permissions !== void 0 && input.scopes !== void 0) {
18
+ throw new TypeError("Authyon: supply permissions or scopes, not both.");
19
+ }
20
+ const values = input.permissions ?? input.scopes;
21
+ if (!Array.isArray(values) || values.length === 0) {
22
+ throw new TypeError("Authyon: explicit credential permissions are required.");
23
+ }
24
+ const permissions = values.map((value) => {
25
+ if (typeof value !== "string") throw new TypeError("Authyon: invalid permission.");
26
+ const normalized = value.trim().toLowerCase();
27
+ if (!/^(?:\*|[a-z][a-z0-9_-]*):(?:\*|[a-z][a-z0-9_-]*):(?:\*|[a-z][a-z0-9_-]*)$/u.test(normalized)) {
28
+ throw new TypeError("Authyon: permissions must have namespace:resource:action format.");
29
+ }
30
+ return normalized;
31
+ });
32
+ return { permissions: [...new Set(permissions)] };
33
+ }
34
+ function lifetimeBody(input) {
35
+ if (input.lifetimeDays === void 0 || input.lifetimeDays === null) return {};
36
+ if (!Number.isInteger(input.lifetimeDays) || input.lifetimeDays < 1 || input.lifetimeDays > 3650) {
37
+ throw new RangeError("Authyon: lifetimeDays must be between 1 and 3650.");
38
+ }
39
+ return { lifetimeDays: input.lifetimeDays };
40
+ }
41
+ function credentialQuery(options = {}) {
42
+ const { skip, take, search } = options;
43
+ if (skip !== void 0 && (!Number.isInteger(skip) || skip < 0 || skip > 2147483647))
44
+ throw new RangeError("Authyon: invalid skip.");
45
+ if (take !== void 0 && (!Number.isInteger(take) || take < 1 || take > 100))
46
+ throw new RangeError("Authyon: take must be between 1 and 100.");
47
+ if (search !== void 0 && (typeof search !== "string" || search.trim().length > 200))
48
+ throw new RangeError("Authyon: search must contain at most 200 characters.");
49
+ return { search: search?.trim() || void 0, skip, take };
50
+ }
51
+ function credentialSummary(value) {
52
+ return {
53
+ id: value.id,
54
+ clientId: value.clientId,
55
+ description: value.description,
56
+ createdAt: value.createdAt,
57
+ lastUsedAt: value.lastUsedAt,
58
+ revokedAt: value.revokedAt,
59
+ expiresAt: value.expiresAt ?? null,
60
+ isActive: value.isActive,
61
+ permissions: [...value.permissions]
62
+ };
63
+ }
64
+ function credentialDetail(value) {
65
+ return {
66
+ ...credentialSummary(value),
67
+ createdBy: value.createdBy == null ? null : {
68
+ id: value.createdBy.id,
69
+ type: value.createdBy.type,
70
+ displayName: value.createdBy.displayName
71
+ },
72
+ updatedAt: value.updatedAt,
73
+ secretRotatedAt: value.secretRotatedAt,
74
+ expiresAt: value.expiresAt ?? null,
75
+ ageSeconds: value.ageSeconds,
76
+ lifetimeSeconds: value.lifetimeSeconds,
77
+ accessTokenLifetimeSeconds: value.accessTokenLifetimeSeconds
78
+ };
79
+ }
80
+ async function credentialPage(request, path, options = {}) {
81
+ const query = credentialQuery(options);
82
+ const page = await request(path, { query });
83
+ if (!page || !Array.isArray(page.data))
84
+ throw new TypeError("Authyon: expected a paginated credential response.");
85
+ return {
86
+ data: page.data.map(credentialSummary),
87
+ ...page.perPage === void 0 ? {} : { perPage: page.perPage },
88
+ pageSize: page.pageSize,
89
+ total: page.total,
90
+ pages: page.pages,
91
+ hasNext: page.hasNext,
92
+ hasPrev: page.hasPrev
93
+ };
94
+ }
95
+ async function allCredentials(request, path) {
96
+ const result = [];
97
+ const seen = /* @__PURE__ */ new Set();
98
+ let skip = 0;
99
+ for (let iteration = 0; iteration < 1e3; iteration++) {
100
+ const page = await request(
101
+ path,
102
+ iteration === 0 ? {} : { query: { skip, take: 100 } }
103
+ );
104
+ if (Array.isArray(page)) {
105
+ if (iteration !== 0)
106
+ throw new Error("Authyon: credential pagination changed during listing.");
107
+ return page.map(credentialSummary);
108
+ }
109
+ if (!page || !Array.isArray(page.data))
110
+ throw new TypeError("Authyon: invalid credential page.");
111
+ for (const row of page.data) {
112
+ if (seen.has(row.id))
113
+ throw new Error("Authyon: credential pages overlapped; retry the listing.");
114
+ seen.add(row.id);
115
+ result.push(credentialSummary(row));
116
+ }
117
+ if (!page.hasNext) return result;
118
+ if (page.data.length === 0) throw new Error("Authyon: credential pagination made no progress.");
119
+ skip += page.data.length;
120
+ }
121
+ throw new Error("Authyon: use listPage for more than 1000 credential pages.");
122
+ }
123
+
124
+ // src/client/scopedManagementClient.ts
125
+ function scopedRequest(request, source) {
126
+ return async (path, options = {}) => {
127
+ const token = typeof source === "function" ? await source() : source;
128
+ if (typeof token !== "string" || !token.trim() || /\s/u.test(token))
129
+ throw new TypeError("Authyon: a valid access token is required.");
130
+ return request(path, {
131
+ ...options,
132
+ headers: { ...options.headers, Authorization: `Bearer ${token}` }
133
+ });
134
+ };
135
+ }
136
+ function environmentPath(scope) {
137
+ return `/platform/workspaces/${segment(scope.workspaceId)}/environments/${segment(scope.environmentId)}`;
138
+ }
139
+ function tenantPath(scope) {
140
+ return `${environmentPath(scope)}/tenants/${segment(scope.tenantId)}`;
141
+ }
142
+ function credentialPath(scope) {
143
+ return `${scope.tenantId === void 0 ? environmentPath(scope) : tenantPath(scope)}/credentials`;
144
+ }
145
+ function workspacePath(id) {
146
+ return `/platform/workspaces/${segment(id)}`;
147
+ }
148
+ function workspaceRole(role) {
149
+ if (role !== "admin" && role !== "auditor")
150
+ throw new TypeError("Authyon: workspace role must be admin or auditor.");
151
+ return role;
152
+ }
153
+ var _request;
154
+ var PlatformScopedClient = class {
155
+ /** @hidden */
156
+ constructor(request, token) {
157
+ __privateAdd(this, _request);
158
+ this.credentials = {
159
+ list: (scope, options = {}) => credentialPage(__privateGet(this, _request), credentialPath(scope), options),
160
+ get: async (scope, credentialId) => credentialDetail(await __privateGet(this, _request).call(this, `${credentialPath(scope)}/${segment(credentialId)}`)),
161
+ create: (scope, input) => __privateGet(this, _request).call(this, credentialPath(scope), {
162
+ method: "POST",
163
+ body: { description: input.description, ...lifetimeBody(input), ...permissionsBody(input) }
164
+ }),
165
+ updatePermissions: (scope, credentialId, input) => __privateGet(this, _request).call(this, `${credentialPath(scope)}/${segment(credentialId)}/permissions`, {
166
+ method: "PUT",
167
+ body: permissionsBody(input)
168
+ }),
169
+ updateScopes: (scope, credentialId, scopes) => this.credentials.updatePermissions(scope, credentialId, { scopes }),
170
+ /** Returns a new secret once. API may require an explicit step-up first. */
171
+ rotate: (scope, credentialId) => __privateGet(this, _request).call(this, `${credentialPath(scope)}/${segment(credentialId)}/rotate`, { method: "POST" }),
172
+ revoke: (scope, credentialId) => __privateGet(this, _request).call(this, `${credentialPath(scope)}/${segment(credentialId)}`, { method: "DELETE" })
173
+ };
174
+ this.workspaces = {
175
+ team: (workspaceId) => __privateGet(this, _request).call(this, `${workspacePath(workspaceId)}/team`),
176
+ members: {
177
+ invite: (workspaceId, input) => __privateGet(this, _request).call(this, `${workspacePath(workspaceId)}/invites`, {
178
+ method: "POST",
179
+ body: { email: input.email, role: workspaceRole(input.role) }
180
+ }),
181
+ /** memberId comes from team.members; it is not the platform userId. */
182
+ remove: (workspaceId, memberId) => __privateGet(this, _request).call(this, `${workspacePath(workspaceId)}/members/${segment(memberId)}`, {
183
+ method: "DELETE"
184
+ }),
185
+ changeRole: (workspaceId, memberId, role) => __privateGet(this, _request).call(this, `${workspacePath(workspaceId)}/members/${segment(memberId)}`, {
186
+ method: "PATCH",
187
+ body: { role: workspaceRole(role) }
188
+ })
189
+ },
190
+ invites: {
191
+ create: (workspaceId, input) => this.workspaces.members.invite(workspaceId, input),
192
+ revoke: (workspaceId, inviteId) => __privateGet(this, _request).call(this, `${workspacePath(workspaceId)}/invites/${segment(inviteId)}`, {
193
+ method: "DELETE"
194
+ })
195
+ }
196
+ };
197
+ this.tenants = {
198
+ members: {
199
+ list: (scope, options = {}) => __privateGet(this, _request).call(this, `${tenantPath(scope)}/members`, { query: options }),
200
+ add: (scope, userId, roles) => __privateGet(this, _request).call(this, `${tenantPath(scope)}/members`, { method: "POST", body: { userId, roles } }),
201
+ remove: (scope, userId) => __privateGet(this, _request).call(this, `${tenantPath(scope)}/members/${segment(userId)}`, { method: "DELETE" })
202
+ }
203
+ };
204
+ this.auth = {
205
+ /** Explicitly confirms the current platform session; passwords are not retained. */
206
+ stepUp: (currentPassword) => __privateGet(this, _request).call(this, "/platform/auth/step-up", { method: "POST", body: { currentPassword } })
207
+ };
208
+ __privateSet(this, _request, scopedRequest(request, token));
209
+ }
210
+ };
211
+ _request = new WeakMap();
212
+ var _request2;
213
+ var UserScopedClient = class {
214
+ /** @hidden */
215
+ constructor(request, token) {
216
+ __privateAdd(this, _request2);
217
+ this.tenants = {
218
+ members: {
219
+ list: (tenantId, options = {}) => __privateGet(this, _request2).call(this, `/auth/tenants/${segment(tenantId)}/members`, { query: options }),
220
+ /** Adds an existing environment user by email; does not send an invitation email. */
221
+ invite: (tenantId, input) => __privateGet(this, _request2).call(this, `/auth/tenants/${segment(tenantId)}/members`, {
222
+ method: "POST",
223
+ body: { email: input.email, roles: input.roles }
224
+ }),
225
+ remove: (tenantId, userId) => __privateGet(this, _request2).call(this, `/auth/tenants/${segment(tenantId)}/members/${segment(userId)}`, {
226
+ method: "DELETE"
227
+ })
228
+ }
229
+ };
230
+ __privateSet(this, _request2, scopedRequest(request, token));
231
+ }
232
+ };
233
+ _request2 = new WeakMap();
234
+ var _request3;
235
+ var WorkspaceInvitesClient = class {
236
+ /** @hidden */
237
+ constructor(request) {
238
+ __privateAdd(this, _request3);
239
+ __privateSet(this, _request3, request);
240
+ }
241
+ preview(token) {
242
+ return __privateGet(this, _request3).call(this, `/platform/workspace-invites/${segment(token)}`);
243
+ }
244
+ accept(token, input = {}) {
245
+ return __privateGet(this, _request3).call(this, `/platform/workspace-invites/${segment(token)}/accept`, {
246
+ method: "POST",
247
+ body: { name: input.name, password: input.password }
248
+ });
249
+ }
250
+ };
251
+ _request3 = new WeakMap();
252
+
1
253
  // ../../internal/core/config/defaults.ts
2
254
  var DEFAULT_BASE_URL = "https://api.authyon.com";
3
255
  var DEFAULT_EXPIRY_SKEW_MS = 3e4;
4
256
 
5
257
  // ../../internal/core/auth/expiringTokenProvider.ts
258
+ var _token, _inFlight;
6
259
  var ExpiringTokenProvider = class {
7
260
  constructor(acquire, expirySkewMs = DEFAULT_EXPIRY_SKEW_MS) {
8
261
  this.acquire = acquire;
9
262
  this.expirySkewMs = expirySkewMs;
10
- this.token = null;
11
- this.inFlight = null;
263
+ __privateAdd(this, _token, null);
264
+ __privateAdd(this, _inFlight, null);
12
265
  }
13
266
  async getAccessToken() {
14
- if (this.token && Date.now() < this.token.expiresAt - this.expirySkewMs) {
15
- return this.token.accessToken;
267
+ if (__privateGet(this, _token) && Date.now() < __privateGet(this, _token).expiresAt - this.expirySkewMs) {
268
+ return __privateGet(this, _token).accessToken;
16
269
  }
17
- if (this.inFlight) return this.inFlight;
18
- this.inFlight = this.acquire().then((token) => {
19
- this.token = token;
270
+ if (__privateGet(this, _inFlight)) return __privateGet(this, _inFlight);
271
+ __privateSet(this, _inFlight, this.acquire().then((token) => {
272
+ __privateSet(this, _token, token);
20
273
  return token.accessToken;
21
274
  }).finally(() => {
22
- this.inFlight = null;
23
- });
24
- return this.inFlight;
275
+ __privateSet(this, _inFlight, null);
276
+ }));
277
+ return __privateGet(this, _inFlight);
25
278
  }
26
279
  clear() {
27
- this.token = null;
280
+ __privateSet(this, _token, null);
28
281
  }
29
282
  };
283
+ _token = new WeakMap();
284
+ _inFlight = new WeakMap();
30
285
 
31
286
  // ../../internal/core/errors/authyonError.ts
32
287
  var ErrorCodes = {
@@ -157,7 +412,8 @@ var FetchHttpAdapter = class {
157
412
  method: request.method,
158
413
  headers: request.headers,
159
414
  body: request.body,
160
- signal: request.signal
415
+ signal: request.signal,
416
+ redirect: "error"
161
417
  });
162
418
  }
163
419
  };
@@ -209,6 +465,10 @@ function defaultHttpLogger(event) {
209
465
  }
210
466
  function sanitizeUrl(value) {
211
467
  const url = new URL(value);
468
+ url.username = "";
469
+ url.password = "";
470
+ url.hash = "";
471
+ url.pathname = url.pathname.replace(/(\/platform\/workspace-invites\/)[^/]+/u, "$1REDACTED");
212
472
  const queryKeys = /* @__PURE__ */ new Set();
213
473
  url.searchParams.forEach((_value, key) => queryKeys.add(key));
214
474
  url.search = queryKeys.size > 0 ? [...queryKeys].map((key) => `${encodeURIComponent(key)}=REDACTED`).join("&") : "";
@@ -494,8 +754,10 @@ function isRecord(value) {
494
754
  }
495
755
 
496
756
  // src/client/authyonServerClient.ts
757
+ var _clientSecret;
497
758
  var AuthyonServerClient = class {
498
759
  constructor(options = {}) {
760
+ __privateAdd(this, _clientSecret);
499
761
  // ── Discovery ──────────────────────────────────────────────────────────────
500
762
  this.discovery = {
501
763
  /** GET /.well-known/jwks.json — the environment's public signing keys. */
@@ -531,6 +793,9 @@ var AuthyonServerClient = class {
531
793
  }
532
794
  })
533
795
  };
796
+ this.workspaceInvites = new WorkspaceInvitesClient(
797
+ (path, options) => this.http.request(path, options)
798
+ );
534
799
  // ── Environment management (users, tenants, roles, permissions, audit) ───
535
800
  this.environment = {
536
801
  users: {
@@ -622,6 +887,47 @@ var AuthyonServerClient = class {
622
887
  )
623
888
  },
624
889
  tenants: {
890
+ credentials: {
891
+ /** GET /env/tenants/{tenantId}/credentials. Returns metadata only, including revoked credentials. */
892
+ list: (tenantId) => allCredentials(
893
+ (path, options) => this.request(path, { ...options, envBearer: true }),
894
+ `/env/tenants/${segment(tenantId)}/credentials`
895
+ ),
896
+ /** Paginated searchable listing. Prefer this over loading every credential. */
897
+ listPage: (tenantId, options = {}) => credentialPage(
898
+ (path, requestOptions) => this.request(path, { ...requestOptions, envBearer: true }),
899
+ `/env/tenants/${segment(tenantId)}/credentials`,
900
+ options
901
+ ),
902
+ get: async (tenantId, credentialId) => credentialDetail(
903
+ await this.request(
904
+ `/env/tenants/${segment(tenantId)}/credentials/${segment(credentialId)}`,
905
+ { envBearer: true }
906
+ )
907
+ ),
908
+ /** Explicit scopes/permissions; only issuance returns the client secret. */
909
+ create: (tenantId, input) => this.request(`/env/tenants/${segment(tenantId)}/credentials`, {
910
+ method: "POST",
911
+ envBearer: true,
912
+ body: { description: input.description, ...lifetimeBody(input), ...permissionsBody(input) }
913
+ }),
914
+ /** Returns a new secret once while keeping the same client id. */
915
+ rotate: (tenantId, credentialId) => this.request(
916
+ `/env/tenants/${segment(tenantId)}/credentials/${segment(credentialId)}/rotate`,
917
+ { method: "POST", envBearer: true }
918
+ ),
919
+ updatePermissions: (tenantId, credentialId, input) => this.request(
920
+ `/env/tenants/${segment(tenantId)}/credentials/${segment(credentialId)}/permissions`,
921
+ { method: "PUT", envBearer: true, body: permissionsBody(input) }
922
+ ),
923
+ updateScopes: (tenantId, credentialId, scopes) => this.environment.tenants.credentials.updatePermissions(tenantId, credentialId, {
924
+ scopes
925
+ }),
926
+ revoke: (tenantId, credentialId) => this.request(`/env/tenants/${segment(tenantId)}/credentials/${segment(credentialId)}`, {
927
+ method: "DELETE",
928
+ envBearer: true
929
+ })
930
+ },
625
931
  /** GET /env/tenants — paginated, searchable list of tenants in the environment. */
626
932
  list: (params = {}) => this.request("/env/tenants", { envBearer: true, query: params }),
627
933
  /** POST /env/tenants — create a tenant in the environment. */
@@ -768,7 +1074,7 @@ var AuthyonServerClient = class {
768
1074
  };
769
1075
  this.envKey = options.envKey;
770
1076
  this.clientId = options.clientId;
771
- this.clientSecret = options.clientSecret;
1077
+ __privateSet(this, _clientSecret, options.clientSecret);
772
1078
  this.transport = createSharedTransport({
773
1079
  baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,
774
1080
  allowInsecureHttp: options.allowInsecureHttp,
@@ -779,14 +1085,14 @@ var AuthyonServerClient = class {
779
1085
  });
780
1086
  this.http = new JsonHttpClient(this.transport);
781
1087
  this.environmentTokenProvider = new ExpiringTokenProvider(async () => {
782
- if (!this.clientId || !this.clientSecret) {
1088
+ if (!this.clientId || !__privateGet(this, _clientSecret)) {
783
1089
  throw new Error(
784
1090
  "Authyon: `clientId`/`clientSecret` are required for environment management calls (mint a pair in the console, under the environment's OAuth clients)."
785
1091
  );
786
1092
  }
787
1093
  const token = await this.environmentAuth.token({
788
1094
  clientId: this.clientId,
789
- clientSecret: this.clientSecret
1095
+ clientSecret: __privateGet(this, _clientSecret)
790
1096
  });
791
1097
  return {
792
1098
  accessToken: token.access_token,
@@ -855,6 +1161,14 @@ var AuthyonServerClient = class {
855
1161
  tenant(credentials) {
856
1162
  return new TenantScopedClient(this, credentials);
857
1163
  }
1164
+ /** Uses only the supplied platform-user access token. */
1165
+ platform(token) {
1166
+ return new PlatformScopedClient((path, options) => this.http.request(path, options), token);
1167
+ }
1168
+ /** Uses an end-user token; the configured environment key selects the environment. */
1169
+ user(token) {
1170
+ return new UserScopedClient((path, options) => this.request(path, options), token);
1171
+ }
858
1172
  /** @internal used by {@link TenantScopedClient} to share the base URL/fetch/error handling. */
859
1173
  _requestAsTenant(accessToken, path, options = {}) {
860
1174
  return this.request(path, {
@@ -864,6 +1178,7 @@ var AuthyonServerClient = class {
864
1178
  });
865
1179
  }
866
1180
  };
1181
+ _clientSecret = new WeakMap();
867
1182
  var TenantScopedClient = class {
868
1183
  constructor(server, credentials) {
869
1184
  this.members = {
@@ -942,40 +1257,42 @@ function createClient(options = {}) {
942
1257
  }
943
1258
 
944
1259
  // src/client/authyonServerClientBuilder.ts
1260
+ var _options;
945
1261
  var AuthyonServerClientBuilder = class {
946
1262
  constructor() {
947
- this.options = {};
1263
+ __privateAdd(this, _options, {});
948
1264
  }
949
1265
  withEnvironmentKey(envKey) {
950
- this.options.envKey = envKey;
1266
+ __privateGet(this, _options).envKey = envKey;
951
1267
  return this;
952
1268
  }
953
1269
  withEnvironmentCredentials(clientId, clientSecret) {
954
- this.options.clientId = clientId;
955
- this.options.clientSecret = clientSecret;
1270
+ __privateGet(this, _options).clientId = clientId;
1271
+ __privateGet(this, _options).clientSecret = clientSecret;
956
1272
  return this;
957
1273
  }
958
1274
  withBaseUrl(baseUrl, allowInsecureHttp = false) {
959
- this.options.baseUrl = baseUrl;
960
- this.options.allowInsecureHttp = allowInsecureHttp;
1275
+ __privateGet(this, _options).baseUrl = baseUrl;
1276
+ __privateGet(this, _options).allowInsecureHttp = allowInsecureHttp;
961
1277
  return this;
962
1278
  }
963
1279
  withTimeout(timeoutMs) {
964
- this.options.timeoutMs = timeoutMs;
1280
+ __privateGet(this, _options).timeoutMs = timeoutMs;
965
1281
  return this;
966
1282
  }
967
1283
  withHttpAdapter(httpAdapter) {
968
- this.options.httpAdapter = httpAdapter;
1284
+ __privateGet(this, _options).httpAdapter = httpAdapter;
969
1285
  return this;
970
1286
  }
971
1287
  withHttpLogger(httpLogger) {
972
- this.options.httpLogger = httpLogger;
1288
+ __privateGet(this, _options).httpLogger = httpLogger;
973
1289
  return this;
974
1290
  }
975
1291
  build() {
976
- return new AuthyonServerClient({ ...this.options });
1292
+ return new AuthyonServerClient({ ...__privateGet(this, _options) });
977
1293
  }
978
1294
  };
1295
+ _options = new WeakMap();
979
1296
 
980
1297
  // ../../internal/core/authorization/ability.ts
981
1298
  var AuthyonAbility = class {
@@ -1085,7 +1402,7 @@ function matchesToken(value, expected, wildcard) {
1085
1402
  function matchesSegments(pattern, value) {
1086
1403
  const patternSegments = pattern.split(":");
1087
1404
  const valueSegments = value.split(":");
1088
- return patternSegments.length === valueSegments.length && patternSegments.every((segment, index) => segment === "*" || segment === valueSegments[index]);
1405
+ return patternSegments.length === valueSegments.length && patternSegments.every((segment2, index) => segment2 === "*" || segment2 === valueSegments[index]);
1089
1406
  }
1090
1407
  function matchesField(pattern, field) {
1091
1408
  if (pattern === "*" || pattern === field) return true;
@@ -1289,8 +1606,11 @@ export {
1289
1606
  FetchHttpAdapter,
1290
1607
  JwksTokenVerifier,
1291
1608
  LoggingHttpAdapter,
1609
+ PlatformScopedClient,
1292
1610
  TenantScopedClient,
1293
1611
  TokenVerificationError,
1612
+ UserScopedClient,
1613
+ WorkspaceInvitesClient,
1294
1614
  authorizeRequest,
1295
1615
  authorizeToken,
1296
1616
  createAuthorizationErrorResponse,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@authyon/server",
3
- "version": "0.2.0-beta.2",
3
+ "version": "0.2.0-beta.3",
4
4
  "description": "Authyon SDK for backends — server-to-server organization/member management and access-token verification.",
5
5
  "license": "MIT",
6
6
  "type": "module",