Initial commit

Signed-off-by: mctaylors <cantsendmails@mctaylors.ru>
This commit is contained in:
Macintxsh 2024-06-06 22:39:59 +05:00
commit 5f64caf6bc
Signed by: mctaylors
GPG key ID: 4EEF4F949A266EE2
13 changed files with 400 additions and 0 deletions

33
activate/index.html Normal file
View file

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>CensoredManager - Activate</title>
<link rel="stylesheet" href="/assets/css/styles.css"/>
</head>
<body>
<div>
<form id="activate-form">
<label>
Cheque activation form
<br/>
<input id="id" placeholder="ID" required/>
</label>
<button type="submit">Activate</button>
<span id="notification"></span>
</form>
</div>
<hr/>
<div>
<a href=".."><button>Back</button></a>
Balance: <span class="highlighted" id="balance">-</span>
<span class="right footer">
CensoredManager<br/>
<sup><a href="/">home</a> - <a href="https://git.mctaylors.ru/mctaylors/CensoredManager">source code</a></sup>
</span>
</div>
<script src="/assets/js/shared.js"></script>
<script src="/assets/js/cookie.js"></script>
<script src="/assets/js/activate.js"></script>
</body>
</html>

18
assets/css/styles.css Normal file
View file

@ -0,0 +1,18 @@
:root {
}
.highlighted {
font-weight: bold;
}
.right {
float: right;
}
.footer {
font-style: italic;
}
.display {
font-size: 24px;
}

22
assets/js/activate.js Normal file
View file

@ -0,0 +1,22 @@
const token = docCookies.getItem("token");
const notificationElement = document.getElementById("notification");
const balanceElement = document.getElementById("balance");
window.addEventListener("load", async function () {
balanceElement.innerText = await getBalance(token);
});
document.getElementById("activate-form").addEventListener("submit", async (e) => {
e.preventDefault();
const id = document.getElementById("id").value;
const infoResult = await chequeInfo(id);
const activateResult = await activateCheque(token, id);
if (activateResult !== undefined) {
notificationElement.innerText = `+${infoResult['amount']} coins`;
notificationElement.style.color = "green";
balanceElement.innerText = activateResult;
} else {
notificationElement.innerText = "Incorrect ID!";
notificationElement.style.color = "red";
}
});

22
assets/js/auth.js Normal file
View file

@ -0,0 +1,22 @@
const notificationElement = document.getElementById("notification");
const apiProviderElement = document.getElementById("api-provider");
window.addEventListener("load", function () {
apiProviderElement.href = `https://${api_provider}`;
apiProviderElement.innerText = api_provider;
if (docCookies.hasItem('token')) {
document.getElementById('form').innerHTML = 'Already logged in! <a href="/"><button>Home</button></a>';
}
});
document.getElementById("token-form").addEventListener("submit", async (e) => {
e.preventDefault();
const token = document.getElementById("token").value;
if (await getId(token).then(value => value['status'])) {
docCookies.setItem("token", document.getElementById("token").value);
window.location = "/";
} else {
notificationElement.innerText = "Incorrect token!";
notificationElement.style.color = "red";
}
});

48
assets/js/cookie.js Normal file
View file

@ -0,0 +1,48 @@
/*\
|*|
|*| :: cookies.js ::
|*|
|*| A complete cookies reader/writer framework with full unicode support.
|*|
|*| https://developer.mozilla.org/en-US/docs/DOM/document.cookie
|*|
|*| Syntaxes:
|*|
|*| * docCookies.setItem(name, value[, end[, path[, domain[, secure[, samesite]]]]])
|*| * docCookies.getItem(name)
|*| * docCookies.removeItem(name[, path])
|*| * docCookies.hasItem(name)
|*|
\*/
const docCookies = {
getItem: function (sKey) {
if (!sKey || !this.hasItem(sKey)) { return null; }
return unescape(document.cookie.replace(new RegExp("(?:^|.*;\\s*)" + escape(sKey).replace(/[\-.+*]/g, "\\$&") + "\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*"), "$1"));
},
setItem: function (sKey, sValue, vEnd, sPath, sDomain, bSecure, sSameSite) {
if (!sKey || /^(?:expires|max-age|path|domain|secure|samesite)$/i.test(sKey)) { return; }
let sExpires = "";
if (vEnd) {
switch (vEnd.constructor) {
case Number:
sExpires = vEnd === Infinity ? "; expires=Tue, 19 Jan 2038 03:14:07 UTC" : "; max-age=" + vEnd;
break;
case String:
sExpires = "; expires=" + vEnd;
break;
case Date:
sExpires = "; expires=" + vEnd.toUTCString();
break;
}
}
document.cookie = escape(sKey) + "=" + escape(sValue) + sExpires + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : "; path=/") + (bSecure ? "; secure" : "") + (sSameSite ? "; samesite=" + sSameSite : "; samesite=strict");
},
removeItem: function (sKey, sPath) {
if (!sKey || !this.hasItem(sKey)) { return; }
document.cookie = escape(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT" + (sPath ? "; path=" + sPath : "");
},
hasItem: function (sKey) {
return (new RegExp("(?:^|;\\s*)" + escape(sKey).replace(/[\-.+*]/g, "\\$&") + "\\s*\\=")).test(document.cookie);
}
};

