Added 'altcha' captcha system for account and channel creation.
This commit is contained in:
parent
60801f0dc2
commit
e0f53df176
20 changed files with 326 additions and 55 deletions
|
|
@ -13,13 +13,19 @@ 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%;
|
||||
}
|
||||
|
||||
input{
|
||||
margin: 0 0 2em;
|
||||
.register-prompt{
|
||||
width: 100%
|
||||
}
|
||||
|
||||
#register-button{
|
||||
width: 6em;
|
||||
height: 2em;
|
||||
}
|
||||
|
|
@ -16,9 +16,16 @@ 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%;
|
||||
}
|
||||
|
||||
input{
|
||||
margin: 0 0 2em;
|
||||
.register-prompt{
|
||||
width: 100%
|
||||
}
|
||||
|
||||
#register-button{
|
||||
width: 6em;
|
||||
height: 2em;
|
||||
}
|
||||
|
|
@ -59,6 +59,16 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
|||
|
||||
--background-panel-effect-pretty: blur(4px);
|
||||
--background-panel-effect-fast: none;
|
||||
|
||||
/* altcha theming */
|
||||
--altcha-border-width: 1px;
|
||||
--altcha-border-radius: 1em;
|
||||
--altcha-color-base: var(--bg1);
|
||||
--altcha-color-border: var(--accent1);
|
||||
--altcha-color-text: var(--accent1);
|
||||
--altcha-color-border-focus: currentColor;
|
||||
--altcha-color-error-text: #f23939;
|
||||
--altcha-max-width: 260px;
|
||||
}
|
||||
|
||||
/* global */
|
||||
|
|
@ -108,6 +118,10 @@ button:active{
|
|||
box-shadow: var(--focus-glow0-alt0);
|
||||
}
|
||||
|
||||
input{
|
||||
accent-color: var(--focus0);
|
||||
}
|
||||
|
||||
.danger-button{
|
||||
background-color: var(--danger0);
|
||||
color: var(--accent1);
|
||||
|
|
@ -384,4 +398,13 @@ span.emote-panel-list-emote:active, span.emote-list-trash-icon:active{
|
|||
span.emote-list-trash-icon{
|
||||
background-color: var(--bg2);
|
||||
border: 1px solid var(--accent0)
|
||||
}
|
||||
|
||||
/* altcha theming*/
|
||||
div.altcha{
|
||||
box-shadow: 4px 4px 1px var(--bg1-alt0) inset;
|
||||
}
|
||||
|
||||
altcha-widget a{
|
||||
color: var(--accent1);
|
||||
}
|
||||
|
|
@ -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)*/
|
||||
|
|
@ -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();
|
||||
|
|
@ -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){
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue