mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-11-07 13:22:54 +00:00
Shorten bucket slugs and fix CORS refresh
This commit is contained in:
1 parent
8a278ca0ac
commit
1684c7070b
2 files changed
+92
-6
No files matched your search
@@ -31,6 +31,7 @@ import {
|
||||
putCors,
|
||||
attachCustomDomainAndWait,
|
||||
setManagedDomain,
|
||||
deriveShortSubdomain,
|
||||
} from "./storage/r2-mgmt.js";
|
||||
import {
|
||||
makeR2Client,
|
||||
@@ -1573,11 +1574,17 @@ class bitvidApp {
|
||||
}
|
||||
|
||||
deriveSubdomainForNpub(npub) {
|
||||
try {
|
||||
return deriveShortSubdomain(npub);
|
||||
} catch (err) {
|
||||
console.warn("Failed to derive short subdomain, falling back:", err);
|
||||
}
|
||||
|
||||
const base = String(npub || "user")
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9-]/g, "")
|
||||
.replace(/^-+|[-]+$/g, "");
|
||||
return base.slice(0, 48) || "user";
|
||||
return base.slice(0, 32) || "user";
|
||||
}
|
||||
|
||||
async ensureBucketConfigForNpub(npub) {
|
||||
@@ -1617,6 +1624,28 @@ class bitvidApp {
|
||||
} catch (err) {
|
||||
console.warn("Failed to refresh bucket configuration:", err);
|
||||
}
|
||||
} else if (
|
||||
accessKeyId &&
|
||||
secretAccessKey &&
|
||||
corsOrigins.length > 0
|
||||
) {
|
||||
try {
|
||||
const s3 = makeR2Client({
|
||||
accountId,
|
||||
accessKeyId,
|
||||
secretAccessKey,
|
||||
});
|
||||
await ensureBucketCors({
|
||||
s3,
|
||||
bucket: entry.bucket,
|
||||
origins: corsOrigins,
|
||||
});
|
||||
} catch (err) {
|
||||
console.warn(
|
||||
"Failed to refresh bucket CORS via access keys:",
|
||||
err
|
||||
);
|
||||
}
|
||||
}
|
||||
return {
|
||||
entry,
|
||||
@@ -1821,17 +1850,17 @@ class bitvidApp {
|
||||
const publicUrl = buildPublicUrl(entry.publicBaseUrl, sampleKey);
|
||||
const fullPreview = `${entry.bucket} • ${publicUrl}`;
|
||||
|
||||
let displayHostAndPath = truncateMiddle(publicUrl, 96);
|
||||
let displayHostAndPath = truncateMiddle(publicUrl, 72);
|
||||
try {
|
||||
const parsed = new URL(publicUrl);
|
||||
const cleanPath = parsed.pathname.replace(/^\//, "");
|
||||
const truncatedPath = truncateMiddle(cleanPath || sampleKey, 48);
|
||||
displayHostAndPath = `${truncateMiddle(parsed.host, 48)}/${truncatedPath}`;
|
||||
const truncatedPath = truncateMiddle(cleanPath || sampleKey, 32);
|
||||
displayHostAndPath = `${truncateMiddle(parsed.host, 32)}/${truncatedPath}`;
|
||||
} catch (err) {
|
||||
// ignore URL parse issues and fall back to the raw string
|
||||
}
|
||||
|
||||
const truncatedBucket = truncateMiddle(entry.bucket, 40);
|
||||
const truncatedBucket = truncateMiddle(entry.bucket, 28);
|
||||
el.textContent = `${truncatedBucket} • ${displayHostAndPath}`;
|
||||
el.setAttribute("title", fullPreview);
|
||||
}
|
||||
|
||||
+58
-1
@@ -1,6 +1,16 @@
|
||||
// js/storage/r2-mgmt.js
|
||||
function computeSlugHash(input) {
|
||||
const text = String(input || "");
|
||||
let hash = 0;
|
||||
for (let i = 0; i < text.length; i += 1) {
|
||||
hash = Math.imul(31, hash) + text.charCodeAt(i);
|
||||
}
|
||||
return (hash >>> 0).toString(36);
|
||||
}
|
||||
|
||||
export function sanitizeBucketName(npub) {
|
||||
let value = String(npub || "")
|
||||
const raw = String(npub || "");
|
||||
let value = raw
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9-]/g, "-")
|
||||
.replace(/-+/g, "-")
|
||||
@@ -10,6 +20,14 @@ export function sanitizeBucketName(npub) {
|
||||
value = "bitvid-user";
|
||||
}
|
||||
|
||||
if (value.length > 32) {
|
||||
const prefix = value.slice(0, 20).replace(/-+$/g, "");
|
||||
const hash = computeSlugHash(raw).slice(0, 8);
|
||||
value = [prefix, hash].filter(Boolean).join("-");
|
||||
}
|
||||
|
||||
value = value.replace(/-+/g, "-").replace(/^-+|[-]+$/g, "");
|
||||
|
||||
if (!/^[a-z0-9]/.test(value)) {
|
||||
value = `bv-${value}`;
|
||||
}
|
||||
@@ -29,6 +47,45 @@ export function sanitizeBucketName(npub) {
|
||||
return value;
|
||||
}
|
||||
|
||||
export function deriveShortSubdomain(npub) {
|
||||
const bucketSlug = sanitizeBucketName(npub);
|
||||
const hash = computeSlugHash(npub).slice(0, 6);
|
||||
|
||||
const prefix = bucketSlug
|
||||
.replace(/^bv-/, "")
|
||||
.slice(0, 18)
|
||||
.replace(/-+$/g, "");
|
||||
|
||||
let candidate = [prefix, hash].filter(Boolean).join("-");
|
||||
candidate = candidate
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9-]/g, "-")
|
||||
.replace(/-+/g, "-")
|
||||
.replace(/^-+|[-]+$/g, "");
|
||||
|
||||
if (!candidate) {
|
||||
candidate = "user";
|
||||
}
|
||||
|
||||
if (candidate.length > 32) {
|
||||
candidate = candidate.slice(0, 32).replace(/-+$/g, "");
|
||||
}
|
||||
|
||||
if (!/^[a-z0-9]/.test(candidate)) {
|
||||
candidate = `u${candidate}`;
|
||||
}
|
||||
|
||||
if (!/[a-z0-9]$/.test(candidate)) {
|
||||
candidate = `${candidate}0`;
|
||||
}
|
||||
|
||||
while (candidate.length < 3) {
|
||||
candidate += "0";
|
||||
}
|
||||
|
||||
return candidate;
|
||||
}
|
||||
|
||||
function buildError(error, fallbackMessage) {
|
||||
if (error instanceof Error) {
|
||||
return error;
|
||||
|
||||
Reference in new issue
Block a user