| /* |
| * Copyright (C) 2022 Savoir-faire Linux Inc. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU Affero General Public License as |
| * published by the Free Software Foundation; either version 3 of the |
| * License, or (at your option) any later version. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU Affero General Public License for more details. |
| * |
| * You should have received a copy of the GNU Affero General Public |
| * License along with this program. If not, see |
| * <https://www.gnu.org/licenses/>. |
| */ |
| import { AccountDetails, VolatileDetails } from './AccountDetails.js'; |
| import { Contact } from './Contact.js'; |
| import { Conversation } from './Conversation.js'; |
| import { Lookup, PromiseExecutor } from './util.js'; |
| |
| type Devices = Record<string, string>; |
| |
| export type RegistrationState = |
| | 'UNREGISTERED' |
| | 'TRYING' |
| | 'REGISTERED' |
| | 'ERROR_GENERIC' |
| | 'ERROR_AUTH' |
| | 'ERROR_NETWORK' |
| | 'ERROR_HOST' |
| | 'ERROR_SERVICE_UNAVAILABLE' |
| | 'ERROR_NEED_MIGRATION' |
| | 'INITIALIZING'; |
| |
| interface AccountRegisteringName extends PromiseExecutor<number> { |
| name: string; |
| } |
| |
| export class Account { |
| private readonly id: string; |
| private _details: AccountDetails; |
| private _volatileDetails: VolatileDetails; |
| private readonly contactCache: Record<string, Contact>; |
| private _contacts: Contact[]; |
| private readonly conversations: Record<string, Conversation>; |
| private defaultModerators: Contact[]; |
| private _lookups: Lookup[]; |
| private devices: Devices; |
| private _registrationState: RegistrationState | undefined; |
| private _registeringName: AccountRegisteringName | undefined; |
| |
| static TYPE_JAMI: string; |
| static TYPE_SIP: string; |
| static BOOL_TRUE: string; |
| static BOOL_FALSE: string; |
| |
| constructor(id: string, details: AccountDetails, volatileDetails: VolatileDetails) { |
| this.id = id; |
| this._details = details || {}; |
| this._volatileDetails = volatileDetails || {}; |
| this.contactCache = {}; |
| this._contacts = []; |
| this.conversations = {}; |
| this.defaultModerators = []; |
| this._lookups = []; |
| this.devices = {}; |
| this.registrationState = undefined; |
| this._registeringName = undefined; |
| } |
| |
| static from(object: any) { |
| const account = new Account(object.id, object.details, object.volatileDetails); |
| if (object.defaultModerators) account.defaultModerators = object.defaultModerators.map((m: any) => Contact.from(m)); |
| return account; |
| } |
| |
| update(data: Account) { |
| this._details = data._details; |
| this._volatileDetails = data._volatileDetails; |
| } |
| |
| async getObject() { |
| const hasModerators = this.defaultModerators && this.defaultModerators.length; |
| return { |
| id: this.id, |
| details: this._details, |
| defaultModerators: hasModerators |
| ? await Promise.all(this.defaultModerators.map(async (c) => await c.getObject())) |
| : undefined, |
| volatileDetails: this._volatileDetails, |
| }; |
| } |
| |
| getId() { |
| return this.id; |
| } |
| |
| getType() { |
| return this._details['Account.type']; |
| } |
| |
| getUri() { |
| return this._details['Account.username']; |
| } |
| |
| getRegisteredName() { |
| return this._volatileDetails['Account.registeredName']; |
| } |
| |
| isRendezVous() { |
| return this._details['Account.rendezVous'] === Account.BOOL_TRUE; |
| } |
| |
| isPublicIn() { |
| return this._details['DHT.PublicInCalls'] === Account.BOOL_TRUE; |
| } |
| |
| setDetail(detail: keyof AccountDetails, value: string) { |
| this._details[detail] = value; |
| } |
| |
| updateDetails(details: Partial<AccountDetails>) { |
| return Object.assign(this._details, details); |
| } |
| |
| getDetails() { |
| return this._details; |
| } |
| |
| getSummary() { |
| return this.getObject(); |
| } |
| |
| getDisplayName() { |
| return this._details['Account.displayName'] || this.getDisplayUri(); |
| } |
| |
| getDisplayUri() { |
| return this.getRegisteredName() || this.getUri(); |
| } |
| |
| getDisplayNameNoFallback() { |
| return this._details['Account.displayName'] || this.getRegisteredName(); |
| } |
| |
| getConversationIds() { |
| return Object.keys(this.conversations); |
| } |
| |
| getConversations() { |
| return this.conversations; |
| } |
| |
| getConversation(conversationId: string) { |
| return this.conversations[conversationId]; |
| } |
| |
| addConversation(conversation: Conversation) { |
| const conversationId = conversation.getId(); |
| if (conversationId != null) { |
| this.conversations[conversationId] = conversation; |
| } else { |
| throw new Error('Conversation ID cannot be undefined'); |
| } |
| } |
| |
| removeConversation(conversationId: string) { |
| delete this.conversations[conversationId]; |
| } |
| |
| getContactFromCache(uri: string) { |
| let contact = this.contactCache[uri]; |
| if (!contact) { |
| contact = new Contact(uri); |
| this.contactCache[uri] = contact; |
| } |
| return contact; |
| } |
| |
| getContacts() { |
| return this._contacts; |
| } |
| |
| set contacts(contacts: Contact[]) { |
| this._contacts = contacts; |
| } |
| |
| getDefaultModerators() { |
| return this.defaultModerators; |
| } |
| |
| set details(value: AccountDetails) { |
| this._details = value; |
| } |
| |
| set volatileDetails(value: VolatileDetails) { |
| this._volatileDetails = value; |
| } |
| |
| get lookups(): Lookup[] { |
| return this._lookups; |
| } |
| |
| set lookups(lookups: Lookup[]) { |
| this._lookups = lookups; |
| } |
| |
| setDevices(devices: Devices) { |
| this.devices = { ...devices }; |
| } |
| |
| getDevices() { |
| return this.devices; |
| } |
| |
| get registrationState(): RegistrationState | undefined { |
| return this._registrationState; |
| } |
| |
| set registrationState(registrationState: RegistrationState | undefined) { |
| this._registrationState = registrationState; |
| } |
| |
| get registeringName(): AccountRegisteringName | undefined { |
| return this._registeringName; |
| } |
| |
| set registeringName(registeringName: AccountRegisteringName | undefined) { |
| this._registeringName = registeringName; |
| } |
| } |
| |
| Account.TYPE_JAMI = 'RING'; |
| Account.TYPE_SIP = 'SIP'; |
| |
| Account.BOOL_TRUE = 'true'; |
| Account.BOOL_FALSE = 'false'; |