Compare commits
No commits in common. "c2bbf0b6f8283b4384f28d37fa38c7fad6021bcf" and "b80f82b9f29a4082d5c4bc5f994a10f1b60d7881" have entirely different histories.
c2bbf0b6f8
...
b80f82b9f2
12 changed files with 47 additions and 358 deletions
|
|
@ -1,125 +0,0 @@
|
||||||
/*Canopy - The next generation of stoner streaming software
|
|
||||||
Copyright (C) 2024-2026 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 {validationResult, matchedData} = require('express-validator');
|
|
||||||
|
|
||||||
//local imports
|
|
||||||
const {userModel} = require('../../../schemas/user/userSchema');
|
|
||||||
const accountUtils = require('../../../utils/sessionUtils');
|
|
||||||
const {exceptionHandler, errorHandler} = require('../../../utils/loggerUtils');
|
|
||||||
|
|
||||||
//api account functions
|
|
||||||
module.exports.get = async function(req, res){
|
|
||||||
try{
|
|
||||||
//syntactic sugar :P
|
|
||||||
const user = req.session.user;
|
|
||||||
|
|
||||||
//make sure we're not bullshitting ourselves here.
|
|
||||||
if(user == null || user.user == null){
|
|
||||||
return errorHandler(res, 'You must be logged in to retrieve your ignored users!', 'unauthorized');
|
|
||||||
}
|
|
||||||
|
|
||||||
//Grab user
|
|
||||||
const userDB = await userModel.findOne({user: user.user});
|
|
||||||
|
|
||||||
//Bitch about non-existant users
|
|
||||||
if(!userDB){
|
|
||||||
return errorHandler(res, 'User not found!', 'unauthorized');
|
|
||||||
}
|
|
||||||
|
|
||||||
//Set status and send ignored user list
|
|
||||||
res.status(200);
|
|
||||||
return res.send((await userDB.getIgnoredUsers(false)).user);
|
|
||||||
|
|
||||||
}catch(err){
|
|
||||||
exceptionHandler(res, err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.post = async function(req, res){
|
|
||||||
try{
|
|
||||||
const validResult = validationResult(req);
|
|
||||||
|
|
||||||
if(validResult.isEmpty()){
|
|
||||||
//syntactic sugar :P
|
|
||||||
const user = req.session.user;
|
|
||||||
const data = matchedData(req);
|
|
||||||
|
|
||||||
//make sure we're not bullshitting ourselves here.
|
|
||||||
if(user == null || user.user == null){
|
|
||||||
return errorHandler(res, 'You must be logged in to ignore a user!', 'unauthorized');
|
|
||||||
}
|
|
||||||
|
|
||||||
//Grab user
|
|
||||||
const userDB = await userModel.findOne({user: user.user});
|
|
||||||
|
|
||||||
//Bitch about non-existant users
|
|
||||||
if(!userDB){
|
|
||||||
return errorHandler(res, 'User not found!', 'unauthorized');
|
|
||||||
}
|
|
||||||
|
|
||||||
//Ignore given user
|
|
||||||
await userDB.ignoreByUser(data.user);
|
|
||||||
|
|
||||||
//Set status and send ignored user list
|
|
||||||
res.status(200);
|
|
||||||
return res.send((await userDB.getIgnoredUsers(false)).user);
|
|
||||||
}else{
|
|
||||||
res.status(400);
|
|
||||||
res.send({errors: validResult.array()})
|
|
||||||
}
|
|
||||||
}catch(err){
|
|
||||||
exceptionHandler(res, err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.delete = async function(req, res){
|
|
||||||
try{
|
|
||||||
const validResult = validationResult(req);
|
|
||||||
|
|
||||||
if(validResult.isEmpty()){
|
|
||||||
//syntactic sugar :P
|
|
||||||
const user = req.session.user;
|
|
||||||
const data = matchedData(req);
|
|
||||||
|
|
||||||
//make sure we're not bullshitting ourselves here.
|
|
||||||
if(user == null || user.user == null){
|
|
||||||
return errorHandler(res, 'You must be logged in to ignore a user!', 'unauthorized');
|
|
||||||
}
|
|
||||||
|
|
||||||
//Grab user
|
|
||||||
const userDB = await userModel.findOne({user: user.user});
|
|
||||||
|
|
||||||
//Bitch about non-existant users
|
|
||||||
if(!userDB){
|
|
||||||
return errorHandler(res, 'User not found!', 'unauthorized');
|
|
||||||
}
|
|
||||||
|
|
||||||
//Unignore given user
|
|
||||||
await userDB.unignoreByUser(data.user);
|
|
||||||
|
|
||||||
//Set status and send ignored user list
|
|
||||||
res.status(200);
|
|
||||||
return res.send((await userDB.getIgnoredUsers(false)).user);
|
|
||||||
}else{
|
|
||||||
res.status(400);
|
|
||||||
res.send({errors: validResult.array()})
|
|
||||||
}
|
|
||||||
}catch(err){
|
|
||||||
exceptionHandler(res, err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -27,11 +27,9 @@ const validator = require('validator');//No express here, so regular validator i
|
||||||
//profile functions
|
//profile functions
|
||||||
module.exports.get = async function(req, res){
|
module.exports.get = async function(req, res){
|
||||||
try{
|
try{
|
||||||
//Get profile name from URL
|
|
||||||
var profileName = req.url.slice(1) == '' ? (req.session.user ? req.session.user.user : null) : req.url.slice(1);
|
var profileName = req.url.slice(1) == '' ? (req.session.user ? req.session.user.user : null) : req.url.slice(1);
|
||||||
|
|
||||||
//Pull profile including semi-sensitive information (this object will only be parsed server side)
|
const profile = await userModel.findProfile({user: profileName}, true);
|
||||||
const profile = await userModel.findProfile({user: profileName}, true, true);
|
|
||||||
|
|
||||||
if(profile){
|
if(profile){
|
||||||
//If we have a user, check if the is looking at their own profile
|
//If we have a user, check if the is looking at their own profile
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,6 @@ const rankEnumController = require("../../controllers/api/account/rankEnumContro
|
||||||
const passwordResetRequestController = require("../../controllers/api/account/passwordResetRequestController");
|
const passwordResetRequestController = require("../../controllers/api/account/passwordResetRequestController");
|
||||||
const passwordResetController = require("../../controllers/api/account/passwordResetController");
|
const passwordResetController = require("../../controllers/api/account/passwordResetController");
|
||||||
const emailChangeRequestController = require('../../controllers/api/account/emailChangeRequestController');
|
const emailChangeRequestController = require('../../controllers/api/account/emailChangeRequestController');
|
||||||
const ignoredController = require("../../controllers/api/account/ignoredController");
|
|
||||||
const deleteController = require("../../controllers/api/account/deleteController");
|
const deleteController = require("../../controllers/api/account/deleteController");
|
||||||
|
|
||||||
//globals
|
//globals
|
||||||
|
|
@ -75,10 +74,6 @@ router.post('/passwordResetRequest', accountValidator.user(), passwordResetReque
|
||||||
router.post('/passwordReset', accountValidator.securityToken(), accountValidator.securePass(), accountValidator.pass('confirmPass'), passwordResetController.post);
|
router.post('/passwordReset', accountValidator.securityToken(), accountValidator.securePass(), accountValidator.pass('confirmPass'), passwordResetController.post);
|
||||||
//email change request
|
//email change request
|
||||||
router.post('/emailChangeRequest', accountValidator.email(), accountValidator.pass(), emailChangeRequestController.post);
|
router.post('/emailChangeRequest', accountValidator.email(), accountValidator.pass(), emailChangeRequestController.post);
|
||||||
//ignored users list management
|
|
||||||
router.get('/ignore', ignoredController.get);
|
|
||||||
router.post('/ignore', accountValidator.user(), ignoredController.post);
|
|
||||||
router.post('/unignore', accountValidator.user(), ignoredController.delete);
|
|
||||||
//account deletion
|
//account deletion
|
||||||
router.post('/delete', accountValidator.pass(), deleteController.post);
|
router.post('/delete', accountValidator.pass(), deleteController.post);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -702,6 +702,8 @@ userSchema.methods.ignoreByUserDoc = async function(userDB){
|
||||||
|
|
||||||
//Save the DB document
|
//Save the DB document
|
||||||
await this.save();
|
await this.save();
|
||||||
|
|
||||||
|
console.log(await this.getIgnoredUsers());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -735,6 +737,8 @@ userSchema.methods.unignoreByUserDoc = async function(userDB){
|
||||||
|
|
||||||
//Save the DB document
|
//Save the DB document
|
||||||
await this.save();
|
await this.save();
|
||||||
|
|
||||||
|
console.log(await this.getIgnoredUsers());
|
||||||
}
|
}
|
||||||
|
|
||||||
userSchema.methods.getIgnoredUsers = async function(fetchAlts = true){
|
userSchema.methods.getIgnoredUsers = async function(fetchAlts = true){
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. %>
|
||||||
<span class="account-settings" id="account-settings-buttons">
|
<span class="account-settings" id="account-settings-buttons">
|
||||||
<button href="javascript:" class="account-settings positive-button" id="account-settings-update-email-button">Update Email</button>
|
<button href="javascript:" class="account-settings positive-button" id="account-settings-update-email-button">Update Email</button>
|
||||||
<button href="javascript:" class="account-settings positive-button" id="account-settings-change-password-button">Change Password</button>
|
<button href="javascript:" class="account-settings positive-button" id="account-settings-change-password-button">Change Password</button>
|
||||||
<button href="javascript:" class="account-settings positive-button" id="account-settings-ignored-users-button">Ignored Users</button>
|
|
||||||
<button href="javascript:" class="account-settings danger-button" id="account-settings-delete-button">Delete Account</button>
|
<button href="javascript:" class="account-settings danger-button" id="account-settings-delete-button">Delete Account</button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -153,8 +153,7 @@ p.navbar-item, input.navbar-item{
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
/*Popup backer has to exist behind popups that are behind default ones for error reasons*/
|
z-index: 9000;
|
||||||
z-index: 8998;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.popup-div{
|
.popup-div{
|
||||||
|
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
/*Canopy - The next generation of stoner streaming software
|
|
||||||
Copyright (C) 2024-2026 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/>.*/
|
|
||||||
|
|
||||||
/*Gotta keep er' behind the errors*/
|
|
||||||
.popup-div:has(#ignored-users-popup){
|
|
||||||
z-index: 8999;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ignored-users-popup-list-div{
|
|
||||||
padding: 0;
|
|
||||||
margin-bottom: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ignored-users-popup-ignored-user {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ignored-users-popup-ignored-user-label {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ignored-users-popup-ignored-user {
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 0 0.5em;
|
|
||||||
}
|
|
||||||
|
|
@ -23,7 +23,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
||||||
--bg1: rgb(70, 70, 70);
|
--bg1: rgb(70, 70, 70);
|
||||||
--bg2: rgb(220, 220, 220);
|
--bg2: rgb(220, 220, 220);
|
||||||
--bg1-alt0: rgb(30, 30, 30);
|
--bg1-alt0: rgb(30, 30, 30);
|
||||||
--bg1-alt1: rgb(10, 10, 10);
|
|
||||||
--bg2-alt0: rgb(180, 180, 180);
|
--bg2-alt0: rgb(180, 180, 180);
|
||||||
|
|
||||||
--accent0: rgb(47, 47, 47);
|
--accent0: rgb(47, 47, 47);
|
||||||
|
|
@ -589,18 +588,6 @@ select.panel-head-element{
|
||||||
color: var(--accent1);
|
color: var(--accent1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Ignored Users Popup*/
|
|
||||||
#ignored-users-popup-list-div{
|
|
||||||
border-radius: 0;
|
|
||||||
border: 1px solid var(--accent1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.ignored-users-popup-ignored-user:nth-child(even):not(.chat-entry-toke){
|
|
||||||
box-shadow: 3px 0px 1px var(--bg1-alt1) inset;
|
|
||||||
background-color: var(--bg1-alt0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* psa */
|
/* psa */
|
||||||
#psa-container{
|
#psa-container{
|
||||||
border: 3px solid var(--danger0);
|
border: 3px solid var(--danger0);
|
||||||
|
|
|
||||||
|
|
@ -778,18 +778,6 @@ select.panel-head-element{
|
||||||
color: var(--accent1);
|
color: var(--accent1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Ignored Users Popup*/
|
|
||||||
#ignored-users-popup-list-div{
|
|
||||||
border-radius: 0;
|
|
||||||
border: 1px solid var(--accent1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.ignored-users-popup-ignored-user:nth-child(even):not(.chat-entry-toke){
|
|
||||||
box-shadow: 3px 0px 1px var(--bg1) inset;
|
|
||||||
background-color: var(--bg2-alt0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* psa */
|
/* psa */
|
||||||
#psa-container{
|
#psa-container{
|
||||||
border: 3px solid var(--danger0);
|
border: 3px solid var(--danger0);
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,46 @@ class profileUpdateImagePrompt extends profileUpdatePrompt{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class passwordResetPrompt{
|
||||||
|
constructor(){
|
||||||
|
this.oldPassNode = document.querySelector('#account-settings-password-reset-old');
|
||||||
|
this.newPassNode = document.querySelector('#account-settings-password-reset-new');
|
||||||
|
this.confirmPassNode = document.querySelector('#account-settings-password-reset-confirm');
|
||||||
|
|
||||||
|
this.setupInput(this.oldPassNode);
|
||||||
|
this.setupInput(this.newPassNode);
|
||||||
|
this.setupInput(this.confirmPassNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
setupInput(node){
|
||||||
|
if(node != null){
|
||||||
|
node.addEventListener("keydown", this.update.bind(this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async update(event){
|
||||||
|
var hasVal = (this.oldPassNode.value && this.newPassNode.value && this.confirmPassNode.value);
|
||||||
|
if((!event || event.key == "Enter") && hasVal){
|
||||||
|
if(this.newPassNode.value == this.confirmPassNode.value){
|
||||||
|
const updateObj = {};
|
||||||
|
|
||||||
|
updateObj.passChange = {
|
||||||
|
oldPass: this.oldPassNode.value,
|
||||||
|
newPass: this.newPassNode.value,
|
||||||
|
confirmPass: this.confirmPassNode.value
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await utils.ajax.updateProfile(updateObj);
|
||||||
|
|
||||||
|
if(response != null){
|
||||||
|
//Return user homepage after good pass change, as we've probably been logged out by the server for security.
|
||||||
|
window.location.pathname = '/';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class tokeList{
|
class tokeList{
|
||||||
constructor(){
|
constructor(){
|
||||||
this.tokeList = document.querySelector('#profile-tokes');
|
this.tokeList = document.querySelector('#profile-tokes');
|
||||||
|
|
@ -248,93 +288,6 @@ class changePasswordPopup{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ignoredUsersPopup{
|
|
||||||
constructor(){
|
|
||||||
this.popup = new canopyUXUtils.popup("ignoredUsers", true, this.asyncConstructor.bind(this), document, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
asyncConstructor(){
|
|
||||||
this.ignoredUsersListDiv = document.querySelector('#ignored-users-popup-list-div')
|
|
||||||
this.ignorePrompt = document.querySelector('#ignored-users-popup-prompt');
|
|
||||||
this.ignoreButton = document.querySelector('#ignored-users-popup-button');
|
|
||||||
|
|
||||||
//Refresh ignored list
|
|
||||||
this.refreshList();
|
|
||||||
|
|
||||||
this.setupInput();
|
|
||||||
}
|
|
||||||
|
|
||||||
//grabs and re-renders list, good for asynchronous fire-and-forget usage
|
|
||||||
async refreshList(){
|
|
||||||
this.renderUsers(await utils.ajax.getIgnoredUsers());
|
|
||||||
}
|
|
||||||
|
|
||||||
renderUsers(users){
|
|
||||||
//Clear out list div
|
|
||||||
this.ignoredUsersListDiv.innerHTML = '';
|
|
||||||
|
|
||||||
//run through our ignored users
|
|
||||||
for(const user of users){
|
|
||||||
//Create a div about it
|
|
||||||
const userDiv = document.createElement('div');
|
|
||||||
userDiv.classList.add('ignored-users-popup-ignored-user');
|
|
||||||
|
|
||||||
//Create userlabel
|
|
||||||
const userLabel = document.createElement('p');
|
|
||||||
userLabel.classList.add('ignored-users-popup-ignored-user-label');
|
|
||||||
userLabel.textContent = user.user;
|
|
||||||
|
|
||||||
//Create unignore icon
|
|
||||||
const unignoreIcon = document.createElement('i');
|
|
||||||
unignoreIcon.classList.add('bi-emoji-smile-fill', 'ignored-users-popup-unignore-user-icon');
|
|
||||||
unignoreIcon.title = `Unignore ${user.user}`;
|
|
||||||
|
|
||||||
//Make the unignore button actually fuckin' do something for once in its no-good, lazy, yellowbellied, chicken-fucking life
|
|
||||||
unignoreIcon.addEventListener('click', (event)=>{this.unignore(user.user)});
|
|
||||||
|
|
||||||
//ASSEMBLE
|
|
||||||
userDiv.append(userLabel, unignoreIcon);
|
|
||||||
|
|
||||||
//Render out to popup
|
|
||||||
this.ignoredUsersListDiv.appendChild(userDiv);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setupInput(){
|
|
||||||
this.ignorePrompt.addEventListener('keydown', this.ignore.bind(this));
|
|
||||||
this.ignoreButton.addEventListener('click', this.ignore.bind(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
async ignore(event){
|
|
||||||
//If we clicked or hit enter
|
|
||||||
if(event.key == null || event.key == "Enter"){
|
|
||||||
//Tell server who you wanna ignore and get the new list back
|
|
||||||
const ignoredList = await utils.ajax.ignoreUser(this.ignorePrompt.value);
|
|
||||||
|
|
||||||
//If we received a good list
|
|
||||||
if(ignoredList != null){
|
|
||||||
//Render out received ignored lsit
|
|
||||||
this.renderUsers(ignoredList);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Clear prompt
|
|
||||||
this.ignorePrompt.value = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async unignore(user){
|
|
||||||
//Tell server who you wanna unignore and get the new list back
|
|
||||||
const ignoredList = await utils.ajax.unignoreUser(user);
|
|
||||||
|
|
||||||
//If we received a good list
|
|
||||||
if(ignoredList != null){
|
|
||||||
//Render out received ignored lsit
|
|
||||||
this.renderUsers(ignoredList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class deleteAccountPopup{
|
class deleteAccountPopup{
|
||||||
constructor(){
|
constructor(){
|
||||||
this.popup = new canopyUXUtils.popup("nukeUser", true, this.asyncConstructor.bind(this));
|
this.popup = new canopyUXUtils.popup("nukeUser", true, this.asyncConstructor.bind(this));
|
||||||
|
|
@ -365,5 +318,4 @@ const bioPrompt = new profileUpdateTextPrompt('bio', true);
|
||||||
const profileTokeList = new tokeList();
|
const profileTokeList = new tokeList();
|
||||||
const accountEmailChange = new accountSettingsButton('update-email', changeEmailPopup);
|
const accountEmailChange = new accountSettingsButton('update-email', changeEmailPopup);
|
||||||
const accountPasswordChange = new accountSettingsButton('change-password', changePasswordPopup);
|
const accountPasswordChange = new accountSettingsButton('change-password', changePasswordPopup);
|
||||||
const accountIgnoredUsers = new accountSettingsButton('change-password', changePasswordPopup);
|
const accountDeleteButton = new accountSettingsButton('delete', deleteAccountPopup);
|
||||||
const accountDeleteButton = new accountSettingsButton('ignored-users', ignoredUsersPopup);
|
|
||||||
|
|
@ -885,52 +885,6 @@ class canopyAjaxUtils{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getIgnoredUsers(){
|
|
||||||
var response = await fetch(`/api/account/ignore`,{
|
|
||||||
method: "GET"
|
|
||||||
});
|
|
||||||
|
|
||||||
if(response.ok){
|
|
||||||
return (await response.json())
|
|
||||||
}else{
|
|
||||||
utils.ux.displayResponseError(await response.json());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async ignoreUser(user){
|
|
||||||
const response = await fetch(`/api/account/ignore`,{
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"x-csrf-token": utils.ajax.getCSRFToken()
|
|
||||||
},
|
|
||||||
body: JSON.stringify({user})
|
|
||||||
});
|
|
||||||
|
|
||||||
if(response.ok){
|
|
||||||
return (await response.json())
|
|
||||||
}else{
|
|
||||||
utils.ux.displayResponseError(await response.json());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async unignoreUser(user){
|
|
||||||
const response = await fetch(`/api/account/unignore`,{
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"x-csrf-token": utils.ajax.getCSRFToken()
|
|
||||||
},
|
|
||||||
body: JSON.stringify({user})
|
|
||||||
});
|
|
||||||
|
|
||||||
if(response.ok){
|
|
||||||
return (await response.json())
|
|
||||||
}else{
|
|
||||||
utils.ux.displayResponseError(await response.json());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async deleteAccount(pass){
|
async deleteAccount(pass){
|
||||||
const response = await fetch(`/api/account/delete`,{
|
const response = await fetch(`/api/account/delete`,{
|
||||||
method: "POST",
|
method: "POST",
|
||||||
|
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
<!-- Canopy - The next generation of stoner streaming software
|
|
||||||
Copyright (C) 2024-2026 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/>. -->
|
|
||||||
<!-- <link rel="stylesheet" type="text/css" href="/css/popup/schedule.css"> -->
|
|
||||||
<link rel="stylesheet" type="text/css" href="/css/popup/ignoredUsers.css">
|
|
||||||
<h3 class="popup-title">Ignored Users</h3>
|
|
||||||
<div id="ignored-users-popup">
|
|
||||||
<div id="ignored-users-popup-list-div" class="dynamic-container resizable">
|
|
||||||
</div>
|
|
||||||
<input id="ignored-users-popup-prompt" placeholder="Username">
|
|
||||||
<button class="positive-button" id="ignored-users-popup-button">Ignore User</button>
|
|
||||||
</div>
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue