- Added "HW" (Hardware) category to the platform with a dedicated icon and color
- Updated challenge grid to 6 columns on desktop to accommodate the new category - Alphabetized challenge categories in the main view and Admin panel selection - Alphabetized operators list in the Admin panel with case-insensitive sorting - Restricted visibility of Challenges, Scoreboard, and Score Matrix to authenticated users only - Secured the /state API endpoint to prevent leaking challenges, solves, teams, or internal IP (dockerIp) to guests - Implemented server-side verification of user profile in the state response to prevent client-side admin spoofing - Refactored the /state backend endpoint using async/await for better reliability and error handling - Rebranded the project from "cypherstrike-ctf" to "hipctf" across package.json, index.html, and server defaults - Synchronized browser page title with the competition name configured in the Admin panel - Fixed a "black page" issue by resolving a missing React import and adding frontend sanity checks
This commit is contained in:
@@ -3,6 +3,7 @@ import React, { useState, useMemo } from 'react';
|
||||
import { X, CheckCircle2, Download, Globe, Sparkles, Heart, Clock, Bell } from 'lucide-react';
|
||||
import { useCTF } from './CTFContext';
|
||||
import { Challenge, Difficulty } from './types';
|
||||
import { CATEGORIES } from './constants';
|
||||
import { Button, CategoryIcon, Countdown } from './UIComponents';
|
||||
import { calculateChallengeValue, getFirstBloodBonusFactor } from './services/scoring';
|
||||
|
||||
@@ -122,7 +123,6 @@ export const ChallengeList: React.FC = () => {
|
||||
const [selectedChallenge, setSelectedChallenge] = useState<Challenge | null>(null);
|
||||
const [showRefreshPopup, setShowRefreshPopup] = useState(false);
|
||||
const difficultyWeight: Record<Difficulty, number> = { 'Low': 1, 'Medium': 2, 'High': 3 };
|
||||
const CATEGORIES = ['WEB', 'PWN', 'REV', 'CRY', 'MSC'];
|
||||
|
||||
const now = Date.now();
|
||||
const startTime = parseInt(state.config.eventStartTime || "0");
|
||||
@@ -178,7 +178,7 @@ export const ChallengeList: React.FC = () => {
|
||||
|
||||
return (
|
||||
<div className="w-full px-6 py-12">
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-5 gap-8 max-w-[1600px] mx-auto">
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-6 gap-8 max-w-[1800px] mx-auto">
|
||||
{CATEGORIES.map(category => {
|
||||
const categoryChallenges = (state.challenges || [])
|
||||
.filter(c => c.category === category)
|
||||
@@ -188,7 +188,7 @@ export const ChallengeList: React.FC = () => {
|
||||
<div key={category} className="flex flex-col gap-6">
|
||||
<div className="flex flex-col items-center gap-2 mb-4">
|
||||
<div className="p-3 bg-white/5 hxp-border border-[#333] hover:border-[#bf00ff] transition-colors">
|
||||
<CategoryIcon category={category} size={48} color={category === 'WEB' ? '#ff0000' : category === 'PWN' ? '#ffaa00' : category === 'REV' ? '#00ccff' : '#bf00ff'} />
|
||||
<CategoryIcon category={category} size={48} color={category === 'WEB' ? '#ff0000' : category === 'PWN' ? '#ffaa00' : category === 'REV' ? '#00ccff' : category === 'HW' ? '#00ff00' : '#bf00ff'} />
|
||||
</div>
|
||||
<h3 className="text-3xl font-black italic text-white uppercase tracking-tighter">{category}</h3>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user