Skip to content
Open
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
9 changes: 2 additions & 7 deletions apps/web/src/app/(app)/components/SidebarUserFooter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
} from '@/components/ui/dropdown-menu';
import { Avatar, AvatarImage, AvatarFallback } from '@radix-ui/react-avatar';
import { BookOpen, ChevronsUpDown, Download, FileDown, LogOut, UserCog } from 'lucide-react';
import { signOut } from 'next-auth/react';
import { useRouter } from 'next/navigation';

type User = {
Expand All @@ -37,12 +36,8 @@ function getUserInitials(name: string) {
export default function SidebarUserFooter({ user, isLoading }: SidebarUserFooterProps) {
const router = useRouter();

const handleLogout = async () => {
try {
await fetch('/api/auth/revoke-web-session', { method: 'POST' });
} finally {
await signOut({ callbackUrl: '/' });
}
const handleLogout = () => {
router.push('/users/sign_out?callbackUrl=%2F');
};

return (
Expand Down
11 changes: 3 additions & 8 deletions apps/web/src/app/device-auth/DeviceAuthClient.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use client';

import { useState } from 'react';
import { signOut } from 'next-auth/react';
import { z } from 'zod';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
Expand Down Expand Up @@ -55,14 +54,10 @@ export function DeviceAuthClient({ code, viewerToken, isAppMode, user }: DeviceA
const shellClassName = getDeviceAuthShellClassName(isAppMode);
const outcomeHeaderClassName = getDeviceAuthOutcomeHeaderClassName();

const handleSignOut = async () => {
const handleSignOut = () => {
setIsSigningOut(true);

try {
await fetch('/api/auth/revoke-web-session', { method: 'POST' });
} finally {
await signOut({ callbackUrl: getDeviceAuthSignInUrl(code, { app: isAppMode }) });
}
const callbackUrl = getDeviceAuthSignInUrl(code, { app: isAppMode });
window.location.assign(`/users/sign_out?callbackUrl=${encodeURIComponent(callbackUrl)}`);
};

const redirectToSignIn = () => {
Expand Down
66 changes: 66 additions & 0 deletions apps/web/src/app/users/sign_out/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
'use client';

import { useRouter, useSearchParams } from 'next/navigation';
import { signOut } from 'next-auth/react';
import { useState } from 'react';

import { AuthPageLayout } from '@/components/auth/AuthPageLayout';
import { Button } from '@/components/ui/button';
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from '@/components/ui/card';

function safeCallbackUrl(raw: string | null): string {
if (!raw) return '/profile';
if (!raw.startsWith('/') || raw.startsWith('//')) return '/profile';
return raw;
}

export default function SignOutPage() {
const router = useRouter();
const params = useSearchParams();
const callbackUrl = safeCallbackUrl(params.get('callbackUrl'));
const [submitting, setSubmitting] = useState(false);

const handleSignOut = async () => {
if (submitting) return;
setSubmitting(true);
try {
await fetch('/api/auth/revoke-web-session', { method: 'POST' });
} finally {
await signOut({ callbackUrl });
}
};

return (
<AuthPageLayout>
<Card className="w-full max-w-md">
<CardHeader>
<CardTitle>Sign out of Kilo?</CardTitle>
<CardDescription>
You&apos;ll need to sign in again to access your account.
</CardDescription>
</CardHeader>
<CardContent />
<CardFooter className="flex flex-col-reverse gap-2 sm:flex-row sm:justify-end">
<Button
type="button"
variant="outline"
onClick={() => router.back()}
disabled={submitting}
>
Cancel
</Button>
<Button type="button" onClick={handleSignOut} disabled={submitting}>
{submitting ? 'Signing out…' : 'Sign out'}
</Button>
</CardFooter>
</Card>
</AuthPageLayout>
);
}
2 changes: 1 addition & 1 deletion apps/web/src/components/dev/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,5 @@ export async function nuke() {
throw new Error('Failed to nuke account. Please try again later.');
}

redirect('/api/auth/signout?callbackUrl=/profile');
redirect('/users/sign_out?callbackUrl=/profile');
}
1 change: 1 addition & 0 deletions apps/web/src/lib/user/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1058,6 +1058,7 @@ export const authOptions: NextAuthOptions = {
pages: {
signIn: '/users/sign_in',
error: '/users/sign_in',
signOut: '/users/sign_out',
},
debug: !!getEnvVariable('DEBUG_AUTH'),
};
Expand Down