Added 'altcha' captcha system for account and channel creation.

This commit is contained in:
rainbow napkin 2024-12-26 06:09:49 -05:00
parent 60801f0dc2
commit e0f53df176
20 changed files with 326 additions and 55 deletions

View file

@ -15,17 +15,60 @@ 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/>.*/
//I could make a class like the others but it's so god-damned basic why bother?
async function registerPrompt(event){
if(!event || event.key == "Enter"){
var name = document.querySelector("#register-channel-name").value;
var description = document.querySelector("#register-description").value;
var thumbnail = document.querySelector("#register-thumbnail").value;
class registerPrompt{
constructor(){
//Grab input prompts
this.name = document.querySelector("#register-channel-name");
this.description = document.querySelector("#register-description");
this.thumbnail = document.querySelector("#register-thumbnail");
//Grab register button
this.button = document.querySelector("#register-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 register event listener to register button
this.button.addEventListener("click", this.register.bind(this));
}
verify(event){
//pull verification payload from event
this.verification = event.detail.payload;
}
register(){
//If altcha verification isn't complete
if(this.verification == null){
//don't bother
return;
}
//Send the registration informaiton off to the server
utils.ajax.newChannel(this.name.value, this.description.value, this.thumbnail.value, this.verification);
}
}
const registerForm = new registerPrompt();
/*async function registerPrompt(event){
if(!event || event.key == "Enter"){
utils.ajax.newChannel(name, description, thumbnail);
}
}
//assign events
document.querySelector("#register-channel-name").addEventListener("keydown", registerPrompt)
document.querySelector("#register-description").addEventListener("keydown", registerPrompt)
document.querySelector("#register-thumbnail").addEventListener("keydown", registerPrompt)
document.querySelector("#register-thumbnail").addEventListener("keydown", registerPrompt)*/

View file

@ -14,20 +14,56 @@ 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/>.*/
//I could make a class like the others but it's so god-damned basic why bother?
async function registerPrompt(event){
if(!event || event.key == "Enter"){
var user = document.querySelector("#register-username").value;
var pass = document.querySelector("#register-password").value;
var passConfirm = document.querySelector("#register-password-confirm").value;
var email = document.querySelector("#register-email").value;
class registerPrompt{
constructor(){
//Grab user prompt
this.user = document.querySelector("#register-username");
//Grab pass prompts
this.pass = document.querySelector("#register-password");
this.passConfirm = document.querySelector("#register-password-confirm");
//Grab email prompt
this.email = document.querySelector("#register-email");
//Grab register button
this.button = document.querySelector("#register-button");
//Grab altcha widget
this.altcha = document.querySelector("altcha-widget");
//Setup null property to hold verification payload from altcha widget
this.verification = null
utils.ajax.register(user, pass, passConfirm, email);
//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 register event listener to register button
this.button.addEventListener("click", this.register.bind(this));
}
verify(event){
//pull verification payload from event
this.verification = event.detail.payload;
}
register(){
//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.register(this.user.value , this.pass.value , this.passConfirm.value , this.email.value, this.verification);
}
}
//assign events
document.querySelector("#register-username").addEventListener("keydown", registerPrompt)
document.querySelector("#register-password").addEventListener("keydown", registerPrompt)
document.querySelector("#register-password-confirm").addEventListener("keydown", registerPrompt)
document.querySelector("#register-email").addEventListener("keydown", registerPrompt)
const registerForm = new registerPrompt();

View file

@ -187,21 +187,45 @@ class canopyUXUtils{
}
createPopup(){
this.popupBacker = document.createElement('div');
this.popupBacker.classList.add('popup-backer');
//Check if another popup has already thrown a backer up
if(document.querySelector('.popup-backer') == null){
//Create popup backer
this.popupBacker = document.createElement('div');
this.popupBacker.classList.add('popup-backer');
}
//Create popup
this.popupDiv = document.createElement('div');
this.popupDiv.classList.add('popup-div');
//Create close icon
this.closeIcon = document.createElement('i');
this.closeIcon.classList.add('bi-x','popup-close-icon');
this.closeIcon.addEventListener("click", this.closePopup.bind(this));
//Create content div
this.contentDiv = document.createElement('div');
this.contentDiv.classList.add('popup-content-div');
//Append popup innards
this.popupDiv.appendChild(this.closeIcon);
this.popupDiv.appendChild(this.contentDiv);
//Bit hacky but the only way to remove an event listener while keeping the function bound to this
//Isn't javascript precious?
this.keyClose = ((event)=>{
//If we hit enter
if(event.key == "Enter"){
//Close the pop-up
this.closePopup();
//Remove this event listener
document.removeEventListener('keydown', this.keyClose);
}
}).bind(this);
//Add event listener to close popup when enter is hit
document.addEventListener('keydown', this.keyClose);
}
async fillPopupContent(){
@ -221,13 +245,31 @@ class canopyUXUtils{
}
displayPopup(){
//Blur active element that probably caused the popup
document.activeElement.blur();
//display the popup
document.body.prepend(this.popupDiv);
document.body.prepend(this.popupBacker);
//if we created a popup backer
if(this.popupBacker != null){
//display the popup backer
document.body.prepend(this.popupBacker);
}
}
closePopup(){
//Take out the popup
this.popupDiv.remove();
this.popupBacker.remove();
//Look for the backer instead of using the object property since the bitch mighta been created by someone else
const foundBacker = document.querySelector('.popup-backer');
//if there aren't any more popups
if(document.querySelector('.popup-div') == null && foundBacker != null){
//Take out the backer
foundBacker.remove();
}
}
}
@ -346,13 +388,13 @@ class canopyAjaxUtils{
}
async register(user, pass, passConfirm, email){
async register(user, pass, passConfirm, email, verification){
var response = await fetch(`/api/account/register`,{
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(email ? {user, pass, passConfirm, email} : {user, pass, passConfirm})
body: JSON.stringify(email ? {user, pass, passConfirm, email, verification} : {user, pass, passConfirm, verification})
});
if(response.status == 200){
@ -435,13 +477,13 @@ class canopyAjaxUtils{
}
}
async newChannel(name, description, thumbnail){
async newChannel(name, description, thumbnail, verification){
var response = await fetch(`/api/channel/register`,{
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(thumbnail ? {name, description, thumbnail} : {name, description})
body: JSON.stringify(thumbnail ? {name, description, thumbnail, verification} : {name, description, verification})
});
if(response.status == 200){