1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-11 14:04:03 +00:00

organization observable race condition in key-connector

This commit is contained in:
Maciej Zieniuk
2025-03-19 22:48:00 +00:00
parent b829a08250
commit c2b103dc18
3 changed files with 23 additions and 16 deletions

View File

@@ -11,7 +11,7 @@ export abstract class KeyConnectorService {
abstract migrateUser(userId: UserId): Promise<void>;
abstract userNeedsMigration(userId: UserId): Promise<boolean>;
abstract userNeedsMigration(userId: UserId, organizations: Organization[]): Promise<boolean>;
abstract convertNewSsoUserToKeyConnector(
tokenResponse: IdentityTokenResponse,

View File

@@ -82,9 +82,9 @@ export class KeyConnectorService implements KeyConnectorServiceAbstraction {
return firstValueFrom(this.stateProvider.getUserState$(USES_KEY_CONNECTOR, userId));
}
async userNeedsMigration(userId: UserId) {
async userNeedsMigration(userId: UserId, organizations: Organization[]) {
const loggedInUsingSso = await this.tokenService.getIsExternal(userId);
const requiredByOrganization = (await this.getManagingOrganization(userId)) != null;
const requiredByOrganization = this.findManagingOrganization(organizations) != null;
const userIsNotUsingKeyConnector = !(await this.getUsesKeyConnector(userId));
return loggedInUsingSso && requiredByOrganization && userIsNotUsingKeyConnector;
@@ -120,14 +120,8 @@ export class KeyConnectorService implements KeyConnectorServiceAbstraction {
}
async getManagingOrganization(userId: UserId): Promise<Organization> {
const orgs = await firstValueFrom(this.organizationService.organizations$(userId));
return orgs.find(
(o) =>
o.keyConnectorEnabled &&
o.type !== OrganizationUserType.Admin &&
o.type !== OrganizationUserType.Owner &&
!o.isProviderUser,
);
const organizations = await firstValueFrom(this.organizationService.organizations$(userId));
return this.findManagingOrganization(organizations);
}
async convertNewSsoUserToKeyConnector(
@@ -203,4 +197,14 @@ export class KeyConnectorService implements KeyConnectorServiceAbstraction {
}
throw new Error("Key Connector error");
}
private findManagingOrganization(organizations: Organization[]) {
return organizations.find(
(o) =>
o.keyConnectorEnabled &&
o.type !== OrganizationUserType.Admin &&
o.type !== OrganizationUserType.Owner &&
!o.isProviderUser,
);
}
}

View File

@@ -7,6 +7,7 @@ import {
CollectionData,
CollectionDetailsResponse,
} from "@bitwarden/admin-console/common";
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
import { KeyService } from "@bitwarden/key-management";
// FIXME: remove `src` and fix import
@@ -213,15 +214,13 @@ export class DefaultSyncService extends CoreSyncService {
await this.providerService.save(providers, response.id);
await this.syncProfileOrganizations(response, response.id);
const organizations = await this.syncProfileOrganizations(response, response.id);
if (await this.keyConnectorService.userNeedsMigration(response.id)) {
if (await this.keyConnectorService.userNeedsMigration(response.id, organizations)) {
await this.keyConnectorService.setConvertAccountRequired(true, response.id);
this.messageSender.send("convertAccountToKeyConnector");
} else {
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.keyConnectorService.removeConvertAccountRequired(response.id);
await this.keyConnectorService.removeConvertAccountRequired(response.id);
}
}
@@ -293,6 +292,10 @@ export class DefaultSyncService extends CoreSyncService {
});
await this.organizationService.replace(organizations, userId);
return Object.values(organizations).map(
(organizationData) => new Organization(organizationData),
);
}
private async syncFolders(response: FolderResponse[], userId: UserId) {