mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-13 22:32:04 +00:00
fix(onboarding): scope tour-launcher sessionStorage keys by user id (v1.4.15 H4)
Both `healthlog-tour-session-dismissed` and `healthlog-tour-referrer`
were un-scoped global keys, so a browser shared by two HealthLog
identities (admin impersonating a target user, family laptop, etc.)
inherited the first user's "tour dismissed for this session" flag —
the second user logged in and silently never saw the spotlight tour.
Both keys are now suffixed with `:${userId}`, so each identity's
state stays independent. The two builders (`tourSessionDismissedKey`
and `tourReferrerKey`) are exported so the wizard's `persistAndExit`
shares the same wire format and a unit test pins the scheme against
future drift.
One-off cost: every currently-open tab re-fires the tour once on the
next load because the legacy un-prefixed keys are no longer read.
Acceptable tax for multi-tenant correctness ahead of v1.5.
This commit is contained in:
1 parent
7f1a4ded25
commit
2afe3c47ce
3 files changed
+109
-34
No files matched your search
@@ -19,6 +19,8 @@ import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Logo } from "@/components/ui/logo";
|
||||
import { MeasurementForm } from "@/components/measurements/measurement-form";
|
||||
import { tourReferrerKey } from "@/components/onboarding/tour-launcher";
|
||||
import { useAuth } from "@/hooks/use-auth";
|
||||
import { useTranslations } from "@/lib/i18n/context";
|
||||
import { locales, localeLabels, type Locale } from "@/lib/i18n/config";
|
||||
import { cn } from "@/lib/utils";
|
||||
@@ -74,6 +76,7 @@ export default function OnboardingPage() {
|
||||
const router = useRouter();
|
||||
const queryClient = useQueryClient();
|
||||
const { t, locale, setLocale } = useTranslations();
|
||||
const { user } = useAuth();
|
||||
|
||||
const [step, setStep] = useState<1 | 2 | 3>(1);
|
||||
const [saving, setSaving] = useState(false);
|
||||
@@ -129,10 +132,19 @@ export default function OnboardingPage() {
|
||||
// render-phase decision can stay pure under
|
||||
// `react-hooks/purity` — the launcher consumes-and-clears the
|
||||
// key on first read.
|
||||
try {
|
||||
window.sessionStorage.setItem("healthlog-tour-referrer", "1");
|
||||
} catch {
|
||||
/* ignore — storage disabled or full */
|
||||
//
|
||||
// v1.4.15 H4: key is scoped by user id so a shared browser
|
||||
// (admin impersonation, family laptop) keeps each user's
|
||||
// wizard-referrer state independent. Skip the write entirely
|
||||
// if the auth payload hasn't loaded — the worst-case is the
|
||||
// tour pops up immediately instead of after the 1.5s grace
|
||||
// window, which is harmless.
|
||||
if (user?.id) {
|
||||
try {
|
||||
window.sessionStorage.setItem(tourReferrerKey(user.id), "1");
|
||||
} catch {
|
||||
/* ignore — storage disabled or full */
|
||||
}
|
||||
}
|
||||
|
||||
if (opts?.gotoSettingsHash) {
|
||||
|
||||
Reference in new issue
Block a user