///////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2002-2021, Open Design Alliance (the "Alliance").
// All rights reserved.
//
// This software and its documentation and related materials are owned by
// the Alliance. The software may only be incorporated into application
// programs owned by members of the Alliance, subject to a signed
// Membership Agreement and Supplemental Software License Agreement with the
// Alliance. The structure and organization of this software are the valuable
// trade secrets of the Alliance and its suppliers. The software is also
// protected by copyright law and international treaty provisions. Application
// programs incorporating this software must include the following statement
// with their copyright notices:
//
// This application incorporates Open Design Alliance software pursuant to a
// license agreement with Open Design Alliance.
// Open Design Alliance Copyright (C) 2002-2021 by Open Design Alliance.
// All rights reserved.
//
// By use of this software, its documentation or related materials, you
// acknowledge and accept the above terms.
///////////////////////////////////////////////////////////////////////////////
import { IHttpClient } from "./IHttpClient";
import { json, userFullName, userInitials } from "./impl/Utils";
export interface UserParams {
/**
* `true` if user is an administrator
*/
isAdmin?: boolean;
/**
* User name
*/
userName?: string;
/**
* First name
*/
firstName?: string;
/**
* Last name
*/
lastName?: string;
/**
* `true` if user is allowed to create a project
*/
canCreateProject?: boolean;
/**
* The maximum number of projects that the user can create
*/
projectsLimit?: number;
/**
* The size of the file storage available to the user
*/
storageLimit?: number;
}
/**
* The class representing a `user` entity.
*/
export class User {
private _data: any;
protected httpClient: IHttpClient;
/**
* @param data - An object that implements user data storage.
* @param httpClient - Http client.
*/
constructor(data: any, httpClient: IHttpClient) {
this.httpClient = httpClient;
this.data = data;
}
/**
* User avatar image URL. Use {@link User#setAvatar | setAvatar()} to change avatar image.
*
* @readonly
*/
get avatarUrl(): string {
return this._data.avatarUrl;
}
/**
* `true` if user is allowed to create a project.
*
* @readonly
*/
get canCreateProject(): boolean {
return this.data.canCreateProject;
}
/**
* User account registration time (UTC) in the format specified in ISO 8601.
*
* @readonly
*/
get createAt(): string {
return this.data.createAt;
}
/**
* User custom fields object, to store custom data.
*/
get customFields(): any {
return this.data.customFields;
}
set customFields(value: any) {
this._data.customFields = value;
}
/**
* Raw user data received from the server.
*
* @readonly
*/
get data(): any {
return this._data;
}
private set data(value: any) {
this._data = value;
this._data.avatarUrl = value.avatarImage ? `${this.httpClient.serverUrl}/users/${this._data.id}/avatar` : "";
this._data.fullName = userFullName(this._data);
this._data.initials = userInitials(this._data.fullName);
}
/**
* User email.
*
* @readonly
*/
get email(): string {
return this.data.email;
}
/**
* The user's email confirmation code, or an empty string if the email has already been confirmed.
*
* @readonly
*/
get emailConfirmationId(): string {
return this.data.emailConfirmationId;
}
/**
* First name.
*/
get firstName(): string {
return this.data.firstName;
}
set firstName(value: string) {
this._data.firstName = value;
}
/**
* Full name. Returns the user's first and last name. If first name and last names are empty,
* returns the user name.
*/
get fullName(): string {
return this.data.fullName;
}
/**
* Unique user ID.
*
* @readonly
*/
get id(): string {
return this.data.id;
}
/**
* User initials. Returns a first letters of the user's first and last names. If first name
* and last names are empty, returns the first letter of the user name.
*/
get initials(): string {
return this.data.initials;
}
/**
* `false` if the user has not yet confirmed his email address.
*
* @readonly
*/
get isEmailConfirmed(): boolean {
return this.data.isEmailConfirmed;
}
/**
* User last update time (UTC) in the format specified in ISO 8601.
*/
get lastModified(): string {
return this.data.lastModified;
}
/**
* Last name.
*/
get lastName(): string {
return this.data.lastName;
}
set lastName(value: string) {
this._data.lastName = value;
}
/**
* User last sign in time (UTC) in the format specified in ISO 8601.
*/
get lastSignIn(): string {
return this.data.lastSignIn;
}
/**
* The maximum number of projects that a user can create.
*
* @readonly
*/
get projectsLimit(): number {
return this.data.projectsLimit;
}
/**
* The user's API key.
*
* @readonly
*/
get token(): string {
return this.data.tokenInfo.token;
}
/**
* User name.
*/
get userName(): string {
return this.data.userName;
}
set userName(value: string) {
this._data.userName = value;
}
/**
* Refresh user data. Only admins can checkout other users, if the current logged in user
* does not have administrator rights, hi can only checkout himself, otherwise an exception
* will be thrown.
*/
async checkout(): Promise {
if (this.id === this.httpClient.signInUserId) {
const data = await json(this.httpClient.get("/user"));
this.data = { id: this.id, ...data };
} else {
const data = await json(this.httpClient.get(`/users/${this.id}`));
this.data = { id: data.id, ...data.userBrief };
}
return this;
}
/**
* Update user data on the server. Only admins can update other users, if the current logged
* in user does not have administrator rights, hi can only update himself, otherwise an
* exception will be thrown.
*
* @async
* @param data - Raw user data.
*/
async update(data: any) {
if (this.id === this.httpClient.signInUserId) {
const newData = await json(this.httpClient.put("/user", data));
this.data = { id: this.id, ...newData };
} else {
const newData = await json(this.httpClient.put(`/users/${this.id}`, { userBrief: data }));
this.data = { id: newData.id, ...newData.userBrief };
}
return this;
}
/**
* Delete a user from the server. Only admins can delete users, if the current logged in user
* does not have administrator rights, an exception will be thrown.
*
* Admins can delete themselves or other admins. An admin can only delete himself if he is
* not the last administrator.
*
* You need to re-login to continue working after deleting the current logged in user.
*
* @async
* @returns Returns the raw data of a deleted user.
*/
delete(): Promise {
return json(this.httpClient.delete(`/users/${this.id}`)).then((data) => {
if (this.id === this.httpClient.signInUserId) {
this.httpClient.headers = {};
this.httpClient.signInUserId = "";
}
return data;
});
}
/**
* Save user data changes to the server. Call this method to update user data on the server
* after any changes.
*
* @async
*/
save(): Promise {
return this.update(this.data);
}
/**
* Set or remove the user avatar. Only admins can set the avatar of other users, if the
* current logged in user does not have administrator rights, he can only set his own avatar,
* otherwise an exception will be thrown.
*
* @async
* @param image - Avatar image. Can be a Data URL string, ArrayBuffer, Blob or
* Web API File object. Setting the `image` to `null` will remove the avatar.
*/
async setAvatar(image?: ArrayBuffer | Blob | globalThis.File | FormData | string | null): Promise {
if (image) {
if (this.id === this.httpClient.signInUserId) {
const data = await json(this.httpClient.post("/user/avatar", image));
this.data = { id: this.id, ...data };
} else {
const data = await json(this.httpClient.post(`/users/${this.id}/avatar`, image));
this.data = { id: data.id, ...data.userBrief };
}
} else {
if (this.id === this.httpClient.signInUserId) {
const data = await json(this.httpClient.delete("/user/avatar"));
this.data = { id: this.id, ...data };
} else {
const data = await json(this.httpClient.delete(`/users/${this.id}/avatar`));
this.data = { id: data.id, ...data.userBrief };
}
}
return this;
}
}