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
|
//Generate the password reset link
|
||||||
const requestDB = await passwordResetModel.generateResetToken(userDB);
|
const requestDB = await passwordResetModel.create({user: userDB._id});
|
||||||
|
|
||||||
//send successful response
|
//send successful response
|
||||||
res.status(200);
|
res.status(200);
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,9 @@ const passwordResetSchema = new mongoose.Schema({
|
||||||
},
|
},
|
||||||
token: {
|
token: {
|
||||||
type: mongoose.SchemaTypes.String,
|
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: {
|
date: {
|
||||||
|
|
||||||
|
|
@ -47,21 +49,6 @@ const passwordResetSchema = new mongoose.Schema({
|
||||||
});
|
});
|
||||||
|
|
||||||
//statics
|
//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(){
|
passwordResetSchema.statics.processExpiredRequests = async function(){
|
||||||
//Pull all requests from the DB
|
//Pull all requests from the DB
|
||||||
const requestDB = await this.find({});
|
const requestDB = await this.find({});
|
||||||
|
|
|
||||||
|
|
@ -380,6 +380,10 @@ select.panel-head-element{
|
||||||
color: var(--danger0);
|
color: var(--danger0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.popup-div a{
|
||||||
|
color: var(--accent1);
|
||||||
|
}
|
||||||
|
|
||||||
/* tooltip */
|
/* tooltip */
|
||||||
div.tooltip{
|
div.tooltip{
|
||||||
background-color: var(--bg1);
|
background-color: var(--bg1);
|
||||||
|
|
|
||||||
|
|
@ -286,6 +286,7 @@ class adminUserList{
|
||||||
this.userNames = document.querySelectorAll(".admin-user-list-name");
|
this.userNames = document.querySelectorAll(".admin-user-list-name");
|
||||||
this.rankSelectors = document.querySelectorAll(".admin-user-list-rank-select");
|
this.rankSelectors = document.querySelectorAll(".admin-user-list-rank-select");
|
||||||
this.banIcons = document.querySelectorAll(".admin-user-list-ban-icon");
|
this.banIcons = document.querySelectorAll(".admin-user-list-ban-icon");
|
||||||
|
this.passResetIcons = document.querySelectorAll(".admin-user-list-pw-reset-icon");
|
||||||
|
|
||||||
this.setupInput();
|
this.setupInput();
|
||||||
}
|
}
|
||||||
|
|
@ -318,6 +319,10 @@ class adminUserList{
|
||||||
for(let banIcon of this.banIcons){
|
for(let banIcon of this.banIcons){
|
||||||
banIcon.addEventListener("click", this.banPopup.bind(this));
|
banIcon.addEventListener("click", this.banPopup.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(let passResetIcon of this.passResetIcons){
|
||||||
|
passResetIcon.addEventListener("click", this.genResetLink.bind(this))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async setRank(event){
|
async setRank(event){
|
||||||
|
|
@ -327,6 +332,35 @@ class adminUserList{
|
||||||
this.updateSelect(await adminUtil.setUserRank(user, rank), event.target);
|
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){
|
banPopup(event){
|
||||||
const user = event.target.id.replace("admin-user-list-ban-icon-","");
|
const user = event.target.id.replace("admin-user-list-ban-icon-","");
|
||||||
new canopyAdminUtils.banUserPopup(user, userBanList.renderBanList.bind(userBanList));
|
new canopyAdminUtils.banUserPopup(user, userBanList.renderBanList.bind(userBanList));
|
||||||
|
|
|
||||||
|
|
@ -169,6 +169,7 @@ class canopyUXUtils{
|
||||||
}
|
}
|
||||||
|
|
||||||
remove(){
|
remove(){
|
||||||
|
this.tooltip.dispatchEvent(new Event("close"));
|
||||||
this.tooltip.remove();
|
this.tooltip.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -259,6 +260,8 @@ class canopyUXUtils{
|
||||||
}
|
}
|
||||||
|
|
||||||
closePopup(){
|
closePopup(){
|
||||||
|
this.popupDiv.dispatchEvent(new Event("close"));
|
||||||
|
|
||||||
//Take out the popup
|
//Take out the popup
|
||||||
this.popupDiv.remove();
|
this.popupDiv.remove();
|
||||||
|
|
||||||
|
|
@ -487,8 +490,13 @@ class canopyAjaxUtils{
|
||||||
body: JSON.stringify({token, pass, confirmPass, verification})
|
body: JSON.stringify({token, pass, confirmPass, verification})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//If we received a successful response
|
||||||
if(response.status == 200){
|
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{
|
}else{
|
||||||
utils.ux.displayResponseError(await response.json());
|
utils.ux.displayResponseError(await response.json());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue