diff --git a/main.js b/main.js index 33ee536..c80e8f1 100644 --- a/main.js +++ b/main.js @@ -11,11 +11,13 @@ import { loadUnlock, displayUnlock, displayHint, + getSolution, loadSolution, displaySolution, displayHintUnlock, displaySolutionUnlock, submitRating, + checkSolution, } from "./pages/challenge"; import { getScoreboard, getScoreboardDetail, getBrackets } from "./pages/scoreboard"; import { updateSettings, generateToken, deleteToken } from "./pages/settings"; @@ -93,6 +95,9 @@ const _functions = { // Display solves for challenge displaySolves: null, + + // Check whether UI should reach out for solution ID + checkSolution: null, }, challenges: { @@ -142,6 +147,8 @@ const pages = { displayHintUnlock, displaySolutionUnlock, displayHint, + getSolution, + checkSolution, loadSolution, displaySolution, submitRating, diff --git a/pages/challenge.js b/pages/challenge.js index 7c61c5f..8edfe3f 100644 --- a/pages/challenge.js +++ b/pages/challenge.js @@ -133,6 +133,34 @@ export async function displaySolves(challengeId) { } } +export async function getSolution(challengeId) { + const response = await CTFd.fetch(`/api/v1/challenges/${challengeId}/solution`, { + method: "GET", + }); + + const body = await response.json(); + return body["data"]; +} + +// Function to check whether the UI should check for a challenge solution +export async function checkSolution(solutionState, challengeData, submissionStatus) { + if (CTFd._functions.challenge.checkSolution) { + return CTFd._functions.challenge.checkSolution( + solutionState, + challengeData, + submissionStatus + ); + } + if (solutionState == "hidden" || solutionState == "visible") { + return false; + } else if (solutionState == "solved" && submissionStatus === "correct") { + return true; + } else { + // We default to true in case there is a solution state that we are not aware of + return true; + } +} + export async function loadSolution(solutionId) { const response = await CTFd.fetch(`/api/v1/solutions/${solutionId}`, { method: "GET",