Skip to content
Merged
Show file tree
Hide file tree
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
20 changes: 5 additions & 15 deletions agents-manage-ui/src/app/[tenantId]/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,12 @@
import { cookies } from 'next/headers';
import { redirect } from 'next/navigation';
import type { FC } from 'react';
import { HeaderMenus } from '@/components/layout/header-menus';
import { SentryScopeProvider } from '@/components/sentry-scope-provider';
import { AppSidebarProvider } from '@/components/sidebar-nav/app-sidebar-provider';
import { Separator } from '@/components/ui/separator';
import { SidebarInset, SidebarTrigger } from '@/components/ui/sidebar';
import { BETTER_AUTH_SESSION_TOKEN_COOKIE } from '@/lib/auth/constants';
import { cn } from '@/lib/utils';

export default async function Layout({ children, breadcrumbs }: LayoutProps<'/[tenantId]'>) {
// Server-side auth gate: redirect to login if no session cookie is present.
// This protects all routes under /[tenantId]/* (work-apps, stats, settings, etc.)
// from being rendered without authentication.
const cookieStore = await cookies();
const sessionToken = cookieStore.get(BETTER_AUTH_SESSION_TOKEN_COOKIE);

if (!sessionToken?.value) {
redirect('/login');
}

const Layout: FC<LayoutProps<'/[tenantId]'>> = ({ children, breadcrumbs }) => {
return (
<AppSidebarProvider>
<SentryScopeProvider>
Expand Down Expand Up @@ -55,4 +43,6 @@ export default async function Layout({ children, breadcrumbs }: LayoutProps<'/[t
</SentryScopeProvider>
</AppSidebarProvider>
);
}
};

export default Layout;
14 changes: 12 additions & 2 deletions agents-manage-ui/src/app/logout/route.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import { cookies } from 'next/headers';
import { type NextRequest, NextResponse } from 'next/server';
import { getAgentsApiUrl } from '@/lib/api/api-config';
import { BETTER_AUTH_COOKIE_PREFIX, BETTER_AUTH_COOKIES } from '@/lib/auth/constants';
import { getLogger } from '@/lib/logger';

/**
* Known better-auth cookie names to clear.
* These follow the pattern: better-auth.{cookie_name}
*/
const BETTER_AUTH_COOKIES = [
'better-auth.session_token',
'better-auth.session_data',
'better-auth.dont_remember',
'better-auth.two_factor',
];

const DEFAULT_REDIRECT = '/login';

/**
Expand Down Expand Up @@ -39,7 +49,7 @@ export async function GET(request: NextRequest) {

// Get all better-auth cookies to forward to the sign-out endpoint
const allCookies = cookieStore.getAll();
const authCookies = allCookies.filter((c) => c.name.includes(BETTER_AUTH_COOKIE_PREFIX));
const authCookies = allCookies.filter((c) => c.name.includes('better-auth'));
const cookieHeader = authCookies.map((c) => `${c.name}=${c.value}`).join('; ');

// Call the better-auth sign-out endpoint on the agents API
Expand Down
5 changes: 2 additions & 3 deletions agents-manage-ui/src/lib/api/api-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
* Centralized configuration for API endpoints and settings
*/

import { BETTER_AUTH_COOKIE_PREFIX } from '../auth/constants';
import { DEFAULT_INKEEP_AGENTS_API_URL } from '../runtime-config/defaults';
import { ApiError } from '../types/errors';

Expand Down Expand Up @@ -44,7 +43,7 @@ async function makeApiRequestInternal<T>(
if (rawCookieHeader) {
// Filter to only forward Better Auth cookies for security
const cookiePairs = rawCookieHeader.split(';').map((c) => c.trim());
const authCookies = cookiePairs.filter((c) => c.includes(BETTER_AUTH_COOKIE_PREFIX));
const authCookies = cookiePairs.filter((c) => c.includes('better-auth'));
cookieHeader = authCookies.join('; ');
}

Expand All @@ -53,7 +52,7 @@ async function makeApiRequestInternal<T>(
const { cookies } = await import('next/headers');
const cookieStore = await cookies();
const allCookies = cookieStore.getAll();
const authCookies = allCookies.filter((c) => c.name.includes(BETTER_AUTH_COOKIE_PREFIX));
const authCookies = allCookies.filter((c) => c.name.includes('better-auth'));
cookieHeader = authCookies.map((c) => `${c.name}=${c.value}`).join('; ');
}
} catch {
Expand Down
23 changes: 0 additions & 23 deletions agents-manage-ui/src/lib/auth/constants.ts

This file was deleted.

Loading