Migrate auth flow module to pinia store
This commit is contained in:
parent
60e5c3b042
commit
4ee26c6041
8 changed files with 91 additions and 110 deletions
|
|
@ -21,6 +21,7 @@ import { useOAuthStore } from 'src/stores/oauth'
|
||||||
import { useI18nStore } from 'src/stores/i18n'
|
import { useI18nStore } from 'src/stores/i18n'
|
||||||
import { useInterfaceStore } from 'src/stores/interface'
|
import { useInterfaceStore } from 'src/stores/interface'
|
||||||
import { useAnnouncementsStore } from 'src/stores/announcements'
|
import { useAnnouncementsStore } from 'src/stores/announcements'
|
||||||
|
import { useAuthFlowStore } from 'src/stores/auth_flow'
|
||||||
|
|
||||||
let staticInitialResults = null
|
let staticInitialResults = null
|
||||||
|
|
||||||
|
|
@ -153,7 +154,7 @@ const setSettings = async ({ apiConfig, staticConfig, store }) => {
|
||||||
: config.logoMargin
|
: config.logoMargin
|
||||||
})
|
})
|
||||||
copyInstanceOption('logoLeft')
|
copyInstanceOption('logoLeft')
|
||||||
store.commit('authFlow/setInitialStrategy', config.loginMethod)
|
useAuthFlowStore().setInitialStrategy(config.loginMethod)
|
||||||
|
|
||||||
copyInstanceOption('redirectRootNoLogin')
|
copyInstanceOption('redirectRootNoLogin')
|
||||||
copyInstanceOption('redirectRootLogin')
|
copyInstanceOption('redirectRootLogin')
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,8 @@ import { h, resolveComponent } from 'vue'
|
||||||
import LoginForm from '../login_form/login_form.vue'
|
import LoginForm from '../login_form/login_form.vue'
|
||||||
import MFARecoveryForm from '../mfa_form/recovery_form.vue'
|
import MFARecoveryForm from '../mfa_form/recovery_form.vue'
|
||||||
import MFATOTPForm from '../mfa_form/totp_form.vue'
|
import MFATOTPForm from '../mfa_form/totp_form.vue'
|
||||||
import { mapGetters } from 'vuex'
|
import { mapState } from 'pinia'
|
||||||
|
import { useAuthFlowStore } from 'src/stores/auth_flow'
|
||||||
|
|
||||||
const AuthForm = {
|
const AuthForm = {
|
||||||
name: 'AuthForm',
|
name: 'AuthForm',
|
||||||
|
|
@ -15,7 +16,7 @@ const AuthForm = {
|
||||||
if (this.requiredRecovery) { return 'MFARecoveryForm' }
|
if (this.requiredRecovery) { return 'MFARecoveryForm' }
|
||||||
return 'LoginForm'
|
return 'LoginForm'
|
||||||
},
|
},
|
||||||
...mapGetters('authFlow', ['requiredTOTP', 'requiredRecovery'])
|
...mapState(useAuthFlowStore, ['requiredTOTP', 'requiredRecovery'])
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
MFARecoveryForm,
|
MFARecoveryForm,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import { mapState, mapGetters, mapActions, mapMutations } from 'vuex'
|
import { mapState } from 'vuex'
|
||||||
import { mapStores } from 'pinia'
|
import { mapStores, mapActions, mapState as mapPiniaState } from 'pinia'
|
||||||
import oauthApi from '../../services/new_api/oauth.js'
|
import oauthApi from '../../services/new_api/oauth.js'
|
||||||
import { useOAuthStore } from 'src/stores/oauth.js'
|
import { useOAuthStore } from 'src/stores/oauth.js'
|
||||||
|
import { useAuthFlowStore } from 'src/stores/auth_flow.js'
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
faTimes
|
faTimes
|
||||||
|
|
@ -25,13 +26,10 @@ const LoginForm = {
|
||||||
instance: state => state.instance,
|
instance: state => state.instance,
|
||||||
loggingIn: state => state.users.loggingIn,
|
loggingIn: state => state.users.loggingIn,
|
||||||
}),
|
}),
|
||||||
...mapGetters(
|
...mapPiniaState(useAuthFlowStore, ['requiredPassword', 'requiredToken', 'requiredMFA'])
|
||||||
'authFlow', ['requiredPassword', 'requiredToken', 'requiredMFA']
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapMutations('authFlow', ['requireMFA']),
|
...mapActions(useAuthFlowStore, ['requireMFA', 'login']),
|
||||||
...mapActions({ login: 'authFlow/login' }),
|
|
||||||
submit () {
|
submit () {
|
||||||
this.isTokenAuth ? this.submitToken() : this.submitPassword()
|
this.isTokenAuth ? this.submitToken() : this.submitPassword()
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import mfaApi from '../../services/new_api/mfa.js'
|
import mfaApi from '../../services/new_api/mfa.js'
|
||||||
import { mapState, mapGetters, mapActions, mapMutations } from 'vuex'
|
import { mapState } from 'vuex'
|
||||||
import { mapStores } from 'pinia'
|
import { mapStores, mapActions, mapState as mapPiniaState } from 'pinia'
|
||||||
import { useOAuthStore } from 'src/stores/oauth.js'
|
import { useOAuthStore } from 'src/stores/oauth.js'
|
||||||
|
import { useAuthFlowStore } from 'src/stores/auth_flow.js'
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
faTimes
|
faTimes
|
||||||
|
|
@ -17,8 +18,8 @@ export default {
|
||||||
error: false
|
error: false
|
||||||
}),
|
}),
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({
|
...mapPiniaState(useAuthFlowStore, {
|
||||||
authSettings: 'authFlow/settings'
|
authSettings: store => store.settings
|
||||||
}),
|
}),
|
||||||
...mapStores(useOAuthStore),
|
...mapStores(useOAuthStore),
|
||||||
...mapState({
|
...mapState({
|
||||||
|
|
@ -26,8 +27,7 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapMutations('authFlow', ['requireTOTP', 'abortMFA']),
|
...mapActions(useAuthFlowStore, ['requireTOTP', 'abortMFA', 'login']),
|
||||||
...mapActions({ login: 'authFlow/login' }),
|
|
||||||
clearError () { this.error = false },
|
clearError () { this.error = false },
|
||||||
|
|
||||||
focusOnCodeInput () {
|
focusOnCodeInput () {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import mfaApi from '../../services/new_api/mfa.js'
|
import mfaApi from '../../services/new_api/mfa.js'
|
||||||
import { mapState, mapGetters, mapActions, mapMutations } from 'vuex'
|
import { mapState } from 'vuex'
|
||||||
import { mapStores } from 'pinia'
|
import { mapStores, mapActions, mapState as mapPiniaState } from 'pinia'
|
||||||
import { useOAuthStore } from 'src/stores/oauth.js'
|
import { useOAuthStore } from 'src/stores/oauth.js'
|
||||||
|
import { useAuthFlowStore } from 'src/stores/auth_flow.js'
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
faTimes
|
faTimes
|
||||||
|
|
@ -17,8 +18,8 @@ export default {
|
||||||
error: false
|
error: false
|
||||||
}),
|
}),
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({
|
...mapPiniaState(useAuthFlowStore, {
|
||||||
authSettings: 'authFlow/settings'
|
authSettings: store => store.settings
|
||||||
}),
|
}),
|
||||||
...mapStores(useOAuthStore),
|
...mapStores(useOAuthStore),
|
||||||
...mapState({
|
...mapState({
|
||||||
|
|
@ -26,8 +27,7 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapMutations('authFlow', ['requireRecovery', 'abortMFA']),
|
...mapActions(useAuthFlowStore, ['requireRecovery', 'abortMFA', 'login']),
|
||||||
...mapActions({ login: 'authFlow/login' }),
|
|
||||||
clearError () { this.error = false },
|
clearError () { this.error = false },
|
||||||
|
|
||||||
focusOnCodeInput () {
|
focusOnCodeInput () {
|
||||||
|
|
|
||||||
|
|
@ -1,86 +0,0 @@
|
||||||
import { useOAuthStore } from 'src/stores/oauth.js'
|
|
||||||
|
|
||||||
const PASSWORD_STRATEGY = 'password'
|
|
||||||
const TOKEN_STRATEGY = 'token'
|
|
||||||
|
|
||||||
// MFA strategies
|
|
||||||
const TOTP_STRATEGY = 'totp'
|
|
||||||
const RECOVERY_STRATEGY = 'recovery'
|
|
||||||
|
|
||||||
// initial state
|
|
||||||
const state = {
|
|
||||||
settings: {},
|
|
||||||
strategy: PASSWORD_STRATEGY,
|
|
||||||
initStrategy: PASSWORD_STRATEGY // default strategy from config
|
|
||||||
}
|
|
||||||
|
|
||||||
const resetState = (state) => {
|
|
||||||
state.strategy = state.initStrategy
|
|
||||||
state.settings = {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// getters
|
|
||||||
const getters = {
|
|
||||||
settings: (state) => {
|
|
||||||
return state.settings
|
|
||||||
},
|
|
||||||
requiredPassword: (state) => {
|
|
||||||
return state.strategy === PASSWORD_STRATEGY
|
|
||||||
},
|
|
||||||
requiredToken: (state) => {
|
|
||||||
return state.strategy === TOKEN_STRATEGY
|
|
||||||
},
|
|
||||||
requiredTOTP: (state) => {
|
|
||||||
return state.strategy === TOTP_STRATEGY
|
|
||||||
},
|
|
||||||
requiredRecovery: (state) => {
|
|
||||||
return state.strategy === RECOVERY_STRATEGY
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// mutations
|
|
||||||
const mutations = {
|
|
||||||
setInitialStrategy (state, strategy) {
|
|
||||||
if (strategy) {
|
|
||||||
state.initStrategy = strategy
|
|
||||||
state.strategy = strategy
|
|
||||||
}
|
|
||||||
},
|
|
||||||
requirePassword (state) {
|
|
||||||
state.strategy = PASSWORD_STRATEGY
|
|
||||||
},
|
|
||||||
requireToken (state) {
|
|
||||||
state.strategy = TOKEN_STRATEGY
|
|
||||||
},
|
|
||||||
requireMFA (state, { settings }) {
|
|
||||||
state.settings = settings
|
|
||||||
state.strategy = TOTP_STRATEGY // default strategy of MFA
|
|
||||||
},
|
|
||||||
requireRecovery (state) {
|
|
||||||
state.strategy = RECOVERY_STRATEGY
|
|
||||||
},
|
|
||||||
requireTOTP (state) {
|
|
||||||
state.strategy = TOTP_STRATEGY
|
|
||||||
},
|
|
||||||
abortMFA (state) {
|
|
||||||
resetState(state)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// actions
|
|
||||||
const actions = {
|
|
||||||
|
|
||||||
async login ({ state, dispatch }, { access_token: accessToken }) {
|
|
||||||
useOAuthStore().setToken(accessToken)
|
|
||||||
await dispatch('loginUser', accessToken, { root: true })
|
|
||||||
resetState(state)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
namespaced: true,
|
|
||||||
state,
|
|
||||||
getters,
|
|
||||||
mutations,
|
|
||||||
actions
|
|
||||||
}
|
|
||||||
|
|
@ -6,7 +6,6 @@ import api from './api.js'
|
||||||
import config from './config.js'
|
import config from './config.js'
|
||||||
import profileConfig from './profileConfig.js'
|
import profileConfig from './profileConfig.js'
|
||||||
import adminSettings from './adminSettings.js'
|
import adminSettings from './adminSettings.js'
|
||||||
import authFlow from './auth_flow.js'
|
|
||||||
import drafts from './drafts.js'
|
import drafts from './drafts.js'
|
||||||
import chats from './chats.js'
|
import chats from './chats.js'
|
||||||
|
|
||||||
|
|
@ -19,7 +18,6 @@ export default {
|
||||||
config,
|
config,
|
||||||
profileConfig,
|
profileConfig,
|
||||||
adminSettings,
|
adminSettings,
|
||||||
authFlow,
|
|
||||||
drafts,
|
drafts,
|
||||||
chats
|
chats
|
||||||
}
|
}
|
||||||
|
|
|
||||||
69
src/stores/auth_flow.js
Normal file
69
src/stores/auth_flow.js
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
import { useOAuthStore } from 'src/stores/oauth.js'
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
|
const PASSWORD_STRATEGY = 'password'
|
||||||
|
const TOKEN_STRATEGY = 'token'
|
||||||
|
|
||||||
|
// MFA strategies
|
||||||
|
const TOTP_STRATEGY = 'totp'
|
||||||
|
const RECOVERY_STRATEGY = 'recovery'
|
||||||
|
|
||||||
|
export const useAuthFlowStore = defineStore('authFlow', {
|
||||||
|
// initial state
|
||||||
|
state: () => ({
|
||||||
|
settings: {},
|
||||||
|
strategy: PASSWORD_STRATEGY,
|
||||||
|
initStrategy: PASSWORD_STRATEGY // default strategy from config
|
||||||
|
}),
|
||||||
|
// getters
|
||||||
|
getters: {
|
||||||
|
requiredPassword: (state) => {
|
||||||
|
return state.strategy === PASSWORD_STRATEGY
|
||||||
|
},
|
||||||
|
requiredToken: (state) => {
|
||||||
|
return state.strategy === TOKEN_STRATEGY
|
||||||
|
},
|
||||||
|
requiredTOTP: (state) => {
|
||||||
|
return state.strategy === TOTP_STRATEGY
|
||||||
|
},
|
||||||
|
requiredRecovery: (state) => {
|
||||||
|
return state.strategy === RECOVERY_STRATEGY
|
||||||
|
},
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
setInitialStrategy (strategy) {
|
||||||
|
if (strategy) {
|
||||||
|
this.initStrategy = strategy
|
||||||
|
this.strategy = strategy
|
||||||
|
}
|
||||||
|
},
|
||||||
|
requirePassword () {
|
||||||
|
this.strategy = PASSWORD_STRATEGY
|
||||||
|
},
|
||||||
|
requireToken () {
|
||||||
|
this.strategy = TOKEN_STRATEGY
|
||||||
|
},
|
||||||
|
requireMFA ({ settings }) {
|
||||||
|
this.settings = settings
|
||||||
|
this.strategy = TOTP_STRATEGY // default strategy of MFA
|
||||||
|
},
|
||||||
|
requireRecovery () {
|
||||||
|
this.strategy = RECOVERY_STRATEGY
|
||||||
|
},
|
||||||
|
requireTOTP () {
|
||||||
|
this.strategy = TOTP_STRATEGY
|
||||||
|
},
|
||||||
|
abortMFA () {
|
||||||
|
this.resetState()
|
||||||
|
},
|
||||||
|
resetState () {
|
||||||
|
this.strategy = this.initStrategy
|
||||||
|
this.settings = {}
|
||||||
|
},
|
||||||
|
async login ({ access_token: accessToken }) {
|
||||||
|
useOAuthStore().setToken(accessToken)
|
||||||
|
await window.vuex.dispatch('loginUser', accessToken, { root: true })
|
||||||
|
this.resetState()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
Loading…
Add table
Add a link
Reference in a new issue