{"version":3,"file":"NotificationServicesPushController.cjs","sourceRoot":"","sources":["../../src/NotificationServicesPushController/NotificationServicesPushController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n  ControllerGetStateAction,\n  ControllerStateChangeEvent,\n  StateMetadata,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport type { AuthenticationController } from '@metamask/profile-sync-controller';\nimport log from 'loglevel';\n\nimport type { Types } from '../NotificationServicesController';\nimport type { NotificationServicesPushControllerMethodActions } from './NotificationServicesPushController-method-action-types';\nimport type { ENV } from './services/endpoints';\nimport {\n  activatePushNotifications,\n  deleteLinksAPI,\n  deactivatePushNotifications,\n  updateLinksAPI,\n} from './services/services';\nimport type { PushNotificationEnv } from './types';\nimport type { PushService } from './types/push-service-interface';\n\nconst controllerName = 'NotificationServicesPushController';\n\nexport type NotificationServicesPushControllerState = {\n  isPushEnabled: boolean;\n  fcmToken: string;\n  isUpdatingFCMToken: boolean;\n};\n\nconst MESSENGER_EXPOSED_METHODS = [\n  'subscribeToPushNotifications',\n  'enablePushNotifications',\n  'addPushNotificationLinks',\n  'disablePushNotifications',\n  'updateTriggerPushNotifications',\n  'deletePushNotificationLinks',\n] as const;\n\nexport type NotificationServicesPushControllerGetStateAction =\n  ControllerGetStateAction<\n    typeof controllerName,\n    NotificationServicesPushControllerState\n  >;\n\nexport type Actions =\n  | NotificationServicesPushControllerGetStateAction\n  | NotificationServicesPushControllerMethodActions;\n\ntype AllowedActions =\n  AuthenticationController.AuthenticationControllerGetBearerTokenAction;\n\nexport type NotificationServicesPushControllerStateChangeEvent =\n  ControllerStateChangeEvent<\n    typeof controllerName,\n    NotificationServicesPushControllerState\n  >;\n\nexport type NotificationServicesPushControllerOnNewNotificationEvent = {\n  type: `${typeof controllerName}:onNewNotifications`;\n  payload: [Types.INotification];\n};\n\nexport type NotificationServicesPushControllerPushNotificationClickedEvent = {\n  type: `${typeof controllerName}:pushNotificationClicked`;\n  payload: [Types.INotification];\n};\n\nexport type Events =\n  | NotificationServicesPushControllerStateChangeEvent\n  | NotificationServicesPushControllerOnNewNotificationEvent\n  | NotificationServicesPushControllerPushNotificationClickedEvent;\n\nexport type NotificationServicesPushControllerMessenger = Messenger<\n  typeof controllerName,\n  Actions | AllowedActions,\n  Events\n>;\n\nexport const defaultState: NotificationServicesPushControllerState = {\n  isPushEnabled: true,\n  fcmToken: '',\n  isUpdatingFCMToken: false,\n};\nconst metadata: StateMetadata<NotificationServicesPushControllerState> = {\n  isPushEnabled: {\n    includeInStateLogs: true,\n    persist: true,\n    includeInDebugSnapshot: true,\n    usedInUi: true,\n  },\n  fcmToken: {\n    includeInStateLogs: false,\n    persist: true,\n    includeInDebugSnapshot: true,\n    usedInUi: true,\n  },\n  isUpdatingFCMToken: {\n    includeInStateLogs: false,\n    persist: false,\n    includeInDebugSnapshot: true,\n    usedInUi: true,\n  },\n};\n\nconst defaultPushEnv: PushNotificationEnv = {\n  apiKey: '',\n  authDomain: '',\n  storageBucket: '',\n  projectId: '',\n  messagingSenderId: '',\n  appId: '',\n  measurementId: '',\n  vapidKey: '',\n};\n\nexport type ControllerConfig = {\n  /**\n   * User locale for server push notifications\n   */\n  getLocale?: () => string;\n\n  /**\n   * Global switch to determine to use push notifications\n   * Allows us to control Builds on extension (MV2 vs MV3)\n   */\n  isPushFeatureEnabled?: boolean;\n\n  /**\n   * determine the config used for push notification services\n   */\n  platform: 'extension' | 'mobile';\n\n  /**\n   * Push Service Interface\n   * - create reg token\n   * - delete reg token\n   * - subscribe to push notifications\n   */\n  pushService: PushService;\n\n  env?: ENV;\n};\n\ntype StateCommand =\n  | { type: 'enable'; fcmToken: string }\n  | { type: 'disable' }\n  | { type: 'update'; fcmToken: string };\n\n/**\n * Manages push notifications for the application, including enabling, disabling, and updating triggers for push notifications.\n * This controller integrates with Firebase Cloud Messaging (FCM) to handle the registration and management of push notifications.\n * It is responsible for registering and unregistering the service worker that listens for push notifications,\n * managing the FCM token, and communicating with the server to register or unregister the device for push notifications.\n * Additionally, it provides functionality to update the server with new UUIDs that should trigger push notifications.\n */\nexport class NotificationServicesPushController extends BaseController<\n  typeof controllerName,\n  NotificationServicesPushControllerState,\n  NotificationServicesPushControllerMessenger\n> {\n  #pushListenerUnsubscribe: (() => void) | undefined = undefined;\n\n  readonly #env: PushNotificationEnv;\n\n  readonly #config: ControllerConfig;\n\n  constructor({\n    messenger,\n    state,\n    env,\n    config,\n  }: {\n    messenger: NotificationServicesPushControllerMessenger;\n    state: NotificationServicesPushControllerState;\n    /** Push Environment is only required for extension */\n    env?: PushNotificationEnv;\n    config: ControllerConfig;\n  }) {\n    super({\n      messenger,\n      metadata,\n      name: controllerName,\n      state: { ...defaultState, ...state },\n    });\n\n    this.#env = env ?? defaultPushEnv;\n    this.#config = config;\n\n    this.messenger.registerMethodActionHandlers(\n      this,\n      MESSENGER_EXPOSED_METHODS,\n    );\n\n    this.#clearLoadingStates();\n  }\n\n  #clearLoadingStates(): void {\n    this.update((state) => {\n      state.isUpdatingFCMToken = false;\n    });\n  }\n\n  async #getAndAssertBearerToken(): Promise<string> {\n    const bearerToken = await this.messenger.call(\n      'AuthenticationController:getBearerToken',\n    );\n    if (!bearerToken) {\n      throw new Error('BearerToken token is missing');\n    }\n\n    return bearerToken;\n  }\n\n  #updatePushState(command: StateCommand): void {\n    if (command.type === 'enable') {\n      this.update((state) => {\n        state.isPushEnabled = true;\n        state.fcmToken = command.fcmToken;\n        state.isUpdatingFCMToken = false;\n      });\n    }\n\n    if (command.type === 'disable') {\n      this.update((state) => {\n        // Note we do not want to clear the old FCM token\n        // We can send it as an old token to our backend to cleanup next time turned on\n        state.isPushEnabled = false;\n        state.isUpdatingFCMToken = false;\n      });\n    }\n\n    if (command.type === 'update') {\n      this.update((state) => {\n        state.isPushEnabled = true;\n        state.fcmToken = command.fcmToken;\n        state.isUpdatingFCMToken = false;\n      });\n    }\n  }\n\n  public async subscribeToPushNotifications(): Promise<void> {\n    if (!this.#config.isPushFeatureEnabled) {\n      return;\n    }\n\n    if (this.#pushListenerUnsubscribe) {\n      this.#pushListenerUnsubscribe();\n      this.#pushListenerUnsubscribe = undefined;\n    }\n\n    try {\n      this.#pushListenerUnsubscribe =\n        (await this.#config.pushService.subscribeToPushNotifications(\n          this.#env,\n        )) ?? undefined;\n    } catch {\n      // Do nothing, we are silently failing if push notification registration fails\n    }\n  }\n\n  /**\n   * Enables push notifications for the application.\n   *\n   * This method sets up the necessary infrastructure for handling push notifications by:\n   * 1. Registering the service worker to listen for messages.\n   * 2. Fetching the Firebase Cloud Messaging (FCM) token from Firebase.\n   * 3. Sending the FCM token to the server responsible for sending notifications, to register the device.\n   *\n   * @param addresses - An array of addresses to enable push notifications for.\n   */\n  public async enablePushNotifications(addresses: string[]): Promise<void> {\n    if (!this.#config.isPushFeatureEnabled) {\n      return;\n    }\n\n    this.update((state) => {\n      state.isUpdatingFCMToken = true;\n    });\n\n    // Handle creating new reg token (if available)\n    try {\n      const bearerToken = await this.#getAndAssertBearerToken().catch(\n        () => null,\n      );\n\n      // If there is a bearer token, lets try to refresh/create new reg token\n      if (bearerToken) {\n        // Activate Push Notifications\n        const fcmToken = await activatePushNotifications({\n          bearerToken,\n          addresses,\n          env: this.#env,\n          createRegToken: this.#config.pushService.createRegToken,\n          regToken: {\n            platform: this.#config.platform,\n            locale: this.#config.getLocale?.() ?? 'en',\n            oldToken: this.state.fcmToken,\n          },\n          controllerEnv: this.#config.env ?? 'prd',\n        });\n\n        if (fcmToken) {\n          this.#updatePushState({ type: 'enable', fcmToken });\n        }\n      }\n    } catch {\n      // Do nothing, we are silently failing\n    }\n\n    // New token created, (re)subscribe to push notifications\n    try {\n      await this.subscribeToPushNotifications();\n    } catch {\n      // Do nothing we are silently failing\n    }\n\n    this.update((state) => {\n      state.isUpdatingFCMToken = false;\n    });\n  }\n\n  /**\n   * Disables push notifications for the application.\n   * This removes the registration token on this device, and ensures we unsubscribe from any listeners\n   */\n  public async disablePushNotifications(): Promise<void> {\n    if (!this.#config.isPushFeatureEnabled) {\n      return;\n    }\n\n    this.update((state) => {\n      state.isUpdatingFCMToken = true;\n    });\n\n    try {\n      // Send a request to the server to unregister the token/device\n      await deactivatePushNotifications({\n        env: this.#env,\n        deleteRegToken: this.#config.pushService.deleteRegToken,\n        regToken: this.state.fcmToken,\n      });\n    } catch (error) {\n      const errorMessage = `Failed to disable push notifications: ${\n        error as string\n      }`;\n      log.error(errorMessage);\n      throw new Error(errorMessage);\n    } finally {\n      this.update((state) => {\n        state.isUpdatingFCMToken = false;\n      });\n    }\n\n    // Unsubscribe from push notifications\n    this.#pushListenerUnsubscribe?.();\n\n    // Update State\n    this.#updatePushState({ type: 'disable' });\n  }\n\n  /**\n   * Adds backend push notification links for the given addresses using the current FCM token.\n   * This is used when accounts are added after push notifications have already been enabled,\n   * so backend can link the existing device token to the newly added addresses.\n   *\n   * @param addresses - Addresses that should be linked to push notifications.\n   * @returns Whether the add request succeeded.\n   */\n  public async addPushNotificationLinks(addresses: string[]): Promise<boolean> {\n    if (\n      !this.#config.isPushFeatureEnabled ||\n      addresses.length === 0 ||\n      !this.state.fcmToken\n    ) {\n      return false;\n    }\n\n    try {\n      const bearerToken = await this.#getAndAssertBearerToken();\n      return await updateLinksAPI({\n        bearerToken,\n        addresses,\n        regToken: {\n          token: this.state.fcmToken,\n          platform: this.#config.platform,\n          locale: this.#config.getLocale?.() ?? 'en',\n        },\n        env: this.#config.env ?? 'prd',\n      });\n    } catch {\n      return false;\n    }\n  }\n\n  /**\n   * Deletes backend push notification links for the given addresses on the current platform.\n   * This is used when accounts are removed (for example SRP removal), so backend can remove\n   * all associated FCM tokens for those address/platform pairs.\n   *\n   * @param addresses - Addresses that should be unlinked from push notifications.\n   * @returns Whether the delete request succeeded.\n   */\n  public async deletePushNotificationLinks(\n    addresses: string[],\n  ): Promise<boolean> {\n    if (\n      !this.#config.isPushFeatureEnabled ||\n      addresses.length === 0 ||\n      !this.state.fcmToken\n    ) {\n      return false;\n    }\n\n    try {\n      const bearerToken = await this.#getAndAssertBearerToken();\n      return await deleteLinksAPI({\n        bearerToken,\n        addresses,\n        platform: this.#config.platform,\n        token: this.state.fcmToken,\n        env: this.#config.env ?? 'prd',\n      });\n    } catch {\n      return false;\n    }\n  }\n\n  /**\n   * Updates the triggers for push notifications.\n   * This method is responsible for updating the server with the new set of addresses that should trigger push notifications.\n   * It uses the current FCM token and a BearerToken for authentication.\n   *\n   * @param addresses - An array of addresses that should trigger push notifications.\n   * @deprecated - this is not used anymore and will most likely be removed\n   */\n  public async updateTriggerPushNotifications(\n    addresses: string[],\n  ): Promise<void> {\n    if (!this.#config.isPushFeatureEnabled) {\n      return;\n    }\n\n    this.update((state) => {\n      state.isUpdatingFCMToken = true;\n    });\n\n    try {\n      const bearerToken = await this.#getAndAssertBearerToken();\n      const fcmToken = await activatePushNotifications({\n        bearerToken,\n        addresses,\n        env: this.#env,\n        createRegToken: this.#config.pushService.createRegToken,\n        regToken: {\n          platform: this.#config.platform,\n          locale: this.#config.getLocale?.() ?? 'en',\n          oldToken: this.state.fcmToken,\n        },\n        controllerEnv: this.#config.env ?? 'prd',\n      });\n\n      // update the state with the new FCM token\n      if (fcmToken) {\n        this.#updatePushState({ type: 'update', fcmToken });\n      }\n    } catch (error) {\n      const errorMessage = `Failed to update triggers for push notifications: ${\n        error as string\n      }`;\n      log.error(errorMessage);\n      throw new Error(errorMessage);\n    } finally {\n      this.update((state) => {\n        state.isUpdatingFCMToken = false;\n      });\n    }\n  }\n}\n"]}