From 194374ea7302246ec50be13e4baeb7024382f101 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Fri, 19 Oct 2018 11:20:04 -0400 Subject: [PATCH] support org/collection selection on cipher add --- src/abstractions/cipher.service.ts | 2 +- src/angular/components/add-edit.component.ts | 46 +++++++++++++++++++- src/models/request/cipherCreateRequest.ts | 4 +- src/services/cipher.service.ts | 9 ++-- 4 files changed, 50 insertions(+), 11 deletions(-) diff --git a/src/abstractions/cipher.service.ts b/src/abstractions/cipher.service.ts index 1aae907f34..71fa641228 100644 --- a/src/abstractions/cipher.service.ts +++ b/src/abstractions/cipher.service.ts @@ -25,7 +25,7 @@ export abstract class CipherService { getLastUsedForUrl: (url: string) => Promise; updateLastUsedDate: (id: string) => Promise; saveNeverDomain: (domain: string) => Promise; - saveWithServer: (cipher: Cipher, collectionIds?: string[]) => Promise; + saveWithServer: (cipher: Cipher) => Promise; shareWithServer: (cipher: CipherView, organizationId: string, collectionIds: string[]) => Promise; shareManyWithServer: (ciphers: CipherView[], organizationId: string, collectionIds: string[]) => Promise; shareAttachmentWithServer: (attachmentView: AttachmentView, cipherId: string, diff --git a/src/angular/components/add-edit.component.ts b/src/angular/components/add-edit.component.ts index 345a22740a..c7e6c7cf86 100644 --- a/src/angular/components/add-edit.component.ts +++ b/src/angular/components/add-edit.component.ts @@ -1,25 +1,30 @@ import { EventEmitter, Input, + OnInit, Output, } from '@angular/core'; import { CipherType } from '../../enums/cipherType'; import { FieldType } from '../../enums/fieldType'; +import { OrganizationUserStatusType } from '../../enums/organizationUserStatusType'; import { SecureNoteType } from '../../enums/secureNoteType'; import { UriMatchType } from '../../enums/uriMatchType'; import { AuditService } from '../../abstractions/audit.service'; import { CipherService } from '../../abstractions/cipher.service'; +import { CollectionService } from '../../abstractions/collection.service'; import { FolderService } from '../../abstractions/folder.service'; import { I18nService } from '../../abstractions/i18n.service'; import { PlatformUtilsService } from '../../abstractions/platformUtils.service'; import { StateService } from '../../abstractions/state.service'; +import { UserService } from '../../abstractions/user.service'; import { Cipher } from '../../models/domain/cipher'; import { CardView } from '../../models/view/cardView'; import { CipherView } from '../../models/view/cipherView'; +import { CollectionView } from '../../models/view/collectionView'; import { FieldView } from '../../models/view/fieldView'; import { FolderView } from '../../models/view/folderView'; import { IdentityView } from '../../models/view/identityView'; @@ -27,7 +32,9 @@ import { LoginUriView } from '../../models/view/loginUriView'; import { LoginView } from '../../models/view/loginView'; import { SecureNoteView } from '../../models/view/secureNoteView'; -export class AddEditComponent { +import { Utils } from '../../misc/utils'; + +export class AddEditComponent implements OnInit { @Input() folderId: string = null; @Input() cipherId: string; @Input() type: CipherType; @@ -40,6 +47,7 @@ export class AddEditComponent { editMode: boolean = false; cipher: CipherView; folders: FolderView[]; + collections: CollectionView[] = []; title: string; formPromise: Promise; deletePromise: Promise; @@ -55,10 +63,14 @@ export class AddEditComponent { identityTitleOptions: any[]; addFieldTypeOptions: any[]; uriMatchOptions: any[]; + ownershipOptions: any[] = []; + + private writeableCollections: CollectionView[]; constructor(protected cipherService: CipherService, protected folderService: FolderService, protected i18nService: I18nService, protected platformUtilsService: PlatformUtilsService, - protected auditService: AuditService, protected stateService: StateService) { + protected auditService: AuditService, protected stateService: StateService, + protected userService: UserService, protected collectionService: CollectionService) { this.typeOptions = [ { name: i18nService.t('typeLogin'), value: CipherType.Login }, { name: i18nService.t('typeCard'), value: CipherType.Card }, @@ -115,6 +127,19 @@ export class AddEditComponent { ]; } + async ngOnInit() { + const myEmail = await this.userService.getEmail(); + this.ownershipOptions.push({ name: myEmail, value: null }); + const orgs = await this.userService.getAllOrganizations(); + orgs.sort(Utils.getSortFunction(this.i18nService, 'name')).forEach((o) => { + if (o.enabled && o.status === OrganizationUserStatusType.Confirmed) { + this.ownershipOptions.push({ name: o.name, value: o.id }); + } + }); + const allCollections = await this.collectionService.getAllDecrypted(); + this.writeableCollections = allCollections.filter((c) => !c.readOnly); + } + async load() { this.editMode = this.cipherId != null; if (this.editMode) { @@ -132,6 +157,7 @@ export class AddEditComponent { this.cipher = await cipher.decrypt(); } else { this.cipher = new CipherView(); + this.cipher.organizationId = null; this.cipher.folderId = this.folderId; this.cipher.type = this.type == null ? CipherType.Login : this.type; this.cipher.login = new LoginView(); @@ -159,6 +185,11 @@ export class AddEditComponent { this.cipher.login.uris = null; } + if (!this.editMode && this.cipher.organizationId != null) { + this.cipher.collectionIds = this.collections == null ? [] : + this.collections.filter((c) => (c as any).checked).map((c) => c.id); + } + const cipher = await this.encryptCipher(); try { this.formPromise = this.saveCipher(cipher); @@ -282,6 +313,17 @@ export class AddEditComponent { u.showOptions = u.showOptions == null ? true : u.showOptions; } + organizationChanged() { + if (this.writeableCollections != null) { + this.writeableCollections.forEach((c) => (c as any).checked = false); + } + if (this.cipher.organizationId != null) { + this.collections = this.writeableCollections.filter((c) => c.organizationId === this.cipher.organizationId); + } else { + this.collections = []; + } + } + async checkPassword() { if (this.checkPasswordPromise != null) { return; diff --git a/src/models/request/cipherCreateRequest.ts b/src/models/request/cipherCreateRequest.ts index f9f7a8af5b..683d0a52ef 100644 --- a/src/models/request/cipherCreateRequest.ts +++ b/src/models/request/cipherCreateRequest.ts @@ -6,8 +6,8 @@ export class CipherCreateRequest { cipher: CipherRequest; collectionIds: string[]; - constructor(cipher: Cipher, collectionIds: string[]) { + constructor(cipher: Cipher) { this.cipher = new CipherRequest(cipher); - this.collectionIds = collectionIds; + this.collectionIds = cipher.collectionIds; } } diff --git a/src/services/cipher.service.ts b/src/services/cipher.service.ts index d53c5a0a66..3428851195 100644 --- a/src/services/cipher.service.ts +++ b/src/services/cipher.service.ts @@ -439,11 +439,11 @@ export class CipherService implements CipherServiceAbstraction { await this.storageService.save(Keys.neverDomains, domains); } - async saveWithServer(cipher: Cipher, collectionIds: string[] = null): Promise { + async saveWithServer(cipher: Cipher): Promise { let response: CipherResponse; if (cipher.id == null) { - if (collectionIds != null) { - const request = new CipherCreateRequest(cipher, collectionIds); + if (cipher.collectionIds != null) { + const request = new CipherCreateRequest(cipher); response = await this.apiService.postCipherCreate(request); } else { const request = new CipherRequest(cipher); @@ -451,9 +451,6 @@ export class CipherService implements CipherServiceAbstraction { } cipher.id = response.id; } else { - if (collectionIds != null) { - throw new Error('You cannot edit with collection ids.'); - } const request = new CipherRequest(cipher); response = await this.apiService.putCipher(cipher.id, request); }