feat: Refresh invite (#6469)
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
import * as crypto from "crypto"
|
||||
|
||||
import { Context, DAL } from "@medusajs/types"
|
||||
import {
|
||||
InjectTransactionManager,
|
||||
MedusaError,
|
||||
ModulesSdkUtils,
|
||||
arrayDifference,
|
||||
} from "@medusajs/utils"
|
||||
import jwt, { JwtPayload } from "jsonwebtoken"
|
||||
|
||||
@@ -13,8 +16,8 @@ type InjectedDependencies = {
|
||||
inviteRepository: DAL.RepositoryService
|
||||
}
|
||||
|
||||
// 7 days
|
||||
const DEFAULT_VALID_INVITE_DURATION = 1000 * 60 * 60 * 24 * 7
|
||||
// 1 day
|
||||
const DEFAULT_VALID_INVITE_DURATION = 60 * 60 * 24
|
||||
|
||||
export default class InviteService<
|
||||
TEntity extends Invite = Invite
|
||||
@@ -85,6 +88,48 @@ export default class InviteService<
|
||||
return await super.update(updates, context)
|
||||
}
|
||||
|
||||
@InjectTransactionManager("inviteRepository_")
|
||||
async refreshInviteTokens(
|
||||
inviteIds: string[],
|
||||
context: Context = {}
|
||||
): Promise<TEntity[]> {
|
||||
const [invites, count] = await super.listAndCount(
|
||||
{ id: inviteIds },
|
||||
{},
|
||||
context
|
||||
)
|
||||
|
||||
if (count !== inviteIds.length) {
|
||||
const missing = arrayDifference(
|
||||
inviteIds,
|
||||
invites.map((invite) => invite.id)
|
||||
)
|
||||
|
||||
if (missing.length > 0) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`The following invites do not exist: ${missing.join(", ")}`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const expiresIn: number =
|
||||
parseInt(this.getOption("valid_duration")) ||
|
||||
DEFAULT_VALID_INVITE_DURATION
|
||||
|
||||
const updates = invites.map((invite) => {
|
||||
return {
|
||||
id: invite.id,
|
||||
expires_at: new Date().setMilliseconds(
|
||||
new Date().getMilliseconds() + expiresIn
|
||||
),
|
||||
token: this.generateToken({ id: invite.id }),
|
||||
}
|
||||
})
|
||||
|
||||
return await super.update(updates, context)
|
||||
}
|
||||
|
||||
@InjectTransactionManager("inviteRepository_")
|
||||
async validateInviteToken(
|
||||
token: string,
|
||||
@@ -119,8 +164,10 @@ export default class InviteService<
|
||||
|
||||
return jwt.sign(data, jwtSecret, {
|
||||
expiresIn,
|
||||
jwtid: crypto.randomUUID(),
|
||||
})
|
||||
}
|
||||
|
||||
private validateToken(data: any): JwtPayload {
|
||||
const jwtSecret = this.getOption("jwt_secret")
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ import {
|
||||
MedusaContext,
|
||||
ModulesSdkUtils,
|
||||
InjectManager,
|
||||
buildEventMessages,
|
||||
CommonEvents,
|
||||
UserEvents,
|
||||
} from "@medusajs/utils"
|
||||
@@ -74,7 +73,53 @@ export default class UserModuleService<
|
||||
token: string,
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<UserTypes.InviteDTO> {
|
||||
return await this.inviteService_.validateInviteToken(token, sharedContext)
|
||||
const invite = await this.inviteService_.validateInviteToken(
|
||||
token,
|
||||
sharedContext
|
||||
)
|
||||
|
||||
return await this.baseRepository_.serialize<UserTypes.InviteDTO>(invite, {
|
||||
populate: true,
|
||||
})
|
||||
}
|
||||
|
||||
@InjectManager("baseRepository_")
|
||||
@EmitEvents()
|
||||
async refreshInviteTokens(
|
||||
inviteIds: string[],
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<UserTypes.InviteDTO[]> {
|
||||
const invites = await this.refreshInviteTokens_(inviteIds, sharedContext)
|
||||
|
||||
sharedContext.messageAggregator?.saveRawMessageData(
|
||||
invites.map((invite) => ({
|
||||
eventName: UserEvents.invite_token_generated,
|
||||
metadata: {
|
||||
service: this.constructor.name,
|
||||
action: "token_generated",
|
||||
object: "invite",
|
||||
},
|
||||
data: invite.id,
|
||||
}))
|
||||
)
|
||||
|
||||
return await this.baseRepository_.serialize<UserTypes.InviteDTO[]>(
|
||||
invites,
|
||||
{
|
||||
populate: true,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@InjectTransactionManager("baseRepository_")
|
||||
async refreshInviteTokens_(
|
||||
inviteIds: string[],
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
) {
|
||||
return await this.inviteService_.refreshInviteTokens(
|
||||
inviteIds,
|
||||
sharedContext
|
||||
)
|
||||
}
|
||||
|
||||
create(
|
||||
@@ -194,6 +239,18 @@ export default class UserModuleService<
|
||||
}))
|
||||
)
|
||||
|
||||
sharedContext.messageAggregator?.saveRawMessageData(
|
||||
invites.map((invite) => ({
|
||||
eventName: UserEvents.invite_token_generated,
|
||||
metadata: {
|
||||
service: this.constructor.name,
|
||||
action: "token_generated",
|
||||
object: "invite",
|
||||
},
|
||||
data: { id: invite.id },
|
||||
}))
|
||||
)
|
||||
|
||||
return Array.isArray(data) ? serializedInvites : serializedInvites[0]
|
||||
}
|
||||
|
||||
@@ -210,7 +267,7 @@ export default class UserModuleService<
|
||||
}
|
||||
})
|
||||
|
||||
return await this.inviteService_.create(toCreate)
|
||||
return await this.inviteService_.create(toCreate, sharedContext)
|
||||
}
|
||||
|
||||
updateInvites(
|
||||
|
||||
Reference in New Issue
Block a user