more static files access fix

This commit is contained in:
Yared Yemane 2026-04-27 04:54:52 -07:00
parent 599c5dd239
commit 89597dbc87

View File

@ -31,6 +31,7 @@ import {
getTopLevelCourseModules, getTopLevelCourseModules,
updateTopLevelCourseModule, updateTopLevelCourseModule,
} from "../../api/courses.api"; } from "../../api/courses.api";
import { resolveFileUrl } from "../../api/files.api";
import type { import type {
ProgramCourseListItem, ProgramCourseListItem,
TopLevelCourseModuleItem, TopLevelCourseModuleItem,
@ -51,6 +52,28 @@ function isLikelyImageUrl(src: string): boolean {
); );
} }
function isSignedS3Url(src: string): boolean {
const trimmed = src.trim();
if (!trimmed.startsWith("http://") && !trimmed.startsWith("https://")) {
return false;
}
try {
const url = new URL(trimmed);
return url.searchParams.has("X-Amz-Signature");
} catch {
return false;
}
}
function extractObjectKeyFromUrl(src: string): string {
try {
const url = new URL(src);
return url.pathname.replace(/^\/+/, "").trim();
} catch {
return "";
}
}
/** Default purple gradient with optional cover image; gradient stays if URL missing or image errors. */ /** Default purple gradient with optional cover image; gradient stays if URL missing or image errors. */
function ModuleCardTopMedia({ iconSrc }: { iconSrc: string }) { function ModuleCardTopMedia({ iconSrc }: { iconSrc: string }) {
const [coverFailed, setCoverFailed] = useState(false); const [coverFailed, setCoverFailed] = useState(false);
@ -197,7 +220,23 @@ export function CourseDetailPage() {
if (modulesOutcome.status === "fulfilled") { if (modulesOutcome.status === "fulfilled") {
const raw = modulesOutcome.value.data?.data?.modules; const raw = modulesOutcome.value.data?.data?.modules;
const list = Array.isArray(raw) ? raw : []; const list = Array.isArray(raw) ? raw : [];
const sorted = [...list].sort( const refreshed = await Promise.all(
list.map(async (module) => {
const icon = module.icon?.trim() ?? "";
if (!icon || !isSignedS3Url(icon)) return module;
const objectKey = extractObjectKeyFromUrl(icon);
if (!objectKey) return module;
try {
const resolved = await resolveFileUrl(objectKey);
const freshUrl = resolved.data?.data?.url?.trim();
if (!freshUrl) return module;
return { ...module, icon: freshUrl };
} catch {
return module;
}
}),
);
const sorted = [...refreshed].sort(
(a, b) => (a.sort_order ?? 0) - (b.sort_order ?? 0), (a, b) => (a.sort_order ?? 0) - (b.sort_order ?? 0),
); );
setModules(sorted); setModules(sorted);