passed/static/index.js

219 lines
5.2 KiB
JavaScript
Raw Normal View History

2024-10-30 12:24:59 +00:00
const loadingDialog = {
dialog: document.querySelector("dialog#loading-dialog"),
init() {
this.dialog.addEventListener("cancel", (ev) => {
2024-10-29 23:08:11 +00:00
ev.preventDefault();
2024-10-30 12:24:59 +00:00
});
},
show() {
this.dialog.showModal();
},
close() {
this.dialog.close();
},
};
const errorDialog = {
dialog: document.querySelector("dialog#error-dialog"),
error: document.querySelector("textarea#error"),
reload: document.querySelector("button#error-reload"),
init() {
this.dialog.addEventListener("close", (ev) => {
window.location.reload();
});
2024-10-29 23:08:11 +00:00
2024-10-30 12:24:59 +00:00
this.reload.addEventListener("click", (ev) => {
window.location.href = "/";
});
},
show(err) {
this.error.value = err;
console.error(err);
this.dialog.showModal();
},
};
const urlDialog = {
dialog: document.querySelector("dialog#url-dialog"),
url: document.querySelector("input#url"),
urlCopy: document.querySelector("button#url-copy"),
close: document.querySelector("button#url-close"),
init() {
this.dialog.addEventListener("close", (ev) => {});
this.urlCopy.addEventListener("click", (ev) => {
this.url.select();
this.url.setSelectionRange(0, 99999);
navigator.clipboard.writeText(this.url.value);
});
2024-10-29 23:08:11 +00:00
2024-10-30 12:24:59 +00:00
this.close.addEventListener("click", (ev) => {
this.dialog.close();
});
},
show(url) {
this.url.value = url;
this.dialog.showModal();
},
};
const notFoundDialog = {
dialog: document.querySelector("dialog#not-found"),
close: document.querySelector("button#not-found-close"),
init() {
this.dialog.addEventListener("close", (ev) => {
window.location.hash = "";
window.location.reload();
2024-10-30 12:24:59 +00:00
});
2024-10-29 23:08:11 +00:00
2024-10-30 12:24:59 +00:00
this.close.addEventListener("click", (ev) => {
window.location.hash = "";
window.location.reload();
2024-10-30 12:24:59 +00:00
});
},
show() {
this.dialog.showModal();
},
};
const viewDialog = {
dialog: document.querySelector("dialog#view-dialog"),
password: document.querySelector("textarea#view-password"),
close: document.querySelector("button#view-close"),
init() {
this.dialog.addEventListener("close", (ev) => {
window.location.hash = "";
window.location.reload();
2024-10-30 12:24:59 +00:00
});
2024-10-29 23:08:11 +00:00
2024-10-30 12:24:59 +00:00
this.close.addEventListener("click", (ev) => {
this.dialog.close();
});
},
show(password) {
this.password.value = password;
this.dialog.showModal();
},
};
const confirmViewDialog = {
dialog: document.querySelector("dialog#confirm-view-dialog"),
cancel: document.querySelector("button#view-cancel"),
confirm: document.querySelector("button#view-confirm"),
resolve: null,
reject: null,
init() {
this.dialog.addEventListener("cancel", (ev) => {
this.dialog.close();
this.resolve(false);
});
2024-10-29 23:08:11 +00:00
2024-10-30 12:24:59 +00:00
this.cancel.addEventListener("click", (ev) => {
this.dialog.close();
this.resolve(false);
});
2024-10-29 23:08:11 +00:00
2024-10-30 12:24:59 +00:00
this.confirm.addEventListener("click", (ev) => {
this.dialog.close();
this.resolve(true);
});
},
show() {
return new Promise((resolve, reject) => {
this.resolve = resolve;
this.reject = reject;
this.dialog.showModal();
});
},
};
2024-10-29 23:49:30 +00:00
2024-10-30 12:24:59 +00:00
async function viewPassword() {
2024-10-29 23:49:30 +00:00
try {
2024-10-30 12:24:59 +00:00
loadingDialog.show();
2024-10-29 23:49:30 +00:00
let id, key, iv;
// We need to be backwards compatible with old links that still use the query
if (window.location.search.trim() != "") {
const params = new URLSearchParams(window.location.search);
id = params.get("id");
key = params.get("key");
iv = params.get("iv");
} else {
// Need to remove leading "#"
const hash = window.location.hash.substring(1);
const split = hash.split(":");
id = split[0];
key = split[1];
iv = split[2];
}
2024-10-29 23:49:30 +00:00
2024-10-30 12:24:59 +00:00
const exists = await hasPassword(id);
if (!exists) {
notFoundDialog.show();
2024-10-29 23:49:30 +00:00
return;
}
2024-10-30 12:24:59 +00:00
const shouldView = await confirmViewDialog.show();
if (!shouldView) {
// This is needed for the redirect, otherwise the user won't get redirected
setTimeout(() => {
window.location.hash = "";
window.location.reload();
}, 0);
2024-10-30 12:24:59 +00:00
return;
2024-10-29 23:49:30 +00:00
}
2024-10-30 12:24:59 +00:00
const encrypted = await getPassword(id);
const password = await decryptPassword(encrypted, key, iv);
viewDialog.show(password);
2024-10-29 23:49:30 +00:00
} catch (error) {
2024-10-30 12:24:59 +00:00
errorDialog.show(error);
2024-10-29 23:49:30 +00:00
} finally {
2024-10-30 12:24:59 +00:00
loadingDialog.close();
2024-10-29 23:49:30 +00:00
}
2024-10-29 23:08:11 +00:00
}
2024-10-30 12:24:59 +00:00
const enterPassword = document.querySelector("form#enter-password");
2024-10-29 23:08:11 +00:00
2024-10-30 12:24:59 +00:00
enterPassword.addEventListener("submit", async (ev) => {
2024-10-29 23:08:11 +00:00
try {
2024-10-30 12:24:59 +00:00
loadingDialog.show();
ev.preventDefault();
const data = new FormData(ev.target);
const password = await encryptPassword(data.get("password"));
const id = await uploadPassword(
password.password,
parseInt(data.get("expires-in")),
2024-10-29 23:08:11 +00:00
);
2024-10-30 12:24:59 +00:00
const url = new URL(window.location);
url.hash = [id, password.key, password.iv].join(":");
2024-10-30 12:24:59 +00:00
urlDialog.show(url.toString());
2024-10-29 23:08:11 +00:00
} catch (error) {
2024-10-30 12:24:59 +00:00
errorDialog.show(error);
2024-10-29 23:08:11 +00:00
} finally {
loadingDialog.close();
}
2024-10-30 12:24:59 +00:00
});
2024-10-29 23:08:11 +00:00
2024-10-30 12:24:59 +00:00
loadingDialog.init();
errorDialog.init();
urlDialog.init();
notFoundDialog.init();
viewDialog.init();
confirmViewDialog.init();
2024-10-29 23:08:11 +00:00
const hash = window.location.hash;
if (hash.trim() != "") {
viewPassword();
}
// We need to be backwards compatible with the old links
2024-10-30 12:24:59 +00:00
const query = window.location.search;
if (query.trim() != "") {
viewPassword();
}