2018-05-14 19:37:52 +02:00
|
|
|
import * as program from 'commander';
|
|
|
|
|
2018-10-14 04:27:33 +02:00
|
|
|
import { CipherView } from 'jslib/models/view/cipherView';
|
|
|
|
|
2019-10-01 17:29:25 +02:00
|
|
|
import { ApiService } from 'jslib/abstractions/api.service';
|
2018-05-14 19:37:52 +02:00
|
|
|
import { CipherService } from 'jslib/abstractions/cipher.service';
|
2018-05-18 21:26:59 +02:00
|
|
|
import { CollectionService } from 'jslib/abstractions/collection.service';
|
|
|
|
import { FolderService } from 'jslib/abstractions/folder.service';
|
2018-08-13 20:38:04 +02:00
|
|
|
import { SearchService } from 'jslib/abstractions/search.service';
|
2018-05-18 21:26:59 +02:00
|
|
|
import { UserService } from 'jslib/abstractions/user.service';
|
2018-05-14 19:37:52 +02:00
|
|
|
|
2019-10-01 17:29:25 +02:00
|
|
|
import {
|
|
|
|
CollectionDetailsResponse as ApiCollectionDetailsResponse,
|
|
|
|
CollectionResponse as ApiCollectionResponse,
|
|
|
|
} from 'jslib/models/response/collectionResponse';
|
|
|
|
import { ListResponse as ApiListResponse } from 'jslib/models/response/listResponse';
|
|
|
|
|
|
|
|
import { CollectionData } from 'jslib/models/data/collectionData';
|
|
|
|
|
|
|
|
import { Collection } from 'jslib/models/domain/collection';
|
|
|
|
|
2019-03-16 03:34:59 +01:00
|
|
|
import { Response } from 'jslib/cli/models/response';
|
|
|
|
import { ListResponse } from 'jslib/cli/models/response/listResponse';
|
|
|
|
|
2018-05-14 20:54:19 +02:00
|
|
|
import { CipherResponse } from '../models/response/cipherResponse';
|
|
|
|
import { CollectionResponse } from '../models/response/collectionResponse';
|
|
|
|
import { FolderResponse } from '../models/response/folderResponse';
|
2018-05-18 21:26:59 +02:00
|
|
|
import { OrganizationResponse } from '../models/response/organizationResponse';
|
2019-10-07 15:58:19 +02:00
|
|
|
import { OrganizationUserResponse } from '../models/response/organizationUserResponse';
|
2018-05-14 20:54:19 +02:00
|
|
|
|
2018-05-16 17:17:40 +02:00
|
|
|
import { CliUtils } from '../utils';
|
|
|
|
|
2019-10-01 17:29:25 +02:00
|
|
|
import { Utils } from 'jslib/misc/utils';
|
|
|
|
|
2018-05-14 19:37:52 +02:00
|
|
|
export class ListCommand {
|
|
|
|
constructor(private cipherService: CipherService, private folderService: FolderService,
|
2018-08-13 20:38:04 +02:00
|
|
|
private collectionService: CollectionService, private userService: UserService,
|
2019-10-01 17:29:25 +02:00
|
|
|
private searchService: SearchService, private apiService: ApiService) { }
|
2018-05-14 19:37:52 +02:00
|
|
|
|
2018-05-14 20:54:19 +02:00
|
|
|
async run(object: string, cmd: program.Command): Promise<Response> {
|
2018-05-14 22:25:14 +02:00
|
|
|
switch (object.toLowerCase()) {
|
2018-05-14 19:37:52 +02:00
|
|
|
case 'items':
|
2018-05-16 16:56:46 +02:00
|
|
|
return await this.listCiphers(cmd);
|
2018-05-14 19:37:52 +02:00
|
|
|
case 'folders':
|
2018-05-16 16:56:46 +02:00
|
|
|
return await this.listFolders(cmd);
|
2018-05-14 19:37:52 +02:00
|
|
|
case 'collections':
|
2018-05-16 16:56:46 +02:00
|
|
|
return await this.listCollections(cmd);
|
2019-10-01 17:29:25 +02:00
|
|
|
case 'org-collections':
|
|
|
|
return await this.listOrganizationCollections(cmd);
|
2019-10-07 15:58:19 +02:00
|
|
|
case 'org-members':
|
|
|
|
return await this.listOrganizationMembers(cmd);
|
2018-05-18 21:26:59 +02:00
|
|
|
case 'organizations':
|
|
|
|
return await this.listOrganizations(cmd);
|
2018-05-14 19:37:52 +02:00
|
|
|
default:
|
2018-05-14 20:54:19 +02:00
|
|
|
return Response.badRequest('Unknown object.');
|
2018-05-14 19:37:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-03 18:44:33 +01:00
|
|
|
private async listCiphers(options: program.OptionValues) {
|
2018-10-14 04:27:33 +02:00
|
|
|
let ciphers: CipherView[];
|
2021-02-03 18:44:33 +01:00
|
|
|
options.trash = options.trash || false;
|
|
|
|
if (options.url != null && options.url.trim() !== '') {
|
|
|
|
ciphers = await this.cipherService.getAllDecryptedForUrl(options.url);
|
2018-10-14 04:27:33 +02:00
|
|
|
} else {
|
|
|
|
ciphers = await this.cipherService.getAllDecrypted();
|
|
|
|
}
|
2018-05-16 16:56:46 +02:00
|
|
|
|
2021-02-03 18:44:33 +01:00
|
|
|
if (options.folderid != null || options.collectionid != null || options.organizationid != null) {
|
2018-05-16 16:56:46 +02:00
|
|
|
ciphers = ciphers.filter((c) => {
|
2021-02-03 18:44:33 +01:00
|
|
|
if (options.trash !== c.isDeleted) {
|
2020-04-14 19:04:19 +02:00
|
|
|
return false;
|
|
|
|
}
|
2021-02-03 18:44:33 +01:00
|
|
|
if (options.folderid != null) {
|
|
|
|
if (options.folderid === 'notnull' && c.folderId != null) {
|
2018-05-16 16:56:46 +02:00
|
|
|
return true;
|
|
|
|
}
|
2021-02-03 18:44:33 +01:00
|
|
|
const folderId = options.folderid === 'null' ? null : options.folderid;
|
2018-05-16 16:56:46 +02:00
|
|
|
if (folderId === c.folderId) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-03 18:44:33 +01:00
|
|
|
if (options.organizationid != null) {
|
|
|
|
if (options.organizationid === 'notnull' && c.organizationId != null) {
|
2018-05-16 16:56:46 +02:00
|
|
|
return true;
|
|
|
|
}
|
2021-02-03 18:44:33 +01:00
|
|
|
const organizationId = options.organizationid === 'null' ? null : options.organizationid;
|
2018-05-16 16:56:46 +02:00
|
|
|
if (organizationId === c.organizationId) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-03 18:44:33 +01:00
|
|
|
if (options.collectionid != null) {
|
|
|
|
if (options.collectionid === 'notnull' && c.collectionIds != null && c.collectionIds.length > 0) {
|
2018-05-16 16:56:46 +02:00
|
|
|
return true;
|
|
|
|
}
|
2021-02-03 18:44:33 +01:00
|
|
|
const collectionId = options.collectionid === 'null' ? null : options.collectionid;
|
2018-10-14 06:09:53 +02:00
|
|
|
if (collectionId == null && (c.collectionIds == null || c.collectionIds.length === 0)) {
|
2018-05-16 16:56:46 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (collectionId != null && c.collectionIds != null && c.collectionIds.indexOf(collectionId) > -1) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
});
|
2021-02-03 18:44:33 +01:00
|
|
|
} else if (options.search == null || options.search.trim() === '') {
|
|
|
|
ciphers = ciphers.filter((c) => options.trash === c.isDeleted);
|
2018-05-16 16:56:46 +02:00
|
|
|
}
|
|
|
|
|
2021-02-03 18:44:33 +01:00
|
|
|
if (options.search != null && options.search.trim() !== '') {
|
|
|
|
ciphers = this.searchService.searchCiphersBasic(ciphers, options.search, options.trash);
|
2018-05-16 16:56:46 +02:00
|
|
|
}
|
|
|
|
|
2018-05-14 20:54:19 +02:00
|
|
|
const res = new ListResponse(ciphers.map((o) => new CipherResponse(o)));
|
|
|
|
return Response.success(res);
|
2018-05-14 19:37:52 +02:00
|
|
|
}
|
|
|
|
|
2021-02-03 18:44:33 +01:00
|
|
|
private async listFolders(options: program.OptionValues) {
|
2018-05-16 16:56:46 +02:00
|
|
|
let folders = await this.folderService.getAllDecrypted();
|
|
|
|
|
2021-02-03 18:44:33 +01:00
|
|
|
if (options.search != null && options.search.trim() !== '') {
|
|
|
|
folders = CliUtils.searchFolders(folders, options.search);
|
2018-05-16 16:56:46 +02:00
|
|
|
}
|
|
|
|
|
2018-05-14 20:54:19 +02:00
|
|
|
const res = new ListResponse(folders.map((o) => new FolderResponse(o)));
|
|
|
|
return Response.success(res);
|
2018-05-14 19:37:52 +02:00
|
|
|
}
|
|
|
|
|
2021-02-03 18:44:33 +01:00
|
|
|
private async listCollections(options: program.OptionValues) {
|
2018-05-16 16:56:46 +02:00
|
|
|
let collections = await this.collectionService.getAllDecrypted();
|
|
|
|
|
2021-02-03 18:44:33 +01:00
|
|
|
if (options.organizationid != null) {
|
2018-05-16 16:56:46 +02:00
|
|
|
collections = collections.filter((c) => {
|
2021-02-03 18:44:33 +01:00
|
|
|
if (options.organizationid === c.organizationId) {
|
2018-05-16 16:56:46 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-02-03 18:44:33 +01:00
|
|
|
if (options.search != null && options.search.trim() !== '') {
|
|
|
|
collections = CliUtils.searchCollections(collections, options.search);
|
2018-05-16 16:56:46 +02:00
|
|
|
}
|
|
|
|
|
2018-05-14 20:54:19 +02:00
|
|
|
const res = new ListResponse(collections.map((o) => new CollectionResponse(o)));
|
|
|
|
return Response.success(res);
|
2018-05-14 19:37:52 +02:00
|
|
|
}
|
2018-05-18 21:26:59 +02:00
|
|
|
|
2021-02-03 18:44:33 +01:00
|
|
|
private async listOrganizationCollections(options: program.OptionValues) {
|
|
|
|
if (options.organizationid == null || options.organizationid === '') {
|
2019-10-01 17:29:25 +02:00
|
|
|
return Response.badRequest('--organizationid <organizationid> required.');
|
|
|
|
}
|
2021-02-03 18:44:33 +01:00
|
|
|
if (!Utils.isGuid(options.organizationid)) {
|
|
|
|
return Response.error('`' + options.organizationid + '` is not a GUID.');
|
2019-10-01 17:29:25 +02:00
|
|
|
}
|
2021-02-03 18:44:33 +01:00
|
|
|
const organization = await this.userService.getOrganization(options.organizationid);
|
2019-10-01 17:29:25 +02:00
|
|
|
if (organization == null) {
|
|
|
|
return Response.error('Organization not found.');
|
|
|
|
}
|
|
|
|
|
2019-10-07 15:58:19 +02:00
|
|
|
try {
|
|
|
|
let response: ApiListResponse<ApiCollectionResponse>;
|
2020-12-22 19:59:07 +01:00
|
|
|
if (organization.canManageAllCollections) {
|
2021-02-03 18:44:33 +01:00
|
|
|
response = await this.apiService.getCollections(options.organizationid);
|
2019-10-07 15:58:19 +02:00
|
|
|
} else {
|
|
|
|
response = await this.apiService.getUserCollections();
|
|
|
|
}
|
2021-02-03 18:44:33 +01:00
|
|
|
const collections = response.data.filter((c) => c.organizationId === options.organizationid).map((r) =>
|
2019-10-07 15:58:19 +02:00
|
|
|
new Collection(new CollectionData(r as ApiCollectionDetailsResponse)));
|
|
|
|
let decCollections = await this.collectionService.decryptMany(collections);
|
2021-02-03 18:44:33 +01:00
|
|
|
if (options.search != null && options.search.trim() !== '') {
|
|
|
|
decCollections = CliUtils.searchCollections(decCollections, options.search);
|
2019-10-07 15:58:19 +02:00
|
|
|
}
|
|
|
|
const res = new ListResponse(decCollections.map((o) => new CollectionResponse(o)));
|
|
|
|
return Response.success(res);
|
|
|
|
} catch (e) {
|
|
|
|
return Response.error(e);
|
2019-10-01 17:29:25 +02:00
|
|
|
}
|
2019-10-07 15:58:19 +02:00
|
|
|
}
|
|
|
|
|
2021-02-03 18:44:33 +01:00
|
|
|
private async listOrganizationMembers(options: program.OptionValues) {
|
|
|
|
if (options.organizationid == null || options.organizationid === '') {
|
2019-10-07 15:58:19 +02:00
|
|
|
return Response.badRequest('--organizationid <organizationid> required.');
|
|
|
|
}
|
2021-02-03 18:44:33 +01:00
|
|
|
if (!Utils.isGuid(options.organizationid)) {
|
|
|
|
return Response.error('`' + options.organizationid + '` is not a GUID.');
|
2019-10-07 15:58:19 +02:00
|
|
|
}
|
2021-02-03 18:44:33 +01:00
|
|
|
const organization = await this.userService.getOrganization(options.organizationid);
|
2019-10-07 15:58:19 +02:00
|
|
|
if (organization == null) {
|
|
|
|
return Response.error('Organization not found.');
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
2021-02-03 18:44:33 +01:00
|
|
|
const response = await this.apiService.getOrganizationUsers(options.organizationid);
|
2019-10-07 15:58:19 +02:00
|
|
|
const res = new ListResponse(response.data.map((r) => {
|
|
|
|
const u = new OrganizationUserResponse();
|
|
|
|
u.email = r.email;
|
|
|
|
u.name = r.name;
|
|
|
|
u.id = r.id;
|
|
|
|
u.status = r.status;
|
|
|
|
u.type = r.type;
|
|
|
|
u.twoFactorEnabled = r.twoFactorEnabled;
|
|
|
|
return u;
|
|
|
|
}));
|
|
|
|
return Response.success(res);
|
|
|
|
} catch (e) {
|
|
|
|
return Response.error(e);
|
2019-10-01 17:29:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-03 18:44:33 +01:00
|
|
|
private async listOrganizations(options: program.OptionValues) {
|
2018-05-18 21:26:59 +02:00
|
|
|
let organizations = await this.userService.getAllOrganizations();
|
|
|
|
|
2021-02-03 18:44:33 +01:00
|
|
|
if (options.search != null && options.search.trim() !== '') {
|
|
|
|
organizations = CliUtils.searchOrganizations(organizations, options.search);
|
2018-05-18 21:26:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
const res = new ListResponse(organizations.map((o) => new OrganizationResponse(o)));
|
|
|
|
return Response.success(res);
|
|
|
|
}
|
2018-05-14 19:37:52 +02:00
|
|
|
}
|