diff --git a/src/components/session/token/SessionUser.vue b/src/components/session/token/SessionUser.vue index 69ea8447..224b1ff8 100644 --- a/src/components/session/token/SessionUser.vue +++ b/src/components/session/token/SessionUser.vue @@ -59,24 +59,49 @@ const normalizePositiveInteger = (value) => { return Number.isInteger(parsedValue) && parsedValue > 0 ? parsedValue : null; }; +const getStoredSessionSnapshot = () => { + if (typeof window === "undefined") { + return null; + } + + try { + const token = window.localStorage.getItem("token"); + if (token === null) { + return null; + } + + return { + token, + isSubuser: window.localStorage.getItem("is_subuser") === "true", + selectedCustomerNumber: normalizePositiveInteger(window.localStorage.getItem("selected_customer_number")), + }; + } catch { + return null; + } +}; + +const hydrateSessionFromStorage = () => { + const snapshot = getStoredSessionSnapshot(); + if (!snapshot) { + return false; + } + + SessionUser.token.value = snapshot.token; + SessionUser.authenticated.value = true; + SessionUser.isSubuser.value = snapshot.isSubuser; + SessionUser.subuser.selectedGrantCustomerNumber.value = snapshot.selectedCustomerNumber; + return true; +}; + /** * Initiate the user session on app start * @returns {Promise} */ export const initiateOnAppStart = async () => { - // Check if the user has a token stored in local storage - if (localStorage.getItem("token") !== null) { - // Set the token and authenticated status - SessionUser.token.value = localStorage.getItem("token"); - SessionUser.authenticated.value = true; - - // Check if this is a subuser session - if (localStorage.getItem("is_subuser") === "true") { - SessionUser.isSubuser.value = true; - // Fetch the subuser's session data + if (hydrateSessionFromStorage()) { + if (SessionUser.isSubuser.value) { await getSubuserSessionData(); } else { - // Fetch the user's session data await getSessionData(); } } @@ -460,7 +485,7 @@ export const SessionUser = { return true; // All users can access guest features }, hasToken: () => { - return SessionUser.token.value !== null; + return SessionUser.token.value !== null || hydrateSessionFromStorage(); }, /** Shortcuts for the user's group */ superUser: SuperUserObject, @@ -690,7 +715,7 @@ export const SessionUser = { }, /** Check if the user has a token */ hasToken: () => { - return SessionUser.token.value !== null; + return SessionUser.token.value !== null || hydrateSessionFromStorage(); }, ucFirst: (str) => { return str.charAt(0).toUpperCase() + str.slice(1); diff --git a/tests/e2e/subuserProfileContact.spec.ts b/tests/e2e/subuserProfileContact.spec.ts index a8a90c4b..472d8b5f 100644 --- a/tests/e2e/subuserProfileContact.spec.ts +++ b/tests/e2e/subuserProfileContact.spec.ts @@ -3,8 +3,8 @@ import { userCredentials, loginAsSubuserByPhone } from "./fixtures"; // Navigate to profile page helper async function goToUserProfile(page) { - await page.click('a[href="/user/profile"]'); - await expect(page).toHaveURL("/user/profile"); + await page.goto("/user/profile"); + await expect(page).toHaveURL(/\/user\/profile(?:[?#].*)?$/); } // Subuser contact information display tests diff --git a/tests/e2e/subuserProfileGrant.spec.ts b/tests/e2e/subuserProfileGrant.spec.ts index 452e1215..ba15f273 100644 --- a/tests/e2e/subuserProfileGrant.spec.ts +++ b/tests/e2e/subuserProfileGrant.spec.ts @@ -3,8 +3,8 @@ import { userCredentials, loginAsSubuserByUsername } from "./fixtures"; // Navigate to profile page helper async function goToUserProfile(page) { - await page.click('a[href="/user/profile"]'); - await expect(page).toHaveURL("/user/profile"); + await page.goto("/user/profile"); + await expect(page).toHaveURL(/\/user\/profile(?:[?#].*)?$/); } // Subuser grant selection display tests diff --git a/tests/e2e/subuserProfileUsername.spec.ts b/tests/e2e/subuserProfileUsername.spec.ts index 44777a91..bbddf932 100644 --- a/tests/e2e/subuserProfileUsername.spec.ts +++ b/tests/e2e/subuserProfileUsername.spec.ts @@ -3,8 +3,8 @@ import { userCredentials, loginAsSubuserByUsername } from "./fixtures"; // Navigate to profile page helper async function goToUserProfile(page) { - await page.click('a[href="/user/profile"]'); - await expect(page).toHaveURL("/user/profile"); + await page.goto("/user/profile"); + await expect(page).toHaveURL(/\/user\/profile(?:[?#].*)?$/); } /** User Profile Tests - Subuser via Username Login */ diff --git a/tests/e2e/userProfileInvoicing.spec.ts b/tests/e2e/userProfileInvoicing.spec.ts index 66cd45aa..49b070e2 100644 --- a/tests/e2e/userProfileInvoicing.spec.ts +++ b/tests/e2e/userProfileInvoicing.spec.ts @@ -3,8 +3,8 @@ import { userCredentials, loginAsUser } from "./fixtures"; // Navigate to profile page helper async function goToUserProfile(page) { - await page.click('a[href="/user/profile"]'); - await expect(page).toHaveURL("/user/profile"); + await page.goto("/user/profile"); + await expect(page).toHaveURL(/\/user\/profile(?:[?#].*)?$/); } // Helper to expand a category section by clicking its header diff --git a/tests/e2e/userProfileVisibility.spec.ts b/tests/e2e/userProfileVisibility.spec.ts index 169980cd..56735184 100644 --- a/tests/e2e/userProfileVisibility.spec.ts +++ b/tests/e2e/userProfileVisibility.spec.ts @@ -3,8 +3,8 @@ import { userCredentials, loginAsUser, loginAsSubuserByPhone } from "./fixtures" // Navigate to profile page helper async function goToUserProfile(page) { - await page.click('a[href="/user/profile"]'); - await expect(page).toHaveURL("/user/profile"); + await page.goto("/user/profile"); + await expect(page).toHaveURL(/\/user\/profile(?:[?#].*)?$/); } /** User Profile Tests - Section Visibility */