Prettied up UI for password resets. Now to move on to email component.
This commit is contained in:
parent
ed698f40c7
commit
3671b43789
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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({});
|
||||
|
|
|
|||
|
|
@ -380,6 +380,10 @@ select.panel-head-element{
|
|||
color: var(--danger0);
|
||||
}
|
||||
|
||||
.popup-div a{
|
||||
color: var(--accent1);
|
||||
}
|
||||
|
||||
/* tooltip */
|
||||
div.tooltip{
|
||||
background-color: var(--bg1);
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue