1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-06 00:13:28 +00:00

feat(SSO): (Auth/[PM-22110] Remove Alternate Login Options when SSO Required (#16340)

If a user is part of an org that has the `RequireSso` policy, when that user successfully logs in we add their email to a local `ssoRequiredCache` on their device. The next time this user goes to the `/login` screen on this device, we will use that cache to determine that for this email we should only show the "Use single sign-on" button and disable the alternate login buttons.

These changes are behind the flag: `PM22110_DisableAlternateLoginMethods`
This commit is contained in:
rr-bw
2025-09-22 08:32:20 -07:00
committed by GitHub
parent b455cb5986
commit 3bbc6c564c
15 changed files with 539 additions and 19 deletions

View File

@@ -900,7 +900,11 @@ export default class MainBackground {
this.restrictedItemTypesService,
);
this.ssoLoginService = new SsoLoginService(this.stateProvider, this.logService);
this.ssoLoginService = new SsoLoginService(
this.stateProvider,
this.logService,
this.policyService,
);
this.userVerificationApiService = new UserVerificationApiService(this.apiService);

View File

@@ -1,5 +1,13 @@
import { Component, Inject, OnDestroy, OnInit } from "@angular/core";
import { combineLatest, map, Observable, Subject, switchMap, takeUntil } from "rxjs";
import {
combineLatest,
firstValueFrom,
map,
Observable,
Subject,
switchMap,
takeUntil,
} from "rxjs";
import {
OrganizationUserApiService,
@@ -14,8 +22,10 @@ import { PolicyType } from "@bitwarden/common/admin-console/enums";
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
import { Policy } from "@bitwarden/common/admin-console/models/domain/policy";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
import { getUserId } from "@bitwarden/common/auth/services/account.service";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
@@ -65,6 +75,7 @@ export class OrganizationOptionsComponent implements OnInit, OnDestroy {
private keyService: KeyService,
private accountService: AccountService,
private linkSsoService: LinkSsoService,
private ssoLoginService: SsoLoginServiceAbstraction,
) {}
async ngOnInit() {
@@ -167,6 +178,14 @@ export class OrganizationOptionsComponent implements OnInit, OnDestroy {
title: "",
message: this.i18nService.t("unlinkedSso"),
});
const disableAlternateLoginMethodsFlagEnabled = await this.configService.getFeatureFlag(
FeatureFlag.PM22110_DisableAlternateLoginMethods,
);
if (disableAlternateLoginMethodsFlagEnabled) {
await this.removeEmailFromSsoRequiredCacheIfPresent();
}
} catch (e) {
this.logService.error(e);
}
@@ -186,16 +205,36 @@ export class OrganizationOptionsComponent implements OnInit, OnDestroy {
try {
this.actionPromise = this.organizationApiService.leave(org.id);
await this.actionPromise;
this.toastService.showToast({
variant: "success",
title: "",
message: this.i18nService.t("leftOrganization"),
});
const disableAlternateLoginMethodsFlagEnabled = await this.configService.getFeatureFlag(
FeatureFlag.PM22110_DisableAlternateLoginMethods,
);
if (disableAlternateLoginMethodsFlagEnabled) {
await this.removeEmailFromSsoRequiredCacheIfPresent();
}
} catch (e) {
this.logService.error(e);
}
}
private async removeEmailFromSsoRequiredCacheIfPresent() {
const activeAccount = await firstValueFrom(this.accountService.activeAccount$);
if (!activeAccount) {
this.logService.error("Active account not found.");
return;
}
await this.ssoLoginService.removeFromSsoRequiredCacheIfPresent(activeAccount.email);
}
async toggleResetPasswordEnrollment(org: Organization) {
if (!this.organization.resetPasswordEnrolled) {
await EnrollMasterPasswordReset.open(

View File

@@ -6725,6 +6725,15 @@
"disabledSso": {
"message": "SSO turned on"
},
"emailMustLoginWithSso": {
"message": "$EMAIL$ must login with Single Sign-on",
"placeholders": {
"email": {
"content": "$1",
"example": "name@example.com"
}
}
},
"enabledKeyConnector": {
"message": "Key Connector activated"
},