@finos/legend-application 16.0.105 → 16.0.107

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.
@@ -16,6 +16,11 @@
16
16
  /**
17
17
  * Must be rendered inside an `<AuthProvider>` and an
18
18
  * `<ApplicationStoreProvider>`.
19
+ *
20
+ * Keeps the in-memory token and cookie in sync with the OIDC provider
21
+ * and proactively renews the access token before it expires so that
22
+ * long-running sessions (e.g. Legend marketplace AI chat, query execution) never send
23
+ * stale credentials.
19
24
  */
20
25
  export declare const LegendTokenSync: (props: {
21
26
  children: React.ReactNode;
@@ -1 +1 @@
1
- {"version":3,"file":"LegendTokenSync.d.ts","sourceRoot":"","sources":["../../src/components/LegendTokenSync.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAQH;;;GAGG;AACH,eAAO,MAAM,eAAe,GAAI,OAAO;IACrC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,KAAG,KAAK,CAAC,YAgCT,CAAC"}
1
+ {"version":3,"file":"LegendTokenSync.d.ts","sourceRoot":"","sources":["../../src/components/LegendTokenSync.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAQH;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,GAAI,OAAO;IACrC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,KAAG,KAAK,CAAC,YA2DT,CAAC"}
@@ -14,7 +14,7 @@ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
14
14
  * See the License for the specific language governing permissions and
15
15
  * limitations under the License.
16
16
  */
17
- import { useEffect } from 'react';
17
+ import { useEffect, useCallback } from 'react';
18
18
  import { useAuth } from 'react-oidc-context';
19
19
  import { LogEvent } from '@finos/legend-shared';
20
20
  import { useApplicationStore } from './ApplicationStoreProvider.js';
@@ -22,12 +22,26 @@ import { APPLICATION_EVENT } from '../__lib__/LegendApplicationEvent.js';
22
22
  /**
23
23
  * Must be rendered inside an `<AuthProvider>` and an
24
24
  * `<ApplicationStoreProvider>`.
25
+ *
26
+ * Keeps the in-memory token and cookie in sync with the OIDC provider
27
+ * and proactively renews the access token before it expires so that
28
+ * long-running sessions (e.g. Legend marketplace AI chat, query execution) never send
29
+ * stale credentials.
25
30
  */
26
31
  export const LegendTokenSync = (props) => {
27
32
  const auth = useAuth();
28
33
  const applicationStore = useApplicationStore();
29
34
  const token = auth.user?.access_token;
30
35
  const expiresAt = auth.user?.expires_at;
36
+ const attemptSilentRenew = useCallback(async () => {
37
+ try {
38
+ await auth.signinSilent();
39
+ }
40
+ catch {
41
+ applicationStore.logService.warn(LogEvent.create(APPLICATION_EVENT.TOKEN_EXPIRED), 'OIDC silent renewal failed — clearing token');
42
+ applicationStore.setAccessToken(undefined);
43
+ }
44
+ }, [auth, applicationStore]);
31
45
  // Sync token into ApplicationStore whenever it changes (including
32
46
  // after a successful automatic silent renewal). When the auth object
33
47
  // contains an `expires_at` timestamp we derive `max-age` so the
@@ -38,15 +52,26 @@ export const LegendTokenSync = (props) => {
38
52
  : undefined;
39
53
  applicationStore.setAccessToken(token ?? undefined, maxAge);
40
54
  }, [applicationStore, token, expiresAt]);
55
+ useEffect(() => {
56
+ const removeExpiring = auth.events.addAccessTokenExpiring(() => {
57
+ applicationStore.logService.info(LogEvent.create(APPLICATION_EVENT.TOKEN_EXPIRED), 'OIDC access token expiring soon — attempting silent renewal');
58
+ attemptSilentRenew().catch(() => {
59
+ /* handled inside attemptSilentRenew */
60
+ });
61
+ });
62
+ return removeExpiring;
63
+ }, [auth.events, applicationStore, attemptSilentRenew]);
41
64
  // If the token fully expires (automatic renewal failed or was never
42
- // attempted) clear the stale token immediately.
65
+ // attempted) make one last renewal attempt before giving up.
43
66
  useEffect(() => {
44
67
  const removeExpired = auth.events.addAccessTokenExpired(() => {
45
- applicationStore.logService.warn(LogEvent.create(APPLICATION_EVENT.TOKEN_EXPIRED), 'OIDC access token expired — clearing token');
46
- applicationStore.setAccessToken(undefined);
68
+ applicationStore.logService.warn(LogEvent.create(APPLICATION_EVENT.TOKEN_EXPIRED), 'OIDC access token expired — attempting silent renewal');
69
+ attemptSilentRenew().catch(() => {
70
+ /* handled inside attemptSilentRenew */
71
+ });
47
72
  });
48
73
  return removeExpired;
49
- }, [auth.events, applicationStore]);
74
+ }, [auth.events, applicationStore, attemptSilentRenew]);
50
75
  return _jsx(_Fragment, { children: props.children });
51
76
  };
52
77
  //# sourceMappingURL=LegendTokenSync.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LegendTokenSync.js","sourceRoot":"","sources":["../../src/components/LegendTokenSync.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAEzE;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,KAE/B,EAAsB,EAAE;IACvB,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,gBAAgB,GAAG,mBAAmB,EAAE,CAAC;IAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC;IACtC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC;IAExC,kEAAkE;IAClE,sEAAsE;IACtE,gEAAgE;IAChE,wDAAwD;IACxD,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,MAAM,GACV,SAAS,KAAK,SAAS;YACrB,CAAC,CAAC,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;YAC3C,CAAC,CAAC,SAAS,CAAC;QAChB,gBAAgB,CAAC,cAAc,CAAC,KAAK,IAAI,SAAS,EAAE,MAAM,CAAC,CAAC;IAC9D,CAAC,EAAE,CAAC,gBAAgB,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;IAEzC,oEAAoE;IACpE,gDAAgD;IAChD,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,qBAAqB,CAAC,GAAG,EAAE;YAC3D,gBAAgB,CAAC,UAAU,CAAC,IAAI,CAC9B,QAAQ,CAAC,MAAM,CAAC,iBAAiB,CAAC,aAAa,CAAC,EAChD,4CAA4C,CAC7C,CAAC;YACF,gBAAgB,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;QACH,OAAO,aAAa,CAAC;IACvB,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAEpC,OAAO,4BAAG,KAAK,CAAC,QAAQ,GAAI,CAAC;AAC/B,CAAC,CAAC"}
1
+ {"version":3,"file":"LegendTokenSync.js","sourceRoot":"","sources":["../../src/components/LegendTokenSync.tsx"],"names":[],"mappings":"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"}
package/lib/index.css CHANGED
@@ -1,4 +1,4 @@
1
- /** @license @finos/legend-application v16.0.105
1
+ /** @license @finos/legend-application v16.0.107
2
2
  * Copyright (c) 2020-present, Goldman Sachs
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
package/lib/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@finos/legend-application",
3
- "version": "16.0.105",
3
+ "version": "16.0.107",
4
4
  "description": "Legend application core",
5
5
  "keywords": [
6
6
  "legend",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@finos/legend-application",
3
- "version": "16.0.105",
3
+ "version": "16.0.107",
4
4
  "description": "Legend application core",
5
5
  "keywords": [
6
6
  "legend",
@@ -45,9 +45,9 @@
45
45
  "test:watch": "jest --watch"
46
46
  },
47
47
  "dependencies": {
48
- "@finos/legend-art": "7.1.147",
49
- "@finos/legend-shared": "11.0.24",
50
- "@finos/legend-storage": "3.0.145",
48
+ "@finos/legend-art": "7.1.148",
49
+ "@finos/legend-shared": "11.0.25",
50
+ "@finos/legend-storage": "3.0.146",
51
51
  "@types/react": "19.0.10",
52
52
  "@types/react-dom": "19.0.4",
53
53
  "@types/react-router-dom": "5.3.3",
@@ -14,7 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import { useEffect } from 'react';
17
+ import { useEffect, useCallback } from 'react';
18
18
  import { useAuth } from 'react-oidc-context';
19
19
  import { LogEvent } from '@finos/legend-shared';
20
20
  import { useApplicationStore } from './ApplicationStoreProvider.js';
@@ -23,6 +23,11 @@ import { APPLICATION_EVENT } from '../__lib__/LegendApplicationEvent.js';
23
23
  /**
24
24
  * Must be rendered inside an `<AuthProvider>` and an
25
25
  * `<ApplicationStoreProvider>`.
26
+ *
27
+ * Keeps the in-memory token and cookie in sync with the OIDC provider
28
+ * and proactively renews the access token before it expires so that
29
+ * long-running sessions (e.g. Legend marketplace AI chat, query execution) never send
30
+ * stale credentials.
26
31
  */
27
32
  export const LegendTokenSync = (props: {
28
33
  children: React.ReactNode;
@@ -32,6 +37,18 @@ export const LegendTokenSync = (props: {
32
37
  const token = auth.user?.access_token;
33
38
  const expiresAt = auth.user?.expires_at;
34
39
 
40
+ const attemptSilentRenew = useCallback(async () => {
41
+ try {
42
+ await auth.signinSilent();
43
+ } catch {
44
+ applicationStore.logService.warn(
45
+ LogEvent.create(APPLICATION_EVENT.TOKEN_EXPIRED),
46
+ 'OIDC silent renewal failed — clearing token',
47
+ );
48
+ applicationStore.setAccessToken(undefined);
49
+ }
50
+ }, [auth, applicationStore]);
51
+
35
52
  // Sync token into ApplicationStore whenever it changes (including
36
53
  // after a successful automatic silent renewal). When the auth object
37
54
  // contains an `expires_at` timestamp we derive `max-age` so the
@@ -44,18 +61,33 @@ export const LegendTokenSync = (props: {
44
61
  applicationStore.setAccessToken(token ?? undefined, maxAge);
45
62
  }, [applicationStore, token, expiresAt]);
46
63
 
64
+ useEffect(() => {
65
+ const removeExpiring = auth.events.addAccessTokenExpiring(() => {
66
+ applicationStore.logService.info(
67
+ LogEvent.create(APPLICATION_EVENT.TOKEN_EXPIRED),
68
+ 'OIDC access token expiring soon — attempting silent renewal',
69
+ );
70
+ attemptSilentRenew().catch(() => {
71
+ /* handled inside attemptSilentRenew */
72
+ });
73
+ });
74
+ return removeExpiring;
75
+ }, [auth.events, applicationStore, attemptSilentRenew]);
76
+
47
77
  // If the token fully expires (automatic renewal failed or was never
48
- // attempted) clear the stale token immediately.
78
+ // attempted) make one last renewal attempt before giving up.
49
79
  useEffect(() => {
50
80
  const removeExpired = auth.events.addAccessTokenExpired(() => {
51
81
  applicationStore.logService.warn(
52
82
  LogEvent.create(APPLICATION_EVENT.TOKEN_EXPIRED),
53
- 'OIDC access token expired — clearing token',
83
+ 'OIDC access token expired — attempting silent renewal',
54
84
  );
55
- applicationStore.setAccessToken(undefined);
85
+ attemptSilentRenew().catch(() => {
86
+ /* handled inside attemptSilentRenew */
87
+ });
56
88
  });
57
89
  return removeExpired;
58
- }, [auth.events, applicationStore]);
90
+ }, [auth.events, applicationStore, attemptSilentRenew]);
59
91
 
60
92
  return <>{props.children}</>;
61
93
  };