Compare commits
20 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0a38ac6035 | ||
|
|
83de989e97 | ||
|
|
a954c845cf | ||
|
|
a0bb249ebc | ||
|
|
50015218a6 | ||
|
|
465fef3ca8 | ||
|
|
156f121fcc | ||
|
|
948a28f1d6 | ||
|
|
2e1ed82538 | ||
|
|
5a0c18e434 | ||
|
|
95e1c66570 | ||
|
|
5b56bcdb08 | ||
|
|
a36742d485 | ||
|
|
2c265e4eb6 | ||
|
|
1f0b14d326 | ||
|
|
0abddc846b | ||
|
|
cdda6bb8bf | ||
|
|
7c29db35e4 | ||
|
|
15411c9744 | ||
|
|
d0040c6c1f |
|
|
@ -303,5 +303,10 @@ module.exports = [
|
|||
"type": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "reset",
|
||||
"description": "Reset or change your extension password", // Opens a modal to reset password
|
||||
"type": 1
|
||||
}
|
||||
]
|
||||
49
freepbx.js
49
freepbx.js
|
|
@ -155,24 +155,45 @@ class FreepbxManager {
|
|||
return await this.pbxCall(query);
|
||||
}
|
||||
|
||||
// async updateName(ext, name) {
|
||||
// const query = gql`
|
||||
// mutation updateName($ext: ID!, $name: String!) {
|
||||
// updateExtension(input: {extensionId: $ext, name: $name}) {
|
||||
// status,
|
||||
// message
|
||||
// }
|
||||
// }`;
|
||||
async updateExtName(ext, name) {
|
||||
const query = gql`
|
||||
mutation updateExt($ext: ID!, $name: String, $password: String) {
|
||||
updateExtension(input: {
|
||||
extensionId: $ext
|
||||
name: $name
|
||||
}) {
|
||||
status,
|
||||
message
|
||||
}
|
||||
}`;
|
||||
|
||||
// const variables = {
|
||||
// ext,
|
||||
// name,
|
||||
// };
|
||||
const variables = {
|
||||
ext,
|
||||
endName,
|
||||
};
|
||||
|
||||
// return await this.pbxCall(query, variables);
|
||||
// }
|
||||
return await this.pbxCall(query, variables);
|
||||
}
|
||||
// TODO: Implement updateName method, Current implementation resets extension for some reason
|
||||
|
||||
async updateExtPassword(ext, password) {
|
||||
const query = gql`
|
||||
mutation updateExt($ext: ID!, $name: String, $password: String) {
|
||||
updateExtension(input: {
|
||||
extensionId: $ext
|
||||
extPassword: $password
|
||||
}) {
|
||||
status,
|
||||
message
|
||||
}
|
||||
}`;
|
||||
const variables = {
|
||||
ext,
|
||||
password,
|
||||
};
|
||||
return await this.pbxCall(query, variables);
|
||||
}
|
||||
|
||||
async joinPageGroup(ext, pageGroup) {
|
||||
const [lookup] = await this.pool.query('SELECT * FROM paging_groups WHERE page_number = ? AND ext = ?', [pageGroup, ext]);
|
||||
if (lookup) {
|
||||
|
|
|
|||
18
index.js
18
index.js
|
|
@ -138,6 +138,24 @@ client.on('interactionCreate', async interaction => {
|
|||
});;
|
||||
}
|
||||
break;
|
||||
case Discord.InteractionType.ModalSubmit:
|
||||
const modal = require(`./interactionHandlers/modals/${interaction.customId}`);
|
||||
|
||||
if (!modal) return;
|
||||
|
||||
try {
|
||||
await modal.execute(interaction);
|
||||
} catch (error) {
|
||||
log.error(error);
|
||||
await interaction.reply({ content: 'There was an error while executing this modal!', ephemeral: true }).catch((error) => {
|
||||
log.error(`Failed to inform user of error: ${error}`);
|
||||
});
|
||||
}
|
||||
break;
|
||||
default: {
|
||||
log.warn(`Unknown interaction type received: ${interaction.type}`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -94,6 +94,13 @@ module.exports.execute = async (interaction) => {
|
|||
emoji: "ℹ️",
|
||||
style: Discord.ButtonStyle.Primary,
|
||||
custom_id: "getExtensionInfo"
|
||||
},
|
||||
{
|
||||
type: Discord.ComponentType.Button,
|
||||
label: "Reset Password",
|
||||
emoji: "🔄",
|
||||
style: Discord.ButtonStyle.Danger,
|
||||
custom_id: "resetPassword"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
3
interactionHandlers/commands/reset.js
Normal file
3
interactionHandlers/commands/reset.js
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
module.exports = {};
|
||||
|
||||
module.exports.execute = require("../common/resetPasswordDialog").execute;
|
||||
|
|
@ -20,6 +20,20 @@ module.exports.execute = async (interaction) => {
|
|||
description: `**PBX Address:** \`${process.env.PBX_HOSTNAME}\`\n**Extension/Username:** \`${extInfo.fetchExtension.user.extension}\`\n**Name:** \`${extInfo.fetchExtension.user.name}\`\n**Password:** ||\`${extInfo.fetchExtension.user.extPassword}\`||`,
|
||||
color: 0x00ff00
|
||||
}
|
||||
],
|
||||
components: [
|
||||
{
|
||||
type: 1,
|
||||
components: [
|
||||
{
|
||||
type: Discord.ComponentType.Button,
|
||||
label: "Reset Password",
|
||||
emoji: "🔄",
|
||||
style: Discord.ButtonStyle.Danger,
|
||||
custom_id: "resetPassword"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
|
|
|
|||
41
interactionHandlers/common/resetPasswordDialog.js
Normal file
41
interactionHandlers/common/resetPasswordDialog.js
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
const pool = global.pool
|
||||
const fpbx = global.fpbx
|
||||
const client = global.client
|
||||
const log = global.log
|
||||
|
||||
module.exports = {};
|
||||
|
||||
module.exports.execute = async (interaction) => {
|
||||
const [lookup] = await pool.query('SELECT * FROM discord_users WHERE discordId = ?', [interaction.user.id]);
|
||||
if (!lookup) {
|
||||
await interaction.reply({ content: `We're sorry, It doesn't look like you have an extension!`, ephemeral: true });
|
||||
return;
|
||||
}
|
||||
interaction.showModal({
|
||||
title: 'Reset Extension Password',
|
||||
customId: 'resetPasswordModal',
|
||||
label: 'Reset Extension Password',
|
||||
components: [
|
||||
{
|
||||
type: 1, // Action Row
|
||||
components: [
|
||||
// {
|
||||
// type: 18, // Label
|
||||
// ,
|
||||
// component:
|
||||
// }
|
||||
{
|
||||
type: 4, // Text Input
|
||||
customId: 'newPassword',
|
||||
label: "New Password. Leave blank for random.",
|
||||
style: 1,
|
||||
min_length: 6,
|
||||
max_length: 64,
|
||||
placeholder: 'New Password',
|
||||
required: false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
3
interactionHandlers/components/resetPassword.js
Normal file
3
interactionHandlers/components/resetPassword.js
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
module.exports = {};
|
||||
|
||||
module.exports.execute = require("../common/resetPasswordDialog").execute;
|
||||
32
interactionHandlers/modals/resetPasswordModal.js
Normal file
32
interactionHandlers/modals/resetPasswordModal.js
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
const pool = global.pool
|
||||
const fpbx = global.fpbx
|
||||
const client = global.client
|
||||
const log = global.log
|
||||
module.exports = {};
|
||||
|
||||
module.exports.execute = async (interaction) => {
|
||||
const [lookup] = await pool.query('SELECT * FROM discord_users WHERE discordId = ?', [interaction.user.id]);
|
||||
if (!lookup) {
|
||||
await interaction.reply({ content: `We're sorry, It doesn't look like you have an extension!`, ephemeral: true });
|
||||
return;
|
||||
}
|
||||
const extData = await fpbx.getExtension(lookup.extension); // Verify extension exists
|
||||
console.log(extData)
|
||||
await interaction.deferReply({ ephemeral: true });
|
||||
// console.log(JSON.stringify(interaction, null, 2));
|
||||
const newPassword = interaction.fields.getTextInputValue('newPassword');
|
||||
let passwordToSet = newPassword;
|
||||
if (!newPassword || newPassword.trim() === '') {
|
||||
// Generate password based on process.env.PASSWORD_LENGTH and process.env.PASSWORD_CHARS or default to 32 alphanumeric with caps
|
||||
const length = parseInt(process.env.PASSWORD_LENGTH) || 32;
|
||||
const chars = process.env.PASSWORD_CHARS || 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
passwordToSet = Array.from({ length }, () => chars.charAt(Math.floor(Math.random() * chars.length))).join('');
|
||||
}
|
||||
try {
|
||||
await fpbx.updateExtPassword(lookup.extension, passwordToSet);
|
||||
await interaction.editReply({ content: `Your extension password has been reset successfully! Your new password is: ||\`${passwordToSet}\`||`, ephemeral: true });
|
||||
} catch (error) {
|
||||
log.error(error);
|
||||
await interaction.editReply({ content: 'There was an error while resetting your extension password!', ephemeral: true });
|
||||
}
|
||||
}
|
||||
10
package-lock.json
generated
10
package-lock.json
generated
|
|
@ -704,15 +704,6 @@
|
|||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
},
|
||||
"node_modules/encoding": {
|
||||
"version": "0.1.13",
|
||||
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
|
||||
"integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"iconv-lite": "^0.6.2"
|
||||
}
|
||||
},
|
||||
"node_modules/env-paths": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
|
||||
|
|
@ -851,6 +842,7 @@
|
|||
"version": "15.8.0",
|
||||
"resolved": "https://registry.npmjs.org/graphql/-/graphql-15.8.0.tgz",
|
||||
"integrity": "sha512-5gghUc24tP9HRznNpV2+FIoq3xKkj5dTQqf4v0CpdPbFVwFkWoxOM+o+2OC9ZSvjEMTjfmG9QT+gcvggTwW1zw==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">= 10.x"
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue