PIN verification, notifications, multiple notif providers
Discord, Email & Telegram can be enabled, although email is always enabled right now (will fix). Also apparently markdown hyperlinks don't work in Discord, eventually will implement something to convert them to embeds.
This commit is contained in:
+54
-1
@@ -8,12 +8,16 @@ interface formWindow extends Window {
|
||||
invalidPassword: string;
|
||||
successModal: Modal;
|
||||
telegramModal: Modal;
|
||||
discordModal: Modal;
|
||||
confirmationModal: Modal
|
||||
code: string;
|
||||
messages: { [key: string]: string };
|
||||
confirmation: boolean;
|
||||
telegramRequired: boolean;
|
||||
telegramPIN: string;
|
||||
discordRequired: boolean;
|
||||
discordPIN: string;
|
||||
discordStartCommand: string;
|
||||
userExpiryEnabled: boolean;
|
||||
userExpiryMonths: number;
|
||||
userExpiryDays: number;
|
||||
@@ -68,7 +72,7 @@ if (window.telegramEnabled) {
|
||||
telegramVerified = true;
|
||||
waiting.classList.add("~positive");
|
||||
waiting.classList.remove("~info");
|
||||
window.notifications.customPositive("telegramVerified", "", window.messages["telegramVerified"]);
|
||||
window.notifications.customPositive("telegramVerified", "", window.messages["verified"]);
|
||||
setTimeout(window.telegramModal.close, 2000);
|
||||
telegramButton.classList.add("unfocused");
|
||||
document.getElementById("contact-via").classList.remove("unfocused");
|
||||
@@ -84,6 +88,46 @@ if (window.telegramEnabled) {
|
||||
};
|
||||
}
|
||||
|
||||
var discordVerified = false;
|
||||
if (window.discordEnabled) {
|
||||
window.discordModal = new Modal(document.getElementById("modal-discord"), window.discordRequired);
|
||||
const discordButton = document.getElementById("link-discord") as HTMLSpanElement;
|
||||
discordButton.onclick = () => {
|
||||
const waiting = document.getElementById("discord-waiting") as HTMLSpanElement;
|
||||
toggleLoader(waiting);
|
||||
window.discordModal.show();
|
||||
let modalClosed = false;
|
||||
window.discordModal.onclose = () => {
|
||||
modalClosed = true;
|
||||
toggleLoader(waiting);
|
||||
}
|
||||
const checkVerified = () => _get("/invite/" + window.code + "/discord/verified/" + window.discordPIN, null, (req: XMLHttpRequest) => {
|
||||
if (req.readyState == 4) {
|
||||
if (req.status == 401) {
|
||||
window.discordModal.close();
|
||||
window.notifications.customError("invalidCodeError", window.messages["errorInvalidCode"]);
|
||||
return;
|
||||
} else if (req.status == 200) {
|
||||
if (req.response["success"] as boolean) {
|
||||
discordVerified = true;
|
||||
waiting.classList.add("~positive");
|
||||
waiting.classList.remove("~info");
|
||||
window.notifications.customPositive("discordVerified", "", window.messages["verified"]);
|
||||
setTimeout(window.discordModal.close, 2000);
|
||||
discordButton.classList.add("unfocused");
|
||||
document.getElementById("contact-via").classList.remove("unfocused");
|
||||
const radio = document.getElementById("contact-via-discord") as HTMLInputElement;
|
||||
radio.checked = true;
|
||||
} else if (!modalClosed) {
|
||||
setTimeout(checkVerified, 1500);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
checkVerified();
|
||||
};
|
||||
}
|
||||
|
||||
if (window.confirmation) {
|
||||
window.confirmationModal = new Modal(document.getElementById("modal-confirmation"), true);
|
||||
}
|
||||
@@ -161,6 +205,8 @@ interface sendDTO {
|
||||
password: string;
|
||||
telegram_pin?: string;
|
||||
telegram_contact?: boolean;
|
||||
discord_pin?: string;
|
||||
discord_contact?: boolean;
|
||||
}
|
||||
|
||||
const create = (event: SubmitEvent) => {
|
||||
@@ -179,6 +225,13 @@ const create = (event: SubmitEvent) => {
|
||||
send.telegram_contact = true;
|
||||
}
|
||||
}
|
||||
if (discordVerified) {
|
||||
send.discord_pin = window.discordPIN;
|
||||
const radio = document.getElementById("contact-via-discord") as HTMLInputElement;
|
||||
if (radio.checked) {
|
||||
send.discord_contact = true;
|
||||
}
|
||||
}
|
||||
_post("/newUser", send, (req: XMLHttpRequest) => {
|
||||
if (req.readyState == 4) {
|
||||
let vals = req.response as respDTO;
|
||||
|
||||
+152
-18
@@ -7,12 +7,16 @@ interface User {
|
||||
id: string;
|
||||
name: string;
|
||||
email: string | undefined;
|
||||
notify_email: boolean;
|
||||
last_active: number;
|
||||
admin: boolean;
|
||||
disabled: boolean;
|
||||
expiry: number;
|
||||
telegram: string;
|
||||
notify_telegram: boolean;
|
||||
discord: string;
|
||||
notify_discord: boolean;
|
||||
discord_id: string;
|
||||
}
|
||||
|
||||
interface getPinResponse {
|
||||
@@ -27,11 +31,16 @@ class user implements User {
|
||||
private _admin: HTMLSpanElement;
|
||||
private _disabled: HTMLSpanElement;
|
||||
private _email: HTMLInputElement;
|
||||
private _notifyEmail: boolean;
|
||||
private _emailAddress: string;
|
||||
private _emailEditButton: HTMLElement;
|
||||
private _telegram: HTMLTableDataCellElement;
|
||||
private _telegramUsername: string;
|
||||
private _notifyTelegram: boolean;
|
||||
private _discord: HTMLTableDataCellElement;
|
||||
private _discordUsername: string;
|
||||
private _discordID: string;
|
||||
private _notifyDiscord: boolean;
|
||||
private _expiry: HTMLTableDataCellElement;
|
||||
private _expiryUnix: number;
|
||||
private _lastActive: HTMLTableDataCellElement;
|
||||
@@ -81,6 +90,19 @@ class user implements User {
|
||||
this._email.textContent = value;
|
||||
}
|
||||
}
|
||||
|
||||
get notify_email(): boolean { return this._notifyEmail; }
|
||||
set notify_email(s: boolean) {
|
||||
this._notifyEmail = s;
|
||||
if (window.telegramEnabled && this._telegramUsername != "") {
|
||||
const email = this._telegram.getElementsByClassName("accounts-contact-email")[0] as HTMLInputElement;
|
||||
email.checked = s;
|
||||
}
|
||||
if (window.discordEnabled && this._discordUsername != "") {
|
||||
const email = this._discord.getElementsByClassName("accounts-contact-email")[0] as HTMLInputElement;
|
||||
email.checked = s;
|
||||
}
|
||||
}
|
||||
|
||||
get telegram(): string { return this._telegramUsername; }
|
||||
set telegram(u: string) {
|
||||
@@ -90,7 +112,7 @@ class user implements User {
|
||||
this._telegram.innerHTML = `<span class="chip btn !low">Add</span>`;
|
||||
(this._telegram.querySelector("span") as HTMLSpanElement).onclick = this._addTelegram;
|
||||
} else {
|
||||
this._telegram.innerHTML = `
|
||||
let innerHTML = `
|
||||
<a href="https://t.me/${u}" target="_blank">@${u}</a>
|
||||
<i class="icon ri-settings-2-line ml-half dropdown-button"></i>
|
||||
<div class="dropdown manual">
|
||||
@@ -98,23 +120,34 @@ class user implements User {
|
||||
<div class="card ~neutral !low">
|
||||
<span class="supra sm">${window.lang.strings("contactThrough")}</span>
|
||||
<label class="switch pb-1 mt-half">
|
||||
<input type="radio" name="accounts-contact-${this.id}" class="accounts-contact-email">
|
||||
<input type="checkbox" name="accounts-contact-${this.id}" class="accounts-contact-email">
|
||||
<span>Email</span>
|
||||
</label>
|
||||
<label class="switch pb-1">
|
||||
<input type="radio" name="accounts-contact-${this.id}">
|
||||
<input type="checkbox" name="accounts-contact-${this.id}" class="accounts-contact-telegram">
|
||||
<span>Telegram</span>
|
||||
</label>
|
||||
`;
|
||||
if (window.discordEnabled && this._discordUsername != "") {
|
||||
innerHTML += `
|
||||
<label class="switch pb-1">
|
||||
<input type="checkbox" name="accounts-contact-${this.id}" class="accounts-contact-discord">
|
||||
<span>Discord</span>
|
||||
</label>
|
||||
`;
|
||||
}
|
||||
innerHTML += `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
this._discord.innerHTML = innerHTML;
|
||||
// Javascript is necessary as including the button inside the dropdown would make it too wide to display next to the username.
|
||||
const button = this._telegram.querySelector("i");
|
||||
const dropdown = this._telegram.querySelector("div.dropdown") as HTMLDivElement;
|
||||
const radios = this._telegram.querySelectorAll("input") as NodeListOf<HTMLInputElement>;
|
||||
for (let i = 0; i < radios.length; i++) {
|
||||
radios[i].onclick = this._setTelegramNotify;
|
||||
const checks = this._telegram.querySelectorAll("input") as NodeListOf<HTMLInputElement>;
|
||||
for (let i = 0; i < checks.length; i++) {
|
||||
checks[i].onclick = () => this._setNotifyMethod("telegram");
|
||||
}
|
||||
|
||||
button.onclick = () => {
|
||||
@@ -134,36 +167,128 @@ class user implements User {
|
||||
set notify_telegram(s: boolean) {
|
||||
if (!window.telegramEnabled || !this._telegramUsername) return;
|
||||
this._notifyTelegram = s;
|
||||
const radios = this._telegram.querySelectorAll("input") as NodeListOf<HTMLInputElement>;
|
||||
radios[0].checked = !s;
|
||||
radios[1].checked = s;
|
||||
const telegram = this._telegram.getElementsByClassName("accounts-contact-telegram")[0] as HTMLInputElement;
|
||||
telegram.checked = s;
|
||||
if (window.discordEnabled && this._discordUsername != "") {
|
||||
const telegram = this._discord.getElementsByClassName("accounts-contact-telegram")[0] as HTMLInputElement;
|
||||
telegram.checked = s;
|
||||
}
|
||||
}
|
||||
|
||||
private _setTelegramNotify = () => {
|
||||
const radios = this._telegram.querySelectorAll("input") as NodeListOf<HTMLInputElement>;
|
||||
private _setNotifyMethod = (mode: string = "telegram") => {
|
||||
let el: HTMLElement;
|
||||
if (mode == "telegram") { el = this._telegram }
|
||||
else if (mode == "discord") { el = this._discord }
|
||||
const email = el.getElementsByClassName("accounts-contact-email")[0] as HTMLInputElement;
|
||||
let send = {
|
||||
id: this.id,
|
||||
enabled: radios[1].checked
|
||||
};
|
||||
_post("/users/telegram/notify", send, (req: XMLHttpRequest) => {
|
||||
email: email.checked
|
||||
}
|
||||
if (window.telegramEnabled && this._telegramUsername != "") {
|
||||
const telegram = el.getElementsByClassName("accounts-contact-telegram")[0] as HTMLInputElement;
|
||||
send["telegram"] = telegram.checked;
|
||||
}
|
||||
if (window.discordEnabled && this._discordUsername != "") {
|
||||
const discord = el.getElementsByClassName("accounts-contact-discord")[0] as HTMLInputElement;
|
||||
send["discord"] = discord.checked;
|
||||
}
|
||||
_post("/users/contact", send, (req: XMLHttpRequest) => {
|
||||
if (req.readyState == 4) {
|
||||
if (req.status != 200) {
|
||||
window.notifications.customError("errorSetTelegramNotify", window.lang.notif("errorSaveSettings"));
|
||||
radios[0].checked, radios[1].checked= radios[1].checked, radios[0].checked;
|
||||
window.notifications.customError("errorSetNotify", window.lang.notif("errorSaveSettings"));
|
||||
document.dispatchEvent(new CustomEvent("accounts-reload"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}, false, (req: XMLHttpRequest) => {
|
||||
if (req.status == 0) {
|
||||
window.notifications.connectionError();
|
||||
radios[0].checked, radios[1].checked= radios[1].checked, radios[0].checked;
|
||||
document.dispatchEvent(new CustomEvent("accounts-reload"));
|
||||
return;
|
||||
} else if (req.status == 401) {
|
||||
radios[0].checked, radios[1].checked= radios[1].checked, radios[0].checked;
|
||||
window.notifications.customError("401Error", window.lang.notif("error401Unauthorized"));
|
||||
document.dispatchEvent(new CustomEvent("accounts-reload"));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
get discord(): string { return this._discordUsername; }
|
||||
set discord(u: string) {
|
||||
if (!window.discordEnabled) return;
|
||||
this._discordUsername = u;
|
||||
if (u == "") {
|
||||
this._discord.innerHTML = `<span class="chip btn !low">Add</span>`;
|
||||
// (this._discord.querySelector("span") as HTMLSpanElement).onclick = this._addDiscord;
|
||||
} else {
|
||||
let innerHTML = `
|
||||
<a href="https://discord.com/users/${this._discordID}" class="discord-link" target="_blank">@${u}</a>
|
||||
<i class="icon ri-settings-2-line ml-half dropdown-button"></i>
|
||||
<div class="dropdown manual">
|
||||
<div class="dropdown-display">
|
||||
<div class="card ~neutral !low">
|
||||
<span class="supra sm">${window.lang.strings("contactThrough")}</span>
|
||||
<label class="switch pb-1 mt-half">
|
||||
<input type="radio" name="accounts-contact-${this.id}" class="accounts-contact-email">
|
||||
<span>Email</span>
|
||||
</label>
|
||||
<label class="switch pb-1">
|
||||
<input type="radio" name="accounts-contact-${this.id}" class="accounts-contact-discord">
|
||||
<span>Discord</span>
|
||||
</label>
|
||||
`;
|
||||
if (window.telegramEnabled && this._telegramUsername != "") {
|
||||
innerHTML += `
|
||||
<label class="switch pb-1">
|
||||
<input type="radio" name="accounts-contact-${this.id}" class="accounts-contact-telegram">
|
||||
<span>Telegram</span>
|
||||
</label>
|
||||
`;
|
||||
}
|
||||
innerHTML += `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
this._discord.innerHTML = innerHTML;
|
||||
// Javascript is necessary as including the button inside the dropdown would make it too wide to display next to the username.
|
||||
const button = this._discord.querySelector("i");
|
||||
const dropdown = this._discord.querySelector("div.dropdown") as HTMLDivElement;
|
||||
const checks = this._discord.querySelectorAll("input") as NodeListOf<HTMLInputElement>;
|
||||
for (let i = 0; i < checks.length; i++) {
|
||||
checks[i].onclick = () => this._setNotifyMethod("discord");
|
||||
}
|
||||
|
||||
button.onclick = () => {
|
||||
dropdown.classList.add("selected");
|
||||
document.addEventListener("click", outerClickListener);
|
||||
};
|
||||
const outerClickListener = (event: Event) => {
|
||||
if (!(event.target instanceof HTMLElement && (this._discord.contains(event.target) || button.contains(event.target)))) {
|
||||
dropdown.classList.remove("selected");
|
||||
document.removeEventListener("click", outerClickListener);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
get discord_id(): string { return this._discordID; }
|
||||
set discord_id(id: string) {
|
||||
this._discordID = id;
|
||||
const link = this._discord.getElementsByClassName("discord-link")[0] as HTMLAnchorElement;
|
||||
link.href = `https://discord.com/users/${id}`;
|
||||
}
|
||||
|
||||
get notify_discord(): boolean { return this._notifyDiscord; }
|
||||
set notify_discord(s: boolean) {
|
||||
if (!window.discordEnabled || !this._discordUsername) return;
|
||||
this._notifyDiscord = s;
|
||||
const discord = this._discord.getElementsByClassName("accounts-contact-discord")[0] as HTMLInputElement;
|
||||
discord.checked = s;
|
||||
if (window.telegramEnabled && this._telegramUsername != "") {
|
||||
const discord = this._discord.getElementsByClassName("accounts-contact-discord")[0] as HTMLInputElement;
|
||||
discord.checked = s;
|
||||
}
|
||||
}
|
||||
|
||||
get expiry(): number { return this._expiryUnix; }
|
||||
set expiry(unix: number) {
|
||||
@@ -200,6 +325,11 @@ class user implements User {
|
||||
<td class="accounts-telegram"></td>
|
||||
`;
|
||||
}
|
||||
if (window.discordEnabled) {
|
||||
innerHTML += `
|
||||
<td class="accounts-discord"></td>
|
||||
`;
|
||||
}
|
||||
innerHTML += `
|
||||
<td class="accounts-expiry"></td>
|
||||
<td class="accounts-last-active"></td>
|
||||
@@ -213,6 +343,7 @@ class user implements User {
|
||||
this._email = this._row.querySelector(".accounts-email-container") as HTMLInputElement;
|
||||
this._emailEditButton = this._row.querySelector(".accounts-email-edit") as HTMLElement;
|
||||
this._telegram = this._row.querySelector(".accounts-telegram") as HTMLTableDataCellElement;
|
||||
this._discord = this._row.querySelector(".accounts-discord") as HTMLTableDataCellElement;
|
||||
this._expiry = this._row.querySelector(".accounts-expiry") as HTMLTableDataCellElement;
|
||||
this._lastActive = this._row.querySelector(".accounts-last-active") as HTMLTableDataCellElement;
|
||||
this._check.onchange = () => { this.selected = this._check.checked; }
|
||||
@@ -320,11 +451,14 @@ class user implements User {
|
||||
this.name = user.name;
|
||||
this.email = user.email || "";
|
||||
this.telegram = user.telegram;
|
||||
this.discord = user.discord;
|
||||
this.last_active = user.last_active;
|
||||
this.admin = user.admin;
|
||||
this.disabled = user.disabled;
|
||||
this.expiry = user.expiry;
|
||||
this.notify_telegram = user.notify_telegram;
|
||||
this.notify_discord = user.notify_discord;
|
||||
this.notify_email = user.notify_email;
|
||||
}
|
||||
|
||||
asElement = (): HTMLTableRowElement => { return this._row; }
|
||||
|
||||
@@ -21,6 +21,7 @@ declare interface Window {
|
||||
notificationsEnabled: boolean;
|
||||
emailEnabled: boolean;
|
||||
telegramEnabled: boolean;
|
||||
discordEnabled: boolean;
|
||||
ombiEnabled: boolean;
|
||||
usernameEnabled: boolean;
|
||||
token: string;
|
||||
|
||||
Reference in New Issue
Block a user