From 0363e9f12ee745fea7371cf565d6374e30df1abe Mon Sep 17 00:00:00 2001 From: tejaskh3 Date: Mon, 26 May 2025 10:24:36 +0530 Subject: [PATCH 1/4] feat: add feature flag on verify command --- .../workflows/register-commands-production.yaml | 2 +- .../workflows/register-commands-staging.yaml | 2 +- config/config.ts | 6 ++++++ src/constants/commands.ts | 8 ++++++++ src/constants/urls.ts | 4 ++++ src/controllers/baseHandler.ts | 7 ++++++- src/controllers/verifyCommand.ts | 17 +++++++++++++---- src/typeDefinitions/default.types.d.ts | 1 + src/typeDefinitions/verify.types.ts | 5 +++++ 9 files changed, 45 insertions(+), 7 deletions(-) create mode 100644 src/typeDefinitions/verify.types.ts diff --git a/.github/workflows/register-commands-production.yaml b/.github/workflows/register-commands-production.yaml index 0fa0d5b0..f0a2e5d2 100644 --- a/.github/workflows/register-commands-production.yaml +++ b/.github/workflows/register-commands-production.yaml @@ -54,7 +54,7 @@ jobs: with: apiToken: ${{secrets.CLOUDFLARE_API_TOKEN}} accountId: ${{secrets.CLOUDFLARE_ACCOUNT_ID}} - wranglerVersion: '3.57.0' + wranglerVersion: "3.57.0" secrets: | DISCORD_PUBLIC_KEY DISCORD_TOKEN diff --git a/.github/workflows/register-commands-staging.yaml b/.github/workflows/register-commands-staging.yaml index eb26226a..d3e0837d 100644 --- a/.github/workflows/register-commands-staging.yaml +++ b/.github/workflows/register-commands-staging.yaml @@ -54,7 +54,7 @@ jobs: with: apiToken: ${{secrets.CLOUDFLARE_API_TOKEN}} accountId: ${{secrets.CLOUDFLARE_ACCOUNT_ID}} - wranglerVersion: '3.57.0' + wranglerVersion: "3.57.0" secrets: | DISCORD_PUBLIC_KEY DISCORD_TOKEN diff --git a/config/config.ts b/config/config.ts index 70e8e89e..f681517d 100644 --- a/config/config.ts +++ b/config/config.ts @@ -13,6 +13,9 @@ import { RDS_STAGING_STATUS_SITE_URL, RDS_DASHBOARD_SITE_URL, RDS_STAGING_DASHBOARD_SITE_URL, + RDS_MAIN_SITE_URL, + RDS_STAGING_MAIN_SITE_URL, + RDS_DEVELOPMENT_MAIN_SITE_URL, } from "../src/constants/urls"; import { DISCORD_PROFILE_SERVICE_HELP_GROUP, @@ -74,6 +77,7 @@ const config = (env: env) => { PROFILE_SERVICE_HELP_GROUP_ID: DISCORD_PROFILE_SERVICE_HELP_GROUP, RDS_STATUS_SITE_URL: RDS_STATUS_SITE_URL, DASHBOARD_SITE_URL: RDS_DASHBOARD_SITE_URL, + MAIN_SITE_URL: RDS_MAIN_SITE_URL, }, staging: { RDS_BASE_API_URL: RDS_BASE_STAGING_API_URL, @@ -82,6 +86,7 @@ const config = (env: env) => { PROFILE_SERVICE_HELP_GROUP_ID: DISCORD_PROFILE_SERVICE_STAGING_HELP_GROUP, RDS_STATUS_SITE_URL: RDS_STAGING_STATUS_SITE_URL, DASHBOARD_SITE_URL: RDS_STAGING_DASHBOARD_SITE_URL, + MAIN_SITE_URL: RDS_STAGING_MAIN_SITE_URL, }, default: { RDS_BASE_API_URL: RDS_BASE_DEVELOPMENT_API_URL, @@ -91,6 +96,7 @@ const config = (env: env) => { DISCORD_PROFILE_SERVICE_DEVELOPMENT_HELP_GROUP, RDS_STATUS_SITE_URL: RDS_STATUS_SITE_URL, DASHBOARD_SITE_URL: RDS_DASHBOARD_SITE_URL, + MAIN_SITE_URL: RDS_DEVELOPMENT_MAIN_SITE_URL, }, }; diff --git a/src/constants/commands.ts b/src/constants/commands.ts index 0e3fda76..cb909c12 100644 --- a/src/constants/commands.ts +++ b/src/constants/commands.ts @@ -11,6 +11,14 @@ export const VERIFY = { name: "verify", description: "Generate a link with user specific token to link with RDS backend.", + options: [ + { + name: "dev", + description: "want to verify from main site?", + type: 5, + required: false, + }, + ], }; export const GROUP_INVITE = { diff --git a/src/constants/urls.ts b/src/constants/urls.ts index 6ebf15e2..2779c080 100644 --- a/src/constants/urls.ts +++ b/src/constants/urls.ts @@ -27,3 +27,7 @@ export const RDS_STAGING_STATUS_SITE_URL = export const RDS_DASHBOARD_SITE_URL = "https://dashboard.realdevsquad.com"; export const RDS_STAGING_DASHBOARD_SITE_URL = "https://staging-dashboard.realdevsquad.com"; + +export const RDS_MAIN_SITE_URL = "https://realdevsquad.com"; +export const RDS_STAGING_MAIN_SITE_URL = "https://staging-www.realdevsquad.com"; +export const RDS_DEVELOPMENT_MAIN_SITE_URL = "http://localhost:4200"; diff --git a/src/controllers/baseHandler.ts b/src/controllers/baseHandler.ts index 645be466..d40b23c5 100644 --- a/src/controllers/baseHandler.ts +++ b/src/controllers/baseHandler.ts @@ -61,13 +61,18 @@ export async function baseHandler( return helloCommand(message.member.user.id); } case getCommandName(VERIFY): { + const data = message.data?.options as Array; + const dev = data.find( + (item) => item.name === "dev" + ) as unknown as DevFlag; return await verifyCommand( message.member.user.id, message.member.user.avatar, message.member.user.username, message.member.user.discriminator, message.member.joined_at, - env + env, + dev ); } case getCommandName(MENTION_EACH): { diff --git a/src/controllers/verifyCommand.ts b/src/controllers/verifyCommand.ts index f430495e..fe26049a 100644 --- a/src/controllers/verifyCommand.ts +++ b/src/controllers/verifyCommand.ts @@ -8,6 +8,7 @@ import { env } from "../typeDefinitions/default.types"; import { discordEphemeralResponse } from "../utils/discordEphemeralResponse"; import { generateUniqueToken } from "../utils/generateUniqueToken"; import { sendUserDiscordData } from "../utils/sendUserDiscordData"; +import { DevFlag } from "../typeDefinitions/verify.types"; export async function verifyCommand( userId: number, @@ -15,10 +16,10 @@ export async function verifyCommand( userName: string, discriminator: string, discordJoinedAt: string, - env: env + env: env, + dev?: DevFlag ) { const token = await generateUniqueToken(); - const response = await sendUserDiscordData( token, userId, @@ -28,9 +29,17 @@ export async function verifyCommand( discordJoinedAt, env ); + if (response?.status === 201 || response?.status === 200) { - const verificationSiteURL = config(env).VERIFICATION_SITE_URL; - const message = `${VERIFICATION_STRING}\n${verificationSiteURL}/discord?token=${token}\n${VERIFICATION_SUBSTRING}`; + let verificationSiteURL = ""; + let message = ""; + if (dev) { + verificationSiteURL = config(env).MAIN_SITE_URL; + message = `${VERIFICATION_STRING}\n${verificationSiteURL}/discord?dev=true&token=${token}\n${VERIFICATION_SUBSTRING}`; + } else { + verificationSiteURL = config(env).VERIFICATION_SITE_URL; + message = `${VERIFICATION_STRING}\n${verificationSiteURL}/discord?token=${token}\n${VERIFICATION_SUBSTRING}`; + } return discordEphemeralResponse(message); } else { return discordEphemeralResponse(RETRY_COMMAND); diff --git a/src/typeDefinitions/default.types.d.ts b/src/typeDefinitions/default.types.d.ts index b1828b20..fac737f8 100644 --- a/src/typeDefinitions/default.types.d.ts +++ b/src/typeDefinitions/default.types.d.ts @@ -13,6 +13,7 @@ export interface variables { TRACKING_CHANNEL_URL: string; PROFILE_SERVICE_HELP_GROUP_ID: string; RDS_STATUS_SITE_URL: string; + MAIN_SITE_URL: string; } export interface discordCommand { diff --git a/src/typeDefinitions/verify.types.ts b/src/typeDefinitions/verify.types.ts new file mode 100644 index 00000000..f2de01e5 --- /dev/null +++ b/src/typeDefinitions/verify.types.ts @@ -0,0 +1,5 @@ +export type DevFlag = { + name: string; + type: number; + value: boolean; +}; From ba94af449e313175c2e9ef0eddd83a3fa9b473f3 Mon Sep 17 00:00:00 2001 From: tejaskh3 Date: Mon, 26 May 2025 10:50:34 +0530 Subject: [PATCH 2/4] feat: add test cases --- src/controllers/verifyCommand.ts | 3 +- tests/unit/handlers/verifyCommand.test.ts | 63 +++++++++++++++++++++++ 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/src/controllers/verifyCommand.ts b/src/controllers/verifyCommand.ts index fe26049a..5fde0d8e 100644 --- a/src/controllers/verifyCommand.ts +++ b/src/controllers/verifyCommand.ts @@ -29,11 +29,10 @@ export async function verifyCommand( discordJoinedAt, env ); - if (response?.status === 201 || response?.status === 200) { let verificationSiteURL = ""; let message = ""; - if (dev) { + if (dev?.value) { verificationSiteURL = config(env).MAIN_SITE_URL; message = `${VERIFICATION_STRING}\n${verificationSiteURL}/discord?dev=true&token=${token}\n${VERIFICATION_SUBSTRING}`; } else { diff --git a/tests/unit/handlers/verifyCommand.test.ts b/tests/unit/handlers/verifyCommand.test.ts index 8f566293..78e637c0 100644 --- a/tests/unit/handlers/verifyCommand.test.ts +++ b/tests/unit/handlers/verifyCommand.test.ts @@ -10,6 +10,7 @@ import { env, mockDateNow, } from "../../fixtures/fixture"; +import { DevFlag } from "../../../src/typeDefinitions/verify.types"; describe("verifyCommand", () => { beforeEach(() => { @@ -24,6 +25,68 @@ describe("verifyCommand", () => { jest.spyOn(Date, "now").mockRestore(); }); + test("should return message with verification site url when dev is false", async () => { + jest.spyOn(global, "fetch").mockResolvedValueOnce({ + ok: true, + status: 200, + json: jest.fn().mockResolvedValueOnce(discordUserData), + } as unknown as Response); + + const { verifyCommand } = await import( + "../../../src/controllers/verifyCommand" + ); + + const result = await verifyCommand( + 1, + "userAvatarHash", + "userName", + "discriminator", + "2021-07-25T19:25:16.172000+00:00", + env, + { + value: false, + type: 5, + name: "dev", + } as DevFlag + ); + + const resultText = await result.text(); + const resultData = JSON.parse(resultText); + + const verificationSiteURL = config(env).VERIFICATION_SITE_URL; + const message = `${VERIFICATION_STRING}\n${verificationSiteURL}/discord?token=${UNIQUE_TOKEN}\n${VERIFICATION_SUBSTRING}`; + expect(resultData.data.content).toEqual(message); + }); + + test("should return message with verification site url when dev is true", async () => { + jest.spyOn(global, "fetch").mockResolvedValueOnce({ + ok: true, + status: 200, + json: jest.fn().mockResolvedValueOnce(discordUserData), + } as unknown as Response); + + const { verifyCommand } = await import( + "../../../src/controllers/verifyCommand" + ); + + const result = await verifyCommand( + 1, + "userAvatarHash", + "userName", + "discriminator", + "2021-07-25T19:25:16.172000+00:00", + env, + { value: true, type: 5, name: "dev" } as DevFlag + ); + + const resultText = await result.text(); + const resultData = JSON.parse(resultText); + + const verificationSiteURL = config(env).MAIN_SITE_URL; + const message = `${VERIFICATION_STRING}\n${verificationSiteURL}/discord?dev=true&token=${UNIQUE_TOKEN}\n${VERIFICATION_SUBSTRING}`; + expect(resultData.data.content).toEqual(message); + }); + test("should return JSON response when response is ok", async () => { jest.spyOn(global, "fetch").mockResolvedValueOnce({ ok: true, From d1d97d0bbeea1fc7f1a670ea83e67653153cd1a5 Mon Sep 17 00:00:00 2001 From: tejaskh3 Date: Mon, 26 May 2025 11:03:10 +0530 Subject: [PATCH 3/4] fix: comments --- src/constants/commands.ts | 2 +- src/controllers/baseHandler.ts | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/constants/commands.ts b/src/constants/commands.ts index cb909c12..d1a00d39 100644 --- a/src/constants/commands.ts +++ b/src/constants/commands.ts @@ -14,7 +14,7 @@ export const VERIFY = { options: [ { name: "dev", - description: "want to verify from main site?", + description: "Use new website for verification.", type: 5, required: false, }, diff --git a/src/controllers/baseHandler.ts b/src/controllers/baseHandler.ts index d40b23c5..6c79bef5 100644 --- a/src/controllers/baseHandler.ts +++ b/src/controllers/baseHandler.ts @@ -62,9 +62,14 @@ export async function baseHandler( } case getCommandName(VERIFY): { const data = message.data?.options as Array; - const dev = data.find( - (item) => item.name === "dev" - ) as unknown as DevFlag; + const devOption = data?.find((item) => item.name === "dev"); + const dev = devOption + ? ({ + name: devOption.name, + type: devOption.type, + value: Boolean(devOption.value), + } as DevFlag) + : undefined; return await verifyCommand( message.member.user.id, message.member.user.avatar, From 33afc2ea968544dfba0d8032baf30825ac57608c Mon Sep 17 00:00:00 2001 From: tejaskh3 Date: Tue, 27 May 2025 02:24:41 +0530 Subject: [PATCH 4/4] revert: yml file changes --- .github/workflows/register-commands-production.yaml | 1 - .github/workflows/register-commands-staging.yaml | 1 - 2 files changed, 2 deletions(-) diff --git a/.github/workflows/register-commands-production.yaml b/.github/workflows/register-commands-production.yaml index f0a2e5d2..83d45d9f 100644 --- a/.github/workflows/register-commands-production.yaml +++ b/.github/workflows/register-commands-production.yaml @@ -54,7 +54,6 @@ jobs: with: apiToken: ${{secrets.CLOUDFLARE_API_TOKEN}} accountId: ${{secrets.CLOUDFLARE_ACCOUNT_ID}} - wranglerVersion: "3.57.0" secrets: | DISCORD_PUBLIC_KEY DISCORD_TOKEN diff --git a/.github/workflows/register-commands-staging.yaml b/.github/workflows/register-commands-staging.yaml index d3e0837d..ad30ff32 100644 --- a/.github/workflows/register-commands-staging.yaml +++ b/.github/workflows/register-commands-staging.yaml @@ -54,7 +54,6 @@ jobs: with: apiToken: ${{secrets.CLOUDFLARE_API_TOKEN}} accountId: ${{secrets.CLOUDFLARE_ACCOUNT_ID}} - wranglerVersion: "3.57.0" secrets: | DISCORD_PUBLIC_KEY DISCORD_TOKEN