-
Notifications
You must be signed in to change notification settings - Fork 13
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
2users), hidden challenges are also returned along with avisibilityproperty 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 type2user) - 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
costkey 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
idfield 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,dynamicand at least oneflagsare 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
challare 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 |