Skip to content

Commit

Permalink
Merge pull request #2 from ky28059/main
Browse files Browse the repository at this point in the history
Pull wrapping, experimental support to internal
ky28059 authored Nov 9, 2024
2 parents 3f0b625 + fd7687e commit 088007a
Showing 8 changed files with 45 additions and 16 deletions.
2 changes: 1 addition & 1 deletion app/challenges/Challenge.tsx
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@ export default function Challenge(props: Challenge & { solved: boolean }) {
return (
<div className="bg-black/50 px-6 py-4 rounded border border-tertiary backdrop-blur-sm">
<div className="flex items-center gap-2">
<h3 className="font-semibold">
<h3 className="font-semibold [overflow-wrap:anywhere]">
{props.category}/{props.name}
</h3>

2 changes: 1 addition & 1 deletion app/challenges/GridChallenge.tsx
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ export default function GridChallenge(props: Challenge & { solved: boolean }) {
className={'px-8 py-6 rounded border transition duration-150 text-center focus:outline-none focus:ring-2 backdrop-blur-sm ' + (props.solved ? 'bg-success/20 border-success hover:bg-success/30' : 'bg-black/50 border-tertiary hover:border-secondary')}
onClick={() => setOpen(true)}
>
<h3 className="font-medium mb-2 flex gap-2 items-center justify-center">
<h3 className="font-medium mb-2 flex gap-2 items-center justify-center [overflow-wrap:anywhere]">
{props.solved && (
<BiCheck className="flex-none bg-success/40 p-0.5 mb-0.5 rounded-full" />
)}
2 changes: 1 addition & 1 deletion app/challenges/GridChallengeModal.tsx
Original file line number Diff line number Diff line change
@@ -37,7 +37,7 @@ export default function GridChallengeModal(props: GridChallengeModalProps) {

<Tab.Panels>
<Tab.Panel>
<h1 className="text-2xl text-center mb-2">
<h1 className="text-2xl text-center mb-2 [overflow-wrap:anywhere]">
{props.challenge.name}
</h1>
<p className="text-lg text-center text-primary mb-6">
4 changes: 2 additions & 2 deletions app/challenges/SolvesModal.tsx
Original file line number Diff line number Diff line change
@@ -19,10 +19,10 @@ export default function SolvesModal(props: SolvesModalProps) {
isOpen={props.open}
setIsOpen={props.setOpen}
>
<h1 className="flex gap-2 items-center text-2xl font-bold mb-4">
<h1 className="flex gap-2 items-center text-2xl font-bold mb-4 [overflow-wrap:anywhere]">
Solves for {props.challenge.name}

<span className="text-sm px-2 py-0.5 bg-theme-bright/25 text-theme-bright font-semibold rounded-full">
<span className="flex-none text-sm px-2 py-0.5 bg-theme-bright/25 text-theme-bright font-semibold rounded-full">
{props.challenge.category}
</span>
</h1>
39 changes: 33 additions & 6 deletions app/challenges/page.tsx
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@ import CTFNotStarted from '@/components/CTFNotStarted';
// Utils
import { getChallenges } from '@/util/challenges';
import { getMyProfile } from '@/util/profile';
import { getAdminChallenges } from '@/util/admin';
import { AUTH_COOKIE_NAME } from '@/util/config';


@@ -27,20 +28,46 @@ export default async function ChallengesPage() {
if (profile.kind === 'badToken')
return redirect('/logout');

return challenges.kind === 'goodChallenges' ? (
if (challenges.kind !== 'goodChallenges') return (
<CTFNotStarted />
);

// Support non-standard properties by sourcing them from the admin endpoint.
const adminData = await getAdminChallData();
let challs = challenges.data;

if (adminData) {
// Filter out challs with prereqs that are not met yet
const solved = new Set(profile.data.solves.map((c) => c.id));
challs = challs.filter((c) => !adminData[c.id].prereqs || adminData[c.id].prereqs!.every((p) => solved.has(p)));

// Inject desired properties back into client challenges
for (const c of challs) {
c.difficulty = adminData[c.id].difficulty;
}
}

return (
<div className="container relative pt-32 pb-14 flex flex-col md:flex-row gap-6">
<Filters
challenges={challenges.data}
challenges={challs}
solves={profile.data.solves}
/>
<Challenges
challenges={challenges.data}
challenges={challs}
solves={profile.data.solves}
/>

<DisplayToggle />
</div>
) : (
<CTFNotStarted />
)
);
}

async function getAdminChallData() {
if (!process.env.ADMIN_TOKEN) return;

const res = await getAdminChallenges(process.env.ADMIN_TOKEN);
if (res.kind === 'badToken') return;

return Object.fromEntries(res.data.map((c) => [c.id, c]));
}
2 changes: 1 addition & 1 deletion app/profile/ProfileSolve.tsx
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ import { DateTime } from 'luxon';
export default function ProfileSolve(props: Solve) {
return (
<div className="table-row">
<div className="table-cell px-2">
<div className="table-cell px-2 [overflow-wrap:anywhere]">
{props.name}
<span className="font-semibold bg-theme-bright/25 text-theme-bright px-2 py-1 text-xs rounded-full ml-2">
{props.category}
8 changes: 4 additions & 4 deletions util/admin.ts
Original file line number Diff line number Diff line change
@@ -2,9 +2,11 @@ import type { Challenge } from '@/util/challenges';
import type { BadTokenResponse } from '@/util/errors';


export type AdminChallenge = Challenge & {
export type AdminChallenge = Exclude<Challenge, 'solves' | 'points' | 'sortWeight'> & {
flag: string,
points: { min: number, max: number }

prereqs?: string[], // Non-standard
}

type AdminChallengesResponse = {
@@ -15,9 +17,7 @@ type AdminChallengesResponse = {

export async function getAdminChallenges(token: string): Promise<AdminChallengesResponse | BadTokenResponse> {
const res = await fetch(`${process.env.API_BASE}/admin/challs`, {
headers: {
'Authorization': `Bearer ${token}`
}
headers: { 'Authorization': `Bearer ${token}` }
});

return res.json();
2 changes: 2 additions & 0 deletions util/challenges.ts
Original file line number Diff line number Diff line change
@@ -11,6 +11,8 @@ export type Challenge = {
sortWeight: number,
solves: number,
points: number,

difficulty?: string, // Non-standard
}

type FileData = {

0 comments on commit 088007a

Please sign in to comment.