-
Notifications
You must be signed in to change notification settings - Fork 12
Challenge Endpoints
Show all available challenges, sorted by category
Authenticated
No input required
// Type 0 or 1 users
{
"success": true,
"data": [
{
"_id": "CATEGORY_NAME",
"challenges": [
{
"_id": "CHALLENGE_ID",
"name": "CHALLENGE_NAME",
"points": "int",
"solved": "bool",
"tags": [
"CHALLENGE_TAGS"
],
"requires": "required challenge to unlock this challenge"
}
]
}
]
}
// Type 2 users
{
"success": true,
"data": [
{
"_id": "CATEGORY_NAME",
"challenges": [
{
"_id": "CHALLENGE_ID",
"name": "CHALLENGE_NAME",
"points": "int",
"solved": "bool",
"tags": [
"CHALLENGE_TAGS"
],
"requires": "required challenge to unlock this challenge",
"visibility": true
}
]
}
]
}
- For admin users (type
2
users), hidden challenges are also returned along with avisibility
property for each challenge
Show all available challenges in a category
Authenticated
GET /v1/challenge/list/CATEGORY_NAME
{
"success": true,
"challenges": [
{
"_id": "CHALLENGE_ID",
"name": "CHALLENGE_NAME",
"points": "int",
"solved": "bool",
"tags": [],
"requires": "required_challenge_to_solve"
}
]
}
- Only shows challenges with
visibility: true
Error | Definition |
---|---|
not-found |
No challenges were found (matching the criteria if specified) |
Show all available categories
Authenticated
No input required
{
"success": true,
"categories": [
"NEW_CATEGORIES",
"OTHER_NEW_CATEGORIES"
]
}
- Only shows challenges with
visibility: true
No special errors
Show all categories including hidden ones
Authenticated // Permissions: 2
No input required
{
"success": true,
"categories": [
"NEW_CATEGORIES",
"OTHER_NEW_CATEGORIES"
]
}
- Only shows challenges with
visibility: true
No special errors
Show all challenges
Authenticated // Permissions: 2
No input required
{
"success": true,
"challenges": [
{
"_id": "CHALLENGE_ID",
"name": "CHALLENGE_NAME",
"category": "CHALLENGE_CATEGORY",
"points": "int",
"solves": "array",
"visibility": true,
"requires": "chall"
},
{
"_id": "CHALLENGE_ID",
"name": "CHALLENGE_NAME",
"category": "CHALLENGE_CATEGORY",
"points": "int",
"solves": "array",
"visibility": true,
"requires": "chall"
}
]
}
- Shows all challenges, including those with
visibility: false
No special errors
Get the details of a challenge
Authenticated
GET: /v1/challenge/show/CHALLENGE_ID
{
"success": true,
"challenge": {
"name": "CHALLENGE_NAME",
"category": "CHALLENGE_CATEGORY",
"description": "CHALLENGE_DESCRIPTION (HTML)",
"points": "int",
"author": "CHALLENGE_AUTHOR",
"created": "CREATION_TIMESTAMP",
"solves": [
"USERNAME_OF_SOLVER"
],
"max_attempts": "int (0 means unlimited)",
"tags": [
"CHALLENGE_TAG"
],
"hints": [
{
"bought": true,
"hint": "HINT_CONTENTS" // hint 1
},
{
"bought": false,
"cost": "int" // hint 2
}
]
}
}
- Only shows challenges with
visibility: true
(unless the user is a type2
user) - The endpoint will not return any info if the user has yet to solve the required challenge
- Hints: if the hint has been bought, the object will provide the hint directly. If not, the
cost
key will be an integer of the number of points needed
Error | Definition |
---|---|
notfound |
No challenge found |
required-challenge-not-found |
The required challenge was not found. This likely means that the challenge that should be solved to unlock this challenge has been deleted/no longer exists |
required-challenge-not-completed |
The user has yet to completed the required challenge to unlock this challenge |
Get all the details of a challenge
Authenticated // Permissions: 2
GET: /v1/challenge/show/CHALLENGE_ID/detailed
{
"success": true,
"challenge": {
"_id": "CHALLENGE_ID",
"name": "CHALLENGE_NAME",
"category": "CHALLENGE_CATEGORY",
"description": "CHALLENGE_DESCRIPTION (HTML)",
"points": "int",
"author": "CHALLENGE_AUTHOR",
"created": "CREATION_TIMESTAMP",
"solves": [
"USERNAME_OF_SOLVER"
],
"max_attempts": "int (0 means unlimited)",
"used_attempts": "int",
"tags": [
"CHALLENGE_TAG"
],
"visibility": "bool",
"flags": [
"FLAG"
],
"hints": [
{
"hint": "HINT_CONTENTS",
"cost": "int",
"purchased": [
"USERNAME"
]
},
{
"hint": "HINT_CONTENTS",
"cost": "int",
"purchased": [
"USERNAME"
]
}
],
"dynamic": true // whether the challenge uses dynamic scoring
"initial": 100 // initial score for dynamic challs
"minSolves": 10 // number of solves for the challenge till it decays till the minimum score below
"minimum": 50 // minimum score to decay to for dynamic challs
}
}
Error | Definition |
---|---|
permissions |
The logged-in user does not have sufficient permissions to create a new challenge |
Buy a hint for a challenge
Authenticated
{
"id": "int",
"chall": "CHALLENGE_ID"
}
{
"success": true,
"hint": "HINT_CONTENT"
}
- The
id
field refers to the index of the hint (e.g. the 1st hint would be ID = 0) - The server will return the hint if it has already been bought, but will not deduct any points
- Buying a hint triggers a websocket message broadcast to all live scoreboard clients
Error | Definition |
---|---|
not-found |
The CHALLENGE_ID specified was invalid |
out-of-range |
The id field is too large or too small (minimum is 0) |
required-challenge-not-found |
The required challenge was not found. This likely means that the challenge that should be solved to unlock this challenge has been deleted/no longer exists |
required-challenge-not-completed |
The user has yet to completed the required challenge to unlock this challenge |
Submit a flag for a challenge
Authenticated
{
"flag": "FLAG_TO_BE_SUBMITTED",
"chall": "CHALLENGE_ID"
}
{
"success": true,
"data": "correct/ding dong your flag is wrong"
}
- On a correct solve, this endpoint broadcasts a websocket msg to all connected clients to update the scoreboard
Error | Definition |
---|---|
not-found |
The CHALLENGE_ID specified was invalid |
submitted |
This challenge was already solved |
exceeded |
The user has already exceeded the maximum number of attempts allowed |
submission-disabled |
Challenge submission has been disabled by the admin and no new submissions are allowed |
required-challenge-not-found |
The required challenge was not found. This likely means that the challenge that should be solved to unlock this challenge has been deleted/no longer exists |
required-challenge-not-completed |
The user has yet to completed the required challenge to unlock this challenge |
Create a new challenge
Authenticated // Permissions: 1
{
"name": "CHALLENGE_NAME",
"category": "CATEGORY",
"description": "CHALLENGE_DESCRIPTION (HTML)",
"points": "POINTS (int)",
"flags": [
"FLAG"
],
"tags": [
"TAG"
],
"hints": [
{
"hint": "HINT",
"cost": "HINT_COST (int)"
}
],
"max_attempts": "int",
"visibility": "bool",
"writeup": "writeup_link",
"writeupComplete": true, //whether to show writeup only after challenge is solved
"requires": "required challenge to unlock this challenge",
"dynamic": true // whether the challenge uses dynamic scoring
"initial": 100 // initial score for dynamic challs
"minSolves": 10 // number of solves for the challenge till it decays till the minimum score below
"minimum": 50 // minimum score to decay to for dynamic challs
}
{
"success": true
}
- File uploads have not been implemented
- Validation:
name
,category
,description
,points
,visibility
,dynamic
and at least oneflags
are required fields - Validation must be done on the client side as the server does not produce meaning output (integers are passed through
parseInt
)
Error | Definition |
---|---|
permissions |
The logged-in user does not have sufficient permissions to create a new challenge |
exists |
Another challenge already exists with this name |
validation |
The input was malformed |
Edit a challenge
Authenticated // Permissions: 2
{
"id": "CHALLENGE_ID",
"chall": "CHALLENGE_NAME",
"name": "NEW_CHALLENGE_NAME",
"category": "NEW_CATEGORIES",
"description": "NEW_CHALLENGE_DESCRIPTION (HTML)",
"points": "NEW_POINTS (int)",
"flags": [
"NEW_FLAG"
],
"tags": [
"NEW_TAG"
],
"hints": [{
"hint": "NEW_HINT",
"cost": "NEW_HINT_COST (int)",
"purchased": [
"USERNAME (required, even if empty)"
]
}],
"max_attempts": "int",
"visibility": "bool",
"writeup": "writeup_link",
"writeupComplete": true, //See /new for info on this property,
"requires": "required_challenge",
"dynamic": true // whether the challenge uses dynamic scoring
"initial": 100 // initial score for dynamic challs
"minSolves": 10 // number of solves for the challenge till it decays till the minimum score below
"minimum": 50 // minimum score to decay to for dynamic challs
}
{
"success": true
}
- All fields other than
chall
are optional. -
All entries must be filled with the original data as well (Entries which are marked as
''
, an empty string, will be treated that the user wants to delete that entry)- e.g. to add a new flag, input
["old flag", "new flag"]
- Deletes hint purchases without compensation if this is not done (but can also be used to award hints to users)
- e.g. to add a new flag, input
- File uploads have not been implemented
- Validation must be done on the client side as the server does not produce meaning output (integers are passed not through
parseInt
- perform on client side)
Error | Definition |
---|---|
notfound |
The CHALLENGE_ID specified was not found |
permissions |
The logged-in user does not have sufficient permissions to edit a challenge |
Edit the visibility of a list of challenges
Authenticated // Permissions: 2
{
"challenges": ["CHALLENGE_ID1", "CHALLENE_ID2"...]
}
{
"success": true
}
Error | Definition |
---|---|
notfound |
The CHALLENGE_ID specified was invalid |
permissions |
The logged-in user does not have sufficient permissions to edit a challenge |
validation |
Check that the input is an array |
Edit a category's metadata
Authenticated // Permissions: 2
{
"category": "CATEGORY_NAME",
"new_name": "NEW_CATEGORY_NAME (optional)",
"visibility": "bool (optional)"
}
{
"success": true
}
Error | Definition |
---|---|
notfound |
The CATEGORY_NAME specified was invalid |
permissions |
The logged-in user does not have sufficient permissions to edit a challenge |
Delete a list of challenges
Authenticated // Permissions: 2
{
"chall": ["CHALLENGE_ID", "CHALLENGE_ID2"...]
}
{
"success": true
}
- Deletes transaction records for the challenges as well. Hence, any points earned from this challenge, and any hints taken from this challenge are refunded.
Error | Definition |
---|---|
notfound |
One of the challenges was not found |
permissions |
The logged-in user does not have sufficient permissions to edit a challenge |
Returns the states of the admin panel challenges settings
Authenticated // Permissions: 2
None
{
"success": ,
"states": []
}
Error | Definition |
---|---|
permissions |
The logged-in user does not have sufficient permissions to edit a challenge |