From a104db8906a5bdad88ceac51f0ba76fa1f41c84b Mon Sep 17 00:00:00 2001 From: Jonathan Cobb Date: Sat, 11 Jan 2020 01:59:02 -0500 Subject: [PATCH] start adding restore functionality --- src/_services/network.service.js | 12 +++- src/_store/networks.module.js | 53 ++++++++++++-- src/account/NetworkPage.vue | 107 +++++++++++++++++++++++++++-- src/account/NetworksPage.vue | 30 ++++---- src/account/NewNetworkPage.vue | 2 +- src/account/profile/ActionPage.vue | 2 +- src/auth/MultifactorAuthPage.vue | 2 +- 7 files changed, 178 insertions(+), 30 deletions(-) diff --git a/src/_services/network.service.js b/src/_services/network.service.js index 9d923ff..075c04f 100644 --- a/src/_services/network.service.js +++ b/src/_services/network.service.js @@ -9,7 +9,9 @@ export const networkService = { getStatusesByNetworkId, getNodesByNetworkId, stopNetwork, - deleteNetwork + deleteNetwork, + requestNetworkKeys, + retrieveNetworkKeys }; function getAllNetworks(userId, messages, errors) { @@ -46,3 +48,11 @@ function stopNetwork(userId, networkId, messages, errors) { function deleteNetwork(userId, networkId, messages, errors) { return fetch(`${config.apiUrl}/users/${userId}/plans/${networkId}`, util.deleteWithAuth()).then(util.handleCrudResponse(messages, errors)); } + +function requestNetworkKeys(userId, networkId, messages, errors) { + return fetch(`${config.apiUrl}/users/${userId}/networks/${networkId}/actions/keys`, util.getWithAuth()).then(util.handleCrudResponse(messages, errors)); +} + +function retrieveNetworkKeys(userId, networkId, code, password, messages, errors) { + return fetch(`${config.apiUrl}/users/${userId}/networks/${networkId}/actions/keys/${code}`, util.postWithAuth({name: 'password', value: password})).then(util.handleCrudResponse(messages, errors)); +} \ No newline at end of file diff --git a/src/_store/networks.module.js b/src/_store/networks.module.js index 6da30c3..3f32433 100644 --- a/src/_store/networks.module.js +++ b/src/_store/networks.module.js @@ -5,7 +5,8 @@ import { util } from '../_helpers'; const state = { loading: { networks: false, network: false, deleting: false, - nearestRegions: false, startingNetwork: false, networkStatuses: false, networkNodes: false + nearestRegions: false, startingNetwork: false, networkStatuses: false, networkNodes: false, + requestNetworkKeys: false, retrieveNetworkKeys: false }, creating: null, error: null, @@ -14,7 +15,9 @@ const state = { nearestRegions: null, newNodeNotification: null, networkStatuses: {}, - networkNodes: null + networkNodes: null, + networkKeysRequested: null, + networkKeys: null }; const actions = { @@ -70,7 +73,7 @@ const actions = { }, stopNetwork({ commit }, {userId, networkId, messages, errors}) { - commit('stopNetworkRequest', id); + commit('stopNetworkRequest', networkId); networkService.stopNetwork(userId, networkId, messages, errors) .then( network => commit('stopNetworkSuccess', network), @@ -79,7 +82,7 @@ const actions = { }, deleteNetwork({ commit }, {userId, networkId, messages, errors}) { - commit('deleteNetworkRequest', id); + commit('deleteNetworkRequest', networkId); networkService.deleteNetwork(userId, networkId, messages, errors) .then( network => commit('deleteNetworkSuccess', network), @@ -95,6 +98,24 @@ const actions = { error => commit('getNearestRegionsFailure', error) ); }, + + requestNetworkKeys({ commit }, {userId, networkId, messages, errors}) { + commit('requestNetworkKeysRequest'); + networkService.requestNetworkKeys(userId, networkId, messages, errors) + .then( + ok => commit('requestNetworkKeysSuccess', networkId), + error => commit('requestNetworkKeysFailure', error) + ); + }, + + retrieveNetworkKeys({ commit }, {userId, networkId, code, password, messages, errors}) { + commit('retrieveNetworkKeysRequest'); + networkService.retrieveNetworkKeys(userId, networkId, code, password, messages, errors) + .then( + keys => commit('retrieveNetworkKeysSuccess', keys), + error => commit('retrieveNetworkKeysFailure', error) + ); + } }; const mutations = { @@ -200,6 +221,30 @@ const mutations = { getNearestRegionsFailure(state, error) { state.loading.nearestRegions = false; state.error = { error }; + }, + + requestNetworkKeysRequest(state) { + state.loading.requestNetworkKeys = true; + }, + requestNetworkKeysSuccess(state, networkId) { + state.loading.requestNetworkKeys = false; + state.networkKeysRequested = networkId; + }, + requestNetworkKeysFailure(state, error) { + state.loading.requestNetworkKeys = false; + state.error = { error }; + }, + + retrieveNetworkKeysRequest(state) { + state.loading.retrieveNetworkKeys = true; + }, + retrieveNetworkKeysSuccess(state, keys) { + state.loading.retrieveNetworkKeys = false; + state.networkKeys = keys; + }, + retrieveNetworkKeysFailure(state, error) { + state.loading.retrieveNetworkKeys = false; + state.error = { error }; } }; diff --git a/src/account/NetworkPage.vue b/src/account/NetworkPage.vue index 55bb882..281f7f1 100644 --- a/src/account/NetworkPage.vue +++ b/src/account/NetworkPage.vue @@ -2,6 +2,7 @@

{{network.name}}.{{network.domainName}} - {{messages['msg_network_state_'+network.state]}}

+
{{messages.label_percent.parseMessage(this, {percent: stats.percent})}}
@@ -38,6 +39,54 @@
+
+ +
{{ errors.first('networkKeys') }}
+
{{messages.message_network_action_keys_requested}}
+ +
{{messages.message_network_action_retrieve_keys}}
+
+
+ + +
{{ errors.first('retrieveNetworkKeys') }}
+
+
+ + +
{{ errors.first('password') }}
+
+ +
+
+

{{messages.message_network_keys}}

: {{networkKeys}} +
+ {{messages.message_network_keys_description}} +
+
+
+ +
+ +
+ +
+
+

{{messages.title_network_danger_zone}}

+
{{ errors.first('node') }}
+
+
+ + {{messages.link_network_action_stop_description}} +
+
+
+
+ + {{messages.link_network_action_delete_description}} +
+
+
@@ -48,17 +97,25 @@ export default { data() { return { + user: util.currentUser(), networkId: this.$route.params.id, stats: null, - refresher: null + refresher: null, + restoreKeyCode: null, + restoreKeyPassword: null }; }, computed: { - ...mapState('networks', ['network', 'newNodeNotification', 'networkStatuses', 'networkNodes']), + ...mapState('networks', [ + 'network', 'newNodeNotification', 'networkStatuses', 'networkNodes', 'networkKeysRequested', 'networkKeys' + ]), ...mapState('system', ['messages']) }, methods: { - ...mapActions('networks', ['getNetworkById', 'deleteNetwork', 'getStatusesByNetworkId', 'getNodesByNetworkId']), + ...mapActions('networks', [ + 'getNetworkById', 'deleteNetwork', 'getStatusesByNetworkId', 'getNodesByNetworkId', + 'stopNetwork', 'deleteNetwork', 'requestNetworkKeys' + ]), ...mapGetters('networks', ['loading']), refreshStatus (userId) { this.getNetworkById({userId: userId, networkId: this.networkId, messages: this.messages, errors: this.errors}); @@ -78,6 +135,44 @@ }, startStatusRefresher (user) { this.refresher = setInterval(() => this.refreshStatus(user.uuid), 5000); + }, + stopNet () { + this.errors.clear(); + this.stopNetwork({ + userId: this.user.uuid, + networkId: this.networkId, + messages: this.messages, + errors: this.errors + }); + }, + deleteNet () { + this.errors.clear(); + this.deleteNetwork({ + userId: this.user.uuid, + networkId: this.networkId, + messages: this.messages, + errors: this.errors + }); + }, + requestRestoreKey () { + this.errors.clear(); + this.requestNetworkKeys({ + userId: this.user.uuid, + networkId: this.networkId, + messages: this.messages, + errors: this.errors + }); + }, + retrieveRestoreKey () { + this.errors.clear(); + this.retrieveNetworkKeys({ + userId: this.user.uuid, + networkId: this.networkId, + code: this.restoreKeyCode, + password: this.restoreKeyPassword, + messages: this.messages, + errors: this.errors + }); } }, created () { @@ -93,10 +188,12 @@ // console.log('watch.networkNodes: received: '+JSON.stringify(nodes)); }, networkStatuses (stats) { - console.log('received stats: '+JSON.stringify(stats)); if (stats) { - // adapted from: https://code-boxx.com/simple-vanilla-javascript-progress-bar/ if (!stats.hasOwnProperty(this.networkId)) return; + if (stats[this.networkId].length === 0) { + clearInterval(this.refresher); + return; + } this.stats = stats[this.networkId][0]; // todo: when we have multiple nodes, this will need to be changed if (this.stats.percent === 100) { clearInterval(this.refresher); diff --git a/src/account/NetworksPage.vue b/src/account/NetworksPage.vue index e9ce4f0..8d75d32 100644 --- a/src/account/NetworksPage.vue +++ b/src/account/NetworksPage.vue @@ -10,27 +10,14 @@ {{messages.label_field_networks_locale}} {{messages.label_field_networks_timezone}} {{messages.label_field_networks_object_state}} - {{messages.label_field_networks_action_view}} - {{messages.label_field_networks_action_stop}} - {{messages.label_field_networks_action_delete}} - {{network.name}}.{{network.domainName}} + {{network.name}}.{{network.domainName}} {{messages['locale_'+network.locale] || network.locale}} {{messages['tz_name_'+network.timezone] || network.timezone}} {{messages['msg_network_state_'+network.state]}} - {{messages.table_row_networks_action_view}} - - - {{messages.table_row_networks_action_stop}} - - - - - {{messages.table_row_networks_action_delete}} - @@ -52,9 +39,7 @@ export default { computed: { - ...mapState({ - networks: state => state.networks.networks - }), + ...mapState('networks', ['networks']), ...mapState('system', ['messages']) }, created () { @@ -63,6 +48,17 @@ methods: { ...mapActions('networks', ['getAllNetworks', 'stopNetwork', 'deleteNetwork']), ...mapGetters('networks', ['loading']) + }, + watch: { + networks (nets) { + if (nets && nets.length) { + if (nets.length === 0) { + this.$router.replace({path: '/bubble/new'}); + } else if (nets.length === 1 && util.currentUser().admin !== true) { + this.$router.replace({path: '/bubble/' + nets[0].name}); + } + } + } } }; \ No newline at end of file diff --git a/src/account/NewNetworkPage.vue b/src/account/NewNetworkPage.vue index 2845848..8cedfd2 100644 --- a/src/account/NewNetworkPage.vue +++ b/src/account/NewNetworkPage.vue @@ -228,7 +228,7 @@ accountPlan: { name: '', domain: '', - locale: '', + locale: util.currentUser().locale, timezone: '', plan: 'bubble', footprint: 'Worldwide', diff --git a/src/account/profile/ActionPage.vue b/src/account/profile/ActionPage.vue index 33d6598..2e3e6e8 100644 --- a/src/account/profile/ActionPage.vue +++ b/src/account/profile/ActionPage.vue @@ -42,7 +42,7 @@ errors: this.errors }); } else { - this.$router.push({path:'/me/profile', params: {'action': 'invalid'}}); + this.$router.push({path:'/me/profile', params: {action: 'invalid'}}); } }, watch: { diff --git a/src/auth/MultifactorAuthPage.vue b/src/auth/MultifactorAuthPage.vue index a03c2a6..350446e 100644 --- a/src/auth/MultifactorAuthPage.vue +++ b/src/auth/MultifactorAuthPage.vue @@ -70,7 +70,7 @@ if (isAuthenticator(type)) { console.log('submitVerification: sending authenticator code: '+code); this.sendAuthenticatorCode({ - uuid: this.username, + userId: this.username, code: code, verifyOnly: false, messages: this.messages,