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
43 changes: 35 additions & 8 deletions src/app/actions/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {cookies, headers} from 'next/headers';
import {redirect} from 'next/navigation';

import CachyBuilderClient from '@/lib/api';
import {isAccessibleToken} from '@/lib/api/base';
import {defaultSession, SessionData, sessionOptions} from '@/lib/session';
import {
LoginRequest,
Expand Down Expand Up @@ -36,7 +37,7 @@ export async function getAccessibleServers() {
return redirect('/');
}
return session.tokens.map((token, index) => ({
accessible: token.token !== '' && token.scopes.length > 0,
accessible: isAccessibleToken(token),
active: index === session.serverIndex,
description: token.description,
name: token.name,
Expand Down Expand Up @@ -168,23 +169,49 @@ export async function logout() {
return redirect('/');
}

export async function retryServerAccess(serverName: string) {
const {cachyBuilderClient, session} = await getSession();
if (!session.isLoggedIn) {
return redirect('/');
}
try {
const {tokens, unreachable} =
await cachyBuilderClient.syncLoggedInUserScopes(
true,
await headers(),
serverName
);
if (unreachable.includes(serverName)) {
return {
error: `Server "${serverName}" is still unreachable. The builder API may be down or your token has expired.`,
};
}
session.tokens = tokens;
await session.save();
return {msg: `Restored access to "${serverName}".`};
} catch (error) {
return {
error: `Failed to retry access for "${serverName}": ${error instanceof Error ? error.message : 'Unknown error'}`,
};
}
}

export async function syncLoggedInUserScopes() {
const {cachyBuilderClient, session} = await getSession();
if (!session.isLoggedIn) {
return redirect('/');
}
try {
const {errors, tokens} = await cachyBuilderClient.syncLoggedInUserScopes(
true,
await headers()
);
const {tokens, unreachable} =
await cachyBuilderClient.syncLoggedInUserScopes(true, await headers());
session.tokens = tokens;
await session.save();
return {
success: tokens.length > 0,
success: tokens.some(isAccessibleToken),
unreachable,
warning:
errors.length > 0
? `Failed to sync scopes on some servers, these servers will be disabled for current session:\n${errors}`
unreachable.length > 0
? `Could not validate access on: ${unreachable.join(', ')}. You can retry per server from the sidebar switcher.`
: undefined,
};
} catch (error) {
Expand Down
57 changes: 21 additions & 36 deletions src/app/validate/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,47 +11,32 @@ export default function Page() {
const [status, setStatus] = useState(
'CachyOS Builder Dashboard is loading...'
);
const [doRedirect, setDoRedirect] = useState(false);
useEffect(() => {
let redirectTimeout: null | ReturnType<typeof setTimeout> = null;
setStatus('Configuring dashboard with your access scopes...');
const timeout = setTimeout(() => {
syncLoggedInUserScopes()
.then(data => {
if (data.error) {
return setStatus(data.error);
} else if (data.success) {
if (Array.isArray(data.warning) && data.warning.length) {
setStatus(
`Some errors occurred while syncing scopes:\n${data.warning}`
);
setDoRedirect(true);
} else {
setStatus('Scopes synced successfully. Redirecting...');
setDoRedirect(true);
}
} else {
setStatus(
'Unable to configure scopes for your account. Please contact site administrator.'
);
}
})
.catch(() => {});
}, 7000);
syncLoggedInUserScopes()
.then(data => {
if (data.error) {
return setStatus(data.error);
}
if (data.success) {
setStatus(
data.warning ?? 'Scopes synced successfully. Redirecting...'
);
redirectTimeout = setTimeout(() => {
router.push('/dashboard/package-list');
}, 1200);
} else {
setStatus(
'Unable to configure scopes for your account. Please contact site administrator.'
);
}
})
.catch(() => {});
return () => {
clearTimeout(timeout);
if (redirectTimeout) clearTimeout(redirectTimeout);
};
}, [router]);
useEffect(() => {
if (doRedirect) {
const redirectTimeout = setTimeout(() => {
setDoRedirect(true);
router.push('/dashboard/package-list');
}, 1200);
return () => {
clearTimeout(redirectTimeout);
};
}
}, [router, doRedirect]);
return (
<div className="flex min-h-svh w-full items-center justify-center p-6 md:p-10">
<div className="w-full max-w-md">
Expand Down
Loading