/////////////////////////////////////////////////////////////////////////////// // 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; } }