43
assets/js/create.js Normal file
View file

@ -0,0 +1,43 @@
const token = docCookies.getItem("token");
const notificationElement = document.getElementById("notification");
const balanceElement = document.getElementById("balance");
let balance;
window.addEventListener("load", async function () {
refreshBalance(await getBalance(token));
});
function refreshBalance(from) {
balance = from;
balanceElement.innerText = balance;
}
document.getElementById("create-form").addEventListener("submit", async (e) => {
e.preventDefault();
const act = parseInt(document.getElementById("act").value);
if (act <= 0) {
notificationElement.innerText = "Activation amount cannot be lower than 0!";
notificationElement.style.color = "red";
return;
}
const amount = parseInt(document.getElementById("amount").value);
const bottleneck = Math.floor(balance / act);
if (amount <= 0 || amount > bottleneck) {
notificationElement.innerText = `Incorrect coin amount. (1-${bottleneck} allowed)`;
notificationElement.style.color = "red";
return;
}
const createResult = await createCheque(token, amount, act);
if (createResult['status']) {
notificationElement.innerHTML = `Cheque has been created.
<button type="button" onclick="navigator.clipboard.writeText(${createResult['id']})">Copy ID</button>
<button type="button" onclick="navigator.clipboard.writeText(
'https://t.me/${telegram_bot}?start=${createResult['id']}')">Copy link</button>`;
notificationElement.style.color = "green";
refreshBalance(createResult['balance']);
} else {
notificationElement.innerText = "Incorrect ID!";
notificationElement.style.color = "red";
}
});

28
assets/js/delete.js Normal file
View file

@ -0,0 +1,28 @@
const token = docCookies.getItem("token");
const notificationElement = document.getElementById("notification");
const balanceElement = document.getElementById("balance");
window.addEventListener("load", async function () {
balanceElement.innerText = await getBalance(token);
});
document.getElementById("delete-form").addEventListener("submit", async (e) => {
e.preventDefault();
const id = document.getElementById("id").value;
const infoResult = await chequeInfo(id);
if (infoResult !== undefined) {
const coinsLeft = infoResult['amount'] * infoResult['count'];
const deleteResult = await deleteCheque(token, id);
if (deleteResult !== undefined) {
notificationElement.innerText = `+${coinsLeft} coins`;
notificationElement.style.color = "green";
balanceElement.innerText = deleteResult;
} else {
notificationElement.innerText = "You do not own this cheque.";
notificationElement.style.color = "red";
}
} else {
notificationElement.innerText = "Incorrect ID!";
notificationElement.style.color = "red";
}
});

15
assets/js/index.js Normal file
View file

@ -0,0 +1,15 @@
const token = docCookies.getItem("token");
const amountElement = document.getElementById("amount");
const listElement = document.getElementById("list");
const userElement = document.getElementById("user");
window.addEventListener("load", async function () {
userElement.innerText = docCookies.getItem("token").substring(0, 4) + "**";
listElement.href = `https://${api_provider}/get_cheques?token=${token}`;
amountElement.innerText = await getBalance(token);
});
function logout() {
docCookies.removeItem("token");
window.location = "/auth/";
}

42
assets/js/shared.js Normal file
View file

