feat: Reset password (#8962)
* wip * more work * wip * more work * wrap up first iteration * work on new approach * more work * move middleware func to route * cleanup * more work * wrap up * more work * fix workflow * minor tweaks * finalize * Use JWT secret instead
This commit is contained in:
1 parent
2c5e72d141
commit
e27056b3c3
29 files changed
+633
-194
No files matched your search
@@ -1 +1,3 @@
|
||||
export * from "./steps"
|
||||
export * from "./workflows"
|
||||
|
||||
@@ -30,7 +30,7 @@ export const setAuthAppMetadataStep = createStep(
|
||||
|
||||
appMetadata[key] = data.value
|
||||
|
||||
await service.updateAuthIdentites({
|
||||
await service.updateAuthIdentities({
|
||||
id: authIdentity.id,
|
||||
app_metadata: appMetadata,
|
||||
})
|
||||
@@ -58,7 +58,7 @@ export const setAuthAppMetadataStep = createStep(
|
||||
delete appMetadata[key]
|
||||
}
|
||||
|
||||
await service.updateAuthIdentites({
|
||||
await service.updateAuthIdentities({
|
||||
id: authIdentity.id,
|
||||
app_metadata: appMetadata,
|
||||
})
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
import {
|
||||
AuthWorkflowEvents,
|
||||
generateJwtToken,
|
||||
MedusaError,
|
||||
} from "@medusajs/utils";
|
||||
import {
|
||||
createWorkflow,
|
||||
transform,
|
||||
WorkflowResponse,
|
||||
} from "@medusajs/workflows-sdk";
|
||||
import { emitEventStep, useRemoteQueryStep } from "../../common";
|
||||
|
||||
export const generateResetPasswordTokenWorkflow = createWorkflow(
|
||||
"generate-reset-password-token",
|
||||
(input: { entityId: string; provider: string; secret: string }) => {
|
||||
const providerIdentities = useRemoteQueryStep({
|
||||
entry_point: "provider_identity",
|
||||
fields: ["auth_identity_id", "provider_metadata"],
|
||||
variables: {
|
||||
filters: {
|
||||
entity_id: input.entityId,
|
||||
provider: input.provider,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const token = transform(
|
||||
{ input, providerIdentities },
|
||||
({ input, providerIdentities }) => {
|
||||
const providerIdentity = providerIdentities?.[0]
|
||||
|
||||
if (!providerIdentity) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Provider identity with entity_id ${input.entityId} and provider ${input.provider} not found`
|
||||
)
|
||||
}
|
||||
|
||||
const token = generateJwtToken(
|
||||
{
|
||||
entity_id: input.entityId,
|
||||
provider: input.provider,
|
||||
},
|
||||
{
|
||||
secret: input.secret,
|
||||
expiresIn: "15m",
|
||||
}
|
||||
)
|
||||
|
||||
return token
|
||||
}
|
||||
)
|
||||
|
||||
emitEventStep({
|
||||
eventName: AuthWorkflowEvents.PASSWORD_RESET,
|
||||
data: { entity_id: input.entityId, token },
|
||||
})
|
||||
|
||||
return new WorkflowResponse(token)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1 @@
|
||||
export * from "./generate-reset-password-token"
|
||||
@@ -83,6 +83,11 @@ export type ProviderIdentityDTO = {
|
||||
*/
|
||||
entity_id: string
|
||||
|
||||
/**
|
||||
* The ID of the auth identity linked to the provider identity.
|
||||
*/
|
||||
auth_identity_id?: string
|
||||
|
||||
/**
|
||||
* The auth identity linked to the provider identity.
|
||||
*/
|
||||
@@ -205,6 +210,11 @@ export interface FilterableProviderIdentityProps
|
||||
*/
|
||||
entity_id?: string
|
||||
|
||||
/**
|
||||
* Filter the provider identities by the ID of the auth identity they are linked to.
|
||||
*/
|
||||
auth_identity_id?: string
|
||||
|
||||
/**
|
||||
* The provider handle to filter the provider identity by.
|
||||
*/
|
||||
|
||||
@@ -41,4 +41,8 @@ export interface IAuthProvider {
|
||||
data: AuthenticationInput,
|
||||
authIdentityProviderService: AuthIdentityProviderService
|
||||
): Promise<AuthenticationResponse>
|
||||
update: (
|
||||
data: Record<string, unknown>,
|
||||
authIdentityProviderService: AuthIdentityProviderService
|
||||
) => Promise<AuthenticationResponse>
|
||||
}
|
||||
@@ -54,6 +54,11 @@ export interface IAuthModuleService extends IModuleService {
|
||||
providerData: AuthenticationInput
|
||||
): Promise<AuthenticationResponse>
|
||||
|
||||
updateProvider(
|
||||
provider: string,
|
||||
providerData: Record<string, unknown>
|
||||
): Promise<AuthenticationResponse>
|
||||
|
||||
/**
|
||||
* When authenticating users with a third-party provider, such as Google, the user performs an
|
||||
* action to finish the authentication, such as enter their credentials in Google's sign-in
|
||||
@@ -244,13 +249,13 @@ export interface IAuthModuleService extends IModuleService {
|
||||
* @returns {Promise<AuthIdentityDTO[]>} The updated auths.
|
||||
*
|
||||
* @example
|
||||
* const authIdentities = await authModuleService.updateAuthIdentites([
|
||||
* const authIdentities = await authModuleService.updateAuthIdentities([
|
||||
* {
|
||||
* id: "authusr_123",
|
||||
* },
|
||||
* ])
|
||||
*/
|
||||
updateAuthIdentites(
|
||||
updateAuthIdentities(
|
||||
data: UpdateAuthIdentityDTO[],
|
||||
sharedContext?: Context
|
||||
): Promise<AuthIdentityDTO[]>
|
||||
@@ -263,11 +268,11 @@ export interface IAuthModuleService extends IModuleService {
|
||||
* @returns {Promise<AuthIdentityDTO>} The updated auth.
|
||||
*
|
||||
* @example
|
||||
* const authIdentity = await authModuleService.updateAuthIdentites({
|
||||
* const authIdentity = await authModuleService.updateAuthIdentities({
|
||||
* id: "authusr_123",
|
||||
* })
|
||||
*/
|
||||
updateAuthIdentites(
|
||||
updateAuthIdentities(
|
||||
data: UpdateAuthIdentityDTO,
|
||||
sharedContext?: Context
|
||||
): Promise<AuthIdentityDTO>
|
||||
@@ -399,7 +404,7 @@ export interface IAuthModuleService extends IModuleService {
|
||||
* },
|
||||
* ])
|
||||
*/
|
||||
updateProviderIdentites(
|
||||
updateProviderIdentities(
|
||||
data: UpdateProviderIdentityDTO[],
|
||||
sharedContext?: Context
|
||||
): Promise<ProviderIdentityDTO[]>
|
||||
@@ -412,11 +417,11 @@ export interface IAuthModuleService extends IModuleService {
|
||||
* @returns {Promise<ProviderIdentityDTO>} The updated provider identity.
|
||||
*
|
||||
* @example
|
||||
* const providerIdentity = await authModuleService.updateProviderIdentites({
|
||||
* const providerIdentity = await authModuleService.updateProviderIdentities({
|
||||
* id: "provider_123",
|
||||
* })
|
||||
*/
|
||||
updateProviderIdentites(
|
||||
updateProviderIdentities(
|
||||
data: UpdateProviderIdentityDTO,
|
||||
sharedContext?: Context
|
||||
): Promise<ProviderIdentityDTO>
|
||||
|
||||
@@ -2,7 +2,7 @@ import {
|
||||
AuthenticationInput,
|
||||
AuthenticationResponse,
|
||||
AuthIdentityProviderService,
|
||||
IAuthProvider,
|
||||
IAuthProvider
|
||||
} from "@medusajs/types"
|
||||
|
||||
/**
|
||||
@@ -238,6 +238,15 @@ export abstract class AbstractAuthModuleProvider implements IAuthProvider {
|
||||
)
|
||||
}
|
||||
|
||||
update(
|
||||
data: Record<string, unknown>,
|
||||
authIdentityProviderService: AuthIdentityProviderService
|
||||
): Promise<AuthenticationResponse> {
|
||||
throw new Error(
|
||||
`Method 'update' not implemented for provider ${this.provider}`
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* This method validates the callback of an authentication request.
|
||||
*
|
||||
|
||||
@@ -10,6 +10,16 @@ export const OrderWorkflowEvents = {
|
||||
COMPLETED: "order.completed",
|
||||
}
|
||||
|
||||
export const UserWorkflowEvents = {
|
||||
CREATED: "user.created",
|
||||
UPDATED: "user.updated",
|
||||
DELETED: "user.deleted",
|
||||
}
|
||||
|
||||
export const AuthWorkflowEvents = {
|
||||
PASSWORD_RESET: "auth.password_reset",
|
||||
}
|
||||
|
||||
export const SalesChannelWorkflowEvents = {
|
||||
CREATED: "sales-channel.created",
|
||||
UPDATED: "sales-channel.updated",
|
||||
|
||||
@@ -7,9 +7,3 @@ export const UserEvents = {
|
||||
...buildEventNamesFromEntityName(eventBaseNames, Modules.USER),
|
||||
INVITE_TOKEN_GENERATED: `${Modules.USER}.user.invite.token_generated`,
|
||||
}
|
||||
|
||||
export const UserWorkflowEvents = {
|
||||
CREATED: "user.created",
|
||||
UPDATED: "user.updated",
|
||||
DELETED: "user.deleted",
|
||||
}
|
||||
Reference in new issue
Block a user