fix: harden getActiveContext and add error logging on presentations page
- getActiveContext now verifies team still exists (teams.get) before trusting the cookie/prefs tenantId, preventing stale E Ofis cookie from causing an onboarding redirect loop - Resolved tenantId from getUserTeams() is now persisted to cookie so subsequent requests skip the resolution path - Added catch+log on presentations data fetch to surface the actual error in server logs
This commit is contained in:
@@ -25,7 +25,10 @@ export default async function PresentationsPage() {
|
||||
Query.limit(200),
|
||||
],
|
||||
}),
|
||||
]);
|
||||
]).catch((e) => {
|
||||
console.error("[PresentationsPage] data fetch failed:", e);
|
||||
throw e;
|
||||
});
|
||||
|
||||
const presentations = JSON.parse(JSON.stringify(presResult.rows)) as Presentation[];
|
||||
|
||||
|
||||
@@ -14,6 +14,18 @@ export type ActiveContext = {
|
||||
settings: TenantSettings | null;
|
||||
};
|
||||
|
||||
async function setActiveTenantCookie(tenantId: string) {
|
||||
try {
|
||||
(await cookies()).set(ACTIVE_TENANT_COOKIE, tenantId, {
|
||||
path: "/",
|
||||
httpOnly: true,
|
||||
sameSite: "strict",
|
||||
secure: process.env.NODE_ENV === "production",
|
||||
maxAge: 60 * 60 * 24 * 365,
|
||||
});
|
||||
} catch { /* ignore in middleware context */ }
|
||||
}
|
||||
|
||||
export async function getActiveContext(): Promise<ActiveContext | null> {
|
||||
const user = await getCurrentUser();
|
||||
if (!user) return null;
|
||||
@@ -22,17 +34,19 @@ export async function getActiveContext(): Promise<ActiveContext | null> {
|
||||
|
||||
let tenantId = await getActiveTenantId();
|
||||
|
||||
// Validate cookie tenantId — user must actually be a member of that team.
|
||||
// Validate cookie/prefs tenantId — team must exist and user must be a member.
|
||||
if (tenantId) {
|
||||
try {
|
||||
await adminTeams.get(tenantId); // throws if team was deleted
|
||||
const memberships = await adminTeams.listMemberships(tenantId);
|
||||
const isMember = memberships.memberships.some((m) => m.userId === user.$id);
|
||||
if (!isMember) {
|
||||
// Stale or cross-account cookie — clear and re-resolve.
|
||||
try { (await cookies()).delete(ACTIVE_TENANT_COOKIE); } catch { /* ignore */ }
|
||||
tenantId = null;
|
||||
}
|
||||
} catch {
|
||||
// Team deleted or inaccessible — clear stale pointer.
|
||||
try { (await cookies()).delete(ACTIVE_TENANT_COOKIE); } catch { /* ignore */ }
|
||||
tenantId = null;
|
||||
}
|
||||
}
|
||||
@@ -40,6 +54,8 @@ export async function getActiveContext(): Promise<ActiveContext | null> {
|
||||
if (!tenantId) {
|
||||
const userTeams = await getUserTeams();
|
||||
tenantId = userTeams?.teams[0]?.$id ?? null;
|
||||
// Persist so the next request skips this resolution path.
|
||||
if (tenantId) await setActiveTenantCookie(tenantId);
|
||||
}
|
||||
|
||||
if (!tenantId) return null;
|
||||
|
||||
Reference in New Issue
Block a user