diff --git a/packages/neuron-wallet/src/controllers/helpers.ts b/packages/neuron-wallet/src/controllers/helpers.ts index b21657f17e..2c93882cb0 100644 --- a/packages/neuron-wallet/src/controllers/helpers.ts +++ b/packages/neuron-wallet/src/controllers/helpers.ts @@ -1,6 +1,6 @@ import Key from '../keys/key' import { ResponseCode } from '.' -import { CatchControllerError } from '../utils/decorators' +import { CatchControllerError } from '../decorators' import i18n from '../utils/i18n' export enum HelpersMethod { diff --git a/packages/neuron-wallet/src/controllers/networks.ts b/packages/neuron-wallet/src/controllers/networks.ts index cf24e1c46e..083dadacbe 100644 --- a/packages/neuron-wallet/src/controllers/networks.ts +++ b/packages/neuron-wallet/src/controllers/networks.ts @@ -1,6 +1,6 @@ import { ResponseCode } from '.' import NetworksService, { NetworkType, NetworkID, Network } from '../services/networks' -import { CatchControllerError } from '../utils/decorators' +import { CatchControllerError } from '../decorators' import i18n from '../utils/i18n' export enum NetworksMethod { diff --git a/packages/neuron-wallet/src/controllers/transactions.ts b/packages/neuron-wallet/src/controllers/transactions.ts index f18183cd4b..b2729c5fb6 100644 --- a/packages/neuron-wallet/src/controllers/transactions.ts +++ b/packages/neuron-wallet/src/controllers/transactions.ts @@ -5,7 +5,7 @@ import TransactionsService, { PaginationResult, TransactionsByLockHashesParam, } from '../services/transactions' -import { CatchControllerError } from '../utils/decorators' +import { CatchControllerError } from '../decorators' import i18n from '../utils/i18n' /** @@ -21,7 +21,10 @@ export default class TransactionsController { ): Promise>> { const transactions = await TransactionsService.getAll(params) - if (!transactions) throw new Error(i18n.t('messages.no-response-from-transaction-service')) + if (!transactions) + throw new Error( + i18n.t('messages.transactions-service-not-responds', { service: i18n.t('services.transactions') }), + ) return { status: ResponseCode.Success, @@ -35,7 +38,8 @@ export default class TransactionsController { ): Promise>> { const transactions = await TransactionsService.getAllByAddresses(params) - if (!transactions) throw new Error(i18n.t('messages.no-response-from-transaction-service')) + if (!transactions) + throw new Error(i18n.t('messages.service-not-responds', { service: i18n.t('services.transactions') })) return { status: ResponseCode.Success, diff --git a/packages/neuron-wallet/src/controllers/wallets.ts b/packages/neuron-wallet/src/controllers/wallets.ts index b6dae2c5a4..35b7751d87 100644 --- a/packages/neuron-wallet/src/controllers/wallets.ts +++ b/packages/neuron-wallet/src/controllers/wallets.ts @@ -1,9 +1,11 @@ import WalletsService, { Wallet, WalletProperties } from '../services/wallets' import { ResponseCode } from './index' import windowManage from '../utils/windowManage' -import { Channel, MIN_PASSWORD_LENGTH, MAX_PASSWORD_LENGTH } from '../utils/const' +import { Channel } from '../utils/const' import Key from '../keys/key' +import { CatchControllerError } from '../decorators' import i18n from '../utils/i18n' +import { verifyPasswordComplexity } from '../utils/validators' export enum WalletsMethod { GetAll = 'getAll', @@ -19,52 +21,47 @@ export enum WalletsMethod { SendCapacity = 'sendCapacity', } +/** + * @class WalletsController + * @description handle messages from wallets channel + */ class WalletsController { static service = new WalletsService() - public static getAll = (): Controller.Response => { + @CatchControllerError + public static async getAll(): Promise> { const wallets = WalletsController.service.getAll() - if (wallets) { - return { - status: ResponseCode.Success, - result: wallets, - } - } + if (!wallets) throw new Error(i18n.t('wallets-service-not-responds', { services: i18n.t('services.wallets') })) return { - status: ResponseCode.Fail, - msg: i18n.t('messages.wallet-not-found'), + status: ResponseCode.Success, + result: wallets, } } - public static get = (id: string): Controller.Response => { + @CatchControllerError + public static async get(id: string): Promise> { + if (typeof id === 'undefined') throw new Error(i18n.t('messages.id-is-required')) + const wallet = WalletsController.service.get(id) - if (wallet) { - return { - status: ResponseCode.Success, - result: wallet, - } - } + if (!wallet) throw new Error(i18n.t('messages.wallet-is-not-found', { id })) return { - status: ResponseCode.Fail, - msg: i18n.t('messages.wallet-not-found'), + status: ResponseCode.Success, + result: wallet, } } - public static generateMnemonic = (): Controller.Response => { + @CatchControllerError + public static async generateMnemonic(): Promise> { const mnemonic = Key.generateMnemonic() - if (mnemonic) { - return { - status: ResponseCode.Success, - result: mnemonic, - } - } + if (!mnemonic) throw new Error(i18n.t('messages.failed-to-create-mnemonic')) return { - status: ResponseCode.Fail, - msg: i18n.t('messages.failed-to-create-mnemonic'), + status: ResponseCode.Success, + result: mnemonic, } } - public static importMnemonic = async ({ + @CatchControllerError + public static async importMnemonic({ name, password, mnemonic, @@ -76,33 +73,30 @@ class WalletsController { mnemonic: string receivingAddressNumber: number changeAddressNumber: number - }): Promise> => { - try { - WalletsController.verifyPasswordComplexity(password) - const key = await Key.fromMnemonic(mnemonic, password, receivingAddressNumber, changeAddressNumber) - const currentWallet = WalletsController.service.getCurrent() - const wallet = WalletsController.service.create({ - name, - keystore: key.keystore!, - addresses: key.addresses!, - }) - windowManage.broadcast(Channel.Wallets, WalletsMethod.GetAll, WalletsController.getAll()) - if (!currentWallet && WalletsController.service.getAll().length === 1) { - windowManage.broadcast(Channel.Wallets, WalletsMethod.GetActive, WalletsController.getActive()) - } - return { - status: ResponseCode.Success, - result: wallet, - } - } catch (e) { - return { - status: ResponseCode.Fail, - msg: e.message, - } + }): Promise> { + const key = await Key.fromMnemonic(mnemonic, password, receivingAddressNumber, changeAddressNumber) + const currentWallet = WalletsController.service.getCurrent() + const wallet = WalletsController.service.create({ + name, + keystore: key.keystore || null, + addresses: key.addresses || { + receiving: [], + change: [], + }, + }) + // TODO: use event listener on wallets service + windowManage.broadcast(Channel.Wallets, WalletsMethod.GetAll, await WalletsController.getAll()) + if (!currentWallet && WalletsController.service.getAll().length === 1) { + windowManage.broadcast(Channel.Wallets, WalletsMethod.GetActive, await WalletsController.getActive()) + } + return { + status: ResponseCode.Success, + result: wallet, } } - public static create = async ({ + @CatchControllerError + public static async create({ name, password, mnemonic, @@ -114,18 +108,18 @@ class WalletsController { mnemonic: string receivingAddressNumber: number changeAddressNumber: number - }): Promise> => { - const res = await WalletsController.importMnemonic({ + }): Promise> { + return WalletsController.importMnemonic({ name, password, mnemonic, receivingAddressNumber, changeAddressNumber, }) - return res } - public static importKeystore = ({ + @CatchControllerError + public static async importKeystore({ name, password, keystore, @@ -137,59 +131,24 @@ class WalletsController { keystore: string receivingAddressNumber: number changeAddressNumber: number - }): Controller.Response => { - try { - WalletsController.verifyPasswordComplexity(password) - const key = Key.fromKeystore(keystore, password, receivingAddressNumber, changeAddressNumber) - const wallet = WalletsController.service.create({ - name, - keystore: key.keystore!, - addresses: key.addresses!, - }) - windowManage.broadcast(Channel.Wallets, WalletsMethod.GetAll, WalletsController.getAll()) - return { - status: ResponseCode.Success, - result: wallet, - } - } catch (e) { - return { - status: ResponseCode.Fail, - msg: e.message, - } - } - } - - public static verifyPasswordComplexity = (password: string) => { - if (password.length < MIN_PASSWORD_LENGTH) { - throw Error(i18n.t('messages.wallet-password-less-than-min-length', { minPasswordLength: MIN_PASSWORD_LENGTH })) - } - if (password.length > MAX_PASSWORD_LENGTH) { - throw Error(i18n.t('messages.wallet-password-more-than-max-length', { maxPasswordLength: MAX_PASSWORD_LENGTH })) - } - let complex = 0 - let reg = /\d/ - if (reg.test(password)) { - complex++ - } - reg = /[a-z]/ - if (reg.test(password)) { - complex++ - } - reg = /[A-Z]/ - if (reg.test(password)) { - complex++ - } - reg = /[^0-9a-zA-Z]/ - if (reg.test(password)) { - complex++ - } - if (complex < 3) { - throw Error(i18n.t('messages.wallet-password-letter-complexity')) + }): Promise> { + const key = Key.fromKeystore(keystore, password, receivingAddressNumber, changeAddressNumber) + const wallet = WalletsController.service.create({ + name, + keystore: key.keystore || null, + addresses: key.addresses || { receiving: [], change: [] }, + }) + // TODO: use event listener on wallets service + windowManage.broadcast(Channel.Wallets, WalletsMethod.GetAll, await WalletsController.getAll()) + return { + status: ResponseCode.Success, + result: wallet, } } // TODO: update addresses? - public static update = ({ + @CatchControllerError + public static async update({ id, name, password, @@ -199,124 +158,94 @@ class WalletsController { password: string name: string newPassword?: string - }): Controller.Response => { - try { - const wallet = WalletsController.service.get(id) - if (wallet) { - const props: WalletProperties = { - name: wallet.name, - addresses: wallet.addresses, - keystore: wallet.loadKeystore(), - } - if (newPassword) { - if (WalletsController.service.validate({ id, password })) { - WalletsController.verifyPasswordComplexity(password) - const key = Key.fromKeystore(JSON.stringify(wallet!.loadKeystore()), password) - props.keystore = key.toKeystore(JSON.stringify(key.keysData!), newPassword) - } else { - return { - status: ResponseCode.Fail, - msg: i18n.t('messages.wallet-incorrect-password'), - } - } - } - if (name) { - props.name = name - } - WalletsController.service.update(id, props) - windowManage.broadcast(Channel.Wallets, WalletsMethod.GetAll, WalletsController.getAll()) - return { - status: ResponseCode.Success, - result: WalletsController.service.get(id), - } - } - return { - status: ResponseCode.Fail, - msg: i18n.t('messages.wallet-not-found'), - } - } catch (e) { - return { - status: ResponseCode.Fail, - msg: e.message, - } + }): Promise> { + const wallet = WalletsController.service.get(id) + if (!wallet) throw new Error(i18n.t('wallet-is-not-found', { id })) + + const props: WalletProperties = { + name: name || wallet.name, + addresses: wallet.addresses, + keystore: wallet.loadKeystore(), } - } - public static delete = ({ id, password }: { id: string; password: string }): Controller.Response => { - if (WalletsController.service.validate({ id, password })) { - if (WalletsController.service.delete(id)) { - return { - status: ResponseCode.Success, - result: { - allWallets: WalletsController.service.getAll(), - activeWallet: WalletsController.service.getCurrent(), - }, - } + if (newPassword) { + if (WalletsController.service.validate({ id, password })) { + verifyPasswordComplexity(password) + const key = Key.fromKeystore(JSON.stringify(wallet!.loadKeystore()), password) + props.keystore = key.toKeystore(JSON.stringify(key.keysData!), newPassword) + } else { + throw new Error(i18n.t('messages.wallet-incorrect-password')) } + } - return { - status: ResponseCode.Fail, - msg: i18n.t('messages.failed-to-delete-wallet'), - } + WalletsController.service.update(id, props) + // TODO: use event listener on wallets service + windowManage.broadcast(Channel.Wallets, WalletsMethod.GetAll, await WalletsController.getAll()) + return { + status: ResponseCode.Success, + result: WalletsController.service.get(id), } + } + + @CatchControllerError + public static async delete({ id, password }: { id: string; password: string }): Promise> { + if (!WalletsController.service.validate({ id, password })) + throw new Error(i18n.t('messages.wallet-incorrect-password')) + + WalletsController.service.delete(id) return { - status: ResponseCode.Fail, - msg: i18n.t('messages.wallet-incorrect-password'), + status: ResponseCode.Success, + result: { + allWallets: WalletsController.service.getAll(), + activeWallet: WalletsController.service.getCurrent(), + }, } } - public static export = ({ id, password }: { id: string; password: string }): Controller.Response => { - if (WalletsController.service.validate({ id, password })) { - return { - status: ResponseCode.Success, - result: JSON.stringify(WalletsController.service.get(id)), - } + @CatchControllerError + public static async export({ id, password }: { id: string; password: string }): Promise> { + if (!WalletsController.service.validate({ id, password })) { + throw new Error(i18n.t('messages.wallet-incorrect-password')) } return { - status: ResponseCode.Fail, - msg: i18n.t('messages.wallet-incorrect-password'), + status: ResponseCode.Success, + result: JSON.stringify(WalletsController.service.get(id)), } } - public static getActive = () => { + @CatchControllerError + public static async getActive() { const activeWallet = WalletsController.service.getCurrent() - if (activeWallet) { - return { - status: ResponseCode.Success, - result: { - ...activeWallet, - addresses: { - receiving: activeWallet.addresses.receiving.map(addr => addr.address), - change: activeWallet.addresses.change.map(addr => addr.address), - }, - }, - } + if (!activeWallet) { + throw new Error(i18n.t('messages.no-active-wallet')) } - return { - status: ResponseCode.Fail, - msg: i18n.t('messages.no-active-wallet'), + status: ResponseCode.Success, + result: { + ...activeWallet, + addresses: { + receiving: activeWallet.addresses.receiving.map(addr => addr.address), + change: activeWallet.addresses.change.map(addr => addr.address), + }, + }, } } - public static activate = (id: string) => { - const success = WalletsController.service.setCurrent(id) - if (success) { - windowManage.broadcast(Channel.Wallets, WalletsMethod.GetActive, WalletsController.getActive()) - return { - status: ResponseCode.Success, - result: WalletsController.service.getCurrent(), - } - } + @CatchControllerError + public static async activate(id: string) { + WalletsController.service.setCurrent(id) + // TODO: use event listener on wallets service + windowManage.broadcast(Channel.Wallets, WalletsMethod.GetActive, await WalletsController.getActive()) return { - status: ResponseCode.Fail, - msg: i18n.t('messages.failed-to-activate-wallet'), + status: ResponseCode.Success, + result: WalletsController.service.getCurrent(), } // TODO: verification } - public static sendCapacity = async (params: { + @CatchControllerError + public static async sendCapacity(params: { id: string items: { address: CKBComponents.Hash256 @@ -324,13 +253,8 @@ class WalletsController { unit: 'byte' | 'shannon' }[] password: string - }) => { - if (!params) { - return { - status: ResponseCode.Fail, - msg: 'Parameters not received', - } - } + }) { + if (!params) throw new Error(i18n.t('messages.parameters-of-sending-transactions-are-required')) try { const hash = await WalletsController.service.sendCapacity(params.items, params.password) return { diff --git a/packages/neuron-wallet/src/utils/decorators.ts b/packages/neuron-wallet/src/decorators/errors.ts similarity index 100% rename from packages/neuron-wallet/src/utils/decorators.ts rename to packages/neuron-wallet/src/decorators/errors.ts diff --git a/packages/neuron-wallet/src/decorators/index.ts b/packages/neuron-wallet/src/decorators/index.ts new file mode 100644 index 0000000000..e51520df2d --- /dev/null +++ b/packages/neuron-wallet/src/decorators/index.ts @@ -0,0 +1,7 @@ +import errorsDecorators from './errors' + +export const { CatchControllerError } = errorsDecorators + +export default { + ...errorsDecorators, +} diff --git a/packages/neuron-wallet/src/keys/key.ts b/packages/neuron-wallet/src/keys/key.ts index 5f156c271b..2e2744ddf1 100644 --- a/packages/neuron-wallet/src/keys/key.ts +++ b/packages/neuron-wallet/src/keys/key.ts @@ -5,6 +5,8 @@ import SHA3 from 'sha3' import { v4 as uuid } from 'uuid' import Address, { HDAddress } from '../services/addresses' import { Keystore, KdfParams, KeysData } from './keystore' +import i18n from '../utils/i18n' +import { verifyPasswordComplexity } from '../utils/validators' import { Keychain } from './hd' export interface Addresses { @@ -53,6 +55,10 @@ export default class Key { receivingAddressNumber = DefaultAddressNumber.Receiving, changeAddressNumber = DefaultAddressNumber.Change, ) { + if (!password) throw new Error(i18n.t('messages.password-is-required')) + verifyPasswordComplexity(password) + + if (!keystore) throw new Error(i18n.t('messages.keystore-is-required')) const keystoreObject: Keystore = JSON.parse(keystore) const key = new Key() key.keystore = keystoreObject @@ -98,6 +104,10 @@ export default class Key { receivingAddressNumber = DefaultAddressNumber.Receiving, changeAddressNumber = DefaultAddressNumber.Change, ) { + if (!password) throw new Error(i18n.t('messages.password-is-required')) + verifyPasswordComplexity(password) + + if (!mnemonic) throw new Error(i18n.t('messages.mnemonic-is-required')) if (!bip39.validateMnemonic(mnemonic)) { throw new Error('Wrong Mnemonic') } diff --git a/packages/neuron-wallet/src/locales/en.ts b/packages/neuron-wallet/src/locales/en.ts index a887f43460..107fc4a5b4 100644 --- a/packages/neuron-wallet/src/locales/en.ts +++ b/packages/neuron-wallet/src/locales/en.ts @@ -33,6 +33,10 @@ export default { toggleDevTools: 'Toggle DevTools', }, }, + services: { + transactions: 'Transactions', + wallets: 'Wallets', + }, messages: { 'failed-to-load-networks': 'Failed to load networks', 'Networks-will-be-reset': 'Networks will be reset', @@ -46,7 +50,7 @@ export default { 'current-key-has-no-data': 'Current Key has no data', 'address-is-invalid': 'Address {{address}} is invalid', 'codehash-is-not-loaded': 'codehash is not loaded', - 'wallet-not-found': 'Wallet not found', + 'wallet-is-not-found': 'Wallet {{id}} not found', 'no-active-wallet': 'No active wallet', 'wallet-incorrect-password': 'Incorrect password', 'failed-to-create-mnemonic': 'Failed to create mnemonic', @@ -61,8 +65,12 @@ export default { 'cannot-delete-active-network-due-to-lack-of-default-one': 'Cannot delete active network due to lack of default one', 'active-network-is-not-set': 'Active network is not set', - 'no-response-from-transaction-service': 'No response from transaction service', 'transaction-is-not-found': 'Transaction {{hash}} is not found', + 'service-not-responds': '{{service}} service not respond', + 'name-is-required': 'Name is required', + 'mnemonic-is-required': 'Mnemonic is required', + 'keystore-is-required': '-eystore is required', + 'parameters-of-sending-transactions-are-required': 'Parameters of sending transactions are required', }, }, } diff --git a/packages/neuron-wallet/src/locales/zh.ts b/packages/neuron-wallet/src/locales/zh.ts index 9c8379cc18..a5de635068 100644 --- a/packages/neuron-wallet/src/locales/zh.ts +++ b/packages/neuron-wallet/src/locales/zh.ts @@ -33,6 +33,10 @@ export default { toggleDevTools: '开发者工具', }, }, + services: { + transactions: '交易', + wallets: '钱包', + }, messages: { 'failed-to-load-networks': '加载节点失败', 'Networks-will-be-reset': '节点列表将被重置', @@ -45,7 +49,7 @@ export default { 'current-key-has-no-data': '当前 Key 文件缺少数据', 'address-is-invalid': '地址 {{address}} 不合法', 'codehash-is-not-loaded': 'codehash 还未加载完成', - 'wallet-not-found': '未找到钱包', + 'wallet-is-not-found': '未找到钱包 {{id}}', 'no-active-wallet': '没有默认钱包', 'wallet-incorrect-password': '密码错误', 'failed-to-create-mnemonic': '创建助记词失败', @@ -59,8 +63,12 @@ export default { 'default-network-is-unremovable': '默认网络不可删除', 'cannot-delete-active-network-due-to-lack-of-default-one': '未设置默认网络, 因此无法删除当前网络', 'active-network-is-not-set': '未设置当前网络', - 'no-response-from-transaction-service': '交易服务未响应', 'transaction-is-not-found': '未找到交易 {{hash}}', + 'service-not-responds': '{{service}} 服务未响应', + 'name-is-required': '缺少名称', + 'mnemonic-is-required': '缺少助记词', + 'keystore-is-required': '缺少 Keystore', + 'parameters-of-sending-transactions-are-required': '缺少交易参数', }, }, } diff --git a/packages/neuron-wallet/src/services/wallets.ts b/packages/neuron-wallet/src/services/wallets.ts index b5fd4c5501..3a85bf7c68 100644 --- a/packages/neuron-wallet/src/services/wallets.ts +++ b/packages/neuron-wallet/src/services/wallets.ts @@ -104,6 +104,8 @@ export default class WalletService { } public create = (props: WalletProperties): Wallet => { + if (!props.name) throw new Error(i18n.t('messages.name-is-required')) + const index = this.getAll().findIndex(wallet => wallet.name === props.name) if (index !== -1) { throw Error(i18n.t('messages.wallet-name-existed')) @@ -134,13 +136,14 @@ export default class WalletService { } } - public delete = (id: string): boolean => { + public delete = (id: string) => { const current = this.getCurrent() const currentId = current ? current.id : '' const wallets = this.getAll() const index = wallets.findIndex((w: Wallet) => w.id === id) + if (index === -1) { - return false + throw new Error(i18n.t('wallet-is-not-found', { id })) } const wallet = FileKeystoreWallet.fromJSON(wallets[index]) @@ -156,17 +159,12 @@ export default class WalletService { this.listStore.clear() } } - - return true } - public setCurrent = (id: string): boolean => { + public setCurrent = (id: string) => { const wallet = this.get(id) - if (wallet) { - this.listStore.writeSync(this.currentWalletKey, id) - return true - } - return false + if (!wallet) throw new Error(i18n.t('messages.wallet-is-not-found', { id })) + this.listStore.writeSync(this.currentWalletKey, id) } public getCurrent = (): Wallet | undefined => { @@ -179,13 +177,9 @@ export default class WalletService { public validate = ({ id, password }: { id: string; password: string }) => { const wallet = this.get(id) - if (wallet) { - const key = new Key({ keystore: wallet.loadKeystore() }) - return key.checkPassword(password) - } - - // TODO: Throw wallet not found instead. - return false + if (!wallet) throw new Error(i18n.t('messages.wallet-is-not-found', { id })) + const key = new Key({ keystore: wallet.loadKeystore() }) + return key.checkPassword(password) } public clearAll = () => { diff --git a/packages/neuron-wallet/src/startup/initWindow.ts b/packages/neuron-wallet/src/startup/initWindow.ts index c9f9e118a7..793756547a 100644 --- a/packages/neuron-wallet/src/startup/initWindow.ts +++ b/packages/neuron-wallet/src/startup/initWindow.ts @@ -5,11 +5,9 @@ import { Channel } from '../utils/const' const { WalletsController, NetworksController } = controllers const initWindow = async (win: BrowserWindow) => { - const wallet = WalletsController.getActive() as any - const wallets = WalletsController.getAll() as any const initState = { - activeWallet: wallet.status ? wallet.result : null, - wallets: wallets.status ? wallets.result : [], + activeWallet: await WalletsController.service.getCurrent(), + wallets: await WalletsController.service.getAll(), activeNetworkId: await NetworksController.service.activeId(), networks: await NetworksController.service.getAll(), locale: app.getLocale(), diff --git a/packages/neuron-wallet/src/utils/validators.ts b/packages/neuron-wallet/src/utils/validators.ts new file mode 100644 index 0000000000..72bb46f9d2 --- /dev/null +++ b/packages/neuron-wallet/src/utils/validators.ts @@ -0,0 +1,35 @@ +import i18n from './i18n' +import { MIN_PASSWORD_LENGTH, MAX_PASSWORD_LENGTH } from './const' + +export const verifyPasswordComplexity = (password: string) => { + if (password.length < MIN_PASSWORD_LENGTH) { + throw Error(i18n.t('messages.wallet-password-less-than-min-length', { minPasswordLength: MIN_PASSWORD_LENGTH })) + } + if (password.length > MAX_PASSWORD_LENGTH) { + throw Error(i18n.t('messages.wallet-password-more-than-max-length', { maxPasswordLength: MAX_PASSWORD_LENGTH })) + } + let complex = 0 + let reg = /\d/ + if (reg.test(password)) { + complex++ + } + reg = /[a-z]/ + if (reg.test(password)) { + complex++ + } + reg = /[A-Z]/ + if (reg.test(password)) { + complex++ + } + reg = /[^0-9a-zA-Z]/ + if (reg.test(password)) { + complex++ + } + if (complex < 3) { + throw Error(i18n.t('messages.wallet-password-letter-complexity')) + } +} + +export default { + verifyPasswordComplexity, +} diff --git a/packages/neuron-wallet/tests/controllers/wallets.test.ts b/packages/neuron-wallet/tests/controllers/wallets.test.ts deleted file mode 100644 index 975a62ee57..0000000000 --- a/packages/neuron-wallet/tests/controllers/wallets.test.ts +++ /dev/null @@ -1,25 +0,0 @@ -import controllers from '../../src/controllers' -import i18n from '../../src/utils/i18n' -import { MIN_PASSWORD_LENGTH } from '../../src/utils/const' - -const { WalletsController } = controllers - -describe('wallet controllers tests', () => { - it('verify password complexity', () => { - expect(WalletsController.verifyPasswordComplexity('12ab....')) - expect(WalletsController.verifyPasswordComplexity('1234ABbaa3')) - expect(WalletsController.verifyPasswordComplexity('1234AB!@')) - expect(() => WalletsController.verifyPasswordComplexity('12abAC.')).toThrow( - i18n.t('messages.wallet-password-less-than-min-length', { minPasswordLength: MIN_PASSWORD_LENGTH }), - ) - expect(() => WalletsController.verifyPasswordComplexity('1234567a')).toThrow( - i18n.t('messages.wallet-password-letter-complexity'), - ) - expect(() => WalletsController.verifyPasswordComplexity('1234ABAAA')).toThrow( - i18n.t('messages.wallet-password-letter-complexity'), - ) - expect(() => WalletsController.verifyPasswordComplexity('!@~ABAAA')).toThrow( - i18n.t('messages.wallet-password-letter-complexity'), - ) - }) -}) diff --git a/packages/neuron-wallet/tests/services/wallets.test.ts b/packages/neuron-wallet/tests/services/wallets.test.ts index 8c2e8af920..5c77293776 100644 --- a/packages/neuron-wallet/tests/services/wallets.test.ts +++ b/packages/neuron-wallet/tests/services/wallets.test.ts @@ -173,8 +173,7 @@ describe('wallet service', () => { it('save wallet', () => { const { id } = walletService.create(wallet1) const wallet = walletService.get(id) - expect(wallet).toBeDefined() - expect(wallet!.name).toEqual(wallet1.name) + expect(wallet && wallet.name).toEqual(wallet1.name) }) it('wallet not exist', () => { @@ -194,8 +193,7 @@ describe('wallet service', () => { wallet1.name = wallet2.name walletService.update(w1.id, wallet1) const wallet = walletService.get(w1.id) - expect(wallet).toBeDefined() - expect(wallet!.name).toEqual(wallet2.name) + expect(wallet && wallet.name).toEqual(wallet2.name) }) it('update addresses', () => { @@ -233,8 +231,7 @@ describe('wallet service', () => { wallet1.addresses = addresses walletService.update(w1.id, wallet1) const wallet = walletService.get(w1.id) - expect(wallet).toBeDefined() - expect(wallet!.addresses).toEqual(addresses) + expect(wallet && wallet.addresses).toEqual(addresses) }) it('delete wallet', () => { @@ -249,19 +246,25 @@ describe('wallet service', () => { it('get and set active wallet', () => { const w1 = walletService.create(wallet1) const w2 = walletService.create(wallet2) - expect(walletService.setCurrent(w1.id)).toBeTruthy() - expect(walletService.getCurrent()!.id).toEqual(w1.id) - expect(walletService.setCurrent(w2.id)).toBeTruthy() - expect(walletService.getCurrent()!.id).toEqual(w2.id) - expect(walletService.setCurrent(w1.id)).toBeTruthy() + + expect(() => walletService.setCurrent(w1.id)).not.toThrowError() + + let currentWallet = walletService.getCurrent() + expect(currentWallet && currentWallet.id).toEqual(w1.id) + + expect(() => walletService.setCurrent(w2.id)).not.toThrowError() + + currentWallet = walletService.getCurrent() + expect(currentWallet && currentWallet.id).toEqual(w2.id) + + expect(() => walletService.setCurrent(w1.id)).not.toThrowError() }) it('first wallet is active wallet', () => { const w1 = walletService.create(wallet1) walletService.create(wallet2) const activeWallet = walletService.getCurrent() - expect(activeWallet).toBeDefined() - expect(activeWallet!.id).toEqual(w1.id) + expect(activeWallet && activeWallet.id).toEqual(w1.id) }) it('delete current wallet', () => { @@ -269,8 +272,7 @@ describe('wallet service', () => { const w2 = walletService.create(wallet2) walletService.delete(w1.id) const activeWallet = walletService.getCurrent() - expect(activeWallet).toBeDefined() - expect(activeWallet!.id).toEqual(w2.id) + expect(activeWallet && activeWallet.id).toEqual(w2.id) expect(walletService.getAll().length).toEqual(1) }) @@ -279,7 +281,6 @@ describe('wallet service', () => { const w2 = walletService.create(wallet2) walletService.delete(w2.id) const activeWallet = walletService.getCurrent() - expect(activeWallet).toBeDefined() - expect(activeWallet!.id).toEqual(w1.id) + expect(activeWallet && activeWallet.id).toEqual(w1.id) }) }) diff --git a/packages/neuron-wallet/tests/utils/validators.test.ts b/packages/neuron-wallet/tests/utils/validators.test.ts new file mode 100644 index 0000000000..a6721ee27e --- /dev/null +++ b/packages/neuron-wallet/tests/utils/validators.test.ts @@ -0,0 +1,17 @@ +import { verifyPasswordComplexity } from '../../src/utils/validators' +import i18n from '../../src/utils/i18n' +import { MIN_PASSWORD_LENGTH } from '../../src/utils/const' + +describe('validators', () => { + it('verify password complexity', () => { + expect(verifyPasswordComplexity('12ab....')) + expect(verifyPasswordComplexity('1234ABbaa3')) + expect(verifyPasswordComplexity('1234AB!@')) + expect(() => verifyPasswordComplexity('12abAC.')).toThrow( + i18n.t('messages.wallet-password-less-than-min-length', { minPasswordLength: MIN_PASSWORD_LENGTH }), + ) + expect(() => verifyPasswordComplexity('1234567a')).toThrow(i18n.t('messages.wallet-password-letter-complexity')) + expect(() => verifyPasswordComplexity('1234ABAAA')).toThrow(i18n.t('messages.wallet-password-letter-complexity')) + expect(() => verifyPasswordComplexity('!@~ABAAA')).toThrow(i18n.t('messages.wallet-password-letter-complexity')) + }) +})