diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md deleted file mode 100644 index fec9c6a..0000000 --- a/.github/pull_request_template.md +++ /dev/null @@ -1,33 +0,0 @@ -Date: `` - -Developer Name: `` - ----- - -## Issue Ticket Number:- -`` - -## Description: -`` - - -Is Under Feature Flag -- [ ] Yes -- [ ] No - -Database changes -- [ ] Yes -- [ ] No - -Breaking changes (If your feature is breaking/missing something please mention pending tickets) -- [ ] Yes -- [ ] No - -Is Development Tested? - -- [ ] Yes -- [ ] No - - -### Add relevant Screenshot below ( e.g test coverage etc. ) - diff --git a/.github/workflows/production.yaml b/.github/workflows/production.yaml index b7d269a..11b4c73 100644 --- a/.github/workflows/production.yaml +++ b/.github/workflows/production.yaml @@ -6,7 +6,7 @@ on: jobs: Deploy-to-Cloudflare: runs-on: ubuntu-latest - environment: ${{ vars.CURRENT_ENVIRONMENT }} + environment: production steps: - uses: actions/checkout@v3 - run: npm install @@ -21,6 +21,8 @@ jobs: CRON_JOB_PRIVATE_KEY DISCORD_BOT_PRIVATE_KEY DISCORD_BOT_API_URL + DISCORD_SERVICE_PRIVATE_KEY + FF_CRON_DISCORD_KEY_PAIR_FLOW env: CLOUDFLARE_API_TOKEN: ${{secrets.CLOUDFLARE_API_TOKEN}} CLOUDFLARE_ACCOUNT_ID: ${{secrets.CLOUDFLARE_ACCOUNT_ID}} @@ -28,3 +30,5 @@ jobs: CRON_JOB_PRIVATE_KEY: ${{secrets.CRON_JOB_PRIVATE_KEY}} DISCORD_BOT_PRIVATE_KEY: ${{secrets.DISCORD_BOT_PRIVATE_KEY}} DISCORD_BOT_API_URL: ${{secrets.DISCORD_BOT_API_URL}} + DISCORD_SERVICE_PRIVATE_KEY: ${{secrets.DISCORD_SERVICE_PRIVATE_KEY}} + FF_CRON_DISCORD_KEY_PAIR_FLOW: ${{vars.FF_CRON_DISCORD_KEY_PAIR_FLOW}} diff --git a/.github/workflows/staging.yaml b/.github/workflows/staging.yaml index 4186b2d..6042d7b 100644 --- a/.github/workflows/staging.yaml +++ b/.github/workflows/staging.yaml @@ -6,7 +6,7 @@ on: jobs: Deploy-to-Cloudflare: runs-on: ubuntu-latest - environment: ${{ vars.CURRENT_ENVIRONMENT }} + environment: staging steps: - uses: actions/checkout@v3 - run: npm install @@ -21,6 +21,8 @@ jobs: CRON_JOB_PRIVATE_KEY DISCORD_BOT_PRIVATE_KEY DISCORD_BOT_API_URL + DISCORD_SERVICE_PRIVATE_KEY + FF_CRON_DISCORD_KEY_PAIR_FLOW env: CLOUDFLARE_API_TOKEN: ${{secrets.CLOUDFLARE_API_TOKEN}} CLOUDFLARE_ACCOUNT_ID: ${{secrets.CLOUDFLARE_ACCOUNT_ID}} @@ -28,3 +30,5 @@ jobs: CRON_JOB_PRIVATE_KEY: ${{secrets.CRON_JOB_PRIVATE_KEY}} DISCORD_BOT_PRIVATE_KEY: ${{secrets.DISCORD_BOT_PRIVATE_KEY}} DISCORD_BOT_API_URL: ${{secrets.DISCORD_BOT_API_URL}} + DISCORD_SERVICE_PRIVATE_KEY: ${{secrets.DISCORD_SERVICE_PRIVATE_KEY}} + FF_CRON_DISCORD_KEY_PAIR_FLOW: ${{vars.FF_CRON_DISCORD_KEY_PAIR_FLOW}} diff --git a/package-lock.json b/package-lock.json index 5a00182..08f22f9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,7 +24,7 @@ "ts-jest": "29.1.1", "ts-node": "10.9.1", "typescript": "5.1.6", - "wrangler": "3.0.0" + "wrangler": "3.1.1" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -1245,6 +1245,15 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@fastify/busboy": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.0.0.tgz", + "integrity": "sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ==", + "dev": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", @@ -2441,18 +2450,6 @@ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, - "node_modules/busboy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", - "dev": true, - "dependencies": { - "streamsearch": "^1.1.0" - }, - "engines": { - "node": ">=10.16.0" - } - }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -5784,15 +5781,6 @@ "npm": ">=6" } }, - "node_modules/streamsearch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", - "dev": true, - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -6136,12 +6124,12 @@ } }, "node_modules/undici": { - "version": "5.22.1", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.22.1.tgz", - "integrity": "sha512-Ji2IJhFXZY0x/0tVBXeQwgPlLWw13GVzpsWPQ3rV50IFMMof2I55PZZxtm4P6iNq+L5znYN9nSTAq0ZyE6lSJw==", + "version": "5.26.3", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.26.3.tgz", + "integrity": "sha512-H7n2zmKEWgOllKkIUkLvFmsJQj062lSm3uA4EYApG8gLuiOM0/go9bIoC3HVaSnfg4xunowDE2i9p8drkXuvDw==", "dev": true, "dependencies": { - "busboy": "^1.6.0" + "@fastify/busboy": "^2.0.0" }, "engines": { "node": ">=14.0" @@ -6263,9 +6251,9 @@ } }, "node_modules/wrangler": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.0.0.tgz", - "integrity": "sha512-azppXJjEQeaVg3wxFZJOGDGtpR8e9clHr2aHuanGHOk9vX3gvesCv97BF/n8qh1Y1d7vDKOBdfQW3UOYZNFGNw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.1.1.tgz", + "integrity": "sha512-iG6QGOt+qgSm7UroJ8IJ+JdXEcDcW7yp9ilP0V7alCGhKm8shqa/M1iyMOpukZSCSZo8Vmn5nH2C9OY1PR3dQQ==", "dev": true, "dependencies": { "@cloudflare/kv-asset-handler": "^0.2.0", @@ -6274,7 +6262,7 @@ "blake3-wasm": "^2.1.5", "chokidar": "^3.5.3", "esbuild": "0.16.3", - "miniflare": "^3.0.0", + "miniflare": "^3.0.1", "nanoid": "^3.3.3", "path-to-regexp": "^6.2.0", "selfsigned": "^2.0.1", diff --git a/package.json b/package.json index 492e1a6..452b70b 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "ts-jest": "29.1.1", "ts-node": "10.9.1", "typescript": "5.1.6", - "wrangler": "3.0.0" + "wrangler": "3.1.1" }, "dependencies": { "@tsndr/cloudflare-worker-jwt": "2.2.1" diff --git a/src/constants/commons.ts b/src/constants/commons.ts index 77deb0f..5814c54 100644 --- a/src/constants/commons.ts +++ b/src/constants/commons.ts @@ -1,3 +1,3 @@ export const MISSED_UPDATES_PROD_ROLE_ID = '1183553844811153458'; -export const MISSED_UPDATES_STAGING_ROLE_ID = '1183553844811153458'; +export const MISSED_UPDATES_STAGING_ROLE_ID = '1184201657404362772'; export const MISSED_UPDATES_DEVELOPMENT_ROLE_ID = '1181214205081296896'; diff --git a/src/handlers/scheduledEventHandler.ts b/src/handlers/scheduledEventHandler.ts index e5d81c8..bbb28ac 100644 --- a/src/handlers/scheduledEventHandler.ts +++ b/src/handlers/scheduledEventHandler.ts @@ -72,7 +72,7 @@ export const addMissedUpdatesRole = async (env: env) => { const missedUpdatesUsers = await getMissedUpdatesUsers(env, cursor); - if (!!missedUpdatesUsers && missedUpdatesUsers.usersToAddRole?.length > 1) { + if (!!missedUpdatesUsers && missedUpdatesUsers.usersToAddRole?.length >= 1) { const discordUserIdRoleIdList: DiscordUserRole[] = missedUpdatesUsers.usersToAddRole.map((userId) => ({ userid: userId, roleid: config(env).MISSED_UPDATES_ROLE_ID, @@ -89,6 +89,7 @@ export const addMissedUpdatesRole = async (env: env) => { } cursor = missedUpdatesUsers?.cursor; } + // add logs for the results https://github.com/Real-Dev-Squad/website-backend/issues/1784 } catch (err) { console.error('Error while adding missed updates roles'); } diff --git a/src/services/discordBotServices.ts b/src/services/discordBotServices.ts index 5550262..fea813c 100644 --- a/src/services/discordBotServices.ts +++ b/src/services/discordBotServices.ts @@ -6,8 +6,9 @@ export const updateUserRoles = async (env: env, payload: DiscordUserRole[]): Pro try { const url = config(env).DISCORD_BOT_API_URL; const token = await generateDiscordBotJwt(env); - - const response = await env.DISCORD_BOT.fetch(`${url}/roles?action=add-role`, { + //TODO(@Ajeyakrishna-k): remove dev flag https://github.com/Real-Dev-Squad/discord-slash-commands/issues/193 + const devQuery = env.FF_CRON_DISCORD_KEY_PAIR_FLOW === 'true' ? '&dev=true' : ''; + const response = await env.DISCORD_BOT.fetch(`${url}/roles?action=add-role${devQuery}`, { method: 'POST', headers: { Authorization: `Bearer ${token}`, diff --git a/src/services/rdsBackendService.ts b/src/services/rdsBackendService.ts index 695b0f8..720e08c 100644 --- a/src/services/rdsBackendService.ts +++ b/src/services/rdsBackendService.ts @@ -7,7 +7,7 @@ export const getMissedUpdatesUsers = async (env: env, cursor: string | undefined const baseUrl = config(env).RDS_BASE_API_URL; const url = new URL(`${baseUrl}/tasks/users/discord`); - url.searchParams.append('q', 'status:missed-updates'); + url.searchParams.append('q', 'status:missed-updates -days-count:3'); if (cursor) { url.searchParams.append('cursor', cursor); } @@ -26,7 +26,7 @@ export const getMissedUpdatesUsers = async (env: env, cursor: string | undefined const responseData: DiscordUsersResponse = await response.json(); return responseData?.data; } catch (error) { - console.error('Error occurrent while fetching discord user details'); + console.error('Error occurred while fetching discord user details'); throw error; } }; diff --git a/src/tests/handlers/missedRoleHandler.test.ts b/src/tests/handlers/missedRoleHandler.test.ts index db8f233..0052c37 100644 --- a/src/tests/handlers/missedRoleHandler.test.ts +++ b/src/tests/handlers/missedRoleHandler.test.ts @@ -30,6 +30,15 @@ describe('addMissedUpdatesRole', () => { expect(updateUserRoles).toHaveBeenCalledTimes(2); }); + it('should call getMissedUpdatesUsers and updateUserRoles when theres only one user', async () => { + const usersMockData = { ...missedUpdatesUsersMockWithoutCursor }; + usersMockData.usersToAddRole = usersMockData.usersToAddRole.slice(0, 1); + (getMissedUpdatesUsers as jest.Mock).mockResolvedValueOnce(usersMockData); + await addMissedUpdatesRole({}); + expect(getMissedUpdatesUsers).toHaveBeenCalledTimes(1); + expect(updateUserRoles).toHaveBeenCalledTimes(1); + }); + it('should not call updateUserRoles when there are no users to add role', async () => { (getMissedUpdatesUsers as jest.Mock).mockResolvedValueOnce(missedUpdatesUsersMockWithNoUsers); diff --git a/src/tests/services/rdsBackendService.test.ts b/src/tests/services/rdsBackendService.test.ts index cbf1a28..994f110 100644 --- a/src/tests/services/rdsBackendService.test.ts +++ b/src/tests/services/rdsBackendService.test.ts @@ -21,7 +21,7 @@ describe('rdsBackendService', () => { } as unknown as Response); const result = await getMissedUpdatesUsers({}, cursor); const url = new URL(`${config({}).RDS_BASE_API_URL}/tasks/users/discord`); - url.searchParams.append('q', 'status:missed-updates'); + url.searchParams.append('q', 'status:missed-updates -days-count:3'); expect(fetch).toHaveBeenCalledWith(url, { method: 'GET', headers: { @@ -39,7 +39,7 @@ describe('rdsBackendService', () => { } as unknown as Response); const result = await getMissedUpdatesUsers({}, 'cursorValue'); const url = new URL(`${config({}).RDS_BASE_API_URL}/tasks/users/discord`); - url.searchParams.append('q', 'status:missed-updates'); + url.searchParams.append('q', 'status:missed-updates -days-count:3'); url.searchParams.append('cursor', 'cursorValue'); expect(fetch).toHaveBeenCalledWith(url, { method: 'GET', @@ -62,7 +62,7 @@ describe('rdsBackendService', () => { const consoleSpy = jest.spyOn(console, 'error'); jest.spyOn(global, 'fetch').mockRejectedValueOnce(new Error('Error occurred')); await expect(getMissedUpdatesUsers({}, cursor)).rejects.toThrow('Error occurred'); - expect(consoleSpy).toHaveBeenCalledWith('Error occurrent while fetching discord user details'); + expect(consoleSpy).toHaveBeenCalledWith('Error occurred while fetching discord user details'); }); }); }); diff --git a/src/utils/generateJwt.ts b/src/utils/generateJwt.ts index b086ae0..4a7f278 100644 --- a/src/utils/generateJwt.ts +++ b/src/utils/generateJwt.ts @@ -7,7 +7,7 @@ export const generateJwt = async (env: env) => { const authToken = await jwt.sign( { name: 'Cron Job Handler', - exp: Math.floor(Date.now() / 1000) + 2, + exp: Math.floor(Date.now() / 1000) + 60, }, env.CRON_JOB_PRIVATE_KEY, { algorithm: 'RS256' }, @@ -21,11 +21,13 @@ export const generateJwt = async (env: env) => { export const generateDiscordBotJwt = async (env: env) => { try { + //TODO(@Ajeyakrishna-k): remove dev flag https://github.com/Real-Dev-Squad/discord-slash-commands/issues/193 + const privateKey = env.FF_CRON_DISCORD_KEY_PAIR_FLOW === 'true' ? env.DISCORD_SERVICE_PRIVATE_KEY : env.DISCORD_BOT_PRIVATE_KEY; const authToken = await jwt.sign( { - exp: Math.floor(Date.now() / 1000) + 2, + exp: Math.floor(Date.now() / 1000) + 60, }, - env.DISCORD_BOT_PRIVATE_KEY, + privateKey, { algorithm: 'RS256' }, ); return authToken; diff --git a/src/worker.ts b/src/worker.ts index ea872dd..60bd74d 100644 --- a/src/worker.ts +++ b/src/worker.ts @@ -2,7 +2,7 @@ import { addMissedUpdatesRole, callDiscordNicknameBatchUpdate } from './handlers import { env } from './types/global.types'; const EVERY_6_HOURS = '0 */6 * * *'; -const EVERY_12_HOURS = '0 */12 * * *'; +const EVERY_11_HOURS = '0 */11 * * *'; export default { // eslint-disable-next-line no-unused-vars @@ -11,7 +11,7 @@ export default { case EVERY_6_HOURS: { return await callDiscordNicknameBatchUpdate(env); } - case EVERY_12_HOURS: { + case EVERY_11_HOURS: { return await addMissedUpdatesRole(env); } default: diff --git a/wrangler.toml b/wrangler.toml index da44cc5..2162ea7 100644 --- a/wrangler.toml +++ b/wrangler.toml @@ -22,7 +22,7 @@ services = [ ] [triggers] -crons = ["0 */6 * * *","0 */12 * * *" ] +crons = ["0 */6 * * *","0 */11 * * *" ] # # Durable Object binding - For more information: https://developers.cloudflare.com/workers/runtime-apis/durable-objects # [[durable_objects]]