mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-09-06 12:25:02 +00:00
fix(backoffice): stop sharing the position cookie with Smart Office
Both apps wrote a cookie named `current-position-id` but stored different ids in it — freight the `employeePositionId`, Smart Office the `position.id`. On a shared domain each login overwrote the other's desk selection, and the loser silently fell back to the first position. Freight now uses `freight-current-position-id` through a small helper that reads the old name once, so a session live across the deploy keeps its desk, and clears it on every write. Also mounts the position switcher in the freight dashboard header. It only existed under /performance-management, so on every other page a two-desk user had no way to switch and was stuck on whatever `useAuthUser` defaulted to. It now hides below two positions rather than showing a one-option dropdown to the single-desk majority. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -30,6 +30,10 @@ import {
|
||||
persistRememberMePreference,
|
||||
setAuthCookies,
|
||||
} from "@/shared/utils/authPersistence";
|
||||
import {
|
||||
getPositionCookie,
|
||||
setPositionCookie,
|
||||
} from "@/shared/utils/positionCookie";
|
||||
import { clearComplaintVerification } from "@/complaints/utils/complaintVerificationStorage";
|
||||
|
||||
interface LoginPayload {
|
||||
@@ -46,7 +50,7 @@ export const useAuthUser = () => {
|
||||
const { t } = useTranslation();
|
||||
const { handleError } = useErrorHandler(t);
|
||||
const delegatedPositionId = Cookies.get("delegatedPositionId");
|
||||
const currentPositionId = Cookies.get("current-position-id");
|
||||
const currentPositionId = getPositionCookie();
|
||||
|
||||
const {
|
||||
setUser,
|
||||
@@ -96,7 +100,7 @@ export const useAuthUser = () => {
|
||||
userDetails.employee?.[0]?.positions?.[0]?.employeePositionId;
|
||||
if (firstPositionId) {
|
||||
setSelectedPositionId(firstPositionId);
|
||||
Cookies.set("current-position-id", firstPositionId, cookieOptions);
|
||||
setPositionCookie(firstPositionId, cookieOptions);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +145,7 @@ export const useAuthUser = () => {
|
||||
|
||||
if (fallbackId) {
|
||||
setSelectedPositionId(fallbackId);
|
||||
Cookies.set("current-position-id", fallbackId);
|
||||
setPositionCookie(fallbackId);
|
||||
}
|
||||
} else if (selectedPositionId) {
|
||||
// Self-heal stale cookies that were set to position.id instead of
|
||||
@@ -157,10 +161,7 @@ export const useAuthUser = () => {
|
||||
|
||||
if (matchingPosition?.employeePositionId) {
|
||||
setSelectedPositionId(matchingPosition.employeePositionId);
|
||||
Cookies.set(
|
||||
"current-position-id",
|
||||
matchingPosition.employeePositionId,
|
||||
);
|
||||
setPositionCookie(matchingPosition.employeePositionId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
getAuthCookieOptions,
|
||||
setAuthCookies,
|
||||
} from "@/shared/utils/authPersistence";
|
||||
import { setPositionCookie } from "@/shared/utils/positionCookie";
|
||||
import type { VerifiedCitizen } from "@/complaints/types/complaint.types";
|
||||
|
||||
function unwrapApiData<T>(payload: T | { data?: T }): T {
|
||||
@@ -138,7 +139,7 @@ export async function persistFaydaRegistrationAuth(
|
||||
const firstPositionId =
|
||||
userDetails.employee?.[0]?.positions?.[0]?.employeePositionId;
|
||||
if (firstPositionId) {
|
||||
Cookies.set("current-position-id", firstPositionId, cookieOptions);
|
||||
setPositionCookie(firstPositionId, cookieOptions);
|
||||
}
|
||||
|
||||
return userDetails;
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
import Cookies from "js-cookie";
|
||||
|
||||
type CookieOptions = NonNullable<Parameters<typeof Cookies.set>[2]>;
|
||||
|
||||
/**
|
||||
* Freight's own active-position cookie.
|
||||
*
|
||||
* Smart Office is a separate app on the same IAM and it also writes a cookie
|
||||
* named `current-position-id` — but it stores `position.id` where freight
|
||||
* stores `employeePositionId`. The two are not interchangeable, so on a shared
|
||||
* domain each app's login silently overwrote the other's desk selection and the
|
||||
* loser fell back to `positions[0]`. Freight keeps its own cookie name so both
|
||||
* can hold a selection at once.
|
||||
*/
|
||||
export const POSITION_COOKIE = "freight-current-position-id";
|
||||
|
||||
/**
|
||||
* The pre-rename, shared-with-Smart-Office name. Still read so a session that
|
||||
* is live across the deploy keeps its desk, and cleared on every write so the
|
||||
* colliding cookie does not linger.
|
||||
*/
|
||||
const LEGACY_POSITION_COOKIE = "current-position-id";
|
||||
|
||||
/** The active `employeePositionId`, or undefined when no desk is selected. */
|
||||
export const getPositionCookie = (): string | undefined =>
|
||||
Cookies.get(POSITION_COOKIE) ?? Cookies.get(LEGACY_POSITION_COOKIE);
|
||||
|
||||
export const setPositionCookie = (
|
||||
value: string,
|
||||
options?: CookieOptions,
|
||||
): void => {
|
||||
Cookies.set(POSITION_COOKIE, value, options);
|
||||
Cookies.remove(LEGACY_POSITION_COOKIE);
|
||||
};
|
||||
|
||||
export const clearPositionCookie = (): void => {
|
||||
Cookies.remove(POSITION_COOKIE);
|
||||
Cookies.remove(LEGACY_POSITION_COOKIE);
|
||||
};
|
||||
Reference in New Issue
Block a user