@rixl/sdk 0.21.0 → 0.21.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.d.ts +7 -1
- package/dist/index.js +39 -15
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -14839,6 +14839,11 @@ declare const hasPermission: (required: string) => boolean;
|
|
|
14839
14839
|
* Called on sign-out so no grant outlives the session, and before an
|
|
14840
14840
|
* organization switch so the previous organization's grants cannot be read as
|
|
14841
14841
|
* the new one's while the fresh answer is in flight.
|
|
14842
|
+
*
|
|
14843
|
+
* Emptying the set is not enough on its own: a resolution issued before the
|
|
14844
|
+
* clear can land after it and repopulate the store with the retired scope's
|
|
14845
|
+
* grants. Retiring the epoch here makes any such answer be discarded, so
|
|
14846
|
+
* sign-out cannot be undone by a request that was already in the air.
|
|
14842
14847
|
*/
|
|
14843
14848
|
declare const clearPermissions: () => void;
|
|
14844
14849
|
//#endregion
|
|
@@ -14848,7 +14853,8 @@ declare const clearPermissions: () => void;
|
|
|
14848
14853
|
*
|
|
14849
14854
|
* Call before switching the active organization: without it, a request issued
|
|
14850
14855
|
* for the previous organization can land afterwards and repopulate the store
|
|
14851
|
-
* with permissions the user no longer holds.
|
|
14856
|
+
* with permissions the user no longer holds. Sign-out needs no such call —
|
|
14857
|
+
* `clearPermissions` retires the scope itself.
|
|
14852
14858
|
*/
|
|
14853
14859
|
declare const invalidatePermissions: () => void;
|
|
14854
14860
|
/**
|
package/dist/index.js
CHANGED
|
@@ -3370,6 +3370,25 @@ const matches = (held, required) => {
|
|
|
3370
3370
|
return (SUPERSETS[verb] ?? []).some((superset) => held.has(resource + superset));
|
|
3371
3371
|
};
|
|
3372
3372
|
|
|
3373
|
+
//#endregion
|
|
3374
|
+
//#region src/auth/permissions/epoch.ts
|
|
3375
|
+
/**
|
|
3376
|
+
* Counts the identity scopes that have come and gone — an organization switch,
|
|
3377
|
+
* a sign-out. A response that started under an earlier scope answers a question
|
|
3378
|
+
* nobody is asking any more and must not be written into the store.
|
|
3379
|
+
*
|
|
3380
|
+
* It lives here rather than in `./resolve` so `permissionStore` can retire a
|
|
3381
|
+
* scope from `clearPermissions` without importing the resolver, whose module
|
|
3382
|
+
* graph reaches back into `authStore`.
|
|
3383
|
+
*/
|
|
3384
|
+
const state$1 = shared("permissionEpoch", () => ({ current: 0 }));
|
|
3385
|
+
/** The scope in effect right now. Compare against a value captured earlier. */
|
|
3386
|
+
const permissionEpoch = () => state$1.current;
|
|
3387
|
+
/** Retires the current scope, so answers already in flight for it are dropped. */
|
|
3388
|
+
const retirePermissionEpoch = () => {
|
|
3389
|
+
state$1.current += 1;
|
|
3390
|
+
};
|
|
3391
|
+
|
|
3373
3392
|
//#endregion
|
|
3374
3393
|
//#region src/auth/permissionStore.ts
|
|
3375
3394
|
/**
|
|
@@ -3401,8 +3420,14 @@ const hasPermission = (required) => matches(permissions.get(), required);
|
|
|
3401
3420
|
* Called on sign-out so no grant outlives the session, and before an
|
|
3402
3421
|
* organization switch so the previous organization's grants cannot be read as
|
|
3403
3422
|
* the new one's while the fresh answer is in flight.
|
|
3423
|
+
*
|
|
3424
|
+
* Emptying the set is not enough on its own: a resolution issued before the
|
|
3425
|
+
* clear can land after it and repopulate the store with the retired scope's
|
|
3426
|
+
* grants. Retiring the epoch here makes any such answer be discarded, so
|
|
3427
|
+
* sign-out cannot be undone by a request that was already in the air.
|
|
3404
3428
|
*/
|
|
3405
3429
|
const clearPermissions = () => {
|
|
3430
|
+
retirePermissionEpoch();
|
|
3406
3431
|
permissions.set(/* @__PURE__ */ new Set());
|
|
3407
3432
|
permissionsResolved.set(false);
|
|
3408
3433
|
};
|
|
@@ -4962,23 +4987,20 @@ const verifyPasskeyForLogin = async (session_id, credential) => {
|
|
|
4962
4987
|
|
|
4963
4988
|
//#endregion
|
|
4964
4989
|
//#region src/auth/permissions/resolve.ts
|
|
4965
|
-
/**
|
|
4966
|
-
* Incremented whenever the identity's scope changes — an organization switch,
|
|
4967
|
-
* a sign-out. A response that started before the change belongs to the previous
|
|
4968
|
-
* scope and must not be written into the store.
|
|
4969
|
-
*/
|
|
4970
|
-
let epoch = 0;
|
|
4971
4990
|
/** An `ensurePermissions` call already in flight, so concurrent guards share one request. */
|
|
4972
4991
|
let pending = null;
|
|
4992
|
+
/** The scope `pending` was issued under; once retired, its answer is worthless. */
|
|
4993
|
+
let pendingEpoch = 0;
|
|
4973
4994
|
/**
|
|
4974
4995
|
* Invalidates any resolution already in flight.
|
|
4975
4996
|
*
|
|
4976
4997
|
* Call before switching the active organization: without it, a request issued
|
|
4977
4998
|
* for the previous organization can land afterwards and repopulate the store
|
|
4978
|
-
* with permissions the user no longer holds.
|
|
4999
|
+
* with permissions the user no longer holds. Sign-out needs no such call —
|
|
5000
|
+
* `clearPermissions` retires the scope itself.
|
|
4979
5001
|
*/
|
|
4980
5002
|
const invalidatePermissions = () => {
|
|
4981
|
-
|
|
5003
|
+
retirePermissionEpoch();
|
|
4982
5004
|
pending = null;
|
|
4983
5005
|
};
|
|
4984
5006
|
/**
|
|
@@ -4996,9 +5018,9 @@ const invalidatePermissions = () => {
|
|
|
4996
5018
|
* than keeps stale grants.
|
|
4997
5019
|
*/
|
|
4998
5020
|
const resolvePermissions = async () => {
|
|
4999
|
-
const started =
|
|
5021
|
+
const started = permissionEpoch();
|
|
5000
5022
|
const info = await getUserInfo();
|
|
5001
|
-
if (started !==
|
|
5023
|
+
if (started !== permissionEpoch()) return;
|
|
5002
5024
|
permissions.set(new Set(info.permissions));
|
|
5003
5025
|
permissionsResolved.set(true);
|
|
5004
5026
|
};
|
|
@@ -5013,12 +5035,14 @@ const resolvePermissions = async () => {
|
|
|
5013
5035
|
*/
|
|
5014
5036
|
const ensurePermissions = async () => {
|
|
5015
5037
|
if (permissionsResolved.get()) return;
|
|
5016
|
-
|
|
5017
|
-
|
|
5018
|
-
|
|
5019
|
-
|
|
5038
|
+
const started = permissionEpoch();
|
|
5039
|
+
if (pending && pendingEpoch === started) return pending;
|
|
5040
|
+
pendingEpoch = started;
|
|
5041
|
+
const request = resolvePermissions().finally(() => {
|
|
5042
|
+
if (pending === request) pending = null;
|
|
5020
5043
|
});
|
|
5021
|
-
|
|
5044
|
+
pending = request;
|
|
5045
|
+
return request;
|
|
5022
5046
|
};
|
|
5023
5047
|
|
|
5024
5048
|
//#endregion
|