You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ngcp-csc-ui/src/store/user.js

605 lines
21 KiB

'use strict'
import _ from 'lodash'
import QRCode from 'qrcode'
import { date } from 'quasar'
import {
apiDownloadFile,
httpApi
} from 'src/api/common'
import { callInitialize } from 'src/api/ngcp-call'
import {
changePassword,
changeSIPPassword,
createCustomerPhonebook,
createPhonebook,
generateGeneralPassword,
getBrandingLogo,
getCustomerPhonebook,
getNcosLevels,
getNcosSet,
getPreferences,
getSubscriberPhonebook,
getSubscriberProfile,
getSubscriberRegistrations,
recoverPassword,
resetPassword,
setPreference,
setValueName,
setValueNameCustomer,
setValueNumber,
setValueNumberCustomer,
setValueShared,
uploadCsv
} from 'src/api/subscriber'
import {
changeExpiredPassword,
createAuthToken,
getPreLoginPasswordInfo,
getUserData,
login
} from 'src/api/user'
import {
deleteJwt, getJwt, getSubscriberId, setJwt, setSubscriberId
} from 'src/auth'
import { PROFILE_ATTRIBUTE_MAP } from 'src/constants'
import { getSipInstanceId } from 'src/helpers/call-utils'
import { qrPayload } from 'src/helpers/qr'
import { PATH_CHANGE_PASSWORD } from 'src/router/routes'
import { setLocal } from 'src/storage'
import { RequestState } from 'src/store/common'
export default {
namespaced: true,
state: {
jwt: null,
subscriberId: null,
subscriber: null,
capabilities: null,
profile: null,
features: {
sendFax: true,
sendSms: false
},
loginRequesting: false,
loginSucceeded: false,
loginError: null,
userDataRequesting: false,
userDataSucceeded: false,
userDataError: null,
changePasswordState: RequestState.initiated,
changePasswordError: null,
newPasswordRequesting: false,
logo: null,
logoRequesting: false,
logoRequested: false,
resellerBranding: null,
defaultBranding: {},
subscriberRegistrations: [],
subscriberPhonebook: [],
customerPhonebook: [],
phonebookMap: {},
platformInfo: null,
qrCode: null,
qrExpiringTime: null
},
getters: {
isLogged (state) {
return !_.isEmpty(state.jwt) && !_.isEmpty(state.subscriberId)
},
hasUser (state) {
return state.subscriber !== null
},
getUsername (state) {
if (state.subscriber !== null && !_.isEmpty(state.subscriber.display_name)) {
return state.subscriber.display_name
} else if (state.subscriber !== null) {
return state.subscriber.webusername
}
return ''
},
isAdmin (state) {
return state.subscriber !== null && state.subscriber.administrative
},
isPbxAdmin (state, getters) {
return getters.isAdmin && state.capabilities !== null && state.capabilities.cloudpbx
},
isPbxEnabled (state) {
return state.capabilities !== null && state.capabilities.cloudpbx
},
hasSmsCapability (state) {
return state.capabilities !== null &&
state.capabilities.sms === true
},
hasSendSmsFeature (state) {
return state.features.sendSms
},
hasSendFaxFeature (state) {
return state.features.sendFax
},
hasFaxCapability (state) {
return state.capabilities !== null &&
state.capabilities.faxserver
},
hasFaxCapabilityAndFaxActive (state) {
return state.capabilities !== null &&
state.capabilities.faxserver &&
state.capabilities.faxactive
},
getSubscriberId (state) {
return state.subscriberId
},
loginRequesting (state, getters) {
return state.loginRequesting || getters.userDataRequesting
},
loginSucceeded (state, getters) {
return state.loginSucceeded && getters.userDataSucceeded
},
loginError (state) {
return state.loginError
},
passwordRequirements (state) {
return state.platformInfo?.security?.password || []
},
userDataRequesting (state) {
return state.userDataRequesting
},
userDataSucceeded (state) {
return state.userDataSucceeded
},
jwtTTL (state) {
const expirationBuffer = 0.05
try {
const jwtParts = getJwt().split('.')
const jwtPayload = JSON.parse(atob(jwtParts[1]))
if (_.isNumber(jwtPayload.exp)) {
const timeDiff = Math.floor((Date.now() / 1000) - jwtPayload.exp)
const timeLeft = Math.abs(timeDiff)
const timeLeftBuffer = Math.round(timeLeft * expirationBuffer)
return timeLeft - timeLeftBuffer
}
return null
} catch (err) {
return null
}
},
getSubscriber (state) {
return state.subscriber
},
getCustomerId (state) {
return state.subscriber?.customer_id
},
isPasswordChanging (state) {
return state.changePasswordState === RequestState.requesting
},
primaryNumber (state) {
if (state.subscriber === null) {
return null
}
return state.subscriber.primary_number
},
aliasNumbers (state) {
if (state.subscriber === null) {
return []
}
return state.subscriber.alias_numbers
},
isLogoRequesting (state) {
return state.logoRequesting
},
isLogoRequested (state) {
return state.logoRequested
},
hasSubscriberProfileAttribute: (state) => {
return (attribute) => {
return state.profile ? state.profile.attributes.includes(attribute) : true
}
},
hasSubscriberProfileAttributes: (state) => {
return (attributes) => {
return state.profile
? state.profile.attributes.some((item) => {
return attributes.includes(item)
})
: true
}
},
isOldCSCProxyingAllowed (state, getters) {
return getters.isAdmin && state.platformInfo?.csc_v2_mode === 'mixed' && !!getters.getCustomerId
},
isLicenseActive: (state) => {
return (license) => {
return state?.platformInfo.licenses.includes(license)
}
},
isPbxPilot (state) {
return !!state.subscriber?.is_pbx_pilot
},
isPbxGroup (state) {
return !!state.subscriber?.is_pbx_group
},
isPbxSeat (state, getters) {
return !getters.isPbxPilot && !getters.isPbxGroup && !!state.subscriber?.pbx_extension
},
isPbxAttendant (state, getters) {
return getters.isPbxPilot || getters.isPbxGroup || getters.isPbxSeat
},
isSpCe (state) {
return state.platformInfo.type === 'spce'
}
},
mutations: {
loginRequesting (state) {
state.loginRequesting = true
state.loginSucceeded = false
state.loginError = null
},
loginSucceeded (state, options) {
state.jwt = options.jwt
state.subscriberId = options.subscriberId
state.loginRequesting = false
state.loginSucceeded = true
state.loginError = null
},
loginFailed (state, error) {
state.loginRequesting = false
state.loginSucceeded = false
state.loginError = error
},
userDataRequesting (state) {
state.resellerBranding = null
state.userDataRequesting = true
state.userDataSucceeded = false
state.userDataError = null
},
userDataSucceeded (state, options) {
state.subscriber = options.subscriber
state.capabilities = options.capabilities
state.resellerBranding = options.resellerBranding
state.platformInfo = options.platformInfo
state.userDataSucceeded = true
state.userDataRequesting = false
state.userDataError = null
},
subscriberUpdateSucceeded (state, data) {
state.subscriber = data
},
userDataFailed (state, error) {
state.userDataError = error
state.userDataSucceeded = false
state.userDataRequesting = false
},
logout (state) {
state.jwt = null
state.subscriberId = null
state.subscriber = null
state.capabilities = null
state.loginRequesting = false
state.loginSucceeded = false
state.loginError = null
state.userDataRequesting = false
state.userDataSucceeded = false
state.userDataError = null
},
userPasswordRequesting (state) {
state.changePasswordState = RequestState.requesting
state.changePasswordError = null
},
userPasswordSucceeded (state) {
state.changePasswordState = RequestState.succeeded
state.changePasswordError = null
},
userPasswordFailed (state, error) {
state.changePasswordError = error
state.changePasswordState = RequestState.failed
},
newPasswordRequesting (state, isRequesting) {
state.newPasswordRequesting = isRequesting
},
updateLogo (state, value) {
state.logo = value
},
updateFaxActiveCapabilityState (state, value) {
state.capabilities.faxactive = value
},
updateLogoRequestState (state, isRequesting) {
state.logoRequesting = isRequesting
state.logoRequested = !isRequesting
},
setDefaultBranding (state, value) {
state.defaultBranding = value
},
setSubscriberRegistrations (state, value) {
state.subscriberRegistrations = value
},
setSubscriberPhonebook (state, value) {
state.subscriberPhonebook = value
},
setCustomerPhonebook (state, value) {
state.customerPhonebook = value
},
setProfile (state, value) {
state.profile = value
},
setQrCode (state, qrCode) {
state.qrCode = qrCode
},
setQrExpiringTime (state, qrExpiringTime) {
state.qrExpiringTime = qrExpiringTime
},
setPhonebookShared (state, { id, value }) {
const index = state.subscriberPhonebook.findIndex((row) => {
return row.id === id
})
if (index > -1) {
state.subscriberPhonebook[index].shared = value
}
}
},
actions: {
async login (context, options) {
context.commit('loginRequesting')
try {
const result = await login(options.username, options.password)
setJwt(result.jwt)
setSubscriberId(result.subscriberId)
context.commit('loginSucceeded', {
jwt: getJwt(),
subscriberId: getSubscriberId()
})
await context.dispatch('initUser')
await this.$router.push({ name: 'dashboard' })
} catch (err) {
context.commit('loginFailed', err.message)
if (err.message === 'Password expired') {
this.$router.push({ path: PATH_CHANGE_PASSWORD })
}
}
},
logout () {
deleteJwt()
document.location.href = document.location.pathname
},
async initUser (context) {
if (!context.getters.userDataSucceeded) {
try {
context.commit('userDataRequesting')
const userData = await getUserData(getSubscriberId())
context.commit('userDataSucceeded', userData)
if (_.isNumber(context.getters.jwtTTL)) {
setTimeout(() => {
setLocal('show_session_expired_msg', true)
context.dispatch('logout')
}, context.getters.jwtTTL * 1000)
}
if (userData.subscriber.profile_id) {
const profile = await getSubscriberProfile(userData.subscriber.profile_id)
context.commit('setProfile', profile)
}
if (context.getters.hasSubscriberProfileAttribute(PROFILE_ATTRIBUTE_MAP.cscCalls)) {
await callInitialize({
subscriber: userData.subscriber,
instanceId: getSipInstanceId()
})
}
} catch (err) {
await context.dispatch('logout')
throw err
}
}
},
async changeExpiredPassword (context, newPassword) {
context.commit('userPasswordRequesting')
try {
await changeExpiredPassword(newPassword)
} catch (error) {
return context.commit('userPasswordFailed', error)
}
context.commit('userPasswordSucceeded')
},
async changePassword (context, newPassword) {
const subscriberId = getSubscriberId()
await changePassword(subscriberId, newPassword)
await context.dispatch('logout')
},
async changeSIPPassword (context, newPassword) {
const subscriberId = getSubscriberId()
const subscriberData = await changeSIPPassword(subscriberId, newPassword)
context.commit('subscriberUpdateSucceeded', subscriberData)
},
async resetPassword ({ commit }, data) {
commit('newPasswordRequesting', true)
const response = await resetPassword(data)
commit('newPasswordRequesting', false)
return response
},
async recoverPassword ({ commit, dispatch, state, rootGetters }, data) {
commit('userPasswordRequesting')
try {
const res = await recoverPassword(data)
if (res.status === 200 || res.status === 201) {
commit('userPasswordSucceeded')
} else {
commit('userPasswordFailed')
}
} catch (err) {
commit('userPasswordFailed', err.message)
}
},
async getCustomLogo (context) {
if (!context.state.logo) {
context.commit('updateLogoRequestState', true)
context.commit('updateLogo', await getBrandingLogo(context.state.subscriberId))
context.commit('updateLogoRequestState', false)
}
return context.state.logo
},
setDefaultBranding (context, value) {
if (value) {
context.commit('setDefaultBranding', value)
}
},
async loadSubscriberRegistrations ({ commit, dispatch, state, rootGetters }, options) {
try {
const list = await getSubscriberRegistrations({
...options
})
commit('setSubscriberRegistrations', list.items)
return list.totalCount
} catch (err) {
commit('setSubscriberRegistrations', [])
throw err
}
},
async loadSubscriberPhonebook ({ commit, dispatch, state, rootGetters }, options) {
try {
const list = await getSubscriberPhonebook({
...options
})
commit('setSubscriberPhonebook', list.items)
return list.totalCount
} catch (err) {
commit('setSubscriberPhonebook', [])
throw err
}
},
async loadCustomerPhonebook ({ commit, dispatch, state, rootGetters }, options) {
try {
const list = await getCustomerPhonebook({
...options
})
commit('setCustomerPhonebook', list.items)
return list.totalCount
} catch (err) {
commit('setCustomerPhonebook', [])
throw err
}
},
async ajaxDownloadPhonebookCSV ({ commit }, customerId = 0) {
const apiGetOptions = {
resource: 'customerphonebookentries',
config: {
headers: {
Accept: 'text/csv'
},
params: {
customer_id: customerId
}
}
}
await apiDownloadFile({
apiGetOptions,
defaultFileName: 'customer_phonebook_entries.csv',
defaultContentType: 'text/csv'
})
},
async removeSubscriberRegistration (context, row) {
await httpApi.delete(`api/subscriberregistrations/${row.id}`)
},
async removeSubscriberPhonebook (context, row) {
await httpApi.delete(`api/subscriberphonebookentries/${row.id}`)
},
async removeCustomerPhonebook (context, row) {
await httpApi.delete(`api/customerphonebookentries/${row.id}`)
},
async getNcosLevelsSubscriber () {
const ncosLevel = []
const list = await getNcosLevels()
list.items.forEach((ncos) => {
ncosLevel.push({
label: ncos.level,
value: ncos.id
})
})
return ncosLevel
},
async getNcosSetSubscriber () {
const ncosSet = []
const list = await getNcosSet()
list.forEach((setNcos) => {
ncosSet.push({
label: setNcos.name,
value: setNcos.id
})
})
return ncosSet
},
async getCurrentNcosLevelsSubscriber () {
const list = await getPreferences(getSubscriberId())
const currentNcosLevel = list.ncos
return currentNcosLevel
},
async getCurrentNcosSetSubscriber () {
const list = await getPreferences(getSubscriberId())
const currentNcosSet = list.ncos_set
return currentNcosSet
},
async setNcosLevelsSubscriber (value) {
await setPreference(getSubscriberId(), 'ncos', value)
},
async getPhonebookDetails (context, id) {
const list = await httpApi.get(`api/subscriberphonebookentries/${id}`)
return list
},
async getPhonebookCustomerDetails (context, id) {
const list = await httpApi.get(`api/customerphonebookentries/${id}`)
return list
},
async getValueShared (context, options) {
await setValueShared(options.phonebookId, options.shared)
},
async updateValueShared (context, row) {
context.commit('setPhonebookShared', { id: row.id, value: !row.shared })
await setValueShared(row.id, row.shared)
},
async getValueName (context, options) {
await setValueName(options.phonebookId, options.name)
},
async getValueNameCustomer (context, options) {
await setValueNameCustomer(options.phonebookId, options.name)
},
async getValueNumber (context, options) {
await setValueNumber(options.phonebookId, options.number)
},
async getValueNumberCustomer (context, options) {
await setValueNumberCustomer(options.phonebookId, options.number)
},
async createPhonebookSubscriber (context, data) {
await createPhonebook(data)
},
async createPhonebookCustomer (context, data) {
await createCustomerPhonebook(data)
},
async uploadPhonebookCustomer (context, data) {
await uploadCsv(context, data)
},
async fetchAuthToken ({ commit, state, getters }, expiringTime = 300) {
const subscriber = state.subscriber
const expireDate = date.addToDate(new Date(), { seconds: expiringTime })
commit('setQrExpiringTime', expiringTime)
try {
const authToken = await createAuthToken(expiringTime)
const data = qrPayload({
subscriber: subscriber.username,
server: subscriber.domain,
expire: expireDate.getTime(),
token: authToken
})
const qrCode = await QRCode.toDataURL(data)
commit('setQrCode', qrCode)
} catch (err) {
commit('setQrCode', null)
}
},
async fetchPreLoginPasswordInfo () {
return await getPreLoginPasswordInfo()
},
async generatePasswordUser () {
const password = await generateGeneralPassword()
return password
}
}
}