Started work on migration UI. Improved email handling.
This commit is contained in:
parent
bddbd9cd36
commit
eb48b92551
31
src/controllers/migrateController.js
Normal file
31
src/controllers/migrateController.js
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/*Canopy - The next generation of stoner streaming software
|
||||
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
||||
|
||||
//Config
|
||||
const config = require('../../config.json');
|
||||
|
||||
//Local Imports
|
||||
const altchaUtils = require('../utils/altchaUtils');
|
||||
const csrfUtils = require('../utils/csrfUtils');
|
||||
|
||||
//register page functions
|
||||
module.exports.get = async function(req, res){
|
||||
//Generate captcha
|
||||
const challenge = await altchaUtils.genCaptcha();
|
||||
|
||||
//Render page
|
||||
return res.render('migrate', {instance: config.instanceName, user: req.session.user, challenge, csrfToken: csrfUtils.generateToken(req)});
|
||||
}
|
||||
30
src/routers/migrateRouter.js
Normal file
30
src/routers/migrateRouter.js
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/*Canopy - The next generation of stoner streaming software
|
||||
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
||||
|
||||
//npm imports
|
||||
const { Router } = require('express');
|
||||
|
||||
|
||||
//local imports
|
||||
const migrateController = require("../controllers/migrateController");
|
||||
|
||||
//globals
|
||||
const router = Router();
|
||||
|
||||
//routing functions
|
||||
router.get('/', migrateController.get);
|
||||
|
||||
module.exports = router;
|
||||
|
|
@ -316,6 +316,12 @@ migrationSchema.statics.consumeByUsername = async function(ip, migration){
|
|||
//Pull migration doc by case-insensitive username
|
||||
const migrationDB = await this.findOne({user: new RegExp(migration.user, 'i')});
|
||||
|
||||
//If we have no migration document
|
||||
if(migrationDB == null){
|
||||
//Bitch and moan
|
||||
throw loggerUtils.exceptionSmith("Incorrect username/password.", "migration");
|
||||
}
|
||||
|
||||
//Wait on the miration DB token to be consumed
|
||||
await migrationDB.consume(ip, migration);
|
||||
}
|
||||
|
|
@ -359,7 +365,7 @@ migrationSchema.methods.consume = async function(ip, migration){
|
|||
await newUser.tattooIPRecord(ip);
|
||||
|
||||
//if we submitted an email
|
||||
if(this.email != null && this.email != ''){
|
||||
if(this.email != null && validator.isEmail(this.email)){
|
||||
//Generate new email change request
|
||||
const requestDB = await emailChangeModel.create({user: newUser._id, newEmail: this.email, ipHash: ip});
|
||||
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ const channelRouter = require('./routers/channelRouter');
|
|||
const newChannelRouter = require('./routers/newChannelRouter');
|
||||
const passwordResetRouter = require('./routers/passwordResetRouter');
|
||||
const emailChangeRouter = require('./routers/emailChangeController');
|
||||
const migrateRouter = require('./routers/migrateRouter');
|
||||
//Panel
|
||||
const panelRouter = require('./routers/panelRouter');
|
||||
//Popup
|
||||
|
|
@ -161,6 +162,7 @@ app.use('/c', channelRouter);
|
|||
app.use('/newChannel', newChannelRouter);
|
||||
app.use('/passwordReset', passwordResetRouter);
|
||||
app.use('/emailChange', emailChangeRouter);
|
||||
app.use('/migrate', migrateRouter);
|
||||
//Panel
|
||||
app.use('/panel', panelRouter);
|
||||
//tooltip
|
||||
|
|
|
|||
|
|
@ -173,10 +173,10 @@ module.exports.errorMiddleware = function(err, req, res, next){
|
|||
* @param {Error} err - error to dump to file
|
||||
* @param {Date} date - Date of error, defaults to now
|
||||
*/
|
||||
module.exports.dumpError = async function(err, date = new Date()){
|
||||
module.exports.dumpError = async function(err, date = new Date(), subDir){
|
||||
try{
|
||||
//Crash directory
|
||||
const dir = "./log/crash/"
|
||||
const dir = `./log/crash/${subDir}`
|
||||
|
||||
//Double check crash folder exists
|
||||
try{
|
||||
|
|
|
|||
|
|
@ -19,6 +19,11 @@ const config = require('../../config.json');
|
|||
|
||||
//NPM imports
|
||||
const nodeMailer = require("nodemailer");
|
||||
const validator = require('validator');
|
||||
|
||||
//local imports
|
||||
const loggerUtils = require('./loggerUtils');
|
||||
|
||||
|
||||
//Setup mail transport
|
||||
/**
|
||||
|
|
@ -43,6 +48,13 @@ const transporter = nodeMailer.createTransport({
|
|||
* @returns {Object} Sent mail info
|
||||
*/
|
||||
module.exports.mailem = async function(to, subject, body, htmlBody = false){
|
||||
try{
|
||||
//If we have a bad email address
|
||||
if(!validator.isEmail(to)){
|
||||
//fuck off
|
||||
return;
|
||||
}
|
||||
|
||||
//Create mail object
|
||||
const mailObj = {
|
||||
from: `"Tokebot🤖💨"<${config.mail.address}>`,
|
||||
|
|
@ -65,6 +77,9 @@ module.exports.mailem = async function(to, subject, body, htmlBody = false){
|
|||
|
||||
//return the mail info
|
||||
return sentMail;
|
||||
}catch(err){
|
||||
loggerUtils.dumpError(err, new Date(), 'mail/');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
46
src/views/migrate.ejs
Normal file
46
src/views/migrate.ejs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
<%# Canopy - The next generation of stoner streaming software
|
||||
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. %>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<%- include('partial/styles', {instance, user}); %>
|
||||
<%- include('partial/csrfToken', {csrfToken}); %>
|
||||
<link rel="stylesheet" type="text/css" href="/css/migrate.css">
|
||||
<link rel="stylesheet" type="text/css" href="/lib/altcha/altcha.css">
|
||||
<title><%= instance %> - Account Migration</title>
|
||||
</head>
|
||||
<body>
|
||||
<%- include('partial/navbar', {user}); %>
|
||||
<form action="javascript:">
|
||||
<label>Username:</label>
|
||||
<input class="migrate-prompt" id="migrate-username" placeholder="Required">
|
||||
<label>Old Password:</label>
|
||||
<input class="migrate-prompt" id="migrate-password-old" placeholder="Required" type="password">
|
||||
<label>Password:</label>
|
||||
<input class="migrate-prompt" id="migrate-password" placeholder="Required" type="password">
|
||||
<label>Confirm Password:</label>
|
||||
<input class="migrate-prompt" id="migrate-password-confirm" placeholder="Required" type="password">
|
||||
<altcha-widget floating challengejson="<%= JSON.stringify(challenge) %>"></altcha-widget>
|
||||
<button id="migrate-button" class='positive-button'>migrate</button>
|
||||
</form>
|
||||
</body>
|
||||
<footer>
|
||||
<%- include('partial/scripts', {user}); %>
|
||||
<script src="/js/migrate.js"></script>
|
||||
<script src="/lib/altcha/altcha.js" type="module"></script>
|
||||
</footer>
|
||||
</html>
|
||||
31
www/css/migrate.css
Normal file
31
www/css/migrate.css
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/*Canopy - The next generation of stoner streaming software
|
||||
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
||||
form{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 0.5em;
|
||||
margin: 5% 17%;
|
||||
}
|
||||
|
||||
.migrate-prompt{
|
||||
width: 100%
|
||||
}
|
||||
|
||||
#migrate-button{
|
||||
width: 6em;
|
||||
height: 2em;
|
||||
}
|
||||
68
www/js/migrate.js
Normal file
68
www/js/migrate.js
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/*Canopy - The next generation of stoner streaming software
|
||||
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
||||
|
||||
class migratePrompt{
|
||||
constructor(){
|
||||
//Grab user prompt
|
||||
this.user = document.querySelector("#migrate-username");
|
||||
//Grab pass prompts
|
||||
this.oldPass = document.querySelector("#migrate-password-old");
|
||||
this.pass = document.querySelector("#migrate-password");
|
||||
this.passConfirm = document.querySelector("#migrate-password-confirm");
|
||||
//Grab migrate button
|
||||
this.button = document.querySelector("#migrate-button");
|
||||
//Grab altcha widget
|
||||
this.altcha = document.querySelector("altcha-widget");
|
||||
//Setup null property to hold verification payload from altcha widget
|
||||
this.verification = null
|
||||
|
||||
//Run input setup after DOM content has completely loaded to ensure altcha event listeners work
|
||||
document.addEventListener('DOMContentLoaded', this.setupInput.bind(this));
|
||||
}
|
||||
|
||||
setupInput(){
|
||||
//Add verification event listener to altcha widget
|
||||
this.altcha.addEventListener("verified", this.verify.bind(this));
|
||||
|
||||
//Add migrate event listener to migrate button
|
||||
this.button.addEventListener("click", this.migrate.bind(this));
|
||||
}
|
||||
|
||||
verify(event){
|
||||
//pull verification payload from event
|
||||
this.verification = event.detail.payload;
|
||||
}
|
||||
|
||||
migrate(){
|
||||
//If altcha verification isn't complete
|
||||
if(this.verification == null){
|
||||
//don't bother
|
||||
return;
|
||||
}
|
||||
|
||||
//if the confirmation password doesn't match
|
||||
if(this.pass.value != this.passConfirm.value){
|
||||
//Scream and shout
|
||||
new canopyUXUtils.popup(`<p>Confirmation password does not match!</p>`);
|
||||
return;
|
||||
}
|
||||
|
||||
//Send the registration informaiton off to the server
|
||||
utils.ajax.migrate(this.user.value , this.oldPass.value, this.pass.value , this.passConfirm.value , this.verification);
|
||||
}
|
||||
}
|
||||
|
||||
const migrateForm = new migratePrompt();
|
||||
Loading…
Reference in a new issue