OverviewFilesCommitsIssuesDocsReleasesPeers

keet-deobfuscated / @holepunchto / keet-store / store / identity / identity.reducer.js

475 lines · javascript ref:
import { createAction as e, createSelector as t, createSlice as i } from "@reduxjs/toolkit"
import { isFeatureSupported as r, FEATURES as n } from "@holepunchto/keet-core/features"
import {
  IDENTITY_MEMBER_STATUS as c,
  IDENTITY_STATUS as a,
  IDENTITY_USERNAME_STATUS as s,
  IDENTITY_USERNAME_SAVE_STATUS as o,
  QUERY_IDENTITY_SOURCE as d,
  MAX_REMAINING_EDITS as y,
  AVATAR_BASE_EMPTY_URL as I,
} from "./identity.constants"
import { normalizeIdentity as u, phraseToWords as m } from "./identity.model"
import {
  IDENTITY_MEMBER_INITIAL_STATE as p,
  IDENTITY_MEMBER_STATE_KEY as v,
} from "./member/identity-member.constant"
import { identityMemberSlice as g } from "./member"
import { getPreferencesRecoveryPhraseMigrationDeclined as S } from "../preferences"
export const IDENTITY_STATE_KEY = "identity"
export const BACKUP_CREATE_INITIAL_STATE = {
  agreement: !1,
  loading: !1,
  errorMsg: "",
  success: !1,
  secretWords: [],
  checkWords: [],
  quickSetup: !1,
}
export const MIGRATE_RECOVERY_PHRASE_INITIAL_STATE = {
  error: !1,
  loading: !1,
  manyRetries: !1,
  success: !1,
}
export const SYNC_DEVICE_INITIAL_STATE = {
  agreement: !1,
  errorMsg: "",
  waitingIdentity: !1,
  success: !1,
  seedId: "",
}
const l = { isSearching: !1, list: [] }
export const MY_IDENTITY_INITIAL_STATE = {
  status: a.UNKNOWN,
  avatar: null,
  avatarUrl: "",
  avatarUrlMedium: "",
  displayName: "",
  color: "",
  username: "",
  confirmed: !1,
  local: {},
  memberId: "",
  profileId: "",
  searchResults: { [d.GLOBAL]: l, [d.START_NEW_CHAT]: l },
  selectedProfile: { contactInfo: null },
  usernameStatus: s.UNKNOWN,
  createUsernameStatus: o.UNKNOWN,
  deviceLoading: !1,
  deviceLoadError: "",
  invitationLink: "",
  invitedDevices: [],
  devices: [],
  secretPhrase: "",
  hasDiscoveryKey: void 0,
  hasSecretPhraseStored: !1,
  agreement: !1,
  contactInvitation: "",
  actionType: void 0,
  usernameError: void 0,
  usernameEditCounts: null,
  loggedOut: !1,
  settings: { disableReadReceipts: !1 },
  privateProfileVersion: null,
}
export const DEVICE_REMOVAL_INITIAL_STATE = { isLoading: !1, isError: !1, isSuccess: !1 }
export const INITIAL_STATE = {
  accountRecover: { agreement: !1, loading: !1, errorMsg: "", success: !1 },
  migrateRecoveryPhrase: MIGRATE_RECOVERY_PHRASE_INITIAL_STATE,
  backupCreate: BACKUP_CREATE_INITIAL_STATE,
  syncDevice: SYNC_DEVICE_INITIAL_STATE,
  myIdentity: MY_IDENTITY_INITIAL_STATE,
  [v]: p,
  peerIdentity: { byId: {} },
  privateProfileStats: {},
  termsOfService: !1,
  removeDeviceStatus: DEVICE_REMOVAL_INITIAL_STATE,
}
export const identitySlice = i({
  name: "identity",
  initialState: INITIAL_STATE,
  reducers: {
    setAccountRecoveryAgreement: (e, { payload: t }) => {
      e.accountRecover.agreement = t
    },
    setAccountRecoverySuccess: (e) => {
      ;((e.accountRecover.success = !0), (e.accountRecover.loading = !1))
    },
    setAccountRecoveryError: (e, { payload: t }) => {
      ;((e.accountRecover.errorMsg = t.message), (e.accountRecover.loading = !1))
    },
    submitAccountRecovery: (e, t) => {
      ;((e.accountRecover.loading = !0), (e.accountRecover.errorMsg = ""))
    },
    resetAccountRecovery: (e) => {
      e.accountRecover = { ...e.accountRecover, loading: !1, errorMsg: "", success: !1 }
    },
    setBackupCreateAgreement: (e, { payload: t }) => {
      e.backupCreate.agreement = t
    },
    setBackupCreateErrorMsg: (e) => {
      e.backupCreate.errorMsg = ""
    },
    setBackupCreateSecretPhrase: (e, { payload: t }) => {
      e.backupCreate.secretWords = m(t)
    },
    setBackupCreateCheckWords: (e, { payload: t }) => {
      e.backupCreate.checkWords = t
    },
    submitBackupCreate: (e) => {
      ;((e.backupCreate.errorMsg = ""), (e.backupCreate.loading = !0))
    },
    createAndSubmitBackup: (e, { payload: t }) => {
      ;((e.backupCreate.errorMsg = ""),
        (e.backupCreate.quickSetup = !t),
        (e.backupCreate.agreement = !0),
        (e.backupCreate.loading = !0),
        (e.backupCreate.secretWords = []))
    },
    submitBackupSuccess: (e) => {
      ;((e.backupCreate.loading = !1), (e.backupCreate.success = !0))
    },
    resetBackupCreate: (e) => {
      e.backupCreate = { ...BACKUP_CREATE_INITIAL_STATE, agreement: e.backupCreate.agreement }
    },
    setMigrateRecoveryPhrase: (e, t) => {
      e.migrateRecoveryPhrase = { ...e.migrateRecoveryPhrase, ...t.payload }
    },
    updateIdentityDeviceRequest: (e, t) => {
      ;((e.myIdentity.deviceLoading = !0), (e.myIdentity.deviceLoadError = ""))
    },
    updateIdentityDeviceSuccess: (e, { payload: t }) => {
      const { deviceId: i, name: r } = t
      ;((e.myIdentity.deviceLoading = !1),
        (e.myIdentity.devices = e.myIdentity.devices.map((e) =>
          e.deviceId === i ? { ...e, name: r } : e,
        )))
    },
    updateIdentityDeviceFailure: (e, { payload: t }) => {
      ;((e.myIdentity.deviceLoading = !1), (e.myIdentity.deviceLoadError = t.message))
    },
    setSyncDeviceAgreement: (e, { payload: t }) => {
      e.syncDevice.agreement = t
    },
    setSyncDeviceErrorMsg: (e, { payload: t }) => {
      e.syncDevice.errorMsg = t
    },
    setSyncDeviceSeedId: (e, { payload: t }) => {
      ;((e.syncDevice.seedId = t),
        (e.syncDevice.agreement = !0),
        (e.syncDevice.waitingIdentity = !0))
    },
    initSyncDevice: (e) => {
      e.syncDevice.seedId ||
        (e.syncDevice = {
          ...e.syncDevice,
          errorMsg: "",
          success: !1,
          waitingIdentity: !1,
          seedId: "",
        })
    },
    cancelSyncDeviceSuccess: (e) => {
      e.syncDevice = {
        agreement: e.syncDevice.agreement,
        errorMsg: "",
        waitingIdentity: !1,
        success: !1,
        seedId: "",
      }
    },
    setIdentityAsked: (e) => {
      e.myIdentity.status === a.UNKNOWN && (e.myIdentity.status = a.ASKED)
    },
    setIdentity: (e, t) => {
      const { payload: i } = t,
        r = u(i),
        n = r.memberId !== e.myIdentity.memberId,
        c = r.devices.filter(({ confirmed: e, deviceId: t }) => e && t)
      ;((e.myIdentity = { ...e.myIdentity, ...r, devices: c }),
        n &&
          e.syncDevice.waitingIdentity &&
          (e.syncDevice = {
            ...SYNC_DEVICE_INITIAL_STATE,
            agreement: e.syncDevice.agreement,
            success: !0,
          }),
        0 !== e.myIdentity.invitedDevices.length &&
          c.forEach((t) => {
            if (!("deviceId" in t)) return
            const { deviceId: i } = t,
              r = e.myIdentity.invitedDevices.findIndex((e) => e.deviceId === i)
            ;-1 !== r && e.myIdentity.invitedDevices.splice(r, 1)
          }))
    },
    setIdentityAgreement: (e, { payload: t }) => {
      e.myIdentity.agreement = t
    },
    setIdentityInvitationLink: (e, { payload: t }) => {
      e.myIdentity.invitationLink = t
    },
    setIdentitySecretPhrase: (e, { payload: t }) => {
      e.myIdentity.secretPhrase = t || MY_IDENTITY_INITIAL_STATE.secretPhrase
    },
    setIdentityHasSecretPhraseStored: (e, { payload: t }) => {
      e.myIdentity.hasSecretPhraseStored = t
    },
    setIdentityContactInvitation: (e, { payload: t }) => {
      e.myIdentity.contactInvitation = t
    },
    setIdentityUsernameActionType: (e, { payload: t }) => {
      e.myIdentity.actionType = t
    },
    setPrivateProfileStats: (e, { payload: t }) => {
      e.privateProfileStats = t
    },
    cancelIdentityInvitationLink: (e) => {
      e.myIdentity.invitationLink = ""
    },
    addIdentityInvitedDevice: (e, { payload: t }) => {
      t?.deviceId &&
        ((e.myIdentity.invitedDevices = e.myIdentity.invitedDevices.filter(
          (e) => e.deviceId !== t.deviceId,
        )),
        e.myIdentity.invitedDevices.push(t),
        (e.myIdentity.invitationLink = ""))
    },
    removeIdentityInvitedDevice: (e, { payload: t }) => {
      e.myIdentity.invitedDevices = e.myIdentity.invitedDevices.filter((e) => e.deviceId !== t)
    },
    setTermsOfService: (e, { payload: t }) => {
      e.termsOfService = t
    },
    queryIdentityRecords: (e, { payload: t }) => {
      const i = t.opts?.source || d.GLOBAL
      ;((e.myIdentity.searchResults[i].isSearching = !0), (e.myIdentity.searchResults[i].list = []))
    },
    updateIdentitySearchList: (e, { payload: t }) => {
      const { list: i, source: r = d.GLOBAL } = t
      ;((e.myIdentity.searchResults[r].isSearching = !1), (e.myIdentity.searchResults[r].list = i))
    },
    updateIdentitySelectedProfile: (e, { payload: t }) => {
      e.myIdentity.selectedProfile = { contactInfo: t }
    },
    updateIdentityVerifyStatus: (e, { payload: t }) => {
      e.myIdentity.usernameStatus = t
    },
    resetIdentityVerifyStatus: (e) => {
      e.myIdentity.usernameStatus = s.UNKNOWN
    },
    updateUsernameReservationInfo: (e, t) => {
      const { error: i, username: r, status: n, count: c } = t.payload || {}
      ;(n === o.RESERVED && (e.myIdentity.actionType = void 0),
        (e.myIdentity.createUsernameStatus = n ?? e.myIdentity.createUsernameStatus),
        (e.myIdentity.username = r ?? e.myIdentity.username),
        (e.myIdentity.usernameError = i ?? e.myIdentity.usernameError),
        (e.myIdentity.usernameEditCounts = c ?? e.myIdentity.usernameEditCounts))
    },
    resetUsernameReservationInfo: (e) => {
      ;((e.myIdentity.usernameError = void 0), (e.myIdentity.createUsernameStatus = o.NOT_STARTED))
    },
    updatePeerIdentity: (e, { payload: t }) => {
      const { memberId: i, identityRecord: r } = t
      e.peerIdentity.byId[i] = { status: c.LOADED, ...r }
    },
    updateRemoveDeviceStatus: (e, { payload: t }) => {
      e.removeDeviceStatus = { ...e.removeDeviceStatus, ...t }
    },
    setPrivateProfileVersion: (e, { payload: t }) => {
      e.myIdentity.privateProfileVersion = t
    },
  },
  extraReducers: (e) => {
    e.addDefaultCase((e, t) => {
      e[v] = g.reducer(e[v], t)
    })
  },
})
export const getIdentityState = (e) => e.identity
export const getAccountRecoveryAgreement = (e) => getIdentityState(e).accountRecover.agreement
export const getAccountRecoveryLoading = (e) => getIdentityState(e).accountRecover.loading
export const getAccountRecoveryErrorMsg = (e) => getIdentityState(e).accountRecover.errorMsg
export const getAccountRecoverySuccess = (e) => getIdentityState(e).accountRecover.success
export const getBackupCreateAgreement = (e) => getIdentityState(e).backupCreate.agreement
export const getBackupCreateLoading = (e) => getIdentityState(e).backupCreate.loading
export const getBackupCreateQuickSetup = (e) => getIdentityState(e).backupCreate.quickSetup
export const getBackupCreateErrorMsg = (e) => getIdentityState(e).backupCreate.errorMsg
export const getBackupCreateSuccess = (e) => getIdentityState(e).backupCreate.success
export const getBackupCreateSecretWords = (e) => getIdentityState(e).backupCreate.secretWords
export const getBackupCreateCheckWords = (e) => getIdentityState(e).backupCreate.checkWords
export const getSyncDeviceAgreement = (e) => getIdentityState(e).syncDevice.agreement
export const getSyncDeviceErrorMsg = (e) => getIdentityState(e).syncDevice.errorMsg
export const getSyncDeviceWaitingIdentity = (e) => getIdentityState(e).syncDevice.waitingIdentity
export const getSyncDeviceSuccess = (e) => getIdentityState(e).syncDevice.success
export const getSyncDeviceSeedId = (e) => getIdentityState(e).syncDevice.seedId
export const getMyIdentity = (e) => getIdentityState(e).myIdentity
export const getIdentityDevices = (e) => getIdentityState(e).myIdentity.devices
export const getIdentityDeviceCurrent = t([getIdentityDevices], (e) => e.find((e) => !!e.current))
export const getIdentityStatus = (e) => getIdentityState(e).myIdentity.status
export const getIdentityMigrateRecoveryPhrase = (e) => getIdentityState(e).migrateRecoveryPhrase
export const getIdentityShouldMigrateRecoveryPhrase = (e) =>
  !1 === getIdentityState(e).myIdentity.hasDiscoveryKey
