feat(auth): stage passenger sign-in on a single identifier field

This commit is contained in:
Abubeker Yasin
2026-08-27 11:37:54 +03:00
parent 1be2cadf0e
commit 979053ea4f
15 changed files with 1034 additions and 182 deletions

View File

@@ -1,4 +1,11 @@
import { IsEmail, IsNotEmpty, IsString, ValidateNested } from 'class-validator';
import {
IsEmail,
IsNotEmpty,
IsString,
IsStrongPassword,
Length,
ValidateNested,
} from 'class-validator';
import { Type } from 'class-transformer';
import { ApiProperty } from '@nestjs/swagger';
@@ -75,3 +82,55 @@ export class FaydaVerifyAndLoginDto {
@IsString()
otp: string;
}
/**
* Step 1 of the staged sign-in. One field: the passenger types either their phone number
* or their email and the server decides which of the three branches follows.
*/
export class IdentifierLookupDto {
@ApiProperty({
example: '+251912345678',
description: 'Phone number or email address — the server detects which',
})
@IsString()
@IsNotEmpty()
identifier: string;
}
/** Step 2a: ask for the SMS code that lets an account with no password set one. */
export class PasswordSetupRequestDto {
@ApiProperty({ example: '+251912345678', description: 'Phone number or email address' })
@IsString()
@IsNotEmpty()
identifier: string;
}
/** Step 2b: redeem the code, set the password, and receive a session in one call. */
export class PasswordSetupCompleteDto {
@ApiProperty({ example: '+251912345678', description: 'Phone number or email address' })
@IsString()
@IsNotEmpty()
identifier: string;
@ApiProperty({ example: '123456', description: '6-digit code received via SMS' })
@IsString()
@Length(4, 10)
otp: string;
// The credential is written directly against iam.user_credentials rather than through
// the IAM's own set-password route, so the IAM's @IsStrongPassword rule has to be
// restated here or weak passwords would slip in unvalidated.
@ApiProperty({ example: 'Str0ng!Pass', format: 'password' })
@IsStrongPassword({
minLength: 8,
minLowercase: 1,
minUppercase: 1,
minNumbers: 1,
minSymbols: 1,
})
newPassword: string;
@ApiProperty({ example: 'Str0ng!Pass', format: 'password' })
@IsString()
confirmPassword: string;
}