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
18 changes: 14 additions & 4 deletions sky/dashboard/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions sky/dashboard/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"chart.js": "^4.4.3",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"cookie": "^1.0.2",
"date-fns": "^3.6.0",
"express": "^4.19.2",
"http-proxy-middleware": "^3.0.0",
Expand Down
17 changes: 17 additions & 0 deletions sky/dashboard/src/components/auth/signout.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react';
import { Slot } from '@radix-ui/react-slot';
import { useSignOut } from '@/hooks/auth/useSignOut';
import Link from 'next/link';

export function SignOut(props) {
const { asChild = false, children, ...rest } = props;
const Comp = asChild ? Slot : Link;

const { signOutUrl } = useSignOut();

return (
<Comp {...rest} href={signOutUrl}>
{children}
</Comp>
);
}
8 changes: 8 additions & 0 deletions sky/dashboard/src/components/elements/sidebar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import { Settings, User } from 'lucide-react';
import { BASE_PATH, ENDPOINT } from '@/data/connectors/constants';
import { CustomTooltip } from '@/components/utils';
import { useMobile } from '@/hooks/useMobile';
import { SignOut } from '../auth/signout';
import { useAuthMethod } from '@/hooks/auth/useAuthMethod';

// Create a context for sidebar state management
const SidebarContext = createContext(null);
Expand Down Expand Up @@ -161,6 +163,7 @@ export function TopBar() {
const { userEmail, userRole, isMobileSidebarOpen, toggleMobileSidebar } =
useSidebar();
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
const authMethod = useAuthMethod();

const dropdownRef = useRef(null);
const mobileNavRef = useRef(null);
Expand Down Expand Up @@ -487,6 +490,11 @@ export function TopBar() {
>
See all users
</Link>
{authMethod === 'oauth2' && (
<SignOut className="block px-4 py-2 text-sm text-red-600 hover:bg-red-50 hover:text-red-700 transition-colors">
Sign out
</SignOut>
)}
</div>
)}
</div>
Expand Down
13 changes: 13 additions & 0 deletions sky/dashboard/src/hooks/auth/useAuthMethod.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { useCallback } from 'react';
import * as cookie from 'cookie';

export function useAuthMethod() {
const getBrowserCookie = useCallback((name) => {
const cookies = cookie.parse(document.cookie || '');
return name in cookies ? cookies[name] : undefined;
}, []);

// Only check OAuth2
// Cannot check other methods (e.g., basic auth) from the browser
return getBrowserCookie('_oauth2_proxy') ? 'oauth2' : undefined;
}
27 changes: 27 additions & 0 deletions sky/dashboard/src/hooks/auth/useSignOut.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { useMemo } from 'react';
import { useAuthMethod } from './useAuthMethod';
import { useRouter } from 'next/router';
import { ENDPOINT } from '@/data/connectors/constants';

export function useSignOut(props) {
const { redirect } = props || {};

const authMethod = useAuthMethod();
const router = useRouter();

const signOutUrl = useMemo(() => {
if (authMethod === 'oauth2') {
const url = new URL(`${ENDPOINT}/oauth2/sign_out`, window.location.href);

if (redirect) {
url.searchParams.append('rd', redirect);
}

return url;
} else {
return undefined;
}
}, [authMethod, router, redirect]);

return { signOutUrl };
}
Loading