export const getMigrateRecoveryPhraseBannerVisible = (e) =>
  getIdentityShouldMigrateRecoveryPhrase(e) && !S(e)
export const getIdentityProfile = t(
  (e) => getIdentityState(e).myIdentity,
  ({
    avatar: e,
    avatarUrl: t,
    avatarUrlMedium: i,
    displayName: r,
    username: n,
    memberId: c,
    color: a,
  }) => ({
    avatar: e,
    avatarUrl: t,
    avatarUrlMedium: i,
    displayName: r,
    username: n,
    memberId: c,
    color: a,
  }),
)
export const getMyMemberId = (e) => getIdentityState(e).myIdentity.memberId
export const getMyContactInvitation = (e) => getIdentityState(e).myIdentity.contactInvitation
export const getIsIdentityComplete = (e) => getIdentityStatus(e) === a.COMPLETE
export const getIsIdentityNameSet = (e) => {
  const { displayName: t } = getIdentityState(e).myIdentity
  return !!t && !/^\s/.test(t)
}
export const getHasIdentityUsername = (e) => !!getIdentityState(e).myIdentity.username
export const getIsIdentityConfirmed = (e) => getIdentityState(e).myIdentity.confirmed
export const getIsIdentityLoggedOut = (e) => getIdentityState(e).myIdentity.loggedOut
export const getIdentityInvitationLink = (e) => getIdentityState(e).myIdentity.invitationLink
export const getIdentityInvitedDevices = (e) => getIdentityState(e).myIdentity.invitedDevices
export const getIdentitySecretPhrase = (e) => getIdentityState(e).myIdentity.secretPhrase
export const getIdentityAgreement = (e) => getIdentityState(e).myIdentity.agreement
export const getIdentityHasSecretPhraseStored = (e) =>
  getIdentityState(e).myIdentity.hasSecretPhraseStored
