@genesislcap/foundation-auth 15.50.2 → 15.50.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.
@@ -238,6 +238,15 @@ export interface AuthConfig extends PartialFASTElementDefinition {
238
238
  * The amount of seconds to display user feedback messages, such as "check your inbox" etc. Defaults to 3 seconds.
239
239
  */
240
240
  feedbackDelay?: number;
241
+ /**
242
+ * Session refresh timeout.
243
+ *
244
+ * @remarks
245
+ * How many milliseconds silent login waits to refresh an expired session with the refresh cookie (including
246
+ * waiting for another tab that is already refreshing) before showing the silent login error. Keep it above the
247
+ * cross-tab lock wait of about 31 seconds. Defaults to 35 seconds.
248
+ */
249
+ sessionRefreshTimeout?: number;
241
250
  /**
242
251
  * I18n resources.
243
252
  *
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/config/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAE7D,OAAO,EAAE,gBAAgB,EAAO,4BAA4B,EAAE,MAAM,yBAAyB,CAAC;AAK9F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGlD,OAAO,EAA0B,eAAe,EAAE,MAAM,aAAa,CAAC;AAEtE;;GAEG;AAEH;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,YAAY,EAAE,WAAW,GAAG,IAAI,CAAC;IACjC,QAAQ,EAAE,WAAW,CAAC;IACtB,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,EAAE,WAAW,CAAC;CACvB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG;IACtB;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF;;;;GAIG;AACH,MAAM,WAAW,UAAW,SAAQ,4BAA4B;IAC9D;;;;;OAKG;IACH,eAAe,EAAE,eAAe,CAAC;IACjC;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,IAAI,EAAE,gBAAgB,GAAG,gBAAgB,EAAE,GAAG,IAAI,CAAC;IACnD;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;;;;;;;;;;OAeG;IACH,UAAU,EAAE,gBAAgB,GAAG,gBAAgB,EAAE,GAAG,IAAI,CAAC;IACzD;;;;;OAKG;IACH,eAAe,EAAE;QACf,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,WAAW,GAAG,WAAW,GAAG,YAAY,CAAC;KAChD,GAAG,IAAI,CAAC;IACT;;;;;;;;;;OAUG;IACH,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,OAAO,GAAG,WAAW,CAAC,EAAE,CAAC;IACzD;;;;;;OAMG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC;;;;;OAKG;IACH,MAAM,EAAE,cAAc,CAAC;IACvB;;;;;OAKG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;;;OAOG;IACH,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,iBAAiB,EAAE,MAAM,IAAI,CAAC;IAC9B;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,kBAAkB,EAAE,MAAM,IAAI,CAAC;IAC/B;;;;;OAKG;IACH,GAAG,EAAE,SAAS,GAAG,IAAI,CAAC;IACtB;;;;;;;;;;OAUG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,qBAAqB,CAAC,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IAEnD;;OAEG;IACH,wBAAwB,CAAC,EAAE,OAAO,CAAC;CACpC;AAED;;;GAGG;AACH,eAAO,MAAM,iBAAiB,EAAE,UA2C/B,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,kEAOtB,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/config/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAE7D,OAAO,EAAE,gBAAgB,EAAO,4BAA4B,EAAE,MAAM,yBAAyB,CAAC;AAK9F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGlD,OAAO,EAA0B,eAAe,EAAE,MAAM,aAAa,CAAC;AAEtE;;GAEG;AAEH;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,YAAY,EAAE,WAAW,GAAG,IAAI,CAAC;IACjC,QAAQ,EAAE,WAAW,CAAC;IACtB,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,EAAE,WAAW,CAAC;CACvB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG;IACtB;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF;;;;GAIG;AACH,MAAM,WAAW,UAAW,SAAQ,4BAA4B;IAC9D;;;;;OAKG;IACH,eAAe,EAAE,eAAe,CAAC;IACjC;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,IAAI,EAAE,gBAAgB,GAAG,gBAAgB,EAAE,GAAG,IAAI,CAAC;IACnD;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;;;;;;;;;;OAeG;IACH,UAAU,EAAE,gBAAgB,GAAG,gBAAgB,EAAE,GAAG,IAAI,CAAC;IACzD;;;;;OAKG;IACH,eAAe,EAAE;QACf,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,WAAW,GAAG,WAAW,GAAG,YAAY,CAAC;KAChD,GAAG,IAAI,CAAC;IACT;;;;;;;;;;OAUG;IACH,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,OAAO,GAAG,WAAW,CAAC,EAAE,CAAC;IACzD;;;;;;OAMG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC;;;;;OAKG;IACH,MAAM,EAAE,cAAc,CAAC;IACvB;;;;;OAKG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;;;OAOG;IACH,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,iBAAiB,EAAE,MAAM,IAAI,CAAC;IAC9B;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,kBAAkB,EAAE,MAAM,IAAI,CAAC;IAC/B;;;;;OAKG;IACH,GAAG,EAAE,SAAS,GAAG,IAAI,CAAC;IACtB;;;;;;;;;;OAUG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;;OAOG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,qBAAqB,CAAC,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IAEnD;;OAEG;IACH,wBAAwB,CAAC,EAAE,OAAO,CAAC;CACpC;AAED;;;GAGG;AACH,eAAO,MAAM,iBAAiB,EAAE,UA4C/B,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,kEAOtB,CAAC"}
@@ -60,6 +60,54 @@ export declare class DefaultAuthMachine extends AbstractMachine<AuthMachineConte
60
60
  actions: string[];
61
61
  target: string;
62
62
  };
63
+ /**
64
+ * Fetches login details with the session cookie. A 401 goes to `unauthorizedTarget`.
65
+ */
66
+ protected loginDetailsStateNode: (unauthorizedTarget: string) => {
67
+ invoke: {
68
+ id: string;
69
+ src: import("xstate").StateMachine<import("@genesislcap/foundation-state-machine").FetchMachineContext, FetchMachineEvent, import("xstate").ParameterizedObject, import("xstate").ProvidedActor, any, import("xstate").ResolveTypegenMeta<import("xstate").TypegenDisabled, FetchMachineEvent, import("xstate").ParameterizedObject, import("xstate").ProvidedActor>>;
70
+ onDone: ({
71
+ actions: string[];
72
+ target: string;
73
+ } | {
74
+ guard: string;
75
+ target: string;
76
+ })[];
77
+ onError: ({
78
+ guard: string;
79
+ target: string;
80
+ } | {
81
+ target: string;
82
+ guard?: undefined;
83
+ })[];
84
+ };
85
+ entry: {
86
+ (_: import("xstate").ActionArgs<import("xstate").MachineContext, import("xstate").EventObject, import("xstate").ParameterizedObject>): void;
87
+ type: string;
88
+ to: string | import("xstate").AnyActorRef | ((args: import("xstate").UnifiedArg<import("xstate").MachineContext, import("xstate").EventObject>) => string | import("xstate").AnyActorRef);
89
+ event: any;
90
+ id: string | undefined;
91
+ delay: string | number | import("xstate").DelayExpr<import("xstate").MachineContext, import("xstate").EventObject>;
92
+ resolve: (actorContext: import("xstate").AnyActorContext, state: import("xstate").AnyState, args: import("xstate").ActionArgs<any, any>, { to, event: eventOrExpr, id, delay }: {
93
+ to: import("xstate").AnyActorRef | string | ((args: import("xstate").UnifiedArg<import("xstate").MachineContext, import("xstate").EventObject>) => import("xstate").AnyActorRef | string);
94
+ event: import("xstate").EventObject | import("xstate").SendExpr<import("xstate").MachineContext, import("xstate").EventObject, import("xstate").EventObject>;
95
+ id: string | undefined;
96
+ delay: string | number | import("xstate").DelayExpr<import("xstate").MachineContext, import("xstate").EventObject> | undefined;
97
+ }) => (import("xstate").AnyState | {
98
+ to: import("xstate").AnyActorRef;
99
+ event: import("xstate").EventObject;
100
+ id: string | undefined;
101
+ delay: number | undefined;
102
+ })[];
103
+ execute: (actorContext: import("xstate").AnyActorContext, params: {
104
+ to: import("xstate").AnyActorRef;
105
+ event: import("xstate").EventObject;
106
+ id: string | undefined;
107
+ delay: number | undefined;
108
+ }) => void;
109
+ }[];
110
+ };
63
111
  }
