From f7279f1b966e0cb43fa35d44827d50f2da606d91 Mon Sep 17 00:00:00 2001 From: Stevche Radevski Date: Thu, 28 Nov 2024 12:06:32 +0100 Subject: [PATCH] fix: Use the correct defaults for the invite token expiry (#10344) --- .../__tests__/invite/admin/invite.spec.ts | 31 +++++++++++++++++++ .../__tests__/invite.spec.ts | 13 ++++++-- .../modules/user/src/services/user-module.ts | 9 +++--- 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/integration-tests/http/__tests__/invite/admin/invite.spec.ts b/integration-tests/http/__tests__/invite/admin/invite.spec.ts index cf659a00c1..bbfa33473e 100644 --- a/integration-tests/http/__tests__/invite/admin/invite.spec.ts +++ b/integration-tests/http/__tests__/invite/admin/invite.spec.ts @@ -156,6 +156,37 @@ medusaIntegrationTestRunner({ expect(e.response.data.message).toEqual("Unauthorized") }) }) + + it("should fail to accept with an expired token", async () => { + jest.useFakeTimers() + + const signup = await api.post("/auth/user/emailpass/register", { + email: "test@medusa-commerce.com", + password: "secret_password", + }) + + // Advance time by 25 hours + jest.advanceTimersByTime(25 * 60 * 60 * 1000) + + await api + .post( + `/admin/invites/accept?token=${invite.token}`, + { + first_name: "Another Test", + last_name: "User", + }, + { + headers: { authorization: `Bearer ${signup.data.token}` }, + } + ) + .catch((e) => { + expect(e.response.status).toEqual(401) + expect(e.response.data.message).toEqual("Unauthorized") + }) + + jest.useRealTimers() + }) + it("should resend an invite", async () => { const resendResponse = ( await api.post(`/admin/invites/${invite.id}/resend`, {}, adminHeaders) diff --git a/packages/modules/user/integration-tests/__tests__/invite.spec.ts b/packages/modules/user/integration-tests/__tests__/invite.spec.ts index 11c403597e..bddd63e45a 100644 --- a/packages/modules/user/integration-tests/__tests__/invite.spec.ts +++ b/packages/modules/user/integration-tests/__tests__/invite.spec.ts @@ -1,14 +1,16 @@ -import { IUserModuleService } from "@medusajs/framework/types/dist/user" +import { IUserModuleService } from "@medusajs/framework/types" import { Modules, UserEvents } from "@medusajs/framework/utils" import { MockEventBusService, moduleIntegrationTestRunner, } from "@medusajs/test-utils" +import jwt, { JwtPayload } from "jsonwebtoken" jest.setTimeout(30000) -const today = new Date() -const expireDate = new Date(today.setDate(today.getDate() + 10)) +const expireDate = new Date().setMilliseconds( + new Date().getMilliseconds() + 60 * 60 * 24 +) const defaultInviteData = [ { @@ -111,6 +113,11 @@ moduleIntegrationTestRunner({ id, }) ) + + const tokenContent = jwt.decode(invite.token) as JwtPayload + expect(tokenContent.exp).toBeLessThanOrEqual( + Date.now() / 1000 + 60 * 60 * 24 + ) }) it("should throw an error when an invite with the given id does not exist", async () => { diff --git a/packages/modules/user/src/services/user-module.ts b/packages/modules/user/src/services/user-module.ts index 60712936f0..be41c2b0f4 100644 --- a/packages/modules/user/src/services/user-module.ts +++ b/packages/modules/user/src/services/user-module.ts @@ -27,8 +27,7 @@ type InjectedDependencies = { inviteService: ModulesSdkTypes.IMedusaInternalService } -// 1 day -const DEFAULT_VALID_INVITE_DURATION = 60 * 60 * 24 * 1000 +const DEFAULT_VALID_INVITE_DURATION_SECONDS = 60 * 60 * 24 export default class UserModuleService extends MedusaService<{ User: { @@ -60,7 +59,7 @@ export default class UserModuleService jwtSecret: moduleDeclaration["jwt_secret"], expiresIn: parseInt(moduleDeclaration["valid_duration"]) || - DEFAULT_VALID_INVITE_DURATION, + DEFAULT_VALID_INVITE_DURATION_SECONDS, } if (!this.config.jwtSecret) { @@ -153,7 +152,7 @@ export default class UserModuleService return { id: invite.id, expires_at: new Date().setMilliseconds( - new Date().getMilliseconds() + this.config.expiresIn + new Date().getMilliseconds() + this.config.expiresIn * 1000 ), token: this.generateToken({ id: invite.id, email: invite.email }), } @@ -325,7 +324,7 @@ export default class UserModuleService return { id: invite.id, expires_at: new Date().setMilliseconds( - new Date().getMilliseconds() + this.config.expiresIn + new Date().getMilliseconds() + this.config.expiresIn * 1000 ), token: this.generateToken({ id: invite.id, email: invite.email }), }