feat: auth file uploaders
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
94058efb60
commit
70925e6f08
@ -17,7 +17,7 @@
|
|||||||
"@szhsin/react-menu": "^3.3.1",
|
"@szhsin/react-menu": "^3.3.1",
|
||||||
"@types/use-sync-external-store": "^0.0.4",
|
"@types/use-sync-external-store": "^0.0.4",
|
||||||
"@uidotdev/usehooks": "^2.3.1",
|
"@uidotdev/usehooks": "^2.3.1",
|
||||||
"@void-cat/api": "^1.0.4",
|
"@void-cat/api": "^1.0.10",
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.3.4",
|
||||||
"dexie": "^3.2.4",
|
"dexie": "^3.2.4",
|
||||||
"emojilib": "^3.0.10",
|
"emojilib": "^3.0.10",
|
||||||
|
@ -1,21 +1,43 @@
|
|||||||
|
import { base64 } from "@scure/base";
|
||||||
|
import { EventKind, EventPublisher } from "@snort/system";
|
||||||
import { UploadResult } from "Upload";
|
import { UploadResult } from "Upload";
|
||||||
|
|
||||||
export default async function NostrBuild(file: File | Blob): Promise<UploadResult> {
|
export default async function NostrBuild(file: File | Blob, publisher?: EventPublisher): Promise<UploadResult> {
|
||||||
|
const auth = publisher
|
||||||
|
? async (url: string, method: string) => {
|
||||||
|
const auth = await publisher.generic(eb => {
|
||||||
|
return eb.kind(EventKind.HttpAuthentication).tag(["u", url]).tag(["method", method]);
|
||||||
|
});
|
||||||
|
return `Nostr ${base64.encode(new TextEncoder().encode(JSON.stringify(auth)))}`;
|
||||||
|
}
|
||||||
|
: undefined;
|
||||||
|
|
||||||
const fd = new FormData();
|
const fd = new FormData();
|
||||||
fd.append("fileToUpload", file);
|
fd.append("fileToUpload", file);
|
||||||
fd.append("submit", "Upload Image");
|
fd.append("submit", "Upload Image");
|
||||||
|
|
||||||
const rsp = await fetch("https://nostr.build/api/upload/snort.php", {
|
const url = "https://nostr.build/api/v2/upload/files";
|
||||||
|
const headers = {
|
||||||
|
accept: "application/json",
|
||||||
|
} as Record<string, string>;
|
||||||
|
if (auth) {
|
||||||
|
headers["Authorization"] = await auth(url, "POST");
|
||||||
|
}
|
||||||
|
|
||||||
|
const rsp = await fetch(url, {
|
||||||
body: fd,
|
body: fd,
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers,
|
||||||
accept: "application/json",
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
if (rsp.ok) {
|
if (rsp.ok) {
|
||||||
const data = await rsp.json();
|
const data = (await rsp.json()) as {
|
||||||
|
success: boolean;
|
||||||
|
data: Array<{
|
||||||
|
url: string;
|
||||||
|
}>;
|
||||||
|
};
|
||||||
return {
|
return {
|
||||||
url: new URL(data).toString(),
|
url: data.data[0].url,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
|
@ -3,7 +3,7 @@ import { VoidApi } from "@void-cat/api";
|
|||||||
|
|
||||||
import { FileExtensionRegex, VoidCatHost } from "Const";
|
import { FileExtensionRegex, VoidCatHost } from "Const";
|
||||||
import { UploadResult } from "Upload";
|
import { UploadResult } from "Upload";
|
||||||
import { magnetURIDecode } from "SnortUtils";
|
import { base64 } from "@scure/base";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Upload file to void.cat
|
* Upload file to void.cat
|
||||||
@ -14,7 +14,15 @@ export default async function VoidCatUpload(
|
|||||||
filename: string,
|
filename: string,
|
||||||
publisher?: EventPublisher,
|
publisher?: EventPublisher,
|
||||||
): Promise<UploadResult> {
|
): Promise<UploadResult> {
|
||||||
const api = new VoidApi(VoidCatHost);
|
const auth = publisher
|
||||||
|
? async (url: string, method: string) => {
|
||||||
|
const auth = await publisher.generic(eb => {
|
||||||
|
return eb.kind(EventKind.HttpAuthentication).tag(["u", url]).tag(["method", method]);
|
||||||
|
});
|
||||||
|
return `Nostr ${base64.encode(new TextEncoder().encode(JSON.stringify(auth)))}`;
|
||||||
|
}
|
||||||
|
: undefined;
|
||||||
|
const api = new VoidApi(VoidCatHost, auth);
|
||||||
const uploader = api.getUploader(file);
|
const uploader = api.getUploader(file);
|
||||||
|
|
||||||
const rsp = await uploader.upload({
|
const rsp = await uploader.upload({
|
||||||
@ -32,7 +40,8 @@ export default async function VoidCatUpload(
|
|||||||
} as UploadResult;
|
} as UploadResult;
|
||||||
|
|
||||||
if (publisher) {
|
if (publisher) {
|
||||||
const tags = [
|
// NIP-94
|
||||||
|
/*const tags = [
|
||||||
["url", resultUrl],
|
["url", resultUrl],
|
||||||
["x", rsp.file?.metadata?.digest ?? ""],
|
["x", rsp.file?.metadata?.digest ?? ""],
|
||||||
["m", rsp.file?.metadata?.mimeType ?? "application/octet-stream"],
|
["m", rsp.file?.metadata?.mimeType ?? "application/octet-stream"],
|
||||||
@ -51,7 +60,7 @@ export default async function VoidCatUpload(
|
|||||||
eb.kind(EventKind.FileHeader).content(filename);
|
eb.kind(EventKind.FileHeader).content(filename);
|
||||||
tags.forEach(t => eb.tag(t));
|
tags.forEach(t => eb.tag(t));
|
||||||
return eb;
|
return eb;
|
||||||
});
|
});*/
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
} else {
|
} else {
|
||||||
|
@ -6,6 +6,7 @@ import VoidCat from "Upload/VoidCat";
|
|||||||
import NostrImg from "Upload/NostrImg";
|
import NostrImg from "Upload/NostrImg";
|
||||||
import { KieranPubKey } from "Const";
|
import { KieranPubKey } from "Const";
|
||||||
import { bech32ToHex } from "SnortUtils";
|
import { bech32ToHex } from "SnortUtils";
|
||||||
|
import useEventPublisher from "Hooks/useEventPublisher";
|
||||||
|
|
||||||
export interface UploadResult {
|
export interface UploadResult {
|
||||||
url?: string;
|
url?: string;
|
||||||
@ -41,11 +42,12 @@ export interface Uploader {
|
|||||||
|
|
||||||
export default function useFileUpload(): Uploader {
|
export default function useFileUpload(): Uploader {
|
||||||
const fileUploader = useLogin().preferences.fileUploader;
|
const fileUploader = useLogin().preferences.fileUploader;
|
||||||
|
const { publisher } = useEventPublisher();
|
||||||
|
|
||||||
switch (fileUploader) {
|
switch (fileUploader) {
|
||||||
case "nostr.build": {
|
case "nostr.build": {
|
||||||
return {
|
return {
|
||||||
upload: NostrBuild,
|
upload: f => NostrBuild(f, publisher),
|
||||||
} as Uploader;
|
} as Uploader;
|
||||||
}
|
}
|
||||||
case "nostrimg.com": {
|
case "nostrimg.com": {
|
||||||
@ -55,7 +57,7 @@ export default function useFileUpload(): Uploader {
|
|||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
return {
|
return {
|
||||||
upload: (f, n) => VoidCat(f, n, undefined),
|
upload: (f, n) => VoidCat(f, n, publisher),
|
||||||
} as Uploader;
|
} as Uploader;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
10
yarn.lock
10
yarn.lock
@ -2715,7 +2715,7 @@ __metadata:
|
|||||||
"@typescript-eslint/eslint-plugin": ^6.1.0
|
"@typescript-eslint/eslint-plugin": ^6.1.0
|
||||||
"@typescript-eslint/parser": ^6.1.0
|
"@typescript-eslint/parser": ^6.1.0
|
||||||
"@uidotdev/usehooks": ^2.3.1
|
"@uidotdev/usehooks": ^2.3.1
|
||||||
"@void-cat/api": ^1.0.4
|
"@void-cat/api": ^1.0.10
|
||||||
"@webbtc/webln-types": ^1.0.10
|
"@webbtc/webln-types": ^1.0.10
|
||||||
"@webpack-cli/generators": ^3.0.4
|
"@webpack-cli/generators": ^3.0.4
|
||||||
"@webscopeio/react-textarea-autocomplete": ^4.9.2
|
"@webscopeio/react-textarea-autocomplete": ^4.9.2
|
||||||
@ -3865,12 +3865,12 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@void-cat/api@npm:^1.0.4":
|
"@void-cat/api@npm:^1.0.10":
|
||||||
version: 1.0.7
|
version: 1.0.10
|
||||||
resolution: "@void-cat/api@npm:1.0.7"
|
resolution: "@void-cat/api@npm:1.0.10"
|
||||||
dependencies:
|
dependencies:
|
||||||
sjcl: ^1.0.8
|
sjcl: ^1.0.8
|
||||||
checksum: 208461ed5583e53d2dd96e8734569f84296faaf0a2af3151ec3119e723fb758d0a7c8e092b9dd7018aabf7fafec7c424383fab9e8dce4ead3142601ee91e0650
|
checksum: 8ec846aefa3fad3cfee018959a95fa93195112382b7d655098f3df8059555367166ee54c13900ff9f459baef44ffb39e5f5e44dc492a2f61477cbdae798d0cbb
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user