Page MenuHomePhorge

No OneTemporary

Size
12 KB
Referenced Files
None
Subscribers
None
diff --git a/src/components/login_form/login_form.js b/src/components/login_form/login_form.js
index d4a05fc287..603f486653 100644
--- a/src/components/login_form/login_form.js
+++ b/src/components/login_form/login_form.js
@@ -1,79 +1,76 @@
import { mapState, mapGetters, mapActions, mapMutations } from 'vuex'
import oauthApi from '../../services/new_api/oauth.js'
const LoginForm = {
data: () => ({
user: {},
error: false
}),
computed: {
- isPasswordAuth () { return this.authMethod === 'password' },
- isTokenAuth () { return this.authMethod === 'token' },
+ isPasswordAuth () { return this.requiredPassword },
+ isTokenAuth () { return this.requiredToken },
...mapState({
registrationOpen: state => state.instance.registrationOpen,
instance: state => state.instance,
loggingIn: state => state.users.loggingIn,
oauth: state => state.oauth
}),
- ...mapGetters({ authMethod: 'authFlow/authMethod' })
+ ...mapGetters(
+ 'authFlow', ['requiredPassword', 'requiredToken', 'requiredMFA']
+ )
},
methods: {
- ...mapMutations({ setStage: 'authFlow/setStage' }),
+ ...mapMutations('authFlow', ['requireMFA', 'setupMFA']),
...mapActions({ login: 'authFlow/login' }),
submit () {
- this.tokenMethod ? this.submitToken() : this.submitPassword()
+ this.isTokenMethod ? this.submitToken() : this.submitPassword()
},
submitToken () {
oauthApi.login({
oauth: this.oauth,
instance: this.instance.server,
commit: this.$store.commit
})
},
submitPassword () {
const data = {
oauth: this.oauth,
instance: this.instance.server
}
this.error = false
oauthApi.getOrCreateApp(data).then((app) => {
oauthApi.getTokenWithCredentials(
{
app,
instance: data.instance,
username: this.user.username,
password: this.user.password
}
).then((result) => {
if (result.error) {
if (result.error === 'mfa_required') {
- this.setStage({
- app: app,
- settings: result,
- stage: 'second',
- authMethod: 'totp'
- })
- return
+ this.setupMFA({app: app, settings: result})
+ this.requireMFA()
} else {
this.error = result.error
this.focusOnPasswordInput()
- return
}
+ return
}
this.login(result).then(() => {
this.$router.push({name: 'friends'})
})
})
})
},
clearError () { this.error = false },
focusOnPasswordInput () {
let passwordInput = this.$refs.passwordInput
passwordInput.focus()
passwordInput.setSelectionRange(0, passwordInput.value.length)
}
}
}
export default LoginForm
diff --git a/src/components/mfa_form/recovery_form.js b/src/components/mfa_form/recovery_form.js
index 2477e27372..af069f0342 100644
--- a/src/components/mfa_form/recovery_form.js
+++ b/src/components/mfa_form/recovery_form.js
@@ -1,41 +1,41 @@
import mfaApi from '../../services/new_api/mfa.js'
import { mapState, mapGetters, mapActions, mapMutations } from 'vuex'
export default {
data: () => ({
code: null,
error: false
}),
computed: {
...mapGetters({
authApp: 'authFlow/app',
authSettings: 'authFlow/settings'
}),
...mapState({ instance: 'instance' })
},
methods: {
- ...mapMutations({ setMethod: 'authFlow/setMethod' }),
+ ...mapMutations({ requireTOTP: 'authFlow/requireTOTP' }),
...mapActions({ login: 'authFlow/login' }),
clearError () { this.error = false },
submit () {
const data = {
app: this.authApp,
instance: this.instance.server,
mfaToken: this.authSettings.mfa_token,
code: this.code
}
mfaApi.verifyRecoveryCode(data).then((result) => {
if (result.error) {
this.error = result.error
this.code = null
return
}
this.login(result).then(() => {
this.$router.push({name: 'friends'})
})
})
}
}
}
diff --git a/src/components/mfa_form/recovery_form.vue b/src/components/mfa_form/recovery_form.vue
index d2f0fb58be..4a5a517eb3 100644
--- a/src/components/mfa_form/recovery_form.vue
+++ b/src/components/mfa_form/recovery_form.vue
@@ -1,38 +1,38 @@
<template>
<div class="login panel panel-default">
<!-- Default panel contents -->
<div class="panel-heading">{{$t('login.heading.recovery')}}</div>
<div class="panel-body">
<form class='login-form' @submit.prevent='submit'>
<div class='form-group'>
<label for='code'>{{$t('login.recovery_code')}}</label>
<input v-model='code' class='form-control' id='code'>
</div>
<div class='form-group'>
<div class='login-bottom'>
<div>
- <a href="#" @click.prevent="setMethod('totp')">
+ <a href="#" @click.prevent="requireTOTP">
{{$t('login.enter_two_factor_code')}}
</a>
</div>
<button type='submit' class='btn btn-default'>
- {{$t('login.verify')}}
+ {{$t('general.verify')}}
</button>
</div>
</div>
</form>
</div>
<div v-if="error" class='form-group'>
<div class='alert error'>
{{error}}
<i class="button-icon icon-cancel" @click="clearError"></i>
</div>
</div>
</div>
</template>
<script src="./recovery_form.js" ></script>
diff --git a/src/components/mfa_form/totp_form.js b/src/components/mfa_form/totp_form.js
index c6089b1b9c..2e1b7ce4ec 100644
--- a/src/components/mfa_form/totp_form.js
+++ b/src/components/mfa_form/totp_form.js
@@ -1,40 +1,40 @@
import mfaApi from '../../services/new_api/mfa.js'
import { mapState, mapGetters, mapActions, mapMutations } from 'vuex'
export default {
data: () => ({
code: null,
error: false
}),
computed: {
...mapGetters({
authApp: 'authFlow/app',
authSettings: 'authFlow/settings'
}),
...mapState({ instance: 'instance' })
},
methods: {
- ...mapMutations({ setMethod: 'authFlow/setMethod' }),
+ ...mapMutations({ requireRecovery: 'authFlow/requireRecovery' }),
...mapActions({ login: 'authFlow/login' }),
clearError () { this.error = false },
submit () {
const data = {
app: this.authApp,
instance: this.instance.server,
mfaToken: this.authSettings.mfa_token,
code: this.code
}
mfaApi.verifyOTPCode(data).then((result) => {
if (result.error) {
this.error = result.error
this.code = null
return
}
this.login(result).then(() => {
this.$router.push({name: 'friends'})
})
})
}
}
}
diff --git a/src/components/mfa_form/totp_form.vue b/src/components/mfa_form/totp_form.vue
index 6507329373..d4a7c84a32 100644
--- a/src/components/mfa_form/totp_form.vue
+++ b/src/components/mfa_form/totp_form.vue
@@ -1,41 +1,41 @@
<template>
<div class="login panel panel-default">
<!-- Default panel contents -->
<div class="panel-heading">
{{$t('login.heading.totp')}}
</div>
<div class="panel-body">
<form class='login-form' @submit.prevent='submit'>
<div class='form-group'>
<label for='code'>
{{$t('login.authentication_code')}}
</label>
<input v-model='code' class='form-control' id='code'>
</div>
<div class='form-group'>
<div class='login-bottom'>
<div>
- <a href="#" @click.prevent="setMethod('recovery')">
+ <a href="#" @click.prevent="requireRecovery">
{{$t('login.enter_recovery_code')}}
</a>
</div>
<button type='submit' class='btn btn-default'>
{{$t('general.verify')}}
</button>
</div>
</div>
</form>
</div>
<div v-if="error" class='form-group'>
<div class='alert error'>
{{error}}
<i class="button-icon icon-cancel" @click="clearError"></i>
</div>
</div>
</div>
</template>
<script src="./totp_form.js"></script>
diff --git a/src/components/user_panel/user_panel.js b/src/components/user_panel/user_panel.js
index f41cc05794..1aeb965a14 100644
--- a/src/components/user_panel/user_panel.js
+++ b/src/components/user_panel/user_panel.js
@@ -1,37 +1,28 @@
import LoginForm from '../login_form/login_form.vue'
import MFARecoveryForm from '../mfa_form/recovery_form.vue'
import MFATOTPForm from '../mfa_form/totp_form.vue'
import PostStatusForm from '../post_status_form/post_status_form.vue'
import UserCard from '../user_card/user_card.vue'
import { mapState, mapGetters } from 'vuex'
const UserPanel = {
computed: {
signedIn () { return this.user },
authForm () {
- switch (this.authMethod) {
- case 'totp':
- return 'MFATOTPForm'
- case 'recovery':
- return 'MFARecoveryForm'
- default:
- return 'LoginForm'
- }
+ if (this.requiredTOTP) { return 'MFATOTPForm' }
+ if (this.requiredRecovery) { return 'MFARecoveryForm' }
+ return 'LoginForm'
},
- ...mapGetters({
- authMethod: 'authFlow/authMethod'
- }),
- ...mapState({
- user: state => state.users.currentUser
- })
+ ...mapGetters('authFlow', ['requiredTOTP', 'requiredRecovery']),
+ ...mapState({ user: state => state.users.currentUser })
},
components: {
MFARecoveryForm,
MFATOTPForm,
LoginForm,
PostStatusForm,
UserCard
}
}
export default UserPanel
diff --git a/src/modules/auth_flow.js b/src/modules/auth_flow.js
index a245117465..b03b4c90f2 100644
--- a/src/modules/auth_flow.js
+++ b/src/modules/auth_flow.js
@@ -1,60 +1,94 @@
+const PASSWORD_STRATEGY = 'password'
+const TOKEN_STRATEGY = 'token'
+
+// MFA strategies
+const TOTP_STRATEGY = 'totp'
+const RECOVERY_STRATEGY = 'recovery'
+
+
+const fetchStrategy = (state, rootState) => {
+ if (state.requiredMFA) {
+ return state.strategy || TOTP_STRATEGY
+ } else {
+ return state.strategy || rootState.instance.loginMethod || PASSWORD_STRATEGY
+ }
+}
+
// initial state
const state = {
app: null,
settings: {},
- stage: 'first', // first, second
- authMethod: 'password' // first (password, token), second (recovery, totp)
+ requiredMFA: false,
+ strategy: null
}
// getters
const getters = {
app: (state, getters) => {
return state.app
},
settings: (state, getters) => {
return state.settings
},
- authMethod: (state, getters, rootState) => {
- if (state.stage === 'first') {
- return state.authMethod || rootState.instance.loginMethod
- }
-
- if (state.stage === 'second') {
- return state.authMethod || 'totp'
- }
+ requiredPassword: (state, getters, rootState) => {
+ return fetchStrategy(state, rootState) === PASSWORD_STRATEGY
+ },
+ requiredToken: (state, getters, rootState) => {
+ return fetchStrategy(state, rootState) === TOKEN_STRATEGY
+ },
+ requiredTOTP: (state, getters, rootState) => {
+ return state.requiredMFA &&
+ fetchStrategy(state, rootState) === TOTP_STRATEGY
+ },
+ requiredRecovery: (state, getters, rootState) => {
+ return state.requiredMFA &&
+ fetchStrategy(state, rootState) === RECOVERY_STRATEGY
}
}
// mutations
const mutations = {
- setStage (state, {stage, authMethod, app, settings}) {
- state.stage = stage
- state.authMethod = authMethod
+ requirePassword (state) {
+ state.strategy = PASSWORD_STRATEGY
+ },
+ requireToken (state) {
+ state.strategy = TOKEN_STRATEGY
+ },
+ setupMFA (state, {app, settings}) { // sets MFA settings (token, supported strategies)
state.settings = settings
state.app = app
},
- setMethod (state, authMethod) {
- state.authMethod = authMethod
+ requireMFA (state) {
+ state.requiredMFA = true
+ state.strategy = TOTP_STRATEGY
+ },
+ requireRecovery (state) {
+ state.strategy = RECOVERY_STRATEGY
+ },
+ requireTOTP (state) {
+ state.strategy = TOTP_STRATEGY
+ },
+ reset (state) {
+ state.requiredMFA = false
+ state.strategy = null
+ state.settings = {}
+ state.app = null
}
}
// actions
const actions = {
async login ({state, dispatch, commit}, {access_token}) {
commit('setToken', access_token, { root: true })
await dispatch('loginUser', access_token, { root: true })
-
- state.stage = 'first'
- state.authMethod = 'password'
- state.settings = {}
- state.app = null
+ commit('reset')
}
}
export default {
namespaced: true,
state,
getters,
mutations,
actions
}

File Metadata

Mime Type
text/x-diff
Expires
Sat, Aug 29, 8:10 PM (1 d, 20 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1737314
Default Alt Text
(12 KB)

Event Timeline