admin cipher attachments
This commit is contained in:
parent
fda8155894
commit
1d60e881ee
2
jslib
2
jslib
|
@ -1 +1 @@
|
|||
Subproject commit ef5eebba66d606d53cf4bc730426ea393276e801
|
||||
Subproject commit 47ab71e73098d1b83a1bdcbae3cd3e2b1d9ccacc
|
|
@ -33,6 +33,7 @@ import { TwoFactorOptionsComponent } from './accounts/two-factor-options.compone
|
|||
import { TwoFactorComponent } from './accounts/two-factor.component';
|
||||
|
||||
import { AddEditComponent as OrgAddEditComponent } from './organizations/add-edit.component';
|
||||
import { AttachmentsComponent as OrgAttachmentsComponent } from './organizations/attachments.component';
|
||||
import { CiphersComponent as OrgCiphersComponent } from './organizations/ciphers.component';
|
||||
import { GroupingsComponent as OrgGroupingsComponent } from './organizations/groupings.component';
|
||||
import { VaultComponent as OrgVaultComponent } from './organizations/vault.component';
|
||||
|
@ -154,6 +155,7 @@ import { SearchCiphersPipe } from 'jslib/angular/pipes/search-ciphers.pipe';
|
|||
NavbarComponent,
|
||||
OptionsComponent,
|
||||
OrgAddEditComponent,
|
||||
OrgAttachmentsComponent,
|
||||
OrgCiphersComponent,
|
||||
OrgGroupingsComponent,
|
||||
OrganizationsComponent,
|
||||
|
@ -200,6 +202,7 @@ import { SearchCiphersPipe } from 'jslib/angular/pipes/search-ciphers.pipe';
|
|||
FolderAddEditComponent,
|
||||
ModalComponent,
|
||||
OrgAddEditComponent,
|
||||
OrgAttachmentsComponent,
|
||||
PasswordGeneratorHistoryComponent,
|
||||
PurgeVaultComponent,
|
||||
ShareComponent,
|
||||
|
|
|
@ -42,12 +42,11 @@ export class AddEditComponent extends BaseAddEditComponent implements OnInit {
|
|||
}
|
||||
|
||||
protected async loadCipher() {
|
||||
if (this.organization.isAdmin) {
|
||||
const response = await this.apiService.getCipherAdmin(this.cipherId);
|
||||
return new Cipher(new CipherData(response));
|
||||
} else {
|
||||
if (!this.organization.isAdmin) {
|
||||
return await super.loadCipher();
|
||||
}
|
||||
const response = await this.apiService.getCipherAdmin(this.cipherId);
|
||||
return new Cipher(new CipherData(response));
|
||||
}
|
||||
|
||||
protected encryptCipher() {
|
||||
|
@ -58,23 +57,21 @@ export class AddEditComponent extends BaseAddEditComponent implements OnInit {
|
|||
}
|
||||
|
||||
protected async saveCipher(cipher: Cipher) {
|
||||
if (this.organization.isAdmin) {
|
||||
const request = new CipherRequest(cipher);
|
||||
if (this.editMode) {
|
||||
return this.apiService.putCipherAdmin(this.cipherId, request);
|
||||
} else {
|
||||
return this.apiService.postCipherAdmin(request);
|
||||
}
|
||||
} else {
|
||||
if (!this.organization.isAdmin) {
|
||||
return super.saveCipher(cipher);
|
||||
}
|
||||
const request = new CipherRequest(cipher);
|
||||
if (this.editMode) {
|
||||
return this.apiService.putCipherAdmin(this.cipherId, request);
|
||||
} else {
|
||||
return this.apiService.postCipherAdmin(request);
|
||||
}
|
||||
}
|
||||
|
||||
protected async deleteCipher() {
|
||||
if (this.organization.isAdmin) {
|
||||
return this.apiService.deleteCipherAdmin(this.cipherId);
|
||||
} else {
|
||||
if (!this.organization.isAdmin) {
|
||||
return super.deleteCipher();
|
||||
}
|
||||
return this.apiService.deleteCipherAdmin(this.cipherId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
import { Component } from '@angular/core';
|
||||
|
||||
import { ToasterService } from 'angular2-toaster';
|
||||
import { Angulartics2 } from 'angulartics2';
|
||||
|
||||
import { ApiService } from 'jslib/abstractions/api.service';
|
||||
import { CipherService } from 'jslib/abstractions/cipher.service';
|
||||
import { CryptoService } from 'jslib/abstractions/crypto.service';
|
||||
import { I18nService } from 'jslib/abstractions/i18n.service';
|
||||
import { PlatformUtilsService } from 'jslib/abstractions/platformUtils.service';
|
||||
import { TokenService } from 'jslib/abstractions/token.service';
|
||||
|
||||
import { CipherData } from 'jslib/models/data/cipherData';
|
||||
import { Cipher } from 'jslib/models/domain/cipher';
|
||||
import { Organization } from 'jslib/models/domain/organization';
|
||||
|
||||
import { AttachmentsComponent as BaseAttachmentsComponent } from '../vault/attachments.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-org-vault-attachments',
|
||||
templateUrl: '../vault/attachments.component.html',
|
||||
})
|
||||
export class AttachmentsComponent extends BaseAttachmentsComponent {
|
||||
organization: Organization;
|
||||
|
||||
constructor(cipherService: CipherService, analytics: Angulartics2,
|
||||
toasterService: ToasterService, i18nService: I18nService,
|
||||
cryptoService: CryptoService, tokenService: TokenService,
|
||||
platformUtilsService: PlatformUtilsService, private apiService: ApiService) {
|
||||
super(cipherService, analytics, toasterService, i18nService, cryptoService, tokenService,
|
||||
platformUtilsService);
|
||||
}
|
||||
|
||||
protected async loadCipher() {
|
||||
if (!this.organization.isAdmin) {
|
||||
return await super.loadCipher();
|
||||
}
|
||||
const response = await this.apiService.getCipherAdmin(this.cipherId);
|
||||
return new Cipher(new CipherData(response));
|
||||
}
|
||||
|
||||
protected saveCipherAttachment(file: File) {
|
||||
return this.cipherService.saveAttachmentWithServer(this.cipherDomain, file, this.organization.isAdmin);
|
||||
}
|
||||
|
||||
protected deleteCipherAttachment(attachmentId: string) {
|
||||
if (!this.organization.isAdmin) {
|
||||
return super.deleteCipherAttachment(attachmentId);
|
||||
}
|
||||
return this.apiService.deleteCipherAttachmentAdmin(this.cipherId, attachmentId);
|
||||
}
|
||||
}
|
|
@ -29,27 +29,27 @@ export class CiphersComponent extends BaseCiphersComponent {
|
|||
}
|
||||
|
||||
async load(filter: (cipher: CipherView) => boolean = null) {
|
||||
if (this.organization.isAdmin) {
|
||||
const ciphers = await this.apiService.getCiphersOrganization(this.organization.id);
|
||||
if (ciphers != null && ciphers.data != null && ciphers.data.length) {
|
||||
const decCiphers: CipherView[] = [];
|
||||
const promises: any[] = [];
|
||||
ciphers.data.forEach((r) => {
|
||||
const data = new CipherData(r);
|
||||
const cipher = new Cipher(data);
|
||||
promises.push(cipher.decrypt().then((c) => decCiphers.push(c)));
|
||||
});
|
||||
await Promise.all(promises);
|
||||
decCiphers.sort(this.cipherService.getLocaleSortingFunction());
|
||||
this.allCiphers = decCiphers;
|
||||
} else {
|
||||
this.allCiphers = [];
|
||||
}
|
||||
this.applyFilter(filter);
|
||||
this.loaded = true;
|
||||
} else {
|
||||
if (!this.organization.isAdmin) {
|
||||
await super.load();
|
||||
return;
|
||||
}
|
||||
const ciphers = await this.apiService.getCiphersOrganization(this.organization.id);
|
||||
if (ciphers != null && ciphers.data != null && ciphers.data.length) {
|
||||
const decCiphers: CipherView[] = [];
|
||||
const promises: any[] = [];
|
||||
ciphers.data.forEach((r) => {
|
||||
const data = new CipherData(r);
|
||||
const cipher = new Cipher(data);
|
||||
promises.push(cipher.decrypt().then((c) => decCiphers.push(c)));
|
||||
});
|
||||
await Promise.all(promises);
|
||||
decCiphers.sort(this.cipherService.getLocaleSortingFunction());
|
||||
this.allCiphers = decCiphers;
|
||||
} else {
|
||||
this.allCiphers = [];
|
||||
}
|
||||
this.applyFilter(filter);
|
||||
this.loaded = true;
|
||||
}
|
||||
|
||||
applyFilter(filter: (cipher: CipherView) => boolean = null) {
|
||||
|
|
|
@ -25,31 +25,31 @@ export class GroupingsComponent extends BaseGroupingsComponent {
|
|||
}
|
||||
|
||||
async loadCollections() {
|
||||
if (this.organization.isAdmin) {
|
||||
const collections = await this.apiService.getCollections(this.organization.id);
|
||||
if (collections != null && collections.data != null && collections.data.length) {
|
||||
const decCollections: CollectionView[] = [];
|
||||
const promises: any[] = [];
|
||||
collections.data.forEach((r) => {
|
||||
const data = new CollectionData(r);
|
||||
const collection = new Collection(data);
|
||||
promises.push(collection.decrypt().then((c) => decCollections.push(c)));
|
||||
});
|
||||
await Promise.all(promises);
|
||||
decCollections.sort(this.collectionService.getLocaleSortingFunction());
|
||||
this.collections = decCollections;
|
||||
} else {
|
||||
this.collections = [];
|
||||
}
|
||||
|
||||
const unassignedCollection = new CollectionView();
|
||||
unassignedCollection.name = this.i18nService.t('unassigned');
|
||||
unassignedCollection.id = 'unassigned';
|
||||
unassignedCollection.organizationId = this.organization.id;
|
||||
unassignedCollection.readOnly = true;
|
||||
this.collections.push(unassignedCollection);
|
||||
} else {
|
||||
if (!this.organization.isAdmin) {
|
||||
await super.loadCollections(this.organization.id);
|
||||
return;
|
||||
}
|
||||
const collections = await this.apiService.getCollections(this.organization.id);
|
||||
if (collections != null && collections.data != null && collections.data.length) {
|
||||
const decCollections: CollectionView[] = [];
|
||||
const promises: any[] = [];
|
||||
collections.data.forEach((r) => {
|
||||
const data = new CollectionData(r);
|
||||
const collection = new Collection(data);
|
||||
promises.push(collection.decrypt().then((c) => decCollections.push(c)));
|
||||
});
|
||||
await Promise.all(promises);
|
||||
decCollections.sort(this.collectionService.getLocaleSortingFunction());
|
||||
this.collections = decCollections;
|
||||
} else {
|
||||
this.collections = [];
|
||||
}
|
||||
|
||||
const unassignedCollection = new CollectionView();
|
||||
unassignedCollection.name = this.i18nService.t('unassigned');
|
||||
unassignedCollection.id = 'unassigned';
|
||||
unassignedCollection.organizationId = this.organization.id;
|
||||
unassignedCollection.readOnly = true;
|
||||
this.collections.push(unassignedCollection);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import { CipherType } from 'jslib/enums/cipherType';
|
|||
import { ModalComponent } from '../modal.component';
|
||||
|
||||
import { AddEditComponent } from './add-edit.component';
|
||||
import { AttachmentsComponent } from './attachments.component';
|
||||
import { CiphersComponent } from './ciphers.component';
|
||||
import { GroupingsComponent } from './groupings.component';
|
||||
|
||||
|
@ -33,6 +34,7 @@ import { GroupingsComponent } from './groupings.component';
|
|||
export class VaultComponent implements OnInit {
|
||||
@ViewChild(GroupingsComponent) groupingsComponent: GroupingsComponent;
|
||||
@ViewChild(CiphersComponent) ciphersComponent: CiphersComponent;
|
||||
@ViewChild('attachments', { read: ViewContainerRef }) attachmentsModalRef: ViewContainerRef;
|
||||
@ViewChild('cipherAddEdit', { read: ViewContainerRef }) cipherAddEditModalRef: ViewContainerRef;
|
||||
|
||||
organization: Organization;
|
||||
|
@ -125,6 +127,30 @@ export class VaultComponent implements OnInit {
|
|||
this.ciphersComponent.searchText = searchText;
|
||||
}
|
||||
|
||||
editCipherAttachments(cipher: CipherView) {
|
||||
if (this.modal != null) {
|
||||
this.modal.close();
|
||||
}
|
||||
|
||||
const factory = this.componentFactoryResolver.resolveComponentFactory(ModalComponent);
|
||||
this.modal = this.attachmentsModalRef.createComponent(factory).instance;
|
||||
const childComponent = this.modal.show<AttachmentsComponent>(AttachmentsComponent, this.attachmentsModalRef);
|
||||
|
||||
childComponent.organization = this.organization;
|
||||
childComponent.cipherId = cipher.id;
|
||||
let madeAttachmentChanges = false;
|
||||
childComponent.onUploadedAttachment.subscribe(() => madeAttachmentChanges = true);
|
||||
childComponent.onDeletedAttachment.subscribe(() => madeAttachmentChanges = true);
|
||||
|
||||
this.modal.onClosed.subscribe(async () => {
|
||||
this.modal = null;
|
||||
if (madeAttachmentChanges) {
|
||||
await this.ciphersComponent.refresh();
|
||||
}
|
||||
madeAttachmentChanges = false;
|
||||
});
|
||||
}
|
||||
|
||||
addCipher() {
|
||||
const component = this.editCipher(null);
|
||||
component.type = this.type;
|
||||
|
|
|
@ -86,6 +86,12 @@ body {
|
|||
}
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5 {
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
}
|
||||
|
||||
.secondary-header, .spaced-header {
|
||||
margin-top: 4rem;
|
||||
}
|
||||
|
@ -130,6 +136,7 @@ body {
|
|||
small {
|
||||
font-weight: normal;
|
||||
text-transform: none;
|
||||
@extend .text-muted;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue