Source

services/Profile.class.js

import ScenidCloudService from './ScenidCloudService.class.js'

const { get: httpGet, delete: httpDelete } = ScenidCloudService.prototype

/**
 * User-scoped client for profile operations on the Scenid Auth Service.
 *
 * Obtained via `sdk.asUser(idToken).Profile()`. All methods require a valid
 * user token — they cannot be called with an admin (service) token.
 *
 * @extends ScenidCloudService
 *
 * @example
 * const profile = sdk.asUser(idToken).Profile()
 *
 * const { result } = await profile.get()
 * console.log(result.displayName, result.emailHint)
 */
class Profile extends ScenidCloudService {
  /**
   * @param {string|function(): Promise.<string>} tokenSource
   * @param {string} serviceUrl
   */
  constructor (tokenSource, serviceUrl) {
    super(tokenSource, serviceUrl)

    /**
     * Returns the current user's profile.
     *
     * Response shape: `{ tenantId, uid, displayName, photoURL, emailHint }`.
     * The `emailHint` field masks the local part of the email address
     * (e.g. `*****@example.com`) to avoid exposing it to client-side code.
     *
     * @function
     * @returns {Promise<ServiceResponse>}
     *
     * @example
     * const { result } = await profile.get()
     * // { tenantId: 't-1', uid: 'u-1', displayName: 'Ada', emailHint: '*****@example.com', photoURL: null }
     */
    this.get = () => httpGet.call(this, '/api/v1/profile')

    /**
     * Updates the current user's display name.
     *
     * @function
     * @param {string} displayName - New display name.
     * @returns {Promise<ServiceResponse>} Resolves with `{ result: 'ok' }` on success.
     *
     * @example
     * await profile.update('Ada Lovelace')
     */
    this.update = displayName => this.put('/api/v1/updateProfile', { displayName })

    /**
     * Updates the current user's avatar photo URL.
     *
     * @function
     * @param {string} photoURL - Publicly accessible URL of the new avatar image.
     * @returns {Promise<ServiceResponse>} Resolves with `{ result: 'ok' }` on success.
     *
     * @example
     * await profile.setAvatar('https://cdn.example.com/avatars/ada.jpg')
     */
    this.setAvatar = photoURL => this.post('/api/v1/avatar', { photoURL })

    /**
     * Sends a password-reset email to the current user's registered address.
     *
     * No body is required — the server derives the email from the authenticated token.
     *
     * @function
     * @returns {Promise<ServiceResponse>} Resolves with `{ result: 'ok' }` on success.
     *
     * @example
     * await profile.requestPasswordReset()
     */
    this.requestPasswordReset = () => this.post('/api/v1/requestPasswordReset')

    /**
     * Permanently deletes the current user's account.
     *
     * The user must confirm their current password. The account is anonymised
     * rather than hard-deleted: the email and display name are replaced with
     * placeholder values and the registration status is set to `deactivated`.
     *
     * @function
     * @param {string} password - The user's current password for confirmation.
     * @returns {Promise<ServiceResponse>} Resolves with `{ result: 'ok' }` on success.
     * @throws {Error} `auth/wrong-password` – provided password did not match.
     *
     * @example
     * await profile.delete(confirmedPassword)
     */
    this.delete = password => httpDelete.call(this, '/api/v1/profile', { password })
  }
}

export default Profile