diff --git a/spec/media-collection-path-spec.mjs b/spec/media-collection-path-spec.mjs new file mode 100644 index 0000000000..26a60dfa19 --- /dev/null +++ b/spec/media-collection-path-spec.mjs @@ -0,0 +1,13 @@ +import { mediaCollectionPath } from "../system/netlify/functions/media-collection.js"; + +describe("media collection paths", () => { + const userId = "auth0|abc"; + it("places bare slugs in their media folder", () => { + expect(mediaCollectionPath({ userId, mediaType: "painting", slug: "work", extension: "png" })) + .toBe("painting/work.png"); + }); + it("preserves storage-qualified slugs", () => { + expect(mediaCollectionPath({ userId, mediaType: "painting", slug: `${userId}/chat/work`, extension: "png" })) + .toBe(`${userId}/chat/work.png`); + }); +}); diff --git a/system/netlify/functions/media-collection.js b/system/netlify/functions/media-collection.js index 548dbddd16..0fce286d57 100644 --- a/system/netlify/functions/media-collection.js +++ b/system/netlify/functions/media-collection.js @@ -4,7 +4,15 @@ import { getHandleOrEmail, userIDFromHandleOrEmail } from "../../backend/authorization.mjs"; import { respond } from "../../backend/http.mjs"; -import { connect } from "../../backend/database.mjs"; +import { connect } from "../../backend/database.mjs"; + +export function mediaCollectionPath({ userId, mediaType, slug, extension }) { + const normalized = `${slug}`.replace(/^\/+/, ""); + const storagePath = normalized.startsWith(`${userId}/`) + ? normalized + : `${mediaType}/${normalized}`; + return `${storagePath}.${extension}`; +} // GET `/media/{@userHandleOrEmail}` will list files. export async function handler(event, context) { @@ -50,7 +58,13 @@ export async function handler(event, context) { // Format the response files = media.map((file) => { - return `${baseUrl}/media/${userId}/${mediaType}/${file.slug}.${extension}`; + const path = mediaCollectionPath({ + userId: userSub, + mediaType, + slug: file.slug, + extension, + }); + return `${baseUrl}/media/${userId}/${path}`; }); disconnect();