@hanzo/rooms 0.1.70 → 0.1.72
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/lib/session.d.ts +12 -3
- package/dist/lib/session.js +39 -20
- package/dist/where.d.ts +6 -0
- package/package.json +1 -1
package/dist/lib/session.d.ts
CHANGED
|
@@ -123,11 +123,20 @@ export declare function own(sub: string | undefined): void;
|
|
|
123
123
|
*/
|
|
124
124
|
export declare function follow(was: string | undefined, moved: () => void): () => void;
|
|
125
125
|
/**
|
|
126
|
-
* The
|
|
127
|
-
*
|
|
128
|
-
*
|
|
126
|
+
* The brands' directories (hanzoai/authz `IsDirectory`): the org a customer's
|
|
127
|
+
* account lives in, its home, and nobody's to work in. IAM lists the home first
|
|
128
|
+
* in the token's `orgs`; cloud opens a directory to no one.
|
|
129
|
+
*/
|
|
130
|
+
export declare const DIRECTORIES: readonly string[];
|
|
131
|
+
/**
|
|
132
|
+
* The organizations this person works in, as the token names them: every org of
|
|
133
|
+
* its `orgs` but a directory, which is a home and nobody's tenant. Empty for an
|
|
134
|
+
* account that has not made one: the SDK's own list falls back to the `owner`
|
|
135
|
+
* claim, which is the application's org and nobody's to work in.
|
|
129
136
|
*/
|
|
130
137
|
export declare function orgs(): string[];
|
|
138
|
+
/** The org of the person's own row: the first entry of the token's `orgs`, a directory or not. */
|
|
139
|
+
export declare function home(): string | null;
|
|
131
140
|
/**
|
|
132
141
|
* The reader's role in one organization as IAM signed it into the token's `orgs`
|
|
133
142
|
* claim — owner, admin or member — or null where the token names no such org.
|
package/dist/lib/session.js
CHANGED
|
@@ -15,12 +15,22 @@
|
|
|
15
15
|
* Two derivations of one name never agree; this is the one derivation.
|
|
16
16
|
*/
|
|
17
17
|
import { api } from './api.js';
|
|
18
|
+
import { where } from '../where.js';
|
|
18
19
|
/** The SDK's own keys, `hanzo_iam_`-prefixed. The far side of a boundary. */
|
|
19
20
|
const PREFIX = 'hanzo_iam_';
|
|
20
21
|
const ACCESS = `${PREFIX}access_token`;
|
|
21
22
|
const REFRESH = `${PREFIX}refresh_token`;
|
|
22
23
|
const EXPIRES = `${PREFIX}expires_at`;
|
|
23
24
|
const KEYS = [ACCESS, REFRESH, `${PREFIX}id_token`, EXPIRES];
|
|
25
|
+
/**
|
|
26
|
+
* The store the SDK keeps the session in: the host's (`configure({ session })`,
|
|
27
|
+
* Hanzo Desktop's keychain, where no token reaches the webview's localStorage),
|
|
28
|
+
* else this page's localStorage. Only the SDK's own keys are read from it; the
|
|
29
|
+
* rooms' own choices (the organization, the person) stay in localStorage.
|
|
30
|
+
*/
|
|
31
|
+
function tokens() {
|
|
32
|
+
return where().session ?? window.localStorage;
|
|
33
|
+
}
|
|
24
34
|
/**
|
|
25
35
|
* The access token, or null.
|
|
26
36
|
*
|
|
@@ -32,7 +42,7 @@ export function bearer() {
|
|
|
32
42
|
if (typeof window === 'undefined')
|
|
33
43
|
return null;
|
|
34
44
|
try {
|
|
35
|
-
return
|
|
45
|
+
return tokens().getItem(ACCESS);
|
|
36
46
|
}
|
|
37
47
|
catch {
|
|
38
48
|
return null;
|
|
@@ -48,7 +58,7 @@ export function live() {
|
|
|
48
58
|
if (typeof window === 'undefined')
|
|
49
59
|
return false;
|
|
50
60
|
try {
|
|
51
|
-
const expires =
|
|
61
|
+
const expires = tokens().getItem(EXPIRES);
|
|
52
62
|
return Boolean(bearer()) && (!expires || Date.now() < Number(expires));
|
|
53
63
|
}
|
|
54
64
|
catch {
|
|
@@ -295,12 +305,14 @@ function claims() {
|
|
|
295
305
|
return claimsOf(bearer());
|
|
296
306
|
}
|
|
297
307
|
/**
|
|
298
|
-
* The
|
|
299
|
-
*
|
|
300
|
-
*
|
|
308
|
+
* The brands' directories (hanzoai/authz `IsDirectory`): the org a customer's
|
|
309
|
+
* account lives in, its home, and nobody's to work in. IAM lists the home first
|
|
310
|
+
* in the token's `orgs`; cloud opens a directory to no one.
|
|
301
311
|
*/
|
|
302
|
-
export
|
|
303
|
-
|
|
312
|
+
export const DIRECTORIES = ['hanzo-id', 'lux-id', 'zoo-id', 'pars-id'];
|
|
313
|
+
/** Every org the token's `orgs` names, home first, each once. */
|
|
314
|
+
function listed(token) {
|
|
315
|
+
const set = claimsOf(token)?.orgs;
|
|
304
316
|
const out = [];
|
|
305
317
|
for (const ref of Array.isArray(set) ? set : []) {
|
|
306
318
|
const o = ref?.org;
|
|
@@ -309,6 +321,19 @@ export function orgs() {
|
|
|
309
321
|
}
|
|
310
322
|
return out;
|
|
311
323
|
}
|
|
324
|
+
/**
|
|
325
|
+
* The organizations this person works in, as the token names them: every org of
|
|
326
|
+
* its `orgs` but a directory, which is a home and nobody's tenant. Empty for an
|
|
327
|
+
* account that has not made one: the SDK's own list falls back to the `owner`
|
|
328
|
+
* claim, which is the application's org and nobody's to work in.
|
|
329
|
+
*/
|
|
330
|
+
export function orgs() {
|
|
331
|
+
return listed(bearer()).filter((o) => !DIRECTORIES.includes(o));
|
|
332
|
+
}
|
|
333
|
+
/** The org of the person's own row: the first entry of the token's `orgs`, a directory or not. */
|
|
334
|
+
export function home() {
|
|
335
|
+
return listed(bearer())[0] ?? null;
|
|
336
|
+
}
|
|
312
337
|
/**
|
|
313
338
|
* The reader's role in one organization as IAM signed it into the token's `orgs`
|
|
314
339
|
* claim — owner, admin or member — or null where the token names no such org.
|
|
@@ -344,8 +369,8 @@ export function named() {
|
|
|
344
369
|
*/
|
|
345
370
|
export function me() {
|
|
346
371
|
const name = claims()?.name;
|
|
347
|
-
const
|
|
348
|
-
return typeof name === 'string' && name &&
|
|
372
|
+
const at = home();
|
|
373
|
+
return typeof name === 'string' && name && at ? `${at}/${name}` : null;
|
|
349
374
|
}
|
|
350
375
|
/** The organization this browser works in: the SDK's selection, when it is one of the token's. */
|
|
351
376
|
export function org() {
|
|
@@ -386,7 +411,7 @@ export function scope() {
|
|
|
386
411
|
*/
|
|
387
412
|
export function renew() {
|
|
388
413
|
try {
|
|
389
|
-
|
|
414
|
+
tokens().setItem(EXPIRES, '0');
|
|
390
415
|
}
|
|
391
416
|
catch {
|
|
392
417
|
/* no store to renew */
|
|
@@ -425,7 +450,7 @@ export const ADMIN_ORG = 'admin';
|
|
|
425
450
|
* organization and the step into one.
|
|
426
451
|
*/
|
|
427
452
|
export function superAdmin() {
|
|
428
|
-
return
|
|
453
|
+
return home() === ADMIN_ORG;
|
|
429
454
|
}
|
|
430
455
|
/** The organization a SuperAdmin stepped into through IAM, from the token's `assumed` claim, or null. */
|
|
431
456
|
export function assumed() {
|
|
@@ -459,17 +484,11 @@ export async function support(org) {
|
|
|
459
484
|
const exp = claimsOf(next ?? null)?.exp;
|
|
460
485
|
if (!res.ok || !next || typeof exp !== 'number')
|
|
461
486
|
throw new Error(body?.msg || `IAM answered ${res.status}.`);
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
pick(org ??
|
|
487
|
+
tokens().setItem(ACCESS, next);
|
|
488
|
+
tokens().setItem(EXPIRES, String(exp * 1000));
|
|
489
|
+
pick(org ?? listed(next).find((o) => !DIRECTORIES.includes(o)) ?? '');
|
|
465
490
|
window.location.reload();
|
|
466
491
|
}
|
|
467
|
-
/** The org of the person's own row: the first entry of a token's `orgs`. */
|
|
468
|
-
function homeOf(token) {
|
|
469
|
-
const set = claimsOf(token)?.orgs;
|
|
470
|
-
const first = Array.isArray(set) ? set[0]?.org : undefined;
|
|
471
|
-
return typeof first === 'string' ? first : '';
|
|
472
|
-
}
|
|
473
492
|
/**
|
|
474
493
|
* Leave support mode when IAM cannot answer the step out: the stored token is
|
|
475
494
|
* marked spent, so the SDK's refresh — which mints from the person's own grant
|
package/dist/where.d.ts
CHANGED
|
@@ -33,6 +33,12 @@ export interface Addresses {
|
|
|
33
33
|
brand?: string;
|
|
34
34
|
/** The publishable key anonymous calls carry. */
|
|
35
35
|
key?: string;
|
|
36
|
+
/**
|
|
37
|
+
* Where the IAM session is kept when it is not this page's `localStorage`:
|
|
38
|
+
* the `storage` the host hands its IamProvider (Hanzo Desktop's keychain).
|
|
39
|
+
* The rooms read the access token, its expiry and its claims from it.
|
|
40
|
+
*/
|
|
41
|
+
session?: Storage;
|
|
36
42
|
/** The plan catalogue as the host's build last read it: the first paint. */
|
|
37
43
|
plans?: BillingPlan[];
|
|
38
44
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hanzo/rooms",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.72",
|
|
4
4
|
"description": "The workspace rooms — Home, Chat, Inbox, Contacts, Meet, Cal, Drive, Board, Work, Bots — and the frame that holds them, once, for every Hanzo surface.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|