@data-fair/lib-vue 1.28.1 → 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.28.1",
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.d.ts CHANGED
@@ -44,16 +44,16 @@ export interface Colors {
44
44
  admin: string;
45
45
  'on-admin': string;
46
46
  }
47
- interface FullSiteInfo {
47
+ export interface FullSiteInfo {
48
48
  main?: boolean;
49
49
  theme: {
50
50
  logo?: string;
51
51
  colors: Colors;
52
- dark: boolean;
52
+ dark?: boolean;
53
53
  darkColors?: Colors;
54
- hc: boolean;
54
+ hc?: boolean;
55
55
  hcColors?: Colors;
56
- hcDark: boolean;
56
+ hcDark?: boolean;
57
57
  hcDarkColors?: Colors;
58
58
  };
59
59
  }
@@ -67,7 +67,8 @@ export interface SiteInfo {
67
67
  colors: Colors;
68
68
  owner: AccountKeys;
69
69
  }
70
- type Theme = 'default' | 'dark' | 'hc' | 'hc-dark';
70
+ export type AppliedTheme = 'default' | 'dark' | 'hc' | 'hc-dark';
71
+ export type Theme = AppliedTheme | 'system';
71
72
  export interface Session {
72
73
  state: SessionState;
73
74
  user: ComputedRef<SessionState['user']>;
@@ -99,6 +100,20 @@ export type SessionAuthenticated = Omit<Session, 'state' | 'user' | 'account' |
99
100
  account: ComputedRef<SessionStateAuthenticated['account']>;
100
101
  accountRole: ComputedRef<SessionStateAuthenticated['accountRole']>;
101
102
  };
103
+ export type ThemeOffers = {
104
+ theme: {
105
+ dark?: boolean;
106
+ hc?: boolean;
107
+ hcDark?: boolean;
108
+ };
109
+ };
110
+ /**
111
+ * Resolves a user theme preference to a concrete AppliedTheme — returns the explicit choice when set,
112
+ * otherwise picks the best variant offered by `site` based on the OS `prefers-color-scheme` / `forced-colors`
113
+ * media queries. Always call this before handing a theme name to Vuetify: its built-in `'system'` defaultTheme
114
+ * bypasses custom themes and falls back to its own light/dark.
115
+ */
116
+ export declare function resolveTheme(userTheme: Theme | null, site: ThemeOffers): AppliedTheme;
102
117
  export declare function getSession(initOptions: Partial<SessionOptions>): Promise<Session>;
103
118
  export declare const sessionKey: unique symbol;
104
119
  export declare function createSession(initOptions: Partial<SessionOptions>): Promise<{
package/session.js CHANGED
@@ -10,10 +10,26 @@ export * from '@data-fair/lib-common-types/session/index.js';
10
10
  const Cookies = cookiesModule;
11
11
  const debug = Debug('session');
12
12
  debug.log = console.log.bind(console);
13
- function getDefaultTheme(site) {
13
+ /**
14
+ * Resolves a user theme preference to a concrete AppliedTheme — returns the explicit choice when set,
15
+ * otherwise picks the best variant offered by `site` based on the OS `prefers-color-scheme` / `forced-colors`
16
+ * media queries. Always call this before handing a theme name to Vuetify: its built-in `'system'` defaultTheme
17
+ * bypasses custom themes and falls back to its own light/dark.
18
+ */
19
+ export function resolveTheme(userTheme, site) {
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';
14
30
  // see https://www.scottohara.me/blog/2021/10/01/detect-high-contrast-and-dark-modes.html
15
- const preferDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
16
- const preferHC = window.matchMedia && window.matchMedia('(forced-colors: active)').matches;
31
+ const preferDark = typeof window !== 'undefined' && window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
32
+ const preferHC = typeof window !== 'undefined' && window.matchMedia && window.matchMedia('(forced-colors: active)').matches;
17
33
  if (site.theme.hcDark && preferDark && preferHC)
18
34
  return 'hc-dark';
19
35
  if (site.theme.hc && preferHC)
@@ -84,7 +100,9 @@ export async function getSession(initOptions) {
84
100
  // cookies are the source of truth and this information is transformed into the state reactive object
85
101
  const cookies = initOptions?.cookies ?? new Cookies(options.req?.headers.cookie);
86
102
  const readState = () => {
87
- theme.value = cookies.get('theme') ?? null;
103
+ // absent cookie is treated as implicit 'system' so consumers (theme-switcher
104
+ // radios, host plugins) always have a meaningful value to bind to.
105
+ theme.value = cookies.get('theme') ?? 'system';
88
106
  const langCookie = cookies.get('i18n_lang');
89
107
  state.lang = langCookie ?? options.defaultLang;
90
108
  const idToken = cookies.get('id_token');
@@ -198,14 +216,20 @@ export async function getSession(initOptions) {
198
216
  goTo(loginUrl(redirect, extraParams, immediateRedirect));
199
217
  };
200
218
  const logout = async (redirect) => {
201
- await customFetch(`${options.directoryUrl}/api/auth`, { method: 'DELETE' });
219
+ const response = await customFetch(`${options.directoryUrl}/api/auth`, { method: 'DELETE' });
202
220
  // sometimes server side cookie deletion is not applied immediately in browser local js context
203
221
  // so we do it here to
204
222
  cookies.remove('id_token');
205
223
  cookies.remove('id_token_org');
206
224
  cookies.remove('id_token_dep');
207
225
  cookies.remove('id_token_role');
208
- goTo(redirect ?? options.logoutRedirectUrl ?? null);
226
+ // RP-Initiated Logout: if the server returned an endSessionUrl, redirect to the SSO logout
227
+ if (response?.endSessionUrl) {
228
+ goTo(response.endSessionUrl);
229
+ }
230
+ else {
231
+ goTo(redirect ?? options.logoutRedirectUrl ?? null);
232
+ }
209
233
  };
210
234
  const switchOrganization = (org, dep, role, updateState = true) => {
211
235
  const cookieOpts = { path: cookiesPath };
@@ -264,8 +288,14 @@ export async function getSession(initOptions) {
264
288
  goTo(null);
265
289
  };
266
290
  const switchTheme = (value) => {
267
- const maxAge = 60 * 60 * 24 * 365; // 1 year
268
- 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
+ }
269
299
  goTo(null);
270
300
  };
271
301
  const keepalive = async () => {
@@ -306,15 +336,14 @@ export async function getSession(initOptions) {
306
336
  authOnlyOtherSite: siteInfo.authOnlyOtherSite,
307
337
  owner: siteInfo.owner
308
338
  };
309
- if (theme.value == null)
310
- theme.value = getDefaultTheme(siteInfo);
311
- if (theme.value === 'hc')
339
+ const applied = resolveTheme(theme.value, siteInfo);
340
+ if (applied === 'hc')
312
341
  partialSite.colors = siteInfo.theme.hcColors;
313
- if (theme.value === 'dark') {
342
+ if (applied === 'dark') {
314
343
  partialSite.colors = siteInfo.theme.darkColors;
315
344
  partialSite.dark = true;
316
345
  }
317
- if (theme.value === 'hc-dark') {
346
+ if (applied === 'hc-dark') {
318
347
  partialSite.colors = siteInfo.theme.hcDarkColors;
319
348
  partialSite.dark = true;
320
349
  }
@@ -329,6 +358,16 @@ export async function getSession(initOptions) {
329
358
  // @ts-ignore
330
359
  if (!ssr && window.__PUBLIC_SITE_INFO)
331
360
  setSiteInfo(window.__PUBLIC_SITE_INFO);
361
+ // re-apply the theme when the OS preference changes while the user is on
362
+ // 'system'. Important for mobile devices that switch light/dark over the day.
363
+ if (!ssr && typeof window !== 'undefined' && window.matchMedia) {
364
+ const onOsPrefChange = () => {
365
+ if (theme.value === 'system' && fullSite.value)
366
+ setSiteInfo(fullSite.value);
367
+ };
368
+ window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', onOsPrefChange);
369
+ window.matchMedia('(forced-colors: active)').addEventListener('change', onOsPrefChange);
370
+ }
332
371
  // immediately performs a keepalive, but only on top windows (not iframes or popups)
333
372
  // and only if it was not done very recently (maybe from a refreshed page next to this one)
334
373
  // also run an auto-refresh loop
package/session.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"session.js","sourceRoot":"","sources":["session.ts"],"names":[],"mappings":"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","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\ninterface 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\ntype Theme = 'default' | 'dark' | 'hc' | 'hc-dark'\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\nfunction getDefaultTheme (site: FullSiteInfo): Theme {\n // see https://www.scottohara.me/blog/2021/10/01/detect-high-contrast-and-dark-modes.html\n const preferDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n const preferHC = 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 theme.value = cookies.get('theme') ?? null\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 await customFetch(`${options.directoryUrl}/api/auth`, { method: 'DELETE' })\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 goTo(redirect ?? options.logoutRedirectUrl ?? null)\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 if (theme.value == null) theme.value = getDefaultTheme(siteInfo)\n if (theme.value === 'hc') partialSite.colors = siteInfo.theme.hcColors\n if (theme.value === 'dark') {\n partialSite.colors = siteInfo.theme.darkColors\n partialSite.dark = true\n }\n if (theme.value === '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 // 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":"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","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"]}