Skip to content

Commit a57345f

Browse files
authored
Add methods and events for email verification and password reset (#1048)
## Description - Add `email_verification.created` and `password_reset.created` events - Add `GET /user_management/email_verification/:id` endpoint - Add `GET /user_management/password_reset/:id` and `POST /user_management/password_reset` endpoints - Deprecate current send password reset endpoint ## Documentation Does this require changes to the WorkOS Docs? E.g. the [API Reference](https://workos.com/docs/reference) or code snippets need updates. ``` [x] Yes ``` If yes, link a related docs PR and add a docs maintainer as a reviewer. Their approval is required. workos/workos#27414
1 parent 6902fa5 commit a57345f

16 files changed

+346
-2
lines changed

src/common/interfaces/event.interface.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,14 @@ import {
1212
} from '../../organizations/interfaces';
1313
import { Connection, ConnectionResponse } from '../../sso/interfaces';
1414
import {
15+
EmailVerificationEvent,
16+
EmailVerificationEventResponse,
1517
InvitationEvent,
1618
InvitationEventResponse,
1719
MagicAuthEvent,
1820
MagicAuthEventResponse,
21+
PasswordResetEvent,
22+
PasswordResetEventResponse,
1923
Session,
2024
SessionResponse,
2125
User,
@@ -196,6 +200,17 @@ export interface DsyncUserUpdatedEventResponse extends EventResponseBase {
196200
data: DirectoryUserResponse & Record<'previous_attributes', any>;
197201
}
198202

203+
export interface EmailVerificationCreatedEvent extends EventBase {
204+
event: 'email_verification.created';
205+
data: EmailVerificationEvent;
206+
}
207+
208+
export interface EmailVerificationCreatedEventResponse
209+
extends EventResponseBase {
210+
event: 'email_verification.created';
211+
data: EmailVerificationEventResponse;
212+
}
213+
199214
export interface InvitationCreatedEvent extends EventBase {
200215
event: 'invitation.created';
201216
data: InvitationEvent;
@@ -216,6 +231,16 @@ export interface MagicAuthCreatedEventResponse extends EventResponseBase {
216231
data: MagicAuthEventResponse;
217232
}
218233

234+
export interface PasswordResetCreatedEvent extends EventBase {
235+
event: 'password_reset.created';
236+
data: PasswordResetEvent;
237+
}
238+
239+
export interface PasswordResetCreatedEventResponse extends EventResponseBase {
240+
event: 'password_reset.created';
241+
data: PasswordResetEventResponse;
242+
}
243+
219244
export interface UserCreatedEvent extends EventBase {
220245
event: 'user.created';
221246
data: User;
@@ -387,8 +412,10 @@ export type Event =
387412
| DsyncUserCreatedEvent
388413
| DsyncUserUpdatedEvent
389414
| DsyncUserDeletedEvent
415+
| EmailVerificationCreatedEvent
390416
| InvitationCreatedEvent
391417
| MagicAuthCreatedEvent
418+
| PasswordResetCreatedEvent
392419
| UserCreatedEvent
393420
| UserUpdatedEvent
394421
| UserDeletedEvent
@@ -419,8 +446,10 @@ export type EventResponse =
419446
| DsyncUserCreatedEventResponse
420447
| DsyncUserUpdatedEventResponse
421448
| DsyncUserDeletedEventResponse
449+
| EmailVerificationCreatedEventResponse
422450
| InvitationCreatedEventResponse
423451
| MagicAuthCreatedEventResponse
452+
| PasswordResetCreatedEventResponse
424453
| UserCreatedEventResponse
425454
| UserUpdatedEventResponse
426455
| UserDeletedEventResponse

src/common/serializers/event.serializer.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ import {
99
import { deserializeOrganization } from '../../organizations/serializers';
1010
import { deserializeConnection } from '../../sso/serializers';
1111
import {
12+
deserializeEmailVerificationEvent,
1213
deserializeInvitationEvent,
1314
deserializeMagicAuthEvent,
15+
deserializePasswordResetEvent,
1416
deserializeUser,
1517
} from '../../user-management/serializers';
1618
import { deserializeOrganizationMembership } from '../../user-management/serializers/organization-membership.serializer';
@@ -83,6 +85,12 @@ export const deserializeEvent = (event: EventResponse): Event => {
8385
event: event.event,
8486
data: deserializeUpdatedEventDirectoryUser(event.data),
8587
};
88+
case 'email_verification.created':
89+
return {
90+
...eventBase,
91+
event: event.event,
92+
data: deserializeEmailVerificationEvent(event.data),
93+
};
8694
case 'invitation.created':
8795
return {
8896
...eventBase,
@@ -95,6 +103,12 @@ export const deserializeEvent = (event: EventResponse): Event => {
95103
event: event.event,
96104
data: deserializeMagicAuthEvent(event.data),
97105
};
106+
case 'password_reset.created':
107+
return {
108+
...eventBase,
109+
event: event.event,
110+
data: deserializePasswordResetEvent(event.data),
111+
};
98112
case 'user.created':
99113
case 'user.updated':
100114
case 'user.deleted':
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"object": "email_verification",
3+
"id": "email_verification_01H5JQDV7R7ATEYZDEG0W5PRYS",
4+
"user_id": "user_01H5JQDV7R7ATEYZDEG0W5PRYS",
5+
"email": "[email protected]",
6+
"expires_at": "2023-07-18T02:07:19.911Z",
7+
"code": "123456",
8+
"created_at": "2023-07-18T02:07:19.911Z",
9+
"updated_at": "2023-07-18T02:07:19.911Z"
10+
}

src/user-management/fixtures/invitation.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"organization_id": "org_01H5JQDV7R7ATEYZDEG0W5PRYS",
1010
"inviter_user_id": null,
1111
"token": "Z1uX3RbwcIl5fIGJJJCXXisdI",
12-
"accept_invitation_url": "https://myauthkit.com/invite?invitation_token=Z1uX3RbwcIl5fIGJJJCXXisdI",
12+
"accept_invitation_url": "https://your-app.com/invite?invitation_token=Z1uX3RbwcIl5fIGJJJCXXisdI",
1313
"created_at": "2023-07-18T02:07:19.911Z",
1414
"updated_at": "2023-07-18T02:07:19.911Z"
1515
}

src/user-management/fixtures/list-invitations.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"organization_id": "org_01H5JQDV7R7ATEYZDEG0W5PRYS",
1313
"inviter_user_id": null,
1414
"token": "Z1uX3RbwcIl5fIGJJJCXXisdI",
15-
"accept_invitation_url": "https://myauthkit.com/invite?invitation_token=Z1uX3RbwcIl5fIGJJJCXXisdI",
15+
"accept_invitation_url": "https://your-app.com/invite?invitation_token=Z1uX3RbwcIl5fIGJJJCXXisdI",
1616
"created_at": "2023-07-18T02:07:19.911Z",
1717
"updated_at": "2023-07-18T02:07:19.911Z"
1818
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"object": "password_reset",
3+
"id": "password_reset_01H5JQDV7R7ATEYZDEG0W5PRYS",
4+
"user_id": "user_01H5JQDV7R7ATEYZDEG0W5PRYS",
5+
"email": "[email protected]",
6+
"password_reset_token": "Z1uX3RbwcIl5fIGJJJCXXisdI",
7+
"password_reset_url": "https://your-app.com/reset-password?token=Z1uX3RbwcIl5fIGJJJCXXisdI",
8+
"expires_at": "2023-07-18T02:07:19.911Z",
9+
"created_at": "2023-07-18T02:07:19.911Z"
10+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export interface CreatePasswordResetOptions {
2+
email: string;
3+
}
4+
5+
export interface SerializedCreatePasswordResetOptions {
6+
email: string;
7+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
export interface EmailVerification {
2+
object: 'email_verification';
3+
id: string;
4+
userId: string;
5+
email: string;
6+
expiresAt: string;
7+
code: string;
8+
createdAt: string;
9+
updatedAt: string;
10+
}
11+
12+
export interface EmailVerificationEvent {
13+
object: 'email_verification';
14+
id: string;
15+
userId: string;
16+
email: string;
17+
expiresAt: string;
18+
createdAt: string;
19+
updatedAt: string;
20+
}
21+
22+
export interface EmailVerificationResponse {
23+
object: 'email_verification';
24+
id: string;
25+
user_id: string;
26+
email: string;
27+
expires_at: string;
28+
code: string;
29+
created_at: string;
30+
updated_at: string;
31+
}
32+
33+
export interface EmailVerificationEventResponse {
34+
object: 'email_verification';
35+
id: string;
36+
user_id: string;
37+
email: string;
38+
expires_at: string;
39+
created_at: string;
40+
updated_at: string;
41+
}

src/user-management/interfaces/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ export * from './authenticate-with-totp-options.interface';
1111
export * from './authentication-response.interface';
1212
export * from './create-magic-auth-options.interface';
1313
export * from './create-organization-membership-options.interface';
14+
export * from './create-password-reset-options.interface';
1415
export * from './create-user-options.interface';
16+
export * from './email-verification.interface';
1517
export * from './enroll-auth-factor.interface';
1618
export * from './factor.interface';
1719
export * from './impersonator.interface';
@@ -22,6 +24,7 @@ export * from './list-organization-memberships-options.interface';
2224
export * from './list-users-options.interface';
2325
export * from './magic-auth.interface';
2426
export * from './organization-membership.interface';
27+
export * from './password-reset.interface';
2528
export * from './reset-password-options.interface';
2629
export * from './revoke-session-options.interface';
2730
export * from './send-invitation-options.interface';
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
export interface PasswordReset {
2+
object: 'password_reset';
3+
id: string;
4+
userId: string;
5+
email: string;
6+
passwordResetToken: string;
7+
passwordResetUrl: string;
8+
expiresAt: string;
9+
createdAt: string;
10+
}
11+
12+
export interface PasswordResetEvent {
13+
object: 'password_reset';
14+
id: string;
15+
userId: string;
16+
email: string;
17+
expiresAt: string;
18+
createdAt: string;
19+
}
20+
21+
export interface PasswordResetResponse {
22+
object: 'password_reset';
23+
id: string;
24+
user_id: string;
25+
email: string;
26+
password_reset_token: string;
27+
password_reset_url: string;
28+
expires_at: string;
29+
created_at: string;
30+
}
31+
32+
export interface PasswordResetEventResponse {
33+
object: 'password_reset';
34+
id: string;
35+
user_id: string;
36+
email: string;
37+
expires_at: string;
38+
created_at: string;
39+
}

0 commit comments

Comments
 (0)