@data-fair/lib-vue 1.29.0 → 1.29.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@data-fair/lib-vue",
3
- "version": "1.29.0",
3
+ "version": "1.29.1",
4
4
  "description": "Composables and other utilities for Vue applications in the data-fair stack.",
5
5
  "main": "index.js",
6
6
  "files": [
package/session.js CHANGED
@@ -17,8 +17,16 @@ debug.log = console.log.bind(console);
17
17
  * bypasses custom themes and falls back to its own light/dark.
18
18
  */
19
19
  export function resolveTheme(userTheme, site) {
20
- if (userTheme && userTheme !== 'system')
21
- return userTheme;
20
+ // honor an explicit choice only while `site` still offers it; otherwise fall through to
21
+ // the OS-preference resolution below (a theme disabled after selection must not stick)
22
+ if (userTheme === 'default')
23
+ return 'default';
24
+ if (userTheme === 'dark' && site.theme.dark)
25
+ return 'dark';
26
+ if (userTheme === 'hc' && site.theme.hc)
27
+ return 'hc';
28
+ if (userTheme === 'hc-dark' && site.theme.hcDark)
29
+ return 'hc-dark';
22
30
  // see https://www.scottohara.me/blog/2021/10/01/detect-high-contrast-and-dark-modes.html
23
31
  const preferDark = typeof window !== 'undefined' && window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
24
32
  const preferHC = typeof window !== 'undefined' && window.matchMedia && window.matchMedia('(forced-colors: active)').matches;
@@ -280,8 +288,14 @@ export async function getSession(initOptions) {
280
288
  goTo(null);
281
289
  };
282
290
  const switchTheme = (value) => {
283
- const maxAge = 60 * 60 * 24 * 365; // 1 year
284
- cookies.set('theme', value, { maxAge, path: cookiesPath });
291
+ // an absent cookie already means 'system' (see init above), so don't persist it explicitly
292
+ if (value === 'system') {
293
+ cookies.remove('theme', { path: cookiesPath });
294
+ }
295
+ else {
296
+ const maxAge = 60 * 60 * 24 * 365; // 1 year
297
+ cookies.set('theme', value, { maxAge, path: cookiesPath });
298
+ }
285
299
  goTo(null);
286
300
  };
287
301
  const keepalive = async () => {
package/session.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"session.js","sourceRoot":"","sources":["session.ts"],"names":[],"mappings":"AACA,OAAO,EAAwC,eAAe,EAAE,MAAM,KAAK,CAAA;AAC3E,OAAO,EAAE,UAAU,EAAc,MAAM,QAAQ,CAAA;AAK/C,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAA;AAClF,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC/B,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AACtC,OAAO,aAAa,MAAM,kBAAkB,CAAA;AAC5C,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,QAAQ,MAAM,mCAAmC,CAAA;AAExD,cAAc,8CAA8C,CAAA;AAE5D,MAAM,OAAO,GAAG,aAAwD,CAAA;AA8GxE,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,CAAA;AAC9B,KAAK,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;AAWrC;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAE,SAAuB,EAAE,IAAiB;IACtE,IAAI,SAAS,IAAI,SAAS,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAA;IACzD,yFAAyF;IACzF,MAAM,UAAU,GAAG,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,UAAU,CAAC,8BAA8B,CAAC,CAAC,OAAO,CAAA;IAClI,MAAM,QAAQ,GAAG,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,UAAU,CAAC,yBAAyB,CAAC,CAAC,OAAO,CAAA;IAC3H,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,UAAU,IAAI,QAAQ;QAAE,OAAO,SAAS,CAAA;IACjE,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,QAAQ;QAAE,OAAO,IAAI,CAAA;IAC1C,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,UAAU;QAAE,OAAO,MAAM,CAAA;IAChD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,SAAS,cAAc,CAAE,GAAkB;IACzC,IAAI,CAAC,GAAG;QAAE,OAAM;IAChB,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAQ,CAAA;IACrC,IAAI,CAAC,OAAO;QAAE,OAAM;IACpB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAA;IAClD,IAAI,OAAO,OAAO,CAAC,GAAG,KAAK,WAAW,IAAI,OAAO,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC;QAC5D,gBAAgB;QAChB,OAAM;IACR,CAAC;IACD,IAAI,OAAO,OAAO,CAAC,GAAG,KAAK,WAAW,IAAI,OAAO,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC;QAC5D,OAAO,CAAC,IAAI,CAAC,wBAAwB,OAAO,CAAC,GAAG,IAAI,GAAG,KAAK,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QACtF,uFAAuF;IACzF,CAAC;IACD,OAAO,OAAe,CAAA;AACxB,CAAC;AAED,MAAM,cAAc,GAAG,GAAG,EAAE;IAC1B,IAAI,CAAC;QACH,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAA;IAC3D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,MAAM,CAAC,QAAQ,CAAA;IACxB,CAAC;AACH,CAAC,CAAA;AAED,MAAM,IAAI,GAAG,CAAC,GAAkB,EAAE,EAAE;IAClC,MAAM,WAAW,GAAG,cAAc,EAAE,CAAA;IACpC,IAAI,WAAW,IAAI,IAAI,EAAE,CAAC;QACxB,MAAM,IAAI,SAAS,CAAC,6EAA6E,CAAC,CAAA;IACpG,CAAC;IACD,IAAI,GAAG;QAAE,WAAW,CAAC,IAAI,GAAG,GAAG,CAAA;;QAC1B,WAAW,CAAC,MAAM,EAAE,CAAA;AAC3B,CAAC,CAAA;AAED,MAAM,cAAc,GAAG,EAAE,YAAY,EAAE,mBAAmB,EAAE,QAAQ,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAA;AAE7F,MAAM,CAAC,KAAK,UAAU,UAAU,CAAE,WAAoC;IACpE,MAAM,OAAO,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,WAAW,EAAE,CAAA;IACrD,MAAM,WAAW,GAAG,OAAO,CAAC,QAAQ,GAAG,GAAG,CAAA;IAC1C,KAAK,CAAC,qBAAqB,OAAO,CAAC,YAAY,iBAAiB,WAAW,EAAE,CAAC,CAAA;IAC9E,MAAM,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAA;IACzB,IAAI,GAAG;QAAE,KAAK,CAAC,oBAAoB,CAAC,CAAA;IAEpC,MAAM,WAAW,GAAG,WAAW,EAAE,WAAW,IAAI,MAAM,CAAA;IAEtD,6FAA6F;IAC7F,uCAAuC;IACvC,MAAM,WAAW,GAAG,QAAQ,CAAC,GAAG,EAAE;QAChC,IAAI,GAAG;YAAE,OAAO,SAAS,CAAA;QAEzB,IAAI,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,kBAAkB;QAC/D,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAA;QACjC,KAAK,CAAC,uCAAuC,EAAE,QAAQ,CAAC,CAAA;QACxD,OAAO,QAAQ,CAAA;IACjB,CAAC,CAAC,CAAA;IAEF,kEAAkE;IAClE,MAAM,KAAK,GAAG,QAAQ,CAAC,EAAkB,CAAC,CAAA;IAC1C,MAAM,QAAQ,GAAG,UAAU,CAAsB,IAAI,CAAC,CAAA;IACtD,MAAM,IAAI,GAAG,UAAU,CAAkB,IAAI,CAAC,CAAA;IAC9C,MAAM,KAAK,GAAG,GAAG,CAAe,IAAI,CAAC,CAAA;IAErC,qGAAqG;IACrG,MAAM,OAAO,GAAG,WAAW,EAAE,OAAO,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;IAChF,MAAM,SAAS,GAAG,GAAG,EAAE;QACrB,6EAA6E;QAC7E,mEAAmE;QACnE,KAAK,CAAC,KAAK,GAAI,OAAO,CAAC,GAAG,CAAC,OAAO,CAAuB,IAAI,QAAQ,CAAA;QAErE,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;QAC3C,KAAK,CAAC,IAAI,GAAG,UAAU,IAAI,OAAO,CAAC,WAAW,CAAA;QAE9C,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;QACvC,MAAM,IAAI,GAAG,cAAc,CAAC,OAAO,CAAC,CAAA;QAEpC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,KAAK,CAAC,IAAI,CAAA;YACjB,OAAO,KAAK,CAAC,YAAY,CAAA;YACzB,OAAO,KAAK,CAAC,OAAO,CAAA;YACpB,OAAO,KAAK,CAAC,WAAW,CAAA;YACxB,OAAM;QACR,CAAC;QAED,uGAAuG;QACvG,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACrC,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;gBACpB,OAAO,GAAG,CAAC,UAAU,CAAA;gBACrB,OAAO,GAAG,CAAC,cAAc,CAAA;YAC3B,CAAC;QACH,CAAC;QAED,KAAK,CAAC,IAAI,GAAG,IAAI,CAAA;QACjB,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;QAClD,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;QAChD,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAA;QACjD,IAAI,cAAc,EAAE,CAAC;YACnB,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;gBACrD,IAAI,CAAC,CAAC,EAAE,KAAK,cAAc;oBAAE,OAAO,KAAK,CAAA;gBACzC,IAAI,YAAY,IAAI,YAAY,KAAK,CAAC,CAAC,UAAU;oBAAE,OAAO,KAAK,CAAA;gBAC/D,IAAI,YAAY,IAAI,YAAY,KAAK,CAAC,CAAC,IAAI;oBAAE,OAAO,KAAK,CAAA;gBACzD,OAAO,IAAI,CAAA;YACb,CAAC,CAAC,CAAA;QACJ,CAAC;aAAM,CAAC;YACN,OAAO,KAAK,CAAC,YAAY,CAAA;QAC3B,CAAC;QACD,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;YACvB,KAAK,CAAC,OAAO,GAAG;gBACd,IAAI,EAAE,cAAc;gBACpB,EAAE,EAAE,KAAK,CAAC,YAAY,CAAC,EAAE;gBACzB,IAAI,EAAE,KAAK,CAAC,YAAY,CAAC,IAAI;gBAC7B,UAAU,EAAE,KAAK,CAAC,YAAY,CAAC,UAAU;gBACzC,cAAc,EAAE,KAAK,CAAC,YAAY,CAAC,cAAc;aAClD,CAAA;YACD,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC,YAAY,CAAC,IAAI,CAAA;QAC7C,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,OAAO,GAAG;gBACd,IAAI,EAAE,MAAM;gBACZ,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE;gBACjB,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI;aACtB,CAAA;YACD,KAAK,CAAC,WAAW,GAAG,OAAO,CAAA;QAC7B,CAAC;QAED,IAAI,KAAK,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC;YAC1B,IAAI,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;gBACtF,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAA;YAC1B,CAAC;YACD,IAAI,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,cAAc,IAAI,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,KAAK,CAAC,YAAY,EAAE,EAAE,EAAE,CAAC;gBACvG,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,YAAY,CAAC,IAAI,CAAA;YAC1C,CAAC;QACH,CAAC;IACH,CAAC,CAAA;IACD,SAAS,EAAE,CAAA;IACX,KAAK,CAAC,eAAe,EAAE,KAAK,CAAC,CAAA;IAE7B,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,oHAAoH;QACpH,6GAA6G;QAC7G,MAAM,eAAe,GAAG,CAAC,KAAmB,EAAE,EAAE;YAC9C,IAAI,KAAK,CAAC,GAAG,KAAK,YAAY,GAAG,OAAO,CAAC,QAAQ;gBAAE,SAAS,EAAE,CAAA;QAChE,CAAC,CAAA;QACD,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,eAAe,CAAC,CAAA;QAEnD,+IAA+I;QAC/I,mDAAmD;QACnD,gFAAgF;QAEhF,4EAA4E;QAC5E,mFAAmF;QACnF,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE;YACjD,IAAI,OAAO,EAAE,IAAI,KAAK,UAAU,EAAE,IAAI,IAAI,OAAO,EAAE,EAAE,KAAK,UAAU,EAAE,EAAE,IAAI,OAAO,EAAE,UAAU,KAAK,UAAU,EAAE,UAAU,EAAE,CAAC;gBAC3H,IAAI,CAAC,IAAI,CAAC,CAAA;YACZ,CAAC;QACH,CAAC,CAAC,CAAA;QACF,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE;YAC3B,IAAI,CAAC,IAAI,CAAC,CAAA;QACZ,CAAC,CAAC,CAAA;QACF,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE;YAC3B,IAAI,CAAC,IAAI,CAAC,CAAA;QACZ,CAAC,CAAC,CAAA;QACF,KAAK,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;YACrB,IAAI,CAAC,GAAG,EAAE,CAAC;gBACT,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,YAAY,GAAG,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAA;YACrF,CAAC;YACD,KAAK,CAAC,eAAe,EAAE,KAAK,CAAC,CAAA;QAC/B,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,mFAAmF;IACnF,SAAS,QAAQ,CAAE,QAAiB,EAAE,cAAsC,EAAE,EAAE,iBAAiB,GAAG,IAAI;QACtG,8EAA8E;QAC9E,IAAI,QAAQ,IAAI,KAAK,CAAC,IAAI,IAAI,iBAAiB;YAAE,OAAO,QAAQ,CAAA;QAChE,IAAI,CAAC,QAAQ,IAAI,WAAW,CAAC,KAAK;YAAE,QAAQ,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAA;QACrE,IAAI,GAAG,GAAG,GAAG,OAAO,CAAC,YAAY,mBAAmB,kBAAkB,CAAC,QAAQ,IAAI,EAAE,CAAC,EAAE,CAAA;QACxF,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;YACxG,GAAG,IAAI,IAAI,GAAG,IAAI,kBAAkB,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,CAAA;QAC1D,CAAC,CAAC,CAAA;QACF,OAAO,GAAG,CAAA;IACZ,CAAC;IACD,MAAM,KAAK,GAAG,CAAC,QAAiB,EAAE,cAAsC,EAAE,EAAE,iBAAiB,GAAG,IAAI,EAAE,EAAE;QACtG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,WAAW,EAAE,iBAAiB,CAAC,CAAC,CAAA;IAC1D,CAAC,CAAA;IACD,MAAM,MAAM,GAAG,KAAK,EAAE,QAAiB,EAAE,EAAE;QACzC,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,GAAG,OAAO,CAAC,YAAY,WAAW,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAA2C,CAAA;QACtI,+FAA+F;QAC/F,sBAAsB;QACtB,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;QAC1B,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAAA;QAC9B,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAAA;QAC9B,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAA;QAC/B,2FAA2F;QAC3F,IAAI,QAAQ,EAAE,aAAa,EAAE,CAAC;YAC5B,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAA;QAC9B,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,iBAAiB,IAAI,IAAI,CAAC,CAAA;QACrD,CAAC;IACH,CAAC,CAAA;IAED,MAAM,kBAAkB,GAAG,CAAC,GAAkB,EAAE,GAAY,EAAE,IAAa,EAAE,WAAW,GAAG,IAAI,EAAE,EAAE;QACjG,MAAM,UAAU,GAAG,EAAE,IAAI,EAAE,WAAW,EAAE,CAAA;QACxC,IAAI,GAAG;YAAE,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,GAAG,EAAE,UAAU,CAAC,CAAA;;YAChD,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,UAAU,CAAC,CAAA;QAC/C,IAAI,GAAG;YAAE,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,GAAG,EAAE,UAAU,CAAC,CAAA;;YAChD,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,UAAU,CAAC,CAAA;QAC/C,IAAI,IAAI;YAAE,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,EAAE,UAAU,CAAC,CAAA;;YACnD,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,UAAU,CAAC,CAAA;QAChD,IAAI,WAAW;YAAE,SAAS,EAAE,CAAA;IAC9B,CAAC,CAAA;IAED,MAAM,YAAY,GAAG,KAAK,EAAE,SAAkB,EAAE,QAAiB,EAAE,EAAE;QACnE,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,MAAM,GAA2B,EAAE,SAAS,EAAE,MAAM,EAAE,CAAA;YAC5D,IAAI,KAAK,CAAC,IAAI,IAAI,IAAI;gBAAE,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAA;YACvD,kCAAkC;YAClC,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;gBACvB,MAAM,CAAC,GAAG,GAAG,KAAK,CAAC,YAAY,CAAC,EAAE,CAAA;gBAClC,IAAI,KAAK,CAAC,YAAY,CAAC,UAAU;oBAAE,MAAM,CAAC,GAAG,GAAG,KAAK,CAAC,YAAY,CAAC,UAAU,CAAA;YAC/E,CAAC;YACD,MAAM,GAAG,GAAG,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,CAAA;YAC5C,IAAI,CAAC,GAAG,CAAC,CAAA;QACX,CAAC;aAAM,CAAC;YACN,MAAM,WAAW,CAAC,GAAG,OAAO,CAAC,YAAY,qBAAqB,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAA;YACrF,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,CAAA;QACxB,CAAC;IACH,CAAC,CAAA;IAED,MAAM,OAAO,GAAG,KAAK,EAAE,IAAgB,EAAE,EAAE;QACzC,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,WAAW,CAAC,GAAG,OAAO,CAAC,YAAY,mBAAmB,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;QAC/F,CAAC;aAAM,CAAC;YACN,MAAM,WAAW,CAAC,GAAG,OAAO,CAAC,YAAY,mBAAmB,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAA;QACrF,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,CAAA;IACZ,CAAC,CAAA;IAED,MAAM,cAAc,GAAG,KAAK,IAAI,EAAE;QAChC,IAAI,KAAK,CAAC,IAAI,IAAI,IAAI;YAAE,OAAM;QAC9B,MAAM,WAAW,CAAC,GAAG,OAAO,CAAC,YAAY,cAAc,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,eAAe,EAAE,IAAI,EAAE,CAAQ,EAAE,CAAC,CAAA;QACtI,SAAS,EAAE,CAAA;IACb,CAAC,CAAA;IAED,MAAM,UAAU,GAAG,CAAC,KAAa,EAAE,EAAE;QACnC,MAAM,MAAM,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,CAAA,CAAC,SAAS;QAC3C,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAA;QAC9D,IAAI,CAAC,IAAI,CAAC,CAAA;IACZ,CAAC,CAAA;IAED,MAAM,WAAW,GAAG,CAAC,KAAY,EAAE,EAAE;QACnC,MAAM,MAAM,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,CAAA,CAAC,SAAS;QAC3C,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAA;QAC1D,IAAI,CAAC,IAAI,CAAC,CAAA;IACZ,CAAC,CAAA;IAED,MAAM,SAAS,GAAG,KAAK,IAAI,EAAE;QAC3B,8FAA8F;QAC9F,qCAAqC;QACrC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;YAAE,OAAM;QACpC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,cAAc,GAAG,OAAO,CAAC,QAAQ,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAA;QAC3F,CAAC;QACD,IAAI,CAAC;YACH,MAAM,WAAW,CAAC,GAAG,OAAO,CAAC,YAAY,qBAAqB,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;QACrF,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,UAAU,IAAI,GAAG,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;gBACxD,OAAO,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAA;YAC5D,CAAC;iBAAM,CAAC;gBACN,MAAM,GAAG,CAAA;YACX,CAAC;QACH,CAAC;QACD,SAAS,EAAE,CAAA;IACb,CAAC,CAAA;IAED,MAAM,eAAe,GAAG,KAAK,IAAI,EAAE;QACjC,OAAO,CAAC,IAAI,CAAC,0DAA0D,CAAC,CAAA;QACxE,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,GAAG,OAAO,CAAC,YAAY,oBAAoB,CAAC,CAAA;QAC/E,WAAW,CAAC,QAAQ,CAAC,CAAA;IACvB,CAAC,CAAA;IAED,MAAM,WAAW,GAAG,CAAC,QAAa,EAAE,EAAE;QACpC,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YACnB,QAAQ,CAAC,KAAK,GAAG,QAAQ,CAAA;YACzB,MAAM,WAAW,GAAa;gBAC5B,IAAI,EAAE,QAAQ,CAAC,IAAI;gBACnB,aAAa,EAAE,QAAQ,CAAC,aAAa;gBACrC,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI;gBACzB,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAM;gBAC7B,QAAQ,EAAE,QAAQ,CAAC,QAAQ;gBAC3B,iBAAiB,EAAE,QAAQ,CAAC,iBAAiB;gBAC7C,KAAK,EAAE,QAAQ,CAAC,KAAK;aACtB,CAAA;YACD,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;YACnD,IAAI,OAAO,KAAK,IAAI;gBAAE,WAAW,CAAC,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAA;YAClE,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;gBACvB,WAAW,CAAC,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAA;gBAC9C,WAAW,CAAC,IAAI,GAAG,IAAI,CAAA;YACzB,CAAC;YACD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;gBAC1B,WAAW,CAAC,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAA;gBAChD,WAAW,CAAC,IAAI,GAAG,IAAI,CAAA;YACzB,CAAC;YACD,IAAI,CAAC,KAAK,GAAG,WAAW,CAAA;QAC1B,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAA;QACvB,CAAC;IACH,CAAC,CAAA;IAED,IAAI,OAAO,CAAC,QAAQ;QAAE,MAAM,eAAe,EAAE,CAAA;IAE7C,aAAa;IACb,IAAI,CAAC,GAAG,IAAI,MAAM,CAAC,kBAAkB;QAAE,WAAW,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAA;IAE7E,yEAAyE;IACzE,8EAA8E;IAC9E,IAAI,CAAC,GAAG,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QAC/D,MAAM,cAAc,GAAG,GAAG,EAAE;YAC1B,IAAI,KAAK,CAAC,KAAK,KAAK,QAAQ,IAAI,QAAQ,CAAC,KAAK;gBAAE,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;QAC7E,CAAC,CAAA;QACD,MAAM,CAAC,UAAU,CAAC,8BAA8B,CAAC,CAAC,gBAAgB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAA;QAC5F,MAAM,CAAC,UAAU,CAAC,yBAAyB,CAAC,CAAC,gBAAgB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAA;IACzF,CAAC;IAED,oFAAoF;IACpF,2FAA2F;IAC3F,gCAAgC;IAChC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC,gBAAgB,IAAI,MAAM,CAAC,EAAE,CAAC;QACvD,MAAM,aAAa,GAAG,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,cAAc,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;QAEpF,IAAI,CAAC,aAAa,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC,GAAG,KAAK,EAAE,CAAC;YAC7E,MAAM,SAAS,EAAE,CAAA;QACnB,CAAC;QAED,MAAM,gBAAgB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA,CAAC,aAAa;QACrD,WAAW,CAAC,GAAG,EAAE;YACf,MAAM,aAAa,GAAG,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,cAAc,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;YACpF,IAAI,CAAC,aAAa,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC,GAAG,gBAAgB,GAAG,CAAC,EAAE,CAAC;gBAC5F,SAAS,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAA;YAC9C,CAAC;QACH,CAAC,EAAE,gBAAgB,CAAC,CAAA;IACtB,CAAC;IAED,MAAM,OAAO,GAAY;QACvB,KAAK;QACL,YAAY,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC;QAChD,IAAI,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC;QAChC,OAAO,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC;QACtC,WAAW,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC;QAC9C,QAAQ,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC;QACxC,IAAI,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC;QAChC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC;QACtB,IAAI,EAAE,eAAe,CAAC,IAAI,CAAC;QAC3B,QAAQ,EAAE,eAAe,CAAC,QAAQ,CAAC;QACnC,QAAQ;QACR,KAAK;QACL,MAAM;QACN,kBAAkB;QAClB,YAAY;QACZ,OAAO;QACP,cAAc;QACd,SAAS;QACT,eAAe;QACf,WAAW;QACX,UAAU;QACV,WAAW;QACX,OAAO;KACR,CAAA;IAED,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,kIAAkI;AAClI,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,SAAS,CAAC,CAAA;AAC3C,MAAM,CAAC,KAAK,UAAU,aAAa,CAAE,WAAoC;IACvE,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,WAAW,CAAC,CAAA;IAC7C,OAAO;QACL,GAAG,OAAO;QACV,OAAO,CAAE,GAAQ,IAAI,GAAG,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,CAAA,CAAC,CAAC;KACxD,CAAA;AACH,CAAC;AACD,MAAM,UAAU,UAAU;IACxB,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,CAAA;IAClC,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAA;IACnF,OAAO,OAAkB,CAAA;AAC3B,CAAC;AACD,MAAM,UAAU,uBAAuB,CAAE,YAAwB;IAC/D,MAAM,OAAO,GAAG,UAAU,EAAE,CAAA;IAC5B,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QACxB,IAAI,YAAY;YAAE,MAAM,YAAY,EAAE,CAAA;;YACjC,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAA;IAC3E,CAAC;IACD,OAAO,OAA+B,CAAA;AACxC,CAAC;AAED,eAAe,UAAU,CAAA","sourcesContent":["import { type IncomingMessage } from 'node:http'\nimport { type Ref, type ComputedRef, type App, shallowReadonly } from 'vue'\nimport { FetchError, type fetch } from 'ofetch'\n\n// minimal structural type compatible with both vue-router v4 and v5\ninterface RouteLocationLike { fullPath: string }\nimport { type AccountKeys, type SessionState, type SessionStateAuthenticated, type User } from '@data-fair/lib-common-types/session/index.js'\nimport { reactive, computed, watch, inject, ref, shallowRef, readonly } from 'vue'\nimport { ofetch } from 'ofetch'\nimport { jwtDecode } from 'jwt-decode'\nimport cookiesModule from 'universal-cookie'\nimport Debug from 'debug'\nimport inIframe from '@data-fair/lib-utils/in-iframe.js'\n\nexport * from '@data-fair/lib-common-types/session/index.js'\n\nconst Cookies = cookiesModule as unknown as typeof cookiesModule.default\n\ninterface GenericCookies {\n get: (key: string) => string | undefined\n set: (key: string, value: string, options?: Record<string, any>) => void\n remove: (key: string) => void\n}\n\nexport interface SessionOptions {\n sitePath: string\n directoryUrl: string\n defaultLang: string\n route?: RouteLocationLike\n logoutRedirectUrl?: string\n req?: IncomingMessage\n cookies?: GenericCookies\n customFetch?: typeof fetch\n siteInfo?: boolean\n}\n\nexport interface Colors {\n background: string\n 'on-background': string\n surface: string\n 'on-surface': string\n primary: string\n 'on-primary': string\n 'text-primary': string\n secondary: string\n 'on-secondary': string\n 'text-secondary': string\n error: string\n 'on-error': string\n info: string\n 'on-info': string\n success: string\n 'on-success': string\n warning: string\n 'on-warning': string\n admin: string\n 'on-admin': string\n}\n\nexport interface FullSiteInfo {\n main?: boolean\n theme: {\n logo?: string\n colors: Colors\n dark?: boolean\n darkColors?: Colors\n hc?: boolean\n hcColors?: Colors\n hcDark?: boolean\n hcDarkColors?: Colors\n }\n}\n\nexport interface SiteInfo {\n main?: boolean\n isAccountMain?: boolean\n authMode: string\n authOnlyOtherSite?: string\n logo?: string\n dark?: boolean\n colors: Colors\n owner: AccountKeys\n}\n\nexport type AppliedTheme = 'default' | 'dark' | 'hc' | 'hc-dark'\n// `theme` cookie semantics:\n// - absent: implicit 'system' (no choice made yet)\n// - 'system': explicit \"follow the OS preference\"\n// - other: explicit override\n// In both 'system' cases the applied theme is computed at runtime via\n// resolveTheme() using prefers-color-scheme + forced-colors.\nexport type Theme = AppliedTheme | 'system'\n\nexport interface Session {\n state: SessionState\n user: ComputedRef<SessionState['user']>\n organization: ComputedRef<SessionState['organization']>\n account: ComputedRef<SessionState['account']>\n accountRole: ComputedRef<SessionState['accountRole']>\n siteRole: ComputedRef<SessionState['siteRole']>\n lang: ComputedRef<SessionState['lang']>\n theme: Ref<null | Theme>\n site: Ref<SiteInfo | null>\n fullSite: Ref<FullSiteInfo | null>\n loginUrl: (redirect?: string, extraParams?: Record<string, string>, immediateRedirect?: true) => string\n login: (redirect?: string, extraParams?: Record<string, string>, immediateRedirect?: true) => void\n logout: (redirect?: string) => Promise<void>\n switchOrganization: (org: string | null, dep?: string, role?: string, updateState?: boolean) => void\n setAdminMode: (adminMode: boolean, redirect?: string) => Promise<void>\n asAdmin: (user: any | null) => Promise<void>\n cancelDeletion: () => Promise<void>\n keepalive: () => Promise<void>\n refreshSiteInfo: () => Promise<void>\n switchTheme: (value: Theme) => void\n switchLang: (value: string) => void\n topLocation: Ref<Location | undefined>\n options: SessionOptions\n}\n\nexport type SessionAuthenticated = Omit<Session, 'state' | 'user' | 'account' | 'accountRole'> & {\n state: SessionStateAuthenticated\n user: ComputedRef<SessionStateAuthenticated['user']>\n account: ComputedRef<SessionStateAuthenticated['account']>\n accountRole: ComputedRef<SessionStateAuthenticated['accountRole']>\n}\n\nconst debug = Debug('session')\ndebug.log = console.log.bind(console)\n\n// loose shape: hosts whose Colors are partially optional (e.g. portal config) can pass their own type\nexport type ThemeOffers = {\n theme: {\n dark?: boolean\n hc?: boolean\n hcDark?: boolean\n }\n}\n\n/**\n * Resolves a user theme preference to a concrete AppliedTheme — returns the explicit choice when set,\n * otherwise picks the best variant offered by `site` based on the OS `prefers-color-scheme` / `forced-colors`\n * media queries. Always call this before handing a theme name to Vuetify: its built-in `'system'` defaultTheme\n * bypasses custom themes and falls back to its own light/dark.\n */\nexport function resolveTheme (userTheme: Theme | null, site: ThemeOffers): AppliedTheme {\n if (userTheme && userTheme !== 'system') return userTheme\n // see https://www.scottohara.me/blog/2021/10/01/detect-high-contrast-and-dark-modes.html\n const preferDark = typeof window !== 'undefined' && window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n const preferHC = typeof window !== 'undefined' && window.matchMedia && window.matchMedia('(forced-colors: active)').matches\n if (site.theme.hcDark && preferDark && preferHC) return 'hc-dark'\n if (site.theme.hc && preferHC) return 'hc'\n if (site.theme.dark && preferDark) return 'dark'\n return 'default'\n}\n\nfunction jwtDecodeAlive (jwt: string | null): User | undefined {\n if (!jwt) return\n const decoded = jwtDecode(jwt) as any\n if (!decoded) return\n const now = Math.ceil(Date.now().valueOf() / 1000)\n if (typeof decoded.exp !== 'undefined' && decoded.exp < now) {\n // token expired\n return\n }\n if (typeof decoded.nbf !== 'undefined' && decoded.nbf > now) {\n console.warn(`token not yet valid: ${decoded.nbf}>${now}, ${JSON.stringify(decoded)}`)\n // do not return here, this is probably a false flag due to a slightly mismatched clock\n }\n return decoded as User\n}\n\nconst getTopLocation = () => {\n try {\n return window.top ? window.top.location : window.location\n } catch (err) {\n return window.location\n }\n}\n\nconst goTo = (url: string | null) => {\n const topLocation = getTopLocation()\n if (topLocation == null) {\n throw new TypeError('session.goTo was called without access to the window object or its location')\n }\n if (url) topLocation.href = url\n else topLocation.reload()\n}\n\nconst defaultOptions = { directoryUrl: '/simple-directory', sitePath: '', defaultLang: 'fr' }\n\nexport async function getSession (initOptions: Partial<SessionOptions>): Promise<Session> {\n const options = { ...defaultOptions, ...initOptions }\n const cookiesPath = options.sitePath + '/'\n debug(`init directoryUrl=${options.directoryUrl}, cookiesPath=${cookiesPath}`)\n const ssr = !!options.req\n if (ssr) debug('run in SSR context')\n\n const customFetch = initOptions?.customFetch ?? ofetch\n\n // use vue-router to detect page change and maintain a reference to the current page location\n // top page if we are in iframe context\n const topLocation = computed(() => {\n if (ssr) return undefined\n\n if (options.route?.fullPath) { /* empty */ } // adds reactivity\n const location = getTopLocation()\n debug('update location based on route change', location)\n return location\n })\n\n // the core state of the session that is filled by reading cookies\n const state = reactive({} as SessionState)\n const fullSite = shallowRef<FullSiteInfo | null>(null)\n const site = shallowRef<SiteInfo | null>(null)\n const theme = ref<Theme | null>(null)\n\n // cookies are the source of truth and this information is transformed into the state reactive object\n const cookies = initOptions?.cookies ?? new Cookies(options.req?.headers.cookie)\n const readState = () => {\n // absent cookie is treated as implicit 'system' so consumers (theme-switcher\n // radios, host plugins) always have a meaningful value to bind to.\n theme.value = (cookies.get('theme') as Theme | undefined) ?? 'system'\n\n const langCookie = cookies.get('i18n_lang')\n state.lang = langCookie ?? options.defaultLang\n\n const idToken = cookies.get('id_token')\n const user = jwtDecodeAlive(idToken)\n\n if (!user) {\n delete state.user\n delete state.organization\n delete state.account\n delete state.accountRole\n return\n }\n\n // this is to prevent null values that are put by SD versions that do not strictly respect their schema\n for (const org of user.organizations) {\n if (!org.department) {\n delete org.department\n delete org.departmentName\n }\n }\n\n state.user = user\n const organizationId = cookies.get('id_token_org')\n const departmentId = cookies.get('id_token_dep')\n const switchedRole = cookies.get('id_token_role')\n if (organizationId) {\n state.organization = state.user.organizations.find(o => {\n if (o.id !== organizationId) return false\n if (departmentId && departmentId !== o.department) return false\n if (switchedRole && switchedRole !== o.role) return false\n return true\n })\n } else {\n delete state.organization\n }\n if (state.organization) {\n state.account = {\n type: 'organization',\n id: state.organization.id,\n name: state.organization.name,\n department: state.organization.department,\n departmentName: state.organization.departmentName\n }\n state.accountRole = state.organization.role\n } else {\n state.account = {\n type: 'user',\n id: state.user.id,\n name: state.user.name\n }\n state.accountRole = 'admin'\n }\n\n if (state.user?.siteOwner) {\n if (state.user.siteOwner.type === 'user' && state.user.siteOwner.id === state.user.id) {\n state.siteRole = 'admin'\n }\n if (state.user.siteOwner.type === 'organization' && state.user.siteOwner.id === state.organization?.id) {\n state.siteRole = state.organization.role\n }\n }\n }\n readState()\n debug('initial state', state)\n\n if (!ssr) {\n // sessionData is also stored in localStorage as a way to access it in simpler pages that do not require use-session\n // and in order to listen to storage event from other contexts and sync session info accross windows and tabs\n const storageListener = (event: StorageEvent) => {\n if (event.key === 'sd-session' + options.sitePath) readState()\n }\n window.addEventListener('storage', storageListener)\n\n // we cannot use onUnmounted here or we get warnings \"onUnmounted is called when there is no active component instance to be associated with. \"\n // TODO: should we have another cleanup mechanism ?\n // onUnmounted(() => { window.removeEventListener('storage', storageListener) })\n\n // trigger some full page refresh when some key session elements are changed\n // the danger of simply using reactivity is too high, data must be re-fetched, etc.\n watch(() => state.account, (account, oldAccount) => {\n if (account?.type !== oldAccount?.type || account?.id !== oldAccount?.id || account?.department !== oldAccount?.department) {\n goTo(null)\n }\n })\n watch(() => state.lang, () => {\n goTo(null)\n })\n watch(() => state.dark, () => {\n goTo(null)\n })\n watch(state, (state) => {\n if (!ssr) {\n window.localStorage.setItem('sd-session' + options.sitePath, JSON.stringify(state))\n }\n debug('state changed', state)\n })\n }\n\n // login can be performed as a simple link (please use target=top) or as a function\n function loginUrl (redirect?: string, extraParams: Record<string, string> = {}, immediateRedirect = true): string {\n // login can also be used to redirect user immediately if he is already logged\n if (redirect && state.user && immediateRedirect) return redirect\n if (!redirect && topLocation.value) redirect = topLocation.value.href\n let url = `${options.directoryUrl}/login?redirect=${encodeURIComponent(redirect ?? '')}`\n Object.keys(extraParams).filter(key => ![null, undefined, ''].includes(extraParams[key])).forEach((key) => {\n url += `&${key}=${encodeURIComponent(extraParams[key])}`\n })\n return url\n }\n const login = (redirect?: string, extraParams: Record<string, string> = {}, immediateRedirect = true) => {\n goTo(loginUrl(redirect, extraParams, immediateRedirect))\n }\n const logout = async (redirect?: string) => {\n const response = await customFetch(`${options.directoryUrl}/api/auth`, { method: 'DELETE' }) as { endSessionUrl?: string } | undefined\n // sometimes server side cookie deletion is not applied immediately in browser local js context\n // so we do it here to\n cookies.remove('id_token')\n cookies.remove('id_token_org')\n cookies.remove('id_token_dep')\n cookies.remove('id_token_role')\n // RP-Initiated Logout: if the server returned an endSessionUrl, redirect to the SSO logout\n if (response?.endSessionUrl) {\n goTo(response.endSessionUrl)\n } else {\n goTo(redirect ?? options.logoutRedirectUrl ?? null)\n }\n }\n\n const switchOrganization = (org: string | null, dep?: string, role?: string, updateState = true) => {\n const cookieOpts = { path: cookiesPath }\n if (org) cookies.set('id_token_org', org, cookieOpts)\n else cookies.remove('id_token_org', cookieOpts)\n if (dep) cookies.set('id_token_dep', dep, cookieOpts)\n else cookies.remove('id_token_dep', cookieOpts)\n if (role) cookies.set('id_token_role', role, cookieOpts)\n else cookies.remove('id_token_role', cookieOpts)\n if (updateState) readState()\n }\n\n const setAdminMode = async (adminMode: boolean, redirect?: string) => {\n if (adminMode) {\n const params: Record<string, string> = { adminMode: 'true' }\n if (state.user != null) params.email = state.user.email\n // preserve current active org/dep\n if (state.organization) {\n params.org = state.organization.id\n if (state.organization.department) params.dep = state.organization.department\n }\n const url = loginUrl(redirect, params, true)\n goTo(url)\n } else {\n await customFetch(`${options.directoryUrl}/api/auth/adminmode`, { method: 'DELETE' })\n goTo(redirect ?? null)\n }\n }\n\n const asAdmin = async (user: any | null) => {\n if (user) {\n await customFetch(`${options.directoryUrl}/api/auth/asadmin`, { method: 'POST', body: user })\n } else {\n await customFetch(`${options.directoryUrl}/api/auth/asadmin`, { method: 'DELETE' })\n }\n goTo(null)\n }\n\n const cancelDeletion = async () => {\n if (state.user == null) return\n await customFetch(`${options.directoryUrl}/api/users/${state.user.id}`, { method: 'PATCH', body: ({ plannedDeletion: null }) as any })\n readState()\n }\n\n const switchLang = (value: string) => {\n const maxAge = 60 * 60 * 24 * 365 // 1 year\n cookies.set('i18n_lang', value, { maxAge, path: cookiesPath })\n goTo(null)\n }\n\n const switchTheme = (value: Theme) => {\n const maxAge = 60 * 60 * 24 * 365 // 1 year\n cookies.set('theme', value, { maxAge, path: cookiesPath })\n goTo(null)\n }\n\n const keepalive = async () => {\n // check cookies.get('id_token') not state.user so that we do a keepalive on expired id tokens\n // as we might have an exchange token\n if (!cookies.get('id_token')) return\n if (!ssr) {\n window.localStorage.setItem('sd-keepalive' + options.sitePath, `${new Date().getTime()}`)\n }\n try {\n await customFetch(`${options.directoryUrl}/api/auth/keepalive`, { method: 'POST' })\n } catch (err) {\n if (err instanceof FetchError && err.statusCode === 401) {\n console.warn('session was expired or deleted server side')\n } else {\n throw err\n }\n }\n readState()\n }\n\n const refreshSiteInfo = async () => {\n console.warn('@data-fair/lib-vue/session refreshSiteInfo is deprecated')\n const siteInfo = await customFetch(`${options.directoryUrl}/api/sites/_public`)\n setSiteInfo(siteInfo)\n }\n\n const setSiteInfo = (siteInfo: any) => {\n if (siteInfo.theme) {\n fullSite.value = siteInfo\n const partialSite: SiteInfo = {\n main: siteInfo.main,\n isAccountMain: siteInfo.isAccountMain,\n logo: siteInfo.theme.logo,\n colors: siteInfo.theme.colors,\n authMode: siteInfo.authMode,\n authOnlyOtherSite: siteInfo.authOnlyOtherSite,\n owner: siteInfo.owner\n }\n const applied = resolveTheme(theme.value, siteInfo)\n if (applied === 'hc') partialSite.colors = siteInfo.theme.hcColors\n if (applied === 'dark') {\n partialSite.colors = siteInfo.theme.darkColors\n partialSite.dark = true\n }\n if (applied === 'hc-dark') {\n partialSite.colors = siteInfo.theme.hcDarkColors\n partialSite.dark = true\n }\n site.value = partialSite\n } else {\n site.value = siteInfo\n }\n }\n\n if (options.siteInfo) await refreshSiteInfo()\n\n // @ts-ignore\n if (!ssr && window.__PUBLIC_SITE_INFO) setSiteInfo(window.__PUBLIC_SITE_INFO)\n\n // re-apply the theme when the OS preference changes while the user is on\n // 'system'. Important for mobile devices that switch light/dark over the day.\n if (!ssr && typeof window !== 'undefined' && window.matchMedia) {\n const onOsPrefChange = () => {\n if (theme.value === 'system' && fullSite.value) setSiteInfo(fullSite.value)\n }\n window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', onOsPrefChange)\n window.matchMedia('(forced-colors: active)').addEventListener('change', onOsPrefChange)\n }\n\n // immediately performs a keepalive, but only on top windows (not iframes or popups)\n // and only if it was not done very recently (maybe from a refreshed page next to this one)\n // also run an auto-refresh loop\n if (!ssr && !inIframe && !('triggerCapture' in window)) {\n const lastKeepalive = window.localStorage.getItem('sd-keepalive' + options.sitePath)\n\n if (!lastKeepalive || (new Date().getTime() - Number(lastKeepalive)) > 10000) {\n await keepalive()\n }\n\n const refreshLoopDelay = 10 * 60 * 1000 // 10 minutes\n setInterval(() => {\n const lastKeepalive = window.localStorage.getItem('sd-keepalive' + options.sitePath)\n if (!lastKeepalive || (new Date().getTime() - Number(lastKeepalive)) > refreshLoopDelay / 2) {\n keepalive().catch(err => console.error(err))\n }\n }, refreshLoopDelay)\n }\n\n const session: Session = {\n state,\n organization: computed(() => state.organization),\n user: computed(() => state.user),\n account: computed(() => state.account),\n accountRole: computed(() => state.accountRole),\n siteRole: computed(() => state.siteRole),\n lang: computed(() => state.lang),\n theme: readonly(theme),\n site: shallowReadonly(site),\n fullSite: shallowReadonly(fullSite),\n loginUrl,\n login,\n logout,\n switchOrganization,\n setAdminMode,\n asAdmin,\n cancelDeletion,\n keepalive,\n refreshSiteInfo,\n switchTheme,\n switchLang,\n topLocation,\n options\n }\n\n return session\n}\n\n// uses pattern for SSR friendly plugin/composable, cf https://antfu.me/posts/composable-vue-vueday-2021#shared-state-ssr-friendly\nexport const sessionKey = Symbol('session')\nexport async function createSession (initOptions: Partial<SessionOptions>) {\n const session = await getSession(initOptions)\n return {\n ...session,\n install (app: App) { app.provide(sessionKey, session) },\n }\n}\nexport function useSession () {\n const session = inject(sessionKey)\n if (!session) throw new Error('useSession requires using the plugin createSession')\n return session as Session\n}\nexport function useSessionAuthenticated (errorBuilder?: () => any) {\n const session = useSession()\n if (!session.state.user) {\n if (errorBuilder) throw errorBuilder()\n else throw new Error('useSessionAuthenticated requires a logged in user')\n }\n return session as SessionAuthenticated\n}\n\nexport default useSession\n"]}
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["session.ts"],"names":[],"mappings":"AACA,OAAO,EAAwC,eAAe,EAAE,MAAM,KAAK,CAAA;AAC3E,OAAO,EAAE,UAAU,EAAc,MAAM,QAAQ,CAAA;AAK/C,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAA;AAClF,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC/B,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AACtC,OAAO,aAAa,MAAM,kBAAkB,CAAA;AAC5C,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,QAAQ,MAAM,mCAAmC,CAAA;AAExD,cAAc,8CAA8C,CAAA;AAE5D,MAAM,OAAO,GAAG,aAAwD,CAAA;AA8GxE,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,CAAA;AAC9B,KAAK,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;AAWrC;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAE,SAAuB,EAAE,IAAiB;IACtE,wFAAwF;IACxF,uFAAuF;IACvF,IAAI,SAAS,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IAC7C,IAAI,SAAS,KAAK,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI;QAAE,OAAO,MAAM,CAAA;IAC1D,IAAI,SAAS,KAAK,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE;QAAE,OAAO,IAAI,CAAA;IACpD,IAAI,SAAS,KAAK,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM;QAAE,OAAO,SAAS,CAAA;IAElE,yFAAyF;IACzF,MAAM,UAAU,GAAG,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,UAAU,CAAC,8BAA8B,CAAC,CAAC,OAAO,CAAA;IAClI,MAAM,QAAQ,GAAG,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,UAAU,CAAC,yBAAyB,CAAC,CAAC,OAAO,CAAA;IAC3H,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,UAAU,IAAI,QAAQ;QAAE,OAAO,SAAS,CAAA;IACjE,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,QAAQ;QAAE,OAAO,IAAI,CAAA;IAC1C,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,UAAU;QAAE,OAAO,MAAM,CAAA;IAChD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,SAAS,cAAc,CAAE,GAAkB;IACzC,IAAI,CAAC,GAAG;QAAE,OAAM;IAChB,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAQ,CAAA;IACrC,IAAI,CAAC,OAAO;QAAE,OAAM;IACpB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAA;IAClD,IAAI,OAAO,OAAO,CAAC,GAAG,KAAK,WAAW,IAAI,OAAO,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC;QAC5D,gBAAgB;QAChB,OAAM;IACR,CAAC;IACD,IAAI,OAAO,OAAO,CAAC,GAAG,KAAK,WAAW,IAAI,OAAO,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC;QAC5D,OAAO,CAAC,IAAI,CAAC,wBAAwB,OAAO,CAAC,GAAG,IAAI,GAAG,KAAK,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QACtF,uFAAuF;IACzF,CAAC;IACD,OAAO,OAAe,CAAA;AACxB,CAAC;AAED,MAAM,cAAc,GAAG,GAAG,EAAE;IAC1B,IAAI,CAAC;QACH,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAA;IAC3D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,MAAM,CAAC,QAAQ,CAAA;IACxB,CAAC;AACH,CAAC,CAAA;AAED,MAAM,IAAI,GAAG,CAAC,GAAkB,EAAE,EAAE;IAClC,MAAM,WAAW,GAAG,cAAc,EAAE,CAAA;IACpC,IAAI,WAAW,IAAI,IAAI,EAAE,CAAC;QACxB,MAAM,IAAI,SAAS,CAAC,6EAA6E,CAAC,CAAA;IACpG,CAAC;IACD,IAAI,GAAG;QAAE,WAAW,CAAC,IAAI,GAAG,GAAG,CAAA;;QAC1B,WAAW,CAAC,MAAM,EAAE,CAAA;AAC3B,CAAC,CAAA;AAED,MAAM,cAAc,GAAG,EAAE,YAAY,EAAE,mBAAmB,EAAE,QAAQ,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAA;AAE7F,MAAM,CAAC,KAAK,UAAU,UAAU,CAAE,WAAoC;IACpE,MAAM,OAAO,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,WAAW,EAAE,CAAA;IACrD,MAAM,WAAW,GAAG,OAAO,CAAC,QAAQ,GAAG,GAAG,CAAA;IAC1C,KAAK,CAAC,qBAAqB,OAAO,CAAC,YAAY,iBAAiB,WAAW,EAAE,CAAC,CAAA;IAC9E,MAAM,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAA;IACzB,IAAI,GAAG;QAAE,KAAK,CAAC,oBAAoB,CAAC,CAAA;IAEpC,MAAM,WAAW,GAAG,WAAW,EAAE,WAAW,IAAI,MAAM,CAAA;IAEtD,6FAA6F;IAC7F,uCAAuC;IACvC,MAAM,WAAW,GAAG,QAAQ,CAAC,GAAG,EAAE;QAChC,IAAI,GAAG;YAAE,OAAO,SAAS,CAAA;QAEzB,IAAI,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,kBAAkB;QAC/D,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAA;QACjC,KAAK,CAAC,uCAAuC,EAAE,QAAQ,CAAC,CAAA;QACxD,OAAO,QAAQ,CAAA;IACjB,CAAC,CAAC,CAAA;IAEF,kEAAkE;IAClE,MAAM,KAAK,GAAG,QAAQ,CAAC,EAAkB,CAAC,CAAA;IAC1C,MAAM,QAAQ,GAAG,UAAU,CAAsB,IAAI,CAAC,CAAA;IACtD,MAAM,IAAI,GAAG,UAAU,CAAkB,IAAI,CAAC,CAAA;IAC9C,MAAM,KAAK,GAAG,GAAG,CAAe,IAAI,CAAC,CAAA;IAErC,qGAAqG;IACrG,MAAM,OAAO,GAAG,WAAW,EAAE,OAAO,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;IAChF,MAAM,SAAS,GAAG,GAAG,EAAE;QACrB,6EAA6E;QAC7E,mEAAmE;QACnE,KAAK,CAAC,KAAK,GAAI,OAAO,CAAC,GAAG,CAAC,OAAO,CAAuB,IAAI,QAAQ,CAAA;QAErE,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;QAC3C,KAAK,CAAC,IAAI,GAAG,UAAU,IAAI,OAAO,CAAC,WAAW,CAAA;QAE9C,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;QACvC,MAAM,IAAI,GAAG,cAAc,CAAC,OAAO,CAAC,CAAA;QAEpC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,KAAK,CAAC,IAAI,CAAA;YACjB,OAAO,KAAK,CAAC,YAAY,CAAA;YACzB,OAAO,KAAK,CAAC,OAAO,CAAA;YACpB,OAAO,KAAK,CAAC,WAAW,CAAA;YACxB,OAAM;QACR,CAAC;QAED,uGAAuG;QACvG,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACrC,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;gBACpB,OAAO,GAAG,CAAC,UAAU,CAAA;gBACrB,OAAO,GAAG,CAAC,cAAc,CAAA;YAC3B,CAAC;QACH,CAAC;QAED,KAAK,CAAC,IAAI,GAAG,IAAI,CAAA;QACjB,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;QAClD,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;QAChD,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAA;QACjD,IAAI,cAAc,EAAE,CAAC;YACnB,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;gBACrD,IAAI,CAAC,CAAC,EAAE,KAAK,cAAc;oBAAE,OAAO,KAAK,CAAA;gBACzC,IAAI,YAAY,IAAI,YAAY,KAAK,CAAC,CAAC,UAAU;oBAAE,OAAO,KAAK,CAAA;gBAC/D,IAAI,YAAY,IAAI,YAAY,KAAK,CAAC,CAAC,IAAI;oBAAE,OAAO,KAAK,CAAA;gBACzD,OAAO,IAAI,CAAA;YACb,CAAC,CAAC,CAAA;QACJ,CAAC;aAAM,CAAC;YACN,OAAO,KAAK,CAAC,YAAY,CAAA;QAC3B,CAAC;QACD,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;YACvB,KAAK,CAAC,OAAO,GAAG;gBACd,IAAI,EAAE,cAAc;gBACpB,EAAE,EAAE,KAAK,CAAC,YAAY,CAAC,EAAE;gBACzB,IAAI,EAAE,KAAK,CAAC,YAAY,CAAC,IAAI;gBAC7B,UAAU,EAAE,KAAK,CAAC,YAAY,CAAC,UAAU;gBACzC,cAAc,EAAE,KAAK,CAAC,YAAY,CAAC,cAAc;aAClD,CAAA;YACD,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC,YAAY,CAAC,IAAI,CAAA;QAC7C,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,OAAO,GAAG;gBACd,IAAI,EAAE,MAAM;gBACZ,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE;gBACjB,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI;aACtB,CAAA;YACD,KAAK,CAAC,WAAW,GAAG,OAAO,CAAA;QAC7B,CAAC;QAED,IAAI,KAAK,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC;YAC1B,IAAI,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;gBACtF,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAA;YAC1B,CAAC;YACD,IAAI,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,cAAc,IAAI,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,KAAK,CAAC,YAAY,EAAE,EAAE,EAAE,CAAC;gBACvG,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,YAAY,CAAC,IAAI,CAAA;YAC1C,CAAC;QACH,CAAC;IACH,CAAC,CAAA;IACD,SAAS,EAAE,CAAA;IACX,KAAK,CAAC,eAAe,EAAE,KAAK,CAAC,CAAA;IAE7B,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,oHAAoH;QACpH,6GAA6G;QAC7G,MAAM,eAAe,GAAG,CAAC,KAAmB,EAAE,EAAE;YAC9C,IAAI,KAAK,CAAC,GAAG,KAAK,YAAY,GAAG,OAAO,CAAC,QAAQ;gBAAE,SAAS,EAAE,CAAA;QAChE,CAAC,CAAA;QACD,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,eAAe,CAAC,CAAA;QAEnD,+IAA+I;QAC/I,mDAAmD;QACnD,gFAAgF;QAEhF,4EAA4E;QAC5E,mFAAmF;QACnF,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE;YACjD,IAAI,OAAO,EAAE,IAAI,KAAK,UAAU,EAAE,IAAI,IAAI,OAAO,EAAE,EAAE,KAAK,UAAU,EAAE,EAAE,IAAI,OAAO,EAAE,UAAU,KAAK,UAAU,EAAE,UAAU,EAAE,CAAC;gBAC3H,IAAI,CAAC,IAAI,CAAC,CAAA;YACZ,CAAC;QACH,CAAC,CAAC,CAAA;QACF,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE;YAC3B,IAAI,CAAC,IAAI,CAAC,CAAA;QACZ,CAAC,CAAC,CAAA;QACF,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE;YAC3B,IAAI,CAAC,IAAI,CAAC,CAAA;QACZ,CAAC,CAAC,CAAA;QACF,KAAK,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;YACrB,IAAI,CAAC,GAAG,EAAE,CAAC;gBACT,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,YAAY,GAAG,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAA;YACrF,CAAC;YACD,KAAK,CAAC,eAAe,EAAE,KAAK,CAAC,CAAA;QAC/B,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,mFAAmF;IACnF,SAAS,QAAQ,CAAE,QAAiB,EAAE,cAAsC,EAAE,EAAE,iBAAiB,GAAG,IAAI;QACtG,8EAA8E;QAC9E,IAAI,QAAQ,IAAI,KAAK,CAAC,IAAI,IAAI,iBAAiB;YAAE,OAAO,QAAQ,CAAA;QAChE,IAAI,CAAC,QAAQ,IAAI,WAAW,CAAC,KAAK;YAAE,QAAQ,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAA;QACrE,IAAI,GAAG,GAAG,GAAG,OAAO,CAAC,YAAY,mBAAmB,kBAAkB,CAAC,QAAQ,IAAI,EAAE,CAAC,EAAE,CAAA;QACxF,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;YACxG,GAAG,IAAI,IAAI,GAAG,IAAI,kBAAkB,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,CAAA;QAC1D,CAAC,CAAC,CAAA;QACF,OAAO,GAAG,CAAA;IACZ,CAAC;IACD,MAAM,KAAK,GAAG,CAAC,QAAiB,EAAE,cAAsC,EAAE,EAAE,iBAAiB,GAAG,IAAI,EAAE,EAAE;QACtG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,WAAW,EAAE,iBAAiB,CAAC,CAAC,CAAA;IAC1D,CAAC,CAAA;IACD,MAAM,MAAM,GAAG,KAAK,EAAE,QAAiB,EAAE,EAAE;QACzC,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,GAAG,OAAO,CAAC,YAAY,WAAW,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAA2C,CAAA;QACtI,+FAA+F;QAC/F,sBAAsB;QACtB,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;QAC1B,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAAA;QAC9B,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAAA;QAC9B,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAA;QAC/B,2FAA2F;QAC3F,IAAI,QAAQ,EAAE,aAAa,EAAE,CAAC;YAC5B,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAA;QAC9B,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,iBAAiB,IAAI,IAAI,CAAC,CAAA;QACrD,CAAC;IACH,CAAC,CAAA;IAED,MAAM,kBAAkB,GAAG,CAAC,GAAkB,EAAE,GAAY,EAAE,IAAa,EAAE,WAAW,GAAG,IAAI,EAAE,EAAE;QACjG,MAAM,UAAU,GAAG,EAAE,IAAI,EAAE,WAAW,EAAE,CAAA;QACxC,IAAI,GAAG;YAAE,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,GAAG,EAAE,UAAU,CAAC,CAAA;;YAChD,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,UAAU,CAAC,CAAA;QAC/C,IAAI,GAAG;YAAE,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,GAAG,EAAE,UAAU,CAAC,CAAA;;YAChD,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,UAAU,CAAC,CAAA;QAC/C,IAAI,IAAI;YAAE,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,EAAE,UAAU,CAAC,CAAA;;YACnD,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,UAAU,CAAC,CAAA;QAChD,IAAI,WAAW;YAAE,SAAS,EAAE,CAAA;IAC9B,CAAC,CAAA;IAED,MAAM,YAAY,GAAG,KAAK,EAAE,SAAkB,EAAE,QAAiB,EAAE,EAAE;QACnE,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,MAAM,GAA2B,EAAE,SAAS,EAAE,MAAM,EAAE,CAAA;YAC5D,IAAI,KAAK,CAAC,IAAI,IAAI,IAAI;gBAAE,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAA;YACvD,kCAAkC;YAClC,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;gBACvB,MAAM,CAAC,GAAG,GAAG,KAAK,CAAC,YAAY,CAAC,EAAE,CAAA;gBAClC,IAAI,KAAK,CAAC,YAAY,CAAC,UAAU;oBAAE,MAAM,CAAC,GAAG,GAAG,KAAK,CAAC,YAAY,CAAC,UAAU,CAAA;YAC/E,CAAC;YACD,MAAM,GAAG,GAAG,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,CAAA;YAC5C,IAAI,CAAC,GAAG,CAAC,CAAA;QACX,CAAC;aAAM,CAAC;YACN,MAAM,WAAW,CAAC,GAAG,OAAO,CAAC,YAAY,qBAAqB,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAA;YACrF,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,CAAA;QACxB,CAAC;IACH,CAAC,CAAA;IAED,MAAM,OAAO,GAAG,KAAK,EAAE,IAAgB,EAAE,EAAE;QACzC,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,WAAW,CAAC,GAAG,OAAO,CAAC,YAAY,mBAAmB,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;QAC/F,CAAC;aAAM,CAAC;YACN,MAAM,WAAW,CAAC,GAAG,OAAO,CAAC,YAAY,mBAAmB,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAA;QACrF,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,CAAA;IACZ,CAAC,CAAA;IAED,MAAM,cAAc,GAAG,KAAK,IAAI,EAAE;QAChC,IAAI,KAAK,CAAC,IAAI,IAAI,IAAI;YAAE,OAAM;QAC9B,MAAM,WAAW,CAAC,GAAG,OAAO,CAAC,YAAY,cAAc,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,eAAe,EAAE,IAAI,EAAE,CAAQ,EAAE,CAAC,CAAA;QACtI,SAAS,EAAE,CAAA;IACb,CAAC,CAAA;IAED,MAAM,UAAU,GAAG,CAAC,KAAa,EAAE,EAAE;QACnC,MAAM,MAAM,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,CAAA,CAAC,SAAS;QAC3C,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAA;QAC9D,IAAI,CAAC,IAAI,CAAC,CAAA;IACZ,CAAC,CAAA;IAED,MAAM,WAAW,GAAG,CAAC,KAAY,EAAE,EAAE;QACnC,2FAA2F;QAC3F,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;YACvB,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAA;QAChD,CAAC;aAAM,CAAC;YACN,MAAM,MAAM,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,CAAA,CAAC,SAAS;YAC3C,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAA;QAC5D,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,CAAA;IACZ,CAAC,CAAA;IAED,MAAM,SAAS,GAAG,KAAK,IAAI,EAAE;QAC3B,8FAA8F;QAC9F,qCAAqC;QACrC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;YAAE,OAAM;QACpC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,cAAc,GAAG,OAAO,CAAC,QAAQ,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAA;QAC3F,CAAC;QACD,IAAI,CAAC;YACH,MAAM,WAAW,CAAC,GAAG,OAAO,CAAC,YAAY,qBAAqB,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;QACrF,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,UAAU,IAAI,GAAG,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;gBACxD,OAAO,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAA;YAC5D,CAAC;iBAAM,CAAC;gBACN,MAAM,GAAG,CAAA;YACX,CAAC;QACH,CAAC;QACD,SAAS,EAAE,CAAA;IACb,CAAC,CAAA;IAED,MAAM,eAAe,GAAG,KAAK,IAAI,EAAE;QACjC,OAAO,CAAC,IAAI,CAAC,0DAA0D,CAAC,CAAA;QACxE,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,GAAG,OAAO,CAAC,YAAY,oBAAoB,CAAC,CAAA;QAC/E,WAAW,CAAC,QAAQ,CAAC,CAAA;IACvB,CAAC,CAAA;IAED,MAAM,WAAW,GAAG,CAAC,QAAa,EAAE,EAAE;QACpC,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YACnB,QAAQ,CAAC,KAAK,GAAG,QAAQ,CAAA;YACzB,MAAM,WAAW,GAAa;gBAC5B,IAAI,EAAE,QAAQ,CAAC,IAAI;gBACnB,aAAa,EAAE,QAAQ,CAAC,aAAa;gBACrC,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI;gBACzB,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAM;gBAC7B,QAAQ,EAAE,QAAQ,CAAC,QAAQ;gBAC3B,iBAAiB,EAAE,QAAQ,CAAC,iBAAiB;gBAC7C,KAAK,EAAE,QAAQ,CAAC,KAAK;aACtB,CAAA;YACD,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;YACnD,IAAI,OAAO,KAAK,IAAI;gBAAE,WAAW,CAAC,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAA;YAClE,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;gBACvB,WAAW,CAAC,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAA;gBAC9C,WAAW,CAAC,IAAI,GAAG,IAAI,CAAA;YACzB,CAAC;YACD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;gBAC1B,WAAW,CAAC,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAA;gBAChD,WAAW,CAAC,IAAI,GAAG,IAAI,CAAA;YACzB,CAAC;YACD,IAAI,CAAC,KAAK,GAAG,WAAW,CAAA;QAC1B,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAA;QACvB,CAAC;IACH,CAAC,CAAA;IAED,IAAI,OAAO,CAAC,QAAQ;QAAE,MAAM,eAAe,EAAE,CAAA;IAE7C,aAAa;IACb,IAAI,CAAC,GAAG,IAAI,MAAM,CAAC,kBAAkB;QAAE,WAAW,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAA;IAE7E,yEAAyE;IACzE,8EAA8E;IAC9E,IAAI,CAAC,GAAG,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QAC/D,MAAM,cAAc,GAAG,GAAG,EAAE;YAC1B,IAAI,KAAK,CAAC,KAAK,KAAK,QAAQ,IAAI,QAAQ,CAAC,KAAK;gBAAE,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;QAC7E,CAAC,CAAA;QACD,MAAM,CAAC,UAAU,CAAC,8BAA8B,CAAC,CAAC,gBAAgB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAA;QAC5F,MAAM,CAAC,UAAU,CAAC,yBAAyB,CAAC,CAAC,gBAAgB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAA;IACzF,CAAC;IAED,oFAAoF;IACpF,2FAA2F;IAC3F,gCAAgC;IAChC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC,gBAAgB,IAAI,MAAM,CAAC,EAAE,CAAC;QACvD,MAAM,aAAa,GAAG,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,cAAc,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;QAEpF,IAAI,CAAC,aAAa,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC,GAAG,KAAK,EAAE,CAAC;YAC7E,MAAM,SAAS,EAAE,CAAA;QACnB,CAAC;QAED,MAAM,gBAAgB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA,CAAC,aAAa;QACrD,WAAW,CAAC,GAAG,EAAE;YACf,MAAM,aAAa,GAAG,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,cAAc,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;YACpF,IAAI,CAAC,aAAa,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC,GAAG,gBAAgB,GAAG,CAAC,EAAE,CAAC;gBAC5F,SAAS,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAA;YAC9C,CAAC;QACH,CAAC,EAAE,gBAAgB,CAAC,CAAA;IACtB,CAAC;IAED,MAAM,OAAO,GAAY;QACvB,KAAK;QACL,YAAY,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC;QAChD,IAAI,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC;QAChC,OAAO,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC;QACtC,WAAW,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC;QAC9C,QAAQ,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC;QACxC,IAAI,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC;QAChC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC;QACtB,IAAI,EAAE,eAAe,CAAC,IAAI,CAAC;QAC3B,QAAQ,EAAE,eAAe,CAAC,QAAQ,CAAC;QACnC,QAAQ;QACR,KAAK;QACL,MAAM;QACN,kBAAkB;QAClB,YAAY;QACZ,OAAO;QACP,cAAc;QACd,SAAS;QACT,eAAe;QACf,WAAW;QACX,UAAU;QACV,WAAW;QACX,OAAO;KACR,CAAA;IAED,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,kIAAkI;AAClI,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,SAAS,CAAC,CAAA;AAC3C,MAAM,CAAC,KAAK,UAAU,aAAa,CAAE,WAAoC;IACvE,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,WAAW,CAAC,CAAA;IAC7C,OAAO;QACL,GAAG,OAAO;QACV,OAAO,CAAE,GAAQ,IAAI,GAAG,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,CAAA,CAAC,CAAC;KACxD,CAAA;AACH,CAAC;AACD,MAAM,UAAU,UAAU;IACxB,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,CAAA;IAClC,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAA;IACnF,OAAO,OAAkB,CAAA;AAC3B,CAAC;AACD,MAAM,UAAU,uBAAuB,CAAE,YAAwB;IAC/D,MAAM,OAAO,GAAG,UAAU,EAAE,CAAA;IAC5B,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QACxB,IAAI,YAAY;YAAE,MAAM,YAAY,EAAE,CAAA;;YACjC,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAA;IAC3E,CAAC;IACD,OAAO,OAA+B,CAAA;AACxC,CAAC;AAED,eAAe,UAAU,CAAA","sourcesContent":["import { type IncomingMessage } from 'node:http'\nimport { type Ref, type ComputedRef, type App, shallowReadonly } from 'vue'\nimport { FetchError, type fetch } from 'ofetch'\n\n// minimal structural type compatible with both vue-router v4 and v5\ninterface RouteLocationLike { fullPath: string }\nimport { type AccountKeys, type SessionState, type SessionStateAuthenticated, type User } from '@data-fair/lib-common-types/session/index.js'\nimport { reactive, computed, watch, inject, ref, shallowRef, readonly } from 'vue'\nimport { ofetch } from 'ofetch'\nimport { jwtDecode } from 'jwt-decode'\nimport cookiesModule from 'universal-cookie'\nimport Debug from 'debug'\nimport inIframe from '@data-fair/lib-utils/in-iframe.js'\n\nexport * from '@data-fair/lib-common-types/session/index.js'\n\nconst Cookies = cookiesModule as unknown as typeof cookiesModule.default\n\ninterface GenericCookies {\n get: (key: string) => string | undefined\n set: (key: string, value: string, options?: Record<string, any>) => void\n remove: (key: string) => void\n}\n\nexport interface SessionOptions {\n sitePath: string\n directoryUrl: string\n defaultLang: string\n route?: RouteLocationLike\n logoutRedirectUrl?: string\n req?: IncomingMessage\n cookies?: GenericCookies\n customFetch?: typeof fetch\n siteInfo?: boolean\n}\n\nexport interface Colors {\n background: string\n 'on-background': string\n surface: string\n 'on-surface': string\n primary: string\n 'on-primary': string\n 'text-primary': string\n secondary: string\n 'on-secondary': string\n 'text-secondary': string\n error: string\n 'on-error': string\n info: string\n 'on-info': string\n success: string\n 'on-success': string\n warning: string\n 'on-warning': string\n admin: string\n 'on-admin': string\n}\n\nexport interface FullSiteInfo {\n main?: boolean\n theme: {\n logo?: string\n colors: Colors\n dark?: boolean\n darkColors?: Colors\n hc?: boolean\n hcColors?: Colors\n hcDark?: boolean\n hcDarkColors?: Colors\n }\n}\n\nexport interface SiteInfo {\n main?: boolean\n isAccountMain?: boolean\n authMode: string\n authOnlyOtherSite?: string\n logo?: string\n dark?: boolean\n colors: Colors\n owner: AccountKeys\n}\n\nexport type AppliedTheme = 'default' | 'dark' | 'hc' | 'hc-dark'\n// `theme` cookie semantics:\n// - absent: implicit 'system' (no choice made yet)\n// - 'system': explicit \"follow the OS preference\"\n// - other: explicit override\n// In both 'system' cases the applied theme is computed at runtime via\n// resolveTheme() using prefers-color-scheme + forced-colors.\nexport type Theme = AppliedTheme | 'system'\n\nexport interface Session {\n state: SessionState\n user: ComputedRef<SessionState['user']>\n organization: ComputedRef<SessionState['organization']>\n account: ComputedRef<SessionState['account']>\n accountRole: ComputedRef<SessionState['accountRole']>\n siteRole: ComputedRef<SessionState['siteRole']>\n lang: ComputedRef<SessionState['lang']>\n theme: Ref<null | Theme>\n site: Ref<SiteInfo | null>\n fullSite: Ref<FullSiteInfo | null>\n loginUrl: (redirect?: string, extraParams?: Record<string, string>, immediateRedirect?: true) => string\n login: (redirect?: string, extraParams?: Record<string, string>, immediateRedirect?: true) => void\n logout: (redirect?: string) => Promise<void>\n switchOrganization: (org: string | null, dep?: string, role?: string, updateState?: boolean) => void\n setAdminMode: (adminMode: boolean, redirect?: string) => Promise<void>\n asAdmin: (user: any | null) => Promise<void>\n cancelDeletion: () => Promise<void>\n keepalive: () => Promise<void>\n refreshSiteInfo: () => Promise<void>\n switchTheme: (value: Theme) => void\n switchLang: (value: string) => void\n topLocation: Ref<Location | undefined>\n options: SessionOptions\n}\n\nexport type SessionAuthenticated = Omit<Session, 'state' | 'user' | 'account' | 'accountRole'> & {\n state: SessionStateAuthenticated\n user: ComputedRef<SessionStateAuthenticated['user']>\n account: ComputedRef<SessionStateAuthenticated['account']>\n accountRole: ComputedRef<SessionStateAuthenticated['accountRole']>\n}\n\nconst debug = Debug('session')\ndebug.log = console.log.bind(console)\n\n// loose shape: hosts whose Colors are partially optional (e.g. portal config) can pass their own type\nexport type ThemeOffers = {\n theme: {\n dark?: boolean\n hc?: boolean\n hcDark?: boolean\n }\n}\n\n/**\n * Resolves a user theme preference to a concrete AppliedTheme — returns the explicit choice when set,\n * otherwise picks the best variant offered by `site` based on the OS `prefers-color-scheme` / `forced-colors`\n * media queries. Always call this before handing a theme name to Vuetify: its built-in `'system'` defaultTheme\n * bypasses custom themes and falls back to its own light/dark.\n */\nexport function resolveTheme (userTheme: Theme | null, site: ThemeOffers): AppliedTheme {\n // honor an explicit choice only while `site` still offers it; otherwise fall through to\n // the OS-preference resolution below (a theme disabled after selection must not stick)\n if (userTheme === 'default') return 'default'\n if (userTheme === 'dark' && site.theme.dark) return 'dark'\n if (userTheme === 'hc' && site.theme.hc) return 'hc'\n if (userTheme === 'hc-dark' && site.theme.hcDark) return 'hc-dark'\n\n // see https://www.scottohara.me/blog/2021/10/01/detect-high-contrast-and-dark-modes.html\n const preferDark = typeof window !== 'undefined' && window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n const preferHC = typeof window !== 'undefined' && window.matchMedia && window.matchMedia('(forced-colors: active)').matches\n if (site.theme.hcDark && preferDark && preferHC) return 'hc-dark'\n if (site.theme.hc && preferHC) return 'hc'\n if (site.theme.dark && preferDark) return 'dark'\n return 'default'\n}\n\nfunction jwtDecodeAlive (jwt: string | null): User | undefined {\n if (!jwt) return\n const decoded = jwtDecode(jwt) as any\n if (!decoded) return\n const now = Math.ceil(Date.now().valueOf() / 1000)\n if (typeof decoded.exp !== 'undefined' && decoded.exp < now) {\n // token expired\n return\n }\n if (typeof decoded.nbf !== 'undefined' && decoded.nbf > now) {\n console.warn(`token not yet valid: ${decoded.nbf}>${now}, ${JSON.stringify(decoded)}`)\n // do not return here, this is probably a false flag due to a slightly mismatched clock\n }\n return decoded as User\n}\n\nconst getTopLocation = () => {\n try {\n return window.top ? window.top.location : window.location\n } catch (err) {\n return window.location\n }\n}\n\nconst goTo = (url: string | null) => {\n const topLocation = getTopLocation()\n if (topLocation == null) {\n throw new TypeError('session.goTo was called without access to the window object or its location')\n }\n if (url) topLocation.href = url\n else topLocation.reload()\n}\n\nconst defaultOptions = { directoryUrl: '/simple-directory', sitePath: '', defaultLang: 'fr' }\n\nexport async function getSession (initOptions: Partial<SessionOptions>): Promise<Session> {\n const options = { ...defaultOptions, ...initOptions }\n const cookiesPath = options.sitePath + '/'\n debug(`init directoryUrl=${options.directoryUrl}, cookiesPath=${cookiesPath}`)\n const ssr = !!options.req\n if (ssr) debug('run in SSR context')\n\n const customFetch = initOptions?.customFetch ?? ofetch\n\n // use vue-router to detect page change and maintain a reference to the current page location\n // top page if we are in iframe context\n const topLocation = computed(() => {\n if (ssr) return undefined\n\n if (options.route?.fullPath) { /* empty */ } // adds reactivity\n const location = getTopLocation()\n debug('update location based on route change', location)\n return location\n })\n\n // the core state of the session that is filled by reading cookies\n const state = reactive({} as SessionState)\n const fullSite = shallowRef<FullSiteInfo | null>(null)\n const site = shallowRef<SiteInfo | null>(null)\n const theme = ref<Theme | null>(null)\n\n // cookies are the source of truth and this information is transformed into the state reactive object\n const cookies = initOptions?.cookies ?? new Cookies(options.req?.headers.cookie)\n const readState = () => {\n // absent cookie is treated as implicit 'system' so consumers (theme-switcher\n // radios, host plugins) always have a meaningful value to bind to.\n theme.value = (cookies.get('theme') as Theme | undefined) ?? 'system'\n\n const langCookie = cookies.get('i18n_lang')\n state.lang = langCookie ?? options.defaultLang\n\n const idToken = cookies.get('id_token')\n const user = jwtDecodeAlive(idToken)\n\n if (!user) {\n delete state.user\n delete state.organization\n delete state.account\n delete state.accountRole\n return\n }\n\n // this is to prevent null values that are put by SD versions that do not strictly respect their schema\n for (const org of user.organizations) {\n if (!org.department) {\n delete org.department\n delete org.departmentName\n }\n }\n\n state.user = user\n const organizationId = cookies.get('id_token_org')\n const departmentId = cookies.get('id_token_dep')\n const switchedRole = cookies.get('id_token_role')\n if (organizationId) {\n state.organization = state.user.organizations.find(o => {\n if (o.id !== organizationId) return false\n if (departmentId && departmentId !== o.department) return false\n if (switchedRole && switchedRole !== o.role) return false\n return true\n })\n } else {\n delete state.organization\n }\n if (state.organization) {\n state.account = {\n type: 'organization',\n id: state.organization.id,\n name: state.organization.name,\n department: state.organization.department,\n departmentName: state.organization.departmentName\n }\n state.accountRole = state.organization.role\n } else {\n state.account = {\n type: 'user',\n id: state.user.id,\n name: state.user.name\n }\n state.accountRole = 'admin'\n }\n\n if (state.user?.siteOwner) {\n if (state.user.siteOwner.type === 'user' && state.user.siteOwner.id === state.user.id) {\n state.siteRole = 'admin'\n }\n if (state.user.siteOwner.type === 'organization' && state.user.siteOwner.id === state.organization?.id) {\n state.siteRole = state.organization.role\n }\n }\n }\n readState()\n debug('initial state', state)\n\n if (!ssr) {\n // sessionData is also stored in localStorage as a way to access it in simpler pages that do not require use-session\n // and in order to listen to storage event from other contexts and sync session info accross windows and tabs\n const storageListener = (event: StorageEvent) => {\n if (event.key === 'sd-session' + options.sitePath) readState()\n }\n window.addEventListener('storage', storageListener)\n\n // we cannot use onUnmounted here or we get warnings \"onUnmounted is called when there is no active component instance to be associated with. \"\n // TODO: should we have another cleanup mechanism ?\n // onUnmounted(() => { window.removeEventListener('storage', storageListener) })\n\n // trigger some full page refresh when some key session elements are changed\n // the danger of simply using reactivity is too high, data must be re-fetched, etc.\n watch(() => state.account, (account, oldAccount) => {\n if (account?.type !== oldAccount?.type || account?.id !== oldAccount?.id || account?.department !== oldAccount?.department) {\n goTo(null)\n }\n })\n watch(() => state.lang, () => {\n goTo(null)\n })\n watch(() => state.dark, () => {\n goTo(null)\n })\n watch(state, (state) => {\n if (!ssr) {\n window.localStorage.setItem('sd-session' + options.sitePath, JSON.stringify(state))\n }\n debug('state changed', state)\n })\n }\n\n // login can be performed as a simple link (please use target=top) or as a function\n function loginUrl (redirect?: string, extraParams: Record<string, string> = {}, immediateRedirect = true): string {\n // login can also be used to redirect user immediately if he is already logged\n if (redirect && state.user && immediateRedirect) return redirect\n if (!redirect && topLocation.value) redirect = topLocation.value.href\n let url = `${options.directoryUrl}/login?redirect=${encodeURIComponent(redirect ?? '')}`\n Object.keys(extraParams).filter(key => ![null, undefined, ''].includes(extraParams[key])).forEach((key) => {\n url += `&${key}=${encodeURIComponent(extraParams[key])}`\n })\n return url\n }\n const login = (redirect?: string, extraParams: Record<string, string> = {}, immediateRedirect = true) => {\n goTo(loginUrl(redirect, extraParams, immediateRedirect))\n }\n const logout = async (redirect?: string) => {\n const response = await customFetch(`${options.directoryUrl}/api/auth`, { method: 'DELETE' }) as { endSessionUrl?: string } | undefined\n // sometimes server side cookie deletion is not applied immediately in browser local js context\n // so we do it here to\n cookies.remove('id_token')\n cookies.remove('id_token_org')\n cookies.remove('id_token_dep')\n cookies.remove('id_token_role')\n // RP-Initiated Logout: if the server returned an endSessionUrl, redirect to the SSO logout\n if (response?.endSessionUrl) {\n goTo(response.endSessionUrl)\n } else {\n goTo(redirect ?? options.logoutRedirectUrl ?? null)\n }\n }\n\n const switchOrganization = (org: string | null, dep?: string, role?: string, updateState = true) => {\n const cookieOpts = { path: cookiesPath }\n if (org) cookies.set('id_token_org', org, cookieOpts)\n else cookies.remove('id_token_org', cookieOpts)\n if (dep) cookies.set('id_token_dep', dep, cookieOpts)\n else cookies.remove('id_token_dep', cookieOpts)\n if (role) cookies.set('id_token_role', role, cookieOpts)\n else cookies.remove('id_token_role', cookieOpts)\n if (updateState) readState()\n }\n\n const setAdminMode = async (adminMode: boolean, redirect?: string) => {\n if (adminMode) {\n const params: Record<string, string> = { adminMode: 'true' }\n if (state.user != null) params.email = state.user.email\n // preserve current active org/dep\n if (state.organization) {\n params.org = state.organization.id\n if (state.organization.department) params.dep = state.organization.department\n }\n const url = loginUrl(redirect, params, true)\n goTo(url)\n } else {\n await customFetch(`${options.directoryUrl}/api/auth/adminmode`, { method: 'DELETE' })\n goTo(redirect ?? null)\n }\n }\n\n const asAdmin = async (user: any | null) => {\n if (user) {\n await customFetch(`${options.directoryUrl}/api/auth/asadmin`, { method: 'POST', body: user })\n } else {\n await customFetch(`${options.directoryUrl}/api/auth/asadmin`, { method: 'DELETE' })\n }\n goTo(null)\n }\n\n const cancelDeletion = async () => {\n if (state.user == null) return\n await customFetch(`${options.directoryUrl}/api/users/${state.user.id}`, { method: 'PATCH', body: ({ plannedDeletion: null }) as any })\n readState()\n }\n\n const switchLang = (value: string) => {\n const maxAge = 60 * 60 * 24 * 365 // 1 year\n cookies.set('i18n_lang', value, { maxAge, path: cookiesPath })\n goTo(null)\n }\n\n const switchTheme = (value: Theme) => {\n // an absent cookie already means 'system' (see init above), so don't persist it explicitly\n if (value === 'system') {\n cookies.remove('theme', { path: cookiesPath })\n } else {\n const maxAge = 60 * 60 * 24 * 365 // 1 year\n cookies.set('theme', value, { maxAge, path: cookiesPath })\n }\n goTo(null)\n }\n\n const keepalive = async () => {\n // check cookies.get('id_token') not state.user so that we do a keepalive on expired id tokens\n // as we might have an exchange token\n if (!cookies.get('id_token')) return\n if (!ssr) {\n window.localStorage.setItem('sd-keepalive' + options.sitePath, `${new Date().getTime()}`)\n }\n try {\n await customFetch(`${options.directoryUrl}/api/auth/keepalive`, { method: 'POST' })\n } catch (err) {\n if (err instanceof FetchError && err.statusCode === 401) {\n console.warn('session was expired or deleted server side')\n } else {\n throw err\n }\n }\n readState()\n }\n\n const refreshSiteInfo = async () => {\n console.warn('@data-fair/lib-vue/session refreshSiteInfo is deprecated')\n const siteInfo = await customFetch(`${options.directoryUrl}/api/sites/_public`)\n setSiteInfo(siteInfo)\n }\n\n const setSiteInfo = (siteInfo: any) => {\n if (siteInfo.theme) {\n fullSite.value = siteInfo\n const partialSite: SiteInfo = {\n main: siteInfo.main,\n isAccountMain: siteInfo.isAccountMain,\n logo: siteInfo.theme.logo,\n colors: siteInfo.theme.colors,\n authMode: siteInfo.authMode,\n authOnlyOtherSite: siteInfo.authOnlyOtherSite,\n owner: siteInfo.owner\n }\n const applied = resolveTheme(theme.value, siteInfo)\n if (applied === 'hc') partialSite.colors = siteInfo.theme.hcColors\n if (applied === 'dark') {\n partialSite.colors = siteInfo.theme.darkColors\n partialSite.dark = true\n }\n if (applied === 'hc-dark') {\n partialSite.colors = siteInfo.theme.hcDarkColors\n partialSite.dark = true\n }\n site.value = partialSite\n } else {\n site.value = siteInfo\n }\n }\n\n if (options.siteInfo) await refreshSiteInfo()\n\n // @ts-ignore\n if (!ssr && window.__PUBLIC_SITE_INFO) setSiteInfo(window.__PUBLIC_SITE_INFO)\n\n // re-apply the theme when the OS preference changes while the user is on\n // 'system'. Important for mobile devices that switch light/dark over the day.\n if (!ssr && typeof window !== 'undefined' && window.matchMedia) {\n const onOsPrefChange = () => {\n if (theme.value === 'system' && fullSite.value) setSiteInfo(fullSite.value)\n }\n window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', onOsPrefChange)\n window.matchMedia('(forced-colors: active)').addEventListener('change', onOsPrefChange)\n }\n\n // immediately performs a keepalive, but only on top windows (not iframes or popups)\n // and only if it was not done very recently (maybe from a refreshed page next to this one)\n // also run an auto-refresh loop\n if (!ssr && !inIframe && !('triggerCapture' in window)) {\n const lastKeepalive = window.localStorage.getItem('sd-keepalive' + options.sitePath)\n\n if (!lastKeepalive || (new Date().getTime() - Number(lastKeepalive)) > 10000) {\n await keepalive()\n }\n\n const refreshLoopDelay = 10 * 60 * 1000 // 10 minutes\n setInterval(() => {\n const lastKeepalive = window.localStorage.getItem('sd-keepalive' + options.sitePath)\n if (!lastKeepalive || (new Date().getTime() - Number(lastKeepalive)) > refreshLoopDelay / 2) {\n keepalive().catch(err => console.error(err))\n }\n }, refreshLoopDelay)\n }\n\n const session: Session = {\n state,\n organization: computed(() => state.organization),\n user: computed(() => state.user),\n account: computed(() => state.account),\n accountRole: computed(() => state.accountRole),\n siteRole: computed(() => state.siteRole),\n lang: computed(() => state.lang),\n theme: readonly(theme),\n site: shallowReadonly(site),\n fullSite: shallowReadonly(fullSite),\n loginUrl,\n login,\n logout,\n switchOrganization,\n setAdminMode,\n asAdmin,\n cancelDeletion,\n keepalive,\n refreshSiteInfo,\n switchTheme,\n switchLang,\n topLocation,\n options\n }\n\n return session\n}\n\n// uses pattern for SSR friendly plugin/composable, cf https://antfu.me/posts/composable-vue-vueday-2021#shared-state-ssr-friendly\nexport const sessionKey = Symbol('session')\nexport async function createSession (initOptions: Partial<SessionOptions>) {\n const session = await getSession(initOptions)\n return {\n ...session,\n install (app: App) { app.provide(sessionKey, session) },\n }\n}\nexport function useSession () {\n const session = inject(sessionKey)\n if (!session) throw new Error('useSession requires using the plugin createSession')\n return session as Session\n}\nexport function useSessionAuthenticated (errorBuilder?: () => any) {\n const session = useSession()\n if (!session.state.user) {\n if (errorBuilder) throw errorBuilder()\n else throw new Error('useSessionAuthenticated requires a logged in user')\n }\n return session as SessionAuthenticated\n}\n\nexport default useSession\n"]}