diff --git a/.eslintignore b/.eslintignore
index b54509b61..d2e8e4bba 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -28,6 +28,7 @@ app/js/components/*
app/js/store/*
app/js/utils/*
!app/js/utils/account-utils*
+!app/js/utils/api-utils*
app/js/profiles/store/*
app/js/profiles/tabs/*
diff --git a/app/js/account/StorageProvidersPage.js b/app/js/account/StorageProvidersPage.js
index f6f5380da..7df9d9dec 100644
--- a/app/js/account/StorageProvidersPage.js
+++ b/app/js/account/StorageProvidersPage.js
@@ -4,9 +4,7 @@ import { connect } from 'react-redux'
import { AccountActions } from '../account/store/account'
import { SettingsActions } from '../account/store/settings'
-import { DROPBOX, BLOCKSTACK_INC } from './utils/index'
-import { getDropboxAccessTokenFromHash,
- redirectToConnectToDropbox } from './utils/dropbox'
+import { BLOCKSTACK_INC } from './utils/index'
import { connectToGaiaHub } from './utils/blockstack-inc'
@@ -15,7 +13,6 @@ import log4js from 'log4js'
const logger = log4js.getLogger('storage/StorageProvidersPage.js')
-const Dropbox = require('dropbox')
function mapStateToProps(state) {
return {
@@ -51,47 +48,18 @@ class StorageProvidersPage extends Component {
this.state = {
hide: true
}
- this.connectDropbox = this.connectDropbox.bind(this)
- this.disconnectDropbox = this.disconnectDropbox.bind(this)
this.updateApi = this.updateApi.bind(this)
}
componentWillMount() {
- const api = this.props.api
- const dropboxAccessToken = getDropboxAccessTokenFromHash(window.location.hash)
const needToConnectGaiaHub = window.location.hash === '#gaiahub'
- const needToConnectDropbox = dropboxAccessToken != null
- if (needToConnectDropbox) {
- const newApi = Object.assign({}, api, { dropboxAccessToken })
- this.props.updateApi(newApi)
- const identityIndex = 0
- const identity = this.props.localIdentities[identityIndex]
- const identityAddress = identity.ownerAddress
- const profileSigningKeypair = this.props.identityKeypairs[identityIndex]
- const profile = identity.profile
-
- // This is okay selecting storage right now is only done during on-boarding
- const firstDropboxUpload = true
-
- setCoreStorageConfig(newApi, identityIndex, identityAddress,
- profile, profileSigningKeypair, firstDropboxUpload)
- .then((indexUrl) => {
- logger.debug(`componentDidMount: indexUrl: ${indexUrl}`)
- // TODO add index URL to token file
- logger.debug('componentDidMount: storage initialized')
- const newApi2 = Object.assign({}, newApi, { storageConnected: true })
- this.props.updateApi(newApi2)
- this.props.storageIsConnected()
- logger.debug('componentDidMount: storage configured')
- })
- }
if (needToConnectGaiaHub) {
logger.debug('componentDidMount: trying to connect gaia hub...')
this.connectSharedService()
}
// We can show the page contents since there's not going to be a redirect
- if (!(needToConnectGaiaHub || needToConnectDropbox)) {
+ if (!(needToConnectGaiaHub)) {
this.setState({ hide: false })
}
}
@@ -109,17 +77,6 @@ class StorageProvidersPage extends Component {
}
}
- connectDropbox() {
- redirectToConnectToDropbox()
- }
-
- disconnectDropbox() {
- const api = this.props.api
- const dbx = new Dropbox({ accessToken: api.dropboxAccessToken })
- dbx.authTokenRevoke()
- this.props.updateApi(Object.assign({}, api, { dropboxAccessToken: null }))
- }
-
connectSharedService() {
const storageProvider = this.props.api.gaiaHubUrl
const signer = this.props.identityKeypairs[0].key
@@ -135,7 +92,7 @@ class StorageProvidersPage extends Component {
const profileSigningKeypair = this.props.identityKeypairs[identityIndex]
const profile = identity.profile
setCoreStorageConfig(newApi, identityIndex, identityAddress,
- profile, profileSigningKeypair)
+ profile, profileSigningKeypair, identity)
.then((indexUrl) => {
logger.debug(`componentDidMount: indexUrl: ${indexUrl}`)
// TODO add index URL to token file
@@ -204,89 +161,6 @@ class StorageProvidersPage extends Component {
Run your own Gaia storage hub
-
- {api.hostedDataLocation !== DROPBOX ?
-
- :
-
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
}
diff --git a/app/js/account/store/settings/actions.js b/app/js/account/store/settings/actions.js
index dd32d8edc..af5d49f18 100644
--- a/app/js/account/store/settings/actions.js
+++ b/app/js/account/store/settings/actions.js
@@ -33,7 +33,6 @@ function refreshBtcPrice(btcPriceUrl) {
function resetApi(api) {
logger.trace('resetApi')
- let dropboxAccessToken = api.dropboxAccessToken
let coreAPIPassword = api.coreAPIPassword
let gaiaHubConfig = api.gaiaHubConfig
@@ -41,17 +40,12 @@ function resetApi(api) {
gaiaHubConfig = null
}
- if (dropboxAccessToken === undefined) {
- dropboxAccessToken = null
- }
-
if (coreAPIPassword === undefined) {
coreAPIPassword = null
}
return dispatch => {
dispatch(updateApi(Object.assign({}, DEFAULT_API, {
gaiaHubConfig,
- dropboxAccessToken,
coreAPIPassword
})))
}
diff --git a/app/js/account/store/settings/default.js b/app/js/account/store/settings/default.js
index 2999b83a5..0a68298c8 100644
--- a/app/js/account/store/settings/default.js
+++ b/app/js/account/store/settings/default.js
@@ -1,4 +1,4 @@
-import { DROPBOX } from '../../../account/utils/index'
+import { BLOCKSTACK_INC } from '../../../account/utils/index'
import { isCoreEndpointDisabled } from '../../../utils/window-utils'
export const REGTEST_CORE_API_PASSWORD = 'blockstack_integration_test_api_password'
@@ -42,15 +42,11 @@ const DEFAULT_API = {
}
},
browserServerUrl: 'https://blockstack-browser-server.appartisan.com',
- hostedDataLocation: DROPBOX,
+ hostedDataLocation: BLOCKSTACK_INC,
coreHost: 'localhost',
corePort: 6270,
coreAPIPassword: null,
logServerPort: '',
- s3ApiKey: '',
- s3ApiSecret: '',
- s3Bucket: '',
- dropboxAccessToken: null,
storageConnected: false,
gaiaHubConfig: null,
gaiaHubUrl: 'https://hub.blockstack.org',
diff --git a/app/js/account/utils/blockstack-inc.js b/app/js/account/utils/blockstack-inc.js
index 7684ffbc4..31ebaba66 100644
--- a/app/js/account/utils/blockstack-inc.js
+++ b/app/js/account/utils/blockstack-inc.js
@@ -1,25 +1,9 @@
// @flow
import log4js from 'log4js'
-import { uploadToGaiaHub, connectToGaiaHub, GaiaHubConfig } from 'blockstack'
+import { connectToGaiaHub, GaiaHubConfig } from 'blockstack'
const logger = log4js.getLogger('account/utils/blockstack-inc.js')
-export function uploadPhotoToGaiaHub(api: {gaiaHubConfig: GaiaHubConfig },
- identityIndex: number, identityAddress: string, photoFile: any, photoIndex: number) {
- logger.trace('uploadPhotoToGaiaHub')
- const hubConfig = api.gaiaHubConfig
- const filename = `${identityIndex}/avatar-${photoIndex}`
- return uploadToGaiaHub(filename, photoFile, hubConfig)
-}
-
-export function uploadProfileToGaiaHub(api: {gaiaHubConfig: GaiaHubConfig},
- identityIndex: number, identityAddress: string, signedProfileTokenData: string) {
- logger.trace('uploadProfileToGaiaHub')
- const hubConfig = api.gaiaHubConfig
- const filename = `${identityIndex}/profile.json`
- return uploadToGaiaHub(filename, signedProfileTokenData, hubConfig, 'application/json')
-}
-
export function redirectToConnectToGaiaHub() {
logger.trace('redirectToConnectToGaiaHub')
const port = location.port === '' ? 80 : location.port
diff --git a/app/js/account/utils/dropbox.js b/app/js/account/utils/dropbox.js
deleted file mode 100644
index 33f31947f..000000000
--- a/app/js/account/utils/dropbox.js
+++ /dev/null
@@ -1,142 +0,0 @@
-// @flow
-import Dropbox from 'dropbox'
-import log4js from 'log4js'
-
-const logger = log4js.getLogger('account/utils/dropbox.js')
-
-export const DROPBOX_APP_ID = 'f3l2g7ge4bs68o4'
-
-export function redirectToConnectToDropbox() {
- const dbx = new Dropbox({ clientId: DROPBOX_APP_ID })
- const port = location.port === '' ? 80 : location.port
- console.log(port)
- window.location = dbx.getAuthenticationUrl(
- `http://localhost:${port}/account/storage`)
-}
-
-function getAvatarPath(identityIndex: number,
- identityAddress: string, photoIndex: number): string {
- const path = `/${identityAddress}/${identityIndex}/avatar-${photoIndex}`
- return path
-}
-
-function getProfilePath(identityIndex: number,
- identityAddress: string): string {
- const path = `/${identityAddress}/${identityIndex}/profile.json`
- return path
-}
-
-function deleteProfile(api: {dropboxAccessToken: string}, identityIndex: number,
- identityAddress: string): Promise<*> {
- const dbx = new Dropbox({ accessToken: api.dropboxAccessToken })
- const path = getProfilePath(identityIndex, identityAddress)
- return dbx.filesDelete({ path })
-}
-
-function uploadProfile(api: {dropboxAccessToken: string}, identityIndex: number,
- identityAddress: string, signedProfileTokenData: string, firstUpload: boolean): Promise<*> {
- return new Promise((resolve, reject) => {
- const dbx = new Dropbox({ accessToken: api.dropboxAccessToken })
- const path = getProfilePath(identityIndex, identityAddress)
- return dbx.filesUpload({ path, contents: signedProfileTokenData, mode: 'overwrite' })
- .then((response) => {
- if (firstUpload === true) { // we can only create shared link once
- logger.debug('uploadProfile: first upload: creating shared link')
- return dbx.sharingCreateSharedLinkWithSettings({ path: response.path_lower, settings: {} })
- .then((shareLinkResponse) => {
- logger.debug(`uploadProfile: shared link: ${shareLinkResponse}`)
- /* Appending dropbox share url with ?dl=1 returns the actual file
- instead of dropbox sign up page */
- const profileUrl = `${shareLinkResponse.url.split('=')[0]}=1`
- resolve(profileUrl)
- })
- .catch((error) => {
- logger.error('uploadProfile: error creating shared link', error)
- reject(error)
- return Promise.reject()
- })
- } else {
- logger.debug('uploadProfile: not first upload - we won\'t create shared link')
- resolve(null)
- return Promise.reject()
- }
- })
- .catch((error) => {
- reject(error)
- })
- })
-}
-
-
-export function uploadProfileToDropbox(api: {dropboxAccessToken: string},
- identityIndex: number, identityAddress: string, signedProfileTokenData: string,
- firstUpload: boolean = false): Promise<*> {
- if (firstUpload === true) { // We try to delete any existing profile file
- return deleteProfile(api, identityIndex, identityAddress)
- .then(() => uploadProfile(api, identityIndex, identityAddress,
- signedProfileTokenData, firstUpload))
- // the profile didn't exist
- .catch(() => uploadProfile(api, identityIndex, identityAddress,
- signedProfileTokenData, firstUpload))
- } else {
- return uploadProfile(api, identityIndex, identityAddress,
- signedProfileTokenData, firstUpload)
- }
-}
-
-function deletePhoto(api: {dropboxAccessToken: string}, identityIndex: number,
- identityAddress: string, photoIndex: number): Promise<*> {
- const dbx = new Dropbox({ accessToken: api.dropboxAccessToken })
- const path = getAvatarPath(identityIndex, identityAddress, photoIndex)
- return dbx.filesDelete({ path })
-}
-
-function uploadPhoto(api: {dropboxAccessToken: string}, identityIndex: number,
- identityAddress: string, photoFile: any, photoIndex: number): Promise<*> {
- const dbx = new Dropbox({ accessToken: api.dropboxAccessToken })
- const path = getAvatarPath(identityIndex, identityAddress, photoIndex)
- return new Promise((resolve, reject) => dbx.filesUpload({ path, contents: photoFile })
- .then((response) => {
- dbx.sharingCreateSharedLinkWithSettings({ path: response.path_lower, settings: {} })
- .then((shareLinkResponse) => {
- /* Appending dropbox share url with ?dl=1 returns the actual file
- instead of dropbox sign up page */
- const avatarUrl = `${shareLinkResponse.url.split('=')[0]}=1`
-
- resolve(avatarUrl)
- })
- .catch((error) => {
- reject(error)
- })
- })
- .catch((error) => {
- reject(error)
- }))
-}
-
-export function uploadPhotoToDropbox(api: {dropboxAccessToken: string},
- identityIndex: number, identityAddress: string, photoFile: any,
- photoIndex: number): Promise<*> {
- logger.debug(`uploadPhotoToDropbox: id index: ${identityIndex} id address ${identityAddress}`)
- // We try to delete any existing photo
- return deletePhoto(api, identityIndex, identityAddress, photoIndex).then(() =>
- uploadPhoto(api, identityIndex, identityAddress, photoFile, photoIndex))
- // the file didn't exist
- .catch(() => uploadPhoto(api, identityIndex, identityAddress, photoFile, photoIndex))
-}
-
-
-export function getDropboxAccessTokenFromHash(hash: string) {
- let tokens = hash.split('access_token=')
- if (tokens.length !== 2) {
- return null
- }
-
- tokens = tokens[1].split('&')
-
- if (tokens[0] === '') {
- return null
- }
-
- return tokens[0]
-}
diff --git a/app/js/account/utils/index.js b/app/js/account/utils/index.js
index 43ab8599c..408eb1e90 100644
--- a/app/js/account/utils/index.js
+++ b/app/js/account/utils/index.js
@@ -1,62 +1,95 @@
// @flow
-import { uploadPhotoToDropbox, uploadProfileToDropbox } from './dropbox'
-import { uploadPhotoToGaiaHub, uploadProfileToGaiaHub } from './blockstack-inc'
-import type { GaiaHubConfig } from './blockstack-inc'
-import log4js from 'log4js'
+import { parseZoneFile } from 'zone-file'
-const logger = log4js.getLogger('account/utils/index.js')
+import type { GaiaHubConfig } from 'blockstack'
+import { connectToGaiaHub, uploadToGaiaHub } from 'blockstack'
+
+import { getTokenFileUrlFromZoneFile } from '../../utils/zone-utils'
export const BLOCKSTACK_INC = 'gaia-hub'
-export const DROPBOX = 'dropbox'
-function getStorageMethod(api: {dropboxAccessToken: string}) {
- if (api.hostedDataLocation === DROPBOX &&
- api.dropboxAccessToken.length > 0) {
- return DROPBOX
+function getProfileUploadLocation(identity: any, hubConfig: GaiaHubConfig) {
+ if (identity.zoneFile) {
+ const zoneFileJson = parseZoneFile(identity.zoneFile)
+ return getTokenFileUrlFromZoneFile(zoneFileJson)
+ } else {
+ // aaron-debt: this should call a function in blockstack.js to get
+ // the read url
+ return `${hubConfig.url_prefix}${hubConfig.address}/profile.json`
}
- return BLOCKSTACK_INC
}
-function checkIdentityInputs(identityIndex: number, identityAddress: string) {
- if (!identityIndex && identityIndex !== 0) {
- const message = 'checkIdentityInputs: No identity index provided'
- logger.error(message)
- throw new Error(message)
+// aaron-debt: this should be moved into blockstack.js
+function canWriteUrl(url: string,
+ hubConfig: GaiaHubConfig): ?string {
+ const readPrefix = `${hubConfig.url_prefix}${hubConfig.address}/`
+ if (url.startsWith(readPrefix)) {
+ return url.substring(readPrefix.length)
+ } else {
+ return null
}
+}
- if (!identityAddress) {
- const message = 'checkIdentityInputs: No identity address provided'
- logger.error(message)
- throw new Error(message)
+function tryUpload(urlToWrite: string, data: string,
+ hubConfig: GaiaHubConfig, mimeType: ?string = undefined) {
+ const filenameWrite = canWriteUrl(urlToWrite, hubConfig)
+ if (filenameWrite === null) {
+ return null
}
+ return uploadToGaiaHub(filenameWrite, data, hubConfig, mimeType)
}
-export function uploadPhoto(api: {dropboxAccessToken: string, gaiaHubConfig: GaiaHubConfig},
- identityIndex: number, identityAddress: string, photoFile: string, photoIndex: number) {
- const storageMethod = getStorageMethod(api)
- logger.debug(`uploadPhoto: id index: ${identityIndex} id address ${identityAddress}`)
- switch (storageMethod) {
- case DROPBOX:
- return uploadPhotoToDropbox(api, identityIndex, identityAddress, photoFile, photoIndex)
- default:
- return uploadPhotoToGaiaHub(api, identityIndex, identityAddress, photoFile, photoIndex)
- }
+export function uploadPhoto(
+ api: {gaiaHubConfig: GaiaHubConfig, gaiaHubUrl: string},
+ identity: any, identityKeyPair: {key: string},
+ photoFile: string, photoIndex: number) {
+ return connectToGaiaHub(api.gaiaHubUrl, identityKeyPair.key)
+ .then((identityHubConfig) => {
+ const globalHubConfig = api.gaiaHubConfig
+
+ let uploadPrefix = getProfileUploadLocation(identity, identityHubConfig)
+ if (uploadPrefix.endsWith('profile.json')) {
+ uploadPrefix = uploadPrefix.substring(0, uploadPrefix.length - 'profile.json'.length)
+ } else {
+ throw new Error(`Cannot determine photo location based on profile location ${uploadPrefix}`)
+ }
+ const urlToWrite = `${uploadPrefix}/avatar-${photoIndex}`
+ let uploadAttempt = tryUpload(urlToWrite, photoFile, identityHubConfig, undefined)
+ if (uploadAttempt === null) {
+ uploadAttempt = tryUpload(urlToWrite, photoFile, globalHubConfig, undefined)
+ }
+
+ // if still null, we don't know the write gaia-hub-config to write the file.
+ if (uploadAttempt === null) {
+ throw new Error(`Wanted to write to ${urlToWrite} but I don't know how.`)
+ }
+
+ return uploadAttempt
+ })
}
-export function uploadProfile(api: {dropboxAccessToken: string, gaiaHubConfig: GaiaHubConfig },
- identityIndex: number, identityAddress: string, signedProfileTokenData: string,
- firstUpload: boolean = false) {
- checkIdentityInputs(identityIndex, identityAddress)
+export function uploadProfile(
+ api: {gaiaHubConfig: GaiaHubConfig, gaiaHubUrl: string},
+ identity: any, identityKeyPair: {key: string},
+ signedProfileTokenData: string) {
+ return connectToGaiaHub(api.gaiaHubUrl, identityKeyPair.key)
+ .then((identityHubConfig) => {
+ const globalHubConfig = api.gaiaHubConfig
- const storageMethod = getStorageMethod(api)
+ const urlToWrite = getProfileUploadLocation(identity, identityHubConfig)
- switch (storageMethod) {
- case DROPBOX:
- return uploadProfileToDropbox(api, identityIndex, identityAddress,
- signedProfileTokenData, firstUpload)
+ let uploadAttempt = tryUpload(urlToWrite, signedProfileTokenData,
+ identityHubConfig, 'application/json')
+ if (uploadAttempt === null) {
+ uploadAttempt = tryUpload(urlToWrite, signedProfileTokenData,
+ globalHubConfig, 'application/json')
+ }
- default:
- return uploadProfileToGaiaHub(api, identityIndex, identityAddress,
- signedProfileTokenData)
- }
+ // if still null, we don't know the write gaia-hub-config to write the file.
+ if (uploadAttempt === null) {
+ throw new Error(`Wanted to write to ${urlToWrite} but I don't know how.`)
+ }
+
+ return uploadAttempt
+ })
}
diff --git a/app/js/auth/components/AuthModal.js b/app/js/auth/components/AuthModal.js
index b4f06fb55..27d8483b4 100644
--- a/app/js/auth/components/AuthModal.js
+++ b/app/js/auth/components/AuthModal.js
@@ -64,7 +64,7 @@ class AuthModal extends Component {
static propTypes = {
defaultIdentity: PropTypes.number.isRequired,
localIdentities: PropTypes.array.isRequired,
- loadAppManifest: PropTypes.func.isRequired,
+ verifyAuthRequestAndLoadManifest: PropTypes.func.isRequired,
clearSessionToken: PropTypes.func.isRequired,
getCoreSessionToken: PropTypes.func.isRequired,
coreAPIPassword: PropTypes.string.isRequired,
@@ -142,7 +142,7 @@ class AuthModal extends Component {
invalidScopes
})
- this.props.loadAppManifest(authRequest)
+ this.props.verifyAuthRequestAndLoadManifest(authRequest)
}
componentWillReceiveProps(nextProps) {
@@ -221,12 +221,15 @@ class AuthModal extends Component {
if (storageConnected) {
getAppBucketUrl('https://hub.blockstack.org', appPrivateKey)
.then((appBucketUrl) => {
- const identityAddress = identity.ownerAddress
- const signedProfileTokenData = signProfileForUpload(profile,
- nextProps.identityKeypairs[identityIndex])
+ logger.debug(`componentWillReceiveProps: appBucketUrl ${appBucketUrl}`)
apps[appDomain] = appBucketUrl
+ logger.debug(`componentWillReceiveProps: new apps array ${JSON.stringify(apps)}`)
profile.apps = apps
- return uploadProfile(this.props.api, identityIndex, identityAddress,
+ const signedProfileTokenData = signProfileForUpload(profile,
+ nextProps.identityKeypairs[identityIndex])
+ logger.debug('componentWillReceiveProps: uploading updated profile with new apps array')
+ return uploadProfile(this.props.api, identity,
+ nextProps.identityKeypairs[identityIndex],
signedProfileTokenData)
})
.then(() => {
@@ -380,7 +383,7 @@ class AuthModal extends Component {
if (requestingStoreWrite && needsCoreStorage) {
logger.trace('login(): Calling setCoreStorageConfig()...')
setCoreStorageConfig(this.props.api, identityIndex, identity.ownerAddress,
- identity.profile, profileSigningKeypair)
+ identity.profile, profileSigningKeypair, identity)
.then(() => {
logger.trace('login(): Core storage successfully configured.')
logger.trace('login(): Calling getCoreSessionToken()...')
@@ -513,7 +516,9 @@ class AuthModal extends Component {
: null}
- The app "{appManifest.name}" wants to
+ The app "{appManifest.name}" located at
+ {decodedToken.payload.domain_name}
+ wants to:
Read your basic info
diff --git a/app/js/auth/store/auth.js b/app/js/auth/store/auth.js
index 18bafc63d..9bb9fce0c 100644
--- a/app/js/auth/store/auth.js
+++ b/app/js/auth/store/auth.js
@@ -1,4 +1,5 @@
-import { getCoreSession, fetchAppManifest } from 'blockstack'
+import { getCoreSession,
+ verifyAuthRequestAndLoadManifest as bskVerifyAuthRequestAndLoadManifest } from 'blockstack'
import log4js from 'log4js'
const logger = log4js.getLogger('auth/store/auth.js')
@@ -78,13 +79,17 @@ function noCoreSessionToken(appDomain) {
}
}
-function loadAppManifest(authRequest) {
+function verifyAuthRequestAndLoadManifest(authRequest) {
return dispatch => {
dispatch(appManifestLoading())
- fetchAppManifest(authRequest).then(appManifest => {
+ bskVerifyAuthRequestAndLoadManifest(authRequest)
+ .then(appManifest => {
dispatch(appManifestLoaded(appManifest))
+ }, () => {
+ logger.error('verifyAuthRequestAndLoadManifest: invalid authentication request')
+ dispatch(appManifestLoadingError('Invalid authentication request.'))
}).catch((e) => {
- logger.error('loadAppManifest: error', e)
+ logger.error('verifyAuthRequestAndLoadManifest: error', e)
dispatch(appManifestLoadingError(e))
})
}
@@ -136,6 +141,6 @@ export const AuthActions = {
clearSessionToken,
getCoreSessionToken,
noCoreSessionToken,
- loadAppManifest,
+ verifyAuthRequestAndLoadManifest,
loginToApp
}
diff --git a/app/js/data/apps.js b/app/js/data/apps.js
index 4548c8b77..a70848b21 100644
--- a/app/js/data/apps.js
+++ b/app/js/data/apps.js
@@ -227,20 +227,6 @@ const apps = {
developer: 'Satraj Bambra',
status: 'user_ready_token',
storageRequired: true
- }, {
- name: 'Cryptagon',
- displayName: 'Cryptagon',
- description: '',
- version: '1.0.0',
- appIcon: {
- small: 'app-icon-cryptagon-256x256.png',
- large: 'app-icon-cryptagon-512x512.png'
- },
- website: 'http://app.cryptagon.io/',
- launchLink: 'http://app.cryptagon.io/',
- developer: 'Bernat Fortet Unanue',
- status: 'user_ready_token',
- storageRequired: true
}, {
name: 'CoinStack',
displayName: 'CoinStack',
diff --git a/app/js/profiles/AllProfilesPage.js b/app/js/profiles/AllProfilesPage.js
index 178e300bc..6b7d40406 100644
--- a/app/js/profiles/AllProfilesPage.js
+++ b/app/js/profiles/AllProfilesPage.js
@@ -110,14 +110,17 @@ class AllProfilesPage extends Component {
processing: true
})
event.preventDefault()
- const encryptedBackupPhrase = this.props.encryptedBackupPhrase
- const password = this.state.password
- const nextUnusedAddressIndex = this.props.nextUnusedAddressIndex
- this.props.createNewProfile(
- encryptedBackupPhrase,
- password, nextUnusedAddressIndex
- )
+ if (!this.state.processing) {
+ const encryptedBackupPhrase = this.props.encryptedBackupPhrase
+ const password = this.state.password
+ const nextUnusedAddressIndex = this.props.nextUnusedAddressIndex
+
+ this.props.createNewProfile(
+ encryptedBackupPhrase,
+ password, nextUnusedAddressIndex
+ )
+ }
}
openPasswordPrompt(event) {
@@ -181,6 +184,7 @@ class AllProfilesPage extends Component {
-
-