mirror of
https://github.com/bitwarden/browser
synced 2025-12-15 07:43:35 +00:00
[PS-1879] Fix Key Connector Migration Flow (#4080)
* Move OrganizationService to fullSync * Add Tech Debt Tracking Link * Remove Commented out code * Add InternalOrganizationService * Use InternalOrganization in services that get to update state
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { map, Observable } from "rxjs";
|
||||
|
||||
import { Utils } from "../../misc/utils";
|
||||
import { OrganizationData } from "../../models/data/organization.data";
|
||||
import { Organization } from "../../models/domain/organization";
|
||||
import { I18nService } from "../i18n.service";
|
||||
|
||||
@@ -83,3 +84,7 @@ export abstract class OrganizationService {
|
||||
canManageSponsorships: () => Promise<boolean>;
|
||||
hasOrganizations: () => boolean;
|
||||
}
|
||||
|
||||
export abstract class InternalOrganizationService extends OrganizationService {
|
||||
replace: (organizations: { [id: string]: OrganizationData }) => Promise<void>;
|
||||
}
|
||||
|
||||
@@ -1,21 +1,16 @@
|
||||
import { BehaviorSubject, concatMap, filter } from "rxjs";
|
||||
import { BehaviorSubject, concatMap } from "rxjs";
|
||||
|
||||
import { OrganizationService as OrganizationServiceAbstraction } from "../../abstractions/organization/organization.service.abstraction";
|
||||
import { InternalOrganizationService as InternalOrganizationServiceAbstraction } from "../../abstractions/organization/organization.service.abstraction";
|
||||
import { StateService } from "../../abstractions/state.service";
|
||||
import { SyncNotifierService } from "../../abstractions/sync/syncNotifier.service.abstraction";
|
||||
import { OrganizationData } from "../../models/data/organization.data";
|
||||
import { Organization } from "../../models/domain/organization";
|
||||
import { isSuccessfullyCompleted } from "../../types/syncEventArgs";
|
||||
|
||||
export class OrganizationService implements OrganizationServiceAbstraction {
|
||||
export class OrganizationService implements InternalOrganizationServiceAbstraction {
|
||||
private _organizations = new BehaviorSubject<Organization[]>([]);
|
||||
|
||||
organizations$ = this._organizations.asObservable();
|
||||
|
||||
constructor(
|
||||
private stateService: StateService,
|
||||
private syncNotifierService: SyncNotifierService
|
||||
) {
|
||||
constructor(private stateService: StateService) {
|
||||
this.stateService.activeAccountUnlocked$
|
||||
.pipe(
|
||||
concatMap(async (unlocked) => {
|
||||
@@ -29,28 +24,6 @@ export class OrganizationService implements OrganizationServiceAbstraction {
|
||||
})
|
||||
)
|
||||
.subscribe();
|
||||
|
||||
this.syncNotifierService.sync$
|
||||
.pipe(
|
||||
filter(isSuccessfullyCompleted),
|
||||
concatMap(async ({ data }) => {
|
||||
const { profile } = data;
|
||||
const organizations: { [id: string]: OrganizationData } = {};
|
||||
profile.organizations.forEach((o) => {
|
||||
organizations[o.id] = new OrganizationData(o);
|
||||
});
|
||||
|
||||
profile.providerOrganizations.forEach((o) => {
|
||||
if (organizations[o.id] == null) {
|
||||
organizations[o.id] = new OrganizationData(o);
|
||||
organizations[o.id].isProviderUser = true;
|
||||
}
|
||||
});
|
||||
|
||||
await this.updateStateAndObservables(organizations);
|
||||
})
|
||||
)
|
||||
.subscribe();
|
||||
}
|
||||
|
||||
async getAll(userId?: string): Promise<Organization[]> {
|
||||
@@ -78,7 +51,7 @@ export class OrganizationService implements OrganizationServiceAbstraction {
|
||||
|
||||
organizations[organization.id] = organization;
|
||||
|
||||
await this.updateStateAndObservables(organizations);
|
||||
await this.replace(organizations);
|
||||
}
|
||||
|
||||
async delete(id: string): Promise<void> {
|
||||
@@ -92,7 +65,7 @@ export class OrganizationService implements OrganizationServiceAbstraction {
|
||||
}
|
||||
|
||||
delete organizations[id];
|
||||
await this.updateStateAndObservables(organizations);
|
||||
await this.replace(organizations);
|
||||
}
|
||||
|
||||
get(id: string): Organization {
|
||||
@@ -121,9 +94,9 @@ export class OrganizationService implements OrganizationServiceAbstraction {
|
||||
return organizations.find((organization) => organization.identifier === identifier);
|
||||
}
|
||||
|
||||
private async updateStateAndObservables(organizationsMap: { [id: string]: OrganizationData }) {
|
||||
await this.stateService.setOrganizations(organizationsMap);
|
||||
this.updateObservables(organizationsMap);
|
||||
async replace(organizations: { [id: string]: OrganizationData }) {
|
||||
await this.stateService.setOrganizations(organizations);
|
||||
this.updateObservables(organizations);
|
||||
}
|
||||
|
||||
private updateObservables(organizationsMap: { [id: string]: OrganizationData }) {
|
||||
|
||||
@@ -7,17 +7,18 @@ import { InternalFolderService } from "../../abstractions/folder/folder.service.
|
||||
import { KeyConnectorService } from "../../abstractions/keyConnector.service";
|
||||
import { LogService } from "../../abstractions/log.service";
|
||||
import { MessagingService } from "../../abstractions/messaging.service";
|
||||
import { InternalOrganizationService } from "../../abstractions/organization/organization.service.abstraction";
|
||||
import { InternalPolicyService } from "../../abstractions/policy/policy.service.abstraction";
|
||||
import { ProviderService } from "../../abstractions/provider.service";
|
||||
import { SendService } from "../../abstractions/send.service";
|
||||
import { SettingsService } from "../../abstractions/settings.service";
|
||||
import { StateService } from "../../abstractions/state.service";
|
||||
import { SyncService as SyncServiceAbstraction } from "../../abstractions/sync/sync.service.abstraction";
|
||||
import { SyncNotifierService } from "../../abstractions/sync/syncNotifier.service.abstraction";
|
||||
import { sequentialize } from "../../misc/sequentialize";
|
||||
import { CipherData } from "../../models/data/cipher.data";
|
||||
import { CollectionData } from "../../models/data/collection.data";
|
||||
import { FolderData } from "../../models/data/folder.data";
|
||||
import { OrganizationData } from "../../models/data/organization.data";
|
||||
import { PolicyData } from "../../models/data/policy.data";
|
||||
import { ProviderData } from "../../models/data/provider.data";
|
||||
import { SendData } from "../../models/data/send.data";
|
||||
@@ -52,7 +53,7 @@ export class SyncService implements SyncServiceAbstraction {
|
||||
private stateService: StateService,
|
||||
private providerService: ProviderService,
|
||||
private folderApiService: FolderApiServiceAbstraction,
|
||||
private syncNotifierService: SyncNotifierService,
|
||||
private organizationService: InternalOrganizationService,
|
||||
private logoutCallback: (expired: boolean) => Promise<void>
|
||||
) {}
|
||||
|
||||
@@ -76,10 +77,8 @@ export class SyncService implements SyncServiceAbstraction {
|
||||
@sequentialize(() => "fullSync")
|
||||
async fullSync(forceSync: boolean, allowThrowOnError = false): Promise<boolean> {
|
||||
this.syncStarted();
|
||||
this.syncNotifierService.next({ status: "Started" });
|
||||
const isAuthenticated = await this.stateService.getIsAuthenticated();
|
||||
if (!isAuthenticated) {
|
||||
this.syncNotifierService.next({ status: "Completed", successfully: false });
|
||||
return this.syncCompleted(false);
|
||||
}
|
||||
|
||||
@@ -95,7 +94,6 @@ export class SyncService implements SyncServiceAbstraction {
|
||||
|
||||
if (!needsSync) {
|
||||
await this.setLastSync(now);
|
||||
this.syncNotifierService.next({ status: "Completed", successfully: false });
|
||||
return this.syncCompleted(false);
|
||||
}
|
||||
|
||||
@@ -112,13 +110,11 @@ export class SyncService implements SyncServiceAbstraction {
|
||||
await this.syncPolicies(response.policies);
|
||||
|
||||
await this.setLastSync(now);
|
||||
this.syncNotifierService.next({ status: "Completed", successfully: true, data: response });
|
||||
return this.syncCompleted(true);
|
||||
} catch (e) {
|
||||
if (allowThrowOnError) {
|
||||
throw e;
|
||||
} else {
|
||||
this.syncNotifierService.next({ status: "Completed", successfully: false });
|
||||
return this.syncCompleted(false);
|
||||
}
|
||||
}
|
||||
@@ -315,11 +311,24 @@ export class SyncService implements SyncServiceAbstraction {
|
||||
await this.stateService.setForcePasswordReset(response.forcePasswordReset);
|
||||
await this.keyConnectorService.setUsesKeyConnector(response.usesKeyConnector);
|
||||
|
||||
const organizations: { [id: string]: OrganizationData } = {};
|
||||
response.organizations.forEach((o) => {
|
||||
organizations[o.id] = new OrganizationData(o);
|
||||
});
|
||||
|
||||
const providers: { [id: string]: ProviderData } = {};
|
||||
response.providers.forEach((p) => {
|
||||
providers[p.id] = new ProviderData(p);
|
||||
});
|
||||
|
||||
response.providerOrganizations.forEach((o) => {
|
||||
if (organizations[o.id] == null) {
|
||||
organizations[o.id] = new OrganizationData(o);
|
||||
organizations[o.id].isProviderUser = true;
|
||||
}
|
||||
});
|
||||
|
||||
await this.organizationService.replace(organizations);
|
||||
await this.providerService.save(providers);
|
||||
|
||||
if (await this.keyConnectorService.userNeedsMigration()) {
|
||||
|
||||
Reference in New Issue
Block a user