add mod support and banning

This commit is contained in:
Elijah R 2024-04-29 12:35:05 -04:00
parent 57095b2371
commit 6faad4b13a
4 changed files with 105 additions and 49 deletions

View file

@ -1,3 +1,3 @@
export const Config = { export const Config = {
APIEndpoint: "https://auth.collabvm.org" APIEndpoint: "http://127.0.0.1:5858"
}; };

View file

@ -80,7 +80,8 @@
<th>Username</th> <th>Username</th>
<th>Email</th> <th>Email</th>
<th>Rank</th> <th>Rank</th>
<th>Banned</th> <th>Banned?</th>
<th>Ban Reason</th>
<th>Date of Birth</th> <th>Date of Birth</th>
<th>Created At</th> <th>Created At</th>
<th>Registration IP</th> <th>Registration IP</th>

View file

@ -129,6 +129,26 @@ export default class AuthManager {
}); });
} }
setUserBan(username : string, banned : boolean, reason : string | undefined = undefined) {
return new Promise<BanResult>(async res => {
if (!this.account) throw new Error("Cannot ban/unban without logging in first");
var data = await fetch(this.apiEndpoint + "/api/v1/admin/ban", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
token: this.account.sessionToken,
username: username,
banned: banned,
reason: reason
})
});
var json = await data.json() as BanResult;
res(json);
});
}
listBots(resultsPerPage : number, page : number, owner : string | undefined) { listBots(resultsPerPage : number, page : number, owner : string | undefined) {
return new Promise<ListBotsResult>(async res => { return new Promise<ListBotsResult>(async res => {
var data = await fetch(this.apiEndpoint + "/api/v1/bots/list", { var data = await fetch(this.apiEndpoint + "/api/v1/bots/list", {
@ -233,6 +253,7 @@ export interface User {
email : string; email : string;
rank : number; rank : number;
banned : boolean; banned : boolean;
banReason : string;
dateOfBirth : string; dateOfBirth : string;
dateJoined : string; dateJoined : string;
registrationIp : string; registrationIp : string;
@ -276,3 +297,8 @@ export interface AdminUpdateBotResult {
success : boolean; success : boolean;
error : string | undefined; error : string | undefined;
} }
export interface BanResult {
success : boolean;
error : string | undefined;
}

View file

@ -61,35 +61,33 @@ var hcaptchaid : string;
elements.adminLoginForm.addEventListener('submit', async e => { elements.adminLoginForm.addEventListener('submit', async e => {
e.preventDefault(); e.preventDefault();
if (auth.info!.hcaptcha.required) { var hcaptchaToken = undefined;
var hcaptchaToken = undefined; if (auth!.info!.hcaptcha.required) {
if (auth!.info!.hcaptcha.required) { var response = hcaptcha.getResponse(hcaptchaid);
var response = hcaptcha.getResponse(hcaptchaid); if (response === "") {
if (response === "") { alert("Missing captcha!");
alert("Missing captcha!"); return false;
}
hcaptchaToken = response;
}
var result = await auth.login(elements.loginUsername.value, elements.loginPassword.value, hcaptchaToken);
elements.loginUsername.value = "";
elements.loginPassword.value = "";
if (auth!.info!.hcaptcha.required) hcaptcha.reset(hcaptchaid);
if (result.success) {
if (result.rank !== 2 && result.rank !== 3) {
if (!result.developer) {
alert("You have no power here!");
await auth.logout();
return false; return false;
} }
hcaptchaToken = response; elements.usersNavLink.style.display = "none";
} loadBotsView();
var result = await auth.login(elements.loginUsername.value, elements.loginPassword.value, hcaptchaToken); } else loadUsersView();
elements.loginUsername.value = ""; localStorage.setItem(`collabvm_session_${new URL(Config.APIEndpoint).host}`, result.token!);
elements.loginPassword.value = ""; loadAdminView();
hcaptcha.reset(hcaptchaid); } else {
if (result.success) { alert("Login failed: " + result.error);
if (result.rank !== 2) {
if (!result.developer) {
alert("You have no power here!");
await auth.logout();
return false;
}
elements.usersNavLink.style.display = "none";
loadBotsView();
} else loadUsersView();
localStorage.setItem(`collabvm_session_${new URL(Config.APIEndpoint).host}`, result.token!);
loadAdminView();
} else {
alert("Login failed: " + result.error);
}
} }
return false; return false;
}); });
@ -133,26 +131,57 @@ elements.searchUsersForm.addEventListener('submit', async e => {
cell.innerText = user.email; cell.innerText = user.email;
cell = row.insertCell(); cell = row.insertCell();
// Rank dropdown // Rank dropdown
var rankSelect = document.createElement('select'); if (auth.account!.rank === 2) {
rankSelect.classList.add('form-select'); var rankSelect = document.createElement('select');
rankSelect.innerHTML = `<option value="1">User</option><option value="2">Administrator</option><option value="3">Moderator</option>`; rankSelect.classList.add('form-select');
rankSelect.value = user.rank.toString(10); rankSelect.innerHTML = `<option value="1">User</option><option value="2">Administrator</option><option value="3">Moderator</option>`;
rankSelect.addEventListener('change', async e => { rankSelect.value = user.rank.toString(10);
var newRank = parseInt(rankSelect.value); rankSelect.addEventListener('change', async e => {
var newRank = parseInt(rankSelect.value);
// @ts-ignore
if (!window.confirm(`Are you sure you want to set ${user.username}'s rank to ${RankString[newRank]}?`)) {
e.preventDefault();
rankSelect.value = user.rank.toString(10);
return false;
}
var result = await auth.updateUser(user.username, newRank);
if (!result.success) {
alert("Failed to set rank: " + result.error);
}
});
cell.appendChild(rankSelect);
} else {
// @ts-ignore // @ts-ignore
if (!window.confirm(`Are you sure you want to set ${user.username}'s rank to ${RankString[newRank]}?`)) { cell.innerText = RankString[user.rank];
e.preventDefault(); }
rankSelect.value = user.rank.toString(10); cell = row.insertCell();
return false; var bannedCheckbox = document.createElement('input');
} bannedCheckbox.type = 'checkbox';
var result = await auth.updateUser(user.username, newRank); bannedCheckbox.checked = user.banned;
if (!result.success) { bannedCheckbox.addEventListener('change', async e => {
alert("Failed to set rank: " + result.error); var banned = bannedCheckbox.checked;
if (banned) {
var reason = window.prompt(`Enter a reason for banning ${user.username}:`);
if (reason === null || reason === "") {
e.preventDefault();
bannedCheckbox.checked = false;
return false;
}
await auth.setUserBan(user.username, true, reason);
banReasonCell.innerText = reason;
} else {
if (!window.confirm(`Are you sure you want to unban ${user.username}?`)) {
e.preventDefault();
bannedCheckbox.checked = true;
return false;
}
await auth.setUserBan(user.username, false);
banReasonCell.innerText = "";
} }
}); });
cell.appendChild(rankSelect); cell.appendChild(bannedCheckbox);
cell = row.insertCell(); var banReasonCell = row.insertCell();
cell.innerText = user.banned ? "Yes" : "No"; banReasonCell.innerText = user.banReason;
cell = row.insertCell(); cell = row.insertCell();
cell.innerText = user.dateOfBirth; cell.innerText = user.dateOfBirth;
cell = row.insertCell(); cell = row.insertCell();
@ -220,10 +249,10 @@ elements.searchBotsForm.addEventListener('submit', async e => {
cell = row.insertCell(); cell = row.insertCell();
cell.innerText = bot.username; cell.innerText = bot.username;
cell = row.insertCell(); cell = row.insertCell();
if (auth!.account!.rank === 2) { if (auth!.account!.rank === 2 || auth!.account!.username === bot.owner) {
var rankSelect = document.createElement('select'); var rankSelect = document.createElement('select');
rankSelect.classList.add('form-select'); rankSelect.classList.add('form-select');
rankSelect.innerHTML = `<option value="1">User</option><option value="2">Administrator</option><option value="3">Moderator</option>`; rankSelect.innerHTML = `<option value="1">User</option>${auth!.account!.rank === 2 && `<option value="2">Administrator</option>`}<option value="3">Moderator</option>`;
rankSelect.value = bot.rank.toString(10); rankSelect.value = bot.rank.toString(10);
rankSelect.addEventListener('change', async e => { rankSelect.addEventListener('change', async e => {
var newRank = parseInt(rankSelect.value); var newRank = parseInt(rankSelect.value);
@ -286,7 +315,7 @@ elements.createBotForm.addEventListener('submit', async e => {
if (token) { if (token) {
var session = await auth.loadSession(token); var session = await auth.loadSession(token);
if (session.success) { if (session.success) {
if (session.rank! !== 2) { if (session.rank! !== 2 && session.rank! !== 3) {
if (!session.developer) { if (!session.developer) {
await auth.logout(); await auth.logout();
localStorage.removeItem(`collabvm_session_${new URL(Config.APIEndpoint).host}`); localStorage.removeItem(`collabvm_session_${new URL(Config.APIEndpoint).host}`);