org vault listing from apis

This commit is contained in:
Kyle Spearrin 2018-07-03 23:33:15 -04:00
parent af43232567
commit ff8c1dfea9
10 changed files with 68 additions and 19 deletions

View File

@ -34,6 +34,7 @@ import { UpdateTwoFactorYubioOtpRequest } from '../models/request/updateTwoFacto
import { BillingResponse } from '../models/response/billingResponse';
import { CipherResponse } from '../models/response/cipherResponse';
import { CollectionResponse } from '../models/response/collectionResponse';
import { DomainsResponse } from '../models/response/domainsResponse';
import { FolderResponse } from '../models/response/folderResponse';
import { IdentityTokenResponse } from '../models/response/identityTokenResponse';
@ -79,6 +80,7 @@ export abstract class ApiService {
postFolder: (request: FolderRequest) => Promise<FolderResponse>;
putFolder: (id: string, request: FolderRequest) => Promise<FolderResponse>;
deleteFolder: (id: string) => Promise<any>;
getCiphersOrganization: (organizationId: string) => Promise<ListResponse<CipherResponse>>;
postCipher: (request: CipherRequest) => Promise<CipherResponse>;
putCipher: (id: string, request: CipherRequest) => Promise<CipherResponse>;
deleteCipher: (id: string) => Promise<any>;
@ -94,6 +96,7 @@ export abstract class ApiService {
deleteCipherAttachment: (id: string, attachmentId: string) => Promise<any>;
postShareCipherAttachment: (id: string, attachmentId: string, data: FormData,
organizationId: string) => Promise<any>;
getCollections: (organizationId: string) => Promise<ListResponse<CollectionResponse>>;
getSync: () => Promise<SyncResponse>;
postImportDirectory: (organizationId: string, request: ImportDirectoryRequest) => Promise<any>;
getSettingsDomains: () => Promise<DomainsResponse>;

View File

@ -44,4 +44,5 @@ export abstract class CipherService {
deleteAttachmentWithServer: (id: string, attachmentId: string) => Promise<void>;
sortCiphersByLastUsed: (a: any, b: any) => number;
sortCiphersByLastUsedThenName: (a: any, b: any) => number;
getLocaleSortingFunction: () => (a: CipherView, b: CipherView) => number;
}

View File

@ -15,4 +15,5 @@ export abstract class CollectionService {
replace: (collections: { [id: string]: CollectionData; }) => Promise<any>;
clear: (userId: string) => Promise<any>;
delete: (id: string | string[]) => Promise<any>;
getLocaleSortingFunction: () => (a: CollectionView, b: CollectionView) => number;
}

View File

@ -19,20 +19,15 @@ export class CiphersComponent {
ciphers: CipherView[] = [];
searchText: string;
searchPlaceholder: string = null;
private filter: (cipher: CipherView) => boolean = null;
protected allCiphers: CipherView[] = [];
protected filter: (cipher: CipherView) => boolean = null;
constructor(protected cipherService: CipherService) { }
async load(filter: (cipher: CipherView) => boolean = null) {
this.filter = filter;
const ciphers = await this.cipherService.getAllDecrypted();
if (this.filter == null) {
this.ciphers = ciphers;
} else {
this.ciphers = ciphers.filter(this.filter);
}
this.allCiphers = await this.cipherService.getAllDecrypted();
this.applyFilter(filter);
this.loaded = true;
}
@ -42,6 +37,15 @@ export class CiphersComponent {
await this.load(this.filter);
}
async applyFilter(filter: (cipher: CipherView) => boolean = null) {
this.filter = filter;
if (this.filter == null) {
this.ciphers = this.allCiphers;
} else {
this.ciphers = this.allCiphers.filter(this.filter);
}
}
selectCipher(cipher: CipherView) {
this.onCipherClicked.emit(cipher);
}

View File

@ -14,6 +14,10 @@ import { CollectionService } from '../../abstractions/collection.service';
import { FolderService } from '../../abstractions/folder.service';
export class GroupingsComponent {
@Input() showFolders = true;
@Input() showCollections = true;
@Input() showFavorites = true;
@Output() onAllClicked = new EventEmitter();
@Output() onFavoritesClicked = new EventEmitter();
@Output() onCipherTypeClicked = new EventEmitter<CipherType>();
@ -44,11 +48,22 @@ export class GroupingsComponent {
}
}
async loadCollections() {
this.collections = await this.collectionService.getAllDecrypted();
async loadCollections(organizationId?: string) {
if (!this.showCollections) {
return;
}
const collections = await this.collectionService.getAllDecrypted();
if (organizationId != null) {
this.collections = collections.filter((c) => c.organizationId === organizationId);
} else {
this.collections = collections;
}
}
async loadFolders() {
if (!this.showFolders) {
return;
}
this.folders = await this.folderService.getAllDecrypted();
}

View File

@ -21,4 +21,15 @@ export class Organization {
this.type = obj.type;
this.enabled = obj.enabled;
}
get canAccess() {
if (this.type === OrganizationUserType.Owner) {
return true;
}
return this.enabled && this.status === OrganizationUserStatusType.Confirmed;
}
get isAdmin() {
return this.type === OrganizationUserType.Owner || this.type === OrganizationUserType.Admin;
}
}

View File

@ -28,12 +28,12 @@ export class CipherResponse {
constructor(response: any) {
this.id = response.Id;
this.organizationId = response.OrganizationId;
this.folderId = response.FolderId;
this.folderId = response.FolderId || null;
this.type = response.Type;
this.name = response.Name;
this.notes = response.Notes;
this.favorite = response.Favorite;
this.edit = response.Edit;
this.favorite = response.Favorite || false;
this.edit = response.Edit || true;
this.organizationUseTotp = response.OrganizationUseTotp;
this.revisionDate = new Date(response.RevisionDate);

View File

@ -40,6 +40,7 @@ import { UpdateTwoFactorYubioOtpRequest } from '../models/request/updateTwoFacto
import { BillingResponse } from '../models/response/billingResponse';
import { CipherResponse } from '../models/response/cipherResponse';
import { CollectionResponse } from '../models/response/collectionResponse';
import { DomainsResponse } from '../models/response/domainsResponse';
import { ErrorResponse } from '../models/response/errorResponse';
import { FolderResponse } from '../models/response/folderResponse';
@ -241,6 +242,12 @@ export class ApiService implements ApiServiceAbstraction {
// Cipher APIs
async getCiphersOrganization(organizationId: string): Promise<ListResponse<CipherResponse>> {
const r = await this.send('GET', '/ciphers/organization-details?organizationId=' + organizationId,
null, true, true);
return new ListResponse(r, CipherResponse);
}
async postCipher(request: CipherRequest): Promise<CipherResponse> {
const r = await this.send('POST', '/ciphers', request, true, true);
return new CipherResponse(r);
@ -304,6 +311,13 @@ export class ApiService implements ApiServiceAbstraction {
attachmentId + '/share?organizationId=' + organizationId, data, true, false);
}
// Collections APIs
async getCollections(organizationId: string): Promise<ListResponse<CollectionResponse>> {
const r = await this.send('GET', '/organizations/' + organizationId + '/collections', null, true, true);
return new ListResponse(r, CollectionResponse);
}
// Sync APIs
async getSync(): Promise<SyncResponse> {

View File

@ -619,9 +619,7 @@ export class CipherService implements CipherServiceAbstraction {
return this.getLocaleSortingFunction()(a, b);
}
// Helpers
private getLocaleSortingFunction(): (a: CipherView, b: CipherView) => number {
getLocaleSortingFunction(): (a: CipherView, b: CipherView) => number {
return (a, b) => {
let aName = a.name;
let bName = b.name;
@ -656,6 +654,8 @@ export class CipherService implements CipherServiceAbstraction {
};
}
// Helpers
private async encryptObjProperty<V extends View, D extends Domain>(model: V, obj: D,
map: any, key: SymmetricCryptoKey): Promise<void> {
const promises = [];

View File

@ -125,7 +125,7 @@ export class CollectionService implements CollectionServiceAbstraction {
this.decryptedCollectionCache = null;
}
private getLocaleSortingFunction(): (a: CollectionView, b: CollectionView) => number {
getLocaleSortingFunction(): (a: CollectionView, b: CollectionView) => number {
return (a, b) => {
if (a.name == null && b.name != null) {
return -1;