mirror of
https://github.com/jakejarvis/sofa.git
synced 2026-10-15 19:45:42 -04:00
fix(auth): refresh the session cookie cache after first-admin promotion
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
3 files changed
+29
-2
No files matched your search
@@ -27,6 +27,8 @@ export const admin = oo.spec(
|
||||
base.middleware(async ({ context, next }) => {
|
||||
const sessionData = await auth.api.getSession({
|
||||
headers: context.headers,
|
||||
// Bypass the 5-minute cookie cache so role changes take effect immediately.
|
||||
query: { disableCookieCache: true },
|
||||
});
|
||||
if (!sessionData?.session || !sessionData?.user) {
|
||||
throw new ORPCError("UNAUTHORIZED");
|
||||
|
||||
@@ -9,7 +9,11 @@ const app = new Hono();
|
||||
|
||||
app.get("/:filename", async (c) => {
|
||||
// Auth + admin check
|
||||
const session = await auth.api.getSession({ headers: c.req.raw.headers });
|
||||
const session = await auth.api.getSession({
|
||||
headers: c.req.raw.headers,
|
||||
// Bypass the 5-minute cookie cache so role changes take effect immediately.
|
||||
query: { disableCookieCache: true },
|
||||
});
|
||||
if (!session) {
|
||||
return c.json({ error: "Unauthorized" }, 401);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { drizzleAdapter } from "@better-auth/drizzle-adapter";
|
||||
import { expo } from "@better-auth/expo";
|
||||
import { APIError, createAuthMiddleware } from "better-auth/api";
|
||||
import { setCookieCache } from "better-auth/cookies";
|
||||
import { type BetterAuthOptions, betterAuth } from "better-auth/minimal";
|
||||
import { admin, genericOAuth } from "better-auth/plugins";
|
||||
import { admin, genericOAuth, type UserWithRole } from "better-auth/plugins";
|
||||
|
||||
import { claimInitialAdmin, isRegistrationOpen } from "@sofa/core/settings";
|
||||
import { db } from "@sofa/db/client";
|
||||
@@ -106,6 +107,26 @@ export const auth = betterAuth({
|
||||
}
|
||||
}
|
||||
}),
|
||||
after: createAuthMiddleware(async (ctx) => {
|
||||
// The first user is promoted to admin by a create.after database hook, which
|
||||
// Better Auth runs after the sign-up transaction commits — i.e. after the
|
||||
// session cookie (including its cached user) was already written with
|
||||
// role "user". Re-read the user and refresh the cache cookie if it changed.
|
||||
const newSession = ctx.context.newSession;
|
||||
if (!newSession) return;
|
||||
try {
|
||||
const fresh = (await ctx.context.internalAdapter.findUserById(
|
||||
newSession.user.id,
|
||||
)) as UserWithRole | null;
|
||||
const cachedRole = (newSession.user as UserWithRole).role;
|
||||
if (!fresh || fresh.role === cachedRole) return;
|
||||
const user = { ...newSession.user, role: fresh.role };
|
||||
await setCookieCache(ctx, { session: newSession.session, user }, false);
|
||||
} catch (err) {
|
||||
// Never turn a successful sign-in into an error over a cache refresh.
|
||||
authLog.warn("Failed to refresh session cookie cache:", err);
|
||||
}
|
||||
}),
|
||||
},
|
||||
databaseHooks: {
|
||||
user: {
|
||||
|
||||
Reference in new issue
Block a user