diff --git a/apps/desktop/package.json b/apps/desktop/package.json index 159d1cc..a9ebbfa 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -4,7 +4,6 @@ "version": "0.1.0", "type": "module", "scripts": { - "dev": "tauri dev", "tauri": "tauri" }, "devDependencies": { diff --git a/packages/api/config/env.ts b/packages/api/config/env.ts index b8d5ea0..0479461 100644 --- a/packages/api/config/env.ts +++ b/packages/api/config/env.ts @@ -17,6 +17,7 @@ const ZodEnvironmentVariables = z.object({ MAIL_LOGGER: z.string(), MAIL_FROM_EMAIL: z.string(), MAIL_FROM_NAME: z.string(), + DISCORD_BLOOD_HOOK: z.string(), }); ZodEnvironmentVariables.parse(process.env); diff --git a/packages/api/helpers/notifyBlood.ts b/packages/api/helpers/notifyBlood.ts new file mode 100644 index 0000000..2bc093b --- /dev/null +++ b/packages/api/helpers/notifyBlood.ts @@ -0,0 +1,43 @@ +import axios from "axios"; + +export const notifyForBlood = async ( + { + teamName, + challengeName, + }: { + teamName: string; + challengeName: string; + } +) => { + try { + const res = await axios.post(process.env.DISCORD_BLOOD_HOOK, { + content: "@here", + tts: false, + embeds: [ + { + id: Date.now().toString(), + description: "", + fields: [], + title: `🎉 ${teamName} owned first blood 🩸 for ${challengeName}`, + color: 7_782_594, + footer: { + icon_url: "https://rcs.encryptedge.in/logo.png", + text: "eeCTF" + }, + author: { + name: "RCS CTF 2024" + } + } + ], + components: [], + actions: {}, + username: "eeCTF Blood Notify" + } + ); + return res.data; + } catch (error) { + if(error instanceof Error) { + throw new TypeError(error.message); + } +} +}; diff --git a/packages/api/services/challenges.service.ts b/packages/api/services/challenges.service.ts index 5aef460..e442de1 100644 --- a/packages/api/services/challenges.service.ts +++ b/packages/api/services/challenges.service.ts @@ -3,9 +3,19 @@ import { SnowflakeId } from "hyperflake"; import { Challenges_Insert_Input, Machines_Insert_Input, Mutation_Root, Query_Root } from "../graphql/types"; import { client } from "../helpers/gqlClient"; +import { notifyForBlood } from "../helpers/notifyBlood"; const snowflake = SnowflakeId(); +interface IBloodCheck extends Query_Root { + blood_check: { + challenge_id: string; + submission: { + submited_flag: string; + }; + }[]; +} + export class ChallengeService { public createMachineS = async (reqBody: IMachineCreateInput) => { try { @@ -164,6 +174,7 @@ export class ChallengeService { public submitFlagS = async (reqBody: IMachineSubmitFlagInput) => { try { + let is_blood_aquired = false; const { challenge_id, submited_flag, team_id, user_id } = reqBody; if (!challenge_id || !submited_flag || !team_id || !user_id) { @@ -175,14 +186,25 @@ export class ChallengeService { scores(where: {challenge_id: {_eq: $challenge_id}, team_id: { _eq: $team_id }}) { id } + + blood_check: scores(where: {challenge_id: {_eq: $challenge_id}}) { + challenge_id + submission { + submited_flag + } + } } `; - const { scores } : Query_Root = await client.request(queryPreCheck, { + const { scores, blood_check } : IBloodCheck = await client.request(queryPreCheck, { challenge_id, team_id, }); + if(blood_check.length > 0){ + is_blood_aquired = true; + } + if(scores.length > 0){ throw new Error("Already solved"); } @@ -236,6 +258,12 @@ export class ChallengeService { id team_id user_id + team { + name + } + challenge { + name + } } } `; @@ -252,6 +280,13 @@ export class ChallengeService { throw new Error("Failed to submit score"); } + if(!is_blood_aquired){ + notifyForBlood({ + teamName: insert_scores_one.team.name, + challengeName: insert_scores_one.challenge.name, + }); + } + return { message: "GG!" };