64
112
  /**
65
113
  * AuthMachine DI key.
@@ -1 +1 @@
1
- {"version":3,"file":"machine.d.ts","sourceRoot":"","sources":["../../../src/machine/machine.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EAEf,YAAY,EACZ,iBAAiB,EAMjB,OAAO,EACR,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AACpD,OAAO,EACL,IAAI,EASL,MAAM,+BAA+B,CAAC;AAEvC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAEjD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAEL,iBAAiB,EAIlB,MAAM,eAAe,CAAC;AAIvB,OAAO,EACL,iBAAiB,EAQlB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,KAAK,EAEV,kBAAkB,EAClB,gBAAgB,EAGhB,WAAW,EACX,WAAW,EAEZ,MAAM,SAAS,CAAC;AAGjB;;;GAGG;AACH,MAAM,WAAW,WAAY,SAAQ,OAAO,CAAC,kBAAkB,EAAE,gBAAgB,CAAC;CAAG;AAErF;;;GAGG;AACH,qBAAa,kBACX,SAAQ,eAAe,CAAC,kBAAkB,EAAE,gBAAgB,CAC5D,YAAW,WAAW;IAGd,OAAO,CAAC,IAAI;IACJ,OAAO,CAAC,YAAY;IACf,OAAO,CAAC,EAAE;IACvB,OAAO,CAAC,IAAI;IACC,OAAO,CAAC,aAAa;IAC5B,OAAO,CAAC,MAAM;IACb,OAAO,CAAC,OAAO;gBANd,IAAI,EAAE,IAAI,EACF,YAAY,EAAE,YAAY,EACrB,EAAE,EAAE,iBAAiB,EAClC,IAAI,EAAE,IAAI,EACG,aAAa,EAAE,iBAAiB,EACvC,MAAM,EAAE,UAAU,EACjB,OAAO,EAAE,WAAW;IAsyB3C,KAAK,CACH,OAAO,GAAE,kBAAkB,CAAC,OAAO,IAAI,CAAC,OAAO,CAM9C;IAKH;;OAEG;IACH,gBAAgB,IAAI,IAAI;IAIxB,SAAS,CAAC,sBAAsB,IAAI,WAAW;IAQ/C,SAAS,CAAC,+BAA+B,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW;IAuB3E,SAAS,CAAC,uBAAuB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,KAAK,GAAG,iBAAiB;IAgB3E,SAAS,CAAC,YAAY;;;;;;;;;;;;;;;;;;;;;MAwBpB;IAEF,SAAS,CAAC,aAAa;;;MAGpB;CACJ;AAED;;;GAGG;AACH,eAAO,MAAM,WAAW,mEAA0E,CAAC;AAEnG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,cAAc,IAAI,WAAW,CAE5C"}
1
+ {"version":3,"file":"machine.d.ts","sourceRoot":"","sources":["../../../src/machine/machine.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EAEf,YAAY,EACZ,iBAAiB,EAMjB,OAAO,EACR,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AACpD,OAAO,EACL,IAAI,EASL,MAAM,+BAA+B,CAAC;AAEvC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAEjD,OAAO,EAAE,UAAU,EAAqB,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAEL,iBAAiB,EAIlB,MAAM,eAAe,CAAC;AAIvB,OAAO,EACL,iBAAiB,EAQlB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIhD,OAAO,KAAK,EAEV,kBAAkB,EAClB,gBAAgB,EAGhB,WAAW,EACX,WAAW,EAEZ,MAAM,SAAS,CAAC;AAGjB;;;GAGG;AACH,MAAM,WAAW,WAAY,SAAQ,OAAO,CAAC,kBAAkB,EAAE,gBAAgB,CAAC;CAAG;AAErF;;;GAGG;AACH,qBAAa,kBACX,SAAQ,eAAe,CAAC,kBAAkB,EAAE,gBAAgB,CAC5D,YAAW,WAAW;IAGd,OAAO,CAAC,IAAI;IACJ,OAAO,CAAC,YAAY;IACf,OAAO,CAAC,EAAE;IACvB,OAAO,CAAC,IAAI;IACC,OAAO,CAAC,aAAa;IAC5B,OAAO,CAAC,MAAM;IACb,OAAO,CAAC,OAAO;gBANd,IAAI,EAAE,IAAI,EACF,YAAY,EAAE,YAAY,EACrB,EAAE,EAAE,iBAAiB,EAClC,IAAI,EAAE,IAAI,EACG,aAAa,EAAE,iBAAiB,EACvC,MAAM,EAAE,UAAU,EACjB,OAAO,EAAE,WAAW;IA2yB3C,KAAK,CACH,OAAO,GAAE,kBAAkB,CAAC,OAAO,IAAI,CAAC,OAAO,CAM9C;IAKH;;OAEG;IACH,gBAAgB,IAAI,IAAI;IAIxB,SAAS,CAAC,sBAAsB,IAAI,WAAW;IAQ/C,SAAS,CAAC,+BAA+B,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW;IAuB3E,SAAS,CAAC,uBAAuB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,KAAK,GAAG,iBAAiB;IAgB3E,SAAS,CAAC,YAAY;;;;;;;;;;;;;;;;;;;;;MAwBpB;IAEF,SAAS,CAAC,aAAa;;;MAGpB;IAEH;;OAEG;IACH,SAAS,CAAC,qBAAqB,GAAI,oBAAoB,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MA0B1D;CACJ;AAED;;;GAGG;AACH,eAAO,MAAM,WAAW,mEAA0E,CAAC;AAEnG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,cAAc,IAAI,WAAW,CAE5C"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Long enough for a lock left by another tab to go stale and be cleared by `tryRefreshSession`.
3
+ */
4
+ export declare const DEFAULT_LOCK_WAIT_MS: number;
5
+ /**
6
+ * Refreshes an expired cookie session using the refresh cookie (`EVENT_LOGIN_AUTH` with empty details).
7
+ *
8
+ * @remarks
9
+ * Shares foundation-comms' cross-tab lock, so tabs restored together don't race to refresh. While another tab holds
10
+ * the lock, keeps retrying until it is released or goes stale (e.g. left behind by a reload mid-refresh); the retry
11
+ * re-checks the session first, so a refresh done by the other tab is picked up without refreshing again.
12
+ *
13
+ * @param options.lockWaitMs - How long to wait for another tab's lock before giving up.
14
+ * @returns true when the session is valid afterwards; false when the server rejected the refresh (NACK or 4xx) or the
15
+ * lock was still held at the deadline.
16
+ * @throws When the refresh could not complete (network error, 5xx, storage unavailable), so callers can tell a
17
+ * transient failure from an expired refresh cookie.
18
+ * @internal
19
+ */
20
+ export declare function refreshCookieSession({ lockWaitMs, }?: {
21
+ lockWaitMs?: number;
22
+ }): Promise<boolean>;
23
+ //# sourceMappingURL=session-refresh.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-refresh.d.ts","sourceRoot":"","sources":["../../../src/machine/session-refresh.ts"],"names":[],"mappings":"AAcA;;GAEG;AACH,eAAO,MAAM,oBAAoB,QAA2C,CAAC;AAoC7E;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,oBAAoB,CAAC,EACzC,UAAiC,GAClC,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAWjD"}
@@ -53,6 +53,7 @@ export const defaultAuthConfig = {
53
53
  toggled: false,
54
54
  },