@ -0,0 +1,42 @@
window.addEventListener("load", async function () {
if (!docCookies.hasItem("token") && window.location.pathname !== "/auth/") {
window.location = "/auth/";
}
});
const api_provider = 'api.example.com';
const telegram_bot = 'example_bot';
async function getId(token) {
return await fetch(`https://${api_provider}/get_id?token=${token}`)
.then(response => response.json());
}
async function getBalance(token) {
return await fetch(`https://${api_provider}/get_balance?token=${token}`)
.then(response => response.json())
.then(value => value['balance']);
}
async function createCheque(token, amount, act) {
return await fetch(`https://${api_provider}/create_cheque?token=${token}&amount=${amount}&act=${act}`)
.then(response => response.json());
}
async function deleteCheque(token, id) {
return await fetch(`https://${api_provider}/delete_cheque?token=${token}&id=${id}`)
.then(response => response.json())
.then(value => value['balance']);
}
async function activateCheque(token, id) {
return await fetch(`https://${api_provider}/activate_cheque?token=${token}&id=${id}`)
.then(response => response.json())
.then(value => value['balance']);
}
async function chequeInfo(id) {
return await fetch(`https://${api_provider}/cheque_info?id=${id}`)
.then(response => response.json())
.then(value => value['info']);
}

31
auth/index.html Normal file
View file

@ -0,0 +1,31 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>CensoredManager - Auth</title>
<link rel="stylesheet" href="/assets/css/styles.css"/>
</head>
<body>
<div id="form">
<form id="token-form">
<label>
Authorize by using <a id="api-provider"></a> token.
<br/>
<input type="password" id="token" placeholder="Token" required/>
</label>
<button type="submit">Authorize</button>
<span id="notification"></span>
</form>
</div>
<hr/>
<div>
<span class="right footer">
CensoredManager<br/>
<sup><s>home</s> - <a href="https://git.mctaylors.ru/mctaylors/CensoredManager">source code</a></sup>
</span>
</div>
<script src="/assets/js/shared.js"></script>
<script src="/assets/js/cookie.js"></script>
<script src="/assets/js/auth.js"></script>
</body>
</html>

34
create/index.html Normal file
View file

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>CensoredManager - Create</title>
<link rel="stylesheet" href="/assets/css/styles.css"/>
</head>
<body>
<div>
<form id="create-form">
<label>
Cheque creation form
<br/>
<input type="number" id="amount" placeholder="Coin amount (per activation)" required/>
<input type="number" id="act" placeholder="Activation amount" required/>
</label>
<button type="submit">Create</button>
<span id="notification"></span>
</form>
</div>
<hr/>
<div>
<a href=".."><button>Back</button></a>
Balance: <span class="highlighted" id="balance">-</span>
<span class="right footer">
CensoredManager<br/>
<sup><a href="/">home</a> - <a href="https://git.mctaylors.ru/mctaylors/CensoredManager">source code</a></sup>
</span>
</div>
<script src="/assets/js/shared.js"></script>
<script src="/assets/js/cookie.js"></script>
<script src="/assets/js/create.js"></script>
</body>
</html>

33
delete/index.html Normal file
View file

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>CensoredManager - Delete</title>
<link rel="stylesheet" href="/assets/css/styles.css"/>
</head>
<body>
<div>
<form id="delete-form">
<label>
Cheque deletion form
<br/>
<input id="id" placeholder="ID" required/>
</label>
<button type="submit">Delete</button>
<span id="notification"></span>
</form>
</div>
<hr/>
<div>
<a href=".."><button>Back</button></a>
Balance: <span class="highlighted" id="balance">-</span>
<span class="right footer">
CensoredManager<br/>
<sup><a href="/">home</a> - <a href="https://git.mctaylors.ru/mctaylors/CensoredManager">source code</a></sup>
</span>
</div>
<script src="/assets/js/shared.js"></script>
<script src="/assets/js/cookie.js"></script>
<script src="/assets/js/delete.js"></script>
</body>
</html>

31
index.html Normal file
View file

@ -0,0 +1,31 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>CensoredManager</title>
<link rel="stylesheet" href="/assets/css/styles.css"/>
</head>
<body>
<div class="right">
Logged in as <span class="highlighted" id="user"></span>
<button onclick="logout()">Logout</button>
</div>
<div>
<span class="highlighted display" id="amount">-</span> coins
</div>
<hr/>
<div>
<a href="activate"><button>Activate</button></a>
<a href="create"><button>Create</button></a>
<a href="delete"><button>Delete</button></a>
<a id="list"><button>List<sup>JSON</sup></button></a>
<span class="right footer">
CensoredManager<br/>
<sup><b>home</b> - <a href="https://git.mctaylors.ru/mctaylors/CensoredManager">source code</a></sup>
</span>
</div>
<script src="/assets/js/shared.js"></script>
<script src="/assets/js/cookie.js"></script>
<script src="/assets/js/index.js"></script>
</body>
</html>