mirror of
https://github.com/bitwarden/browser.git
synced 2024-11-27 12:36:14 +01:00
org vault listing from apis
This commit is contained in:
parent
af43232567
commit
ff8c1dfea9
@ -34,6 +34,7 @@ import { UpdateTwoFactorYubioOtpRequest } from '../models/request/updateTwoFacto
|
|||||||
|
|
||||||
import { BillingResponse } from '../models/response/billingResponse';
|
import { BillingResponse } from '../models/response/billingResponse';
|
||||||
import { CipherResponse } from '../models/response/cipherResponse';
|
import { CipherResponse } from '../models/response/cipherResponse';
|
||||||
|
import { CollectionResponse } from '../models/response/collectionResponse';
|
||||||
import { DomainsResponse } from '../models/response/domainsResponse';
|
import { DomainsResponse } from '../models/response/domainsResponse';
|
||||||
import { FolderResponse } from '../models/response/folderResponse';
|
import { FolderResponse } from '../models/response/folderResponse';
|
||||||
import { IdentityTokenResponse } from '../models/response/identityTokenResponse';
|
import { IdentityTokenResponse } from '../models/response/identityTokenResponse';
|
||||||
@ -79,6 +80,7 @@ export abstract class ApiService {
|
|||||||
postFolder: (request: FolderRequest) => Promise<FolderResponse>;
|
postFolder: (request: FolderRequest) => Promise<FolderResponse>;
|
||||||
putFolder: (id: string, request: FolderRequest) => Promise<FolderResponse>;
|
putFolder: (id: string, request: FolderRequest) => Promise<FolderResponse>;
|
||||||
deleteFolder: (id: string) => Promise<any>;
|
deleteFolder: (id: string) => Promise<any>;
|
||||||
|
getCiphersOrganization: (organizationId: string) => Promise<ListResponse<CipherResponse>>;
|
||||||
postCipher: (request: CipherRequest) => Promise<CipherResponse>;
|
postCipher: (request: CipherRequest) => Promise<CipherResponse>;
|
||||||
putCipher: (id: string, request: CipherRequest) => Promise<CipherResponse>;
|
putCipher: (id: string, request: CipherRequest) => Promise<CipherResponse>;
|
||||||
deleteCipher: (id: string) => Promise<any>;
|
deleteCipher: (id: string) => Promise<any>;
|
||||||
@ -94,6 +96,7 @@ export abstract class ApiService {
|
|||||||
deleteCipherAttachment: (id: string, attachmentId: string) => Promise<any>;
|
deleteCipherAttachment: (id: string, attachmentId: string) => Promise<any>;
|
||||||
postShareCipherAttachment: (id: string, attachmentId: string, data: FormData,
|
postShareCipherAttachment: (id: string, attachmentId: string, data: FormData,
|
||||||
organizationId: string) => Promise<any>;
|
organizationId: string) => Promise<any>;
|
||||||
|
getCollections: (organizationId: string) => Promise<ListResponse<CollectionResponse>>;
|
||||||
getSync: () => Promise<SyncResponse>;
|
getSync: () => Promise<SyncResponse>;
|
||||||
postImportDirectory: (organizationId: string, request: ImportDirectoryRequest) => Promise<any>;
|
postImportDirectory: (organizationId: string, request: ImportDirectoryRequest) => Promise<any>;
|
||||||
getSettingsDomains: () => Promise<DomainsResponse>;
|
getSettingsDomains: () => Promise<DomainsResponse>;
|
||||||
|
@ -44,4 +44,5 @@ export abstract class CipherService {
|
|||||||
deleteAttachmentWithServer: (id: string, attachmentId: string) => Promise<void>;
|
deleteAttachmentWithServer: (id: string, attachmentId: string) => Promise<void>;
|
||||||
sortCiphersByLastUsed: (a: any, b: any) => number;
|
sortCiphersByLastUsed: (a: any, b: any) => number;
|
||||||
sortCiphersByLastUsedThenName: (a: any, b: any) => number;
|
sortCiphersByLastUsedThenName: (a: any, b: any) => number;
|
||||||
|
getLocaleSortingFunction: () => (a: CipherView, b: CipherView) => number;
|
||||||
}
|
}
|
||||||
|
@ -15,4 +15,5 @@ export abstract class CollectionService {
|
|||||||
replace: (collections: { [id: string]: CollectionData; }) => Promise<any>;
|
replace: (collections: { [id: string]: CollectionData; }) => Promise<any>;
|
||||||
clear: (userId: string) => Promise<any>;
|
clear: (userId: string) => Promise<any>;
|
||||||
delete: (id: string | string[]) => Promise<any>;
|
delete: (id: string | string[]) => Promise<any>;
|
||||||
|
getLocaleSortingFunction: () => (a: CollectionView, b: CollectionView) => number;
|
||||||
}
|
}
|
||||||
|
@ -19,20 +19,15 @@ export class CiphersComponent {
|
|||||||
ciphers: CipherView[] = [];
|
ciphers: CipherView[] = [];
|
||||||
searchText: string;
|
searchText: string;
|
||||||
searchPlaceholder: string = null;
|
searchPlaceholder: string = null;
|
||||||
private filter: (cipher: CipherView) => boolean = null;
|
|
||||||
|
protected allCiphers: CipherView[] = [];
|
||||||
|
protected filter: (cipher: CipherView) => boolean = null;
|
||||||
|
|
||||||
constructor(protected cipherService: CipherService) { }
|
constructor(protected cipherService: CipherService) { }
|
||||||
|
|
||||||
async load(filter: (cipher: CipherView) => boolean = null) {
|
async load(filter: (cipher: CipherView) => boolean = null) {
|
||||||
this.filter = filter;
|
this.allCiphers = await this.cipherService.getAllDecrypted();
|
||||||
const ciphers = await this.cipherService.getAllDecrypted();
|
this.applyFilter(filter);
|
||||||
|
|
||||||
if (this.filter == null) {
|
|
||||||
this.ciphers = ciphers;
|
|
||||||
} else {
|
|
||||||
this.ciphers = ciphers.filter(this.filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.loaded = true;
|
this.loaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,6 +37,15 @@ export class CiphersComponent {
|
|||||||
await this.load(this.filter);
|
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) {
|
selectCipher(cipher: CipherView) {
|
||||||
this.onCipherClicked.emit(cipher);
|
this.onCipherClicked.emit(cipher);
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,10 @@ import { CollectionService } from '../../abstractions/collection.service';
|
|||||||
import { FolderService } from '../../abstractions/folder.service';
|
import { FolderService } from '../../abstractions/folder.service';
|
||||||
|
|
||||||
export class GroupingsComponent {
|
export class GroupingsComponent {
|
||||||
|
@Input() showFolders = true;
|
||||||
|
@Input() showCollections = true;
|
||||||
|
@Input() showFavorites = true;
|
||||||
|
|
||||||
@Output() onAllClicked = new EventEmitter();
|
@Output() onAllClicked = new EventEmitter();
|
||||||
@Output() onFavoritesClicked = new EventEmitter();
|
@Output() onFavoritesClicked = new EventEmitter();
|
||||||
@Output() onCipherTypeClicked = new EventEmitter<CipherType>();
|
@Output() onCipherTypeClicked = new EventEmitter<CipherType>();
|
||||||
@ -44,11 +48,22 @@ export class GroupingsComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async loadCollections() {
|
async loadCollections(organizationId?: string) {
|
||||||
this.collections = await this.collectionService.getAllDecrypted();
|
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() {
|
async loadFolders() {
|
||||||
|
if (!this.showFolders) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.folders = await this.folderService.getAllDecrypted();
|
this.folders = await this.folderService.getAllDecrypted();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,4 +21,15 @@ export class Organization {
|
|||||||
this.type = obj.type;
|
this.type = obj.type;
|
||||||
this.enabled = obj.enabled;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,12 +28,12 @@ export class CipherResponse {
|
|||||||
constructor(response: any) {
|
constructor(response: any) {
|
||||||
this.id = response.Id;
|
this.id = response.Id;
|
||||||
this.organizationId = response.OrganizationId;
|
this.organizationId = response.OrganizationId;
|
||||||
this.folderId = response.FolderId;
|
this.folderId = response.FolderId || null;
|
||||||
this.type = response.Type;
|
this.type = response.Type;
|
||||||
this.name = response.Name;
|
this.name = response.Name;
|
||||||
this.notes = response.Notes;
|
this.notes = response.Notes;
|
||||||
this.favorite = response.Favorite;
|
this.favorite = response.Favorite || false;
|
||||||
this.edit = response.Edit;
|
this.edit = response.Edit || true;
|
||||||
this.organizationUseTotp = response.OrganizationUseTotp;
|
this.organizationUseTotp = response.OrganizationUseTotp;
|
||||||
this.revisionDate = new Date(response.RevisionDate);
|
this.revisionDate = new Date(response.RevisionDate);
|
||||||
|
|
||||||
|
@ -40,6 +40,7 @@ import { UpdateTwoFactorYubioOtpRequest } from '../models/request/updateTwoFacto
|
|||||||
|
|
||||||
import { BillingResponse } from '../models/response/billingResponse';
|
import { BillingResponse } from '../models/response/billingResponse';
|
||||||
import { CipherResponse } from '../models/response/cipherResponse';
|
import { CipherResponse } from '../models/response/cipherResponse';
|
||||||
|
import { CollectionResponse } from '../models/response/collectionResponse';
|
||||||
import { DomainsResponse } from '../models/response/domainsResponse';
|
import { DomainsResponse } from '../models/response/domainsResponse';
|
||||||
import { ErrorResponse } from '../models/response/errorResponse';
|
import { ErrorResponse } from '../models/response/errorResponse';
|
||||||
import { FolderResponse } from '../models/response/folderResponse';
|
import { FolderResponse } from '../models/response/folderResponse';
|
||||||
@ -241,6 +242,12 @@ export class ApiService implements ApiServiceAbstraction {
|
|||||||
|
|
||||||
// Cipher APIs
|
// 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> {
|
async postCipher(request: CipherRequest): Promise<CipherResponse> {
|
||||||
const r = await this.send('POST', '/ciphers', request, true, true);
|
const r = await this.send('POST', '/ciphers', request, true, true);
|
||||||
return new CipherResponse(r);
|
return new CipherResponse(r);
|
||||||
@ -304,6 +311,13 @@ export class ApiService implements ApiServiceAbstraction {
|
|||||||
attachmentId + '/share?organizationId=' + organizationId, data, true, false);
|
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
|
// Sync APIs
|
||||||
|
|
||||||
async getSync(): Promise<SyncResponse> {
|
async getSync(): Promise<SyncResponse> {
|
||||||
|
@ -619,9 +619,7 @@ export class CipherService implements CipherServiceAbstraction {
|
|||||||
return this.getLocaleSortingFunction()(a, b);
|
return this.getLocaleSortingFunction()(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helpers
|
getLocaleSortingFunction(): (a: CipherView, b: CipherView) => number {
|
||||||
|
|
||||||
private getLocaleSortingFunction(): (a: CipherView, b: CipherView) => number {
|
|
||||||
return (a, b) => {
|
return (a, b) => {
|
||||||
let aName = a.name;
|
let aName = a.name;
|
||||||
let bName = b.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,
|
private async encryptObjProperty<V extends View, D extends Domain>(model: V, obj: D,
|
||||||
map: any, key: SymmetricCryptoKey): Promise<void> {
|
map: any, key: SymmetricCryptoKey): Promise<void> {
|
||||||
const promises = [];
|
const promises = [];
|
||||||
|
@ -125,7 +125,7 @@ export class CollectionService implements CollectionServiceAbstraction {
|
|||||||
this.decryptedCollectionCache = null;
|
this.decryptedCollectionCache = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getLocaleSortingFunction(): (a: CollectionView, b: CollectionView) => number {
|
getLocaleSortingFunction(): (a: CollectionView, b: CollectionView) => number {
|
||||||
return (a, b) => {
|
return (a, b) => {
|
||||||
if (a.name == null && b.name != null) {
|
if (a.name == null && b.name != null) {
|
||||||
return -1;
|
return -1;
|
||||||
|
Loading…
Reference in New Issue
Block a user