mirror of
https://github.com/bitwarden/browser.git
synced 2024-10-28 07:49:41 +01:00
WIP updating callers
This commit is contained in:
parent
902f49eb00
commit
5b0003b467
@ -8,6 +8,7 @@ import { Observable, combineLatest, first, map, switchMap } from "rxjs";
|
|||||||
import { CollectionService } from "@bitwarden/admin-console/common";
|
import { CollectionService } from "@bitwarden/admin-console/common";
|
||||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
|
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||||
import { OrganizationId } from "@bitwarden/common/types/guid";
|
import { OrganizationId } from "@bitwarden/common/types/guid";
|
||||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||||
@ -49,6 +50,8 @@ export class AssignCollections {
|
|||||||
/** Params needed to populate the assign collections component */
|
/** Params needed to populate the assign collections component */
|
||||||
params: CollectionAssignmentParams;
|
params: CollectionAssignmentParams;
|
||||||
|
|
||||||
|
private activeUserId$ = this.accountService.activeAccount$.pipe(getUserId);
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private location: Location,
|
private location: Location,
|
||||||
private collectionService: CollectionService,
|
private collectionService: CollectionService,
|
||||||
@ -70,7 +73,7 @@ export class AssignCollections {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
combineLatest([cipher$, this.collectionService.decryptedCollections$])
|
combineLatest([cipher$, this.collectionService.decryptedCollections$(this.activeUserId$)])
|
||||||
.pipe(takeUntilDestroyed(), first())
|
.pipe(takeUntilDestroyed(), first())
|
||||||
.subscribe(([cipherView, collections]) => {
|
.subscribe(([cipherView, collections]) => {
|
||||||
let availableCollections = collections.filter((c) => !c.readOnly);
|
let availableCollections = collections.filter((c) => !c.readOnly);
|
||||||
|
@ -22,6 +22,9 @@ import { BrowserApi } from "../../../../platform/browser/browser-api";
|
|||||||
import BrowserPopupUtils from "../../../../platform/popup/browser-popup-utils";
|
import BrowserPopupUtils from "../../../../platform/popup/browser-popup-utils";
|
||||||
import { VaultBrowserStateService } from "../../../services/vault-browser-state.service";
|
import { VaultBrowserStateService } from "../../../services/vault-browser-state.service";
|
||||||
import { VaultFilterService } from "../../../services/vault-filter.service";
|
import { VaultFilterService } from "../../../services/vault-filter.service";
|
||||||
|
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||||
|
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
|
import { firstValueFrom } from "rxjs";
|
||||||
|
|
||||||
const ComponentId = "VaultItemsComponent";
|
const ComponentId = "VaultItemsComponent";
|
||||||
|
|
||||||
@ -49,6 +52,8 @@ export class VaultItemsComponent extends BaseVaultItemsComponent implements OnIn
|
|||||||
private applySavedState = true;
|
private applySavedState = true;
|
||||||
private scrollingContainer = "cdk-virtual-scroll-viewport";
|
private scrollingContainer = "cdk-virtual-scroll-viewport";
|
||||||
|
|
||||||
|
private activeUserId$ = this.accountService.activeAccount$.pipe(getUserId);
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
searchService: SearchService,
|
searchService: SearchService,
|
||||||
private organizationService: OrganizationService,
|
private organizationService: OrganizationService,
|
||||||
@ -64,6 +69,7 @@ export class VaultItemsComponent extends BaseVaultItemsComponent implements OnIn
|
|||||||
private platformUtilsService: PlatformUtilsService,
|
private platformUtilsService: PlatformUtilsService,
|
||||||
cipherService: CipherService,
|
cipherService: CipherService,
|
||||||
private vaultFilterService: VaultFilterService,
|
private vaultFilterService: VaultFilterService,
|
||||||
|
private accountService: AccountService,
|
||||||
) {
|
) {
|
||||||
super(searchService, cipherService);
|
super(searchService, cipherService);
|
||||||
this.applySavedState =
|
this.applySavedState =
|
||||||
@ -133,7 +139,10 @@ export class VaultItemsComponent extends BaseVaultItemsComponent implements OnIn
|
|||||||
this.showVaultFilter = false;
|
this.showVaultFilter = false;
|
||||||
this.collectionId = params.collectionId;
|
this.collectionId = params.collectionId;
|
||||||
this.searchPlaceholder = this.i18nService.t("searchCollection");
|
this.searchPlaceholder = this.i18nService.t("searchCollection");
|
||||||
const collectionNode = await this.collectionService.getNested(this.collectionId);
|
const allCollections = await firstValueFrom(
|
||||||
|
this.collectionService.decryptedCollections$(this.activeUserId$),
|
||||||
|
);
|
||||||
|
const collectionNode = this.collectionService.getNested(allCollections, this.collectionId);
|
||||||
if (collectionNode != null && collectionNode.node != null) {
|
if (collectionNode != null && collectionNode.node != null) {
|
||||||
this.groupingTitle = collectionNode.node.name;
|
this.groupingTitle = collectionNode.node.name;
|
||||||
this.nestedCollections =
|
this.nestedCollections =
|
||||||
|
@ -8,8 +8,8 @@ import { OrganizationService } from "@bitwarden/common/admin-console/abstraction
|
|||||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||||
import { ProductTierType } from "@bitwarden/common/billing/enums";
|
import { ProductTierType } from "@bitwarden/common/billing/enums";
|
||||||
import { SyncService } from "@bitwarden/common/platform/sync";
|
import { SyncService } from "@bitwarden/common/platform/sync";
|
||||||
import { ObservableTracker } from "@bitwarden/common/spec";
|
import { mockAccountServiceWith, ObservableTracker } from "@bitwarden/common/spec";
|
||||||
import { CipherId } from "@bitwarden/common/types/guid";
|
import { CipherId, UserId } from "@bitwarden/common/types/guid";
|
||||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||||
import { VaultSettingsService } from "@bitwarden/common/vault/abstractions/vault-settings/vault-settings.service";
|
import { VaultSettingsService } from "@bitwarden/common/vault/abstractions/vault-settings/vault-settings.service";
|
||||||
import { CipherType } from "@bitwarden/common/vault/enums";
|
import { CipherType } from "@bitwarden/common/vault/enums";
|
||||||
@ -20,6 +20,7 @@ import { BrowserApi } from "../../../platform/browser/browser-api";
|
|||||||
import { VaultPopupAutofillService } from "./vault-popup-autofill.service";
|
import { VaultPopupAutofillService } from "./vault-popup-autofill.service";
|
||||||
import { VaultPopupItemsService } from "./vault-popup-items.service";
|
import { VaultPopupItemsService } from "./vault-popup-items.service";
|
||||||
import { VaultPopupListFiltersService } from "./vault-popup-list-filters.service";
|
import { VaultPopupListFiltersService } from "./vault-popup-list-filters.service";
|
||||||
|
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
|
|
||||||
describe("VaultPopupItemsService", () => {
|
describe("VaultPopupItemsService", () => {
|
||||||
let testBed: TestBed;
|
let testBed: TestBed;
|
||||||
@ -39,6 +40,7 @@ describe("VaultPopupItemsService", () => {
|
|||||||
const collectionService = mock<CollectionService>();
|
const collectionService = mock<CollectionService>();
|
||||||
const vaultAutofillServiceMock = mock<VaultPopupAutofillService>();
|
const vaultAutofillServiceMock = mock<VaultPopupAutofillService>();
|
||||||
const syncServiceMock = mock<SyncService>();
|
const syncServiceMock = mock<SyncService>();
|
||||||
|
const accountServiceMock = mockAccountServiceWith("UserId" as UserId);
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
allCiphers = cipherFactory(10);
|
allCiphers = cipherFactory(10);
|
||||||
@ -90,7 +92,7 @@ describe("VaultPopupItemsService", () => {
|
|||||||
];
|
];
|
||||||
|
|
||||||
organizationServiceMock.organizations$ = new BehaviorSubject([mockOrg]);
|
organizationServiceMock.organizations$ = new BehaviorSubject([mockOrg]);
|
||||||
collectionService.decryptedCollections$ = new BehaviorSubject(mockCollections);
|
collectionService.decryptedCollections$.mockReturnValue(new BehaviorSubject(mockCollections));
|
||||||
|
|
||||||
activeUserLastSync$ = new BehaviorSubject(new Date());
|
activeUserLastSync$ = new BehaviorSubject(new Date());
|
||||||
syncServiceMock.activeUserLastSync$.mockReturnValue(activeUserLastSync$);
|
syncServiceMock.activeUserLastSync$.mockReturnValue(activeUserLastSync$);
|
||||||
@ -105,6 +107,7 @@ describe("VaultPopupItemsService", () => {
|
|||||||
{ provide: CollectionService, useValue: collectionService },
|
{ provide: CollectionService, useValue: collectionService },
|
||||||
{ provide: VaultPopupAutofillService, useValue: vaultAutofillServiceMock },
|
{ provide: VaultPopupAutofillService, useValue: vaultAutofillServiceMock },
|
||||||
{ provide: SyncService, useValue: syncServiceMock },
|
{ provide: SyncService, useValue: syncServiceMock },
|
||||||
|
{ provide: AccountService, useValue: accountServiceMock },
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -36,6 +36,8 @@ import { PopupCipherView } from "../views/popup-cipher.view";
|
|||||||
|
|
||||||
import { VaultPopupAutofillService } from "./vault-popup-autofill.service";
|
import { VaultPopupAutofillService } from "./vault-popup-autofill.service";
|
||||||
import { MY_VAULT_ID, VaultPopupListFiltersService } from "./vault-popup-list-filters.service";
|
import { MY_VAULT_ID, VaultPopupListFiltersService } from "./vault-popup-list-filters.service";
|
||||||
|
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||||
|
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service for managing the various item lists on the new Vault tab in the browser popup.
|
* Service for managing the various item lists on the new Vault tab in the browser popup.
|
||||||
@ -45,6 +47,7 @@ import { MY_VAULT_ID, VaultPopupListFiltersService } from "./vault-popup-list-fi
|
|||||||
})
|
})
|
||||||
export class VaultPopupItemsService {
|
export class VaultPopupItemsService {
|
||||||
private _searchText$ = new BehaviorSubject<string>("");
|
private _searchText$ = new BehaviorSubject<string>("");
|
||||||
|
private activeUserId$ = this.accountService.activeAccount$.pipe(getUserId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subject that emits whenever new ciphers are being processed/filtered.
|
* Subject that emits whenever new ciphers are being processed/filtered.
|
||||||
@ -90,7 +93,7 @@ export class VaultPopupItemsService {
|
|||||||
switchMap((ciphers) =>
|
switchMap((ciphers) =>
|
||||||
combineLatest([
|
combineLatest([
|
||||||
this.organizationService.organizations$,
|
this.organizationService.organizations$,
|
||||||
this.collectionService.decryptedCollections$,
|
this.collectionService.decryptedCollections$(this.activeUserId$),
|
||||||
]).pipe(
|
]).pipe(
|
||||||
map(([organizations, collections]) => {
|
map(([organizations, collections]) => {
|
||||||
const orgMap = Object.fromEntries(organizations.map((org) => [org.id, org]));
|
const orgMap = Object.fromEntries(organizations.map((org) => [org.id, org]));
|
||||||
@ -260,6 +263,7 @@ export class VaultPopupItemsService {
|
|||||||
private collectionService: CollectionService,
|
private collectionService: CollectionService,
|
||||||
private vaultPopupAutofillService: VaultPopupAutofillService,
|
private vaultPopupAutofillService: VaultPopupAutofillService,
|
||||||
private syncService: SyncService,
|
private syncService: SyncService,
|
||||||
|
private accountService: AccountService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
applyFilter(newSearchText: string) {
|
applyFilter(newSearchText: string) {
|
||||||
|
@ -7,11 +7,15 @@ import { OrganizationService } from "@bitwarden/common/admin-console/abstraction
|
|||||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||||
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||||
|
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
import { ProductTierType } from "@bitwarden/common/billing/enums";
|
import { ProductTierType } from "@bitwarden/common/billing/enums";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
|
import { mockAccountServiceWith } from "@bitwarden/common/spec";
|
||||||
|
import { UserId } from "@bitwarden/common/types/guid";
|
||||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||||
import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
|
import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
|
||||||
import { CipherType } from "@bitwarden/common/vault/enums";
|
import { CipherType } from "@bitwarden/common/vault/enums";
|
||||||
|
import { TreeNode } from "@bitwarden/common/vault/models/domain/tree-node";
|
||||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||||
import { FolderView } from "@bitwarden/common/vault/models/view/folder.view";
|
import { FolderView } from "@bitwarden/common/vault/models/view/folder.view";
|
||||||
|
|
||||||
@ -26,8 +30,8 @@ describe("VaultPopupListFiltersService", () => {
|
|||||||
const policyAppliesToActiveUser$ = new BehaviorSubject<boolean>(false);
|
const policyAppliesToActiveUser$ = new BehaviorSubject<boolean>(false);
|
||||||
|
|
||||||
const collectionService = {
|
const collectionService = {
|
||||||
decryptedCollections$,
|
decryptedCollections$: () => decryptedCollections$,
|
||||||
getAllNested: () => Promise.resolve([]),
|
getAllNested: () => [] as TreeNode<CollectionView>[],
|
||||||
} as unknown as CollectionService;
|
} as unknown as CollectionService;
|
||||||
|
|
||||||
const folderService = {
|
const folderService = {
|
||||||
@ -50,13 +54,15 @@ describe("VaultPopupListFiltersService", () => {
|
|||||||
policyAppliesToActiveUser$: jest.fn(() => policyAppliesToActiveUser$),
|
policyAppliesToActiveUser$: jest.fn(() => policyAppliesToActiveUser$),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const accountService = mockAccountServiceWith("userId" as UserId);
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
memberOrganizations$.next([]);
|
memberOrganizations$.next([]);
|
||||||
decryptedCollections$.next([]);
|
decryptedCollections$.next([]);
|
||||||
policyAppliesToActiveUser$.next(false);
|
policyAppliesToActiveUser$.next(false);
|
||||||
policyService.policyAppliesToActiveUser$.mockClear();
|
policyService.policyAppliesToActiveUser$.mockClear();
|
||||||
|
|
||||||
collectionService.getAllNested = () => Promise.resolve([]);
|
collectionService.getAllNested = () => [] as TreeNode<CollectionView>[];
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
providers: [
|
providers: [
|
||||||
{
|
{
|
||||||
@ -84,6 +90,10 @@ describe("VaultPopupListFiltersService", () => {
|
|||||||
useValue: policyService,
|
useValue: policyService,
|
||||||
},
|
},
|
||||||
{ provide: FormBuilder, useClass: FormBuilder },
|
{ provide: FormBuilder, useClass: FormBuilder },
|
||||||
|
{
|
||||||
|
provide: AccountService,
|
||||||
|
useValue: accountService,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -276,13 +286,11 @@ describe("VaultPopupListFiltersService", () => {
|
|||||||
decryptedCollections$.next(testCollections);
|
decryptedCollections$.next(testCollections);
|
||||||
|
|
||||||
collectionService.getAllNested = () =>
|
collectionService.getAllNested = () =>
|
||||||
Promise.resolve(
|
testCollections.map((c) => ({
|
||||||
testCollections.map((c) => ({
|
children: [],
|
||||||
children: [],
|
node: c,
|
||||||
node: c,
|
parent: null,
|
||||||
parent: null,
|
}));
|
||||||
})),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("returns all collections", (done) => {
|
it("returns all collections", (done) => {
|
||||||
|
@ -1,15 +1,7 @@
|
|||||||
import { Injectable } from "@angular/core";
|
import { Injectable } from "@angular/core";
|
||||||
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
||||||
import { FormBuilder } from "@angular/forms";
|
import { FormBuilder } from "@angular/forms";
|
||||||
import {
|
import { combineLatest, distinctUntilChanged, map, Observable, startWith, tap } from "rxjs";
|
||||||
combineLatest,
|
|
||||||
distinctUntilChanged,
|
|
||||||
map,
|
|
||||||
Observable,
|
|
||||||
startWith,
|
|
||||||
switchMap,
|
|
||||||
tap,
|
|
||||||
} from "rxjs";
|
|
||||||
|
|
||||||
import { CollectionService, Collection, CollectionView } from "@bitwarden/admin-console/common";
|
import { CollectionService, Collection, CollectionView } from "@bitwarden/admin-console/common";
|
||||||
import { DynamicTreeNode } from "@bitwarden/angular/vault/vault-filter/models/dynamic-tree-node.model";
|
import { DynamicTreeNode } from "@bitwarden/angular/vault/vault-filter/models/dynamic-tree-node.model";
|
||||||
@ -17,6 +9,8 @@ import { OrganizationService } from "@bitwarden/common/admin-console/abstraction
|
|||||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||||
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||||
|
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
|
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||||
import { ProductTierType } from "@bitwarden/common/billing/enums";
|
import { ProductTierType } from "@bitwarden/common/billing/enums";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||||
@ -81,6 +75,8 @@ export class VaultPopupListFiltersService {
|
|||||||
map((ciphers) => Object.values(ciphers)),
|
map((ciphers) => Object.values(ciphers)),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
private activeUserId$ = this.accountService.activeAccount$.pipe(getUserId);
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private folderService: FolderService,
|
private folderService: FolderService,
|
||||||
private cipherService: CipherService,
|
private cipherService: CipherService,
|
||||||
@ -89,6 +85,7 @@ export class VaultPopupListFiltersService {
|
|||||||
private collectionService: CollectionService,
|
private collectionService: CollectionService,
|
||||||
private formBuilder: FormBuilder,
|
private formBuilder: FormBuilder,
|
||||||
private policyService: PolicyService,
|
private policyService: PolicyService,
|
||||||
|
private accountService: AccountService,
|
||||||
) {
|
) {
|
||||||
this.filterForm.controls.organization.valueChanges
|
this.filterForm.controls.organization.valueChanges
|
||||||
.pipe(takeUntilDestroyed())
|
.pipe(takeUntilDestroyed())
|
||||||
@ -302,7 +299,7 @@ export class VaultPopupListFiltersService {
|
|||||||
previousFilter.organization?.id === currentFilter.organization?.id,
|
previousFilter.organization?.id === currentFilter.organization?.id,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
this.collectionService.decryptedCollections$,
|
this.collectionService.decryptedCollections$(this.activeUserId$),
|
||||||
]).pipe(
|
]).pipe(
|
||||||
map(([filters, allCollections]) => {
|
map(([filters, allCollections]) => {
|
||||||
const organizationId = filters.organization?.id ?? null;
|
const organizationId = filters.organization?.id ?? null;
|
||||||
@ -314,8 +311,8 @@ export class VaultPopupListFiltersService {
|
|||||||
|
|
||||||
return collections;
|
return collections;
|
||||||
}),
|
}),
|
||||||
switchMap(async (collections) => {
|
map((collections) => {
|
||||||
const nestedCollections = await this.collectionService.getAllNested(collections);
|
const nestedCollections = this.collectionService.getAllNested(collections);
|
||||||
|
|
||||||
return new DynamicTreeNode<CollectionView>({
|
return new DynamicTreeNode<CollectionView>({
|
||||||
fullList: collections,
|
fullList: collections,
|
||||||
|
@ -22,7 +22,7 @@ export class VaultFilterService extends BaseVaultFilterService {
|
|||||||
collectionService: CollectionService,
|
collectionService: CollectionService,
|
||||||
policyService: PolicyService,
|
policyService: PolicyService,
|
||||||
stateProvider: StateProvider,
|
stateProvider: StateProvider,
|
||||||
private accountService: AccountService,
|
accountService: AccountService,
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
organizationService,
|
organizationService,
|
||||||
@ -31,6 +31,7 @@ export class VaultFilterService extends BaseVaultFilterService {
|
|||||||
collectionService,
|
collectionService,
|
||||||
policyService,
|
policyService,
|
||||||
stateProvider,
|
stateProvider,
|
||||||
|
accountService,
|
||||||
);
|
);
|
||||||
this.vaultFilter.myVaultOnly = false;
|
this.vaultFilter.myVaultOnly = false;
|
||||||
this.vaultFilter.selectedOrganizationId = null;
|
this.vaultFilter.selectedOrganizationId = null;
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
import { Directive, EventEmitter, Input, OnInit, Output } from "@angular/core";
|
import { Directive, EventEmitter, Input, OnInit, Output } from "@angular/core";
|
||||||
import { firstValueFrom, map } from "rxjs";
|
import { firstValueFrom } from "rxjs";
|
||||||
|
|
||||||
import { CollectionService, CollectionView } from "@bitwarden/admin-console/common";
|
import { CollectionService, CollectionView } from "@bitwarden/admin-console/common";
|
||||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
|
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||||
@ -25,6 +26,8 @@ export class CollectionsComponent implements OnInit {
|
|||||||
collections: CollectionView[] = [];
|
collections: CollectionView[] = [];
|
||||||
organization: Organization;
|
organization: Organization;
|
||||||
|
|
||||||
|
protected activeUserId$ = this.accountService.activeAccount$.pipe(getUserId);
|
||||||
|
|
||||||
protected cipherDomain: Cipher;
|
protected cipherDomain: Cipher;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@ -45,9 +48,7 @@ export class CollectionsComponent implements OnInit {
|
|||||||
async load() {
|
async load() {
|
||||||
this.cipherDomain = await this.loadCipher();
|
this.cipherDomain = await this.loadCipher();
|
||||||
this.collectionIds = this.loadCipherCollections();
|
this.collectionIds = this.loadCipherCollections();
|
||||||
const activeUserId = await firstValueFrom(
|
const activeUserId = await firstValueFrom(this.activeUserId$);
|
||||||
this.accountService.activeAccount$.pipe(map((a) => a?.id)),
|
|
||||||
);
|
|
||||||
this.cipher = await this.cipherDomain.decrypt(
|
this.cipher = await this.cipherDomain.decrypt(
|
||||||
await this.cipherService.getKeyForCipherKeyDecryption(this.cipherDomain, activeUserId),
|
await this.cipherService.getKeyForCipherKeyDecryption(this.cipherDomain, activeUserId),
|
||||||
);
|
);
|
||||||
@ -113,7 +114,9 @@ export class CollectionsComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected async loadCollections() {
|
protected async loadCollections() {
|
||||||
const allCollections = await this.collectionService.getAllDecrypted();
|
const allCollections = await firstValueFrom(
|
||||||
|
this.collectionService.decryptedCollections$(this.activeUserId$),
|
||||||
|
);
|
||||||
return allCollections.filter(
|
return allCollections.filter(
|
||||||
(c) => !c.readOnly && c.organizationId === this.cipher.organizationId,
|
(c) => !c.readOnly && c.organizationId === this.cipher.organizationId,
|
||||||
);
|
);
|
||||||
|
@ -6,6 +6,7 @@ import { OrganizationService } from "@bitwarden/common/admin-console/abstraction
|
|||||||
import { OrganizationUserStatusType } from "@bitwarden/common/admin-console/enums";
|
import { OrganizationUserStatusType } from "@bitwarden/common/admin-console/enums";
|
||||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
|
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||||
@ -26,6 +27,7 @@ export class ShareComponent implements OnInit, OnDestroy {
|
|||||||
organizations$: Observable<Organization[]>;
|
organizations$: Observable<Organization[]>;
|
||||||
|
|
||||||
protected writeableCollections: Checkable<CollectionView>[] = [];
|
protected writeableCollections: Checkable<CollectionView>[] = [];
|
||||||
|
protected activeUserId$ = this.accountService.activeAccount$.pipe(getUserId);
|
||||||
|
|
||||||
private _destroy = new Subject<void>();
|
private _destroy = new Subject<void>();
|
||||||
|
|
||||||
@ -49,7 +51,9 @@ export class ShareComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async load() {
|
async load() {
|
||||||
const allCollections = await this.collectionService.getAllDecrypted();
|
const allCollections = await firstValueFrom(
|
||||||
|
this.collectionService.decryptedCollections$(this.activeUserId$),
|
||||||
|
);
|
||||||
this.writeableCollections = allCollections.map((c) => c).filter((c) => !c.readOnly);
|
this.writeableCollections = allCollections.map((c) => c).filter((c) => !c.readOnly);
|
||||||
|
|
||||||
this.organizations$ = this.organizationService.memberOrganizations$.pipe(
|
this.organizations$ = this.organizationService.memberOrganizations$.pipe(
|
||||||
|
@ -39,6 +39,7 @@ import { SecureNoteView } from "@bitwarden/common/vault/models/view/secure-note.
|
|||||||
import { CipherAuthorizationService } from "@bitwarden/common/vault/services/cipher-authorization.service";
|
import { CipherAuthorizationService } from "@bitwarden/common/vault/services/cipher-authorization.service";
|
||||||
import { DialogService } from "@bitwarden/components";
|
import { DialogService } from "@bitwarden/components";
|
||||||
import { PasswordRepromptService } from "@bitwarden/vault";
|
import { PasswordRepromptService } from "@bitwarden/vault";
|
||||||
|
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||||
|
|
||||||
@Directive()
|
@Directive()
|
||||||
export class AddEditComponent implements OnInit, OnDestroy {
|
export class AddEditComponent implements OnInit, OnDestroy {
|
||||||
@ -98,6 +99,8 @@ export class AddEditComponent implements OnInit, OnDestroy {
|
|||||||
private personalOwnershipPolicyAppliesToActiveUser: boolean;
|
private personalOwnershipPolicyAppliesToActiveUser: boolean;
|
||||||
private previousCipherId: string;
|
private previousCipherId: string;
|
||||||
|
|
||||||
|
protected activeUserId$ = this.accountService.activeAccount$.pipe(getUserId);
|
||||||
|
|
||||||
get fido2CredentialCreationDateValue(): string {
|
get fido2CredentialCreationDateValue(): string {
|
||||||
const dateCreated = this.i18nService.t("dateCreated");
|
const dateCreated = this.i18nService.t("dateCreated");
|
||||||
const creationDate = this.datePipe.transform(
|
const creationDate = this.datePipe.transform(
|
||||||
@ -253,9 +256,7 @@ export class AddEditComponent implements OnInit, OnDestroy {
|
|||||||
if (this.cipher == null) {
|
if (this.cipher == null) {
|
||||||
if (this.editMode) {
|
if (this.editMode) {
|
||||||
const cipher = await this.loadCipher();
|
const cipher = await this.loadCipher();
|
||||||
const activeUserId = await firstValueFrom(
|
const activeUserId = await firstValueFrom(this.activeUserId$);
|
||||||
this.accountService.activeAccount$.pipe(map((a) => a?.id)),
|
|
||||||
);
|
|
||||||
this.cipher = await cipher.decrypt(
|
this.cipher = await cipher.decrypt(
|
||||||
await this.cipherService.getKeyForCipherKeyDecryption(cipher, activeUserId),
|
await this.cipherService.getKeyForCipherKeyDecryption(cipher, activeUserId),
|
||||||
);
|
);
|
||||||
@ -391,9 +392,7 @@ export class AddEditComponent implements OnInit, OnDestroy {
|
|||||||
this.cipher.id = null;
|
this.cipher.id = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const activeUserId = await firstValueFrom(
|
const activeUserId = await firstValueFrom(this.activeUserId$);
|
||||||
this.accountService.activeAccount$.pipe(map((a) => a?.id)),
|
|
||||||
);
|
|
||||||
const cipher = await this.encryptCipher(activeUserId);
|
const cipher = await this.encryptCipher(activeUserId);
|
||||||
try {
|
try {
|
||||||
this.formPromise = this.saveCipher(cipher);
|
this.formPromise = this.saveCipher(cipher);
|
||||||
@ -672,7 +671,9 @@ export class AddEditComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected async loadCollections() {
|
protected async loadCollections() {
|
||||||
const allCollections = await this.collectionService.getAllDecrypted();
|
const allCollections = await firstValueFrom(
|
||||||
|
this.collectionService.decryptedCollections$(this.activeUserId$),
|
||||||
|
);
|
||||||
return allCollections.filter((c) => !c.readOnly);
|
return allCollections.filter((c) => !c.readOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,8 @@ import {
|
|||||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||||
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||||
|
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
|
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||||
import { ActiveUserState, StateProvider } from "@bitwarden/common/platform/state";
|
import { ActiveUserState, StateProvider } from "@bitwarden/common/platform/state";
|
||||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||||
import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
|
import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
|
||||||
@ -30,6 +32,8 @@ export class VaultFilterService implements DeprecatedVaultFilterServiceAbstracti
|
|||||||
private readonly collapsedGroupings$: Observable<Set<string>> =
|
private readonly collapsedGroupings$: Observable<Set<string>> =
|
||||||
this.collapsedGroupingsState.state$.pipe(map((c) => new Set(c)));
|
this.collapsedGroupingsState.state$.pipe(map((c) => new Set(c)));
|
||||||
|
|
||||||
|
protected activeUserId$ = this.accountService.activeAccount$.pipe(getUserId);
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
protected organizationService: OrganizationService,
|
protected organizationService: OrganizationService,
|
||||||
protected folderService: FolderService,
|
protected folderService: FolderService,
|
||||||
@ -37,6 +41,7 @@ export class VaultFilterService implements DeprecatedVaultFilterServiceAbstracti
|
|||||||
protected collectionService: CollectionService,
|
protected collectionService: CollectionService,
|
||||||
protected policyService: PolicyService,
|
protected policyService: PolicyService,
|
||||||
protected stateProvider: StateProvider,
|
protected stateProvider: StateProvider,
|
||||||
|
protected accountService: AccountService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async storeCollapsedFilterNodes(collapsedFilterNodes: Set<string>): Promise<void> {
|
async storeCollapsedFilterNodes(collapsedFilterNodes: Set<string>): Promise<void> {
|
||||||
@ -85,14 +90,16 @@ export class VaultFilterService implements DeprecatedVaultFilterServiceAbstracti
|
|||||||
}
|
}
|
||||||
|
|
||||||
async buildCollections(organizationId?: string): Promise<DynamicTreeNode<CollectionView>> {
|
async buildCollections(organizationId?: string): Promise<DynamicTreeNode<CollectionView>> {
|
||||||
const storedCollections = await this.collectionService.getAllDecrypted();
|
const storedCollections = await firstValueFrom(
|
||||||
|
this.collectionService.decryptedCollections$(this.activeUserId$),
|
||||||
|
);
|
||||||
let collections: CollectionView[];
|
let collections: CollectionView[];
|
||||||
if (organizationId != null) {
|
if (organizationId != null) {
|
||||||
collections = storedCollections.filter((c) => c.organizationId === organizationId);
|
collections = storedCollections.filter((c) => c.organizationId === organizationId);
|
||||||
} else {
|
} else {
|
||||||
collections = storedCollections;
|
collections = storedCollections;
|
||||||
}
|
}
|
||||||
const nestedCollections = await this.collectionService.getAllNested(collections);
|
const nestedCollections = this.collectionService.getAllNested(collections);
|
||||||
return new DynamicTreeNode<CollectionView>({
|
return new DynamicTreeNode<CollectionView>({
|
||||||
fullList: collections,
|
fullList: collections,
|
||||||
nestedList: nestedCollections,
|
nestedList: nestedCollections,
|
||||||
|
@ -45,6 +45,24 @@ const LOGGED_OUT_INFO: AccountInfo = {
|
|||||||
name: undefined,
|
name: undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An rxjs map operator that extracts the UserId from an account, or throws if the account or UserId are null.
|
||||||
|
*/
|
||||||
|
export const getUserId = map<{ id: UserId | undefined }, UserId>((account) => {
|
||||||
|
if (account?.id == null) {
|
||||||
|
throw new Error("Null account or account ID");
|
||||||
|
}
|
||||||
|
|
||||||
|
return account.id;
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An rxjs map operator that extracts the UserId from an account, or returns undefined if the account or UserId are null.
|
||||||
|
*/
|
||||||
|
export const getOptionalUserId = map<{ id: UserId | undefined }, UserId | undefined>(
|
||||||
|
(account) => account?.id ?? undefined,
|
||||||
|
);
|
||||||
|
|
||||||
export class AccountServiceImplementation implements InternalAccountService {
|
export class AccountServiceImplementation implements InternalAccountService {
|
||||||
private accountsState: GlobalState<Record<UserId, AccountInfo>>;
|
private accountsState: GlobalState<Record<UserId, AccountInfo>>;
|
||||||
private activeAccountIdState: GlobalState<UserId | undefined>;
|
private activeAccountIdState: GlobalState<UserId | undefined>;
|
||||||
|
@ -6,6 +6,7 @@ import { ApiService } from "../../abstractions/api.service";
|
|||||||
import { AccountService } from "../../auth/abstractions/account.service";
|
import { AccountService } from "../../auth/abstractions/account.service";
|
||||||
import { AuthService } from "../../auth/abstractions/auth.service";
|
import { AuthService } from "../../auth/abstractions/auth.service";
|
||||||
import { AuthenticationStatus } from "../../auth/enums/authentication-status";
|
import { AuthenticationStatus } from "../../auth/enums/authentication-status";
|
||||||
|
import { getUserId } from "../../auth/services/account.service";
|
||||||
import {
|
import {
|
||||||
SyncCipherNotification,
|
SyncCipherNotification,
|
||||||
SyncFolderNotification,
|
SyncFolderNotification,
|
||||||
@ -149,7 +150,10 @@ export abstract class CoreSyncService implements SyncService {
|
|||||||
notification.collectionIds != null &&
|
notification.collectionIds != null &&
|
||||||
notification.collectionIds.length > 0
|
notification.collectionIds.length > 0
|
||||||
) {
|
) {
|
||||||
const collections = await this.collectionService.getAll();
|
const activeUserId$ = this.accountService.activeAccount$.pipe(getUserId);
|
||||||
|
const collections = await firstValueFrom(
|
||||||
|
this.collectionService.encryptedCollections$(activeUserId$),
|
||||||
|
);
|
||||||
if (collections != null) {
|
if (collections != null) {
|
||||||
for (let i = 0; i < collections.length; i++) {
|
for (let i = 0; i < collections.length; i++) {
|
||||||
if (notification.collectionIds.indexOf(collections[i].id) > -1) {
|
if (notification.collectionIds.indexOf(collections[i].id) > -1) {
|
||||||
|
@ -134,9 +134,13 @@ export class VaultTimeoutService implements VaultTimeoutServiceAbstraction {
|
|||||||
if (userId == null || userId === currentUserId) {
|
if (userId == null || userId === currentUserId) {
|
||||||
await this.searchService.clearIndex();
|
await this.searchService.clearIndex();
|
||||||
await this.folderService.clearCache();
|
await this.folderService.clearCache();
|
||||||
await this.collectionService.clearActiveUserCache();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: is the userId ever null here? Surely a null userId cannot be authenticated?
|
||||||
|
// Also MasterPasswordService throws an exception if the userId is null and hasn't caused any issues
|
||||||
|
// TODO: why do these other services clear lockingUserId and not userId?
|
||||||
|
await this.collectionService.clearDecryptedState(userId);
|
||||||
|
|
||||||
await this.masterPasswordService.clearMasterKey(lockingUserId);
|
await this.masterPasswordService.clearMasterKey(lockingUserId);
|
||||||
|
|
||||||
await this.stateService.setUserKeyAutoUnlock(null, { userId: lockingUserId });
|
await this.stateService.setUserKeyAutoUnlock(null, { userId: lockingUserId });
|
||||||
|
@ -72,6 +72,7 @@ import {
|
|||||||
ImportSuccessDialogComponent,
|
ImportSuccessDialogComponent,
|
||||||
} from "./dialog";
|
} from "./dialog";
|
||||||
import { ImportLastPassComponent } from "./lastpass";
|
import { ImportLastPassComponent } from "./lastpass";
|
||||||
|
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||||
|
|
||||||
const safeProviders: SafeProvider[] = [
|
const safeProviders: SafeProvider[] = [
|
||||||
safeProvider({
|
safeProvider({
|
||||||
@ -129,6 +130,8 @@ export class ImportComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||||||
collections$: Observable<CollectionView[]>;
|
collections$: Observable<CollectionView[]>;
|
||||||
organizations$: Observable<Organization[]>;
|
organizations$: Observable<Organization[]>;
|
||||||
|
|
||||||
|
protected activeUserId$ = this.accountService.activeAccount$.pipe(getUserId);
|
||||||
|
|
||||||
private _organizationId: string;
|
private _organizationId: string;
|
||||||
|
|
||||||
get organizationId(): string {
|
get organizationId(): string {
|
||||||
@ -205,6 +208,7 @@ export class ImportComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||||||
@Optional()
|
@Optional()
|
||||||
protected importCollectionService: ImportCollectionServiceAbstraction,
|
protected importCollectionService: ImportCollectionServiceAbstraction,
|
||||||
protected toastService: ToastService,
|
protected toastService: ToastService,
|
||||||
|
protected accountService: AccountService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
protected get importBlockedByPolicy(): boolean {
|
protected get importBlockedByPolicy(): boolean {
|
||||||
@ -272,15 +276,15 @@ export class ImportComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
this.collections$ = Utils.asyncToObservable(() =>
|
this.collections$ = this.collectionService
|
||||||
this.collectionService
|
.decryptedCollections$(this.activeUserId$)
|
||||||
.getAllDecrypted()
|
.pipe(
|
||||||
.then((decryptedCollections) =>
|
map((decryptedCollections) =>
|
||||||
decryptedCollections
|
decryptedCollections
|
||||||
.filter((c2) => c2.organizationId === value && c2.manage)
|
.filter((c2) => c2.organizationId === value && c2.manage)
|
||||||
.sort(Utils.getSortFunction(this.i18nService, "name")),
|
.sort(Utils.getSortFunction(this.i18nService, "name")),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.formGroup.controls.vaultSelector.setValue("myVault");
|
this.formGroup.controls.vaultSelector.setValue("myVault");
|
||||||
|
@ -33,11 +33,14 @@ import {
|
|||||||
import { BaseVaultExportService } from "./base-vault-export.service";
|
import { BaseVaultExportService } from "./base-vault-export.service";
|
||||||
import { OrganizationVaultExportServiceAbstraction } from "./org-vault-export.service.abstraction";
|
import { OrganizationVaultExportServiceAbstraction } from "./org-vault-export.service.abstraction";
|
||||||
import { ExportFormat } from "./vault-export.service.abstraction";
|
import { ExportFormat } from "./vault-export.service.abstraction";
|
||||||
|
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||||
|
|
||||||
export class OrganizationVaultExportService
|
export class OrganizationVaultExportService
|
||||||
extends BaseVaultExportService
|
extends BaseVaultExportService
|
||||||
implements OrganizationVaultExportServiceAbstraction
|
implements OrganizationVaultExportServiceAbstraction
|
||||||
{
|
{
|
||||||
|
protected activeUserId$ = this.accountService.activeAccount$.pipe(getUserId);
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private cipherService: CipherService,
|
private cipherService: CipherService,
|
||||||
private apiService: ApiService,
|
private apiService: ApiService,
|
||||||
@ -185,9 +188,13 @@ export class OrganizationVaultExportService
|
|||||||
const promises = [];
|
const promises = [];
|
||||||
|
|
||||||
promises.push(
|
promises.push(
|
||||||
this.collectionService.getAllDecrypted().then(async (collections) => {
|
firstValueFrom(this.collectionService.decryptedCollections$(this.activeUserId$)).then(
|
||||||
decCollections = collections.filter((c) => c.organizationId == organizationId && c.manage);
|
(collections) => {
|
||||||
}),
|
decCollections = collections.filter(
|
||||||
|
(c) => c.organizationId == organizationId && c.manage,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
promises.push(
|
promises.push(
|
||||||
@ -217,9 +224,13 @@ export class OrganizationVaultExportService
|
|||||||
const promises = [];
|
const promises = [];
|
||||||
|
|
||||||
promises.push(
|
promises.push(
|
||||||
this.collectionService.getAll().then((collections) => {
|
firstValueFrom(this.collectionService.encryptedCollections$(this.activeUserId$)).then(
|
||||||
encCollections = collections.filter((c) => c.organizationId == organizationId && c.manage);
|
(collections) => {
|
||||||
}),
|
encCollections = collections.filter(
|
||||||
|
(c) => c.organizationId == organizationId && c.manage,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
promises.push(
|
promises.push(
|
||||||
|
@ -21,6 +21,8 @@ import { OrganizationService } from "@bitwarden/common/admin-console/abstraction
|
|||||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||||
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||||
|
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
|
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||||
import { EventType } from "@bitwarden/common/enums";
|
import { EventType } from "@bitwarden/common/enums";
|
||||||
import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service";
|
import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
@ -150,6 +152,8 @@ export class ExportComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||||||
{ name: ".json (Encrypted)", value: "encrypted_json" },
|
{ name: ".json (Encrypted)", value: "encrypted_json" },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
protected activeUserId$ = this.accountService.activeAccount$.pipe(getUserId);
|
||||||
|
|
||||||
private destroy$ = new Subject<void>();
|
private destroy$ = new Subject<void>();
|
||||||
private onlyManagedCollections = true;
|
private onlyManagedCollections = true;
|
||||||
|
|
||||||
@ -167,6 +171,7 @@ export class ExportComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||||||
protected dialogService: DialogService,
|
protected dialogService: DialogService,
|
||||||
protected organizationService: OrganizationService,
|
protected organizationService: OrganizationService,
|
||||||
private collectionService: CollectionService,
|
private collectionService: CollectionService,
|
||||||
|
protected accountService: AccountService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
@ -204,7 +209,7 @@ export class ExportComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.organizations$ = combineLatest({
|
this.organizations$ = combineLatest({
|
||||||
collections: this.collectionService.decryptedCollections$,
|
collections: this.collectionService.decryptedCollections$(this.activeUserId$),
|
||||||
memberOrganizations: this.organizationService.memberOrganizations$,
|
memberOrganizations: this.organizationService.memberOrganizations$,
|
||||||
}).pipe(
|
}).pipe(
|
||||||
map(({ collections, memberOrganizations }) => {
|
map(({ collections, memberOrganizations }) => {
|
||||||
|
@ -5,6 +5,8 @@ import { CollectionService } from "@bitwarden/admin-console/common";
|
|||||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||||
import { OrganizationUserStatusType, PolicyType } from "@bitwarden/common/admin-console/enums";
|
import { OrganizationUserStatusType, PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||||
|
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
|
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||||
import { CipherId } from "@bitwarden/common/types/guid";
|
import { CipherId } from "@bitwarden/common/types/guid";
|
||||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||||
import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
|
import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
|
||||||
@ -29,6 +31,9 @@ export class DefaultCipherFormConfigService implements CipherFormConfigService {
|
|||||||
private cipherService: CipherService = inject(CipherService);
|
private cipherService: CipherService = inject(CipherService);
|
||||||
private folderService: FolderService = inject(FolderService);
|
private folderService: FolderService = inject(FolderService);
|
||||||
private collectionService: CollectionService = inject(CollectionService);
|
private collectionService: CollectionService = inject(CollectionService);
|
||||||
|
private accountService = inject(AccountService);
|
||||||
|
|
||||||
|
protected activeUserId$ = this.accountService.activeAccount$.pipe(getUserId);
|
||||||
|
|
||||||
async buildConfig(
|
async buildConfig(
|
||||||
mode: CipherFormMode,
|
mode: CipherFormMode,
|
||||||
@ -39,9 +44,9 @@ export class DefaultCipherFormConfigService implements CipherFormConfigService {
|
|||||||
await firstValueFrom(
|
await firstValueFrom(
|
||||||
combineLatest([
|
combineLatest([
|
||||||
this.organizations$,
|
this.organizations$,
|
||||||
this.collectionService.encryptedCollections$.pipe(
|
this.collectionService.encryptedCollections$(this.activeUserId$).pipe(
|
||||||
switchMap((c) =>
|
switchMap((c) =>
|
||||||
this.collectionService.decryptedCollections$.pipe(
|
this.collectionService.decryptedCollections$(this.activeUserId$).pipe(
|
||||||
filter((d) => d.length === c.length), // Ensure all collections have been decrypted
|
filter((d) => d.length === c.length), // Ensure all collections have been decrypted
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
import { CommonModule } from "@angular/common";
|
import { CommonModule } from "@angular/common";
|
||||||
import { Component, Input, OnChanges, OnDestroy } from "@angular/core";
|
import { Component, Input, OnChanges, OnDestroy } from "@angular/core";
|
||||||
import { firstValueFrom, Observable, Subject, takeUntil } from "rxjs";
|
import { firstValueFrom, map, Observable, Subject, takeUntil } from "rxjs";
|
||||||
|
|
||||||
import { CollectionService, CollectionView } from "@bitwarden/admin-console/common";
|
import { CollectionService, CollectionView } from "@bitwarden/admin-console/common";
|
||||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||||
|
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
|
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||||
import { isCardExpired } from "@bitwarden/common/autofill/utils";
|
import { isCardExpired } from "@bitwarden/common/autofill/utils";
|
||||||
import { CollectionId } from "@bitwarden/common/types/guid";
|
|
||||||
import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
|
import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
|
||||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||||
import { FolderView } from "@bitwarden/common/vault/models/view/folder.view";
|
import { FolderView } from "@bitwarden/common/vault/models/view/folder.view";
|
||||||
@ -56,10 +57,13 @@ export class CipherViewComponent implements OnChanges, OnDestroy {
|
|||||||
private destroyed$: Subject<void> = new Subject();
|
private destroyed$: Subject<void> = new Subject();
|
||||||
cardIsExpired: boolean = false;
|
cardIsExpired: boolean = false;
|
||||||
|
|
||||||
|
private activeUserId$ = this.accountService.activeAccount$.pipe(getUserId);
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private organizationService: OrganizationService,
|
private organizationService: OrganizationService,
|
||||||
private collectionService: CollectionService,
|
private collectionService: CollectionService,
|
||||||
private folderService: FolderService,
|
private folderService: FolderService,
|
||||||
|
private accountService: AccountService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async ngOnChanges() {
|
async ngOnChanges() {
|
||||||
@ -98,9 +102,13 @@ export class CipherViewComponent implements OnChanges, OnDestroy {
|
|||||||
(!this.collections || this.collections.length === 0)
|
(!this.collections || this.collections.length === 0)
|
||||||
) {
|
) {
|
||||||
this.collections = await firstValueFrom(
|
this.collections = await firstValueFrom(
|
||||||
this.collectionService.decryptedCollectionViews$(
|
this.collectionService
|
||||||
this.cipher.collectionIds as CollectionId[],
|
.decryptedCollections$(this.activeUserId$)
|
||||||
),
|
.pipe(
|
||||||
|
map((allCollections) =>
|
||||||
|
allCollections.filter((c) => this.cipher.collectionIds.includes(c.id)),
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,8 +28,9 @@ import { OrganizationService } from "@bitwarden/common/admin-console/abstraction
|
|||||||
import { OrganizationUserStatusType } from "@bitwarden/common/admin-console/enums";
|
import { OrganizationUserStatusType } from "@bitwarden/common/admin-console/enums";
|
||||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
|
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { CipherId, CollectionId, OrganizationId, UserId } from "@bitwarden/common/types/guid";
|
import { CipherId, CollectionId, OrganizationId } from "@bitwarden/common/types/guid";
|
||||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||||
import {
|
import {
|
||||||
@ -170,7 +171,7 @@ export class AssignCollectionsComponent implements OnInit, OnDestroy, AfterViewI
|
|||||||
private get selectedOrgId(): OrganizationId {
|
private get selectedOrgId(): OrganizationId {
|
||||||
return this.formGroup.getRawValue().selectedOrg || this.params.organizationId;
|
return this.formGroup.getRawValue().selectedOrg || this.params.organizationId;
|
||||||
}
|
}
|
||||||
private activeUserId: UserId;
|
private activeUserId$ = this.accountService.activeAccount$.pipe(getUserId);
|
||||||
private destroy$ = new Subject<void>();
|
private destroy$ = new Subject<void>();
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@ -184,10 +185,6 @@ export class AssignCollectionsComponent implements OnInit, OnDestroy, AfterViewI
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
this.activeUserId = await firstValueFrom(
|
|
||||||
this.accountService.activeAccount$.pipe(map((a) => a?.id)),
|
|
||||||
);
|
|
||||||
|
|
||||||
const onlyPersonalItems = this.params.ciphers.every((c) => c.organizationId == null);
|
const onlyPersonalItems = this.params.ciphers.every((c) => c.organizationId == null);
|
||||||
|
|
||||||
if (this.selectedOrgId === MY_VAULT_ID || onlyPersonalItems) {
|
if (this.selectedOrgId === MY_VAULT_ID || onlyPersonalItems) {
|
||||||
@ -405,7 +402,7 @@ export class AssignCollectionsComponent implements OnInit, OnDestroy, AfterViewI
|
|||||||
*/
|
*/
|
||||||
private getCollectionsForOrganization(orgId: OrganizationId): Observable<CollectionView[]> {
|
private getCollectionsForOrganization(orgId: OrganizationId): Observable<CollectionView[]> {
|
||||||
return combineLatest([
|
return combineLatest([
|
||||||
this.collectionService.decryptedCollections$,
|
this.collectionService.decryptedCollections$(this.activeUserId$),
|
||||||
this.organizationService.organizations$,
|
this.organizationService.organizations$,
|
||||||
]).pipe(
|
]).pipe(
|
||||||
map(([collections, organizations]) => {
|
map(([collections, organizations]) => {
|
||||||
@ -429,7 +426,7 @@ export class AssignCollectionsComponent implements OnInit, OnDestroy, AfterViewI
|
|||||||
shareableCiphers,
|
shareableCiphers,
|
||||||
organizationId,
|
organizationId,
|
||||||
selectedCollectionIds,
|
selectedCollectionIds,
|
||||||
this.activeUserId,
|
await firstValueFrom(this.activeUserId$),
|
||||||
);
|
);
|
||||||
|
|
||||||
this.toastService.showToast({
|
this.toastService.showToast({
|
||||||
@ -470,7 +467,10 @@ export class AssignCollectionsComponent implements OnInit, OnDestroy, AfterViewI
|
|||||||
private async updateAssignedCollections(cipherView: CipherView) {
|
private async updateAssignedCollections(cipherView: CipherView) {
|
||||||
const { collections } = this.formGroup.getRawValue();
|
const { collections } = this.formGroup.getRawValue();
|
||||||
cipherView.collectionIds = collections.map((i) => i.id as CollectionId);
|
cipherView.collectionIds = collections.map((i) => i.id as CollectionId);
|
||||||
const cipher = await this.cipherService.encrypt(cipherView, this.activeUserId);
|
const cipher = await this.cipherService.encrypt(
|
||||||
|
cipherView,
|
||||||
|
await firstValueFrom(this.activeUserId$),
|
||||||
|
);
|
||||||
if (this.params.isSingleCipherAdmin) {
|
if (this.params.isSingleCipherAdmin) {
|
||||||
await this.cipherService.saveCollectionsWithServerAdmin(cipher);
|
await this.cipherService.saveCollectionsWithServerAdmin(cipher);
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user