55
55
  feedbackDelay: 3000,
56
+ sessionRefreshTimeout: 35000,
56
57
  localizationResources,
57
58
  };
58
59
  /**
@@ -4,13 +4,14 @@ import { User } from '@genesislcap/foundation-user';
4
4
  import { UUID, LOGIN_DETAILS_URL, LOGIN_URL, ACCEPT_TERMS_URL, LOGOUT_URL, FORGOT_PASSWORD_URL, CHANGE_PASSWORD_URL, RESET_PASSWORD_URL, createErrorMap, } from '@genesislcap/foundation-utils';
5
5
  import { DI } from '@microsoft/fast-foundation';
6
6
  import { and, assign, createMachine, fromPromise, not, or, raise, sendTo } from 'xstate';
7
- import { AuthConfig } from '../config/config';
7
+ import { AuthConfig, defaultAuthConfig } from '../config/config';
8
8
  import { CredentialManager, CredentialType, } from '../credential';
9
9
  import { MESSAGE_TYPE } from '../dto';
10
10
  import { AuthMessageMapper, createHTTPHeadersFromDTO, isLoginAckEntity, isLoginDetailsAckEntity, isLoginNackEntity, isLogoutAckEntity, isLogoutNackEntity, isNackDTO, } from '../mapper';
11
11
  import { AuthRouting } from '../routes/routing';
12
12
  import { logger } from '../utils';
13
13
  import { setError } from './actions';
14
+ import { refreshCookieSession } from './session-refresh';
14
15
  import { defaultAuthMachineContext, isLoginParams, isQueryParams } from './types';
15
16
  /**
16
17
  * Default AuthMachine.
@@ -18,6 +19,7 @@ import { defaultAuthMachineContext, isLoginParams, isQueryParams } from './types
18
19
  */
