mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-10 13:22:14 +00:00
revert(settings): restore the flat settings navigation
Revert the nine-group consolidation and the card relocations back to the flat sidebar: sessions, trusted devices, and login activity return to Privacy, and account deletion returns inline under Advanced. Drop the /settings/layout redirect and the now-unused group and sign-in cross-link i18n keys across all six locales. Keep the collapse-by-default sessions and activity cards, the medical-history cross-link from "About me", and the chronic-conditions consolidation.
This commit is contained in:
1 parent
7bd26ff2bd
commit
f564cdeef7
19 files changed
+518
-1133
No files matched your search
@@ -1,70 +0,0 @@
|
||||
/**
|
||||
* v1.25.1 (H1) — sign-in management consolidation.
|
||||
*
|
||||
* Active sessions, trusted devices, and the login-activity feed moved out of
|
||||
* the Data & Privacy group into Account → Security so every "who can sign in as
|
||||
* me" control sits in one place. This SSR test pins that the three cards render
|
||||
* inside `<SecuritySection>`.
|
||||
*/
|
||||
import { describe, it, expect, vi } from "vitest";
|
||||
import { renderToStaticMarkup } from "react-dom/server";
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
|
||||
vi.mock("@/hooks/use-auth", () => ({
|
||||
useAuth: () => ({ isAuthenticated: true, isLoading: false }),
|
||||
}));
|
||||
|
||||
import { I18nProvider } from "@/lib/i18n/context";
|
||||
import { queryKeys } from "@/lib/query-keys";
|
||||
import { SecuritySection } from "../index";
|
||||
|
||||
function render() {
|
||||
const client = new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
retry: false,
|
||||
staleTime: Number.POSITIVE_INFINITY,
|
||||
refetchOnMount: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
// Seed the MFA status so the second-factor cards paint instead of skeletons.
|
||||
client.setQueryData(queryKeys.mfaStatus(), {
|
||||
totp: { enabled: false },
|
||||
recoveryCodesRemaining: 0,
|
||||
webauthn: [],
|
||||
passkeyNudgeDismissed: true,
|
||||
});
|
||||
client.setQueryData(queryKeys.passkeys(), []);
|
||||
// Seed the embedded sign-in reads so the cards paint without firing network.
|
||||
client.setQueryData(queryKeys.sessions(), { sessions: [] });
|
||||
client.setQueryData(queryKeys.securityActivity(), { events: [] });
|
||||
client.setQueryData(queryKeys.trustedDevices(), {
|
||||
devices: [
|
||||
{
|
||||
id: "td-1",
|
||||
label: "Firefox on macOS",
|
||||
isCurrent: true,
|
||||
createdAt: "2099-01-01T00:00:00.000Z",
|
||||
lastUsedAt: "2099-01-01T00:00:00.000Z",
|
||||
expiresAt: "2099-01-01T00:00:00.000Z",
|
||||
},
|
||||
],
|
||||
});
|
||||
return renderToStaticMarkup(
|
||||
<I18nProvider initialLocale="en">
|
||||
<QueryClientProvider client={client}>
|
||||
<SecuritySection />
|
||||
</QueryClientProvider>
|
||||
</I18nProvider>,
|
||||
);
|
||||
}
|
||||
|
||||
describe("<SecuritySection> — sign-in management home (H1)", () => {
|
||||
it("renders the active-session, trusted-device, and security-activity cards", () => {
|
||||
const html = render();
|
||||
expect(html).toContain('data-slot="settings-security-sessions-card"');
|
||||
expect(html).toContain('data-slot="settings-trusted-devices-card"');
|
||||
expect(html).toContain('data-slot="settings-security-activity-card"');
|
||||
});
|
||||
});
|
||||
@@ -10,14 +10,6 @@ import { TotpCard } from "./totp-card";
|
||||
import { SecurityKeysCard, type WebauthnKeyInfo } from "./security-keys-card";
|
||||
import { PasskeyListSection } from "./passkey-list-section";
|
||||
import { PasskeyUpgradeNudge } from "./passkey-upgrade-nudge";
|
||||
// v1.25.1 (H1) — active sessions, trusted devices, and the login-activity feed
|
||||
// are "who/what can sign in as me" — the same mental model as the second-factor
|
||||
// and passkey controls above. They used to live in the Data & Privacy group
|
||||
// (split across two top-level groups); they now sit here in Account → Security
|
||||
// as the single sign-in-management home.
|
||||
import { SecuritySessionsCard } from "@/components/settings/security-sessions-card";
|
||||
import { TrustedDevicesCard } from "@/components/settings/trusted-devices-card";
|
||||
import { SecurityActivityCard } from "@/components/settings/security-activity-card";
|
||||
|
||||
interface MfaStatus {
|
||||
totp: { enabled: boolean };
|
||||
@@ -53,40 +45,28 @@ export function SecuritySection() {
|
||||
passkeys != null &&
|
||||
passkeys.length === 0;
|
||||
|
||||
// The second-factor / passkey cards depend on the MFA status payload, so they
|
||||
// skeleton while it loads. The session / device / activity cards own their own
|
||||
// reads and loading states, so they render unconditionally below — a slow or
|
||||
// failed `/api/auth/me/mfa` must never hide active-session revocation.
|
||||
const mfaCards =
|
||||
isLoading || !status ? (
|
||||
<>
|
||||
if (isLoading || !status) {
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<Skeleton className="h-40 w-full rounded-xl" />
|
||||
<Skeleton className="h-40 w-full rounded-xl" />
|
||||
<Skeleton className="h-40 w-full rounded-xl" />
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{showNudge && <PasskeyUpgradeNudge />}
|
||||
|
||||
<TotpCard
|
||||
enabled={status.totp.enabled}
|
||||
recoveryCodesRemaining={status.recoveryCodesRemaining}
|
||||
/>
|
||||
|
||||
<SecurityKeysCard keys={status.webauthn} />
|
||||
|
||||
<PasskeyListSection isAuthenticated={isAuthenticated} />
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
{mfaCards}
|
||||
{showNudge && <PasskeyUpgradeNudge />}
|
||||
|
||||
{/* v1.25.1 (H1) — sign-in management consolidated here. */}
|
||||
<SecuritySessionsCard isAuthenticated={isAuthenticated} />
|
||||
<TrustedDevicesCard isAuthenticated={isAuthenticated} />
|
||||
<SecurityActivityCard isAuthenticated={isAuthenticated} />
|
||||
<TotpCard
|
||||
enabled={status.totp.enabled}
|
||||
recoveryCodesRemaining={status.recoveryCodesRemaining}
|
||||
/>
|
||||
|
||||
<SecurityKeysCard keys={status.webauthn} />
|
||||
|
||||
<PasskeyListSection isAuthenticated={isAuthenticated} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user