From 51ebce17b6a89abe041cf9d0880439f441b195ef Mon Sep 17 00:00:00 2001 From: ccocoa <270871570+ccocoa@users.noreply.github.com> Date: Sun, 28 Jun 2026 10:12:09 +0000 Subject: [PATCH] feat: setup cloudflare pages with functions and update flag validation - Added `functions/api/verify.js` for server-side flag validation. - Added `.github/workflows/cloudflare-pages.yml` for CI/CD. - Updated `src/scripts/main.js` to use the new API endpoint instead of localStorage. Co-authored-by: thirapi <132630759+thirapi@users.noreply.github.com> --- .github/workflows/cloudflare-pages.yml | 19 ++++++++++++++++++ functions/api/verify.js | 20 +++++++++++++++++++ src/scripts/main.js | 27 ++++++++++++++++++-------- 3 files changed, 58 insertions(+), 8 deletions(-) create mode 100644 .github/workflows/cloudflare-pages.yml create mode 100644 functions/api/verify.js diff --git a/.github/workflows/cloudflare-pages.yml b/.github/workflows/cloudflare-pages.yml new file mode 100644 index 0000000..b1219f6 --- /dev/null +++ b/.github/workflows/cloudflare-pages.yml @@ -0,0 +1,19 @@ +name: Cloudflare Pages +on: [push] +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Install dependencies + run: npm install + - name: Build + run: npm run build + - name: Publish + uses: cloudflare/pages-action@v1 + with: + apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} + accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + projectName: 'ctf-platform' + directory: 'dist' + gitHubToken: ${{ secrets.GITHUB_TOKEN }} diff --git a/functions/api/verify.js b/functions/api/verify.js new file mode 100644 index 0000000..a525612 --- /dev/null +++ b/functions/api/verify.js @@ -0,0 +1,20 @@ +export async function onRequestPost(context) { + const { request } = context; + const body = await request.json(); + const { levelId, flag } = body; + + // Logika validasi sederhana + // Dalam produksi, gunakan database atau secret + const expectedFlag = `CTF{SECRET_${levelId}}`; + + if (flag === expectedFlag) { + return new Response(JSON.stringify({ success: true, message: 'Flag benar!' }), { + headers: { 'Content-Type': 'application/json' }, + }); + } + + return new Response(JSON.stringify({ success: false, message: 'Flag salah!' }), { + status: 400, + headers: { 'Content-Type': 'application/json' }, + }); +} diff --git a/src/scripts/main.js b/src/scripts/main.js index 3192a49..73f75bf 100644 --- a/src/scripts/main.js +++ b/src/scripts/main.js @@ -95,15 +95,26 @@ window.runTask = function(id) { document.getElementById(`display-${id}`).innerHTML = input; } -window.submitTask = function(id) { +window.submitTask = async function(id) { const input = document.getElementById(`flag-${id}`).value; - const correctFlag = getSessionFlag(id); - if (input === correctFlag) { - localStorage.setItem(`task_done_${id}`, 'true'); - alert('Mantap, flag benar!'); - renderMissionBoard(); - } else { - alert('Flag salah, coba lagi!'); + try { + const response = await fetch('/api/verify', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ levelId: id, flag: input }) + }); + const result = await response.json(); + + if (result.success) { + localStorage.setItem(`task_done_${id}`, 'true'); + alert('Mantap, flag benar!'); + renderMissionBoard(); + } else { + alert(result.message); + } + } catch (error) { + console.error('Error:', error); + alert('Terjadi kesalahan saat memvalidasi flag.'); } }