diff --git a/src/controllers/api/admin/passwordResetController.js b/src/controllers/api/admin/passwordResetController.js index 2c3306c..a49d1f3 100644 --- a/src/controllers/api/admin/passwordResetController.js +++ b/src/controllers/api/admin/passwordResetController.js @@ -41,7 +41,7 @@ module.exports.post = async function(req, res){ } //Generate the password reset link - const requestDB = await passwordResetModel.generateResetToken(userDB); + const requestDB = await passwordResetModel.create({user: userDB._id}); //send successful response res.status(200); diff --git a/src/schemas/passwordResetSchema.js b/src/schemas/passwordResetSchema.js index 2522a3b..c4dfdf7 100644 --- a/src/schemas/passwordResetSchema.js +++ b/src/schemas/passwordResetSchema.js @@ -36,7 +36,9 @@ const passwordResetSchema = new mongoose.Schema({ }, token: { type: mongoose.SchemaTypes.String, - required: true + required: true, + //Use a cryptographically secure algorythm to create a random hex string from 16 bytes as our reset token + default: ()=>{return crypto.randomBytes(16).toString('hex')} }, date: { @@ -47,21 +49,6 @@ const passwordResetSchema = new mongoose.Schema({ }); //statics -passwordResetSchema.statics.generateResetToken = async function(userDB){ - //Use a cryptographically secure algorythm to create a random hex string from 16 bytes as our reset token - const token = crypto.randomBytes(16).toString('hex'); - - //Create request object - const request = { - user: userDB._id, - token, - date: new Date() - } - - //Create the request entry in the DB and return the newly created record - return await this.create(request); -} - passwordResetSchema.statics.processExpiredRequests = async function(){ //Pull all requests from the DB const requestDB = await this.find({}); diff --git a/www/css/theme/movie-night.css b/www/css/theme/movie-night.css index 2300612..5bf246d 100644 --- a/www/css/theme/movie-night.css +++ b/www/css/theme/movie-night.css @@ -380,6 +380,10 @@ select.panel-head-element{ color: var(--danger0); } +.popup-div a{ + color: var(--accent1); +} + /* tooltip */ div.tooltip{ background-color: var(--bg1); diff --git a/www/js/adminPanel.js b/www/js/adminPanel.js index 9592847..d1b3d86 100644 --- a/www/js/adminPanel.js +++ b/www/js/adminPanel.js @@ -286,6 +286,7 @@ class adminUserList{ this.userNames = document.querySelectorAll(".admin-user-list-name"); this.rankSelectors = document.querySelectorAll(".admin-user-list-rank-select"); this.banIcons = document.querySelectorAll(".admin-user-list-ban-icon"); + this.passResetIcons = document.querySelectorAll(".admin-user-list-pw-reset-icon"); this.setupInput(); } @@ -318,6 +319,10 @@ class adminUserList{ for(let banIcon of this.banIcons){ banIcon.addEventListener("click", this.banPopup.bind(this)); } + + for(let passResetIcon of this.passResetIcons){ + passResetIcon.addEventListener("click", this.genResetLink.bind(this)) + } } async setRank(event){ @@ -327,6 +332,35 @@ class adminUserList{ this.updateSelect(await adminUtil.setUserRank(user, rank), event.target); } + async genResetLink(event){ + //Scrape user + const user = event.target.id.replace("admin-user-list-pw-reset-icon-",""); + + const URL = (await adminUtil.genPasswordResetLink(user)).url; + + //Create span + const span = document.createElement('span'); + //Usually not into doing CSS this way, but I'm not making a dedicated file for a popup this small... + span.style = "text-align: center; display: block;" + + //Create header + const header = document.createElement('h3'); + header.innerText = `Reset Link for ${user}` + + //Create link + const link = document.createElement('a'); + link.innerText = "Reset Link" + link.href = URL; + + //Append link to the header + span.appendChild(header); + span.appendChild(link); + + //Display link in pop-up + new canopyUXUtils.popup(span.outerHTML); + + } + banPopup(event){ const user = event.target.id.replace("admin-user-list-ban-icon-",""); new canopyAdminUtils.banUserPopup(user, userBanList.renderBanList.bind(userBanList)); diff --git a/www/js/utils.js b/www/js/utils.js index 2f14395..eb042bb 100644 --- a/www/js/utils.js +++ b/www/js/utils.js @@ -169,6 +169,7 @@ class canopyUXUtils{ } remove(){ + this.tooltip.dispatchEvent(new Event("close")); this.tooltip.remove(); } } @@ -259,6 +260,8 @@ class canopyUXUtils{ } closePopup(){ + this.popupDiv.dispatchEvent(new Event("close")); + //Take out the popup this.popupDiv.remove(); @@ -487,8 +490,13 @@ class canopyAjaxUtils{ body: JSON.stringify({token, pass, confirmPass, verification}) }); + //If we received a successful response if(response.status == 200){ - return await response.json(); + //Create pop-up + const popup = new canopyUXUtils.popup("Your password has been reset!"); + //Go to home-page on pop-up closure + popup.popupDiv.addEventListener("close", ()=>{window.location = '/'}); + //Otherwise }else{ utils.ux.displayResponseError(await response.json()); }