@babelpeak/babel-suite-react-sdk 0.1.0
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/broker.d.ts +39 -0
- package/dist/broker.js +82 -0
- package/dist/broker.js.map +1 -0
- package/dist/can.d.ts +7 -0
- package/dist/can.js +8 -0
- package/dist/can.js.map +1 -0
- package/dist/config.d.ts +21 -0
- package/dist/config.js +24 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/provider.d.ts +49 -0
- package/dist/provider.js +226 -0
- package/dist/provider.js.map +1 -0
- package/package.json +47 -0
package/dist/broker.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export interface ScopedClaims {
|
|
2
|
+
sub: string;
|
|
3
|
+
aud: string | string[];
|
|
4
|
+
org_id?: string;
|
|
5
|
+
permissions?: string[];
|
|
6
|
+
exp: number;
|
|
7
|
+
iat: number;
|
|
8
|
+
[key: string]: unknown;
|
|
9
|
+
}
|
|
10
|
+
export interface ScopedToken {
|
|
11
|
+
token: string;
|
|
12
|
+
claims: ScopedClaims;
|
|
13
|
+
}
|
|
14
|
+
export declare class ExchangeError extends Error {
|
|
15
|
+
readonly code: string;
|
|
16
|
+
constructor(code: string, message?: string);
|
|
17
|
+
}
|
|
18
|
+
export declare function decodeClaims(token: string): ScopedClaims;
|
|
19
|
+
/**
|
|
20
|
+
* Ottiene e tiene in cache il JWT scoped del servizio via token exchange (RFC 8693).
|
|
21
|
+
* Il token di sessione ampio resta nella SPA: verso le API del servizio viaggia solo quello scoped.
|
|
22
|
+
*/
|
|
23
|
+
export declare class ScopedTokenBroker {
|
|
24
|
+
private readonly opts;
|
|
25
|
+
private cache;
|
|
26
|
+
private inflight;
|
|
27
|
+
constructor(opts: {
|
|
28
|
+
issuer: string;
|
|
29
|
+
clientId: string;
|
|
30
|
+
service: string;
|
|
31
|
+
fetch?: typeof fetch;
|
|
32
|
+
now?: () => number;
|
|
33
|
+
});
|
|
34
|
+
private now;
|
|
35
|
+
isFresh(t: ScopedToken | undefined): t is ScopedToken;
|
|
36
|
+
get(sessionToken: string, orgId?: string | null): Promise<ScopedToken>;
|
|
37
|
+
clear(): void;
|
|
38
|
+
private exchange;
|
|
39
|
+
}
|
package/dist/broker.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
export class ExchangeError extends Error {
|
|
2
|
+
code;
|
|
3
|
+
constructor(code, message) {
|
|
4
|
+
super(message ?? code);
|
|
5
|
+
this.code = code;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
export function decodeClaims(token) {
|
|
9
|
+
const part = token.split('.')[1];
|
|
10
|
+
if (!part)
|
|
11
|
+
throw new Error('JWT non valido');
|
|
12
|
+
const json = atob(part.replace(/-/g, '+').replace(/_/g, '/'));
|
|
13
|
+
const bytes = Uint8Array.from(json, (c) => c.charCodeAt(0));
|
|
14
|
+
return JSON.parse(new TextDecoder().decode(bytes));
|
|
15
|
+
}
|
|
16
|
+
/** Margine prima della scadenza entro cui il token viene riemesso. */
|
|
17
|
+
const REFRESH_MARGIN_SEC = 30;
|
|
18
|
+
/**
|
|
19
|
+
* Ottiene e tiene in cache il JWT scoped del servizio via token exchange (RFC 8693).
|
|
20
|
+
* Il token di sessione ampio resta nella SPA: verso le API del servizio viaggia solo quello scoped.
|
|
21
|
+
*/
|
|
22
|
+
export class ScopedTokenBroker {
|
|
23
|
+
opts;
|
|
24
|
+
cache = new Map();
|
|
25
|
+
inflight = new Map();
|
|
26
|
+
constructor(opts) {
|
|
27
|
+
this.opts = opts;
|
|
28
|
+
}
|
|
29
|
+
now() {
|
|
30
|
+
return Math.floor((this.opts.now?.() ?? Date.now()) / 1000);
|
|
31
|
+
}
|
|
32
|
+
isFresh(t) {
|
|
33
|
+
return !!t && t.claims.exp - REFRESH_MARGIN_SEC > this.now();
|
|
34
|
+
}
|
|
35
|
+
async get(sessionToken, orgId) {
|
|
36
|
+
const key = `${sessionToken}|${orgId ?? ''}`;
|
|
37
|
+
const cached = this.cache.get(key);
|
|
38
|
+
if (this.isFresh(cached))
|
|
39
|
+
return cached;
|
|
40
|
+
const pending = this.inflight.get(key);
|
|
41
|
+
if (pending)
|
|
42
|
+
return pending;
|
|
43
|
+
const p = this.exchange(sessionToken, orgId)
|
|
44
|
+
.then((t) => {
|
|
45
|
+
this.cache.clear();
|
|
46
|
+
this.cache.set(key, t);
|
|
47
|
+
// Anche sotto l'org effettiva: evita un secondo exchange quando la SPA la adotta.
|
|
48
|
+
if (t.claims.org_id)
|
|
49
|
+
this.cache.set(`${sessionToken}|${t.claims.org_id}`, t);
|
|
50
|
+
return t;
|
|
51
|
+
})
|
|
52
|
+
.finally(() => this.inflight.delete(key));
|
|
53
|
+
this.inflight.set(key, p);
|
|
54
|
+
return p;
|
|
55
|
+
}
|
|
56
|
+
clear() {
|
|
57
|
+
this.cache.clear();
|
|
58
|
+
}
|
|
59
|
+
async exchange(sessionToken, orgId) {
|
|
60
|
+
const body = new URLSearchParams({
|
|
61
|
+
grant_type: 'urn:ietf:params:oauth:grant-type:token-exchange',
|
|
62
|
+
client_id: this.opts.clientId,
|
|
63
|
+
subject_token: sessionToken,
|
|
64
|
+
subject_token_type: 'urn:ietf:params:oauth:token-type:access_token',
|
|
65
|
+
audience: this.opts.service,
|
|
66
|
+
});
|
|
67
|
+
if (orgId)
|
|
68
|
+
body.set('org_id', orgId);
|
|
69
|
+
const doFetch = this.opts.fetch ?? fetch;
|
|
70
|
+
const res = await doFetch(`${this.opts.issuer.replace(/\/$/, '')}/oauth/token`, {
|
|
71
|
+
method: 'POST',
|
|
72
|
+
headers: { 'content-type': 'application/x-www-form-urlencoded' },
|
|
73
|
+
body,
|
|
74
|
+
});
|
|
75
|
+
const json = (await res.json());
|
|
76
|
+
if (!res.ok || !json.access_token) {
|
|
77
|
+
throw new ExchangeError(json.error ?? `http_${res.status}`, json.error_description);
|
|
78
|
+
}
|
|
79
|
+
return { token: json.access_token, claims: decodeClaims(json.access_token) };
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=broker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"broker.js","sourceRoot":"","sources":["../src/broker.ts"],"names":[],"mappings":"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"}
|
package/dist/can.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
/** Mostra i figli solo se l'utente ha il permesso (ergonomia di UI, non sicurezza). */
|
|
3
|
+
export declare function Can(props: {
|
|
4
|
+
permission: string;
|
|
5
|
+
children: ReactNode;
|
|
6
|
+
fallback?: ReactNode;
|
|
7
|
+
}): import("react").JSX.Element;
|
package/dist/can.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useSuite } from './provider.js';
|
|
3
|
+
/** Mostra i figli solo se l'utente ha il permesso (ergonomia di UI, non sicurezza). */
|
|
4
|
+
export function Can(props) {
|
|
5
|
+
const { can } = useSuite();
|
|
6
|
+
return _jsx(_Fragment, { children: can(props.permission) ? props.children : (props.fallback ?? null) });
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=can.js.map
|
package/dist/can.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"can.js","sourceRoot":"","sources":["../src/can.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,uFAAuF;AACvF,MAAM,UAAU,GAAG,CAAC,KAAwE;IAC1F,MAAM,EAAE,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;IAC3B,OAAO,4BAAG,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,GAAI,CAAC;AAClF,CAAC"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
declare global {
|
|
2
|
+
interface Window {
|
|
3
|
+
/** Configurazione globale opzionale, per app non costruite con Vite. */
|
|
4
|
+
__BABEL_SUITE__?: {
|
|
5
|
+
issuer?: string;
|
|
6
|
+
clientId?: string;
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export interface ResolvedSuiteConfig {
|
|
11
|
+
issuer: string;
|
|
12
|
+
clientId: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Issuer e client id di Suite: props → window.__BABEL_SUITE__ → VITE_SUITE_ISSUER /
|
|
16
|
+
* VITE_SUITE_CLIENT_ID. Il client id di default è `<service>-web`.
|
|
17
|
+
*/
|
|
18
|
+
export declare function resolveSuiteConfig(service: string, props: {
|
|
19
|
+
issuer?: string;
|
|
20
|
+
clientId?: string;
|
|
21
|
+
}): ResolvedSuiteConfig;
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
function viteEnv() {
|
|
2
|
+
// `import.meta.env` scritto per esteso: è il testo che Vite sostituisce nella build dell'app.
|
|
3
|
+
// Fuori da Vite vale undefined.
|
|
4
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
5
|
+
// @ts-ignore -- tipo fornito da vite/client solo nelle app che lo includono
|
|
6
|
+
return import.meta.env;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Issuer e client id di Suite: props → window.__BABEL_SUITE__ → VITE_SUITE_ISSUER /
|
|
10
|
+
* VITE_SUITE_CLIENT_ID. Il client id di default è `<service>-web`.
|
|
11
|
+
*/
|
|
12
|
+
export function resolveSuiteConfig(service, props) {
|
|
13
|
+
const global = typeof window !== 'undefined' ? window.__BABEL_SUITE__ : undefined;
|
|
14
|
+
const env = viteEnv();
|
|
15
|
+
const issuer = props.issuer ?? global?.issuer ?? env?.VITE_SUITE_ISSUER;
|
|
16
|
+
if (!issuer) {
|
|
17
|
+
throw new Error('Issuer di Suite non configurato: passa `issuer` a <SuiteProvider>, imposta VITE_SUITE_ISSUER o window.__BABEL_SUITE__');
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
issuer,
|
|
21
|
+
clientId: props.clientId ?? global?.clientId ?? env?.VITE_SUITE_CLIENT_ID ?? `${service}-web`,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAYA,SAAS,OAAO;IACd,8FAA8F;IAC9F,gCAAgC;IAChC,6DAA6D;IAC7D,4EAA4E;IAC5E,OAAO,MAAM,CAAC,IAAI,CAAC,GAA2B,CAAC;AACjD,CAAC;AAOD;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAAe,EACf,KAA6C;IAE7C,MAAM,MAAM,GAAG,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC;IAClF,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;IACtB,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,MAAM,EAAE,MAAM,IAAI,GAAG,EAAE,iBAAiB,CAAC;IACxE,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,uHAAuH,CACxH,CAAC;IACJ,CAAC;IACD,OAAO;QACL,MAAM;QACN,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,MAAM,EAAE,QAAQ,IAAI,GAAG,EAAE,oBAAoB,IAAI,GAAG,OAAO,MAAM;KAC9F,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { SuiteProvider, SuiteTestProvider, useSuite, type SuiteContextValue, type SuiteOrg, type SuiteProviderProps, type SuiteStatus, type SuiteUser, } from './provider.js';
|
|
2
|
+
export { Can } from './can.js';
|
|
3
|
+
export { ExchangeError, ScopedTokenBroker, decodeClaims, type ScopedClaims, type ScopedToken, } from './broker.js';
|
|
4
|
+
export { resolveSuiteConfig, type ResolvedSuiteConfig } from './config.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { SuiteProvider, SuiteTestProvider, useSuite, } from './provider.js';
|
|
2
|
+
export { Can } from './can.js';
|
|
3
|
+
export { ExchangeError, ScopedTokenBroker, decodeClaims, } from './broker.js';
|
|
4
|
+
export { resolveSuiteConfig } from './config.js';
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,QAAQ,GAMT,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,YAAY,GAGb,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,kBAAkB,EAA4B,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
export interface SuiteOrg {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
role: string;
|
|
6
|
+
}
|
|
7
|
+
export interface SuiteUser {
|
|
8
|
+
id: string;
|
|
9
|
+
email?: string;
|
|
10
|
+
name?: string;
|
|
11
|
+
}
|
|
12
|
+
export type SuiteStatus = 'loading' | 'anonymous' | 'ready' | 'no-access' | 'error';
|
|
13
|
+
export interface SuiteContextValue {
|
|
14
|
+
status: SuiteStatus;
|
|
15
|
+
user: SuiteUser | null;
|
|
16
|
+
orgs: SuiteOrg[];
|
|
17
|
+
org: SuiteOrg | null;
|
|
18
|
+
permissions: string[];
|
|
19
|
+
/** Solo ergonomia di UI: l'autorizzazione vera resta sulle API. */
|
|
20
|
+
can: (permission: string) => boolean;
|
|
21
|
+
/** JWT scoped del servizio (aud = service), da allegare alle chiamate API. */
|
|
22
|
+
token: string | null;
|
|
23
|
+
error: string | null;
|
|
24
|
+
selectOrg: (orgId: string) => void;
|
|
25
|
+
reloadOrgs: () => Promise<void>;
|
|
26
|
+
login: (returnTo?: string) => Promise<void>;
|
|
27
|
+
logout: () => Promise<void>;
|
|
28
|
+
/** fetch con bearer scoped; su 401 riemette il token e ritenta una volta. */
|
|
29
|
+
fetch: (input: string, init?: RequestInit) => Promise<Response>;
|
|
30
|
+
}
|
|
31
|
+
export interface SuiteProviderProps {
|
|
32
|
+
/** Default: window.__BABEL_SUITE__.issuer o VITE_SUITE_ISSUER. */
|
|
33
|
+
issuer?: string;
|
|
34
|
+
/** Default: window.__BABEL_SUITE__.clientId, VITE_SUITE_CLIENT_ID o `<service>-web`. */
|
|
35
|
+
clientId?: string;
|
|
36
|
+
service: string;
|
|
37
|
+
redirectUri?: string;
|
|
38
|
+
postLogoutRedirectUri?: string;
|
|
39
|
+
scope?: string;
|
|
40
|
+
children: ReactNode;
|
|
41
|
+
}
|
|
42
|
+
/** Provider OIDC preconfigurato sull'issuer di Suite + token scoped del servizio. */
|
|
43
|
+
export declare function SuiteProvider(props: SuiteProviderProps): import("react").JSX.Element;
|
|
44
|
+
export declare function useSuite(): SuiteContextValue;
|
|
45
|
+
/** Per i test e le storybook: fornisce un contesto Suite statico senza OIDC. */
|
|
46
|
+
export declare function SuiteTestProvider(props: {
|
|
47
|
+
value: Partial<SuiteContextValue>;
|
|
48
|
+
children: ReactNode;
|
|
49
|
+
}): import("react").JSX.Element;
|
package/dist/provider.js
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, } from 'react';
|
|
3
|
+
import { WebStorageStateStore } from 'oidc-client-ts';
|
|
4
|
+
import { AuthProvider, useAuth } from 'react-oidc-context';
|
|
5
|
+
import { ExchangeError, ScopedTokenBroker } from './broker.js';
|
|
6
|
+
import { resolveSuiteConfig } from './config.js';
|
|
7
|
+
const SuiteContext = createContext(null);
|
|
8
|
+
const orgStorageKey = (service) => `babel-suite:${service}:org`;
|
|
9
|
+
function readStorage(key) {
|
|
10
|
+
try {
|
|
11
|
+
return window.localStorage.getItem(key);
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function writeStorage(key, value) {
|
|
18
|
+
try {
|
|
19
|
+
if (value === null)
|
|
20
|
+
window.localStorage.removeItem(key);
|
|
21
|
+
else
|
|
22
|
+
window.localStorage.setItem(key, value);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
/* storage non disponibile: la scelta dell'org non viene ricordata */
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/** Provider OIDC preconfigurato sull'issuer di Suite + token scoped del servizio. */
|
|
29
|
+
export function SuiteProvider(props) {
|
|
30
|
+
const { redirectUri, postLogoutRedirectUri, scope } = props;
|
|
31
|
+
const { issuer, clientId } = resolveSuiteConfig(props.service, props);
|
|
32
|
+
const config = useMemo(() => ({
|
|
33
|
+
authority: issuer,
|
|
34
|
+
client_id: clientId,
|
|
35
|
+
redirect_uri: redirectUri ?? `${window.location.origin}/callback`,
|
|
36
|
+
post_logout_redirect_uri: postLogoutRedirectUri ?? `${window.location.origin}/`,
|
|
37
|
+
scope: scope ?? 'openid email profile offline_access orgs',
|
|
38
|
+
response_type: 'code',
|
|
39
|
+
loadUserInfo: true,
|
|
40
|
+
automaticSilentRenew: true,
|
|
41
|
+
// sessionStorage (non localStorage): i token non sopravvivono alla scheda. Una nuova
|
|
42
|
+
// scheda riparte dalla sessione OIDC di Suite con un redirect senza form di login.
|
|
43
|
+
userStore: new WebStorageStateStore({ store: window.sessionStorage }),
|
|
44
|
+
onSigninCallback: (user) => {
|
|
45
|
+
const returnTo = user?.state?.returnTo ?? '/';
|
|
46
|
+
window.history.replaceState({}, document.title, returnTo);
|
|
47
|
+
},
|
|
48
|
+
}), [issuer, clientId, redirectUri, postLogoutRedirectUri, scope]);
|
|
49
|
+
return (_jsx(AuthProvider, { ...config, children: _jsx(SuiteSession, { issuer: issuer, clientId: clientId, service: props.service, children: props.children }) }));
|
|
50
|
+
}
|
|
51
|
+
function SuiteSession(props) {
|
|
52
|
+
const { issuer, clientId, service } = props;
|
|
53
|
+
const auth = useAuth();
|
|
54
|
+
const broker = useMemo(() => new ScopedTokenBroker({ issuer, clientId, service }), [issuer, clientId, service]);
|
|
55
|
+
const [orgId, setOrgId] = useState(() => readStorage(orgStorageKey(service)));
|
|
56
|
+
const [scoped, setScoped] = useState(null);
|
|
57
|
+
const [error, setError] = useState(null);
|
|
58
|
+
const [exchanging, setExchanging] = useState(false);
|
|
59
|
+
const [orgs, setOrgs] = useState([]);
|
|
60
|
+
const sessionToken = auth.user?.access_token;
|
|
61
|
+
const tokenRef = useRef(null);
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
setOrgs((auth.user?.profile?.orgs ?? []));
|
|
64
|
+
}, [auth.user]);
|
|
65
|
+
const refresh = useCallback(async (force = false) => {
|
|
66
|
+
if (!sessionToken)
|
|
67
|
+
return null;
|
|
68
|
+
if (force)
|
|
69
|
+
broker.clear();
|
|
70
|
+
setExchanging(true);
|
|
71
|
+
try {
|
|
72
|
+
const t = await broker.get(sessionToken, orgId);
|
|
73
|
+
tokenRef.current = t;
|
|
74
|
+
setScoped(t);
|
|
75
|
+
setError(null);
|
|
76
|
+
// L'org effettiva è quella del token: allinea la scelta salvata.
|
|
77
|
+
if (t.claims.org_id && t.claims.org_id !== orgId)
|
|
78
|
+
setOrgId(t.claims.org_id);
|
|
79
|
+
return t;
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
if (err instanceof ExchangeError && err.code === 'access_denied' && orgId) {
|
|
83
|
+
// Org salvata non più valida: si riparte dalla prima disponibile.
|
|
84
|
+
writeStorage(orgStorageKey(service), null);
|
|
85
|
+
setOrgId(null);
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
tokenRef.current = null;
|
|
89
|
+
setScoped(null);
|
|
90
|
+
setError(err instanceof ExchangeError ? err.code : err.message);
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
finally {
|
|
94
|
+
setExchanging(false);
|
|
95
|
+
}
|
|
96
|
+
}, [broker, sessionToken, orgId, service]);
|
|
97
|
+
useEffect(() => {
|
|
98
|
+
if (sessionToken)
|
|
99
|
+
void refresh();
|
|
100
|
+
else {
|
|
101
|
+
tokenRef.current = null;
|
|
102
|
+
setScoped(null);
|
|
103
|
+
}
|
|
104
|
+
}, [sessionToken, refresh]);
|
|
105
|
+
// Riemissione poco prima della scadenza (TTL breve per design).
|
|
106
|
+
useEffect(() => {
|
|
107
|
+
if (!scoped)
|
|
108
|
+
return;
|
|
109
|
+
const ms = Math.max((scoped.claims.exp - 30) * 1000 - Date.now(), 5_000);
|
|
110
|
+
const id = window.setTimeout(() => void refresh(true), ms);
|
|
111
|
+
return () => window.clearTimeout(id);
|
|
112
|
+
}, [scoped, refresh]);
|
|
113
|
+
useEffect(() => {
|
|
114
|
+
writeStorage(orgStorageKey(service), orgId);
|
|
115
|
+
}, [orgId, service]);
|
|
116
|
+
const reloadOrgs = useCallback(async () => {
|
|
117
|
+
if (!sessionToken)
|
|
118
|
+
return;
|
|
119
|
+
const res = await fetch(`${issuer.replace(/\/$/, '')}/oauth/userinfo`, {
|
|
120
|
+
headers: { authorization: `Bearer ${sessionToken}` },
|
|
121
|
+
});
|
|
122
|
+
if (res.ok) {
|
|
123
|
+
const info = (await res.json());
|
|
124
|
+
setOrgs(info.orgs ?? []);
|
|
125
|
+
}
|
|
126
|
+
}, [issuer, sessionToken]);
|
|
127
|
+
const authedFetch = useCallback(async (input, init = {}) => {
|
|
128
|
+
const send = (t) => {
|
|
129
|
+
const headers = new Headers(init.headers);
|
|
130
|
+
if (t)
|
|
131
|
+
headers.set('authorization', `Bearer ${t.token}`);
|
|
132
|
+
return fetch(input, { ...init, headers });
|
|
133
|
+
};
|
|
134
|
+
let t = tokenRef.current && broker.isFresh(tokenRef.current) ? tokenRef.current : await refresh();
|
|
135
|
+
let res = await send(t);
|
|
136
|
+
if (res.status === 401) {
|
|
137
|
+
t = await refresh(true);
|
|
138
|
+
res = await send(t);
|
|
139
|
+
}
|
|
140
|
+
return res;
|
|
141
|
+
}, [broker, refresh]);
|
|
142
|
+
const value = useMemo(() => {
|
|
143
|
+
const profile = auth.user?.profile;
|
|
144
|
+
const permissions = scoped?.claims.permissions ?? [];
|
|
145
|
+
const currentOrgId = scoped?.claims.org_id ?? null;
|
|
146
|
+
const org = orgs.find((o) => o.id === currentOrgId) ??
|
|
147
|
+
(currentOrgId ? { id: currentOrgId, name: '', role: '' } : null);
|
|
148
|
+
let status;
|
|
149
|
+
if (auth.isLoading || (sessionToken && exchanging && !scoped))
|
|
150
|
+
status = 'loading';
|
|
151
|
+
else if (!auth.isAuthenticated)
|
|
152
|
+
status = 'anonymous';
|
|
153
|
+
else if (scoped)
|
|
154
|
+
status = 'ready';
|
|
155
|
+
else if (error === 'access_denied')
|
|
156
|
+
status = 'no-access';
|
|
157
|
+
else if (error)
|
|
158
|
+
status = 'error';
|
|
159
|
+
else
|
|
160
|
+
status = 'loading';
|
|
161
|
+
return {
|
|
162
|
+
status,
|
|
163
|
+
user: profile ? { id: profile.sub, email: profile.email, name: profile.name } : null,
|
|
164
|
+
orgs,
|
|
165
|
+
org,
|
|
166
|
+
permissions,
|
|
167
|
+
can: (p) => permissions.includes(p),
|
|
168
|
+
token: scoped?.token ?? null,
|
|
169
|
+
error: error ?? (auth.error ? auth.error.message : null),
|
|
170
|
+
selectOrg: (id) => {
|
|
171
|
+
broker.clear();
|
|
172
|
+
setOrgId(id);
|
|
173
|
+
},
|
|
174
|
+
reloadOrgs,
|
|
175
|
+
login: (returnTo) => auth.signinRedirect({
|
|
176
|
+
state: { returnTo: returnTo ?? window.location.pathname + window.location.search },
|
|
177
|
+
}),
|
|
178
|
+
logout: async () => {
|
|
179
|
+
broker.clear();
|
|
180
|
+
writeStorage(orgStorageKey(service), null);
|
|
181
|
+
await auth.signoutRedirect({ id_token_hint: auth.user?.id_token });
|
|
182
|
+
},
|
|
183
|
+
fetch: authedFetch,
|
|
184
|
+
};
|
|
185
|
+
}, [
|
|
186
|
+
auth,
|
|
187
|
+
scoped,
|
|
188
|
+
orgs,
|
|
189
|
+
exchanging,
|
|
190
|
+
error,
|
|
191
|
+
sessionToken,
|
|
192
|
+
broker,
|
|
193
|
+
reloadOrgs,
|
|
194
|
+
authedFetch,
|
|
195
|
+
service,
|
|
196
|
+
]);
|
|
197
|
+
return _jsx(SuiteContext.Provider, { value: value, children: props.children });
|
|
198
|
+
}
|
|
199
|
+
export function useSuite() {
|
|
200
|
+
const ctx = useContext(SuiteContext);
|
|
201
|
+
if (!ctx)
|
|
202
|
+
throw new Error('useSuite va usato dentro <SuiteProvider>');
|
|
203
|
+
return ctx;
|
|
204
|
+
}
|
|
205
|
+
/** Per i test e le storybook: fornisce un contesto Suite statico senza OIDC. */
|
|
206
|
+
export function SuiteTestProvider(props) {
|
|
207
|
+
const permissions = props.value.permissions ?? [];
|
|
208
|
+
const value = {
|
|
209
|
+
status: 'ready',
|
|
210
|
+
user: null,
|
|
211
|
+
orgs: [],
|
|
212
|
+
org: null,
|
|
213
|
+
token: null,
|
|
214
|
+
error: null,
|
|
215
|
+
selectOrg: () => { },
|
|
216
|
+
reloadOrgs: async () => { },
|
|
217
|
+
login: async () => { },
|
|
218
|
+
logout: async () => { },
|
|
219
|
+
fetch: (input, init) => fetch(input, init),
|
|
220
|
+
...props.value,
|
|
221
|
+
permissions,
|
|
222
|
+
can: props.value.can ?? ((p) => permissions.includes(p)),
|
|
223
|
+
};
|
|
224
|
+
return _jsx(SuiteContext.Provider, { value: value, children: props.children });
|
|
225
|
+
}
|
|
226
|
+
//# sourceMappingURL=provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@babelpeak/babel-suite-react-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "SDK React per le SPA dei servizi Babel: login OIDC, token scoped, permessi",
|
|
5
|
+
"license": "UNLICENSED",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/Babel-Peak/babel-suite.git",
|
|
9
|
+
"directory": "packages/suite-react"
|
|
10
|
+
},
|
|
11
|
+
"publishConfig": {
|
|
12
|
+
"access": "public"
|
|
13
|
+
},
|
|
14
|
+
"type": "module",
|
|
15
|
+
"main": "./dist/index.js",
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"@babel-suite/source": "./src/index.ts",
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"default": "./dist/index.js"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist"
|
|
26
|
+
],
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "tsc -p tsconfig.build.json",
|
|
29
|
+
"typecheck": "tsc --noEmit",
|
|
30
|
+
"test": "vitest run"
|
|
31
|
+
},
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"react": "^18.0.0 || ^19.0.0"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"oidc-client-ts": "^3.5.0",
|
|
37
|
+
"react-oidc-context": "^3.3.1"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@testing-library/react": "^16.3.3",
|
|
41
|
+
"@types/react": "^19.3.0",
|
|
42
|
+
"@types/react-dom": "^19.3.0",
|
|
43
|
+
"jsdom": "^30.1.1",
|
|
44
|
+
"react": "^19.3.0",
|
|
45
|
+
"react-dom": "^19.3.0"
|
|
46
|
+
}
|
|
47
|
+
}
|