mirror of
https://github.com/nextcloud/server.git
synced 2026-06-08 16:26:59 -04:00
Provide initial state for backupcodes in template
This saves a direct request to the server when loading the backup codes. There is no need for this as the data is already known. Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
This commit is contained in:
parent
53c077afc9
commit
0971232050
11 changed files with 142 additions and 38 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -148,7 +148,8 @@ class BackupCodesProvider implements IProvider, IProvidesPersonalSettings {
|
|||
* @return IPersonalProviderSettings
|
||||
*/
|
||||
public function getPersonalSettings(IUser $user): IPersonalProviderSettings {
|
||||
return new Personal();
|
||||
$state = $this->storage->getBackupCodesState($user);
|
||||
return new Personal(base64_encode(json_encode($state)));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,14 +24,22 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\TwoFactorBackupCodes\Settings;
|
||||
|
||||
|
||||
use OCP\Authentication\TwoFactorAuth\IPersonalProviderSettings;
|
||||
use OCP\Template;
|
||||
|
||||
class Personal implements IPersonalProviderSettings {
|
||||
|
||||
/** @var string */
|
||||
private $state;
|
||||
|
||||
public function __construct(string $state) {
|
||||
$this->state = $state;
|
||||
}
|
||||
|
||||
public function getBody(): Template {
|
||||
return new Template('twofactor_backupcodes', 'personal');
|
||||
$template = new Template('twofactor_backupcodes', 'personal');
|
||||
$template->assign('state', $this->state);
|
||||
return $template;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
5
apps/twofactor_backupcodes/package-lock.json
generated
5
apps/twofactor_backupcodes/package-lock.json
generated
|
|
@ -4839,6 +4839,11 @@
|
|||
"integrity": "sha512-x3LV3wdmmERhVCYy3quqA57NJW7F3i6faas++pJQWtknWT+n7k30F4TVdHvCLn48peTJFRvCpxs3UuFPqgeELg==",
|
||||
"dev": true
|
||||
},
|
||||
"vuex": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/vuex/-/vuex-3.0.1.tgz",
|
||||
"integrity": "sha512-wLoqz0B7DSZtgbWL1ShIBBCjv22GV5U+vcBFox658g6V0s4wZV9P4YjCNyoHSyIBpj1f29JBoNQIqD82cR4O3w=="
|
||||
},
|
||||
"watchpack": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz",
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@
|
|||
"dependencies": {
|
||||
"nextcloud-axios": "^0.1.3",
|
||||
"nextcloud-password-confirmation": "^0.1.0",
|
||||
"vue": "^2.5.17"
|
||||
"vue": "^2.5.17",
|
||||
"vuex": "^3.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.1.0",
|
||||
|
|
|
|||
|
|
@ -1,11 +1,5 @@
|
|||
import Axios from 'nextcloud-axios'
|
||||
|
||||
export function getState () {
|
||||
const url = OC.generateUrl('/apps/twofactor_backupcodes/settings/state');
|
||||
|
||||
return Axios.get(url).then(resp => resp.data);
|
||||
}
|
||||
|
||||
export function generateCodes () {
|
||||
const url = OC.generateUrl('/apps/twofactor_backupcodes/settings/create');
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,15 @@
|
|||
import Vue from 'vue';
|
||||
import PersonalSettings from './views/PersonalSettings';
|
||||
import store from './store';
|
||||
|
||||
Vue.prototype.t = t;
|
||||
|
||||
export default new Vue({
|
||||
el: '#twofactor-backupcodes-settings',
|
||||
render: h => h(PersonalSettings)
|
||||
});
|
||||
const initialStateElem = JSON.parse(atob(document.getElementById('twofactor-backupcodes-initial-state').value));
|
||||
store.replaceState(
|
||||
initialStateElem
|
||||
)
|
||||
|
||||
const View = Vue.extend(PersonalSettings)
|
||||
new View({
|
||||
store
|
||||
}).$mount('#twofactor-backupcodes-settings')
|
||||
|
|
|
|||
69
apps/twofactor_backupcodes/src/store.js
Normal file
69
apps/twofactor_backupcodes/src/store.js
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* @copyright 2019 Roeland Jago Douma <roeland@famdouma.nl>
|
||||
*
|
||||
* @author 2019 Roeland Jago Douma <roeland@famdouma.nl>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import Vue from 'vue'
|
||||
import Vuex from 'vuex'
|
||||
|
||||
import {generateCodes} from './service/BackupCodesService'
|
||||
|
||||
Vue.use(Vuex)
|
||||
|
||||
export const mutations = {
|
||||
setEnabled(state, enabled) {
|
||||
Vue.set(state, 'enabled', enabled)
|
||||
},
|
||||
setTotal(state, total) {
|
||||
Vue.set(state, 'total', total)
|
||||
},
|
||||
setUsed(state, used) {
|
||||
Vue.set(state, 'used', used)
|
||||
},
|
||||
setCodes(state, codes) {
|
||||
Vue.set(state, 'codes', codes)
|
||||
}
|
||||
}
|
||||
|
||||
export const actions = {
|
||||
generate ({commit}) {
|
||||
commit('setEnabled', false);
|
||||
|
||||
return generateCodes()
|
||||
.then(({codes, state}) => {
|
||||
commit('setEnabled', state.enabled);
|
||||
commit('setTotal', state.total);
|
||||
commit('setUsed', state.used);
|
||||
commit('setCodes', codes);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default new Vuex.Store({
|
||||
strict: process.env.NODE_ENV !== 'production',
|
||||
state: {
|
||||
enabled: false,
|
||||
total: 0,
|
||||
used: 0,
|
||||
codes: undefined
|
||||
},
|
||||
mutations,
|
||||
actions
|
||||
})
|
||||
|
|
@ -34,17 +34,13 @@
|
|||
|
||||
<script>
|
||||
import confirmPassword from 'nextcloud-password-confirmation';
|
||||
|
||||
import {getState, generateCodes} from '../service/BackupCodesService';
|
||||
import {print} from '../service/PrintService';
|
||||
|
||||
export default {
|
||||
name: "PersonalSettings",
|
||||
data() {
|
||||
return {
|
||||
enabled: false,
|
||||
generatingCodes: false,
|
||||
codes: undefined
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -55,30 +51,27 @@
|
|||
return 'data:text/plain,' + encodeURIComponent(this.codes.reduce((prev, code) => {
|
||||
return prev + code + '\r\n';
|
||||
}, ''));
|
||||
},
|
||||
enabled: function() {
|
||||
return this.$store.state.enabled
|
||||
},
|
||||
total: function() {
|
||||
return this.$store.state.total
|
||||
},
|
||||
used: function() {
|
||||
return this.$store.state.used
|
||||
},
|
||||
codes: function() {
|
||||
return this.$store.state.codes
|
||||
}
|
||||
},
|
||||
created: function() {
|
||||
getState()
|
||||
.then(state => {
|
||||
this.enabled = state.enabled;
|
||||
this.total = state.total;
|
||||
this.used = state.used;
|
||||
})
|
||||
.catch(console.error.bind(this));
|
||||
},
|
||||
methods: {
|
||||
generateBackupCodes: function() {
|
||||
confirmPassword().then(() => {
|
||||
// Hide old codes
|
||||
this.enabled = false;
|
||||
this.generatingCodes = true;
|
||||
|
||||
generateCodes().then(data => {
|
||||
this.enabled = data.state.enabled;
|
||||
this.total = data.state.total;
|
||||
this.used = data.state.used;
|
||||
this.codes = data.codes;
|
||||
|
||||
this.$store.dispatch('generate').then(data => {
|
||||
this.generatingCodes = false;
|
||||
}).catch(err => {
|
||||
OC.Notification.showTemporary(t('twofactor_backupcodes', 'An error occurred while generating your backup codes'));
|
||||
|
|
|
|||
|
|
@ -4,4 +4,6 @@ script('twofactor_backupcodes', 'settings');
|
|||
|
||||
?>
|
||||
|
||||
<input type="hidden" id="twofactor-backupcodes-initial-state" value="<?php p($_['state']); ?>">
|
||||
|
||||
<div id="twofactor-backupcodes-settings"></div>
|
||||
|
|
|
|||
Loading…
Reference in a new issue