Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 29 additions & 6 deletions packages/web/src/app/[domain]/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,15 @@ export default async function Layout(props: LayoutProps) {
return status;
})();

// Hoist membership so it's available for the billing owner check below (#815)
let membership: Awaited<ReturnType<typeof prisma.userToOrg.findUnique<{
where: { orgId_userId: { orgId: string; userId: string } };
include: { user: true };
}>>> = null;

// If the user is authenticated, we must check if they're a member of the org
if (session) {
const membership = await prisma.userToOrg.findUnique({
membership = await prisma.userToOrg.findUnique({
where: {
orgId_userId: {
orgId: org.id,
Expand Down Expand Up @@ -171,11 +177,28 @@ export default async function Layout(props: LayoutProps) {
(subscription.status !== "active" && subscription.status !== "trialing")
)
) {
return (
<UpgradeGuard>
{children}
</UpgradeGuard>
)
// Only redirect org owners to the upgrade page.
// Non-owners see a message to contact their org owner (#815).
if (membership?.role === 'OWNER') {
return (
<UpgradeGuard>
{children}
</UpgradeGuard>
)
} else {
return (
<div className="min-h-screen flex items-center justify-center p-6">
<LogoutEscapeHatch className="absolute top-0 right-0 p-6" />
<div className="text-center max-w-md">
<h2 className="text-xl font-semibold mb-2">Subscription Expired</h2>
<p className="text-muted-foreground">
Your organization&apos;s subscription has expired or is inactive.
Please contact your organization owner to renew the subscription.
</p>
</div>
</div>
)
}
Comment on lines +188 to +201
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Anonymous users with expired subscriptions see a logout escape hatch and an owner-contact message.

When anonymous access is enabled and the subscription is expired, unauthenticated visitors (session === null, membership === null) land in this else branch. They'll see the LogoutEscapeHatch (which may be a no-op if it checks session internally—worth verifying) and a message to "contact your organization owner," which isn't actionable for anonymous visitors.

Consider either:

  1. Guarding LogoutEscapeHatch with session here, and
  2. Adjusting the copy for unauthenticated users (e.g., "This organization's subscription has expired.").
#!/bin/bash
# Check if LogoutEscapeHatch renders conditionally based on session
fd "logoutEscapeHatch" --type f --exec cat {}
🤖 Prompt for AI Agents
In `@packages/web/src/app/`[domain]/layout.tsx around lines 188 - 201, The current
expired-subscription UI renders LogoutEscapeHatch and an owner-contact message
even for anonymous visitors; update the else branch in layout.tsx to (1) only
render <LogoutEscapeHatch> when session is present (guard it with a session
check) and (2) change the copy based on whether session/membership is null—e.g.,
show "This organization's subscription has expired." or other non-actionable
text for anonymous users and keep the "contact your organization owner" text for
authenticated members; locate the logic around session, membership and
LogoutEscapeHatch to apply these conditional checks and text variants.

}
}

Expand Down