- Remove .prettierrc (dead config, Biome replaces Prettier) - Rename lighthouserc.json to lighthouserc.cjs with module.exports for ESM compat - Add logger.warn to empty catch blocks in auth, register, site-settings, prisma-cache, redis, security, rate-limit - Unify ActionResult type: action-helper.ts uses 'ok' consistent with safe-action-shared.ts - Add noUnusedLocals + noUnusedParameters to tsconfig + fix 25 pre-existing unused vars - Replace barrel export src/types/index.ts with direct @/types/common imports - Make trustHost conditional (development only) in auth.ts - Add pre-flight URL validation to update-Nitrov3.sh to catch image.library.url misconfigurations - Improve NITRO_IMAGE_LIBRARY_URL content validation in pre-flight & post-compute checks
51 lines
1.4 KiB
TypeScript
51 lines
1.4 KiB
TypeScript
"use server";
|
|
|
|
import { auth, signOut } from "@/lib/auth";
|
|
import { invalidateJwtVersionCache } from "@/lib/auth/jwt-version-cache";
|
|
import { personalTokenScope } from "@/lib/auth/personal-token-scope";
|
|
import { logger } from "@/lib/logger";
|
|
import { prisma } from "@/lib/prisma";
|
|
|
|
/**
|
|
* Invalidate every CMS JWT for the signed-in user by bumping website_jwt_version,
|
|
* revoke personal access tokens, then end the current browser session too.
|
|
*/
|
|
export async function signOutEverywhere(): Promise<void> {
|
|
const session = await auth();
|
|
const userId = Number(session?.user?.id);
|
|
if (!Number.isInteger(userId) || userId <= 0) {
|
|
await signOut({ redirectTo: "/login" });
|
|
return;
|
|
}
|
|
|
|
try {
|
|
await prisma.user.update({
|
|
where: { id: userId },
|
|
data: { websiteJwtVersion: { increment: 1 } },
|
|
});
|
|
await invalidateJwtVersionCache(userId);
|
|
} catch (err) {
|
|
logger.warn("Failed to bump JWT version during sign-out-everywhere", {
|
|
userId,
|
|
error: err instanceof Error ? err.message : "Unknown",
|
|
});
|
|
}
|
|
|
|
// Revoke API bearer tokens (Sanctum / personal_access_tokens).
|
|
try {
|
|
await prisma.personalAccessTokens.deleteMany({
|
|
where: personalTokenScope(userId),
|
|
});
|
|
} catch (err) {
|
|
logger.warn(
|
|
"Failed to revoke personal access tokens during sign-out-everywhere",
|
|
{
|
|
userId,
|
|
error: err instanceof Error ? err.message : "Unknown",
|
|
},
|
|
);
|
|
}
|
|
|
|
await signOut({ redirectTo: "/login?signedOutAll=1" });
|
|
}
|