@hperchec/scorpion-ui-template-default
Version:
Scorpion UI - Default template
299 lines (295 loc) • 10.8 kB
JavaScript
import { Core, utils } from '@hperchec/scorpion-ui'
const { safeAsync } = utils
const log = (msg) => Core.context.services['store'].options.log(`"Auth" module: ${msg}`, { type: 'store' }) // eslint-disable-line dot-notation
const logError = (msg) => Core.context.services['store'].options.log(`Store "Auth" module: ${msg}`, { type: 'error' }) // eslint-disable-line dot-notation
/**
* Auth
* @alias module:store/modules/Auth
* @type {Object}
*/
export default {
/**
* @private
*/
namespaced: true,
/**
* state
* @type {Object}
* @readonly
* @description Store module state
* @example
* // Access to the module state
* Store.state.Core.Auth
*/
state: {
/**
* currentUser
* @description Current / Authenticated User
* @type {?User}
* @default null
*/
currentUser: null, // default guest
/**
* currentUserLoading
* @description Indicates if current user is loading from API
* @type {boolean}
* @default false
*/
currentUserLoading: false,
/**
* passwordForSecurity
* @description When user enter password for securized features
* @type {string}
* @default '' (empty string)
*/
passwordForSecurity: ''
},
/**
* getters
* @type {Object}
* @readonly
* @description Store module getters
* @example
* // Access to the module getters, where <name> is the getter name
* Store.getters['Core/Auth/<name>']
*/
getters: {
// Nothing here...
},
/**
* actions
* @type {Object}
* @protected
* @description Store module actions
* @example
* // Access to the module action, where <name> is the action name
* Store.dispatch('Core/Auth/<name>')
*/
actions: {
/**
* login
* @description Request `[POST] /api/login` with credentials data.
* If server side success, save tokens in LocalStorage and dispatch 'check'
* @param {Object} context - vuex context
* @param {Object} payload - Method payload
* @param {Object} payload.data - Request data
* @param {string} payload.data.username - Username
* @param {string} payload.data.password - Password
* @return {(boolean|Error)} Return value of 'check'
*/
login: async function ({ commit, dispatch }, { data }) {
const ServerAPI = Core.service('api-manager').use('ServerAPI')
const localStorageManager = Core.context.services['store'].options.localStorageManager() // eslint-disable-line dot-notation
// Set currentUserLoading to true
commit('SET_CURRENT_USER_LOADING', true)
// Define URL
const method = 'POST'
const path = '/login'
const url = `${ServerAPI.options.baseURL}${path}`
log(`Login request - Request [${method}] "${url}" ...`)
// Request server
const response = await safeAsync(() => ServerAPI.request(method, path, {
data: data
}))
// Set currentUserLoading to false
commit('SET_CURRENT_USER_LOADING', false)
// If error
if (response instanceof Error) {
logError(`Login request error - Server response [${method}] "${url}" ...`)
// Return error
return response
}
// Everything is okay
const accessToken = response.data.access_token
// const refreshToken = response.data.refresh_token
log('Set access token in localStorage')
// Save tokens in localStorage
localStorageManager.items[Core.config.auth.accessTokenKey] = accessToken
// localStorageManager.items[Core.config.auth.refreshTokenKey] = refreshToken
// Get user
return dispatch('check')
},
/**
* logout
* @description Remove tokens from the local storage and reset current user
* @param {Object} context - vuex context
* @return {void}
*/
logout: async function ({ commit }) {
const ServerAPI = Core.service('api-manager').use('ServerAPI')
const localStorageManager = Core.context.services['store'].options.localStorageManager() // eslint-disable-line dot-notation
// Set currentUserLoading to true
commit('SET_CURRENT_USER_LOADING', true)
// Define URL
const method = 'POST'
const path = '/logout'
const url = `${ServerAPI.options.baseURL}${path}`
log(`Logout request - Request [${method}] "${url}" ...`)
// Request server
const response = await safeAsync(() => ServerAPI.request(method, path))
// Set currentUserLoading to false
commit('SET_CURRENT_USER_LOADING', false)
// If error
if (response instanceof Error) {
logError(`Logout request error - Server response [${method}] "${url}" ...`)
// Return error
return response
}
// Everything is okay
log('Remove tokens from localStorage')
// Remove access token
delete localStorageManager.items[Core.config.auth.accessTokenKey]
delete localStorageManager.items[Core.config.auth.refreshTokenKey]
// Reset currentUser
commit('RESET_CURRENT_USER')
},
/**
* check
* @description Check if user is authenticated.
* First, check if token is set in the local storage,
* set authorization header and request for user data from server.
* Else, call 'logout' and return false.
* @param {Object} context - vuex context
* @return {(boolean|Error)} False or return value of 'loadCurrentUserData'
*/
check: async function ({ commit, dispatch }) {
const localStorageManager = Core.context.services['store'].options.localStorageManager() // eslint-disable-line dot-notation
log('Check access token in localStorage...')
// Retrieve token in localStorage
const accessToken = localStorageManager.items[Core.config.auth.accessTokenKey]
// const refreshToken = localStorageManager.items[Core.config.auth.refreshTokenKey]
// If no access token
if (!accessToken) {
log('Not authenticated ❌')
return false
}
log('Access token found ✔')
// Set token to headers for each future requests
dispatch('setAuthorizationHeader', { token: accessToken })
// Get User data
return dispatch('loadCurrentUserData')
},
/**
* loadCurrentUserData
* @description Load current user data from API server.
* Request `[GET] /api/me` (See [API Server documentation](/guide/system/api-server/)).
* @param {Object} context - vuex context
* @return {(boolean|Error)} If success: true, else Error
*/
loadCurrentUserData: async function ({ commit, dispatch }) {
const ServerAPI = Core.service('api-manager').use('ServerAPI')
// Set currentUserLoading to true
commit('SET_CURRENT_USER_LOADING', true)
// Define URL
const method = 'GET'
const path = '/me'
const url = `${ServerAPI.options.baseURL}${path}`
log(`Load current user data - Request [${method}] "${url}" ...`)
// Request server
const response = await safeAsync(() => ServerAPI.request(method, path))
// Set currentUserLoading to false
commit('SET_CURRENT_USER_LOADING', false)
// If error
if (response instanceof Error) {
// Authentication token error
logError(`Authentication token error - Server response [${method}] "${url}" ...`)
// Remove token and reset user
dispatch('logout')
// Return error
return response
}
// Everything is okay
// Set user in state
commit('SET_CURRENT_USER', response.data)
log('Authenticated ✔')
// Return true
return true
},
/**
* setAuthorizationHeader
* @description Set the authorization token header for the API instance (ServerAPI).
* @param {Object} context - vuex context
* @param {Object} payload - Method payload
* @param {string} payload.token - The access token
* @return {void}
*/
setAuthorizationHeader: function ({ commit }, { token }) {
const ServerAPI = Core.service('api-manager').use('ServerAPI')
log('Set authorization headers (token) for future requests to Server API')
// Set authorization token
ServerAPI.driver.defaults.headers.common.Authorization = `Bearer ${token}`
},
/**
* resetAuthorizationHeader
* @description Delete the authorization token header for the API instance (ServerAPI).
* @param {Object} context - vuex context
* @return {void}
*/
resetAuthorizationHeader ({ commit }) {
const ServerAPI = Core.service('api-manager').use('ServerAPI')
log('Reset authorization headers of Server API')
// Delete header
delete ServerAPI.driver.defaults.headers.common.Authorization
}
},
/**
* mutations
* @type {Object}
* @protected
* @description Store module mutations
* @example
* // Dispatch a module mutation, where <mutation_name> is the mutation name
* Store.commit('Auth/<mutation_name>', [payload])
*/
mutations: {
/**
* SET_CURRENT_USER
* @description Mutate state.currentUser
* @param {Object} state - vuex store state
* @param {Object} user - Data received from server
* @return {void}
*/
SET_CURRENT_USER (state, user) {
state.currentUser = new Core.context.models.User(user)
state.currentUser.authenticated = true
},
/**
* RESET_CURRENT_USER
* @description Mutate state.currentUser
* @param {Object} state - vuex store state
* @return {void}
*/
RESET_CURRENT_USER (state) {
state.currentUser = new Core.context.models.User()
},
/**
* SET_CURRENT_USER_LOADING
* @description Mutate state.currentUserLoading
* @param {Object} state - vuex store state
* @param {boolean} value - True or false
* @return {void}
*/
SET_CURRENT_USER_LOADING (state, value) {
state.currentUserLoading = value
},
/**
* SET_PASSWORD_FOR_SECURITY
* @description Mutate state.passwordForSecurity
* @param {Object} state - vuex store state
* @param {string} value - Password
* @return {void}
*/
SET_PASSWORD_FOR_SECURITY (state, value) {
state.passwordForSecurity = value
},
/**
* RESET_PASSWORD_FOR_SECURITY
* @description Mutate state.passwordForSecurity
* @param {Object} state - vuex store state
* @return {void}
*/
RESET_PASSWORD_FOR_SECURITY (state) {
state.passwordForSecurity = ''
}
}
}