Initial commit
Signed-off-by: mctaylors <cantsendmails@mctaylors.ru>
This commit is contained in:
commit
5f64caf6bc
13 changed files with 400 additions and 0 deletions
33
activate/index.html
Normal file
33
activate/index.html
Normal 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
18
assets/css/styles.css
Normal 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
22
assets/js/activate.js
Normal 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
22
assets/js/auth.js
Normal 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
48
assets/js/cookie.js
Normal 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
43
assets/js/create.js
Normal 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
28
assets/js/delete.js
Normal 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
15
assets/js/index.js
Normal 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
42
assets/js/shared.js
Normal 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
31
auth/index.html
Normal 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
34
create/index.html
Normal 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
33
delete/index.html
Normal 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
31
index.html
Normal 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>
|
Loading…
Reference in a new issue