import type { AddressMap, ApiClient, CubeSignerResponse, EditPolicy, Empty, JsonValue, MfaReceipts, UpdateContactRequest, } from "./index.ts"; import { CubeSignerClient } from "./index.ts"; import type { ContactInfo, ContactLabel } from "./schema_types.ts"; /** * A representation of a contact within an org. */ export class Contact { /** The CubeSigner instance that this contact is associated with */ readonly #apiClient: ApiClient; /** The id of the contact: "Contact#" followed by a unique identifier. */ readonly id: string; /** * Get the cached properties of this contact. The cached properties reflect * the state of the contact as of the last fetch or update (e.g. this field * will be updated after awaiting `Contact.updateName()`). */ cached: ContactInfo; /** @returns The id of the org this contact is in. */ get orgId(): string { return this.#apiClient.sessionMeta.org_id; } /** * Fetches and returns the latest name associated with the contact. * * @returns The latest name */ async name(): Promise { const data = await this.fetch(); return data.name; } /** * Sets a new name for the contact. * * @param name The new name for the contact */ async setName(name: string) { await this.update({ name }); } /** * Fetches and returns the latest addresses associated with the contact. * * @returns The latest addresses */ async addresses(): Promise { const data = await this.fetch(); return data.addresses as AddressMap; } /** * Sets a new set of addresses for the contact (overwriting the existing addresses). * * @param addresses The new addresses to associate with the contact */ async setAddresses(addresses: AddressMap) { await this.update({ addresses }); } /** * Fetches and returns the latest owner of the contact. * * @returns The user id of the contact's owner * @example User#c3b9379c-4e8c-4216-bd0a-65ace53cf98f */ async owner(): Promise { const data = await this.fetch(); return data.owner; } /** * Sets a new owner for the contact. A contact owner cannot be an alien. * * @param owner The new owner of the contact */ async setOwner(owner: string) { await this.update({ owner }); } /** * @returns The latest labels associated with the contact, if any */ async labels(): Promise { const data = await this.fetch(); return data.labels; } /** * @param labels The new labels that the contact should hold */ async setLabels(labels: ContactLabel[]) { await this.update({ labels }); } /** * Fetches and returns the latest metadata value for the contact. This will be null if there is no metadata defined. * * @returns The latest metadata */ async metadata(): Promise { const data = await this.fetch(); return data.metadata as JsonValue; } /** * Sets a new metadata value for the contact (overwriting the existing value). * * @param metadata The new metadata for the contact */ async setMetadata(metadata: JsonValue) { await this.update({ metadata }); } /** * Fetches and returns the latest edit policy for the contact. * * @returns The edit policy for the contact, or undefined if there is no edit policy */ async editPolicy(): Promise { const data = await this.fetch(); return data.edit_policy; } /** * Sets a new edit policy for the contact (overwriting any existing policy). * To reset the edit policy, set it to {}. * * @param editPolicy The new edit policy for the contact */ async setEditPolicy(editPolicy: EditPolicy) { await this.update({ edit_policy: editPolicy }); } /** * Delete this contact. * * @param mfaReceipt Optional MFA receipt(s) * @returns A response which can be used to approve MFA if needed */ async delete(mfaReceipt?: MfaReceipts): Promise> { return await this.#apiClient.contactDelete(this.id, mfaReceipt); } // -------------------------------------------------------------------------- // -- INTERNAL -------------------------------------------------------------- // -------------------------------------------------------------------------- /** * Create a Contact from ContactInfo. * * @param client The CubeSigner instance this contact is associated with. * @param data The ContactInfo of the contact. */ constructor(client: ApiClient | CubeSignerClient, data: ContactInfo) { this.#apiClient = client instanceof CubeSignerClient ? client.apiClient : client; this.id = data.id; this.cached = data; } /** * Fetches the latest contact information and updates `this.cached`. * * @returns The contact information * @internal */ private async fetch(): Promise { this.cached = await this.#apiClient.contactGet(this.id); return this.cached; } /** * Updates the contact and updates `this.cached` to the latest contact state. * * @param request The parameters to update * @param mfaReceipt Optional MFA receipt(s) * @returns The new contact after the update * @internal */ private async update( request: UpdateContactRequest, mfaReceipt?: MfaReceipts, ): Promise { const resp = await this.#apiClient.contactUpdate(this.id, request, mfaReceipt); if (resp.requiresMfa()) { throw resp; } this.cached = resp.data(); return this.cached; } }