Removed client
59
main
|
@ -8,7 +8,7 @@ import asyncio
|
||||||
from hypercorn.config import Config
|
from hypercorn.config import Config
|
||||||
from hypercorn.asyncio import serve
|
from hypercorn.asyncio import serve
|
||||||
from werkzeug.security import generate_password_hash, check_password_hash
|
from werkzeug.security import generate_password_hash, check_password_hash
|
||||||
from quart import Quart, render_template, request, url_for, flash, redirect, session, make_response, send_from_directory, stream_with_context, Response, request
|
from quart import Quart, request, url_for, flash, redirect, session, make_response, send_from_directory, stream_with_context, Response, request
|
||||||
|
|
||||||
# Parse configuration file, and check if anything is wrong with it
|
# Parse configuration file, and check if anything is wrong with it
|
||||||
if not os.path.exists("config.ini"):
|
if not os.path.exists("config.ini"):
|
||||||
|
@ -107,54 +107,6 @@ async def add_cors_headers(response):
|
||||||
response.headers.add("Access-Control-Allow-Methods", "*")
|
response.headers.add("Access-Control-Allow-Methods", "*")
|
||||||
return response
|
return response
|
||||||
|
|
||||||
# Main page
|
|
||||||
@app.route("/index.html")
|
|
||||||
async def mainrdir():
|
|
||||||
return redirect("/", code=302)
|
|
||||||
@app.route("/")
|
|
||||||
async def main():
|
|
||||||
return await render_template("main.html")
|
|
||||||
|
|
||||||
# Homeserver changer
|
|
||||||
@app.route("/homeserver/index.html")
|
|
||||||
async def homeserverrdir():
|
|
||||||
return redirect("/", code=302)
|
|
||||||
@app.route("/homeserver")
|
|
||||||
async def homeserver():
|
|
||||||
return await render_template("homeserver.html")
|
|
||||||
|
|
||||||
# Web app
|
|
||||||
@app.route("/app/index.html")
|
|
||||||
async def apprdir():
|
|
||||||
return redirect("/app", code=302)
|
|
||||||
@app.route("/app")
|
|
||||||
async def webapp():
|
|
||||||
return await render_template("app.html")
|
|
||||||
|
|
||||||
# Login and signup
|
|
||||||
@app.route("/signup/index.html")
|
|
||||||
async def signuprdir():
|
|
||||||
return redirect("/signup", code=302)
|
|
||||||
@app.route("/signup")
|
|
||||||
async def signup():
|
|
||||||
return await render_template("signup.html")
|
|
||||||
|
|
||||||
@app.route("/login/index.html")
|
|
||||||
async def loginrdir():
|
|
||||||
return redirect("/login", code=302)
|
|
||||||
@app.route("/login")
|
|
||||||
async def login():
|
|
||||||
return await render_template("login.html")
|
|
||||||
|
|
||||||
# Privacy policy
|
|
||||||
@app.route("/privacy/index.html")
|
|
||||||
async def privacyrdir():
|
|
||||||
return redirect("/privacy", code=302)
|
|
||||||
@app.route("/privacy")
|
|
||||||
async def privacy():
|
|
||||||
return await render_template("privacy.html")
|
|
||||||
|
|
||||||
# API
|
|
||||||
@app.route("/api/version", methods=("GET", "POST"))
|
@app.route("/api/version", methods=("GET", "POST"))
|
||||||
async def apiversion():
|
async def apiversion():
|
||||||
return "Burgernotes Version 1.2"
|
return "Burgernotes Version 1.2"
|
||||||
|
@ -535,20 +487,13 @@ def listusers(secretkey):
|
||||||
else:
|
else:
|
||||||
return redirect("/")
|
return redirect("/")
|
||||||
|
|
||||||
@app.route("/logout/index.html")
|
|
||||||
async def logoutrdir():
|
|
||||||
return redirect("/logout", code=302)
|
|
||||||
@app.route("/logout")
|
|
||||||
async def apilogout():
|
|
||||||
return await render_template("logout.html")
|
|
||||||
|
|
||||||
@app.errorhandler(500)
|
@app.errorhandler(500)
|
||||||
async def burger(e):
|
async def burger(e):
|
||||||
return {}, 500
|
return {}, 500
|
||||||
|
|
||||||
@app.errorhandler(404)
|
@app.errorhandler(404)
|
||||||
async def burger(e):
|
async def burger(e):
|
||||||
return await render_template("error.html", errorCode=404, errorMessage="Page not found"), 404
|
return {}, 404
|
||||||
|
|
||||||
# Start server
|
# Start server
|
||||||
hypercornconfig = Config()
|
hypercornconfig = Config()
|
||||||
|
|
|
@ -1,695 +0,0 @@
|
||||||
@import url("../fonts/inter.css");
|
|
||||||
|
|
||||||
:root {
|
|
||||||
--contrast: #eee;
|
|
||||||
--contrast2: #fff;
|
|
||||||
--invertdm: 0%;
|
|
||||||
--bar: #f4f4f4;
|
|
||||||
--editor: #ffffff;
|
|
||||||
--text-color: #000000;
|
|
||||||
--border-color: #dadada;
|
|
||||||
--theme-color: #157efb;
|
|
||||||
--theme-text-color: #ffffff;
|
|
||||||
--exit-color: #e9e9e9;
|
|
||||||
--session-color: #f4f4f4;
|
|
||||||
--note-button: #ffffff;
|
|
||||||
--note-button-text-color: #ffffff;
|
|
||||||
--unselected-note-button-text-color: #000000;
|
|
||||||
--option-background: #ffffff;
|
|
||||||
--invert: 100%;
|
|
||||||
--bottomBarHover: #e4e4e4;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* dark mode */
|
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
|
||||||
:root {
|
|
||||||
--invertdm: 100%;
|
|
||||||
--contrast: #2d2f21;
|
|
||||||
--contrast2: #2d2f21;
|
|
||||||
--bar: #2d2f31;
|
|
||||||
--editor: #202124;
|
|
||||||
--text-color: #ffffff;
|
|
||||||
--border-color: #393b3d;
|
|
||||||
--theme-color: #157efb;
|
|
||||||
--theme-text-color: #ffffff;
|
|
||||||
--exit-color: #454649;
|
|
||||||
--session-color: #2d2f31;
|
|
||||||
--note-button: #202124;
|
|
||||||
--note-button-text-color: #ffffff;
|
|
||||||
--unselected-note-button-text-color: #ffffff;
|
|
||||||
--option-background: #202124;
|
|
||||||
--invert: 100%;
|
|
||||||
--bottomBarHover: #e4e4e4;
|
|
||||||
}
|
|
||||||
|
|
||||||
.startDiv p {
|
|
||||||
color: white !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.topBar p {
|
|
||||||
color: white !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newNote {
|
|
||||||
color: white !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newNote img {
|
|
||||||
filter: invert(100%);
|
|
||||||
}
|
|
||||||
|
|
||||||
#errorDiv p {
|
|
||||||
color: white !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.optionsCoverDiv p {
|
|
||||||
color: white !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.burgerSession img {
|
|
||||||
filter: invert(100%) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.links a {
|
|
||||||
color: white !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inoutdiv p {
|
|
||||||
color: white !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inoutdiv a {
|
|
||||||
color: #969696 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inoutdiv input {
|
|
||||||
color: white;
|
|
||||||
background-color: var(--editor);
|
|
||||||
}
|
|
||||||
|
|
||||||
.flathubLogo {
|
|
||||||
filter: invert(100%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.feature {
|
|
||||||
background-color: rgba(0, 0, 0, 0) !important;
|
|
||||||
color: var(--text-color);
|
|
||||||
}
|
|
||||||
.mainDiv .yellow {
|
|
||||||
border-color: #e9e98d !important;
|
|
||||||
}
|
|
||||||
.mainDiv .green {
|
|
||||||
border-color: #a9f9a9 !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p,
|
|
||||||
li,
|
|
||||||
h1,
|
|
||||||
h2,
|
|
||||||
h3,
|
|
||||||
h4,
|
|
||||||
h5,
|
|
||||||
h6 {
|
|
||||||
color: var(--text-color);
|
|
||||||
white-space: break-spaces;
|
|
||||||
}
|
|
||||||
|
|
||||||
h7 {
|
|
||||||
display: block;
|
|
||||||
font-size: 20px;
|
|
||||||
margin-top: 0.67em;
|
|
||||||
margin-bottom: 0.67em;
|
|
||||||
margin-left: 0;
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
background-color: var(--editor);
|
|
||||||
font-family: "Inter", sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hiddenButton {
|
|
||||||
right: 0px;
|
|
||||||
position: fixed;
|
|
||||||
background-color: var(--editor);
|
|
||||||
color: var(--editor);
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Web app */
|
|
||||||
.topBar {
|
|
||||||
position: fixed;
|
|
||||||
width: 100%;
|
|
||||||
height: 50px;
|
|
||||||
|
|
||||||
background-color: var(--bar);
|
|
||||||
|
|
||||||
border: solid;
|
|
||||||
border-color: var(--border-color);
|
|
||||||
border-width: 0px;
|
|
||||||
border-bottom-width: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bottomBar {
|
|
||||||
position: fixed;
|
|
||||||
width: 100%;
|
|
||||||
height: 29px;
|
|
||||||
bottom: 0;
|
|
||||||
|
|
||||||
background-color: var(--bar);
|
|
||||||
|
|
||||||
border: solid;
|
|
||||||
border-color: var(--border-color);
|
|
||||||
border-width: 0px;
|
|
||||||
border-top-width: 1px;
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bottomBar button {
|
|
||||||
background-color: rgba(0, 0, 0, 0);
|
|
||||||
color: var(--text-color);
|
|
||||||
height: 100%;
|
|
||||||
border: none;
|
|
||||||
font-size: 14px;
|
|
||||||
padding-left: 7.5px;
|
|
||||||
padding-right: 7.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bottomBar .removeButton {
|
|
||||||
filter: invert(var(--invertdm));
|
|
||||||
padding-left: 17.5px;
|
|
||||||
padding-right: 17.5px;
|
|
||||||
background-image: url("../../static/svg/delete.svg");
|
|
||||||
background-position: center;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-size: 55%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bottomBar .textManipulator {
|
|
||||||
margin-left: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bottomBar button:hover {
|
|
||||||
background-color: var(--bottomBarHover);
|
|
||||||
}
|
|
||||||
|
|
||||||
.bottomBar .right {
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.burgerDropdown {
|
|
||||||
position: fixed;
|
|
||||||
z-index: 2;
|
|
||||||
left: 7px;
|
|
||||||
top: 30px;
|
|
||||||
width: 160px;
|
|
||||||
height: 90px;
|
|
||||||
|
|
||||||
background-color: var(--bar);
|
|
||||||
|
|
||||||
border: solid;
|
|
||||||
border-color: var(--border-color);
|
|
||||||
border-width: 1px;
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.burgerDropdown a {
|
|
||||||
position: absolute;
|
|
||||||
width: calc(100% - 14px - 4px - 7px);
|
|
||||||
color: var(--text-color);
|
|
||||||
background-color: #ffffff;
|
|
||||||
height: 35px;
|
|
||||||
line-height: 35px;
|
|
||||||
margin: 7px;
|
|
||||||
padding-left: 7px;
|
|
||||||
border: solid;
|
|
||||||
border-color: var(--border-color);
|
|
||||||
border-width: 1px;
|
|
||||||
border-radius: 8px;
|
|
||||||
font-size: 15px;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.topBar p {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.topBar .logo {
|
|
||||||
padding-left: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.topBar .usernameBox {
|
|
||||||
text-align: right;
|
|
||||||
position: absolute;
|
|
||||||
cursor: pointer;
|
|
||||||
right: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.notesBar {
|
|
||||||
position: fixed;
|
|
||||||
width: 180px;
|
|
||||||
top: 50px;
|
|
||||||
height: calc(100% - 50px - 30px - 1px);
|
|
||||||
|
|
||||||
background-color: var(--bar);
|
|
||||||
border: solid;
|
|
||||||
border-color: var(--border-color);
|
|
||||||
border-width: 0px;
|
|
||||||
border-right-width: 1px;
|
|
||||||
border-top-width: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.notesDiv {
|
|
||||||
height: calc(100% - 50px);
|
|
||||||
overflow-y: scroll;
|
|
||||||
}
|
|
||||||
|
|
||||||
.notesBar .noteButton, .notesBar .loadingStuff {
|
|
||||||
width: calc(100% - 7px - 7px - 3.5px);
|
|
||||||
height: 35px;
|
|
||||||
line-height: 0px;
|
|
||||||
padding: 10px;
|
|
||||||
margin: 5px;
|
|
||||||
margin-bottom: 0;
|
|
||||||
background-color: var(--note-button);
|
|
||||||
color: var(--unselected-note-button-text-color);
|
|
||||||
border: none;
|
|
||||||
border-radius: 8px;
|
|
||||||
|
|
||||||
border: solid;
|
|
||||||
border-color: var(--border-color);
|
|
||||||
border-width: 1px;
|
|
||||||
font-size: 15px;
|
|
||||||
|
|
||||||
text-align: left;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.notesBar .loadingStuff {
|
|
||||||
border: none;
|
|
||||||
background:
|
|
||||||
linear-gradient(0.25turn, transparent, var(--contrast2), transparent),
|
|
||||||
linear-gradient(var(--contrast), var(--contrast)),
|
|
||||||
radial-gradient(38px circle at 19px 19px, #eee 50%, transparent 51%),
|
|
||||||
linear-gradient(var(--contrast), var(--contrast));
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-size: 315px 250px, 315px 180px, 100px 100px, 225px 30px;
|
|
||||||
background-position: -315px 0, 0 0, 0px 190px, 50px 195px;
|
|
||||||
animation: loading 1.5s infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes loading {
|
|
||||||
to {
|
|
||||||
background-position: 315px 0, 0 0, 0 190px, 50px 195px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.notesBar .selected {
|
|
||||||
background-color: var(--theme-color) !important;
|
|
||||||
border: none;
|
|
||||||
color: var(--note-button-text-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.notesBar .newNote {
|
|
||||||
height: 41px;
|
|
||||||
line-height: 41px;
|
|
||||||
width: 100%;
|
|
||||||
text-align: left;
|
|
||||||
background-color: rgba(0, 0, 0, 0);
|
|
||||||
border: none;
|
|
||||||
font-size: 16px;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.notesBar .newNote img {
|
|
||||||
height: 32px;
|
|
||||||
padding-right: 5px;
|
|
||||||
transform: translateY(30%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.noteBox {
|
|
||||||
resize: none;
|
|
||||||
position: fixed;
|
|
||||||
right: 0;
|
|
||||||
top: 55px;
|
|
||||||
padding: 4px;
|
|
||||||
border: none;
|
|
||||||
font-size: 16px;
|
|
||||||
color: var(--text-color);
|
|
||||||
background-color: var(--editor);
|
|
||||||
width: calc(100% - 180px - 7px - 6px);
|
|
||||||
height: calc(100% - 50px - 6px - 8px - 30px);
|
|
||||||
font-family: "Inter", sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
.noteBox:focus {
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.optionsCoverDiv {
|
|
||||||
position: fixed;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
z-index: 2;
|
|
||||||
background-color: rgba(0, 0, 0, 0.7);
|
|
||||||
transition: opacity 1s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.optionsDiv {
|
|
||||||
left: 50%;
|
|
||||||
top: 50%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
position: fixed;
|
|
||||||
background-color: var(--option-background);
|
|
||||||
padding: 10px;
|
|
||||||
color: var(--text-color);
|
|
||||||
border-radius: 8px;
|
|
||||||
min-width: 300px;
|
|
||||||
z-index: 3;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.optionsDiv button {
|
|
||||||
width: 100%;
|
|
||||||
padding: 10px;
|
|
||||||
padding-bottom: 13px;
|
|
||||||
margin-right: 5px;
|
|
||||||
margin-bottom: 7px;
|
|
||||||
padding-left: 15px;
|
|
||||||
padding-right: 15px;
|
|
||||||
color: var(--theme-text-color);
|
|
||||||
border: none;
|
|
||||||
text-decoration: none;
|
|
||||||
background-color: var(--theme-color);
|
|
||||||
border-radius: 8px;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.optionsDiv .normalButton {
|
|
||||||
width: auto;
|
|
||||||
margin-bottom: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.optionsDiv .lastButton {
|
|
||||||
margin-bottom: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.optionsDiv input {
|
|
||||||
width: calc(100% - 12px);
|
|
||||||
height: 25px;
|
|
||||||
background-color: #ffffff;
|
|
||||||
padding-left: 5px;
|
|
||||||
padding-right: 5px;
|
|
||||||
margin-bottom: 7px;
|
|
||||||
border: solid;
|
|
||||||
border-color: var(--border-color);
|
|
||||||
border-width: 1px;
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.optionsDiv .mfacheckbox {
|
|
||||||
display: inline;
|
|
||||||
margin: 0;
|
|
||||||
margin-left: 5px;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
padding: 0;
|
|
||||||
height: 17px;
|
|
||||||
width: 17px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.optionsDiv input:focus {
|
|
||||||
outline: 0;
|
|
||||||
border-color: var(--theme-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.optionsDiv code {
|
|
||||||
padding: 7px;
|
|
||||||
font-size: 14px;
|
|
||||||
border-radius: 8px;
|
|
||||||
background-color: var(--session-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.optionsDiv progress {
|
|
||||||
width: 100%;
|
|
||||||
background-color: var(--session-color);
|
|
||||||
border: none;
|
|
||||||
border-radius: 99px;
|
|
||||||
height: 7px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.optionsDiv progress::-moz-progress-bar {
|
|
||||||
background: var(--theme-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.optionsDiv progresss::-webkit-progress-value {
|
|
||||||
background: var(--theme-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.optionsDiv .exit {
|
|
||||||
position: absolute;
|
|
||||||
right: 5px;
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
font-size: 16px;
|
|
||||||
background-color: var(--exit-color);
|
|
||||||
color: var(--text-color);
|
|
||||||
border-radius: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.optionsDiv img {
|
|
||||||
height: 18px;
|
|
||||||
padding-right: 5px;
|
|
||||||
filter: invert(var(--invert));
|
|
||||||
transform: translateY(3.25px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.optionsDiv .section {
|
|
||||||
width: 100%;
|
|
||||||
height: 1px;
|
|
||||||
background-color: var(--border-color);
|
|
||||||
margin-top: 2px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sessionDiv {
|
|
||||||
max-height: 255px;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sessionDiv div {
|
|
||||||
position: relative;
|
|
||||||
background-color: var(--session-color);
|
|
||||||
border-radius: 8px;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
padding: 10px;
|
|
||||||
height: 35px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sessionDiv div p {
|
|
||||||
display: inline;
|
|
||||||
position: absolute;
|
|
||||||
transform: translateY(-7.5px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.sessionDiv div button {
|
|
||||||
position: absolute;
|
|
||||||
border-radius: 99px;
|
|
||||||
right: 15px;
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
font-size: 16px;
|
|
||||||
transform: translateY(-2px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.sessionDiv img {
|
|
||||||
display: inline;
|
|
||||||
filter: none;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sign up/log in div */
|
|
||||||
|
|
||||||
.inoutdiv {
|
|
||||||
margin: 10%;
|
|
||||||
padding: 30px;
|
|
||||||
border-radius: 25px;
|
|
||||||
border: solid 1px var(--border-color);
|
|
||||||
background-color: var(--bar);
|
|
||||||
}
|
|
||||||
|
|
||||||
.inoutdiv input {
|
|
||||||
width: calc(100% - 120px);
|
|
||||||
height: 30px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
padding-left: 10px;
|
|
||||||
padding-right: 10px;
|
|
||||||
|
|
||||||
border: solid;
|
|
||||||
border-color: var(--border-color);
|
|
||||||
border-width: 1px;
|
|
||||||
border-radius: 8px;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.inoutdiv button {
|
|
||||||
background-color: var(--theme-color);
|
|
||||||
color: white;
|
|
||||||
padding: 10px;
|
|
||||||
margin-right: 5px;
|
|
||||||
padding-left: 20px;
|
|
||||||
padding-right: 20px;
|
|
||||||
|
|
||||||
border: none;
|
|
||||||
border-radius: 8px;
|
|
||||||
|
|
||||||
font-size: 14px;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.inoutdiv a {
|
|
||||||
color: grey;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hidden {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.w100 {
|
|
||||||
font-weight: 300;
|
|
||||||
}
|
|
||||||
|
|
||||||
.w200 {
|
|
||||||
font-weight: 300;
|
|
||||||
}
|
|
||||||
|
|
||||||
.w300 {
|
|
||||||
font-weight: 300;
|
|
||||||
}
|
|
||||||
|
|
||||||
.w400 {
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
|
|
||||||
.w500 {
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.w600 {
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.w700 {
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.w800 {
|
|
||||||
font-weight: 800;
|
|
||||||
}
|
|
||||||
|
|
||||||
.w900 {
|
|
||||||
font-weight: 900;
|
|
||||||
}
|
|
||||||
|
|
||||||
.alertDiv {
|
|
||||||
position: fixed;
|
|
||||||
margin: 0;
|
|
||||||
width: 100%;
|
|
||||||
background-color: #ffffeb;
|
|
||||||
height: 25px;
|
|
||||||
z-index: 9999;
|
|
||||||
top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* main */
|
|
||||||
|
|
||||||
.mainDiv {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.startDiv {
|
|
||||||
text-align: left;
|
|
||||||
margin-top: 8vh;
|
|
||||||
margin-left: 7vh;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.startDiv h1 {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mainDiv a {
|
|
||||||
padding: 15px;
|
|
||||||
padding-left: 20px;
|
|
||||||
padding-right: 20px;
|
|
||||||
margin-right: auto;
|
|
||||||
color: white;
|
|
||||||
text-decoration: none;
|
|
||||||
background-color: var(--theme-color);
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mainDiv .feature {
|
|
||||||
width: calc(100% - 7vh - 7vh - 3.5vh);
|
|
||||||
margin-bottom: 10px;
|
|
||||||
margin-left: 7vh;
|
|
||||||
margin-right: 7vh;
|
|
||||||
padding-left: 10px;
|
|
||||||
padding-right: 10px;
|
|
||||||
|
|
||||||
border: solid;
|
|
||||||
border-radius: 8px;
|
|
||||||
border-width: 1px;
|
|
||||||
border-color: var(--border-color);
|
|
||||||
|
|
||||||
padding-top: 15px;
|
|
||||||
padding-bottom: 15px;
|
|
||||||
font-size: 17px;
|
|
||||||
padding-bottom: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mainDiv .green {
|
|
||||||
background-color: #ebffeb;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mainDiv .yellow {
|
|
||||||
background-color: #ffffeb;
|
|
||||||
}
|
|
||||||
|
|
||||||
.links {
|
|
||||||
text-align: center;
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.links a {
|
|
||||||
margin-left: 5px;
|
|
||||||
text-decoration: none;
|
|
||||||
background-color: var(--bar);
|
|
||||||
color: var(--text-color);
|
|
||||||
padding: 10px;
|
|
||||||
padding-top: 2.5px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
border-radius: 10px;
|
|
||||||
transition: background-color .2s;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.links a:hover {
|
|
||||||
background-color: var(--editor);
|
|
||||||
}
|
|
||||||
|
|
||||||
.links a img {
|
|
||||||
transform: translateY(5px);
|
|
||||||
padding-right: 10px;
|
|
||||||
filter: invert(var(--invertdm));
|
|
||||||
}
|
|
||||||
|
|
||||||
.links a:hover {
|
|
||||||
text-decoration: dashed;
|
|
||||||
}
|
|
|
@ -1,57 +0,0 @@
|
||||||
/* Variable fonts usage:
|
|
||||||
:root { font-family: "Inter", sans-serif; }
|
|
||||||
@supports (font-variation-settings: normal) {
|
|
||||||
:root { font-family: "InterVariable", sans-serif; font-optical-sizing: auto; }
|
|
||||||
} */
|
|
||||||
@font-face {
|
|
||||||
font-family: InterVariable;
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 100 900;
|
|
||||||
font-display: swap;
|
|
||||||
src: url("InterVariable.woff2") format("woff2");
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: InterVariable;
|
|
||||||
font-style: italic;
|
|
||||||
font-weight: 100 900;
|
|
||||||
font-display: swap;
|
|
||||||
src: url("InterVariable-Italic.woff2") format("woff2");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* static fonts */
|
|
||||||
@font-face { font-family: "Inter"; font-style: normal; font-weight: 100; font-display: swap; src: url("Inter-Thin.woff2") format("woff2"); }
|
|
||||||
@font-face { font-family: "Inter"; font-style: italic; font-weight: 100; font-display: swap; src: url("Inter-ThinItalic.woff2") format("woff2"); }
|
|
||||||
@font-face { font-family: "Inter"; font-style: normal; font-weight: 200; font-display: swap; src: url("Inter-ExtraLight.woff2") format("woff2"); }
|
|
||||||
@font-face { font-family: "Inter"; font-style: italic; font-weight: 200; font-display: swap; src: url("Inter-ExtraLightItalic.woff2") format("woff2"); }
|
|
||||||
@font-face { font-family: "Inter"; font-style: normal; font-weight: 300; font-display: swap; src: url("Inter-Light.woff2") format("woff2"); }
|
|
||||||
@font-face { font-family: "Inter"; font-style: italic; font-weight: 300; font-display: swap; src: url("Inter-LightItalic.woff2") format("woff2"); }
|
|
||||||
@font-face { font-family: "Inter"; font-style: normal; font-weight: 400; font-display: swap; src: url("Inter-Regular.woff2") format("woff2"); }
|
|
||||||
@font-face { font-family: "Inter"; font-style: italic; font-weight: 400; font-display: swap; src: url("Inter-Italic.woff2") format("woff2"); }
|
|
||||||
@font-face { font-family: "Inter"; font-style: normal; font-weight: 500; font-display: swap; src: url("Inter-Medium.woff2") format("woff2"); }
|
|
||||||
@font-face { font-family: "Inter"; font-style: italic; font-weight: 500; font-display: swap; src: url("Inter-MediumItalic.woff2") format("woff2"); }
|
|
||||||
@font-face { font-family: "Inter"; font-style: normal; font-weight: 600; font-display: swap; src: url("Inter-SemiBold.woff2") format("woff2"); }
|
|
||||||
@font-face { font-family: "Inter"; font-style: italic; font-weight: 600; font-display: swap; src: url("Inter-SemiBoldItalic.woff2") format("woff2"); }
|
|
||||||
@font-face { font-family: "Inter"; font-style: normal; font-weight: 700; font-display: swap; src: url("Inter-Bold.woff2") format("woff2"); }
|
|
||||||
@font-face { font-family: "Inter"; font-style: italic; font-weight: 700; font-display: swap; src: url("Inter-BoldItalic.woff2") format("woff2"); }
|
|
||||||
@font-face { font-family: "Inter"; font-style: normal; font-weight: 800; font-display: swap; src: url("Inter-ExtraBold.woff2") format("woff2"); }
|
|
||||||
@font-face { font-family: "Inter"; font-style: italic; font-weight: 800; font-display: swap; src: url("Inter-ExtraBoldItalic.woff2") format("woff2"); }
|
|
||||||
@font-face { font-family: "Inter"; font-style: normal; font-weight: 900; font-display: swap; src: url("Inter-Black.woff2") format("woff2"); }
|
|
||||||
@font-face { font-family: "Inter"; font-style: italic; font-weight: 900; font-display: swap; src: url("Inter-BlackItalic.woff2") format("woff2"); }
|
|
||||||
@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 100; font-display: swap; src: url("InterDisplay-Thin.woff2") format("woff2"); }
|
|
||||||
@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 100; font-display: swap; src: url("InterDisplay-ThinItalic.woff2") format("woff2"); }
|
|
||||||
@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 200; font-display: swap; src: url("InterDisplay-ExtraLight.woff2") format("woff2"); }
|
|
||||||
@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 200; font-display: swap; src: url("InterDisplay-ExtraLightItalic.woff2") format("woff2"); }
|
|
||||||
@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 300; font-display: swap; src: url("InterDisplay-Light.woff2") format("woff2"); }
|
|
||||||
@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 300; font-display: swap; src: url("InterDisplay-LightItalic.woff2") format("woff2"); }
|
|
||||||
@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 400; font-display: swap; src: url("InterDisplay-Regular.woff2") format("woff2"); }
|
|
||||||
@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 400; font-display: swap; src: url("InterDisplay-Italic.woff2") format("woff2"); }
|
|
||||||
@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 500; font-display: swap; src: url("InterDisplay-Medium.woff2") format("woff2"); }
|
|
||||||
@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 500; font-display: swap; src: url("InterDisplay-MediumItalic.woff2") format("woff2"); }
|
|
||||||
@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 600; font-display: swap; src: url("InterDisplay-SemiBold.woff2") format("woff2"); }
|
|
||||||
@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 600; font-display: swap; src: url("InterDisplay-SemiBoldItalic.woff2") format("woff2"); }
|
|
||||||
@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 700; font-display: swap; src: url("InterDisplay-Bold.woff2") format("woff2"); }
|
|
||||||
@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 700; font-display: swap; src: url("InterDisplay-BoldItalic.woff2") format("woff2"); }
|
|
||||||
@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 800; font-display: swap; src: url("InterDisplay-ExtraBold.woff2") format("woff2"); }
|
|
||||||
@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 800; font-display: swap; src: url("InterDisplay-ExtraBoldItalic.woff2") format("woff2"); }
|
|
||||||
@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 900; font-display: swap; src: url("InterDisplay-Black.woff2") format("woff2"); }
|
|
||||||
@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 900; font-display: swap; src: url("InterDisplay-BlackItalic.woff2") format("woff2"); }
|
|
|
@ -1,49 +0,0 @@
|
||||||
let homeserverBox = document.getElementById("homeserverBox")
|
|
||||||
let statusBox = document.getElementById("statusBox")
|
|
||||||
let changeButton = document.getElementById("changeButton")
|
|
||||||
|
|
||||||
function showElements(yesorno) {
|
|
||||||
if (!yesorno) {
|
|
||||||
homeserverBox.classList.add("hidden")
|
|
||||||
changeButton.classList.add("hidden")
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
homeserverBox.classList.remove("hidden")
|
|
||||||
changeButton.classList.remove("hidden")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
changeButton.addEventListener("click", (event) => {
|
|
||||||
async function doStuff() {
|
|
||||||
let remote = homeserverBox.value
|
|
||||||
|
|
||||||
if (remote == "") {
|
|
||||||
statusBox.innerText = "A homeserver is required!"
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
showElements(false)
|
|
||||||
statusBox.innerText = "Connecting to homeserver..."
|
|
||||||
|
|
||||||
fetch(remote + "/api/version")
|
|
||||||
.then((response) => response)
|
|
||||||
.then((response) => {
|
|
||||||
async function doStuff() {
|
|
||||||
if (response.status == 200) {
|
|
||||||
localStorage.setItem("homeserverURL", remote)
|
|
||||||
|
|
||||||
window.location.href = document.referrer;
|
|
||||||
}
|
|
||||||
else if (response.status == 404) {
|
|
||||||
statusBox.innerText = "Not a valid homeserver!"
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
statusBox.innerText = "Something went wrong!"
|
|
||||||
showElements(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
doStuff()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
doStuff()
|
|
||||||
});
|
|
|
@ -1,199 +0,0 @@
|
||||||
if (localStorage.getItem("DONOTSHARE-secretkey") !== null) {
|
|
||||||
window.location.replace("../app/index.html")
|
|
||||||
document.body.innerHTML = "Redirecting..."
|
|
||||||
throw new Error();
|
|
||||||
}
|
|
||||||
if (localStorage.getItem("DONOTSHARE-password") !== null) {
|
|
||||||
window.location.replace("../app/index.html")
|
|
||||||
document.body.innerHTML = "Redirecting..."
|
|
||||||
throw new Error();
|
|
||||||
}
|
|
||||||
|
|
||||||
let remote = localStorage.getItem("homeserverURL")
|
|
||||||
if (remote == null) {
|
|
||||||
localStorage.setItem("homeserverURL", "https://notes.hectabit.org")
|
|
||||||
remote = "https://notes.hectabit.org"
|
|
||||||
}
|
|
||||||
|
|
||||||
let usernameBox = document.getElementById("usernameBox")
|
|
||||||
let passwordBox = document.getElementById("passwordBox")
|
|
||||||
let statusBox = document.getElementById("statusBox")
|
|
||||||
let signupButton = document.getElementById("signupButton")
|
|
||||||
let inputNameBox = document.getElementById("inputNameBox")
|
|
||||||
let backButton = document.getElementById("backButton")
|
|
||||||
|
|
||||||
usernameBox.classList.remove("hidden")
|
|
||||||
inputNameBox.innerText = "Username:"
|
|
||||||
|
|
||||||
let currentInputType = 0
|
|
||||||
|
|
||||||
function showInput(inputType) {
|
|
||||||
if (inputType == 0) {
|
|
||||||
usernameBox.classList.remove("hidden")
|
|
||||||
passwordBox.classList.add("hidden")
|
|
||||||
backButton.classList.add("hidden")
|
|
||||||
inputNameBox.innerText = "Username:"
|
|
||||||
statusBox.innerText = "Login to your Burgernotes account!"
|
|
||||||
currentInputType = 0
|
|
||||||
} else if (inputType == 1) {
|
|
||||||
usernameBox.classList.add("hidden")
|
|
||||||
passwordBox.classList.remove("hidden")
|
|
||||||
backButton.classList.remove("hidden")
|
|
||||||
inputNameBox.innerText = "Password:"
|
|
||||||
currentInputType = 1
|
|
||||||
} else if (inputType == 2) {
|
|
||||||
usernameBox.classList.add("hidden")
|
|
||||||
passwordBox.classList.add("hidden")
|
|
||||||
signupButton.classList.add("hidden")
|
|
||||||
backButton.classList.add("hidden")
|
|
||||||
inputNameBox.classList.add("hidden")
|
|
||||||
inputNameBox.innerText = "Password:"
|
|
||||||
currentInputType = 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function showElements(yesorno) {
|
|
||||||
if (!yesorno) {
|
|
||||||
usernameBox.classList.add("hidden")
|
|
||||||
passwordBox.classList.add("hidden")
|
|
||||||
signupButton.classList.add("hidden")
|
|
||||||
backButton.classList.add("hidden")
|
|
||||||
inputNameBox.classList.add("hidden")
|
|
||||||
showInput(currentInputType)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
usernameBox.classList.remove("hidden")
|
|
||||||
passwordBox.classList.remove("hidden")
|
|
||||||
signupButton.classList.remove("hidden")
|
|
||||||
backButton.classList.remove("hidden")
|
|
||||||
inputNameBox.classList.remove("hidden")
|
|
||||||
showInput(currentInputType)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
document.getElementById("homeserver").innerText = "Your homeserver is: " + remote + ". "
|
|
||||||
});
|
|
||||||
|
|
||||||
signupButton.addEventListener("click", (event) => {
|
|
||||||
if (passwordBox.classList.contains("hidden")) {
|
|
||||||
if (usernameBox.value == "") {
|
|
||||||
statusBox.innerText = "A username is required!"
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
statusBox.innerText = "Welcome back, " + usernameBox.value + "!"
|
|
||||||
}
|
|
||||||
showInput(1)
|
|
||||||
} else {
|
|
||||||
async function doStuff() {
|
|
||||||
let username = usernameBox.value
|
|
||||||
let password = passwordBox.value
|
|
||||||
|
|
||||||
if (password == "") {
|
|
||||||
statusBox.innerText = "A password is required!"
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
showInput(2)
|
|
||||||
showElements(true)
|
|
||||||
statusBox.innerText = "Signing in..."
|
|
||||||
|
|
||||||
async function hashpassold(pass) {
|
|
||||||
const key = await hashwasm.argon2id({
|
|
||||||
password: pass,
|
|
||||||
salt: await hashwasm.sha512(pass),
|
|
||||||
parallelism: 1,
|
|
||||||
iterations: 256,
|
|
||||||
memorySize: 512,
|
|
||||||
hashLength: 32,
|
|
||||||
outputType: "encoded"
|
|
||||||
});
|
|
||||||
return key
|
|
||||||
};
|
|
||||||
|
|
||||||
async function hashpass(pass) {
|
|
||||||
let key = pass
|
|
||||||
for (let i = 0; i < 128; i++) {
|
|
||||||
key = await hashwasm.sha3(key)
|
|
||||||
}
|
|
||||||
return key
|
|
||||||
};
|
|
||||||
|
|
||||||
fetch(remote + "/api/login", {
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify({
|
|
||||||
username: username,
|
|
||||||
password: await hashpass(password),
|
|
||||||
passwordchange: "no",
|
|
||||||
newpass: "null"
|
|
||||||
}),
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json; charset=UTF-8"
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then((response) => response)
|
|
||||||
.then((response) => {
|
|
||||||
async function doStuff() {
|
|
||||||
let responseData = await response.json()
|
|
||||||
if (response.status == 200) {
|
|
||||||
localStorage.setItem("DONOTSHARE-secretkey", responseData["key"])
|
|
||||||
localStorage.setItem("DONOTSHARE-password", await hashwasm.sha512(password))
|
|
||||||
|
|
||||||
window.location.href = "../app/index.html"
|
|
||||||
}
|
|
||||||
else if (response.status == 401) {
|
|
||||||
console.log("Trying oldhash")
|
|
||||||
fetch(remote + "/api/login", {
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify({
|
|
||||||
username: username,
|
|
||||||
password: await hashpassold(password),
|
|
||||||
passwordchange: "yes",
|
|
||||||
newpass: await hashpass(password)
|
|
||||||
}),
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json; charset=UTF-8"
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then((response) => response)
|
|
||||||
.then((response) => {
|
|
||||||
async function doStuff2() {
|
|
||||||
let responseData = await response.json()
|
|
||||||
if (response.status == 200) {
|
|
||||||
localStorage.setItem("DONOTSHARE-secretkey", responseData["key"])
|
|
||||||
localStorage.setItem("DONOTSHARE-password", await hashwasm.sha512(password))
|
|
||||||
|
|
||||||
window.location.href = "../app/index.html"
|
|
||||||
}
|
|
||||||
else if (response.status == 401) {
|
|
||||||
statusBox.innerText = "Wrong username or password..."
|
|
||||||
showInput(1)
|
|
||||||
showElements(true)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
statusBox.innerText = "Something went wrong! (error code: " + response.status + ")"
|
|
||||||
showInput(1)
|
|
||||||
showElements(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
doStuff2()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
statusBox.innerText = "Something went wrong! (error code: " + response.status + ")"
|
|
||||||
showInput(1)
|
|
||||||
showElements(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
doStuff()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
doStuff()
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
backButton.addEventListener("click", (event) => {
|
|
||||||
showInput(0)
|
|
||||||
});
|
|
||||||
|
|
||||||
showInput(0)
|
|
|
@ -1,642 +0,0 @@
|
||||||
if (localStorage.getItem("DONOTSHARE-secretkey") === null) {
|
|
||||||
window.location.replace("../login/index.html")
|
|
||||||
document.body.innerHTML = "Redirecting..."
|
|
||||||
throw new Error();
|
|
||||||
}
|
|
||||||
if (localStorage.getItem("DONOTSHARE-password") === null) {
|
|
||||||
window.location.replace("../login/index.html")
|
|
||||||
document.body.innerHTML = "Redirecting..."
|
|
||||||
throw new Error();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (localStorage.getItem("CACHE-username") !== null) {
|
|
||||||
document.getElementById("usernameBox").innerText = localStorage.getItem("CACHE-username")
|
|
||||||
}
|
|
||||||
|
|
||||||
let remote = localStorage.getItem("homeserverURL")
|
|
||||||
if (remote == null) {
|
|
||||||
localStorage.setItem("homeserverURL", "https://notes.hectabit.org")
|
|
||||||
remote = "https://notes.hectabit.org"
|
|
||||||
}
|
|
||||||
|
|
||||||
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]}` }
|
|
||||||
|
|
||||||
function truncateString(str, num) {
|
|
||||||
if (str.length > num) {
|
|
||||||
return str.slice(0, num) + "...";
|
|
||||||
} else {
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let secretkey = localStorage.getItem("DONOTSHARE-secretkey")
|
|
||||||
let password = localStorage.getItem("DONOTSHARE-password")
|
|
||||||
|
|
||||||
let usernameBox = document.getElementById("usernameBox")
|
|
||||||
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")
|
|
||||||
let exitThing = document.getElementById("exitThing")
|
|
||||||
let exitSessionsThing = document.getElementById("exitSessionsThing")
|
|
||||||
let sessionManagerButton = document.getElementById("sessionManagerButton")
|
|
||||||
let sessionManagerDiv = document.getElementById("sessionManagerDiv")
|
|
||||||
let sessionDiv = document.getElementById("sessionDiv")
|
|
||||||
let mfaDiv = document.getElementById("mfaDiv")
|
|
||||||
let deleteMyAccountButton = document.getElementById("deleteMyAccountButton")
|
|
||||||
let storageThing = document.getElementById("storageThing")
|
|
||||||
let storageProgressThing = document.getElementById("storageProgressThing")
|
|
||||||
let usernameThing = document.getElementById("usernameThing")
|
|
||||||
let logOutButton = document.getElementById("logOutButton")
|
|
||||||
let notesBar = document.getElementById("notesBar")
|
|
||||||
let notesDiv = document.getElementById("notesDiv")
|
|
||||||
let newNote = document.getElementById("newNote")
|
|
||||||
let noteBox = document.getElementById("noteBox")
|
|
||||||
let loadingStuff = document.getElementById("loadingStuff")
|
|
||||||
let burgerButton = document.getElementById("burgerButton")
|
|
||||||
let exportNotesButton = document.getElementById("exportNotesButton")
|
|
||||||
|
|
||||||
let selectedNote = 0
|
|
||||||
let timer
|
|
||||||
let waitTime = 400
|
|
||||||
|
|
||||||
if (/Android|iPhone|iPod/i.test(navigator.userAgent)) {
|
|
||||||
noteBox.style.width = "10px";
|
|
||||||
notesBar.style.width = "calc(100% - 10px)"
|
|
||||||
noteBox.readOnly = true
|
|
||||||
noteBox.style.fontSize = "18px"
|
|
||||||
noteBox.classList.add("hidden")
|
|
||||||
|
|
||||||
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() {
|
|
||||||
if (touchendX > touchstartX + 75) {
|
|
||||||
notesBar.style.width = "calc(100% - 10px)";
|
|
||||||
noteBox.style.width = "10px"
|
|
||||||
if (selectedNote != 0) {
|
|
||||||
noteBox.readOnly = true
|
|
||||||
}
|
|
||||||
notesDiv.classList.remove("hidden")
|
|
||||||
noteBox.classList.add("hidden")
|
|
||||||
newNote.classList.remove("hidden")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (touchendX < touchstartX - 75) {
|
|
||||||
noteBox.style.width = "calc(100% - 30px)";
|
|
||||||
notesBar.style.width = "10px"
|
|
||||||
if (selectedNote != 0) {
|
|
||||||
noteBox.readOnly = false
|
|
||||||
}
|
|
||||||
notesDiv.classList.add("hidden")
|
|
||||||
noteBox.classList.remove("hidden")
|
|
||||||
newNote.classList.add("hidden")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
noteBox.value = ""
|
|
||||||
noteBox.readOnly = true
|
|
||||||
|
|
||||||
let noteCount = 0
|
|
||||||
|
|
||||||
function displayError(message) {
|
|
||||||
errorDiv.classList.remove("hidden")
|
|
||||||
optionsCoverDiv.classList.remove("hidden")
|
|
||||||
|
|
||||||
errorMessageThing.innerHTML = message
|
|
||||||
}
|
|
||||||
|
|
||||||
closeErrorButton.addEventListener("click", (event) => {
|
|
||||||
errorDiv.classList.add("hidden")
|
|
||||||
optionsCoverDiv.classList.add("hidden")
|
|
||||||
});
|
|
||||||
|
|
||||||
function displayPrompt(message, placeholdertext, callback) {
|
|
||||||
errorMessageThing.innerText = message
|
|
||||||
errorInput.value = ""
|
|
||||||
errorInput.placeholder = placeholdertext
|
|
||||||
|
|
||||||
closeErrorButton.addEventListener("click", (event) => {
|
|
||||||
if (callback) {
|
|
||||||
callback(errorInput.value)
|
|
||||||
callback = undefined
|
|
||||||
}
|
|
||||||
});
|
|
||||||
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")
|
|
||||||
|
|
||||||
errorInput.focus()
|
|
||||||
}
|
|
||||||
|
|
||||||
closeErrorButton.addEventListener("click", (event) => {
|
|
||||||
errorDiv.classList.add("hidden")
|
|
||||||
optionsCoverDiv.classList.add("hidden")
|
|
||||||
errorInput.classList.add("hidden")
|
|
||||||
cancelErrorButton.classList.add("hidden")
|
|
||||||
});
|
|
||||||
|
|
||||||
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()
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
function truncateString(str, num) {
|
|
||||||
if (str.length > num) {
|
|
||||||
return str.slice(0, num) + "..";
|
|
||||||
} else {
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function updateUserInfo() {
|
|
||||||
fetch(remote + "/api/userinfo", {
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify({
|
|
||||||
secretKey: secretkey
|
|
||||||
}),
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json; charset=UTF-8"
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
noteBox.readOnly = true
|
|
||||||
noteBox.value = ""
|
|
||||||
noteBox.placeholder = "Failed to connect to the server.\nPlease check your internet connection."
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
async function doStuff() {
|
|
||||||
if (response.status == 500) {
|
|
||||||
displayError("Something went wrong! Signing you out..")
|
|
||||||
closeErrorButton.classList.add("hidden")
|
|
||||||
usernameBox.innerText = ""
|
|
||||||
setTimeout(function () {
|
|
||||||
window.location.replace("../logout/index.html")
|
|
||||||
}, 2500);
|
|
||||||
} else {
|
|
||||||
let responseData = await response.json()
|
|
||||||
usernameBox.innerText = responseData["username"]
|
|
||||||
usernameThing.innerText = "Username: " + responseData["username"]
|
|
||||||
storageThing.innerText = "You've used " + formatBytes(responseData["storageused"]) + " out of " + formatBytes(responseData["storagemax"])
|
|
||||||
storageProgressThing.value = responseData["storageused"]
|
|
||||||
storageProgressThing.max = responseData["storagemax"]
|
|
||||||
noteCount = responseData["notecount"]
|
|
||||||
localStorage.setItem("CACHE-username", responseData["username"])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
doStuff()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
usernameBox.addEventListener("click", (event) => {
|
|
||||||
optionsCoverDiv.classList.remove("hidden")
|
|
||||||
optionsDiv.classList.remove("hidden")
|
|
||||||
updateUserInfo()
|
|
||||||
});
|
|
||||||
logOutButton.addEventListener("click", (event) => {
|
|
||||||
window.location.replace("../logout/index.html")
|
|
||||||
});
|
|
||||||
exitThing.addEventListener("click", (event) => {
|
|
||||||
optionsDiv.classList.add("hidden")
|
|
||||||
optionsCoverDiv.classList.add("hidden")
|
|
||||||
});
|
|
||||||
deleteMyAccountButton.addEventListener("click", (event) => {
|
|
||||||
if (confirm("Are you REALLY sure that you want to delete your account? There's no going back!") == true) {
|
|
||||||
fetch(remote + "/api/deleteaccount", {
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify({
|
|
||||||
secretKey: secretkey
|
|
||||||
}),
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json; charset=UTF-8"
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
if (response.status == 200) {
|
|
||||||
window.location.href = "../logout/index.html"
|
|
||||||
} else {
|
|
||||||
displayError("Failed to delete account (HTTP error code " + response.status + ")")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
});
|
|
||||||
sessionManagerButton.addEventListener("click", (event) => {
|
|
||||||
optionsDiv.classList.add("hidden")
|
|
||||||
sessionManagerDiv.classList.remove("hidden")
|
|
||||||
|
|
||||||
fetch(remote + "/api/sessions/list", {
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify({
|
|
||||||
secretKey: secretkey
|
|
||||||
}),
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json; charset=UTF-8"
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.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) {
|
|
||||||
sessionText.innerText = "(current) " + responseData[i]["device"]
|
|
||||||
} else {
|
|
||||||
sessionText.innerText = responseData[i]["device"]
|
|
||||||
}
|
|
||||||
sessionText.title = responseData[i]["device"]
|
|
||||||
sessionRemoveButton.innerText = "x"
|
|
||||||
|
|
||||||
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"))) {
|
|
||||||
sessionImage.src = "/static/svg/device_smartphone.svg"
|
|
||||||
}
|
|
||||||
|
|
||||||
sessionRemoveButton.addEventListener("click", (event) => {
|
|
||||||
fetch(remote + "/api/sessions/remove", {
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify({
|
|
||||||
secretKey: secretkey,
|
|
||||||
sessionId: responseData[i]["id"]
|
|
||||||
}),
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json; charset=UTF-8"
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
if (responseData[i]["thisSession"] == true) {
|
|
||||||
window.location.replace("../logout/index.html")
|
|
||||||
}
|
|
||||||
});
|
|
||||||
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")
|
|
||||||
});
|
|
||||||
|
|
||||||
updateUserInfo()
|
|
||||||
|
|
||||||
function updateWordCount() {
|
|
||||||
let wordCount = noteBox.value.split(" ").length
|
|
||||||
if (wordCount == 1) {
|
|
||||||
wordCount = 0
|
|
||||||
}
|
|
||||||
wordCountBox.innerText = wordCount + " words"
|
|
||||||
}
|
|
||||||
|
|
||||||
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(remote + "/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 = ""
|
|
||||||
displayError("Something went wrong... Please try again later!")
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
selectedNote = nameithink
|
|
||||||
noteBox.readOnly = false
|
|
||||||
noteBox.placeholder = "Type something!"
|
|
||||||
|
|
||||||
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
|
|
||||||
updateWordCount()
|
|
||||||
|
|
||||||
noteBox.addEventListener("input", (event) => {
|
|
||||||
updateWordCount()
|
|
||||||
clearTimeout(timer);
|
|
||||||
timer = setTimeout(() => {
|
|
||||||
let encryptedTitle = "New note"
|
|
||||||
if (noteBox.value.substring(0, noteBox.value.indexOf("\n")) != "") {
|
|
||||||
let firstTitle = noteBox.value.substring(0, noteBox.value.indexOf("\n"));
|
|
||||||
|
|
||||||
document.getElementById(nameithink).innerText = firstTitle
|
|
||||||
encryptedTitle = CryptoJS.AES.encrypt(firstTitle, password).toString();
|
|
||||||
}
|
|
||||||
let encryptedText = CryptoJS.AES.encrypt(noteBox.value, password).toString();
|
|
||||||
|
|
||||||
if (selectedNote == nameithink) {
|
|
||||||
fetch(remote + "/api/editnote", {
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify({
|
|
||||||
secretKey: secretkey,
|
|
||||||
noteId: nameithink,
|
|
||||||
content: encryptedText,
|
|
||||||
title: encryptedTitle
|
|
||||||
}),
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json; charset=UTF-8"
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
if (response.status == 418) {
|
|
||||||
displayError("You've ran out of storage... Changes will not be saved until you free up storage!")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
displayError("Failed to save changes, please try again later...")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}, waitTime);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
doStuff()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateNotes() {
|
|
||||||
fetch(remote + "/api/listnotes", {
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify({
|
|
||||||
secretKey: secretkey
|
|
||||||
}),
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json; charset=UTF-8"
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
async function doStuff() {
|
|
||||||
document.querySelectorAll(".noteButton").forEach((el) => el.remove());
|
|
||||||
noteBox.readOnly = true
|
|
||||||
selectedNote = 0
|
|
||||||
noteBox.placeholder = ""
|
|
||||||
noteBox.value = ""
|
|
||||||
clearTimeout(timer)
|
|
||||||
updateWordCount()
|
|
||||||
|
|
||||||
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 = truncateString(originalTitle, 15)
|
|
||||||
|
|
||||||
noteButton.addEventListener("click", (event) => {
|
|
||||||
if (event.ctrlKey) {
|
|
||||||
fetch(remote + "/api/removenote", {
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify({
|
|
||||||
secretKey: secretkey,
|
|
||||||
noteId: responseData[i]["id"]
|
|
||||||
}),
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json; charset=UTF-8"
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
updateNotes()
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
displayError("Something went wrong! Please try again later...")
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
selectNote(responseData[i]["id"])
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
document.querySelectorAll(".loadingStuff").forEach((el) => el.remove());
|
|
||||||
}
|
|
||||||
doStuff()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
updateNotes()
|
|
||||||
|
|
||||||
newNote.addEventListener("click", (event) => {
|
|
||||||
let noteName = "New note"
|
|
||||||
let encryptedName = CryptoJS.AES.encrypt(noteName, password).toString();
|
|
||||||
fetch(remote + "/api/newnote", {
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify({
|
|
||||||
secretKey: secretkey,
|
|
||||||
noteName: encryptedName,
|
|
||||||
}),
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json; charset=UTF-8"
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
displayError("Failed to create new note, please try again later...")
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
if (response.status !== 200) {
|
|
||||||
updateNotes()
|
|
||||||
displayError("Failed to create new note (HTTP error code " + response.status + ")")
|
|
||||||
} else {
|
|
||||||
updateNotes()
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
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(remote + "/api/exportnotes", {
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify({
|
|
||||||
secretKey: secretkey
|
|
||||||
}),
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json; charset=UTF-8"
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
async function doStuff() {
|
|
||||||
let responseData = await response.json()
|
|
||||||
for (let i in responseData) {
|
|
||||||
exportNotes.innerText = "Decrypting " + i + "/" + noteCount
|
|
||||||
|
|
||||||
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))
|
|
||||||
|
|
||||||
exportNotesButton.innerText = "Export notes"
|
|
||||||
downloadObjectAsJson(jsonString, "data")
|
|
||||||
optionsDiv.classList.add("hidden")
|
|
||||||
displayError("Exported notes!")
|
|
||||||
|
|
||||||
}
|
|
||||||
doStuff()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function isFirstTimeVisitor() {
|
|
||||||
if (document.cookie.indexOf("visited=true") !== -1) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
var expirationDate = new Date();
|
|
||||||
expirationDate.setFullYear(expirationDate.getFullYear() + 1);
|
|
||||||
document.cookie = "visited=true; expires=" + expirationDate.toUTCString() + "; path=/; SameSite=strict";
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function firstNewVersion() {
|
|
||||||
if (document.cookie.indexOf("version=1.1") !== -1) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
var expirationDate = new Date();
|
|
||||||
expirationDate.setFullYear(expirationDate.getFullYear() + 1);
|
|
||||||
document.cookie = "version=1.1; expires=" + expirationDate.toUTCString() + "; path=/; SameSite=strict";
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exportNotesButton.addEventListener("click", (event) => {
|
|
||||||
exportNotesButton.innerText = "Downloading..."
|
|
||||||
exportNotes()
|
|
||||||
});
|
|
||||||
|
|
||||||
removeBox.addEventListener("click", (event) => {
|
|
||||||
if (selectedNote == 0) {
|
|
||||||
displayError("You need to select a note first!")
|
|
||||||
} else {
|
|
||||||
fetch(remote + "/api/removenote", {
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify({
|
|
||||||
secretKey: secretkey,
|
|
||||||
noteId: selectedNote
|
|
||||||
}),
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json; charset=UTF-8"
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
updateNotes()
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
displayError("Something went wrong! Please try again later...")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (isFirstTimeVisitor() && /Android|iPhone|iPod/i.test(navigator.userAgent)) {
|
|
||||||
displayError("To use Burgernotes:\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")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (firstNewVersion()) {
|
|
||||||
displayError("What's new in Burgernotes 1.1?\n\nNote titles are now the first line of a note \(will not break compatibility with older notes\)\nIntroduced improved login screen\nNote titles now scroll correctly")
|
|
||||||
}
|
|
|
@ -1,109 +0,0 @@
|
||||||
if (localStorage.getItem("DONOTSHARE-secretkey") !== null) {
|
|
||||||
window.location.replace("../app/index.html")
|
|
||||||
document.body.innerHTML = "Redirecting..."
|
|
||||||
throw new Error();
|
|
||||||
}
|
|
||||||
if (localStorage.getItem("DONOTSHARE-password") !== null) {
|
|
||||||
window.location.replace("../app/index.html")
|
|
||||||
document.body.innerHTML = "Redirecting..."
|
|
||||||
throw new Error();
|
|
||||||
}
|
|
||||||
|
|
||||||
let remote = localStorage.getItem("homeserverURL")
|
|
||||||
if (remote == null) {
|
|
||||||
localStorage.setItem("homeserverURL", "https://notes.hectabit.org")
|
|
||||||
remote = "https://notes.hectabit.org"
|
|
||||||
}
|
|
||||||
|
|
||||||
let usernameBox = document.getElementById("usernameBox")
|
|
||||||
let passwordBox = document.getElementById("passwordBox")
|
|
||||||
let statusBox = document.getElementById("statusBox")
|
|
||||||
let signupButton = document.getElementById("signupButton")
|
|
||||||
|
|
||||||
function showElements(yesorno) {
|
|
||||||
if (!yesorno) {
|
|
||||||
usernameBox.classList.add("hidden")
|
|
||||||
passwordBox.classList.add("hidden")
|
|
||||||
signupButton.classList.add("hidden")
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
usernameBox.classList.remove("hidden")
|
|
||||||
passwordBox.classList.remove("hidden")
|
|
||||||
signupButton.classList.remove("hidden")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
document.getElementById("homeserver").innerText = "Your homeserver is: " + remote + ". "
|
|
||||||
});
|
|
||||||
|
|
||||||
signupButton.addEventListener("click", (event) => {
|
|
||||||
async function doStuff() {
|
|
||||||
let username = usernameBox.value
|
|
||||||
let password = passwordBox.value
|
|
||||||
|
|
||||||
if (username == "") {
|
|
||||||
statusBox.innerText = "A username is required!"
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if ((username).length > 20) {
|
|
||||||
statusBox.innerText = "Username cannot be more than 20 characters!"
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (password == "") {
|
|
||||||
statusBox.innerText = "A password is required!"
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if ((password).length < 8) {
|
|
||||||
statusBox.innerText = "8 or more characters are required!"
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
showElements(false)
|
|
||||||
statusBox.innerText = "Creating account, please hold on..."
|
|
||||||
|
|
||||||
async function hashpass(pass) {
|
|
||||||
let key = pass
|
|
||||||
for (let i = 0; i < 128; i++) {
|
|
||||||
key = await hashwasm.sha3(key)
|
|
||||||
}
|
|
||||||
return key
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
fetch(remote + "/api/signup", {
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify({
|
|
||||||
username: username,
|
|
||||||
password: await hashpass(password)
|
|
||||||
}),
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json; charset=UTF-8"
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then((response) => response)
|
|
||||||
.then((response) => {
|
|
||||||
async function doStuff() {
|
|
||||||
let responseData = await response.json()
|
|
||||||
|
|
||||||
if (response.status == 200) {
|
|
||||||
statusBox.innerText == "redirecting.."
|
|
||||||
localStorage.setItem("DONOTSHARE-secretkey", responseData["key"])
|
|
||||||
localStorage.setItem("DONOTSHARE-password", await hashwasm.sha512(password))
|
|
||||||
|
|
||||||
window.location.href = "../app/index.html"
|
|
||||||
}
|
|
||||||
else if (response.status == 409) {
|
|
||||||
statusBox.innerText = "Username already taken!"
|
|
||||||
showElements(true)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
statusBox.innerText = "Something went wrong!"
|
|
||||||
showElements(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
doStuff()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
doStuff()
|
|
||||||
});
|
|
|
@ -1 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48"><path d="M450-450H200v-60h250v-250h60v250h250v60H510v250h-60v-250Z"/></svg>
|
|
Before Width: | Height: | Size: 163 B |
|
@ -1 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M320-240 80-480l240-240 57 57-184 184 183 183-56 56Zm320 0-57-57 184-184-183-183 56-56 240 240-240 240Z"/></svg>
|
|
Before Width: | Height: | Size: 209 B |
|
@ -1 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M280-120q-33 0-56.5-23.5T200-200v-520h-40v-80h200v-40h240v40h200v80h-40v520q0 33-23.5 56.5T680-120H280Zm400-600H280v520h400v-520ZM360-280h80v-360h-80v360Zm160 0h80v-360h-80v360ZM280-720v520-520Z"/></svg>
|
|
Before Width: | Height: | Size: 300 B |
|
@ -1 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48"><path d="m361-299 119-121 120 121 47-48-119-121 119-121-47-48-120 121-119-121-48 48 120 121-120 121 48 48ZM261-120q-24 0-42-18t-18-42v-570h-41v-60h188v-30h264v30h188v60h-41v570q0 24-18 42t-42 18H261Zm438-630H261v570h438v-570Zm-438 0v570-570Z"/></svg>
|
|
Before Width: | Height: | Size: 338 B |
|
@ -1 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48"><path d="M70-120q-12.75 0-21.375-8.675Q40-137.351 40-150.175 40-163 48.625-171.5T70-180h820q12.75 0 21.375 8.675 8.625 8.676 8.625 21.5 0 12.825-8.625 21.325T890-120H70Zm70-120q-24 0-42-18t-18-42v-480q0-24 18-42t42-18h680q24 0 42 18t18 42v480q0 24-18 42t-42 18H140Zm0-60h680v-480H140v480Zm0 0v-480 480Z"/></svg>
|
|
Before Width: | Height: | Size: 399 B |
|
@ -1 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48"><path d="M140-160q-24 0-42-18t-18-42v-520q0-24 18-42t42-18h680q24 0 42 18t18 42v520q0 24-18 42t-42 18H140Zm0-60h680v-436H140v436Zm160-72-42-42 103-104-104-104 43-42 146 146-146 146Zm190 4v-60h220v60H490Z"/></svg>
|
|
Before Width: | Height: | Size: 300 B |
|
@ -1 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48"><path d="M260-40q-24 0-42-18t-18-42v-760q0-24 18-42t42-18h440q24 0 42 18t18 42v760q0 24-18 42t-42 18H260Zm0-90v30h440v-30H260Zm0-60h440v-580H260v580Zm0-640h440v-30H260v30Zm0 0v-30 30Zm0 700v30-30Z"/></svg>
|
|
Before Width: | Height: | Size: 293 B |
|
@ -1 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48"><path d="M480-313 287-506l43-43 120 120v-371h60v371l120-120 43 43-193 193ZM220-160q-24 0-42-18t-18-42v-143h60v143h520v-143h60v143q0 24-18 42t-42 18H220Z"/></svg>
|
|
Before Width: | Height: | Size: 249 B |
Before Width: | Height: | Size: 8.1 KiB |
Before Width: | Height: | Size: 8.1 KiB |
|
@ -1 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M280-240q-17 0-28.5-11.5T240-280v-80h520v-360h80q17 0 28.5 11.5T880-680v600L720-240H280ZM80-280v-560q0-17 11.5-28.5T120-880h520q17 0 28.5 11.5T680-840v360q0 17-11.5 28.5T640-440H240L80-280Zm520-240v-280H160v280h440Zm-440 0v-280 280Z"/></svg>
|
|
Before Width: | Height: | Size: 338 B |
3535
static/svg/grid.svg
Before Width: | Height: | Size: 244 KiB |
|
@ -1 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M440-280h80v-240h-80v240Zm40-320q17 0 28.5-11.5T520-640q0-17-11.5-28.5T480-680q-17 0-28.5 11.5T440-640q0 17 11.5 28.5T480-600Zm0 520q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>
|
|
Before Width: | Height: | Size: 516 B |
|
@ -1 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48"><path d="M290-620v-60h550v60H290Zm0 170v-60h550v60H290Zm0 170v-60h550v60H290ZM150-620q-12 0-21-9t-9-21.5q0-12.5 9-21t21.5-8.5q12.5 0 21 8.625T180-650q0 12-8.625 21T150-620Zm0 170q-12 0-21-9t-9-21.5q0-12.5 9-21t21.5-8.5q12.5 0 21 8.625T180-480q0 12-8.625 21T150-450Zm0 170q-12 0-21-9t-9-21.5q0-12.5 9-21t21.5-8.5q12.5 0 21 8.625T180-310q0 12-8.625 21T150-280Z"/></svg>
|
|
Before Width: | Height: | Size: 455 B |
|
@ -1 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48"><path d="M180-120q-24 0-42-18t-18-42v-600q0-24 18-42t42-18h299v60H180v600h299v60H180Zm486-185-43-43 102-102H360v-60h363L621-612l43-43 176 176-174 174Z"/></svg>
|
|
Before Width: | Height: | Size: 247 B |
|
@ -1 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M634-320q-14 0-24-10t-10-24v-132q0-14 10-24t24-10h6v-40q0-33 23.5-56.5T720-640q33 0 56.5 23.5T800-560v40h6q14 0 24 10t10 24v132q0 14-10 24t-24 10H634Zm46-200h80v-40q0-17-11.5-28.5T720-600q-17 0-28.5 11.5T680-560v40ZM280-40q-33 0-56.5-23.5T200-120v-720q0-33 23.5-56.5T280-920h400q33 0 56.5 23.5T760-840v160h-80v-40H280v480h400v-40h80v160q0 33-23.5 56.5T680-40H280Zm0-120v40h400v-40H280Zm0-640h400v-40H280v40Zm0 0v-40 40Zm0 640v40-40Z"/></svg>
|
|
Before Width: | Height: | Size: 538 B |
|
@ -1,82 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<title>Burgernotes</title>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
|
||||||
<link rel="stylesheet" type="text/css" href="../static/css/style.css" />
|
|
||||||
<script type="text/javascript" src="../static/js/crypto-js.js"></script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div class="topBar">
|
|
||||||
<p tabindex="0" class="logo" id="burgerButton">Burgernotes</p>
|
|
||||||
<p tabindex="0" id="usernameBox" class="usernameBox"></p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="bottomBar">
|
|
||||||
<button id="removeBox" class="removeButton"></button>
|
|
||||||
<button id="wordCountBox">0 words</button>
|
|
||||||
<div class="textManipulator">
|
|
||||||
<button id="textMinusBox">-</button>
|
|
||||||
<button id="textSizeBox">16px</button>
|
|
||||||
<button id="textPlusBox">+</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="notesBar" class="notesBar">
|
|
||||||
<button id="newNote" class="newNote"><img id="newNoteImage" draggable="false" alt=""
|
|
||||||
src="../static/svg/add.svg">New note</button>
|
|
||||||
<div id="notesDiv" class="notesDiv">
|
|
||||||
<button class="loadingStuff" id="loadingStuff"></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="optionsCoverDiv" class="optionsCoverDiv hidden">
|
|
||||||
<div id="optionsDiv" class="optionsDiv hidden">
|
|
||||||
<button class="exit" id="exitThing">X</button>
|
|
||||||
<h3 class="w300">Your account</h3>
|
|
||||||
<p id="usernameThing"></p>
|
|
||||||
<p id="passwordThing"></p>
|
|
||||||
<div class="section"></div>
|
|
||||||
<p>Storage</p>
|
|
||||||
<progress id="storageProgressThing" value="0" max="100"></progress><br>
|
|
||||||
<p id="storageThing"></p>
|
|
||||||
<div class="section"></div>
|
|
||||||
<p>Account managment</p>
|
|
||||||
<button id="deleteMyAccountButton"><img src="../static/svg/delete_forever.svg">Delete my account</button>
|
|
||||||
<button id="exportNotesButton"><img src="../static/svg/download.svg">Export notes</button>
|
|
||||||
<button id="sessionManagerButton"><img src="../static/svg/list.svg">Session manager</button>
|
|
||||||
<button class="lastButton" id="logOutButton"><img src="../static/svg/logout.svg">Log out</button>
|
|
||||||
</div>
|
|
||||||
<div id="sessionManagerDiv" class="optionsDiv hidden">
|
|
||||||
<button class="exit" id="exitSessionsThing">X</button>
|
|
||||||
<h3 class="w300">Session manager</h3>
|
|
||||||
<p>Manage your sessions</p>
|
|
||||||
<div class="section"></div>
|
|
||||||
<div class="sessionDiv" id="sessionDiv">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="errorDiv" class="optionsDiv hidden">
|
|
||||||
<p id="errorMessageThing"></p>
|
|
||||||
<input class="hidden" id="errorInput" type="text" placeholder=""><br></input>
|
|
||||||
<button class="normalButton" id="closeErrorButton">Ok</button>
|
|
||||||
<button class="normalButton hidden" id="cancelErrorButton">Cancel</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<textarea id="noteBox" class="noteBox"></textarea>
|
|
||||||
|
|
||||||
<script type="text/javascript" src="../static/js/main.js"></script>
|
|
||||||
<script>
|
|
||||||
for (let i = 0; i < 40; i++) {
|
|
||||||
notesDiv.appendChild(loadingStuff.cloneNode())
|
|
||||||
}
|
|
||||||
loadingStuff.remove()
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
|
@ -1,125 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<title>Burgernotes</title>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div class="mainDiv">
|
|
||||||
<h1>Burgernotes is down</h1>
|
|
||||||
<p>We're down for maintenance, please try again later!</p>
|
|
||||||
|
|
||||||
<!-- please don't mind the spaghetti code :3 -->
|
|
||||||
<img class="grid" src="/grid.svg">
|
|
||||||
<img class="grid grid2" src="/grid.svg">
|
|
||||||
<img class="grid grid3" src="/grid.svg">
|
|
||||||
<img class="grid grid4" src="/grid.svg">
|
|
||||||
<img class="grid grid5" src="/grid.svg">
|
|
||||||
<img class="grid grid6" src="/grid.svg">
|
|
||||||
<img class="grid grid7" src="/grid.svg">
|
|
||||||
<img class="grid grid8" src="/grid.svg">
|
|
||||||
<img class="grid grid9" src="/grid.svg">
|
|
||||||
<img class="grid grid10" src="/grid.svg">
|
|
||||||
<img class="grid grid11" src="/grid.svg">
|
|
||||||
<img class="grid grid12" src="/grid.svg">
|
|
||||||
<img class="grid grid13" src="/grid.svg">
|
|
||||||
<img class="grid grid14" src="/grid.svg">
|
|
||||||
<img class="grid grid15" src="/grid.svg">
|
|
||||||
<img class="grid grid16" src="/grid.svg">
|
|
||||||
<img class="grid grid17" src="/grid.svg">
|
|
||||||
<img class="grid grid18" src="/grid.svg">
|
|
||||||
<img class="grid grid19" src="/grid.svg">
|
|
||||||
<img class="grid grid20" src="/grid.svg">
|
|
||||||
<img class="grid grid21" src="/grid.svg">
|
|
||||||
<img class="grid grid22" src="/grid.svg">
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
@import url("/static/fonts/inter.css");
|
|
||||||
body {
|
|
||||||
position: absolute;
|
|
||||||
margin-left: 25px;
|
|
||||||
left: 0;
|
|
||||||
bottom: 50%;
|
|
||||||
font-family: "Inter", sans-serif;
|
|
||||||
background-color: #202020;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid {
|
|
||||||
position: fixed;
|
|
||||||
left: 0;
|
|
||||||
bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid2 {
|
|
||||||
left: 100px;
|
|
||||||
}
|
|
||||||
.grid3 {
|
|
||||||
left: 200px;
|
|
||||||
}
|
|
||||||
.grid4 {
|
|
||||||
left: 300px;
|
|
||||||
}
|
|
||||||
.grid5 {
|
|
||||||
left: 400px;
|
|
||||||
}
|
|
||||||
.grid6 {
|
|
||||||
left: 500px;
|
|
||||||
}
|
|
||||||
.grid7 {
|
|
||||||
left: 600px;
|
|
||||||
}
|
|
||||||
.grid8 {
|
|
||||||
left: 700px;
|
|
||||||
}
|
|
||||||
.grid9 {
|
|
||||||
left: 800px;
|
|
||||||
}
|
|
||||||
.grid10 {
|
|
||||||
left: 900px;
|
|
||||||
}
|
|
||||||
.grid11 {
|
|
||||||
left: 1000px;
|
|
||||||
}
|
|
||||||
.grid12 {
|
|
||||||
left: 1100px;
|
|
||||||
}
|
|
||||||
.grid13 {
|
|
||||||
left: 1200px;
|
|
||||||
}
|
|
||||||
.grid14 {
|
|
||||||
left: 1300px;
|
|
||||||
}
|
|
||||||
.grid15 {
|
|
||||||
left: 1400px;
|
|
||||||
}
|
|
||||||
.grid16 {
|
|
||||||
left: 1500px;
|
|
||||||
}
|
|
||||||
.grid17 {
|
|
||||||
left: 1600px;
|
|
||||||
}
|
|
||||||
.grid18 {
|
|
||||||
left: 1700px;
|
|
||||||
}
|
|
||||||
.grid19 {
|
|
||||||
left: 1800px;
|
|
||||||
}
|
|
||||||
.grid20 {
|
|
||||||
left: 1900px;
|
|
||||||
}
|
|
||||||
.grid21 {
|
|
||||||
left: 2000px;
|
|
||||||
}
|
|
||||||
.grid22 {
|
|
||||||
left: 2100px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
</html>
|
|
|
@ -1,23 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<title>Burgernotes</title>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
|
||||||
<link rel="stylesheet" type="text/css" href="../static/css/style.css" />
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<h2 class="w300">{{ errorMessage }}</h2>
|
|
||||||
{{ errorCode }} | {{ errorMessage }}
|
|
||||||
</body>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
margin-left: 15px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
</html>
|
|
|
@ -1,38 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<title>Signup - Burgernotes</title>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
|
||||||
<link rel="stylesheet" type="text/css" href="../static/css/style.css">
|
|
||||||
<script src="../static/js/hash-wasm.js"></script>
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
background-color: #d9d9d9;
|
|
||||||
background-image: url("/static/svg/grid.svg");
|
|
||||||
background-repeat: repeat;
|
|
||||||
background-size: 312px
|
|
||||||
}
|
|
||||||
.inoutdiv {
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div class="inoutdiv">
|
|
||||||
<h2 class="w300">Homeserver</h2>
|
|
||||||
<p>Change your Burgernotes homeserver</p>
|
|
||||||
<p id="statusBox"></p>
|
|
||||||
|
|
||||||
<input type="text" value="https://" id="homeserverBox"><br>
|
|
||||||
<button id="changeButton">Change</button><br><br>
|
|
||||||
<p>Please put in the URL in standard format; https://, http://, etc.</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script type="text/javascript" src="../static/js/homeserver.js"></script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
|
@ -1,41 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<title>Login - Burgernotes</title>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
|
||||||
<link rel="stylesheet" type="text/css" href="../static/css/style.css" />
|
|
||||||
<script src="../static/js/hash-wasm.js"></script>
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
background-color: #d9d9d9;
|
|
||||||
background-image: url("/static/svg/grid.svg");
|
|
||||||
background-repeat: repeat;
|
|
||||||
background-size: 312px;
|
|
||||||
}
|
|
||||||
.inoutdiv {
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div class="inoutdiv">
|
|
||||||
<h2 class="w300">Login</h2>
|
|
||||||
<p id="statusBox"></p>
|
|
||||||
<span id="inputNameBox" style="margin-right: 10px;color: var(--text-color);"></span>
|
|
||||||
<input id="usernameBox" class="hidden" type="text" placeholder="Enter your username">
|
|
||||||
<input id="passwordBox" class="hidden" type="password" placeholder="Enter your password">
|
|
||||||
<button id="signupButton">Next</button>
|
|
||||||
<button id="backButton" class="hidden">Back</button>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<p>Don't have an account? If so, <a href="../signup/index.html">Create one here!</a></p>
|
|
||||||
<div style="display: flex;"><p id="homeserver">Your homeserver is loading... </p><div style="display: flex;flex-direction: column;justify-content: center;"><a href="/homeserver">Change</a></div></div>
|
|
||||||
<a href="../privacy/index.html">Privacy & Terms</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script type="text/javascript" src="../static/js/login.js"></script>
|
|
||||||
</body>
|
|
|
@ -1,15 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<title>Burgernotes</title>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
||||||
<head>
|
|
||||||
Logging out..
|
|
||||||
<script>
|
|
||||||
localStorage.removeItem("DONOTSHARE-secretkey")
|
|
||||||
localStorage.removeItem("DONOTSHARE-password")
|
|
||||||
localStorage.removeItem("CACHE-username")
|
|
||||||
window.location.replace("../index.html")
|
|
||||||
</script>
|
|
|
@ -1,47 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<title>Burgernotes</title>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
|
||||||
<link rel="stylesheet" type="text/css" href="./static/css/style.css" />
|
|
||||||
<meta content="Burgernotes" property="og:title" />
|
|
||||||
<meta content="A simple note-taking app!" property="og:description" />
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<a href="https://notes.old.hectabit.org" class="hiddenButton">Click here</a>
|
|
||||||
<div class="mainDiv">
|
|
||||||
<div class="startDiv">
|
|
||||||
<h1 class="w300">Burgernotes</h1>
|
|
||||||
<p>A simple note-taking service!</p>
|
|
||||||
<br>
|
|
||||||
<a href="./app/index.html">Open in your browser</a>
|
|
||||||
|
|
||||||
<a href="./static/burgernotes.mobileconfig" style="margin-top: 5px;">Download for iOS</a>
|
|
||||||
|
|
||||||
<a style="padding: 0; padding-bottom: 0; margin-top: 5px; background-color: rgba(0, 0, 0, 0);" href="https://flathub.org/apps/org.hectabit.burgernotes">
|
|
||||||
<img class="flathubLogo" style="height: 55px;"src="./static/svg/flathublight.svg">
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
<div class="feature green">
|
|
||||||
<h7 class="w300">Secure</h7>
|
|
||||||
<p2>All your notes are fully end-to-end encrypted. Only you can read your notes, not anyone else.</p2>
|
|
||||||
</div>
|
|
||||||
<div class="feature yellow">
|
|
||||||
<h7 class="w300">Always up-to-date</h7>
|
|
||||||
<p2>Your notes seamlessly sync across your devices.</p2>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="links">
|
|
||||||
<a href="https://centrifuge.hectabit.org/hectabit/burgernotes"><img src="/static/svg/code.svg">Source Code</a>
|
|
||||||
<a href="../privacy/index.html"><img src="/static/svg/info.svg">Privacy & Terms</a>
|
|
||||||
<a href="https://discord.gg/8EbKTjmH2d"><img src="/static/svg/forum.svg">Discord</a>
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
|
@ -1,82 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<title>Burgernotes Privacy & Terms</title>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
|
||||||
<link rel="stylesheet" type="text/css" href="../static/css/style.css" />
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<h1 class="w300">Burgernotes Privacy Policy & Terms & Conditions</h1>
|
|
||||||
<h2 class="w300">Preamble</h2>
|
|
||||||
<p><i>Please note that I am not a lawyer, please don't expect too much of this policy :3</i></p>
|
|
||||||
<p>Welcome to the Burgernotes privacy policy! Burgernotes is <a
|
|
||||||
href="https://centrifuge.hectabit.org/hectabit/burgernotes">free & open source</a> software licensed under <a
|
|
||||||
href="https://www.gnu.org/licenses/agpl-3.0.en.html">GNU AGPL-3.0</a>.</p>
|
|
||||||
<h2 class="w300">Information collected when signing up</h2>
|
|
||||||
<p>When signing up for an account, we collect and store the following information:</p>
|
|
||||||
<ul>
|
|
||||||
<li>Username, and your password hashed</li>
|
|
||||||
<li>Date of creating account</li>
|
|
||||||
<li>Web browser "User Agent"</li>
|
|
||||||
</ul>
|
|
||||||
<h2 class="w300">Information collected when logging in</h2>
|
|
||||||
<p>When logging back in to your account, we collect and store the following information:</p>
|
|
||||||
<ul>
|
|
||||||
<li>Web browser "User agent"</li>
|
|
||||||
</ul>
|
|
||||||
<h2 class="w300">Information we collect while using our services</h2>
|
|
||||||
<p>When you create an note, we collect and use this information:</p>
|
|
||||||
<ul>
|
|
||||||
<li>Encrypted note content and title</li>
|
|
||||||
<li>Note creator</li>
|
|
||||||
<li>Note creation date</li>
|
|
||||||
<li>Note last edited date</li>
|
|
||||||
</ul>
|
|
||||||
<p>When you edit an note, we collect and use this information:</p>
|
|
||||||
<ul>
|
|
||||||
<li>Encrypted note content and title</li>
|
|
||||||
<li>Note last edited date</li>
|
|
||||||
</ul>
|
|
||||||
<h2 class="w300">How we use your data</h2>
|
|
||||||
<p>We use your data to make our services work. We don't share your information with third-parties.</p>
|
|
||||||
<h2 class="w300">We can't see notes you create's content and title</h2>
|
|
||||||
<p>Your notes are <a href="https://en.wikipedia.org/wiki/End-to-end_encryption">encrypted end-to-end</a> using AES
|
|
||||||
(Advanced Encryption Standard) 256-bit encryption.</p>
|
|
||||||
<p>We can only see:</p>
|
|
||||||
<ul>
|
|
||||||
<li>Note creation date</li>
|
|
||||||
<li>Note last edited date</li>
|
|
||||||
<li>Note creator</li>
|
|
||||||
</ul>
|
|
||||||
<p>Not note content or title.</p>
|
|
||||||
<h2 class="w300">We don't sell your data</h2>
|
|
||||||
<p>We don't sell or share your data to advertisers or third-parties.</p>
|
|
||||||
<h2 class="w300">Liability</h2>
|
|
||||||
<p>We take no responsibility for the use of burgernotes, or any external instances provided by third-parties. We
|
|
||||||
refuse liability for any inappropriate or illegal use of burgernotes.</p>
|
|
||||||
<p>You may view the AGPL-3.0 license which this software is provided to you with. A copy of the section is below.</p>
|
|
||||||
<p>IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
|
||||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
|
||||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
|
||||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
|
||||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
|
||||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
|
||||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
|
||||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
|
||||||
SUCH DAMAGES.</p>
|
|
||||||
<br>
|
|
||||||
<button onclick="history.back()" style="cursor: pointer; padding: 15px 20px;margin-right: auto;color: white;text-decoration: none;background-color: var(--theme-color);border-radius: 8px;border: medium;font-size: 15px;">Take me back where I was!</button>
|
|
||||||
<br><br>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
margin-left: 15px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
</html>
|
|
|
@ -1,38 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<title>Signup - Burgernotes</title>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
|
||||||
<link rel="stylesheet" type="text/css" href="../static/css/style.css" />
|
|
||||||
<script src="../static/js/hash-wasm.js"></script>
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
background-color: #d9d9d9;
|
|
||||||
background-image: url("/static/svg/grid.svg");
|
|
||||||
background-repeat: repeat;
|
|
||||||
background-size: 312px;
|
|
||||||
}
|
|
||||||
.inoutdiv {
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div class="inoutdiv">
|
|
||||||
<h2 class="w300">Signup</h2>
|
|
||||||
<p>Signup for a Burgernotes account</p>
|
|
||||||
<p id="statusBox"></p>
|
|
||||||
<input id="usernameBox" type="text" placeholder="Username">
|
|
||||||
<input id="passwordBox" type="password" placeholder="Password"><br>
|
|
||||||
<button id="signupButton">Signup</button><br><br>
|
|
||||||
<p>Already have an account? If so, <a href="../login/index.html">Login</a> instead!</p>
|
|
||||||
<p>Please note that it's impossible to reset your password, do not forget it!</p>
|
|
||||||
<div style="display: flex;"><p id="homeserver">Your homeserver is loading... </p><div style="display: flex;flex-direction: column;justify-content: center;"><a href="/homeserver">Change</a></div></div>
|
|
||||||
<a href="../privacy/index.html">Privacy & Terms</a>
|
|
||||||
</div>
|
|
||||||
<script type="text/javascript" src="../static/js/signup.js"></script>
|
|
||||||
</body>
|
|