19
20
  let DefaultAuthMachine = class DefaultAuthMachine extends AbstractMachine {
20
21
  constructor(user, fetchMachine, cm, uuid, messageMapper, config, routing) {
22
+ var _a;
21
23
  super();
22
24
  this.user = user;
23
25
  this.fetchMachine = fetchMachine;
@@ -53,7 +55,37 @@ let DefaultAuthMachine = class DefaultAuthMachine extends AbstractMachine {
53
55
  };
54
56
  this.dtoTransition = () => ({
55
57
  actions: ['setDTO'],
56
- target: 'mapEntity',
58
+ target: '#authMachine.mapEntity',
59
+ });
60
+ /**
61
+ * Fetches login details with the session cookie. A 401 goes to `unauthorizedTarget`.
62
+ */
63
+ this.loginDetailsStateNode = (unauthorizedTarget) => ({
64
+ invoke: {
65
+ id: 'loginDetailsFetcher',
66
+ src: this.fetchMachine.machine,
67
+ onDone: [
68
+ {
69
+ guard: 'isUnauthorizedError',
70
+ target: unauthorizedTarget,
71
+ },
72
+ {
73
+ guard: 'isFetchError',
74
+ target: '#authMachine.error.silentLogin',
75
+ },
76
+ this.dtoTransition(),
77
+ ],
78
+ onError: [
79
+ {
80
+ guard: 'isUnauthorizedError',
81
+ target: unauthorizedTarget,
82
+ },
83
+ {
84
+ target: '#authMachine.error.silentLogin',
85
+ },
86
+ ],
87
+ },
88
+ entry: [sendTo('loginDetailsFetcher', this.createFetchMachineEvent(LOGIN_DETAILS_URL))],
57
89
  });
58
90
  this.machine = createMachine({
59
91
  id: 'authMachine',
@@ -112,38 +144,38 @@ let DefaultAuthMachine = class DefaultAuthMachine extends AbstractMachine {
112
144
  on: this.onIdleEvents(),
113
145
  },
114
146
  /**
115
- * Attempt silent login via cookies (details endpoint returns the same user information as login when authorised)
147
+ * Attempt silent login via cookies (details endpoint returns the same user information as login when authorised).
148
+ * When the session cookie has expired, try once to refresh the session with the refresh cookie before
149
+ * falling back to the login form.
116
150
  */
117
151
  silentLogin: {
118
152
  tags: ['silentLogin', 'pending'],
119
153
  meta: {
120
154
  content: 'Attempting silent login, please wait.',
121
155
  },
122
- invoke: {
123
- id: 'loginDetailsFetcher',
124
- src: fetchMachine.machine,
125
- onDone: [
126
- {
127
- guard: 'isUnauthorizedError',
128
- target: 'loggedOut',
129
- },
130
- {
131
- guard: 'isFetchError',
132
- target: 'error.silentLogin',
133
- },
134
- this.dtoTransition(),
135
- ],
136
- onError: [
137
- {
138
- guard: 'isUnauthorizedError',
139
- target: 'loggedOut',
156
+ initial: 'fetchingDetails',
157
+ states: {
158
+ fetchingDetails: this.loginDetailsStateNode('#authMachine.silentLogin.refreshingSession'),
159
+ refreshingSession: {
160
+ invoke: {
161
+ src: 'sessionRefresher',
162
+ onDone: [
163
+ {
164
+ guard: ({ event }) => event.output === true,
165
+ target: '#authMachine.silentLogin.fetchingRefreshedDetails',
166
+ },
167
+ {
168
+ target: '#authMachine.loggedOut',
169
+ },
170
+ ],
171
+ onError: '#authMachine.error.silentLogin',
140
172
  },
141
- {
142
- target: 'error.silentLogin',
173
+ after: {
174
+ sessionRefreshTimeout: '#authMachine.error.silentLogin',
143
175
  },
144
- ],
176
+ },
177
+ fetchingRefreshedDetails: this.loginDetailsStateNode('#authMachine.loggedOut'),
145
178
  },
146
- entry: [sendTo('loginDetailsFetcher', this.createFetchMachineEvent(LOGIN_DETAILS_URL))],
147
179
  },
148
180
  /**
149
181
  * Login with user credentials or tokens
@@ -678,6 +710,7 @@ let DefaultAuthMachine = class DefaultAuthMachine extends AbstractMachine {
678
710
  }, {
679
711
  actors: {
680
712
  mapper: fromPromise((_a) => __awaiter(this, [_a], void 0, function* ({ input }) { return input.mapper(input.dto); })),
713
+ sessionRefresher: fromPromise(() => refreshCookieSession()),
681
714
  },
682
715
  actions: {
683
716
  setParams: assign(({ event }) => {
@@ -826,6 +859,7 @@ let DefaultAuthMachine = class DefaultAuthMachine extends AbstractMachine {
826
859
  feedbackDelay: this.config.feedbackDelay,
827
860
  logoutFeedbackDelay: 1000,
828
861
  mfaSessionExpiredRedirectDelay: 5000,
862
+ sessionRefreshTimeout: (_a = this.config.sessionRefreshTimeout) !== null && _a !== void 0 ? _a : defaultAuthConfig.sessionRefreshTimeout,
829
863
  },
830
864
  });
831
865
  this.start();
@@ -0,0 +1,66 @@
1
+ import { __awaiter } from "tslib";
2
+ import { onOtherTabReauthComplete, REAUTH_LOCK_TIMEOUT_MS, SessionRefreshResult, tryRefreshSession, } from '@genesislcap/foundation-comms';
3
+ import { logger } from '../utils';
4
+ /**
5
+ * Upper bound between lock checks, so a lock abandoned without a storage event is still picked up once it goes stale.
6
+ */
7
+ const LOCK_RECHECK_MS = 1000;
8
+ /**
9
+ * Long enough for a lock left by another tab to go stale and be cleared by `tryRefreshSession`.
10
+ */
11
+ export const DEFAULT_LOCK_WAIT_MS = REAUTH_LOCK_TIMEOUT_MS + LOCK_RECHECK_MS;
12
+ const HTTP_CLIENT_ERROR_MIN = 400;
13
+ const HTTP_SERVER_ERROR_MIN = 500;
14
+ const isRefreshed = (result) => result === SessionRefreshResult.SUCCESS || result === SessionRefreshResult.ALREADY_VALID;
15
+ const isRejectedByServer = (error) => {
16
+ const status = error === null || error === void 0 ? void 0 : error.status;
17
+ return (typeof status === 'number' && status >= HTTP_CLIENT_ERROR_MIN && status < HTTP_SERVER_ERROR_MIN);
18
+ };
19
+ const waitForLockRelease = (timeoutMs) => new Promise((resolve) => {
20
+ const timeout = setTimeout(() => {
21
+ unsubscribe();
22
+ resolve();
23
+ }, timeoutMs);
24
+ const unsubscribe = onOtherTabReauthComplete(() => {
25
+ clearTimeout(timeout);
26
+ resolve();
27
+ });
28
+ });
29
+ const refreshOnceLockIsFree = (deadline) => __awaiter(void 0, void 0, void 0, function* () {
30
+ const result = yield tryRefreshSession({ reloadOnFailure: false });
31
+ if (result !== SessionRefreshResult.HANDLED_BY_OTHER_TAB || Date.now() >= deadline) {
32
+ return result;
33
+ }
34
+ yield waitForLockRelease(Math.min(LOCK_RECHECK_MS, Math.max(0, deadline - Date.now())));
35
+ return refreshOnceLockIsFree(deadline);
36
+ });
37
+ /**
38
+ * Refreshes an expired cookie session using the refresh cookie (`EVENT_LOGIN_AUTH` with empty details).
39
+ *
40
+ * @remarks
41
+ * Shares foundation-comms' cross-tab lock, so tabs restored together don't race to refresh. While another tab holds
42
+ * the lock, keeps retrying until it is released or goes stale (e.g. left behind by a reload mid-refresh); the retry
43
+ * re-checks the session first, so a refresh done by the other tab is picked up without refreshing again.
44
+ *
45
+ * @param options.lockWaitMs - How long to wait for another tab's lock before giving up.
46
+ * @returns true when the session is valid afterwards; false when the server rejected the refresh (NACK or 4xx) or the
47
+ * lock was still held at the deadline.
48
+ * @throws When the refresh could not complete (network error, 5xx, storage unavailable), so callers can tell a
49
+ * transient failure from an expired refresh cookie.
50
+ * @internal
51
+ */
52
+ export function refreshCookieSession() {
53
+ return __awaiter(this, arguments, void 0, function* ({ lockWaitMs = DEFAULT_LOCK_WAIT_MS, } = {}) {
54
+ try {
55
+ return isRefreshed(yield refreshOnceLockIsFree(Date.now() + lockWaitMs));
56
+ }
57
+ catch (error) {
58
+ if (isRejectedByServer(error)) {
59
+ logger.debug('Session refresh rejected.', error);
60
+ return false;
61
+ }
62
+ logger.warn('Session refresh could not complete.', error);
63
+ throw error;
64
+ }
65
+ });
66
+ }
@@ -606,6 +606,33 @@
606
606
  "endIndex": 2
607
607
  }
608
608
  },
609
+ {
610
+ "kind": "PropertySignature",
611
+ "canonicalReference": "@genesislcap/foundation-auth!AuthConfig#sessionRefreshTimeout:member",
612
+ "docComment": "/**\n * Session refresh timeout.\n *\n * @remarks\n *\n * How many milliseconds silent login waits to refresh an expired session with the refresh cookie (including waiting for another tab that is already refreshing) before showing the silent login error. Keep it above the cross-tab lock wait of about 31 seconds. Defaults to 35 seconds.\n */\n",
613
+ "excerptTokens": [
614
+ {
615
+ "kind": "Content",
616
+ "text": "sessionRefreshTimeout?: "
617
+ },
618
+ {
619
+ "kind": "Content",
620
+ "text": "number"
621
+ },
622
+ {
623
+ "kind": "Content",
624
+ "text": ";"
625
+ }
626
+ ],
627
+ "isReadonly": false,
628
+ "isOptional": true,
629
+ "releaseTag": "Public",
630
+ "name": "sessionRefreshTimeout",
631
+ "propertyTypeTokenRange": {
632
+ "startIndex": 1,
633
+ "endIndex": 2
634
+ }
635
+ },
609
636
  {
610
637
  "kind": "PropertySignature",
611
638
  "canonicalReference": "@genesislcap/foundation-auth!AuthConfig#showChangePasswordLink:member",
@@ -6085,6 +6112,441 @@
6085
6112
  "isAbstract": false,
6086
6113
  "name": "getFromContainer"
6087
6114
  },
6115
+ {
6116
+ "kind": "Property",
6117
+ "canonicalReference": "@genesislcap/foundation-auth!DefaultAuthMachine#loginDetailsStateNode:member",
6118
+ "docComment": "/**\n * Fetches login details with the session cookie. A 401 goes to `unauthorizedTarget`.\n */\n",
6119
+ "excerptTokens": [
6120
+ {
6121
+ "kind": "Content",
6122
+ "text": "protected loginDetailsStateNode: "
6123
+ },
6124
+ {
6125
+ "kind": "Content",
6126
+ "text": "(unauthorizedTarget: string) => {\n invoke: {\n id: string;\n src: import(\"xstate\")."
6127
+ },
6128
+ {
6129
+ "kind": "Reference",
6130
+ "text": "StateMachine",
6131
+ "canonicalReference": "xstate!StateMachine:class"
6132
+ },
6133
+ {
6134
+ "kind": "Content",
6135
+ "text": "<import(\"@genesislcap/foundation-state-machine\")."
6136
+ },
6137
+ {
6138
+ "kind": "Reference",
6139
+ "text": "FetchMachineContext",
6140
+ "canonicalReference": "@genesislcap/foundation-state-machine!FetchMachineContext:interface"
6141
+ },
6142
+ {
6143
+ "kind": "Content",
6144
+ "text": ", "
6145
+ },
6146
+ {
6147
+ "kind": "Reference",
6148
+ "text": "FetchMachineEvent",
6149
+ "canonicalReference": "@genesislcap/foundation-state-machine!FetchMachineEvent:type"
6150
+ },
6151
+ {
6152
+ "kind": "Content",
6153
+ "text": ", import(\"xstate\")."
6154
+ },
6155
+ {
6156
+ "kind": "Reference",
6157
+ "text": "ParameterizedObject",
6158
+ "canonicalReference": "xstate!ParameterizedObject:interface"
6159
+ },
6160
+ {
6161
+ "kind": "Content",
6162
+ "text": ", import(\"xstate\")."
6163
+ },
6164
+ {
6165
+ "kind": "Reference",
6166
+ "text": "ProvidedActor",
6167
+ "canonicalReference": "xstate!ProvidedActor:interface"
6168
+ },
6169
+ {
6170
+ "kind": "Content",
6171
+ "text": ", any, import(\"xstate\")."
6172
+ },
6173
+ {
6174
+ "kind": "Reference",
6175
+ "text": "ResolveTypegenMeta",
6176
+ "canonicalReference": "xstate!ResolveTypegenMeta:interface"
6177
+ },
6178
+ {
6179
+ "kind": "Content",
6180
+ "text": "<import(\"xstate\")."
6181
+ },
6182
+ {
6183
+ "kind": "Reference",
6184
+ "text": "TypegenDisabled",
6185
+ "canonicalReference": "xstate!TypegenDisabled:interface"
6186
+ },
6187
+ {
6188
+ "kind": "Content",
6189
+ "text": ", "
6190
+ },
6191
+ {
6192
+ "kind": "Reference",
6193
+ "text": "FetchMachineEvent",
6194
+ "canonicalReference": "@genesislcap/foundation-state-machine!FetchMachineEvent:type"
6195
+ },
6196
+ {
6197
+ "kind": "Content",
6198
+ "text": ", import(\"xstate\")."
6199
+ },
6200
+ {
6201
+ "kind": "Reference",
6202
+ "text": "ParameterizedObject",
6203
+ "canonicalReference": "xstate!ParameterizedObject:interface"
6204
+ },
6205
+ {
6206
+ "kind": "Content",
6207
+ "text": ", import(\"xstate\")."
6208
+ },
6209
+ {
6210
+ "kind": "Reference",
6211
+ "text": "ProvidedActor",
6212
+ "canonicalReference": "xstate!ProvidedActor:interface"
6213
+ },
6214
+ {
6215
+ "kind": "Content",
6216
+ "text": ">>;\n onDone: ({\n actions: string[];\n target: string;\n } | {\n guard: string;\n target: string;\n })[];\n onError: ({\n guard: string;\n target: string;\n } | {\n target: string;\n guard?: undefined;\n })[];\n };\n entry: {\n (_: import(\"xstate\")."
6217
+ },
6218
+ {
6219
+ "kind": "Reference",
6220
+ "text": "ActionArgs",
6221
+ "canonicalReference": "xstate!ActionArgs:interface"
6222
+ },
6223
+ {
6224
+ "kind": "Content",
6225
+ "text": "<import(\"xstate\")."
6226
+ },
6227
+ {
6228
+ "kind": "Reference",
6229
+ "text": "MachineContext",
6230
+ "canonicalReference": "xstate!MachineContext:type"
6231
+ },
6232
+ {
6233
+ "kind": "Content",
6234
+ "text": ", import(\"xstate\")."
6235
+ },
6236
+ {
6237
+ "kind": "Reference",
6238
+ "text": "EventObject",
6239
+ "canonicalReference": "xstate!EventObject:interface"
6240
+ },
6241
+ {
6242
+ "kind": "Content",
6243
+ "text": ", import(\"xstate\")."
6244
+ },
6245
+ {
6246
+ "kind": "Reference",
6247
+ "text": "ParameterizedObject",
6248
+ "canonicalReference": "xstate!ParameterizedObject:interface"
6249
+ },
6250
+ {
6251
+ "kind": "Content",
6252
+ "text": ">): void;\n type: string;\n to: string | import(\"xstate\")."
6253
+ },
6254
+ {
6255
+ "kind": "Reference",
6256
+ "text": "AnyActorRef",
6257
+ "canonicalReference": "xstate!AnyActorRef:type"
6258
+ },
6259
+ {
6260
+ "kind": "Content",
6261
+ "text": " | ((args: import(\"xstate\")."
6262
+ },
6263
+ {
6264
+ "kind": "Reference",
6265
+ "text": "UnifiedArg",
6266
+ "canonicalReference": "xstate!UnifiedArg:interface"
6267
+ },
6268
+ {
6269
+ "kind": "Content",
6270
+ "text": "<import(\"xstate\")."
6271
+ },
6272
+ {
6273
+ "kind": "Reference",
6274
+ "text": "MachineContext",
6275
+ "canonicalReference": "xstate!MachineContext:type"
6276
+ },
6277
+ {
6278
+ "kind": "Content",
6279
+ "text": ", import(\"xstate\")."
6280
+ },
6281
+ {
6282
+ "kind": "Reference",
6283
+ "text": "EventObject",
6284
+ "canonicalReference": "xstate!EventObject:interface"
6285
+ },
6286
+ {
6287
+ "kind": "Content",
6288
+ "text": ">) => string | import(\"xstate\")."
6289
+ },
6290
+ {
6291
+ "kind": "Reference",
6292
+ "text": "AnyActorRef",
6293
+ "canonicalReference": "xstate!AnyActorRef:type"
6294
+ },
6295
+ {
6296
+ "kind": "Content",
6297
+ "text": ");\n event: any;\n id: string | undefined;\n delay: string | number | import(\"xstate\")."
6298
+ },
6299
+ {
6300
+ "kind": "Reference",
6301
+ "text": "DelayExpr",
6302
+ "canonicalReference": "xstate!DelayExpr:type"
6303
+ },
6304
+ {
6305
+ "kind": "Content",
6306
+ "text": "<import(\"xstate\")."
6307
+ },
6308
+ {
6309
+ "kind": "Reference",
6310
+ "text": "MachineContext",
6311
+ "canonicalReference": "xstate!MachineContext:type"
6312
+ },
6313
+ {
6314
+ "kind": "Content",
6315
+ "text": ", import(\"xstate\")."
6316
+ },
6317
+ {
6318
+ "kind": "Reference",
6319
+ "text": "EventObject",
6320
+ "canonicalReference": "xstate!EventObject:interface"
6321
+ },
6322
+ {
6323
+ "kind": "Content",
6324
+ "text": ">;\n resolve: (actorContext: import(\"xstate\")."
6325
+ },
6326
+ {
6327
+ "kind": "Reference",
6328
+ "text": "AnyActorContext",
6329
+ "canonicalReference": "xstate!AnyActorContext:type"
6330
+ },
6331
+ {
6332
+ "kind": "Content",
6333
+ "text": ", state: import(\"xstate\")."
6334
+ },
6335
+ {
6336
+ "kind": "Reference",
6337
+ "text": "AnyState",
6338
+ "canonicalReference": "xstate!AnyState:type"
6339
+ },
6340
+ {
6341
+ "kind": "Content",
6342
+ "text": ", args: import(\"xstate\")."
6343
+ },
6344
+ {
6345
+ "kind": "Reference",
6346
+ "text": "ActionArgs",
6347
+ "canonicalReference": "xstate!ActionArgs:interface"
6348
+ },
6349
+ {
6350
+ "kind": "Content",
6351
+ "text": "<any, any>, { to, "
6352
+ },
6353
+ {
6354
+ "kind": "Reference",
6355
+ "text": "event",
6356
+ "canonicalReference": "@genesislcap/foundation-auth!~__type#event"
6357
+ },
6358
+ {
6359
+ "kind": "Content",
6360
+ "text": ": eventOrExpr, id, delay }: {\n to: import(\"xstate\")."
6361
+ },
6362
+ {
6363
+ "kind": "Reference",
6364
+ "text": "AnyActorRef",
6365
+ "canonicalReference": "xstate!AnyActorRef:type"
6366
+ },
6367
+ {
6368
+ "kind": "Content",
6369
+ "text": " | string | ((args: import(\"xstate\")."
6370
+ },
6371
+ {
6372
+ "kind": "Reference",
6373
+ "text": "UnifiedArg",
6374
+ "canonicalReference": "xstate!UnifiedArg:interface"
6375
+ },
6376
+ {
6377
+ "kind": "Content",
6378
+ "text": "<import(\"xstate\")."
6379
+ },
6380
+ {
6381
+ "kind": "Reference",
6382
+ "text": "MachineContext",
6383
+ "canonicalReference": "xstate!MachineContext:type"
6384
+ },
6385
+ {
6386
+ "kind": "Content",
6387
+ "text": ", import(\"xstate\")."
6388
+ },
6389
+ {
6390
+ "kind": "Reference",
6391
+ "text": "EventObject",
6392
+ "canonicalReference": "xstate!EventObject:interface"
6393
+ },
6394
+ {
6395
+ "kind": "Content",
6396
+ "text": ">) => import(\"xstate\")."
6397
+ },
6398
+ {
6399
+ "kind": "Reference",
6400
+ "text": "AnyActorRef",
6401
+ "canonicalReference": "xstate!AnyActorRef:type"
6402
+ },
6403
+ {
6404
+ "kind": "Content",
6405
+ "text": " | string);\n event: import(\"xstate\")."
6406
+ },
6407
+ {
6408
+ "kind": "Reference",
6409
+ "text": "EventObject",
6410
+ "canonicalReference": "xstate!EventObject:interface"
6411
+ },
6412
+ {
6413
+ "kind": "Content",
6414
+ "text": " | import(\"xstate\")."
6415
+ },
6416
+ {
6417
+ "kind": "Reference",
6418
+ "text": "SendExpr",
6419
+ "canonicalReference": "xstate!SendExpr:type"
6420
+ },
6421
+ {
6422
+ "kind": "Content",
6423
+ "text": "<import(\"xstate\")."
6424
+ },
6425
+ {
6426
+ "kind": "Reference",
6427
+ "text": "MachineContext",
6428
+ "canonicalReference": "xstate!MachineContext:type"
6429
+ },
6430
+ {
6431
+ "kind": "Content",
6432
+ "text": ", import(\"xstate\")."
6433
+ },
6434
+ {
6435
+ "kind": "Reference",
6436
+ "text": "EventObject",
6437
+ "canonicalReference": "xstate!EventObject:interface"
6438
+ },
6439
+ {
6440
+ "kind": "Content",
6441
+ "text": ", import(\"xstate\")."
6442
+ },
6443
+ {
6444
+ "kind": "Reference",
6445
+ "text": "EventObject",
6446
+ "canonicalReference": "xstate!EventObject:interface"
6447
+ },
6448
+ {
6449
+ "kind": "Content",
6450
+ "text": ">;\n id: string | undefined;\n delay: string | number | import(\"xstate\")."
6451
+ },
6452
+ {
6453
+ "kind": "Reference",
6454
+ "text": "DelayExpr",
6455
+ "canonicalReference": "xstate!DelayExpr:type"
6456
+ },
6457
+ {
6458
+ "kind": "Content",
6459
+ "text": "<import(\"xstate\")."
6460
+ },
6461
+ {
6462
+ "kind": "Reference",
6463
+ "text": "MachineContext",
6464
+ "canonicalReference": "xstate!MachineContext:type"
6465
+ },
6466
+ {
6467
+ "kind": "Content",
6468
+ "text": ", import(\"xstate\")."
6469
+ },
6470
+ {
6471
+ "kind": "Reference",
6472
+ "text": "EventObject",
6473
+ "canonicalReference": "xstate!EventObject:interface"
6474
+ },
6475
+ {
6476
+ "kind": "Content",
6477
+ "text": "> | undefined;\n }) => (import(\"xstate\")."
6478
+ },
6479
+ {
6480
+ "kind": "Reference",
6481
+ "text": "AnyState",
6482
+ "canonicalReference": "xstate!AnyState:type"
6483
+ },
6484
+ {
6485
+ "kind": "Content",
6486
+ "text": " | {\n to: import(\"xstate\")."
6487
+ },
6488
+ {
6489
+ "kind": "Reference",
6490
+ "text": "AnyActorRef",
6491
+ "canonicalReference": "xstate!AnyActorRef:type"
6492
+ },
6493
+ {
6494
+ "kind": "Content",
6495
+ "text": ";\n event: import(\"xstate\")."
6496
+ },
6497
+ {
6498
+ "kind": "Reference",
6499
+ "text": "EventObject",
6500
+ "canonicalReference": "xstate!EventObject:interface"
6501
+ },
6502
+ {
6503
+ "kind": "Content",
6504
+ "text": ";\n id: string | undefined;\n delay: number | undefined;\n })[];\n execute: (actorContext: import(\"xstate\")."
6505
+ },
6506
+ {
6507
+ "kind": "Reference",
6508
+ "text": "AnyActorContext",
6509
+ "canonicalReference": "xstate!AnyActorContext:type"
6510
+ },
6511
+ {
6512
+ "kind": "Content",
6513
+ "text": ", params: {\n to: import(\"xstate\")."
6514
+ },
6515
+ {
6516
+ "kind": "Reference",
6517
+ "text": "AnyActorRef",
6518
+ "canonicalReference": "xstate!AnyActorRef:type"
6519
+ },
6520
+ {
6521
+ "kind": "Content",
6522
+ "text": ";\n event: import(\"xstate\")."
6523
+ },
6524
+ {
6525
+ "kind": "Reference",
6526
+ "text": "EventObject",
6527
+ "canonicalReference": "xstate!EventObject:interface"
6528
+ },
6529
+ {
6530
+ "kind": "Content",
6531
+ "text": ";\n id: string | undefined;\n delay: number | undefined;\n }) => void;\n }[];\n }"
6532
+ },
6533
+ {
6534
+ "kind": "Content",
6535
+ "text": ";"
6536
+ }
6537
+ ],
6538
+ "isReadonly": false,
6539
+ "isOptional": false,
6540
+ "releaseTag": "Public",
6541
+ "name": "loginDetailsStateNode",
6542
+ "propertyTypeTokenRange": {
6543
+ "startIndex": 1,
6544
+ "endIndex": 92
6545
+ },
6546
+ "isStatic": false,
6547
+ "isProtected": true,
6548
+ "isAbstract": false
6549
+ },
6088
6550
  {
6089
6551
  "kind": "Property",
6090
6552
  "canonicalReference": "@genesislcap/foundation-auth!DefaultAuthMachine#onIdleEvents:member",
@@ -3,6 +3,7 @@ import { AbstractStore } from '@genesislcap/foundation-store';
3
3
  import { AbstractStoreRoot } from '@genesislcap/foundation-store';
4
4
  import { ActionArgs } from 'xstate';
5
5
  import { AnyActorContext } from 'xstate';
6
+ import { AnyActorRef } from 'xstate';
6
7
  import { AnyState } from 'xstate';
7
8
  import { Assigner } from 'xstate';
8
9
  import { BindingObserver } from '@microsoft/fast-element';
@@ -12,6 +13,7 @@ import { Container } from '@microsoft/fast-foundation';
12
13
  import { Controller } from '@microsoft/fast-element';
13
14
  import { DefaultUser } from '@genesislcap/foundation-user';
14
15
  import { defaultUserConfig } from '@genesislcap/foundation-user';
16
+ import { DelayExpr } from 'xstate';
15
17
  import { DoneInvokeEvent } from 'xstate';
16
18
  import { ElementStyles } from '@microsoft/fast-element';
17
19
  import { EmitOptions } from '@genesislcap/foundation-events';
@@ -19,6 +21,7 @@ import { EmitReturn } from '@genesislcap/foundation-events';
19
21
  import type { ErrorEvent as ErrorEvent_2 } from 'xstate';
20
22
  import { EventObject } from 'xstate';
21
23
  import { FetchMachine } from '@genesislcap/foundation-state-machine';
24
+ import { FetchMachineContext } from '@genesislcap/foundation-state-machine';
22
25
  import { FetchMachineEvent } from '@genesislcap/foundation-state-machine';
23
26
  import { getUser } from '@genesislcap/foundation-user';
24
27
  import { I18nextConfig } from '@genesislcap/foundation-i18n';
@@ -31,13 +34,19 @@ import { MachineContext as MachineContext_2 } from 'xstate';
31
34
  import { ParameterizedObject } from 'xstate';
32
35
  import { PartialFASTElementDefinition } from '@microsoft/fast-element';
33
36
  import { PropertyAssigner } from 'xstate';
37
+ import { ProvidedActor } from 'xstate';
38
+ import { ResolveTypegenMeta } from 'xstate';
34
39
  import { RouterConfiguration } from '@microsoft/fast-router';
40
+ import { SendExpr } from 'xstate';
35
41
  import type { SetUserProperties } from '@genesislcap/foundation-user';
42
+ import { StateMachine } from 'xstate';
36
43
  import { Store } from '@genesislcap/foundation-store';
37
44
  import { StoreRoot } from '@genesislcap/foundation-store';
38
45
  import { StoreRootEventDetailMap } from '@genesislcap/foundation-store';
39
46
  import { SyntheticViewTemplate } from '@microsoft/fast-element';
40
47
  import { TemplateElementDependency } from '@genesislcap/foundation-ui';
48
+ import { TypegenDisabled } from 'xstate';
49
+ import { UnifiedArg } from 'xstate';
41
50
  import { User } from '@genesislcap/foundation-user';
42
51
  import { UserActionHistory } from '@genesislcap/foundation-user';
43
52
  import { UserAuthenticationChangeEvent } from '@genesislcap/foundation-user';
@@ -258,6 +267,15 @@ export declare interface AuthConfig extends PartialFASTElementDefinition {
258
267
  * The amount of seconds to display user feedback messages, such as "check your inbox" etc. Defaults to 3 seconds.
259
268
  */
260
269
  feedbackDelay?: number;
270
+ /**
271
+ * Session refresh timeout.
272
+ *
273
+ * @remarks
274
+ * How many milliseconds silent login waits to refresh an expired session with the refresh cookie (including
275
+ * waiting for another tab that is already refreshing) before showing the silent login error. Keep it above the
276
+ * cross-tab lock wait of about 31 seconds. Defaults to 35 seconds.
277
+ */
278
+ sessionRefreshTimeout?: number;
261
279
  /**
262
280
  * I18n resources.
263
281
  *
@@ -1040,6 +1058,54 @@ export declare class DefaultAuthMachine extends AbstractMachine<AuthMachineConte
1040
1058
  actions: string[];
1041
1059
  target: string;
1042
1060
  };
1061
+ /**
1062
+ * Fetches login details with the session cookie. A 401 goes to `unauthorizedTarget`.
1063
+ */
1064
+ protected loginDetailsStateNode: (unauthorizedTarget: string) => {
1065
+ invoke: {
1066
+ id: string;
1067
+ src: StateMachine<FetchMachineContext, FetchMachineEvent, ParameterizedObject, ProvidedActor, any, ResolveTypegenMeta<TypegenDisabled, FetchMachineEvent, ParameterizedObject, ProvidedActor>>;
1068
+ onDone: ({
1069
+ actions: string[];
1070
+ target: string;
1071
+ } | {
1072
+ guard: string;
1073
+ target: string;
1074
+ })[];
1075
+ onError: ({
1076
+ guard: string;
1077
+ target: string;
1078
+ } | {
1079
+ target: string;
1080
+ guard?: undefined;
1081
+ })[];
1082
+ };
1083
+ entry: {
1084
+ (_: ActionArgs<MachineContext_2, EventObject, ParameterizedObject>): void;
1085
+ type: string;
1086
+ to: string | AnyActorRef | ((args: UnifiedArg<MachineContext_2, EventObject>) => string | AnyActorRef);
1087
+ event: any;
1088
+ id: string | undefined;
1089
+ delay: string | number | DelayExpr<MachineContext_2, EventObject>;
1090
+ resolve: (actorContext: AnyActorContext, state: AnyState, args: ActionArgs<any, any>, { to, event: eventOrExpr, id, delay }: {
1091
+ to: AnyActorRef | string | ((args: UnifiedArg<MachineContext_2, EventObject>) => AnyActorRef | string);
1092
+ event: EventObject | SendExpr<MachineContext_2, EventObject, EventObject>;
1093
+ id: string | undefined;
1094
+ delay: string | number | DelayExpr<MachineContext_2, EventObject> | undefined;
1095
+ }) => (AnyState | {
1096
+ to: AnyActorRef;
1097
+ event: EventObject;
1098
+ id: string | undefined;
1099
+ delay: number | undefined;
1100
+ })[];
1101
+ execute: (actorContext: AnyActorContext, params: {
1102
+ to: AnyActorRef;
1103
+ event: EventObject;
1104
+ id: string | undefined;
1105
+ delay: number | undefined;
1106
+ }) => void;
1107
+ }[];
1108
+ };
1043
1109
  }
1044
1110
 
1045
1111
  /**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@genesislcap/foundation-auth",
3
3
  "description": "Genesis Foundation Auth",
4
- "version": "15.50.2",
4
+ "version": "15.50.3",
5
5
  "license": "SEE LICENSE IN license.txt",
6
6
  "main": "dist/esm/index.js",
7
7
  "types": "dist/foundation-auth.d.ts",
@@ -134,24 +134,24 @@
134
134
  }
135
135
  },
136
136
  "devDependencies": {
137
- "@genesislcap/foundation-testing": "15.50.2",
138
- "@genesislcap/genx": "15.50.2",
139
- "@genesislcap/ts-builder": "15.50.2",
140
- "@genesislcap/uvu-playwright-builder": "15.50.2",
141
- "@genesislcap/vite-builder": "15.50.2",
142
- "@genesislcap/webpack-builder": "15.50.2"
137
+ "@genesislcap/foundation-testing": "15.50.3",
138
+ "@genesislcap/genx": "15.50.3",
139
+ "@genesislcap/ts-builder": "15.50.3",
140
+ "@genesislcap/uvu-playwright-builder": "15.50.3",
141
+ "@genesislcap/vite-builder": "15.50.3",
142
+ "@genesislcap/webpack-builder": "15.50.3"
143
143
  },
144
144
  "dependencies": {
145
- "@genesislcap/foundation-comms": "15.50.2",
146
- "@genesislcap/foundation-events": "15.50.2",
147
- "@genesislcap/foundation-i18n": "15.50.2",
148
- "@genesislcap/foundation-logger": "15.50.2",
149
- "@genesislcap/foundation-state-machine": "15.50.2",
150
- "@genesislcap/foundation-store": "15.50.2",
151
- "@genesislcap/foundation-ui": "15.50.2",
152
- "@genesislcap/foundation-user": "15.50.2",
153
- "@genesislcap/foundation-utils": "15.50.2",
154
- "@genesislcap/foundation-zero": "15.50.2",
145
+ "@genesislcap/foundation-comms": "15.50.3",
146
+ "@genesislcap/foundation-events": "15.50.3",
147
+ "@genesislcap/foundation-i18n": "15.50.3",
148
+ "@genesislcap/foundation-logger": "15.50.3",
149
+ "@genesislcap/foundation-state-machine": "15.50.3",
150
+ "@genesislcap/foundation-store": "15.50.3",
151
+ "@genesislcap/foundation-ui": "15.50.3",
152
+ "@genesislcap/foundation-user": "15.50.3",
153
+ "@genesislcap/foundation-utils": "15.50.3",
154
+ "@genesislcap/foundation-zero": "15.50.3",
155
155
  "@microsoft/fast-components": "2.30.6",
156
156
  "@microsoft/fast-element": "1.14.0",
157
157
  "@microsoft/fast-foundation": "2.50.0",