Burgernotes/static/js/main.js

620 lines
23 KiB
JavaScript
Raw Normal View History

2023-07-21 20:52:06 +01:00
if (localStorage.getItem("DONOTSHARE-secretkey") === null) {
2023-08-16 14:42:08 +01:00
window.location.replace("/login")
2023-11-03 20:24:40 +00:00
document.body.innerHTML = "Redirecting..."
2023-07-21 20:52:06 +01:00
throw new Error();
}
if (localStorage.getItem("DONOTSHARE-password") === null) {
2023-08-16 14:42:08 +01:00
window.location.replace("/login")
2023-11-03 20:24:40 +00:00
document.body.innerHTML = "Redirecting..."
2023-07-21 20:52:06 +01:00
throw new Error();
}
2023-08-19 18:20:37 +01:00
if (localStorage.getItem("CACHE-username") !== null) {
document.getElementById("usernameBox").innerText = localStorage.getItem("CACHE-username")
}
2023-08-02 20:08:11 +01:00
function formatBytes(a, b = 2) { if (!+a) return "0 Bytes"; const c = 0 > b ? 0 : b, d = Math.floor(Math.log(a) / Math.log(1000)); return `${parseFloat((a / Math.pow(1000, d)).toFixed(c))} ${["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"][d]}` }
2023-07-22 17:15:59 +01:00
2023-08-19 14:17:23 +01:00
function truncateString(str, num) {
if (str.length > num) {
return str.slice(0, num) + "...";
} else {
return str;
}
}
2023-07-21 20:52:06 +01:00
let secretkey = localStorage.getItem("DONOTSHARE-secretkey")
let password = localStorage.getItem("DONOTSHARE-password")
let usernameBox = document.getElementById("usernameBox")
2023-07-22 17:15:59 +01:00
let optionsCoverDiv = document.getElementById("optionsCoverDiv")
let optionsDiv = document.getElementById("optionsDiv")
let errorDiv = document.getElementById("errorDiv")
let errorMessageThing = document.getElementById("errorMessageThing")
let closeErrorButton = document.getElementById("closeErrorButton")
let cancelErrorButton = document.getElementById("cancelErrorButton")
let errorInput = document.getElementById("errorInput")
2023-07-22 17:15:59 +01:00
let exitThing = document.getElementById("exitThing")
2023-08-19 14:17:23 +01:00
let exitSessionsThing = document.getElementById("exitSessionsThing")
let sessionManagerButton = document.getElementById("sessionManagerButton")
let sessionManagerDiv = document.getElementById("sessionManagerDiv")
let sessionDiv = document.getElementById("sessionDiv")
2023-08-28 19:18:14 +01:00
let mfaDiv = document.getElementById("mfaDiv")
2023-08-02 20:08:11 +01:00
let deleteMyAccountButton = document.getElementById("deleteMyAccountButton")
2023-07-22 17:15:59 +01:00
let storageThing = document.getElementById("storageThing")
2023-08-02 20:08:11 +01:00
let storageProgressThing = document.getElementById("storageProgressThing")
2023-07-22 17:15:59 +01:00
let usernameThing = document.getElementById("usernameThing")
let logOutButton = document.getElementById("logOutButton")
2023-07-21 20:52:06 +01:00
let notesBar = document.getElementById("notesBar")
let notesDiv = document.getElementById("notesDiv")
let newNote = document.getElementById("newNote")
let noteBox = document.getElementById("noteBox")
2023-08-04 18:48:26 +01:00
let loadingStuff = document.getElementById("loadingStuff")
2023-08-05 00:29:53 +01:00
let burgerButton = document.getElementById("burgerButton")
2023-08-05 15:12:24 +01:00
let exportNotesButton = document.getElementById("exportNotesButton")
2023-08-04 18:48:26 +01:00
2023-07-21 20:52:06 +01:00
let selectedNote = 0
let timer
let waitTime = 400
if (/Android|iPhone|iPod/i.test(navigator.userAgent)) {
2023-07-21 20:52:06 +01:00
noteBox.style.width = "10px";
notesBar.style.width = "calc(100% - 10px)"
2023-07-21 22:54:43 +01:00
noteBox.readOnly = true
noteBox.style.fontSize = "18px"
2023-08-19 14:17:23 +01:00
noteBox.classList.add("hidden")
2023-07-21 20:52:06 +01:00
notesBar.addEventListener("touchstart", function (event) {
touchstartX = event.changedTouches[0].screenX;
touchstartY = event.changedTouches[0].screenY;
}, false);
notesBar.addEventListener("touchend", function (event) {
touchendX = event.changedTouches[0].screenX;
touchendY = event.changedTouches[0].screenY;
handleGesture();
}, false);
noteBox.addEventListener("touchstart", function (event) {
touchstartX = event.changedTouches[0].screenX;
touchstartY = event.changedTouches[0].screenY;
}, false);
noteBox.addEventListener("touchend", function (event) {
touchendX = event.changedTouches[0].screenX;
touchendY = event.changedTouches[0].screenY;
handleGesture();
}, false);
function handleGesture() {
2023-08-19 14:17:23 +01:00
if (touchendX > touchstartX + 75) {
notesBar.style.width = "calc(100% - 10px)";
noteBox.style.width = "10px"
if (selectedNote != 0) {
noteBox.readOnly = true
}
2023-07-21 20:52:06 +01:00
notesDiv.classList.remove("hidden")
2023-08-19 14:17:23 +01:00
noteBox.classList.add("hidden")
2023-07-21 20:52:06 +01:00
newNote.classList.remove("hidden")
}
2023-08-19 14:17:23 +01:00
if (touchendX < touchstartX - 75) {
2023-07-21 20:52:06 +01:00
noteBox.style.width = "calc(100% - 30px)";
2023-08-19 14:17:23 +01:00
notesBar.style.width = "10px"
if (selectedNote != 0) {
noteBox.readOnly = false
}
2023-07-21 20:52:06 +01:00
notesDiv.classList.add("hidden")
2023-08-19 14:17:23 +01:00
noteBox.classList.remove("hidden")
2023-07-21 20:52:06 +01:00
newNote.classList.add("hidden")
}
}
}
noteBox.value = ""
noteBox.readOnly = true
2023-08-05 23:28:57 +01:00
let noteCount = 0
function displayError(message) {
errorDiv.classList.remove("hidden")
optionsCoverDiv.classList.remove("hidden")
2023-11-03 16:39:48 +00:00
errorMessageThing.innerHTML = message
}
closeErrorButton.addEventListener("click", (event) => {
errorDiv.classList.add("hidden")
optionsCoverDiv.classList.add("hidden")
});
2023-10-16 19:45:00 +01:00
function displayPrompt(message, placeholdertext, callback) {
errorMessageThing.innerText = message
errorInput.value = ""
2023-10-16 19:45:00 +01:00
errorInput.placeholder = placeholdertext
closeErrorButton.addEventListener("click", (event) => {
2023-08-27 15:12:02 +01:00
if (callback) {
callback(errorInput.value)
callback = undefined
}
});
2023-08-09 23:43:28 +01:00
errorInput.addEventListener("keyup", (event) => {
if (event.key == "Enter") {
callback(errorInput.value)
callback = undefined
errorDiv.classList.add("hidden")
optionsCoverDiv.classList.add("hidden")
errorInput.classList.add("hidden")
cancelErrorButton.classList.add("hidden")
}
});
cancelErrorButton.addEventListener("click", (event) => {
callback = undefined
errorDiv.classList.add("hidden")
optionsCoverDiv.classList.add("hidden")
errorInput.classList.add("hidden")
cancelErrorButton.classList.add("hidden")
});
errorDiv.classList.remove("hidden")
optionsCoverDiv.classList.remove("hidden")
errorInput.classList.remove("hidden")
cancelErrorButton.classList.remove("hidden")
2023-08-09 23:43:28 +01:00
errorInput.focus()
}
closeErrorButton.addEventListener("click", (event) => {
errorDiv.classList.add("hidden")
optionsCoverDiv.classList.add("hidden")
errorInput.classList.add("hidden")
cancelErrorButton.classList.add("hidden")
});
2023-10-16 19:45:00 +01:00
function updateFont() {
let currentFontSize = localStorage.getItem("SETTING-fontsize")
noteBox.style.fontSize = currentFontSize + "px"
textSizeBox.innerText = currentFontSize + "px"
}
if (localStorage.getItem("SETTING-fontsize") === null) {
localStorage.setItem("SETTING-fontsize", "16")
updateFont()
} else {
updateFont()
}
textPlusBox.addEventListener("click", (event) => {
localStorage.setItem("SETTING-fontsize", String(Number(localStorage.getItem("SETTING-fontsize")) + Number(1)))
updateFont()
});
textMinusBox.addEventListener("click", (event) => {
localStorage.setItem("SETTING-fontsize", String(Number(localStorage.getItem("SETTING-fontsize")) - Number(1)))
updateFont()
});
2023-08-02 20:08:11 +01:00
function updateUserInfo() {
fetch("/api/userinfo", {
method: "POST",
body: JSON.stringify({
secretKey: secretkey
}),
headers: {
"Content-type": "application/json; charset=UTF-8"
}
})
.then((response) => response)
.then((response) => {
async function doStuff() {
2023-08-19 14:17:23 +01:00
if (response.status == 500) {
2023-11-03 20:24:40 +00:00
displayError("Something went wrong! Signing you out..")
2023-08-19 14:17:23 +01:00
closeErrorButton.classList.add("hidden")
usernameBox.innerText = ""
2023-08-19 18:20:37 +01:00
setTimeout(function () {
2023-08-19 14:17:23 +01:00
window.location.replace("/api/logout")
}, 2500);
} else {
let responseData = await response.json()
usernameBox.innerText = responseData["username"]
2023-11-03 20:24:40 +00:00
usernameThing.innerText = "Username: " + responseData["username"]
storageThing.innerText = "You've used " + formatBytes(responseData["storageused"]) + " out of " + formatBytes(responseData["storagemax"])
2023-08-19 14:17:23 +01:00
storageProgressThing.value = responseData["storageused"]
storageProgressThing.max = responseData["storagemax"]
noteCount = responseData["notecount"]
2023-08-19 18:20:37 +01:00
localStorage.setItem("CACHE-username", responseData["username"])
2023-08-19 14:17:23 +01:00
}
2023-08-02 20:08:11 +01:00
}
doStuff()
});
}
usernameBox.addEventListener("click", (event) => {
optionsCoverDiv.classList.remove("hidden")
optionsDiv.classList.remove("hidden")
2023-08-02 20:08:11 +01:00
updateUserInfo()
});
logOutButton.addEventListener("click", (event) => {
2023-08-19 14:17:23 +01:00
window.location.replace("/api/logout")
2023-08-02 20:08:11 +01:00
});
exitThing.addEventListener("click", (event) => {
optionsDiv.classList.add("hidden")
2023-08-02 20:08:11 +01:00
optionsCoverDiv.classList.add("hidden")
});
deleteMyAccountButton.addEventListener("click", (event) => {
2023-11-03 20:24:40 +00:00
if (confirm("Are you REALLY sure that you want to delete your account? There's no going back!") == true) {
2023-08-02 20:08:11 +01:00
fetch("/api/deleteaccount", {
method: "POST",
body: JSON.stringify({
secretKey: secretkey
}),
headers: {
"Content-type": "application/json; charset=UTF-8"
}
})
2023-08-04 18:48:26 +01:00
.then((response) => response)
.then((response) => {
if (response.status == 200) {
window.location.href = "/api/logout"
} else {
2023-11-03 20:24:40 +00:00
displayError("Failed to delete account (HTTP error code " + response.status + ")")
2023-08-04 18:48:26 +01:00
}
})
2023-08-02 20:08:11 +01:00
}
});
2023-08-19 14:17:23 +01:00
sessionManagerButton.addEventListener("click", (event) => {
optionsDiv.classList.add("hidden")
sessionManagerDiv.classList.remove("hidden")
fetch("/api/sessions/list", {
method: "POST",
body: JSON.stringify({
secretKey: secretkey
}),
headers: {
"Content-type": "application/json; charset=UTF-8"
}
})
.then((response) => response)
.then((response) => {
async function doStuff() {
let responseData = await response.json()
document.querySelectorAll(".burgerSession").forEach((el) => el.remove());
for (let i in responseData) {
let sessionElement = document.createElement("div")
let sessionText = document.createElement("p")
let sessionImage = document.createElement("img")
let sessionRemoveButton = document.createElement("button")
sessionText.classList.add("w300")
if (responseData[i]["thisSession"] == true) {
2023-08-19 18:20:37 +01:00
sessionText.innerText = "(current) " + truncateString(responseData[i]["device"], 18)
2023-08-19 14:17:23 +01:00
} else {
2023-08-19 18:20:37 +01:00
sessionText.innerText = truncateString(responseData[i]["device"], 27)
2023-08-19 14:17:23 +01:00
}
sessionText.title = responseData[i]["device"]
sessionRemoveButton.innerText = "x"
2023-08-19 14:17:23 +01:00
sessionImage.src = "/static/svg/device_other.svg"
ua = responseData[i]["device"]
if (ua.includes("NT") || ua.includes("Linux")) {
sessionImage.src = "/static/svg/device_computer.svg"
}
if (ua.includes("iPhone" || ua.includes("Android") || ua.include ("iPod"))) {
2023-08-19 14:17:23 +01:00
sessionImage.src = "/static/svg/device_smartphone.svg"
}
sessionRemoveButton.addEventListener("click", (event) => {
fetch("/api/sessions/remove", {
method: "POST",
body: JSON.stringify({
secretKey: secretkey,
sessionId: responseData[i]["id"]
}),
headers: {
"Content-type": "application/json; charset=UTF-8"
}
})
.then((response) => response)
.then((response) => {
if (responseData[i]["thisSession"] == true) {
window.location.replace("/api/logout")
}
});
sessionElement.remove()
});
sessionElement.append(sessionImage)
sessionElement.append(sessionText)
sessionElement.append(sessionRemoveButton)
sessionElement.classList.add("burgerSession")
sessionDiv.append(sessionElement)
}
}
doStuff()
});
});
exitSessionsThing.addEventListener("click", (event) => {
optionsDiv.classList.remove("hidden")
sessionManagerDiv.classList.add("hidden")
});
2023-08-02 20:08:11 +01:00
updateUserInfo()
2023-07-21 20:52:06 +01:00
2023-10-16 19:45:00 +01:00
function updateWordCount() {
let wordCount = noteBox.value.split(" ").length
if (wordCount == 1) {
wordCount = 0
}
wordCountBox.innerText = wordCount + " words"
}
2023-07-21 20:52:06 +01:00
function selectNote(nameithink) {
document.querySelectorAll(".noteButton").forEach((el) => el.classList.remove("selected"));
let thingArray = Array.from(document.querySelectorAll(".noteButton")).find(el => el.id == nameithink);
thingArray.classList.add("selected")
fetch("/api/readnote", {
method: "POST",
body: JSON.stringify({
secretKey: secretkey,
noteId: nameithink,
}),
headers: {
"Content-type": "application/json; charset=UTF-8"
}
})
.catch((error) => {
noteBox.readOnly = true
noteBox.value = ""
noteBox.placeholder = ""
2023-11-03 20:24:40 +00:00
displayError("Something went wrong... Please try again later!")
})
2023-07-21 20:52:06 +01:00
.then((response) => response)
.then((response) => {
selectedNote = nameithink
noteBox.readOnly = false
2023-11-03 20:24:40 +00:00
noteBox.placeholder = "Type something!"
2023-07-21 20:52:06 +01:00
async function doStuff() {
let responseData = await response.json()
let bytes = CryptoJS.AES.decrypt(responseData["content"], password);
let originalText = bytes.toString(CryptoJS.enc.Utf8);
noteBox.value = originalText
2023-10-16 19:45:00 +01:00
updateWordCount()
2023-07-21 20:52:06 +01:00
noteBox.addEventListener("input", (event) => {
2023-10-16 19:45:00 +01:00
updateWordCount()
2023-07-21 20:52:06 +01:00
clearTimeout(timer);
timer = setTimeout(() => {
let encryptedText = CryptoJS.AES.encrypt(noteBox.value, password).toString();
if (selectedNote == nameithink) {
fetch("/api/editnote", {
method: "POST",
body: JSON.stringify({
secretKey: secretkey,
noteId: nameithink,
content: encryptedText,
}),
headers: {
"Content-type": "application/json; charset=UTF-8"
}
})
2023-07-22 17:15:59 +01:00
.then((response) => response)
.then((response) => {
if (response.status == 418) {
2023-11-03 20:24:40 +00:00
displayError("You've ran out of storage... Changes will not be saved until you free up storage!")
2023-07-22 17:15:59 +01:00
}
})
.catch((error) => {
2023-11-03 20:24:40 +00:00
displayError("Failed to save changes, please try again later...")
})
2023-07-21 20:52:06 +01:00
}
}, waitTime);
});
}
doStuff()
});
}
function updateNotes() {
fetch("/api/listnotes", {
method: "POST",
body: JSON.stringify({
secretKey: secretkey
}),
headers: {
"Content-type": "application/json; charset=UTF-8"
}
})
.then((response) => response)
.then((response) => {
async function doStuff() {
document.querySelectorAll(".noteButton").forEach((el) => el.remove());
noteBox.readOnly = true
selectedNote = 0
2023-08-03 17:41:58 +01:00
noteBox.placeholder = ""
2023-07-21 20:52:06 +01:00
noteBox.value = ""
clearTimeout(timer)
2023-10-16 19:45:00 +01:00
updateWordCount()
2023-07-21 20:52:06 +01:00
let responseData = await response.json()
for (let i in responseData) {
let noteButton = document.createElement("button");
noteButton.classList.add("noteButton")
notesDiv.append(noteButton)
let bytes = CryptoJS.AES.decrypt(responseData[i]["title"], password);
let originalTitle = bytes.toString(CryptoJS.enc.Utf8);
noteButton.id = responseData[i]["id"]
noteButton.innerText = originalTitle
noteButton.addEventListener("click", (event) => {
if (event.ctrlKey) {
fetch("/api/removenote", {
method: "POST",
body: JSON.stringify({
secretKey: secretkey,
noteId: responseData[i]["id"]
}),
headers: {
"Content-type": "application/json; charset=UTF-8"
}
})
.then((response) => response)
.then((response) => {
updateNotes()
})
.catch((error) => {
2023-11-03 20:24:40 +00:00
displayError("Something went wrong! Please try again later...")
})
2023-07-21 20:52:06 +01:00
} else {
selectNote(responseData[i]["id"])
}
});
}
2023-08-04 21:44:36 +01:00
document.querySelectorAll(".loadingStuff").forEach((el) => el.remove());
2023-07-21 20:52:06 +01:00
}
doStuff()
});
}
updateNotes()
newNote.addEventListener("click", (event) => {
2023-11-03 20:24:40 +00:00
let noteName = displayPrompt("Note name?", "E.G Shopping list", burgerFunction)
function burgerFunction(noteName) {
if (noteName != null) {
2023-11-23 19:30:08 +00:00
if (noteName.length > 21) {
displayError("Invalid note name: Too long (max 21 characters)");
return;
}
let encryptedName = CryptoJS.AES.encrypt(noteName, password).toString();
fetch("/api/newnote", {
method: "POST",
body: JSON.stringify({
secretKey: secretkey,
noteName: encryptedName,
}),
headers: {
"Content-type": "application/json; charset=UTF-8"
2023-07-21 20:52:06 +01:00
}
})
.catch((error) => {
2023-11-03 20:24:40 +00:00
displayError("Failed to create new note, please try again later...")
})
.then((response) => {
if (response.status !== 200) {
updateNotes()
2023-11-03 20:24:40 +00:00
displayError("Failed to create new note (HTTP error code " + response.status + ")")
} else {
updateNotes()
}
});
}
2023-07-21 20:52:06 +01:00
}
2023-08-05 00:29:53 +01:00
});
2023-08-05 15:12:24 +01:00
function downloadObjectAsJson(exportObj, exportName) {
var dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(exportObj));
var downloadAnchorNode = document.createElement("a");
downloadAnchorNode.setAttribute("href", dataStr);
downloadAnchorNode.setAttribute("download", exportName + ".json");
document.body.appendChild(downloadAnchorNode);
downloadAnchorNode.click();
downloadAnchorNode.remove();
}
function exportNotes() {
let noteExport = []
fetch("/api/exportnotes", {
method: "POST",
body: JSON.stringify({
secretKey: secretkey
}),
headers: {
"Content-type": "application/json; charset=UTF-8"
}
})
.then((response) => response)
.then((response) => {
async function doStuff() {
let responseData = await response.json()
for (let i in responseData) {
2023-11-03 20:24:40 +00:00
exportNotes.innerText = "Decrypting " + i + "/" + noteCount
2023-08-05 23:28:57 +01:00
2023-08-05 15:12:24 +01:00
let bytes = CryptoJS.AES.decrypt(responseData[i]["title"], password);
let originalTitle = bytes.toString(CryptoJS.enc.Utf8);
responseData[i]["title"] = originalTitle
let bytesd = CryptoJS.AES.decrypt(responseData[i]["content"], password);
let originalContent = bytesd.toString(CryptoJS.enc.Utf8);
responseData[i]["content"] = originalContent
}
let jsonString = JSON.parse(JSON.stringify(responseData))
2023-11-03 20:24:40 +00:00
exportNotesButton.innerText = "Export notes"
2023-08-05 15:12:24 +01:00
downloadObjectAsJson(jsonString, "data")
optionsDiv.classList.add("hidden")
2023-11-03 20:24:40 +00:00
displayError("Exported notes!")
2023-08-05 15:12:24 +01:00
}
doStuff()
})
}
2024-02-14 18:03:31 +00:00
function isFirstTimeVisitor() {
if (document.cookie.indexOf("visited=true") !== -1) {
return false;
} else {
var expirationDate = new Date();
expirationDate.setFullYear(expirationDate.getFullYear() + 1);
2024-02-14 18:05:42 +00:00
document.cookie = "visited=true; expires=" + expirationDate.toUTCString() + "; path=/; SameSite=strict";
2024-02-14 18:03:31 +00:00
return true;
}
}
2023-08-05 15:12:24 +01:00
exportNotesButton.addEventListener("click", (event) => {
2023-11-03 20:24:40 +00:00
exportNotesButton.innerText = "Downloading..."
2023-08-05 15:12:24 +01:00
exportNotes()
2023-10-16 19:45:00 +01:00
});
removeBox.addEventListener("click", (event) => {
if (selectedNote == 0) {
2023-11-03 20:24:40 +00:00
displayError("You need to select a note first!")
2023-10-16 19:45:00 +01:00
} else {
fetch("/api/removenote", {
method: "POST",
body: JSON.stringify({
secretKey: secretkey,
noteId: selectedNote
}),
headers: {
"Content-type": "application/json; charset=UTF-8"
}
})
.then((response) => response)
.then((response) => {
updateNotes()
})
.catch((error) => {
2023-11-03 20:24:40 +00:00
displayError("Something went wrong! Please try again later...")
2023-10-16 19:45:00 +01:00
})
}
2023-11-03 16:39:48 +00:00
});
2024-02-14 18:03:31 +00:00
if (isFirstTimeVisitor() && /Android|iPhone|iPod/i.test(navigator.userAgent)) {
2024-02-14 18:12:29 +00:00
displayError("To use PageBurger:\n Swipe Right on a note to open it\n Swipe left in the text boxes to return to notes\n Click on a note to highlight it")
}