UNPKG

edge-core-js

Version:

Edge account & wallet management library

130 lines (98 loc) 4.31 kB
function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }import { buildReducer, memoizeReducer } from 'redux-keto' import { verifyData } from '../../util/crypto/verify' import { base58 } from '../../util/encoding' import { searchTree } from './login' import { findDuressStash, } from './login-stash' import { findPin2Stash } from './pin2' export const login = buildReducer({ apiKey(state = '', action) { return action.type === 'INIT' ? action.payload.apiKey : state }, apiSecret(state = null, action) { return action.type === 'INIT' ? _nullishCoalesce(action.payload.apiSecret, () => ( null)) : state }, contextAppId(state = '', action) { return action.type === 'INIT' ? action.payload.appId : state }, deviceDescription(state = null, action) { return action.type === 'INIT' ? action.payload.deviceDescription : state }, localUsers: memoizeReducer( (next) => next.login.contextAppId, (next) => next.login.stashes, (next) => next.clientInfo, (appId, stashes, clientInfo) => { function processStash(stashTree) { const { lastLogin, loginId, recovery2Key, username } = stashTree const stash = searchTree(stashTree, stash => stash.appId === appId) const keyLoginEnabled = stash != null && (stash.passwordAuthBox != null || stash.loginAuthBox != null) // Only look at the duress stash if we're in duress mode: const duressStash = clientInfo.duressEnabled ? findDuressStash(stashTree, appId) : undefined // Only fake pin disabled if the duress stash is present and has a // pin2Key: const fakePinDisabled = _optionalChain([duressStash, 'optionalAccess', _ => _.pin2Key]) != null && _optionalChain([duressStash, 'optionalAccess', _2 => _2.fakePinDisabled]) === true const pin2Stash = findPin2Stash(stashTree, appId) // Disable PIN login if we're faking it from the duress stash, or we // don't have a pin2Key on the account's pin2Stash: const pinLoginEnabled = !fakePinDisabled && _optionalChain([pin2Stash, 'optionalAccess', _3 => _3.pin2Key]) != null return { keyLoginEnabled, lastLogin, loginId: base58.stringify(loginId), pinLoginEnabled, recovery2Key: recovery2Key != null ? base58.stringify(recovery2Key) : undefined, username, voucherId: stash != null ? stash.voucherId : undefined } } return stashes.map(processStash) } ), loginServers(state = [], action) { return action.type === 'INIT' ? action.payload.loginServers : state }, stashes(state = [], action) { switch (action.type) { case 'INIT': { return action.payload.stashes } case 'LOGIN_STASH_DELETED': { const loginId = action.payload return state.filter( stashTree => !verifyData(stashTree.loginId, loginId) ) } case 'LOGIN_STASH_SAVED': { const newStashTree = action.payload const out = state.filter( stashTree => !verifyData(stashTree.loginId, newStashTree.loginId) ) out.unshift(newStashTree) return out } } return state }, walletInfos(state, action, next) { // Optimize the common case: if (next.accountIds.length === 1) { const id = next.accountIds[0] return next.accounts[id].walletInfos } const out = {} for (const accountId of next.accountIds) { const account = next.accounts[accountId] for (const id of Object.keys(account.walletInfos)) { const info = account.walletInfos[id] out[id] = info } } return out } })