v0.16.1 — Fix forced-password-change re-firing every visit
The dashboard gate trusted session.user.mustChangePassword from the JWT, which is only refreshed on re-login/update() — so after a user set a new password the stale cookie kept bouncing them back to /change-password. Read the flag from the DB (the source of truth) so it clears immediately and never re-fires. Cheap for a 2-user app; also re-checks the account is still active. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
import { redirect } from "next/navigation";
|
import { redirect } from "next/navigation";
|
||||||
import { getSession } from "@/lib/auth";
|
import { getSession } from "@/lib/auth";
|
||||||
|
import { db } from "@/lib/db";
|
||||||
import { Sidebar } from "@/components/layout/sidebar";
|
import { Sidebar } from "@/components/layout/sidebar";
|
||||||
import { TopNav } from "@/components/layout/topnav";
|
import { TopNav } from "@/components/layout/topnav";
|
||||||
import { Footer } from "@/components/layout/footer";
|
import { Footer } from "@/components/layout/footer";
|
||||||
@@ -7,10 +8,18 @@ import { Footer } from "@/components/layout/footer";
|
|||||||
export default async function DashboardLayout({ children }: { children: React.ReactNode }) {
|
export default async function DashboardLayout({ children }: { children: React.ReactNode }) {
|
||||||
const session = await getSession();
|
const session = await getSession();
|
||||||
if (!session) redirect("/login");
|
if (!session) redirect("/login");
|
||||||
|
|
||||||
// Force a password change before anything else (provisioned accounts ship with
|
// Force a password change before anything else (provisioned accounts ship with
|
||||||
// a known default + mustChangePassword=true). The target page is outside this
|
// a known default + mustChangePassword=true). Read the flag from the DB, not the
|
||||||
// layout group, so there's no redirect loop.
|
// JWT: the cookie is only refreshed on re-login/update(), so trusting it would
|
||||||
if (session.user.mustChangePassword) redirect("/change-password");
|
// keep bouncing the user back here even after they've set a new password. The
|
||||||
|
// target page is outside this layout group, so there's no redirect loop.
|
||||||
|
const account = await db.user.findUnique({
|
||||||
|
where: { id: session.user.id },
|
||||||
|
select: { active: true, mustChangePassword: true },
|
||||||
|
});
|
||||||
|
if (!account || !account.active) redirect("/login");
|
||||||
|
if (account.mustChangePassword) redirect("/change-password");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex h-screen flex-col">
|
<div className="flex h-screen flex-col">
|
||||||
|
|||||||
@@ -8,6 +8,13 @@ export type ChangelogEntry = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const CHANGELOG: ChangelogEntry[] = [
|
export const CHANGELOG: ChangelogEntry[] = [
|
||||||
|
{
|
||||||
|
version: "0.16.1",
|
||||||
|
date: "2026-06-16",
|
||||||
|
changes: [
|
||||||
|
"Fixed: after you set a new password, the app could keep asking you to change it again on every visit. It now clears the moment you save your new password.",
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
version: "0.16.0",
|
version: "0.16.0",
|
||||||
date: "2026-06-16",
|
date: "2026-06-16",
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
// Bump on every user-visible release. Changelog entries live in `src/lib/changelog.ts`.
|
// Bump on every user-visible release. Changelog entries live in `src/lib/changelog.ts`.
|
||||||
export const APP_VERSION = "0.16.0";
|
export const APP_VERSION = "0.16.1";
|
||||||
|
|||||||
Reference in New Issue
Block a user