From bcebec478e43b3851e85c94335940e8fc7546cc8 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Sun, 10 May 2020 06:46:06 +0300 Subject: moved stuff from settings, cleaned up naming for tabs, added close and peek --- .../settings_modal/tabs/security_tab/confirm.js | 9 ++ .../settings_modal/tabs/security_tab/confirm.vue | 22 +++ .../settings_modal/tabs/security_tab/mfa.js | 155 ++++++++++++++++++ .../settings_modal/tabs/security_tab/mfa.vue | 174 +++++++++++++++++++++ .../tabs/security_tab/mfa_backup_codes.js | 17 ++ .../tabs/security_tab/mfa_backup_codes.vue | 35 +++++ .../settings_modal/tabs/security_tab/mfa_totp.js | 49 ++++++ .../settings_modal/tabs/security_tab/mfa_totp.vue | 43 +++++ .../tabs/security_tab/security_tab.js | 106 +++++++++++++ .../tabs/security_tab/security_tab.vue | 143 +++++++++++++++++ 10 files changed, 753 insertions(+) create mode 100644 src/components/settings_modal/tabs/security_tab/confirm.js create mode 100644 src/components/settings_modal/tabs/security_tab/confirm.vue create mode 100644 src/components/settings_modal/tabs/security_tab/mfa.js create mode 100644 src/components/settings_modal/tabs/security_tab/mfa.vue create mode 100644 src/components/settings_modal/tabs/security_tab/mfa_backup_codes.js create mode 100644 src/components/settings_modal/tabs/security_tab/mfa_backup_codes.vue create mode 100644 src/components/settings_modal/tabs/security_tab/mfa_totp.js create mode 100644 src/components/settings_modal/tabs/security_tab/mfa_totp.vue create mode 100644 src/components/settings_modal/tabs/security_tab/security_tab.js create mode 100644 src/components/settings_modal/tabs/security_tab/security_tab.vue (limited to 'src/components/settings_modal/tabs/security_tab') diff --git a/src/components/settings_modal/tabs/security_tab/confirm.js b/src/components/settings_modal/tabs/security_tab/confirm.js new file mode 100644 index 00000000..0f4ddfc9 --- /dev/null +++ b/src/components/settings_modal/tabs/security_tab/confirm.js @@ -0,0 +1,9 @@ +const Confirm = { + props: ['disabled'], + data: () => ({}), + methods: { + confirm () { this.$emit('confirm') }, + cancel () { this.$emit('cancel') } + } +} +export default Confirm diff --git a/src/components/settings_modal/tabs/security_tab/confirm.vue b/src/components/settings_modal/tabs/security_tab/confirm.vue new file mode 100644 index 00000000..69b3811b --- /dev/null +++ b/src/components/settings_modal/tabs/security_tab/confirm.vue @@ -0,0 +1,22 @@ + + + diff --git a/src/components/settings_modal/tabs/security_tab/mfa.js b/src/components/settings_modal/tabs/security_tab/mfa.js new file mode 100644 index 00000000..abf37062 --- /dev/null +++ b/src/components/settings_modal/tabs/security_tab/mfa.js @@ -0,0 +1,155 @@ +import RecoveryCodes from './mfa_backup_codes.vue' +import TOTP from './mfa_totp.vue' +import Confirm from './confirm.vue' +import VueQrcode from '@chenfengyuan/vue-qrcode' +import { mapState } from 'vuex' + +const Mfa = { + data: () => ({ + settings: { // current settings of MFA + available: false, + enabled: false, + totp: false + }, + setupState: { // setup mfa + state: '', // state of setup. '' -> 'getBackupCodes' -> 'setupOTP' -> 'complete' + setupOTPState: '' // state of setup otp. '' -> 'prepare' -> 'confirm' -> 'complete' + }, + backupCodes: { + getNewCodes: false, + inProgress: false, // progress of fetch codes + codes: [] + }, + otpSettings: { // pre-setup setting of OTP. secret key, qrcode url. + provisioning_uri: '', + key: '' + }, + currentPassword: null, + otpConfirmToken: null, + error: null, + readyInit: false + }), + components: { + 'recovery-codes': RecoveryCodes, + 'totp-item': TOTP, + 'qrcode': VueQrcode, + 'confirm': Confirm + }, + computed: { + canSetupOTP () { + return ( + (this.setupInProgress && this.backupCodesPrepared) || + this.settings.enabled + ) && !this.settings.totp && !this.setupOTPInProgress + }, + setupInProgress () { + return this.setupState.state !== '' && this.setupState.state !== 'complete' + }, + setupOTPInProgress () { + return this.setupState.state === 'setupOTP' && !this.completedOTP + }, + prepareOTP () { + return this.setupState.setupOTPState === 'prepare' + }, + confirmOTP () { + return this.setupState.setupOTPState === 'confirm' + }, + completedOTP () { + return this.setupState.setupOTPState === 'completed' + }, + backupCodesPrepared () { + return !this.backupCodes.inProgress && this.backupCodes.codes.length > 0 + }, + confirmNewBackupCodes () { + return this.backupCodes.getNewCodes + }, + ...mapState({ + backendInteractor: (state) => state.api.backendInteractor + }) + }, + + methods: { + activateOTP () { + if (!this.settings.enabled) { + this.setupState.state = 'getBackupcodes' + this.fetchBackupCodes() + } + }, + fetchBackupCodes () { + this.backupCodes.inProgress = true + this.backupCodes.codes = [] + + return this.backendInteractor.generateMfaBackupCodes() + .then((res) => { + this.backupCodes.codes = res.codes + this.backupCodes.inProgress = false + }) + }, + getBackupCodes () { // get a new backup codes + this.backupCodes.getNewCodes = true + }, + confirmBackupCodes () { // confirm getting new backup codes + this.fetchBackupCodes().then((res) => { + this.backupCodes.getNewCodes = false + }) + }, + cancelBackupCodes () { // cancel confirm form of new backup codes + this.backupCodes.getNewCodes = false + }, + + // Setup OTP + setupOTP () { // prepare setup OTP + this.setupState.state = 'setupOTP' + this.setupState.setupOTPState = 'prepare' + this.backendInteractor.mfaSetupOTP() + .then((res) => { + this.otpSettings = res + this.setupState.setupOTPState = 'confirm' + }) + }, + doConfirmOTP () { // handler confirm enable OTP + this.error = null + this.backendInteractor.mfaConfirmOTP({ + token: this.otpConfirmToken, + password: this.currentPassword + }) + .then((res) => { + if (res.error) { + this.error = res.error + return + } + this.completeSetup() + }) + }, + + completeSetup () { + this.setupState.setupOTPState = 'complete' + this.setupState.state = 'complete' + this.currentPassword = null + this.error = null + this.fetchSettings() + }, + cancelSetup () { // cancel setup + this.setupState.setupOTPState = '' + this.setupState.state = '' + this.currentPassword = null + this.error = null + }, + // end Setup OTP + + // fetch settings from server + async fetchSettings () { + let result = await this.backendInteractor.settingsMFA() + if (result.error) return + this.settings = result.settings + this.settings.available = true + return result + } + }, + mounted () { + this.fetchSettings().then(() => { + this.readyInit = true + }) + } +} +export default Mfa diff --git a/src/components/settings_modal/tabs/security_tab/mfa.vue b/src/components/settings_modal/tabs/security_tab/mfa.vue new file mode 100644 index 00000000..25c4d1dc --- /dev/null +++ b/src/components/settings_modal/tabs/security_tab/mfa.vue @@ -0,0 +1,174 @@ + + + + diff --git a/src/components/settings_modal/tabs/security_tab/mfa_backup_codes.js b/src/components/settings_modal/tabs/security_tab/mfa_backup_codes.js new file mode 100644 index 00000000..f0a984ec --- /dev/null +++ b/src/components/settings_modal/tabs/security_tab/mfa_backup_codes.js @@ -0,0 +1,17 @@ +export default { + props: { + backupCodes: { + type: Object, + default: () => ({ + inProgress: false, + codes: [] + }) + } + }, + data: () => ({}), + computed: { + inProgress () { return this.backupCodes.inProgress }, + ready () { return this.backupCodes.codes.length > 0 }, + displayTitle () { return this.inProgress || this.ready } + } +} diff --git a/src/components/settings_modal/tabs/security_tab/mfa_backup_codes.vue b/src/components/settings_modal/tabs/security_tab/mfa_backup_codes.vue new file mode 100644 index 00000000..d7e98b3c --- /dev/null +++ b/src/components/settings_modal/tabs/security_tab/mfa_backup_codes.vue @@ -0,0 +1,35 @@ + + + diff --git a/src/components/settings_modal/tabs/security_tab/mfa_totp.js b/src/components/settings_modal/tabs/security_tab/mfa_totp.js new file mode 100644 index 00000000..8408d8e9 --- /dev/null +++ b/src/components/settings_modal/tabs/security_tab/mfa_totp.js @@ -0,0 +1,49 @@ +import Confirm from './confirm.vue' +import { mapState } from 'vuex' + +export default { + props: ['settings'], + data: () => ({ + error: false, + currentPassword: '', + deactivate: false, + inProgress: false // progress peform request to disable otp method + }), + components: { + 'confirm': Confirm + }, + computed: { + isActivated () { + return this.settings.totp + }, + ...mapState({ + backendInteractor: (state) => state.api.backendInteractor + }) + }, + methods: { + doActivate () { + this.$emit('activate') + }, + cancelDeactivate () { this.deactivate = false }, + doDeactivate () { + this.error = null + this.deactivate = true + }, + confirmDeactivate () { // confirm deactivate TOTP method + this.error = null + this.inProgress = true + this.backendInteractor.mfaDisableOTP({ + password: this.currentPassword + }) + .then((res) => { + this.inProgress = false + if (res.error) { + this.error = res.error + return + } + this.deactivate = false + this.$emit('deactivate') + }) + } + } +} diff --git a/src/components/settings_modal/tabs/security_tab/mfa_totp.vue b/src/components/settings_modal/tabs/security_tab/mfa_totp.vue new file mode 100644 index 00000000..c6f2cc7b --- /dev/null +++ b/src/components/settings_modal/tabs/security_tab/mfa_totp.vue @@ -0,0 +1,43 @@ + + diff --git a/src/components/settings_modal/tabs/security_tab/security_tab.js b/src/components/settings_modal/tabs/security_tab/security_tab.js new file mode 100644 index 00000000..811161a5 --- /dev/null +++ b/src/components/settings_modal/tabs/security_tab/security_tab.js @@ -0,0 +1,106 @@ +import ProgressButton from 'src/components/progress_button/progress_button.vue' +import Checkbox from 'src/components/checkbox/checkbox.vue' +import Mfa from './mfa.vue' + +const SecurityTab = { + data () { + return { + newEmail: '', + changeEmailError: false, + changeEmailPassword: '', + changedEmail: false, + deletingAccount: false, + deleteAccountConfirmPasswordInput: '', + deleteAccountError: false, + changePasswordInputs: [ '', '', '' ], + changedPassword: false, + changePasswordError: false + } + }, + created () { + this.$store.dispatch('fetchTokens') + }, + components: { + ProgressButton, + Mfa, + Checkbox + }, + computed: { + user () { + return this.$store.state.users.currentUser + }, + pleromaBackend () { + return this.$store.state.instance.pleromaBackend + }, + oauthTokens () { + return this.$store.state.oauthTokens.tokens.map(oauthToken => { + return { + id: oauthToken.id, + appName: oauthToken.app_name, + validUntil: new Date(oauthToken.valid_until).toLocaleDateString() + } + }) + } + }, + methods: { + confirmDelete () { + this.deletingAccount = true + }, + deleteAccount () { + this.$store.state.api.backendInteractor.deleteAccount({ password: this.deleteAccountConfirmPasswordInput }) + .then((res) => { + if (res.status === 'success') { + this.$store.dispatch('logout') + this.$router.push({ name: 'root' }) + } else { + this.deleteAccountError = res.error + } + }) + }, + changePassword () { + const params = { + password: this.changePasswordInputs[0], + newPassword: this.changePasswordInputs[1], + newPasswordConfirmation: this.changePasswordInputs[2] + } + this.$store.state.api.backendInteractor.changePassword(params) + .then((res) => { + if (res.status === 'success') { + this.changedPassword = true + this.changePasswordError = false + this.logout() + } else { + this.changedPassword = false + this.changePasswordError = res.error + } + }) + }, + changeEmail () { + const params = { + email: this.newEmail, + password: this.changeEmailPassword + } + this.$store.state.api.backendInteractor.changeEmail(params) + .then((res) => { + if (res.status === 'success') { + this.changedEmail = true + this.changeEmailError = false + } else { + this.changedEmail = false + this.changeEmailError = res.error + } + }) + }, + logout () { + this.$store.dispatch('logout') + this.$router.replace('/') + }, + revokeToken (id) { + if (window.confirm(`${this.$i18n.t('settings.revoke_token')}?`)) { + this.$store.dispatch('revokeToken', id) + } + } + } +} + +export default SecurityTab diff --git a/src/components/settings_modal/tabs/security_tab/security_tab.vue b/src/components/settings_modal/tabs/security_tab/security_tab.vue new file mode 100644 index 00000000..45bacec1 --- /dev/null +++ b/src/components/settings_modal/tabs/security_tab/security_tab.vue @@ -0,0 +1,143 @@ + + + + -- cgit v1.2.3-70-g09d2 From e7ba4255bbfdc199c513e83007fc6956166b6dc0 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Mon, 25 May 2020 03:43:55 +0300 Subject: eslint --fix + small fix --- src/components/settings_modal/settings_modal.js | 2 +- src/components/settings_modal/settings_modal.vue | 18 +- .../settings_modal/settings_modal_content.vue | 41 ++- .../settings_modal/tabs/data_import_export_tab.vue | 64 ++-- .../settings_modal/tabs/filtering_tab.vue | 152 ++++----- src/components/settings_modal/tabs/general_tab.js | 3 +- src/components/settings_modal/tabs/general_tab.vue | 306 +++++++++--------- .../settings_modal/tabs/mutes_and_blocks_tab.vue | 296 ++++++++--------- .../settings_modal/tabs/notifications_tab.vue | 90 +++--- src/components/settings_modal/tabs/profile_tab.js | 2 +- src/components/settings_modal/tabs/profile_tab.vue | 358 ++++++++++----------- .../tabs/security_tab/security_tab.vue | 242 +++++++------- .../settings_modal/tabs/theme_tab/theme_tab.vue | 150 ++++----- src/components/settings_modal/tabs/version_tab.vue | 50 +-- 14 files changed, 890 insertions(+), 884 deletions(-) (limited to 'src/components/settings_modal/tabs/security_tab') diff --git a/src/components/settings_modal/settings_modal.js b/src/components/settings_modal/settings_modal.js index 192ba5d3..d38c5751 100644 --- a/src/components/settings_modal/settings_modal.js +++ b/src/components/settings_modal/settings_modal.js @@ -12,7 +12,7 @@ const SettingsModal = { modalPeeked () { return this.$store.state.interface.settingsModalState === 'minimized' } - }, + } } export default SettingsModal diff --git a/src/components/settings_modal/settings_modal.vue b/src/components/settings_modal/settings_modal.vue index b9c0689e..b6ca5c6b 100644 --- a/src/components/settings_modal/settings_modal.vue +++ b/src/components/settings_modal/settings_modal.vue @@ -1,15 +1,15 @@ diff --git a/src/components/settings_modal/settings_modal_content.vue b/src/components/settings_modal/settings_modal_content.vue index 1778c23b..013bf34f 100644 --- a/src/components/settings_modal/settings_modal_content.vue +++ b/src/components/settings_modal/settings_modal_content.vue @@ -4,56 +4,63 @@ {{ $t('settings.settings') }} - -
+ class="settings_tab-switcher" + :side-tab-bar="true" + :scrollable-tabs="true" + >
+ >
-
+
+ >
+ >
+ >
+ >
+ >
+ >
+ >
diff --git a/src/components/settings_modal/tabs/data_import_export_tab.vue b/src/components/settings_modal/tabs/data_import_export_tab.vue index 3ddc8b03..b5d0f5ed 100644 --- a/src/components/settings_modal/tabs/data_import_export_tab.vue +++ b/src/components/settings_modal/tabs/data_import_export_tab.vue @@ -1,42 +1,42 @@ diff --git a/src/components/settings_modal/tabs/filtering_tab.vue b/src/components/settings_modal/tabs/filtering_tab.vue index 647ec7b4..eea41514 100644 --- a/src/components/settings_modal/tabs/filtering_tab.vue +++ b/src/components/settings_modal/tabs/filtering_tab.vue @@ -1,86 +1,86 @@