Merge pull request #1773 from PR0M3TH3AN/codex/reorder-upload-flow-in-uploadmodal

Compute upload identifier before building storage keys
This commit is contained in:
thePR0M3TH3AN authored and GitHub committed 2026-01-26 21:43:53 -05:00
commit 0897106c2e
3 files changed
+55 -14

No files matched your search

+24 -5
View File
@@ -44,6 +44,7 @@ import {
VIDEO_NOTE_ERROR_CODES,
} from "./videoNotePayload.js";
import storageService from "./storageService.js";
import { calculateTorrentInfoHash } from "../utils/torrentHash.js";
const STATUS_VARIANTS = new Set(["info", "success", "error", "warning"]);
const INFO_HASH_PATTERN = /^[a-f0-9]{40}$/;
@@ -56,6 +57,26 @@ function isValidInfoHash(value) {
return INFO_HASH_PATTERN.test(value);
}
async function resolveUploadIdentifier({ infoHash = "", file = null } = {}) {
const normalizedInfoHash = normalizeInfoHash(infoHash);
if (isValidInfoHash(normalizedInfoHash)) {
return normalizedInfoHash;
}
if (!file) {
return "";
}
try {
const computedHash = await calculateTorrentInfoHash(file);
const normalizedComputed = normalizeInfoHash(computedHash);
if (isValidInfoHash(normalizedComputed)) {
return normalizedComputed;
}
} catch (err) {
userLogger.warn("Failed to precompute info hash for storage key:", err);
}
return "";
}
function buildCorsGuidance({ accountId } = {}) {
const origin =
typeof window !== "undefined" && window.location
@@ -844,10 +865,9 @@ class R2Service {
this.updateCloudflareProgress(0);
this.setCloudflareUploading(true);
const normalizedInfoHash = normalizeInfoHash(infoHash);
const keyIdentifier = isValidInfoHash(normalizedInfoHash)
? normalizedInfoHash
: "";
const keyIdentifier = await resolveUploadIdentifier({ infoHash, file });
const normalizedInfoHash = normalizeInfoHash(infoHash || keyIdentifier);
const hasValidInfoHash = isValidInfoHash(normalizedInfoHash);
let bucketResult = null;
try {
@@ -983,7 +1003,6 @@ class R2Service {
// - `xs` (eXact Source): The URL to the .torrent file on R2. This allows
// clients to fetch metadata (file structure, piece hashes) instantly via HTTP
// instead of waiting to fetch it from the DHT (which can take minutes).
const hasValidInfoHash = isValidInfoHash(normalizedInfoHash);
let generatedMagnet = "";
let generatedWs = "";
+24 -6
View File
@@ -13,6 +13,7 @@ import {
normalizeVideoNotePayload,
VIDEO_NOTE_ERROR_CODES,
} from "./videoNotePayload.js";
import { calculateTorrentInfoHash } from "../utils/torrentHash.js";
const STATUS_VARIANTS = new Set(["info", "success", "error", "warning"]);
const INFO_HASH_PATTERN = /^[a-f0-9]{40}$/;
@@ -25,6 +26,26 @@ function isValidInfoHash(value) {
return INFO_HASH_PATTERN.test(value);
}
async function resolveUploadIdentifier({ infoHash = "", file = null } = {}) {
const normalizedInfoHash = normalizeInfoHash(infoHash);
if (isValidInfoHash(normalizedInfoHash)) {
return normalizedInfoHash;
}
if (!file) {
return "";
}
try {
const computedHash = await calculateTorrentInfoHash(file);
const normalizedComputed = normalizeInfoHash(computedHash);
if (isValidInfoHash(normalizedComputed)) {
return normalizedComputed;
}
} catch (err) {
userLogger.warn("Failed to precompute info hash for storage key:", err);
}
return "";
}
class S3UploadService {
constructor() {
this.listeners = new Map();
@@ -215,10 +236,9 @@ class S3UploadService {
try {
await ensureS3SdkLoaded();
const normalizedInfoHash = normalizeInfoHash(infoHash);
const keyIdentifier = isValidInfoHash(normalizedInfoHash)
? normalizedInfoHash
: "";
const keyIdentifier = await resolveUploadIdentifier({ infoHash, file });
const normalizedInfoHash = normalizeInfoHash(infoHash || keyIdentifier);
const hasValidInfoHash = isValidInfoHash(normalizedInfoHash);
const s3 = makeS3Client({
endpoint: normalized.endpoint,
@@ -327,8 +347,6 @@ class S3UploadService {
return false;
}
// normalizedInfoHash is already calculated above
const hasValidInfoHash = isValidInfoHash(normalizedInfoHash);
let generatedMagnet = "";
let generatedWs = "";
+7 -3
View File
@@ -515,7 +515,12 @@ export class UploadModal {
this.updateVideoProgress(0, "Preparing upload...");
try {
// 1. Prepare Upload (Get Creds & Bucket)
// 1. Compute Identifier (Info Hash / Fingerprint) before generating keys
const identifier = await this.resolveUploadIdentifier(file);
if (this.videoUploadId !== currentUploadId) return;
// 2. Prepare Upload (Get Creds & Bucket)
const pubkey = this.getCurrentPubkey();
const npub = this.safeEncodeNpub(pubkey);
const service = this.activeProvider === PROVIDERS.R2 || this.activeProvider === "cloudflare_r2"
@@ -526,8 +531,7 @@ export class UploadModal {
if (this.videoUploadId !== currentUploadId) return;
// 2. Determine Keys
const identifier = await this.resolveUploadIdentifier(file);
// 3. Determine Keys
const videoKey = buildR2Key(npub, file, identifier);
const baseDomain = bucketEntry.publicBaseUrl;