forked from Kieran/route96
aidik
55c59a3569
This will prevent premature expiration during a bigger size/slower connection uploads
235 lines
7.3 KiB
JavaScript
235 lines
7.3 KiB
JavaScript
//config
|
|
const subdomain = ""; //"otherstuff.";
|
|
|
|
function isValidJSON(text) {
|
|
try {
|
|
JSON.parse(text);
|
|
return true;
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
async function readClipboard() {
|
|
try {
|
|
const text = await navigator.clipboard.readText();
|
|
return text;
|
|
} catch (err) {
|
|
console.error('Failed to read clipboard contents', err);
|
|
}
|
|
}
|
|
|
|
async function monitorClipboard() {
|
|
return new Promise((resolve) => {
|
|
const intervalId = setInterval(async () => {
|
|
const clipboardContent = await readClipboard();
|
|
|
|
if (clipboardContent && isValidJSON(clipboardContent)) {
|
|
console.log("Valid JSON detected:", clipboardContent);
|
|
let jsonData = JSON.parse(clipboardContent);
|
|
clearInterval(intervalId);
|
|
resolve(jsonData);
|
|
}
|
|
}, 1000);
|
|
});
|
|
}
|
|
|
|
async function executeRequest(auth_event, path, method, body) {
|
|
try {
|
|
let options = {
|
|
"method": method,
|
|
"headers": {
|
|
"accept": "application/json",
|
|
"authorization": `Nostr ${btoa(JSON.stringify(auth_event))}`,
|
|
},
|
|
}
|
|
if (typeof body !== "undefined") {
|
|
options.body = body;
|
|
}
|
|
const rsp = await fetch(`${window.location.protocol}//${subdomain}${window.location.host}` + path, options);
|
|
return rsp;
|
|
} catch (e) {
|
|
}
|
|
}
|
|
|
|
async function dumpToLog(rsp) {
|
|
console.debug(rsp);
|
|
document.querySelector("#log-wrap").classList.remove('hidden');
|
|
document.querySelector("#log").prepend("\n\n");
|
|
const text = await rsp.text();
|
|
if (rsp.ok) {
|
|
document.querySelector("#log").prepend(JSON.stringify(JSON.parse(text), undefined, 2));
|
|
} else {
|
|
document.querySelector("#log").prepend(text);
|
|
}
|
|
document.querySelector("#log").prepend("***************\n\n");
|
|
}
|
|
|
|
async function listFiles() {
|
|
const r_amber = document.querySelector("#sign-amber").checked;
|
|
const r_nip07 = document.querySelector("#sign-nip07").checked;
|
|
|
|
const unsignedEvent = {
|
|
kind: 27235,
|
|
created_at: Math.floor(new Date().getTime() / 1000),
|
|
content: "",
|
|
tags: [
|
|
["u", `${window.location.protocol}//${subdomain}${window.location.host}/n96`],
|
|
["method", "GET"]
|
|
]
|
|
};
|
|
|
|
if (r_amber) {
|
|
try {
|
|
let encodedJson = encodeURIComponent(JSON.stringify(unsignedEvent));
|
|
let intent = `nostrsigner:${encodedJson}?compressionType=none&returnType=event&type=sign_event`;
|
|
let childWin = window.open(intent, "intentwindow");
|
|
|
|
const auth_event = await monitorClipboard();
|
|
console.log('Parsed JSON from clipboard:', auth_event);
|
|
|
|
const rsp = await executeRequest(auth_event, "/n96?page=0&count=100", "GET");
|
|
|
|
await dumpToLog(rsp);
|
|
} catch (err) {
|
|
console.error('Failed to list files', err);
|
|
}
|
|
|
|
} else if (r_nip07) {
|
|
try {
|
|
const auth_event = await window.nostr.signEvent(unsignedEvent);
|
|
|
|
const rsp = await executeRequest(auth_event, "/n96?page=0&count=100", "GET")
|
|
|
|
await dumpToLog(rsp);
|
|
} catch (err) {
|
|
console.error('Failed to list files', err);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
async function uploadFiles(e) {
|
|
try {
|
|
const input = document.querySelector("#file");
|
|
const file = input.files[0];
|
|
console.debug(file);
|
|
|
|
const r_nip96 = document.querySelector("#method-nip96").checked;
|
|
const r_blossom = document.querySelector("#method-blossom").checked;
|
|
if (r_nip96) {
|
|
await uploadFilesNip96(file);
|
|
} else if (r_blossom) {
|
|
await uploadBlossom(file);
|
|
}
|
|
} catch (ex) {
|
|
if (ex instanceof Error) {
|
|
alert(ex.message);
|
|
}
|
|
}
|
|
}
|
|
|
|
function buf2hex(buffer) { // buffer is an ArrayBuffer
|
|
return [...new Uint8Array(buffer)]
|
|
.map(x => x.toString(16).padStart(2, '0'))
|
|
.join('');
|
|
}
|
|
|
|
async function uploadBlossom(file) {
|
|
const r_amber = document.querySelector("#sign-amber").checked;
|
|
const r_nip07 = document.querySelector("#sign-nip07").checked;
|
|
|
|
const now = Math.floor(new Date().getTime() / 1000);
|
|
const hash = await window.crypto.subtle.digest("SHA-256", await file.arrayBuffer());
|
|
|
|
const unsignedEvent = {
|
|
kind: 24242,
|
|
created_at: now,
|
|
content: `Upload ${file.name}`,
|
|
tags: [
|
|
["t", "upload"],
|
|
["u", `${window.location.protocol}//${subdomain}${window.location.host}/upload`],
|
|
["x", buf2hex(hash)],
|
|
["method", "PUT"],
|
|
["expiration", (now + 600).toString()]
|
|
]
|
|
}
|
|
|
|
if (r_amber) {
|
|
try {
|
|
let encodedJson = encodeURIComponent(JSON.stringify(unsignedEvent));
|
|
let intent = `nostrsigner:${encodedJson}?compressionType=none&returnType=event&type=sign_event`;
|
|
let childWin = window.open(intent, "intentwindow");
|
|
|
|
const auth_event = await monitorClipboard();
|
|
console.log('Parsed JSON from clipboard:', auth_event);
|
|
|
|
const rsp = await executeRequest(auth_event, "/upload", "PUT", file);
|
|
|
|
await dumpToLog(rsp);
|
|
} catch (err) {
|
|
console.error('Failed to upload file', err);
|
|
}
|
|
|
|
} else if (r_nip07) {
|
|
try {
|
|
const auth_event = await window.nostr.signEvent(unsignedEvent);
|
|
|
|
const rsp = await executeRequest(auth_event, "/upload", "PUT", file)
|
|
|
|
await dumpToLog(rsp);
|
|
} catch (err) {
|
|
console.error('Failed to upload file', err);
|
|
}
|
|
}
|
|
}
|
|
|
|
async function uploadFilesNip96(file) {
|
|
const r_amber = document.querySelector("#sign-amber").checked;
|
|
const r_nip07 = document.querySelector("#sign-nip07").checked;
|
|
|
|
const fd = new FormData();
|
|
fd.append("size", file.size.toString());
|
|
fd.append("caption", file.name);
|
|
fd.append("media_type", file.type);
|
|
fd.append("file", file);
|
|
fd.append("no_transform", document.querySelector("#no_transform").checked.toString())
|
|
|
|
const unsignedEvent = {
|
|
kind: 27235,
|
|
created_at: Math.floor(new Date().getTime() / 1000),
|
|
content: "",
|
|
tags: [
|
|
["u", `${window.location.protocol}//${subdomain}${window.location.host}/n96`],
|
|
["method", "POST"]
|
|
]
|
|
}
|
|
|
|
if (r_amber) {
|
|
try {
|
|
let encodedJson = encodeURIComponent(JSON.stringify(unsignedEvent));
|
|
let intent = `nostrsigner:${encodedJson}?compressionType=none&returnType=event&type=sign_event`;
|
|
let childWin = window.open(intent, "intentwindow");
|
|
|
|
const auth_event = await monitorClipboard();
|
|
console.log('Parsed JSON from clipboard:', auth_event);
|
|
|
|
const rsp = await executeRequest(auth_event, "/n96", "POST", fd);
|
|
|
|
await dumpToLog(rsp);
|
|
} catch (err) {
|
|
console.error('Failed to upload file', err);
|
|
}
|
|
|
|
} else if (r_nip07) {
|
|
try {
|
|
const auth_event = await window.nostr.signEvent(unsignedEvent);
|
|
|
|
const rsp = await executeRequest(auth_event, "/n96", "POST", fd)
|
|
|
|
await dumpToLog(rsp);
|
|
} catch (err) {
|
|
console.error('Failed to upload file', err);
|
|
}
|
|
}
|
|
} |