mirror of
https://github.com/bitwarden/browser
synced 2025-12-15 07:43:35 +00:00
Merge branch 'master' into feature/org-admin-refresh
This commit is contained in:
@@ -9,7 +9,7 @@ import { FolderService } from "@bitwarden/common/abstractions/folder/folder.serv
|
||||
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/abstractions/log.service";
|
||||
import { MessagingService } from "@bitwarden/common/abstractions/messaging.service";
|
||||
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
|
||||
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
|
||||
import { PasswordRepromptService } from "@bitwarden/common/abstractions/passwordReprompt.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
|
||||
import { PolicyService } from "@bitwarden/common/abstractions/policy/policy.service.abstraction";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Component, Input, OnInit } from "@angular/core";
|
||||
|
||||
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
|
||||
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
|
||||
import { StateService } from "@bitwarden/common/abstractions/state.service";
|
||||
|
||||
@Component({
|
||||
@@ -23,7 +23,7 @@ export class ExportScopeCalloutComponent implements OnInit {
|
||||
) {}
|
||||
|
||||
async ngOnInit(): Promise<void> {
|
||||
if (!(await this.organizationService.hasOrganizations())) {
|
||||
if (!this.organizationService.hasOrganizations()) {
|
||||
return;
|
||||
}
|
||||
this.scopeConfig =
|
||||
@@ -31,7 +31,7 @@ export class ExportScopeCalloutComponent implements OnInit {
|
||||
? {
|
||||
title: "exportingOrganizationVaultTitle",
|
||||
description: "exportingOrganizationVaultDescription",
|
||||
scopeIdentifier: (await this.organizationService.get(this.organizationId)).name,
|
||||
scopeIdentifier: this.organizationService.get(this.organizationId).name,
|
||||
}
|
||||
: {
|
||||
title: "exportingPersonalVaultTitle",
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { Directive, OnInit } from "@angular/core";
|
||||
import { Router } from "@angular/router";
|
||||
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
||||
import { KeyConnectorService } from "@bitwarden/common/abstractions/keyConnector.service";
|
||||
import { OrganizationApiServiceAbstraction } from "@bitwarden/common/abstractions/organization/organization-api.service.abstraction";
|
||||
@@ -23,7 +22,6 @@ export class RemovePasswordComponent implements OnInit {
|
||||
constructor(
|
||||
private router: Router,
|
||||
private stateService: StateService,
|
||||
private apiService: ApiService,
|
||||
private syncService: SyncService,
|
||||
private platformUtilsService: PlatformUtilsService,
|
||||
private i18nService: I18nService,
|
||||
@@ -70,9 +68,7 @@ export class RemovePasswordComponent implements OnInit {
|
||||
|
||||
try {
|
||||
this.leaving = true;
|
||||
this.actionPromise = this.organizationApiService.leave(this.organization.id).then(() => {
|
||||
return this.syncService.fullSync(true);
|
||||
});
|
||||
this.actionPromise = this.organizationApiService.leave(this.organization.id);
|
||||
await this.actionPromise;
|
||||
this.platformUtilsService.showToast("success", null, this.i18nService.t("leftOrganization"));
|
||||
await this.keyConnectorService.removeConvertAccountRequired();
|
||||
|
||||
@@ -1,29 +1,33 @@
|
||||
import { Directive, EventEmitter, Input, OnInit, Output } from "@angular/core";
|
||||
import { Directive, EventEmitter, Input, OnDestroy, OnInit, Output } from "@angular/core";
|
||||
import { firstValueFrom, map, Observable, Subject, takeUntil } from "rxjs";
|
||||
|
||||
import { CipherService } from "@bitwarden/common/abstractions/cipher.service";
|
||||
import { CollectionService } from "@bitwarden/common/abstractions/collection.service";
|
||||
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/abstractions/log.service";
|
||||
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
|
||||
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
|
||||
import { OrganizationUserStatusType } from "@bitwarden/common/enums/organizationUserStatusType";
|
||||
import { Utils } from "@bitwarden/common/misc/utils";
|
||||
import { Organization } from "@bitwarden/common/models/domain/organization";
|
||||
import { CipherView } from "@bitwarden/common/models/view/cipherView";
|
||||
import { CollectionView } from "@bitwarden/common/models/view/collectionView";
|
||||
import { Checkable, isChecked } from "@bitwarden/common/types/checkable";
|
||||
|
||||
@Directive()
|
||||
export class ShareComponent implements OnInit {
|
||||
export class ShareComponent implements OnInit, OnDestroy {
|
||||
@Input() cipherId: string;
|
||||
@Input() organizationId: string;
|
||||
@Output() onSharedCipher = new EventEmitter();
|
||||
|
||||
formPromise: Promise<any>;
|
||||
formPromise: Promise<void>;
|
||||
cipher: CipherView;
|
||||
collections: CollectionView[] = [];
|
||||
organizations: Organization[] = [];
|
||||
collections: Checkable<CollectionView>[] = [];
|
||||
organizations$: Observable<Organization[]>;
|
||||
|
||||
protected writeableCollections: CollectionView[] = [];
|
||||
protected writeableCollections: Checkable<CollectionView>[] = [];
|
||||
|
||||
private _destroy = new Subject<void>();
|
||||
|
||||
constructor(
|
||||
protected collectionService: CollectionService,
|
||||
@@ -38,24 +42,37 @@ export class ShareComponent implements OnInit {
|
||||
await this.load();
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this._destroy.next();
|
||||
this._destroy.complete();
|
||||
}
|
||||
|
||||
async load() {
|
||||
const allCollections = await this.collectionService.getAllDecrypted();
|
||||
this.writeableCollections = allCollections.map((c) => c).filter((c) => !c.readOnly);
|
||||
const orgs = await this.organizationService.getAll();
|
||||
this.organizations = orgs
|
||||
.sort(Utils.getSortFunction(this.i18nService, "name"))
|
||||
.filter((o) => o.enabled && o.status === OrganizationUserStatusType.Confirmed);
|
||||
|
||||
this.organizations$ = this.organizationService.organizations$.pipe(
|
||||
map((orgs) => {
|
||||
return orgs
|
||||
.filter((o) => o.enabled && o.status === OrganizationUserStatusType.Confirmed)
|
||||
.sort(Utils.getSortFunction(this.i18nService, "name"));
|
||||
})
|
||||
);
|
||||
|
||||
this.organizations$.pipe(takeUntil(this._destroy)).subscribe((orgs) => {
|
||||
if (this.organizationId == null && orgs.length > 0) {
|
||||
this.organizationId = orgs[0].id;
|
||||
}
|
||||
});
|
||||
|
||||
const cipherDomain = await this.cipherService.get(this.cipherId);
|
||||
this.cipher = await cipherDomain.decrypt();
|
||||
if (this.organizationId == null && this.organizations.length > 0) {
|
||||
this.organizationId = this.organizations[0].id;
|
||||
}
|
||||
|
||||
this.filterCollections();
|
||||
}
|
||||
|
||||
filterCollections() {
|
||||
this.writeableCollections.forEach((c) => ((c as any).checked = false));
|
||||
this.writeableCollections.forEach((c) => (c.checked = false));
|
||||
if (this.organizationId == null || this.writeableCollections.length === 0) {
|
||||
this.collections = [];
|
||||
} else {
|
||||
@@ -66,9 +83,7 @@ export class ShareComponent implements OnInit {
|
||||
}
|
||||
|
||||
async submit(): Promise<boolean> {
|
||||
const selectedCollectionIds = this.collections
|
||||
.filter((c) => !!(c as any).checked)
|
||||
.map((c) => c.id);
|
||||
const selectedCollectionIds = this.collections.filter(isChecked).map((c) => c.id);
|
||||
if (selectedCollectionIds.length === 0) {
|
||||
this.platformUtilsService.showToast(
|
||||
"error",
|
||||
@@ -80,9 +95,9 @@ export class ShareComponent implements OnInit {
|
||||
|
||||
const cipherDomain = await this.cipherService.get(this.cipherId);
|
||||
const cipherView = await cipherDomain.decrypt();
|
||||
const orgs = await firstValueFrom(this.organizations$);
|
||||
const orgName =
|
||||
this.organizations.find((o) => o.id === this.organizationId)?.name ??
|
||||
this.i18nService.t("organization");
|
||||
orgs.find((o) => o.id === this.organizationId)?.name ?? this.i18nService.t("organization");
|
||||
|
||||
try {
|
||||
this.formPromise = this.cipherService
|
||||
@@ -106,7 +121,7 @@ export class ShareComponent implements OnInit {
|
||||
get canSave() {
|
||||
if (this.collections != null) {
|
||||
for (let i = 0; i < this.collections.length; i++) {
|
||||
if ((this.collections[i] as any).checked) {
|
||||
if (this.collections[i].checked) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,8 +32,8 @@ import { KeyConnectorService as KeyConnectorServiceAbstraction } from "@bitwarde
|
||||
import { LogService } from "@bitwarden/common/abstractions/log.service";
|
||||
import { MessagingService as MessagingServiceAbstraction } from "@bitwarden/common/abstractions/messaging.service";
|
||||
import { NotificationsService as NotificationsServiceAbstraction } from "@bitwarden/common/abstractions/notifications.service";
|
||||
import { OrganizationService as OrganizationServiceAbstraction } from "@bitwarden/common/abstractions/organization.service";
|
||||
import { OrganizationApiServiceAbstraction } from "@bitwarden/common/abstractions/organization/organization-api.service.abstraction";
|
||||
import { OrganizationService as OrganizationServiceAbstraction } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
|
||||
import { PasswordGenerationService as PasswordGenerationServiceAbstraction } from "@bitwarden/common/abstractions/passwordGeneration.service";
|
||||
import { PasswordRepromptService as PasswordRepromptServiceAbstraction } from "@bitwarden/common/abstractions/passwordReprompt.service";
|
||||
import { PlatformUtilsService as PlatformUtilsServiceAbstraction } from "@bitwarden/common/abstractions/platformUtils.service";
|
||||
@@ -50,6 +50,7 @@ import { StateService as StateServiceAbstraction } from "@bitwarden/common/abstr
|
||||
import { StateMigrationService as StateMigrationServiceAbstraction } from "@bitwarden/common/abstractions/stateMigration.service";
|
||||
import { AbstractStorageService } from "@bitwarden/common/abstractions/storage.service";
|
||||
import { SyncService as SyncServiceAbstraction } from "@bitwarden/common/abstractions/sync/sync.service.abstraction";
|
||||
import { SyncNotifierService as SyncNotifierServiceAbstraction } from "@bitwarden/common/abstractions/sync/syncNotifier.service.abstraction";
|
||||
import { TokenService as TokenServiceAbstraction } from "@bitwarden/common/abstractions/token.service";
|
||||
import { TotpService as TotpServiceAbstraction } from "@bitwarden/common/abstractions/totp.service";
|
||||
import { TwoFactorService as TwoFactorServiceAbstraction } from "@bitwarden/common/abstractions/twoFactor.service";
|
||||
@@ -84,8 +85,8 @@ import { FolderService } from "@bitwarden/common/services/folder/folder.service"
|
||||
import { FormValidationErrorsService } from "@bitwarden/common/services/formValidationErrors.service";
|
||||
import { KeyConnectorService } from "@bitwarden/common/services/keyConnector.service";
|
||||
import { NotificationsService } from "@bitwarden/common/services/notifications.service";
|
||||
import { OrganizationService } from "@bitwarden/common/services/organization.service";
|
||||
import { OrganizationApiService } from "@bitwarden/common/services/organization/organization-api.service";
|
||||
import { OrganizationService } from "@bitwarden/common/services/organization/organization.service";
|
||||
import { PasswordGenerationService } from "@bitwarden/common/services/passwordGeneration.service";
|
||||
import { PolicyApiService } from "@bitwarden/common/services/policy/policy-api.service";
|
||||
import { PolicyService } from "@bitwarden/common/services/policy/policy.service";
|
||||
@@ -96,6 +97,7 @@ import { SettingsService } from "@bitwarden/common/services/settings.service";
|
||||
import { StateService } from "@bitwarden/common/services/state.service";
|
||||
import { StateMigrationService } from "@bitwarden/common/services/stateMigration.service";
|
||||
import { SyncService } from "@bitwarden/common/services/sync/sync.service";
|
||||
import { SyncNotifierService } from "@bitwarden/common/services/sync/syncNotifier.service";
|
||||
import { TokenService } from "@bitwarden/common/services/token.service";
|
||||
import { TotpService } from "@bitwarden/common/services/totp.service";
|
||||
import { TwoFactorService } from "@bitwarden/common/services/twoFactor.service";
|
||||
@@ -338,9 +340,9 @@ import { ValidationService } from "./validation.service";
|
||||
LogService,
|
||||
KeyConnectorServiceAbstraction,
|
||||
StateServiceAbstraction,
|
||||
OrganizationServiceAbstraction,
|
||||
ProviderServiceAbstraction,
|
||||
FolderApiServiceAbstraction,
|
||||
SyncNotifierServiceAbstraction,
|
||||
LOGOUT_CALLBACK,
|
||||
],
|
||||
},
|
||||
@@ -506,7 +508,7 @@ import { ValidationService } from "./validation.service";
|
||||
{
|
||||
provide: OrganizationServiceAbstraction,
|
||||
useClass: OrganizationService,
|
||||
deps: [StateServiceAbstraction],
|
||||
deps: [StateServiceAbstraction, SyncNotifierServiceAbstraction],
|
||||
},
|
||||
{
|
||||
provide: ProviderServiceAbstraction,
|
||||
@@ -534,7 +536,15 @@ import { ValidationService } from "./validation.service";
|
||||
{
|
||||
provide: OrganizationApiServiceAbstraction,
|
||||
useClass: OrganizationApiService,
|
||||
deps: [ApiServiceAbstraction],
|
||||
// This is a slightly odd dependency tree for a specialized api service
|
||||
// it depends on SyncService so that new data can be retrieved through the sync
|
||||
// rather than updating the OrganizationService directly. Instead OrganizationService
|
||||
// subscribes to sync notifications and will update itself based on that.
|
||||
deps: [ApiServiceAbstraction, SyncServiceAbstraction],
|
||||
},
|
||||
{
|
||||
provide: SyncNotifierServiceAbstraction,
|
||||
useClass: SyncNotifierService,
|
||||
},
|
||||
{
|
||||
provide: ConfigServiceAbstraction,
|
||||
|
||||
@@ -4,7 +4,7 @@ import { firstValueFrom, from, mergeMap, Observable } from "rxjs";
|
||||
import { CipherService } from "@bitwarden/common/abstractions/cipher.service";
|
||||
import { CollectionService } from "@bitwarden/common/abstractions/collection.service";
|
||||
import { FolderService } from "@bitwarden/common/abstractions/folder/folder.service.abstraction";
|
||||
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
|
||||
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
|
||||
import { PolicyService } from "@bitwarden/common/abstractions/policy/policy.service.abstraction";
|
||||
import { StateService } from "@bitwarden/common/abstractions/state.service";
|
||||
import { PolicyType } from "@bitwarden/common/enums/policyType";
|
||||
@@ -37,8 +37,8 @@ export class VaultFilterService {
|
||||
return new Set(await this.stateService.getCollapsedGroupings());
|
||||
}
|
||||
|
||||
async buildOrganizations(): Promise<Organization[]> {
|
||||
return await this.organizationService.getAll();
|
||||
buildOrganizations(): Promise<Organization[]> {
|
||||
return this.organizationService.getAll();
|
||||
}
|
||||
|
||||
buildNestedFolders(organizationId?: string): Observable<DynamicTreeNode<FolderView>> {
|
||||
|
||||
Reference in New Issue
Block a user