export const getPrivateProfileStats = (e) => getIdentityState(e).privateProfileStats
export const getIdentityProfileName = (e) => getIdentityProfile(e).displayName
export const getIdentityProfileAvatarUrl = (e) => {
  const { avatarUrl: t } = getIdentityProfile(e)
  return t === I ? "" : t
}
export const getIdentityProfileAvatarUrlMedium = (e) => getIdentityProfile(e).avatarUrlMedium
export const getIdentityProfileColor = (e) => getIdentityProfile(e).color
export const getTermsOfService = (e) => getIdentityState(e).termsOfService
export const getIdentityDeviceLoading = (e) => getIdentityState(e).myIdentity.deviceLoading
export const getIdentityDeviceLoadError = (e) => getIdentityState(e).myIdentity.deviceLoadError
export const getIdentitySearchResult =
  (e = d.GLOBAL) =>
  (t) =>
    getIdentityState(t).myIdentity.searchResults[e] || l
export const getIdentitySelectedProfile = (e) => getIdentityState(e).myIdentity.selectedProfile
export const getIdentitySearchResultList = (e) => (t) => getIdentitySearchResult(e)(t).list
export const getIdentitySearchResultIsSearching = (e) => (t) =>
  getIdentitySearchResult(e)(t).isSearching
export const getIdentityUsernameStatus = (e) => getIdentityState(e).myIdentity.usernameStatus
export const getCreateUsernameStatus = (e) => getIdentityState(e).myIdentity.createUsernameStatus
export const getPeerIdentityById = (e) => getIdentityState(e).peerIdentity.byId
export const getPeerIdentityByMemberId = (e) => (t) => getPeerIdentityById(t)[e]
export const getPeerIdentityUsernameByMemberId = (e) => (t) => getPeerIdentityById(t)[e]?.username
export const getIdentityUsernameActionType = (e) => getIdentityState(e).myIdentity.actionType
export const getRemainingEdits = (e) => {
  const t = getIdentityState(e).myIdentity.usernameEditCounts
  return t ? y - t : null
}
export const getCanEditUsername = t(
  [(e) => getIdentityState(e).myIdentity, (e) => getRemainingEdits(e)],
  ({ createUsernameStatus: e, username: t }, i) =>
    t && e !== o.RESERVING && e !== o.EDITING_LIMIT_EXCEEDED && null != i && i > 0,
)
export const getRemoveDeviceStatus = (e) => getIdentityState(e).removeDeviceStatus
export const getUsernameError = (e) => getIdentityState(e).myIdentity.usernameError
export const getIsReadReceiptsDisabled = (e) =>
  getIdentityState(e).myIdentity.settings.disableReadReceipts
