- {this.deviceNameInputContent()}
+ )
+ }
+
+ addOverlayCancelAction () {
+ this.props.hideOverlay('syncAdd')
+ }
+
+ addOverlayConfirmAction () {
+ // verify if you can restore sync
+ this.restoreSyncProfile()
+ }
+
+ onClickSyncChainCodeButton () {
+ this.setState({currentDeviceOption: 'computer'})
+ // close current modal
+ this.props.hideOverlay('syncStart')
+ // open chain code modal
+ this.props.showOverlay('syncChainCode')
+ }
+
+ onClickSyncScanCodeButton () {
+ this.setState({currentDeviceOption: 'mobile'})
+ // close current modal
+ this.props.hideOverlay('syncStart')
+ // open scan code modal
+ this.props.showOverlay('syncScanCode')
+ }
+
+ /**
+ * Sync Chain Code Overlay
+ */
+ get chainCodeOverlayContent () {
+ this.checkDeviceUpdatesFor('syncChainCode')
+ return (
+
+
+
+ {
+ this.state.currentDeviceOption === 'mobile'
+ ? (
+
+
+
+
+ )
+ : null
+ }
+ {this.passphraseContent}
+
+
+ )
+ }
+
+ get chainCodeOverlayFooter () {
+ return (
+
+ {
+ this.state.currentDeviceOption === 'mobile'
+ ?
+ :
+
+
+
+ }
+
+
+
+
+
+ )
+ }
+
+ chainCodeOverlayUseCameraInstead () {
+ // hide current modal
+ this.props.hideOverlay('syncChainCode')
+ // open chain code modal
+ this.props.showOverlay('syncScanCode')
+ }
+
+ chainCodeOverlayPreviousAction () {
+ // hide current modal
+ this.props.hideOverlay('syncChainCode')
+ // open previous modal
+ this.props.showOverlay('syncStart')
+ }
+
+ chainCodeOverlayNextAction () {
+ // close current modal
+ this.props.hideOverlay('syncChainCode')
+ this.props.hideOverlay('syncAdd')
+ }
+
+ /**
+ * Sync Scan Code (QR code) Overlay
+ */
+ get scanCodeOverlayContent () {
+ this.checkDeviceUpdatesFor('syncScanCode')
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+ )
}
- get addOverlayFooter () {
- return
+ get scanCodeOverlayFooter () {
+ return (
+
+ )
}
- get resetOverlayContent () {
- return
+ onHideAnySetupOverlay () {
+ // hide every setup modal
+ this.props.hideOverlay('syncScanCode')
+ this.props.hideOverlay('syncChainCode')
+ this.props.hideOverlay('syncQRPassphrase')
+ this.props.hideOverlay('syncAdd')
+
+ if (!this.isSetup) {
+ // cancel sync without warning as user didn't complete setup
+ this.onReset(false)
+ }
}
- get resetOverlayFooter () {
+ onHideAnyRemovalOverlay () {
+ this.props.hideOverlay('syncReset')
+ this.props.hideOverlay('syncRemove')
+ }
+
+ scanCodeOverlayNoCameraAvailable () {
+ // hide current modal
+ this.props.hideOverlay('syncScanCode')
+ // open chain code modal
+ this.props.showOverlay('syncChainCode')
+ }
+
+ scanCodeOverlayPreviousAction () {
+ // hide current modal
+ this.props.hideOverlay('syncScanCode')
+ // open previous modal
+ this.props.showOverlay('syncStart')
+ }
+
+ checkDeviceUpdatesFor (modalName) {
+ const devices = this.props.syncData.get('devices')
+ const isSetupCompleted = this.props.syncData.get('setupCompleted')
+
+ // if setup is completed there's no need to check for updates
+ if (isSetupCompleted) {
+ return
+ }
+
+ if (devices.isEmpty()) {
+ // Update modal after 5s to check if new device is already fetch
+ setTimeout(() => this.forceUpdate(), 5000)
+ }
+
+ // the only way to finish sync setup is
+ // to have >= 2 devices in the list
+ if (devices.size >= 2) {
+ appActions.syncSetupCompleted(true)
+ // close current modal
+ this.props.hideOverlay(modalName)
+ }
+ }
+
+ scanCodeOverlayNextAction () {
+ // close current modal
+ this.props.hideOverlay('syncScanCode')
+ }
+
+ /**
+ * QR and Passphrase Overlay
+ */
+ get qrPassphraseOverlayContent () {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ {this.passphraseContent}
+
+
+ )
+ }
+
+ get qrPassphraseOverlayFooter () {
+ return (
+
+
+
+
+
+
+
+ )
+ }
+
+ qrPassphraseOverlayDoneAction () {
+ // close current modal
+ this.props.hideOverlay('syncQRPassphrase')
+ }
+
+ get removeOrResetOverlayContent () {
+ return (
+
+
+ {
+ this.state.isRemovingMainDevice ||
+ this.props.syncResetOverlayVisible
+ ? (
+
+ )
+ :
+ }
+
+
+ )
+ }
+
+ onClickCancelRemoveOrResetOverlayButton () {
+ this.props.hideOverlay('syncRemove')
+ this.props.hideOverlay('syncReset')
+ }
+
+ get removeOrResetOverlayFooter () {
+ return
+ }
+
+ get removeOverlayContent () {
+ return (
+
+
+ {
+ this.state.isRemovingMainDevice
+ ? (
+
+ )
+ :
+ }
+
+
+ )
+ }
+
+ get removeOverlayFooter () {
return
}
enableRestore (e) {
- if (this.props.syncRestoreEnabled === false && e.target.value) {
- this.props.enableSyncRestore(true)
- } else if (this.props.syncRestoreEnabled && !e.target.value) {
- this.props.enableSyncRestore(false)
+ let wordCount = 0
+ if (e.target.value.length > 0) {
+ wordCount = e.target.value.trim().replace(/\s+/gi, ' ').split(' ').length
}
+ this.setState({wordCount})
+ this.props.enableSyncRestore(e.target.value &&
+ (wordCount === passphraseUtil.NICEWARE_32_BYTE_WORD_COUNT ||
+ wordCount === passphraseUtil.BIP39_32_BYTE_WORD_COUNT))
}
- reset () {
- const locale = require('../../../../js/l10n')
+ reset (needsConfirmDialog = true) {
const msg = locale.translation('areYouSure')
- if (window.confirm(msg)) {
+ if (needsConfirmDialog && window.confirm(msg)) {
aboutActions.resetSync()
- this.props.hideOverlay('syncReset')
+ appActions.syncSetupCompleted(false)
+ this.retry()
+ this.props.hideOverlay('syncRemove')
+ return
}
+ aboutActions.resetSync()
+ appActions.syncSetupCompleted(false)
+ this.retry()
}
retry () {
@@ -401,11 +836,9 @@ class SyncTab extends ImmutableComponent {
tabActions.reload()
}
- setupSyncProfile (isRestoring) {
- this.props.onChangeSetting(settings.SYNC_DEVICE_NAME,
- this.deviceNameInput.value || this.defaultDeviceName)
- this.toggleSync(settings.SYNC_ENABLED, true, isRestoring)
- this.props.hideOverlay('syncStart')
+ setupSyncProfile (shouldSetup, isRestoring) {
+ this.props.onChangeSetting(settings.SYNC_DEVICE_NAME, this.defaultDeviceName)
+ this.toggleSync(settings.SYNC_ENABLED, shouldSetup, isRestoring)
}
toggleSync (key, value, isRestoring = false) {
@@ -415,94 +848,156 @@ class SyncTab extends ImmutableComponent {
}
}
+ removeSyncDevice (e) {
+ const targetDeviceId = this.state.deviceIdToRemove
+ const isMainDevice = this.state.isRemovingMainDevice
+ const shouldAllowDataClear = this.props.syncResetOverlayVisible
+ // if it's the main device or user asked for a data clear,
+ // reset sync completely
+ if (isMainDevice || shouldAllowDataClear) {
+ aboutActions.resetSync()
+ appActions.syncSetupCompleted(false)
+ } else {
+ appActions.removeSyncDevice(targetDeviceId)
+ }
+ // hide the current overlay
+ this.props.hideOverlay('syncRemove')
+ this.props.hideOverlay('syncReset')
+ }
+
restoreSyncProfile () {
if (this.passphraseInput.value) {
- let text = this.passphraseInput.value.toLowerCase().replace(/,/g, ' ').replace(/\s+/g, ' ').trim()
- let inputCode = ''
+ const text = this.passphraseInput.value.toLowerCase().replace(/,/g, ' ').replace(/\s+/g, ' ').trim()
+ let inputCode
+
try {
- inputCode = window.niceware.passphraseToBytes(text.split(' '))
+ inputCode = passphraseUtil.toBytes32(text)
} catch (e) {
- console.error('Could not convert niceware passphrase', e)
+ console.error('Could not convert passphrase', e)
}
+
if (inputCode && inputCode.length === 32) {
// QR code and device ID are set after sync restarts
aboutActions.saveSyncInitData(Array.from(inputCode))
this.setupSyncProfile(true)
+ appActions.syncSetupCompleted(true)
+ // if successful, close all possible opened dialogs
+ this.props.hideOverlay('syncChainCode')
+ this.props.hideOverlay('syncAdd')
return
}
}
- window.alert('Invalid input code; please try again or create a new profile.')
+ window.alert(locale.translation('invalidCode'))
}
render () {
return
{
- this.isSetup && this.props.syncNewDeviceOverlayVisible
- ?
- : null
- }
- {
- !this.isSetup && this.props.syncStartOverlayVisible
+ this.props.syncStartOverlayVisible
?
: null
}
{
- !this.isSetup && this.props.syncAddOverlayVisible
+ this.props.syncAddOverlayVisible
?
+ onHide={this.onHideAnySetupOverlay.bind(this)} />
: null
}
{
- this.isSetup && this.props.syncResetOverlayVisible
+ this.props.syncScanCodeOverlayVisible
?
+ whiteOverlay
+ title={
+ this.state.currentDeviceOption === 'mobile'
+ ? 'syncScanMobile'
+ : 'syncScanComputer'
+ }
+ titleImage={syncPlusImage}
+ content={this.scanCodeOverlayContent}
+ footer={this.scanCodeOverlayFooter}
+ onHide={this.onHideAnySetupOverlay.bind(this)} />
: null
}
-
-
-
- beta
-
-
-
-
-
-
-
-
- {
- this.setupError
- ? this.errorContent
- : this.isSetup
- ? this.postSetupContent
- : this.setupContent
+ {
+ this.props.syncChainCodeOverlayVisible
+ ?
+ titleArgs={{deviceType: 'syncChainCode'}}
+ titleImage={syncPlusImage}
+ content={this.chainCodeOverlayContent}
+ footer={this.chainCodeOverlayFooter}
+ onHide={this.onHideAnySetupOverlay.bind(this)} />
+ : null
+ }
+ {
+ this.props.syncQRPassphraseOverlayVisible
+ ?
+ : null
+ }
+ {
+ this.props.syncRemoveOverlayVisible ||
+ this.props.syncResetOverlayVisible
+ ?
+ : null
+ }
+ {
+ this.props.syncRemoveOverlayVisible
+ ?
+ : null
+ }
+
+ {
+ this.setupError
+ ? this.errorContent
+ : this.isSetup
+ ? this.postSetupContent
+ : this.setupContent
+ }
{
this.isSetup && this.enabled
?
-
+
*:not(.switchControl)
- marginBottom: `${globalStyles.spacing.modalPanelHeaderMarginBottom} !important`
+
+ syncOverlayBody__syncQRImg_small: {
+ margin: '10px auto',
+ maxWidth: '100%',
+ marginTop: '-20px'
},
+
syncOverlayBody__form: {
- marginBottom: globalStyles.spacing.settingsListContainerMargin
+ background: 'rgba(0, 0, 0, 0.1)',
+ border: '1px solid #000',
+ borderRadius: '4px',
+ padding: '2px',
+ width: '100%'
},
+
+ syncOverlayBody__form_withMargin: {
+ marginTop: '20px'
+ },
+
+ syncOverlayBody__form__wordCount: {
+ display: 'flex',
+ justifyContent: 'space-between',
+ alignItems: 'center',
+ borderBottomLeftRadius: '4px',
+ borderBottomRightRadius: '4px',
+ padding: '5px 10px',
+ fontSize: '13px',
+ fontWeight: 'bold'
+ },
+
syncOverlayBody__formBottomMargin: {
marginBottom: globalStyles.spacing.dialogInsideMargin
+ },
+
+ syncOverlayBody__select: {
+ borderRadius: '4px',
+ boxShadow: '0px 2px 8px -5px rgba(0, 0, 0, 1)',
+ display: 'block',
+ color: 'rgb(68, 68, 68)',
+ fontSize: '14px',
+ border: 'solid 1px rgba(0, 0, 0, 0.2)',
+ outline: 'none',
+ padding: '0.4em',
+ width: '100%',
+ maxWidth: '100%',
+ margin: '20px 0 0'
+ },
+
+ syncOverlayBody__text: {
+ marginBottom: '30px',
+ display: 'block'
+ },
+
+ syncOverlayBody__text_bold: {
+ marginRight: '10px',
+ fontWeight: 'bold'
+ },
+
+ syncOverlayBody__text_center: {
+ margin: 'auto'
+ },
+
+ syncOverlayFooter_split: {
+ display: 'flex',
+ flex: 1,
+ justifyContent: 'space-between',
+ alignItems: 'center'
+ },
+
+ syncOverlayFooter__text_bold: {
+ fontWeight: 'bold'
+ },
+
+ syncOverlayFooter_notice: {
+ fontSize: '13px',
+ width: '-webkit-fill-available',
+ display: 'flex',
+ justifyContent: 'space-between',
+ alignItems: 'center',
+ marginLeft: '90px'
+ },
+
+ syncOverlayFooter_notice_spaced: {
+ marginLeft: '150px'
+ },
+
+ syncOverlayFooter_notice__text: {
+ maxWidth: '50%'
+ },
+
+ syncOverlayFooter_notice__buttons: {
+ display: 'flex'
+ },
+
+ actionIcons__icon: {
+ backgroundColor: '#c4c5c5',
+ width: '1rem',
+ height: '1rem',
+ display: 'inline-block',
+
+ ':hover': {
+ backgroundColor: globalStyles.color.buttonColor
+ }
+ },
+
+ actionIcons__icon_remove: {
+ WebkitMaskImage: `url(${removeIcon})`,
+ display: 'block',
+ margin: 'auto'
+ },
+
+ sync__button_block: {
+ display: 'block',
+ margin: '0 15px 15px',
+ minWidth: '160px'
}
})
diff --git a/app/sessionStore.js b/app/sessionStore.js
index 0b8ffff70b..90084c070b 100644
--- a/app/sessionStore.js
+++ b/app/sessionStore.js
@@ -1025,7 +1025,8 @@ module.exports.defaultAppState = () => {
lastFetchTimestamp: 0,
objectsById: {},
pendingRecords: {},
- lastConfirmedRecordTimestamp: 0
+ lastConfirmedRecordTimestamp: 0,
+ setupCompleted: false
},
cache: {
bookmarkLocation: undefined,
diff --git a/docs/state.md b/docs/state.md
index 65547e3be3..88933f1db1 100644
--- a/docs/state.md
+++ b/docs/state.md
@@ -547,6 +547,7 @@ AppStore
devices: {
[deviceId]: {
name: string,
+ mainDevice: boolean, // whether or not this device is the main device
lastRecordTimestamp: number // last seen Sync record from this device
}
},
@@ -560,6 +561,8 @@ AppStore
record: object, // Sync record sent with SEND_SYNC_RECORDS
}
},
+ lastConfirmedRecordTimestamp: number, // the last computed time sync record was confirmed
+ setupCompleted: boolean, // whether or not sync setup has finished
seed: Array.,
seedQr: string, // data URL of QR code representing the seed
setupError: string? // indicates that an error occurred during sync setup
diff --git a/js/about/preferences.js b/js/about/preferences.js
index e64b653995..5f7f75eda9 100644
--- a/js/about/preferences.js
+++ b/js/about/preferences.js
@@ -439,9 +439,12 @@ class AboutPreferences extends React.Component {
syncStartOverlayVisible: false,
syncAddOverlayVisible: false,
syncNewDeviceOverlayVisible: false,
- syncQRVisible: false,
- syncPassphraseVisible: false,
+ syncQRVisible: true,
+ syncScanCodeOverlayVisible: false,
+ syncChainCodeOverlayVisible: false,
+ syncQRPassphraseOverlayVisible: false,
syncResetOverlayVisible: false,
+ syncRemoveOverlayVisible: false,
syncRestoreEnabled: false,
preferenceTab: this.tabFromCurrentHash,
hintNumber: this.getNextHintNumber(),
@@ -662,29 +665,11 @@ class AboutPreferences extends React.Component {
syncStartOverlayVisible={this.state.syncStartOverlayVisible}
syncAddOverlayVisible={this.state.syncAddOverlayVisible}
syncNewDeviceOverlayVisible={this.state.syncNewDeviceOverlayVisible}
- syncQRVisible={this.state.syncQRVisible}
- showQR={() => {
- this.setState({
- syncQRVisible: true
- })
- }}
- hideQR={() => {
- this.setState({
- syncQRVisible: false
- })
- }}
- syncPassphraseVisible={this.state.syncPassphraseVisible}
- showPassphrase={() => {
- this.setState({
- syncPassphraseVisible: true
- })
- }}
- hidePassphrase={() => {
- this.setState({
- syncPassphraseVisible: false
- })
- }}
+ syncScanCodeOverlayVisible={this.state.syncScanCodeOverlayVisible}
+ syncChainCodeOverlayVisible={this.state.syncChainCodeOverlayVisible}
+ syncQRPassphraseOverlayVisible={this.state.syncQRPassphraseOverlayVisible}
syncResetOverlayVisible={this.state.syncResetOverlayVisible}
+ syncRemoveOverlayVisible={this.state.syncRemoveOverlayVisible}
/>
break
case preferenceTabs.SHIELDS:
diff --git a/js/actions/appActions.js b/js/actions/appActions.js
index 94f633bb12..6ee7e1baea 100644
--- a/js/actions/appActions.js
+++ b/js/actions/appActions.js
@@ -1074,6 +1074,26 @@ const appActions = {
})
},
+ /**
+ * Dispatches a message to stop syncing the requested device.
+ */
+ removeSyncDevice: function (deviceId) {
+ dispatch({
+ actionType: appConstants.APP_REMOVE_SYNC_DEVICE,
+ deviceId
+ })
+ },
+
+ /**
+ * Tells the store that user has finish setting up Sync
+ */
+ syncSetupCompleted: function (isCompleted) {
+ dispatch({
+ actionType: appConstants.APP_SETUP_SYNC_COMPLETED,
+ isCompleted
+ })
+ },
+
/*
* Will pop up an alert/confirm/prompt for a given tab. Window is still usable.
* @param {number} tabId - The tabId
diff --git a/js/constants/appConstants.js b/js/constants/appConstants.js
index 6a0d971a76..bc86482b52 100644
--- a/js/constants/appConstants.js
+++ b/js/constants/appConstants.js
@@ -104,6 +104,8 @@ const appConstants = {
APP_SAVE_SYNC_INIT_DATA: _,
APP_RESET_SYNC_DATA: _,
APP_SET_SYNC_SETUP_ERROR: _,
+ APP_REMOVE_SYNC_DEVICE: _,
+ APP_SETUP_SYNC_COMPLETED: _,
APP_ADD_NOSCRIPT_EXCEPTIONS: _,
APP_TAB_MESSAGE_BOX_SHOWN: _,
APP_TAB_MESSAGE_BOX_DISMISSED: _,
diff --git a/js/stores/appStore.js b/js/stores/appStore.js
index 63448ef661..26d1140fd4 100644
--- a/js/stores/appStore.js
+++ b/js/stores/appStore.js
@@ -34,6 +34,7 @@ const {HrtimeLogger} = require('../../app/common/lib/logUtil')
const platformUtil = require('../../app/common/lib/platformUtil')
const urlUtil = require('../lib/urlutil')
const buildConfig = require('../constants/buildConfig')
+const {getSetting} = require('../../js/settings')
// state helpers
const {makeImmutable, findNullKeyPaths} = require('../../app/common/state/immutableUtil')
@@ -555,6 +556,7 @@ const handleAppAction = (action) => {
}
break
case appConstants.APP_SAVE_SYNC_DEVICES:
+ const hasMainDevice = appState.getIn(['sync', 'devices']).some(device => device.get('mainDevice'))
for (let deviceId of Object.keys(action.devices)) {
const device = action.devices[deviceId]
if (device.lastRecordTimestamp) {
@@ -563,6 +565,9 @@ const handleAppAction = (action) => {
if (device.name) {
appState = appState.setIn(['sync', 'devices', deviceId, 'name'], device.name)
}
+ if (!hasMainDevice && getSetting(settings.SYNC_DEVICE_NAME) === device.name) {
+ appState = appState.setIn(['sync', 'devices', deviceId, 'mainDevice'], true)
+ }
}
break
case appConstants.APP_SAVE_SYNC_INIT_DATA:
@@ -609,6 +614,12 @@ const handleAppAction = (action) => {
appState = appState.setIn(['sync', 'devices'], {})
appState = appState.setIn(['sync', 'objectsById'], {})
break
+ case appConstants.APP_REMOVE_SYNC_DEVICE:
+ appState = appState.deleteIn(['sync', 'devices', action.deviceId])
+ break
+ case appConstants.APP_SETUP_SYNC_COMPLETED:
+ appState = appState.setIn(['sync', 'setupCompleted'], action.isCompleted)
+ break
case appConstants.APP_SET_VERSION_INFO:
if (action.name && action.version) {
appState = appState.setIn(['about', 'brave', 'versionInformation', action.name], action.version)
diff --git a/less/about/preferences.less b/less/about/preferences.less
index 750332ba4d..af247b0182 100644
--- a/less/about/preferences.less
+++ b/less/about/preferences.less
@@ -185,10 +185,8 @@ input[type="checkbox"][disabled] {
table.sortableTable {
// For Sync tab
- tbody td:first-of-type {
+ thead tr th:last-of-type {
text-align: center;
- color: @braveOrange;
- font-weight: 800;
}
}
diff --git a/package-lock.json b/package-lock.json
index 20af179b84..d05b6975ba 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "brave",
- "version": "0.22.0",
+ "version": "0.22.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -1745,6 +1745,18 @@
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.0.tgz",
"integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw=="
},
+ "bip39": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/bip39/-/bip39-2.5.0.tgz",
+ "integrity": "sha512-xwIx/8JKoT2+IPJpFEfXoWdYwP7UVAoUxxLNfGCfVowaJE7yg1Y5B1BVPqlUNsBq5/nGwmFkwRJ8xDW4sX8OdA==",
+ "requires": {
+ "create-hash": "1.1.3",
+ "pbkdf2": "3.0.14",
+ "randombytes": "2.0.6",
+ "safe-buffer": "5.1.1",
+ "unorm": "1.4.1"
+ }
+ },
"bip66": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz",
@@ -2407,6 +2419,52 @@
}
}
},
+ "brave-crypto": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/brave-crypto/-/brave-crypto-0.1.0.tgz",
+ "integrity": "sha512-wwkTQGt0upph8EaB4tUeSUyMlbI07VxgC/8zMoGDz9ucdZgdz2Pk3g1ReCfJpSJYuPMPPG7oSfOXyIOGhD7oIA==",
+ "requires": {
+ "bip39": "2.5.0",
+ "niceware": "1.0.5",
+ "tweetnacl": "1.0.0"
+ },
+ "dependencies": {
+ "tweetnacl": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.0.tgz",
+ "integrity": "sha1-cT2LgY2kIGh0C/aDhtBHnmb8ins="
+ }
+ }
+ },
+ "brave-ui": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/brave-ui/-/brave-ui-0.5.0.tgz",
+ "integrity": "sha512-NN+Ig/Aljrk0A4CJHjAdkoaW7hYnVY/tpL1SypDYyXhUvMmpTLk+kyq3XDm/jJ9mdk+aerF0kMSsvmSVqY3HCQ==",
+ "requires": {
+ "aphrodite": "1.2.5"
+ },
+ "dependencies": {
+ "aphrodite": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/aphrodite/-/aphrodite-1.2.5.tgz",
+ "integrity": "sha1-g1jDbIC7A67puXFlqqcBhiJbSYM=",
+ "requires": {
+ "asap": "2.0.6",
+ "inline-style-prefixer": "3.0.8",
+ "string-hash": "1.1.3"
+ }
+ },
+ "inline-style-prefixer": {
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-3.0.8.tgz",
+ "integrity": "sha1-hVG45bTVcyROZqNLBPfTIHaitTQ=",
+ "requires": {
+ "bowser": "1.9.3",
+ "css-in-js-utils": "2.0.0"
+ }
+ }
+ }
+ },
"brorand": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
@@ -3853,6 +3911,14 @@
"integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=",
"dev": true
},
+ "css-in-js-utils": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-2.0.0.tgz",
+ "integrity": "sha512-yuWmPMD9FLi50Xf3k8W8oO3WM1eVnxEGCldCLyfusQ+CgivFk0s23yst4ooW6tfxMuSa03S6uUEga9UhX6GRrA==",
+ "requires": {
+ "hyphenate-style-name": "1.0.2"
+ }
+ },
"css-list": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/css-list/-/css-list-0.1.3.tgz",
@@ -13696,7 +13762,6 @@
"version": "3.0.14",
"resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz",
"integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==",
- "dev": true,
"requires": {
"create-hash": "1.1.3",
"create-hmac": "1.1.6",
@@ -17306,6 +17371,11 @@
"integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
"dev": true
},
+ "string-hash": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/string-hash/-/string-hash-1.1.3.tgz",
+ "integrity": "sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs="
+ },
"string-width": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
@@ -18386,6 +18456,11 @@
"resolved": "https://registry.npmjs.org/unordered-array-remove/-/unordered-array-remove-1.0.2.tgz",
"integrity": "sha1-xUbo+I4xegzyZEyX7LV9umbSUO8="
},
+ "unorm": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.4.1.tgz",
+ "integrity": "sha1-NkIA1fE2RsqLzURJAnEzVhR5IwA="
+ },
"unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
diff --git a/package.json b/package.json
index a1cdf5fd64..9765bdcede 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "brave",
- "version": "0.22.0",
+ "version": "0.22.1",
"description": "Brave laptop and desktop browser",
"main": "./app/index.js",
"config": {
@@ -93,6 +93,8 @@
"bat-publisher": "^2.0.15",
"bignumber.js": "^4.0.4",
"bloodhound-js": "brave/bloodhound",
+ "brave-crypto": "^0.1.0",
+ "brave-ui": "^0.5.0",
"clipboard-copy": "^1.0.0",
"compare-versions": "^3.0.1",
"date-fns": "^1.29.0",
@@ -111,7 +113,6 @@
"l20n": "^3.5.1",
"lru-cache": "^1.0.0",
"nan": "2.8.0",
- "niceware": "^1.0.4",
"parse-torrent": "^5.8.1",
"prettier-bytes": "^1.0.3",
"prop-types": "^15.5.6",
diff --git a/test/lib/userProfiles.js b/test/lib/userProfiles.js
index 09d4e0ea5c..be63cc73ef 100644
--- a/test/lib/userProfiles.js
+++ b/test/lib/userProfiles.js
@@ -1,5 +1,5 @@
const Immutable = require('immutable')
-const niceware = require('niceware')
+const {passphrase} = require('brave-crypto')
const addBookmarksN = function (total) {
if (!total || total > 65536) {
@@ -10,7 +10,7 @@ const addBookmarksN = function (total) {
const buffer = Buffer.alloc(2)
for (let n = 0; n < total; n++) {
buffer.writeUInt16BE(n)
- const string = niceware.bytesToPassphrase(buffer)[0]
+ const string = passphrase.fromBytesOrHex(buffer).split(' ')[0]
data.push({
location: `https://www.${string}.com`,
title: string,
@@ -32,7 +32,7 @@ const addTabsN = function (total) {
const buffer = Buffer.alloc(2)
for (let n = 0; n < total; n++) {
buffer.writeUInt16BE(n)
- const string = niceware.bytesToPassphrase(buffer)[0]
+ const string = passphrase.fromBytesOrHex(buffer).split(' ')[0]
data.push({
active: false,
discarded: true,
diff --git a/test/unit/about/preferencesTest.js b/test/unit/about/preferencesTest.js
index 3ef3742f17..b7b7ac8731 100644
--- a/test/unit/about/preferencesTest.js
+++ b/test/unit/about/preferencesTest.js
@@ -65,6 +65,14 @@ describe('Preferences component unittest', function () {
mockery.registerMock('../../../../../../extensions/brave/img/ledger/cryptoIcons/BAT_icon.svg')
// Mock image from addFundsDialogFooter
mockery.registerMock('../../../../../extensions/brave/img/ledger/uphold_logo_medium.png')
+ mockery.registerMock('../../../extensions/brave/img/sync/circle_of_sync_landing_graphic.svg')
+ mockery.registerMock('../../../extensions/brave/img/sync/device_type_phone-tablet.svg')
+ mockery.registerMock('../../../extensions/brave/img/sync/device_type_computer.svg')
+ mockery.registerMock('../../../extensions/brave/img/sync/add_device_titleicon.svg')
+ mockery.registerMock('../../../extensions/brave/img/sync/synccode_titleicon.svg')
+ mockery.registerMock('../../../extensions/brave/img/sync/hand_image.png')
+ mockery.registerMock('../../../extensions/brave/img/ledger/icon_remove.svg')
+ mockery.registerMock('../../../extensions/brave/img/sync/remove_device_titleicon.svg')
mockery.registerMock('electron', fakeElectron)