Auth/PM-1658 - Dynamic Org Invite Link to accelerate users through org invite accept process (#6702)

* PM-1658 - Update Accept Organization component to take new org invite qParams into acct for accelerating the user through the org invite accept process.

* PM-1658 - Update trial initiation and register form comps to respect fromOrgInvite when email is populated to make the populated email read only so users in the org invite process dont change it.

* PM-1658 - Per PR feedback, we could simplify the logic by only sending the org sso identifier if it was required to be used.

* PM-1658 - Accept Comp - should send existing user email as qParam to get it to autofill properly. Previous "autofill" was due to using remember email when creating an account before testing the existing user inv flow.
This commit is contained in:
Jared Snider 2023-12-18 11:28:15 -05:00 committed by GitHub
parent 11da91676c
commit 7ffa983469
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 58 additions and 1 deletions

View File

@ -84,6 +84,10 @@ export class AcceptOrganizationComponent extends BaseAcceptComponent {
async unauthedHandler(qParams: Params): Promise<void> {
await this.prepareOrganizationInvitation(qParams);
// In certain scenarios, we want to accelerate the user through the accept org invite process
// For example, if the user has a BW account already, we want them to be taken to login instead of creation.
await this.accelerateInviteAcceptIfPossible(qParams);
}
private async acceptInitOrganizationFlow(qParams: Params): Promise<any> {
@ -186,4 +190,47 @@ export class AcceptOrganizationComponent extends BaseAcceptComponent {
}
await this.stateService.setOrganizationInvitation(qParams);
}
private async accelerateInviteAcceptIfPossible(qParams: Params): Promise<void> {
// Extract the query params we need to make routing acceleration decisions
const orgSsoIdentifier = qParams.orgSsoIdentifier;
const orgUserHasExistingUser = this.stringToNullOrBool(qParams.orgUserHasExistingUser);
// if orgUserHasExistingUser is null, short circuit for backwards compatibility w/ older servers
if (orgUserHasExistingUser == null) {
return;
}
// if user exists, send user to login
if (orgUserHasExistingUser) {
this.router.navigate(["/login"], {
queryParams: { email: qParams.email },
});
return;
}
// no user exists; so either sign in via SSO and JIT provision one or simply register.
if (orgSsoIdentifier) {
// We only send sso org identifier if the org has SSO enabled and the SSO policy required.
this.router.navigate(["/sso"], {
queryParams: { email: qParams.email, identifier: orgSsoIdentifier },
});
return;
}
// if SSO is disabled OR if sso is enabled but the SSO login required policy is not enabled
// then send user to create account
this.router.navigate(["/register"], {
queryParams: { email: qParams.email, fromOrgInvite: true },
});
return;
}
private stringToNullOrBool(s: string | undefined): boolean | null {
if (s === undefined) {
return null;
}
return s.toLowerCase() === "true";
}
}

View File

@ -11,7 +11,13 @@
<div class="tw-mb-3">
<bit-form-field>
<bit-label>{{ "emailAddress" | i18n }}</bit-label>
<input id="register-form_input_email" bitInput type="email" formControlName="email" />
<input
id="register-form_input_email"
bitInput
type="email"
formControlName="email"
[attr.readonly]="queryParamFromOrgInvite ? true : null"
/>
<bit-hint>{{ "emailAddressDesc" | i18n }}</bit-hint>
</bit-form-field>
</div>

View File

@ -25,6 +25,7 @@ import { DialogService } from "@bitwarden/components";
})
export class RegisterFormComponent extends BaseRegisterComponent {
@Input() queryParamEmail: string;
@Input() queryParamFromOrgInvite: boolean;
@Input() enforcedPolicyOptions: MasterPasswordPolicyOptions;
@Input() referenceDataValue: ReferenceEventRequest;

View File

@ -6,6 +6,7 @@
>
<app-register-form
[queryParamEmail]="email"
[queryParamFromOrgInvite]="fromOrgInvite"
[enforcedPolicyOptions]="enforcedPolicyOptions"
[referenceDataValue]="referenceData"
></app-register-form>

View File

@ -52,6 +52,7 @@ enum ValidLayoutParams {
})
export class TrialInitiationComponent implements OnInit, OnDestroy {
email = "";
fromOrgInvite = false;
org = "";
orgInfoSubLabel = "";
orgId = "";
@ -127,6 +128,7 @@ export class TrialInitiationComponent implements OnInit, OnDestroy {
this.referenceData = new ReferenceEventRequest();
if (qParams.email != null && qParams.email.indexOf("@") > -1) {
this.email = qParams.email;
this.fromOrgInvite = qParams.fromOrgInvite === "true";
}
this.referenceDataId = qParams.reference;