export const getPrivateProfileVersion = (e) => getIdentityState(e).myIdentity.privateProfileVersion
export const getIsReadReceiptsSupported = (e) => {
  const t = getPrivateProfileVersion(e)
  return r(t, n.PRIVATE_PROFILE_SETTINGS)
}
export const getIsFavoriteRoomSupported = (e) => {
  const t = getPrivateProfileVersion(e)
  return r(t, n.FAVORITE_ROOMS)
}
export const getIsRoomMarkUnreadSupported = (e) => {
  const t = getPrivateProfileVersion(e)
  return r(t, n.ROOM_MARK_UNREAD)
}
export const {
  setAccountRecoveryAgreement: setAccountRecoveryAgreement,
  setAccountRecoverySuccess: setAccountRecoverySuccess,
  setAccountRecoveryError: setAccountRecoveryError,
  submitAccountRecovery: submitAccountRecovery,
  resetAccountRecovery: resetAccountRecovery,
  setBackupCreateAgreement: setBackupCreateAgreement,
  setBackupCreateErrorMsg: setBackupCreateErrorMsg,
  setBackupCreateSecretPhrase: setBackupCreateSecretPhrase,
  setBackupCreateCheckWords: setBackupCreateCheckWords,
  submitBackupCreate: submitBackupCreate,
  createAndSubmitBackup: createAndSubmitBackup,
  submitBackupSuccess: submitBackupSuccess,
  resetBackupCreate: resetBackupCreate,
  setMigrateRecoveryPhrase: setMigrateRecoveryPhrase,
  setSyncDeviceAgreement: setSyncDeviceAgreement,
  setSyncDeviceErrorMsg: setSyncDeviceErrorMsg,
  setSyncDeviceSeedId: setSyncDeviceSeedId,
  addIdentityInvitedDevice: addIdentityInvitedDevice,
  removeIdentityInvitedDevice: removeIdentityInvitedDevice,
  initSyncDevice: initSyncDevice,
  cancelSyncDeviceSuccess: cancelSyncDeviceSuccess,
  setIdentity: setIdentity,
  setIdentityContactInvitation: setIdentityContactInvitation,
  setIdentityAsked: setIdentityAsked,
  setIdentityInvitationLink: setIdentityInvitationLink,
  setIdentitySecretPhrase: setIdentitySecretPhrase,
  setIdentityAgreement: setIdentityAgreement,
  setIdentityHasSecretPhraseStored: setIdentityHasSecretPhraseStored,
  setIdentityUsernameActionType: setIdentityUsernameActionType,
  cancelIdentityInvitationLink: cancelIdentityInvitationLink,
  setTermsOfService: setTermsOfService,
  updateIdentityDeviceRequest: updateIdentityDeviceRequest,
  updateIdentityDeviceSuccess: updateIdentityDeviceSuccess,
  updateIdentityDeviceFailure: updateIdentityDeviceFailure,
  queryIdentityRecords: queryIdentityRecords,
  updateIdentitySearchList: updateIdentitySearchList,
  updateIdentitySelectedProfile: updateIdentitySelectedProfile,
  updateIdentityVerifyStatus: updateIdentityVerifyStatus,
  updateUsernameReservationInfo: updateUsernameReservationInfo,
  resetIdentityVerifyStatus: resetIdentityVerifyStatus,
  resetUsernameReservationInfo: resetUsernameReservationInfo,
  updatePeerIdentity: updatePeerIdentity,
  updateRemoveDeviceStatus: updateRemoveDeviceStatus,
  setPrivateProfileStats: setPrivateProfileStats,
  setPrivateProfileVersion: setPrivateProfileVersion,
} = identitySlice.actions
export const askBackupCreateSecretWords = e("identity/ask-backup-create-secret-words")
export const resetBackupCreateCheckWords = e("identity/reset-account-create-check-words")
export const submitSyncIdentity = e("identity/submit-sync-identity")
export const cancelSyncDevice = e("identity/device-sync-cancel")
export const createIdentityInvitationLink = e("identity/create-identity-invitation-link")
export const approveIdentityInvitedDevice = e("identity/approve-identity-invited-device")
export const rejectIdentityInvitedDevice = e("identity/reject-identity-invited-device")
export const fetchSecretPhraseCmd = e("identity/fetch-secret-phrase-cmd")
export const clearSecretPhraseCmd = e("identity/clean-secret-phrase-cmd")
export const migrateRecoveryPhraseCmd = e("identity/migrate-recovery-phrase-cmd")
export const migrateRecoveryPhraseDeclineCmd = e("identity/migrate-recovery-phrase-decline-cmd")
export const migrateRecoveryPhraseResetFormCmd = e(
  "identity/migrate-recovery-phrase-reset-form-cmd",
)
export const fetchPrivateProfileStatsCmd = e("identity/fetch-private-profile-stats-cmd")
export const createIdentityUsernameCmd = e("identity/create-identity-username")
export const editIdentityUsernameCmd = e("identity/edit-identity-username")
export const verifyIdentityUsernameCmd = e("identity/verify-identity-username")
export const setIdentityProfile = e("identity/set-profile")
export const askIdentityLoad = e("identity/ask-identity-load")
export const identityLoggedOut = e("identity/logged-out")
export const fetchMyContactInvitationCmd = e("identity/fetch-my-contact-invitation-cmd")
export const removeLinkedDevice = e("identity/remove-linked-device")
export const updateUserSettingsCmd = e("identity/update-user-settings")
export const getIdentityInitialState = identitySlice.getInitialState
export const identityReducerBase = identitySlice.reducer