diff --git a/Config.ts b/Config.ts
index ba970ef..62d8506 100644
--- a/Config.ts
+++ b/Config.ts
@@ -1,3 +1,3 @@
export const Config = {
- APIEndpoint: "https://auth.collabvm.org"
+ APIEndpoint: "http://127.0.0.1:5858"
};
\ No newline at end of file
diff --git a/src/html/index.html b/src/html/index.html
index 15b9647..66d7763 100644
--- a/src/html/index.html
+++ b/src/html/index.html
@@ -80,7 +80,8 @@
Username |
Email |
Rank |
- Banned |
+ Banned? |
+ Ban Reason |
Date of Birth |
Created At |
Registration IP |
diff --git a/src/ts/AuthManager.ts b/src/ts/AuthManager.ts
index 980c07a..db57344 100644
--- a/src/ts/AuthManager.ts
+++ b/src/ts/AuthManager.ts
@@ -129,6 +129,26 @@ export default class AuthManager {
});
}
+ setUserBan(username : string, banned : boolean, reason : string | undefined = undefined) {
+ return new Promise(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) {
return new Promise(async res => {
var data = await fetch(this.apiEndpoint + "/api/v1/bots/list", {
@@ -233,6 +253,7 @@ export interface User {
email : string;
rank : number;
banned : boolean;
+ banReason : string;
dateOfBirth : string;
dateJoined : string;
registrationIp : string;
@@ -275,4 +296,9 @@ export interface CreateBotResult {
export interface AdminUpdateBotResult {
success : boolean;
error : string | undefined;
+}
+
+export interface BanResult {
+ success : boolean;
+ error : string | undefined;
}
\ No newline at end of file
diff --git a/src/ts/main.ts b/src/ts/main.ts
index 44558c6..bf4faab 100644
--- a/src/ts/main.ts
+++ b/src/ts/main.ts
@@ -61,35 +61,33 @@ var hcaptchaid : string;
elements.adminLoginForm.addEventListener('submit', async e => {
e.preventDefault();
- if (auth.info!.hcaptcha.required) {
- var hcaptchaToken = undefined;
- if (auth!.info!.hcaptcha.required) {
- var response = hcaptcha.getResponse(hcaptchaid);
- if (response === "") {
- alert("Missing captcha!");
+ var hcaptchaToken = undefined;
+ if (auth!.info!.hcaptcha.required) {
+ var response = hcaptcha.getResponse(hcaptchaid);
+ if (response === "") {
+ 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;
}
- hcaptchaToken = response;
- }
- var result = await auth.login(elements.loginUsername.value, elements.loginPassword.value, hcaptchaToken);
- elements.loginUsername.value = "";
- elements.loginPassword.value = "";
- hcaptcha.reset(hcaptchaid);
- if (result.success) {
- 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);
- }
+ 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;
});
@@ -133,26 +131,57 @@ elements.searchUsersForm.addEventListener('submit', async e => {
cell.innerText = user.email;
cell = row.insertCell();
// Rank dropdown
- var rankSelect = document.createElement('select');
- rankSelect.classList.add('form-select');
- rankSelect.innerHTML = ``;
- rankSelect.value = user.rank.toString(10);
- rankSelect.addEventListener('change', async e => {
- var newRank = parseInt(rankSelect.value);
+ if (auth.account!.rank === 2) {
+ var rankSelect = document.createElement('select');
+ rankSelect.classList.add('form-select');
+ rankSelect.innerHTML = ``;
+ rankSelect.value = user.rank.toString(10);
+ 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
- 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.innerText = RankString[user.rank];
+ }
+ cell = row.insertCell();
+ var bannedCheckbox = document.createElement('input');
+ bannedCheckbox.type = 'checkbox';
+ bannedCheckbox.checked = user.banned;
+ bannedCheckbox.addEventListener('change', async e => {
+ 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 = row.insertCell();
- cell.innerText = user.banned ? "Yes" : "No";
+ cell.appendChild(bannedCheckbox);
+ var banReasonCell = row.insertCell();
+ banReasonCell.innerText = user.banReason;
cell = row.insertCell();
cell.innerText = user.dateOfBirth;
cell = row.insertCell();
@@ -220,10 +249,10 @@ elements.searchBotsForm.addEventListener('submit', async e => {
cell = row.insertCell();
cell.innerText = bot.username;
cell = row.insertCell();
- if (auth!.account!.rank === 2) {
+ if (auth!.account!.rank === 2 || auth!.account!.username === bot.owner) {
var rankSelect = document.createElement('select');
rankSelect.classList.add('form-select');
- rankSelect.innerHTML = ``;
+ rankSelect.innerHTML = `${auth!.account!.rank === 2 && ``}`;
rankSelect.value = bot.rank.toString(10);
rankSelect.addEventListener('change', async e => {
var newRank = parseInt(rankSelect.value);
@@ -286,7 +315,7 @@ elements.createBotForm.addEventListener('submit', async e => {
if (token) {
var session = await auth.loadSession(token);
if (session.success) {
- if (session.rank! !== 2) {
+ if (session.rank! !== 2 && session.rank! !== 3) {
if (!session.developer) {
await auth.logout();
localStorage.removeItem(`collabvm_session_${new URL(Config.APIEndpoint).host}`);