feat(auth): add phoneNumber to profile update with SMS OTP re-verify
TEC-2722 — PATCH /api/v1/auth/profile now accepts phoneNumber alongside fullName, avatarUrl, and email. Phone changes are deferred until the user confirms the SMS OTP via POST /api/v1/auth/profile/verify-phone, mirroring the existing email-change OTP flow. - Add PhoneChangeRequestedEvent + user.phone_change_otp SMS template - Add VerifyPhoneChangeHandler with Redis-backed 10-minute OTP - Re-check phone uniqueness at verify time to catch races - Extend unit tests for UpdateProfileHandler + add VerifyPhoneChangeHandler spec Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -145,4 +145,9 @@ export class UserEntity extends AggregateRoot<string> {
|
||||
if (email !== undefined) this._email = email;
|
||||
this.updatedAt = new Date();
|
||||
}
|
||||
|
||||
updatePhone(phone: Phone): void {
|
||||
this._phone = phone;
|
||||
this.updatedAt = new Date();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
export { UserRegisteredEvent } from './user-registered.event';
|
||||
export { AgentVerifiedEvent } from './agent-verified.event';
|
||||
export { EmailChangeRequestedEvent } from './email-change-requested.event';
|
||||
export { PhoneChangeRequestedEvent } from './phone-change-requested.event';
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import { type DomainEvent } from '@modules/shared';
|
||||
|
||||
export class PhoneChangeRequestedEvent implements DomainEvent {
|
||||
readonly eventName = 'user.phone_change_requested';
|
||||
readonly occurredAt = new Date();
|
||||
|
||||
constructor(
|
||||
public readonly aggregateId: string,
|
||||
public readonly newPhone: string,
|
||||
public readonly otpCode: string,
|
||||
) {}
|
||||
}
|
||||
Reference in New Issue
Block a user