From e4c4c75983fac8b378e81adec295d4463860a791 Mon Sep 17 00:00:00 2001 From: Han <56923450+waddaboo@users.noreply.github.com> Date: Mon, 4 Nov 2024 17:26:25 +0800 Subject: [PATCH 1/6] feat(api): add invite code validity check --- .../api/src/app/invites/invites.controller.ts | 10 ++++++++++ .../src/app/invites/invites.service.test.ts | 19 +++++++++++++++++++ apps/api/src/app/invites/invites.service.ts | 18 ++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/apps/api/src/app/invites/invites.controller.ts b/apps/api/src/app/invites/invites.controller.ts index 41b0ed05..fc63c39d 100644 --- a/apps/api/src/app/invites/invites.controller.ts +++ b/apps/api/src/app/invites/invites.controller.ts @@ -75,6 +75,16 @@ export class InvitesController { return mapEntity(invite) } + @Get("check/:code/group/:groupId") + @ApiOperation({ description: "Checks if a specific invite is valid." }) + @ApiCreatedResponse({ type: Boolean }) + async checkInvite( + @Param("code") inviteCode: string, + @Param("groupId") groupId: string + ): Promise { + return this.invitesService.checkInvite(inviteCode, groupId) + } + @Patch("redeem") @ApiBody({ type: RedeemInviteDto }) @ApiHeader({ name: "x-api-key", required: true }) diff --git a/apps/api/src/app/invites/invites.service.test.ts b/apps/api/src/app/invites/invites.service.test.ts index 865b95e4..41ade654 100644 --- a/apps/api/src/app/invites/invites.service.test.ts +++ b/apps/api/src/app/invites/invites.service.test.ts @@ -367,6 +367,25 @@ describe("InvitesService", () => { }) }) + describe("# checkInvite", () => { + it("Should return true if invite is valid", async () => { + const { code } = await invitesService.createInvite( + { groupId }, + admin.id + ) + + const invite = await invitesService.checkInvite(code, groupId) + + expect(invite).toBeTruthy() + }) + + it("Should return false if invite is invalid", async () => { + const invite = await invitesService.checkInvite("12345", groupId) + + expect(invite).toBeFalsy() + }) + }) + describe("# redeemInvite", () => { let invite: Invite diff --git a/apps/api/src/app/invites/invites.service.ts b/apps/api/src/app/invites/invites.service.ts index 589e080b..52516b1e 100644 --- a/apps/api/src/app/invites/invites.service.ts +++ b/apps/api/src/app/invites/invites.service.ts @@ -117,6 +117,24 @@ export class InvitesService { return invite } + /** + * Returns boolean value if the invite code is valid. + * @param inviteCode Invite code. + * @param groupId Group id. + * @returns Boolean. + */ + async checkInvite(inviteCode: string, groupId: string): Promise { + const invite = await this.inviteRepository.findOne({ + where: { + code: inviteCode, + group: { id: groupId } + }, + relations: ["group"] + }) + + return !!invite + } + /** * Redeems an invite by consuming its code. Every invite * can be used only once. From 38457e3b6a69c879d03e045fd15e9c81eec4de8e Mon Sep 17 00:00:00 2001 From: Han <56923450+waddaboo@users.noreply.github.com> Date: Mon, 4 Nov 2024 17:27:12 +0800 Subject: [PATCH 2/6] feat(api-sdk): add invite code validity check --- libs/api-sdk/src/apiSdk.ts | 18 +++++++++++++++++- libs/api-sdk/src/index.test.ts | 19 +++++++++++++++++++ libs/api-sdk/src/invites.ts | 25 +++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/libs/api-sdk/src/apiSdk.ts b/libs/api-sdk/src/apiSdk.ts index f0f6b672..0b13ce69 100644 --- a/libs/api-sdk/src/apiSdk.ts +++ b/libs/api-sdk/src/apiSdk.ts @@ -31,7 +31,7 @@ import { getGroupsByType, createAssociatedGroup } from "./groups" -import { createInvite, getInvite, redeemInvite } from "./invites" +import { checkInvite, createInvite, getInvite, redeemInvite } from "./invites" export default class ApiSdk { private _url: string @@ -419,6 +419,22 @@ export default class ApiSdk { return invite } + /** + * Returns boolean value if the invite code is valid. + * @param inviteCode Invite code. + * @param groupId Group id. + * @returns Boolean. + */ + async checkInvite(inviteCode: string, groupId: string): Promise { + const isInviteValid = await checkInvite( + this._config, + inviteCode, + groupId + ) + + return isInviteValid + } + /** * Redeems a specific invite. * @param inviteCode Invite code. diff --git a/libs/api-sdk/src/index.test.ts b/libs/api-sdk/src/index.test.ts index 200fcb42..d51bbf2a 100644 --- a/libs/api-sdk/src/index.test.ts +++ b/libs/api-sdk/src/index.test.ts @@ -1152,6 +1152,25 @@ describe("Bandada API SDK", () => { }) }) + describe("# checkInvite", () => { + it("Should check if an invite is valid", async () => { + const groupId = "95633257675970239314311768035433" + const inviteCode = "C5VAG4HD" + + requestMocked.mockImplementationOnce(() => + Promise.resolve(true) + ) + + const apiSdk: ApiSdk = new ApiSdk(SupportedUrl.DEV) + const isInviteValid = await apiSdk.checkInvite( + inviteCode, + groupId + ) + + expect(isInviteValid).toBeTruthy() + }) + }) + describe("# redeemInvite", () => { it("Should redeem an invite", async () => { const groupId = "95633257675970239314311768035433" diff --git a/libs/api-sdk/src/invites.ts b/libs/api-sdk/src/invites.ts index 70d1031d..49532c2f 100644 --- a/libs/api-sdk/src/invites.ts +++ b/libs/api-sdk/src/invites.ts @@ -21,6 +21,24 @@ export async function getInvite( return invite } +/** + * Returns boolean value if the invite code is valid. + * @param inviteCode Invite code. + * @param groupId Group id. + * @returns Boolean. + */ +export async function checkInvite( + config: object, + inviteCode: string, + groupId: string +): Promise { + const requestUrl = `${url}/check/${inviteCode}/group/${groupId}` + + const req = await request(requestUrl, config) + + return req +} + /** * Creates one new group invite. * @param groupId The group identifier. @@ -47,6 +65,13 @@ export async function createInvite( return req } +/** + * Redeems a specific invite. + * @param inviteCode Invite code to be redeemed. + * @param groupId Group id. + * @param apiKey API Key of the admin. + * @returns The updated redeemed invite. + */ export async function redeemInvite( config: object, inviteCode: string, From 8e9dd3db3eb7eb15763b6496e749440c04070abb Mon Sep 17 00:00:00 2001 From: Han <56923450+waddaboo@users.noreply.github.com> Date: Mon, 4 Nov 2024 17:35:13 +0800 Subject: [PATCH 3/6] feat(client): add invite code validity check --- apps/client/src/api/bandadaAPI.ts | 21 +++++++++++++++++++++ apps/client/src/pages/home.tsx | 11 +++++++++++ 2 files changed, 32 insertions(+) diff --git a/apps/client/src/api/bandadaAPI.ts b/apps/client/src/api/bandadaAPI.ts index 6d629200..c0d5153b 100644 --- a/apps/client/src/api/bandadaAPI.ts +++ b/apps/client/src/api/bandadaAPI.ts @@ -75,6 +75,27 @@ export async function addMemberByInviteCode( } } +export async function checkInvite( + inviteCode: string, + groupId: string +): Promise { + try { + return await request( + `${API_URL}/invites/check/${inviteCode}/group/${groupId}` + ) + } catch (error: any) { + console.error(error) + + if (error.response) { + alert(error.response.statusText) + } else { + alert("Some error occurred!") + } + + return false + } +} + export async function redeemInvite( inviteCode: string, groupId: string diff --git a/apps/client/src/pages/home.tsx b/apps/client/src/pages/home.tsx index f4f5dd19..654af2f4 100644 --- a/apps/client/src/pages/home.tsx +++ b/apps/client/src/pages/home.tsx @@ -63,6 +63,17 @@ export default function HomePage(): JSX.Element { return } + const isValid = await bandadaAPI.checkInvite( + inviteCode, + invite.group.id + ) + + if (!isValid) { + setLoading(false) + alert("Invalid invite code") + return + } + const signer = library.getSigner(account) const message = `Sign this message to generate your Semaphore identity.` From a978e98d0374c2ea68f43b9e74b74ad1a18da723 Mon Sep 17 00:00:00 2001 From: Han <56923450+waddaboo@users.noreply.github.com> Date: Mon, 4 Nov 2024 17:41:23 +0800 Subject: [PATCH 4/6] docs(api-sdk): add checkInvite docs --- libs/api-sdk/README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/libs/api-sdk/README.md b/libs/api-sdk/README.md index 035ce939..0592462d 100644 --- a/libs/api-sdk/README.md +++ b/libs/api-sdk/README.md @@ -521,6 +521,19 @@ const apiKey = "70f07d0d-6aa2-4fe1-b4b9-06c271a641dc" const invite = await apiSdk.getInvite(inviteCode) ``` +## Check invite + +\# **checkInvite**(): _Promise\_ + +Returns boolean value if the invite code is valid. + +```ts +const inviteCode = "C5VAG4HD" +const groupId = "10402173435763029700781503965100" + +const isValid = await apiSdk.checkInvite(inviteCode, groupId) +``` + ## Redeem invite \# **redeemInvite**(): _Promise\_ From 02f6a93ee770b9bed8273a8caecb59725bad9db3 Mon Sep 17 00:00:00 2001 From: Han <56923450+waddaboo@users.noreply.github.com> Date: Mon, 4 Nov 2024 17:45:45 +0800 Subject: [PATCH 5/6] docs: add checkInvite docs --- apps/docs/docs/api-sdk.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/apps/docs/docs/api-sdk.md b/apps/docs/docs/api-sdk.md index 7e78fcdd..1cbe26c2 100644 --- a/apps/docs/docs/api-sdk.md +++ b/apps/docs/docs/api-sdk.md @@ -465,6 +465,19 @@ const apiKey = "70f07d0d-6aa2-4fe1-b4b9-06c271a641dc" const invite = await apiSdk.getInvite(inviteCode) ``` +## Check invite + +\# **checkInvite**(): _Promise\_ + +Returns boolean value if the invite code is valid. + +```ts +const inviteCode = "C5VAG4HD" +const groupId = "10402173435763029700781503965100" + +const isValid = await apiSdk.checkInvite(inviteCode, groupId) +``` + ## Get credential group join URL \# **getCredentialGroupJoinUrl**(): _string_ From f83fd6bbb59d69ffe9cd906de523976804e3d417 Mon Sep 17 00:00:00 2001 From: Han <56923450+waddaboo@users.noreply.github.com> Date: Mon, 4 Nov 2024 17:46:37 +0800 Subject: [PATCH 6/6] docs: add redeemInvite docs --- apps/docs/docs/api-sdk.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/apps/docs/docs/api-sdk.md b/apps/docs/docs/api-sdk.md index 1cbe26c2..dc7bc774 100644 --- a/apps/docs/docs/api-sdk.md +++ b/apps/docs/docs/api-sdk.md @@ -478,6 +478,19 @@ const groupId = "10402173435763029700781503965100" const isValid = await apiSdk.checkInvite(inviteCode, groupId) ``` +## Redeem invite + +\# **redeemInvite**(): _Promise\_ + +Redeems a specific invite. + +```ts +const groupId = "10402173435763029700781503965100" +const inviteCode = "C5VAG4HD" + +const invite = await apiSdk.redeemInvite(inviteCode, groupId) +``` + ## Get credential group join URL \# **getCredentialGroupJoinUrl**(): _string_