org user apis, sort function utils

This commit is contained in:
Kyle Spearrin 2018-07-06 15:00:55 -04:00
parent e25ad93082
commit 7b23b90054
7 changed files with 87 additions and 37 deletions

View File

@ -52,6 +52,7 @@ import { IdentityTokenResponse } from '../models/response/identityTokenResponse'
import { IdentityTwoFactorResponse } from '../models/response/identityTwoFactorResponse'; import { IdentityTwoFactorResponse } from '../models/response/identityTwoFactorResponse';
import { ListResponse } from '../models/response/listResponse'; import { ListResponse } from '../models/response/listResponse';
import { OrganizationResponse } from '../models/response/organizationResponse'; import { OrganizationResponse } from '../models/response/organizationResponse';
import { OrganizationUserUserDetailsResponse } from '../models/response/organizationUserResponse';
import { ProfileResponse } from '../models/response/profileResponse'; import { ProfileResponse } from '../models/response/profileResponse';
import { SyncResponse } from '../models/response/syncResponse'; import { SyncResponse } from '../models/response/syncResponse';
import { TwoFactorAuthenticatorResponse } from '../models/response/twoFactorAuthenticatorResponse'; import { TwoFactorAuthenticatorResponse } from '../models/response/twoFactorAuthenticatorResponse';
@ -70,6 +71,7 @@ export abstract class ApiService {
setUrls: (urls: EnvironmentUrls) => void; setUrls: (urls: EnvironmentUrls) => void;
postIdentityToken: (request: TokenRequest) => Promise<IdentityTokenResponse | IdentityTwoFactorResponse>; postIdentityToken: (request: TokenRequest) => Promise<IdentityTokenResponse | IdentityTwoFactorResponse>;
refreshIdentityToken: () => Promise<any>; refreshIdentityToken: () => Promise<any>;
getProfile: () => Promise<ProfileResponse>; getProfile: () => Promise<ProfileResponse>;
getUserBilling: () => Promise<BillingResponse>; getUserBilling: () => Promise<BillingResponse>;
putProfile: (request: UpdateProfileRequest) => Promise<ProfileResponse>; putProfile: (request: UpdateProfileRequest) => Promise<ProfileResponse>;
@ -88,9 +90,11 @@ export abstract class ApiService {
postAccountPayment: (request: PaymentRequest) => Promise<any>; postAccountPayment: (request: PaymentRequest) => Promise<any>;
postAccountLicense: (data: FormData) => Promise<any>; postAccountLicense: (data: FormData) => Promise<any>;
postAccountKeys: (request: KeysRequest) => Promise<any>; postAccountKeys: (request: KeysRequest) => Promise<any>;
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>;
getCipher: (id: string) => Promise<CipherResponse>; getCipher: (id: string) => Promise<CipherResponse>;
getCipherAdmin: (id: string) => Promise<CipherResponse>; getCipherAdmin: (id: string) => Promise<CipherResponse>;
getCiphersOrganization: (organizationId: string) => Promise<ListResponse<CipherResponse>>; getCiphersOrganization: (organizationId: string) => Promise<ListResponse<CipherResponse>>;
@ -109,28 +113,36 @@ export abstract class ApiService {
postPurgeCiphers: (request: PasswordVerificationRequest) => Promise<any>; postPurgeCiphers: (request: PasswordVerificationRequest) => Promise<any>;
postImportCiphers: (request: ImportCiphersRequest) => Promise<any>; postImportCiphers: (request: ImportCiphersRequest) => Promise<any>;
postImportOrganizationCiphers: (organizationId: string, request: ImportOrganizationCiphersRequest) => Promise<any>; postImportOrganizationCiphers: (organizationId: string, request: ImportOrganizationCiphersRequest) => Promise<any>;
postCipherAttachment: (id: string, data: FormData) => Promise<CipherResponse>; postCipherAttachment: (id: string, data: FormData) => Promise<CipherResponse>;
postCipherAttachmentAdmin: (id: string, data: FormData) => Promise<CipherResponse>; postCipherAttachmentAdmin: (id: string, data: FormData) => Promise<CipherResponse>;
deleteCipherAttachment: (id: string, attachmentId: string) => Promise<any>; deleteCipherAttachment: (id: string, attachmentId: string) => Promise<any>;
deleteCipherAttachmentAdmin: (id: string, attachmentId: string) => Promise<any>; deleteCipherAttachmentAdmin: (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>;
getCollectionDetails: (organizationId: string, id: string) => Promise<CollectionGroupDetailsResponse>; getCollectionDetails: (organizationId: string, id: string) => Promise<CollectionGroupDetailsResponse>;
getCollections: (organizationId: string) => Promise<ListResponse<CollectionResponse>>; getCollections: (organizationId: string) => Promise<ListResponse<CollectionResponse>>;
getCollectionUsers: (organizationId: string, id: string) => Promise<ListResponse<CollectionUserResponse>>; getCollectionUsers: (organizationId: string, id: string) => Promise<ListResponse<CollectionUserResponse>>;
postCollection: (request: CollectionRequest) => Promise<CollectionResponse>; postCollection: (request: CollectionRequest) => Promise<CollectionResponse>;
putCollection: (id: string, request: CollectionRequest) => Promise<CollectionResponse>; putCollection: (id: string, request: CollectionRequest) => Promise<CollectionResponse>;
deleteCollection: (id: string) => Promise<any>; deleteCollection: (id: string) => Promise<any>;
getGroupDetails: (organizationId: string, id: string) => Promise<GroupDetailsResponse>; getGroupDetails: (organizationId: string, id: string) => Promise<GroupDetailsResponse>;
getGroups: (organizationId: string) => Promise<ListResponse<GroupResponse>>; getGroups: (organizationId: string) => Promise<ListResponse<GroupResponse>>;
getGroupUsers: (organizationId: string, id: string) => Promise<ListResponse<GroupUserResponse>>; getGroupUsers: (organizationId: string, id: string) => Promise<ListResponse<GroupUserResponse>>;
postGroup: (request: GroupRequest) => Promise<GroupResponse>; postGroup: (request: GroupRequest) => Promise<GroupResponse>;
putGroup: (id: string, request: GroupRequest) => Promise<GroupResponse>; putGroup: (id: string, request: GroupRequest) => Promise<GroupResponse>;
deleteGroup: (id: string) => Promise<any>; deleteGroup: (id: string) => Promise<any>;
getOrganizationUsers: (organizationId: string) => Promise<ListResponse<OrganizationUserUserDetailsResponse>>;
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>;
putSettingsDomains: (request: UpdateDomainsRequest) => Promise<DomainsResponse>; putSettingsDomains: (request: UpdateDomainsRequest) => Promise<DomainsResponse>;
getTwoFactorProviders: () => Promise<ListResponse<TwoFactorProviderResponse>>; getTwoFactorProviders: () => Promise<ListResponse<TwoFactorProviderResponse>>;
getTwoFactorAuthenticator: (request: PasswordVerificationRequest) => Promise<TwoFactorAuthenticatorResponse>; getTwoFactorAuthenticator: (request: PasswordVerificationRequest) => Promise<TwoFactorAuthenticatorResponse>;
getTwoFactorEmail: (request: PasswordVerificationRequest) => Promise<TwoFactorEmailResponse>; getTwoFactorEmail: (request: PasswordVerificationRequest) => Promise<TwoFactorEmailResponse>;
@ -148,6 +160,7 @@ export abstract class ApiService {
postTwoFactorRecover: (request: TwoFactorRecoveryRequest) => Promise<any>; postTwoFactorRecover: (request: TwoFactorRecoveryRequest) => Promise<any>;
postTwoFactorEmailSetup: (request: TwoFactorEmailRequest) => Promise<any>; postTwoFactorEmailSetup: (request: TwoFactorEmailRequest) => Promise<any>;
postTwoFactorEmail: (request: TwoFactorEmailRequest) => Promise<any>; postTwoFactorEmail: (request: TwoFactorEmailRequest) => Promise<any>;
postOrganization: (request: OrganizationCreateRequest) => Promise<OrganizationResponse>; postOrganization: (request: OrganizationCreateRequest) => Promise<OrganizationResponse>;
postLeaveOrganization: (id: string) => Promise<any>; postLeaveOrganization: (id: string) => Promise<any>;
postOrganizationLicense: (data: FormData) => Promise<OrganizationResponse>; postOrganizationLicense: (data: FormData) => Promise<OrganizationResponse>;

View File

@ -17,5 +17,4 @@ 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;
} }

View File

@ -1,3 +1,5 @@
import { I18nService } from '../abstractions/i18n.service';
// tslint:disable-next-line // tslint:disable-next-line
const nodeURL = typeof window === 'undefined' ? require('url').URL : null; const nodeURL = typeof window === 'undefined' ? require('url').URL : null;
@ -149,6 +151,23 @@ export class Utils {
return url != null ? url.host : null; return url != null ? url.host : null;
} }
static getSortFunction(i18nService: I18nService, prop: string) {
return (a: any, b: any) => {
if (a[prop] == null && b[prop] != null) {
return -1;
}
if (a[prop] != null && b[prop] == null) {
return 1;
}
if (a[prop] == null && b[prop] == null) {
return 0;
}
return i18nService.collator ? i18nService.collator.compare(a[prop], b[prop]) :
a[prop].localeCompare(b[prop]);
};
}
private static getUrl(uriString: string): URL { private static getUrl(uriString: string): URL {
if (uriString == null) { if (uriString == null) {
return null; return null;

View File

@ -0,0 +1,41 @@
import { OrganizationUserStatusType } from '../../enums/organizationUserStatusType';
import { OrganizationUserType } from '../../enums/organizationUserType';
import { SelectionReadOnlyResponse } from './selectionReadOnlyResponse';
export class OrganizationUserResponse {
id: string;
userId: string;
type: OrganizationUserType;
status: OrganizationUserStatusType;
accessAll: boolean;
constructor(response: any) {
this.id = response.Id;
this.userId = response.UserId;
this.type = response.Type;
this.status = response.Status;
this.accessAll = response.AccessAll;
}
}
export class OrganizationUserUserDetailsResponse extends OrganizationUserResponse {
name: string;
email: string;
constructor(response: any) {
super(response);
this.name = response.Name;
this.email = response.Email;
}
}
export class OrganizationUserDetailsResponse extends OrganizationUserResponse {
collections: SelectionReadOnlyResponse;
constructor(response: any) {
super(response);
if (response.Collections != null) {
this.collections = response.Collections.map((c: any) => new SelectionReadOnlyResponse(c));
}
}
}

View File

@ -59,6 +59,7 @@ import { IdentityTokenResponse } from '../models/response/identityTokenResponse'
import { IdentityTwoFactorResponse } from '../models/response/identityTwoFactorResponse'; import { IdentityTwoFactorResponse } from '../models/response/identityTwoFactorResponse';
import { ListResponse } from '../models/response/listResponse'; import { ListResponse } from '../models/response/listResponse';
import { OrganizationResponse } from '../models/response/organizationResponse'; import { OrganizationResponse } from '../models/response/organizationResponse';
import { OrganizationUserUserDetailsResponse } from '../models/response/organizationUserResponse';
import { ProfileResponse } from '../models/response/profileResponse'; import { ProfileResponse } from '../models/response/profileResponse';
import { SyncResponse } from '../models/response/syncResponse'; import { SyncResponse } from '../models/response/syncResponse';
import { TwoFactorAuthenticatorResponse } from '../models/response/twoFactorAuthenticatorResponse'; import { TwoFactorAuthenticatorResponse } from '../models/response/twoFactorAuthenticatorResponse';
@ -425,6 +426,13 @@ export class ApiService implements ApiServiceAbstraction {
return this.send('DELETE', '/groups/' + id, null, true, false); return this.send('DELETE', '/groups/' + id, null, true, false);
} }
// Organization User APIs
async getOrganizationUsers(organizationId: string): Promise<ListResponse<OrganizationUserUserDetailsResponse>> {
const r = await this.send('GET', '/organizations/' + organizationId + '/users', null, true, true);
return new ListResponse(r, OrganizationUserUserDetailsResponse);
}
// Sync APIs // Sync APIs
async getSync(): Promise<SyncResponse> { async getSync(): Promise<SyncResponse> {

View File

@ -10,6 +10,8 @@ import { I18nService } from '../abstractions/i18n.service';
import { StorageService } from '../abstractions/storage.service'; import { StorageService } from '../abstractions/storage.service';
import { UserService } from '../abstractions/user.service'; import { UserService } from '../abstractions/user.service';
import { Utils } from '../misc/utils';
const Keys = { const Keys = {
collectionsPrefix: 'collections_', collectionsPrefix: 'collections_',
}; };
@ -51,7 +53,7 @@ export class CollectionService implements CollectionServiceAbstraction {
promises.push(collection.decrypt().then((c) => decCollections.push(c))); promises.push(collection.decrypt().then((c) => decCollections.push(c)));
}); });
await Promise.all(promises); await Promise.all(promises);
return decCollections.sort(this.getLocaleSortingFunction()); return decCollections.sort(Utils.getSortFunction(this.i18nService, 'name'));
} }
async get(id: string): Promise<Collection> { async get(id: string): Promise<Collection> {
@ -145,21 +147,4 @@ export class CollectionService implements CollectionServiceAbstraction {
await this.storageService.save(Keys.collectionsPrefix + userId, collections); await this.storageService.save(Keys.collectionsPrefix + userId, collections);
this.decryptedCollectionCache = null; this.decryptedCollectionCache = null;
} }
getLocaleSortingFunction(): (a: CollectionView, b: CollectionView) => number {
return (a, b) => {
if (a.name == null && b.name != null) {
return -1;
}
if (a.name != null && b.name == null) {
return 1;
}
if (a.name == null && b.name == null) {
return 0;
}
return this.i18nService.collator ? this.i18nService.collator.compare(a.name, b.name) :
a.name.localeCompare(b.name);
};
}
} }

View File

@ -17,6 +17,8 @@ import { StorageService } from '../abstractions/storage.service';
import { UserService } from '../abstractions/user.service'; import { UserService } from '../abstractions/user.service';
import { CipherData } from '../models/data/cipherData'; import { CipherData } from '../models/data/cipherData';
import { Utils } from '../misc/utils';
const Keys = { const Keys = {
foldersPrefix: 'folders_', foldersPrefix: 'folders_',
ciphersPrefix: 'ciphers_', ciphersPrefix: 'ciphers_',
@ -82,7 +84,7 @@ export class FolderService implements FolderServiceAbstraction {
}); });
await Promise.all(promises); await Promise.all(promises);
decFolders.sort(this.getLocaleSortingFunction()); decFolders.sort(Utils.getSortFunction(this.i18nService, 'name'));
const noneFolder = new FolderView(); const noneFolder = new FolderView();
noneFolder.name = this.i18nService.t('noneFolder'); noneFolder.name = this.i18nService.t('noneFolder');
@ -180,21 +182,4 @@ export class FolderService implements FolderServiceAbstraction {
await this.apiService.deleteFolder(id); await this.apiService.deleteFolder(id);
await this.delete(id); await this.delete(id);
} }
private getLocaleSortingFunction(): (a: FolderView, b: FolderView) => number {
return (a, b) => {
if (a.name == null && b.name != null) {
return -1;
}
if (a.name != null && b.name == null) {
return 1;
}
if (a.name == null && b.name == null) {
return 0;
}
return this.i18nService.collator ? this.i18nService.collator.compare(a.name, b.name) :
a.name.localeCompare(b.name);
};
}
} }