mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
fix: add user email fall back
This commit is contained in:
@@ -421,7 +421,10 @@ export class CompaniesController {
|
||||
@CurrentUser() user: CurrentIamUser,
|
||||
@Body() dto: CompleteIdentityVerificationDto,
|
||||
): Promise<CompanyIdentityStateDto> {
|
||||
return this.companiesService.completeIdentityVerification(user.id, dto);
|
||||
return this.companiesService.completeIdentityVerification(user.id, dto, {
|
||||
email: user.email,
|
||||
phoneNumber: user.phoneNumber,
|
||||
});
|
||||
}
|
||||
|
||||
@Post("identity/gm/same-as-owner")
|
||||
@@ -434,7 +437,10 @@ export class CompaniesController {
|
||||
async setGmSameAsOwner(
|
||||
@CurrentUser() user: CurrentIamUser,
|
||||
): Promise<CompanyIdentityStateDto> {
|
||||
return this.companiesService.setGmSameAsOwner(user.id);
|
||||
return this.companiesService.setGmSameAsOwner(user.id, {
|
||||
email: user.email,
|
||||
phoneNumber: user.phoneNumber,
|
||||
});
|
||||
}
|
||||
|
||||
@Delete("identity/gm")
|
||||
|
||||
@@ -2749,6 +2749,12 @@ export class CompaniesService {
|
||||
async completeIdentityVerification(
|
||||
userId: string,
|
||||
dto: CompleteIdentityVerificationDto,
|
||||
/**
|
||||
* The signed-in account, used as the owner's fallback contact details.
|
||||
* Optional so the callers that only have a user id keep compiling — they
|
||||
* simply get no fallback.
|
||||
*/
|
||||
account?: { email?: string; phoneNumber?: string },
|
||||
): Promise<CompanyIdentityStateDto> {
|
||||
const { company } = await this.getCompanyInfoByUserId(userId);
|
||||
const prefix = IDENTITY_PREFIX[dto.subject];
|
||||
@@ -2780,6 +2786,22 @@ export class CompaniesService {
|
||||
}
|
||||
|
||||
const now = new Date().toISOString();
|
||||
|
||||
// Fayda's email and phone claims are optional and routinely come back empty.
|
||||
// For the owner that leaves the company with no contact details at all: the
|
||||
// step renders no input for them (they are the verification's output), and
|
||||
// "same as owner" then copies those blanks onto `generalManagerEmail` /
|
||||
// `generalManagerPhone`, which `REQUIRED_COMPANY_INFO` demands at submit —
|
||||
// an unfixable dead end. The account doing the onboarding is the one contact
|
||||
// we always have, and it is already OTP-proven, so it stands in.
|
||||
//
|
||||
// Owner only: the PoA and the GM are other people, and the registering
|
||||
// account's address is not theirs to wear.
|
||||
const isOwner = dto.subject === "owner";
|
||||
const email = result.email || (isOwner ? account?.email : undefined);
|
||||
const phone =
|
||||
result.phoneNumber || (isOwner ? account?.phoneNumber : undefined);
|
||||
|
||||
const identity: VerifiedIdentityAttributes = {
|
||||
[`${prefix}FaydaSub`]: result.sub,
|
||||
[`${prefix}FaydaVerifiedAt`]: now,
|
||||
@@ -2787,14 +2809,12 @@ export class CompaniesService {
|
||||
[`${prefix}Gender`]: result.gender ?? null,
|
||||
// The verified payload owns the person's details from here on.
|
||||
...(result.fullName ? { [`${prefix}Name`]: result.fullName } : {}),
|
||||
...(result.email ? { [`${prefix}Email`]: result.email } : {}),
|
||||
...(email ? { [`${prefix}Email`]: email } : {}),
|
||||
// Fayda returns whatever the national registry holds, which is routinely a
|
||||
// local number ("0911223344"). Every typed phone in this service is stored
|
||||
// E.164, and `@IsValidPhone()` rejects anything else — so a raw claim here
|
||||
// becomes a value the portal reads back and cannot resubmit.
|
||||
...(result.phoneNumber
|
||||
? { [`${prefix}Phone`]: normalizeE164(result.phoneNumber) }
|
||||
: {}),
|
||||
...(phone ? { [`${prefix}Phone`]: normalizeE164(phone) } : {}),
|
||||
...(result.address ? { [`${prefix}Address`]: result.address } : {}),
|
||||
};
|
||||
|
||||
@@ -2844,7 +2864,13 @@ export class CompaniesService {
|
||||
* proven identity to copy, only typed text that would arrive wearing a
|
||||
* verified badge.
|
||||
*/
|
||||
async setGmSameAsOwner(userId: string): Promise<CompanyIdentityStateDto> {
|
||||
async setGmSameAsOwner(
|
||||
userId: string,
|
||||
/** Same fallback as {@link completeIdentityVerification}, for owners
|
||||
* verified before that fallback existed — their stored contact details are
|
||||
* blank, and copying blanks here would block the submit. */
|
||||
account?: { email?: string; phoneNumber?: string },
|
||||
): Promise<CompanyIdentityStateDto> {
|
||||
const { company } = await this.getCompanyInfoByUserId(userId);
|
||||
const attrs = company.attributes ?? {};
|
||||
const ownerSub = attrs.ownerFaydaSub as string | undefined;
|
||||
@@ -2854,20 +2880,23 @@ export class CompaniesService {
|
||||
);
|
||||
}
|
||||
|
||||
const ownerEmail = (attrs.ownerEmail as string | undefined) || account?.email || null;
|
||||
const ownerPhone = (attrs.ownerPhone as string | undefined) || account?.phoneNumber || null;
|
||||
|
||||
const copied: Record<string, unknown> = {
|
||||
gmSameAsOwner: true,
|
||||
gmFaydaSub: ownerSub,
|
||||
gmFaydaVerifiedAt: attrs.ownerFaydaVerifiedAt ?? new Date().toISOString(),
|
||||
gmName: attrs.ownerName ?? null,
|
||||
gmEmail: attrs.ownerEmail ?? null,
|
||||
gmPhone: attrs.ownerPhone ?? null,
|
||||
gmEmail: ownerEmail,
|
||||
gmPhone: ownerPhone ? normalizeE164(ownerPhone) : null,
|
||||
gmAddress: attrs.ownerAddress ?? null,
|
||||
gmBirthdate: attrs.ownerBirthdate ?? null,
|
||||
gmGender: attrs.ownerGender ?? null,
|
||||
// Kept in step for the notifiers, same as a GM verification does.
|
||||
generalManagerName: attrs.ownerName ?? null,
|
||||
generalManagerEmail: attrs.ownerEmail ?? null,
|
||||
generalManagerPhone: attrs.ownerPhone ?? null,
|
||||
generalManagerEmail: ownerEmail,
|
||||
generalManagerPhone: ownerPhone ? normalizeE164(ownerPhone) : null,
|
||||
};
|
||||
|
||||
const updated = await this.companiesRepo.update(company.id, {
|
||||
|
||||
Reference in New Issue
Block a user