diff --git a/src/api/pbx-config.js b/src/api/pbx-config.js index 210c0526..218689a8 100644 --- a/src/api/pbx-config.js +++ b/src/api/pbx-config.js @@ -3,9 +3,6 @@ import _ from 'lodash' import { getSubscribers } from './subscriber' -import { - v4 -} from 'uuid' import { getList, get, @@ -14,7 +11,6 @@ import { httpApi } from './common' -export const createId = v4 export const PBX_CONFIG_ORDER_BY = 'create_timestamp' export const PBX_CONFIG_ORDER_DIRECTION = 'desc' diff --git a/src/api/pbx-groups.js b/src/api/pbx-groups.js index 72a4abf6..6a26b4a4 100644 --- a/src/api/pbx-groups.js +++ b/src/api/pbx-groups.js @@ -9,13 +9,13 @@ import { setPbxExtension, setPbxGroupMemberIds, setPbxHuntPolicy, setPbxHuntTimeout, setSubscriberNumbers, - setPbxHuntCancelMode + setPbxHuntCancelMode, + generateGeneralPassword } from './subscriber' import { getAllSoundSets, getPilot, getSoundSet, - createId, PBX_CONFIG_ORDER_BY, PBX_CONFIG_ORDER_DIRECTION, setSubscriberSoundSet @@ -114,13 +114,14 @@ export function getGroupList (options) { }) } -export function createGroup (group) { +export async function createGroup (group) { + const generatePassword = await generateGeneralPassword() return new Promise((resolve, reject) => { let subscriberId Promise.resolve().then(() => { return createSubscriber({ username: createUsername(group.name), - password: createId(), + password: generatePassword, is_pbx_group: true, display_name: group.name, pbx_extension: group.extension, diff --git a/src/api/pbx-seats.js b/src/api/pbx-seats.js index fa9e7e56..fc5b5861 100644 --- a/src/api/pbx-seats.js +++ b/src/api/pbx-seats.js @@ -20,14 +20,14 @@ import { setPreferenceAnnouncementToCallee, setPreferenceIgnoreCfWhenHunting, setPreferenceCstaClient, - setPreferenceCstaController + setPreferenceCstaController, + generateGeneralPassword } from './subscriber' import _ from 'lodash' import { getAllSoundSets, getPilot, getSoundSet, - createId, PBX_CONFIG_ORDER_BY, PBX_CONFIG_ORDER_DIRECTION, setSubscriberSoundSet, @@ -142,7 +142,8 @@ export function getSeatList (options) { }) } -export function createSeat (seat) { +export async function createSeat (seat) { + const generatePassword = await generateGeneralPassword() return new Promise((resolve, reject) => { let subscriberId Promise.resolve().then(() => { @@ -150,7 +151,7 @@ export function createSeat (seat) { username: seat.sipUsername.trim(), display_name: seat.displayName.trim(), webusername: seat.webUsername.trim(), - password: seat.sipPassword ? seat.sipPassword : createId(), + password: seat.sipPassword ? seat.sipPassword : generatePassword, webpassword: seat.webPassword.length > 0 ? seat.webPassword : null, is_pbx_group: false, pbx_extension: seat.extension, diff --git a/src/api/subscriber.js b/src/api/subscriber.js index 4548be80..efd5fc5c 100644 --- a/src/api/subscriber.js +++ b/src/api/subscriber.js @@ -20,6 +20,13 @@ import { assignNumbers } from './user' +const minValue = 3 +const generateSymbols = '!@#$%^&*()_+~`|}{[]:;?><,./-=' +const generateNumbers = '0123456789' +const generateLowercase = 'abcdefghijklmnopqrstuvwxyz' +const generateUppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +const generateLength = 12 + export function getPreferences (id) { return new Promise((resolve, reject) => { httpApi.get('api/subscriberpreferences/' + id).then((result) => { @@ -910,3 +917,33 @@ export function setCustomerPreference (customerId, customerValue, fieldName) { }) }) } + +export async function generateGeneralPassword () { + const getRandomValues = (buf) => crypto.getRandomValues(buf) + const getRandomInt = (max) => { + const randomBuffer = new Uint32Array(1) + getRandomValues(randomBuffer) + return Math.floor(randomBuffer[0] / (0xFFFFFFFF + 1) * max) + } + const getRandomChar = (charset) => charset[getRandomInt(charset.length)] + + const charGroups = [ + generateNumbers, + generateLowercase, + generateUppercase, + generateSymbols + ] + + let password = charGroups.flatMap(group => + Array.from({ length: minValue }, () => getRandomChar(group)) + ).join('') + + while (password.length < generateLength) { + const allChars = charGroups.join('') + password += getRandomChar(allChars) + } + + password = password.split('').sort(() => getRandomInt(2) - 0.5).join('') + + return password +} diff --git a/src/components/form/CscInputPassword.vue b/src/components/form/CscInputPassword.vue index 21658dab..c5ec119d 100644 --- a/src/components/form/CscInputPassword.vue +++ b/src/components/form/CscInputPassword.vue @@ -45,9 +45,10 @@ </template> </csc-input> </template> + <script> import CscInput from 'components/form/CscInput' -import PasswordGenerator from 'generate-password' +import { mapWaitingActions } from 'vue-wait' export default { name: 'CscInputPassword', components: { CscInput }, @@ -55,38 +56,6 @@ export default { generate: { type: Boolean, default: false - }, - generateLength: { - type: Number, - default: 10 - }, - generateNumbers: { - type: Boolean, - default: true - }, - generateLowercase: { - type: Boolean, - default: true - }, - generateUppercase: { - type: Boolean, - default: true - }, - generateSymbols: { - type: Boolean, - default: false - }, - generateExcludeSimilarCharacters: { - type: Boolean, - default: false - }, - generateExclude: { - type: String, - default: '' - }, - generateStrict: { - type: Boolean, - default: true } }, emits: ['generated', 'update:modelValue'], @@ -97,34 +66,20 @@ export default { }, computed: { inputType () { - if (this.visible) { - return 'text' - } else { - return 'password' - } + return this.visible ? 'text' : 'password' }, visibilityIcon () { - if (!this.visible) { - return 'visibility_off' - } else { - return 'visibility' - } + return this.visible ? 'visibility' : 'visibility_off' } }, methods: { - generatePassword () { - const pass = PasswordGenerator.generate({ - length: this.generateLength, - numbers: this.generateNumbers, - lowercase: this.generateLowercase, - uppercase: this.generateUppercase, - symbols: this.generateSymbols, - excludeSimilarCharacters: this.generateExcludeSimilarCharacters, - exclude: this.generateExclude, - strict: this.generateStrict - }) - this.$emit('update:modelValue', pass) - this.$emit('generated', pass) + ...mapWaitingActions('user', { + generatePasswordUser: 'generatePasswordUser' + }), + async generatePassword () { + const password = await this.generatePasswordUser() + this.$emit('update:modelValue', password) + this.$emit('generated', password) }, toggleVisibility () { this.visible = !this.visible diff --git a/src/store/user.js b/src/store/user.js index 85540bbc..6669a281 100644 --- a/src/store/user.js +++ b/src/store/user.js @@ -29,7 +29,8 @@ import { getNcosLevels, getNcosSet, getPreferences, - setPreference + setPreference, + generateGeneralPassword } from '../api/subscriber' import { deleteJwt, getJwt, getSubscriberId, setJwt, setSubscriberId } from 'src/auth' import QRCode from 'qrcode' @@ -567,6 +568,11 @@ export default { } catch (err) { commit('setQrCode', null) } + }, + async generatePasswordUser () { + const password = await generateGeneralPassword() + + return password } } }