fix: add custom endpoint for getVideoBySlug to bypass permissions
- Add GET /sexy/videos/:slug endpoint in bundle that bypasses Directus permissions - Simplify getVideoBySlug to use the new custom endpoint instead of direct API call - Fixes "Video not found" error on production for public video pages - Custom endpoint uses database query like other public endpoints (/sexy/models, etc) - Ensures videos are accessible to unauthenticated users while respecting upload_date 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -204,6 +204,48 @@ export default {
|
||||
}
|
||||
});
|
||||
|
||||
// GET /sexy/videos/:slug - Get single video by slug
|
||||
router.get("/videos/:slug", async (req, res) => {
|
||||
try {
|
||||
const { slug } = req.params;
|
||||
|
||||
const video = await database
|
||||
.select("v.*")
|
||||
.from("sexy_videos as v")
|
||||
.where("v.slug", slug)
|
||||
.where("v.upload_date", "<=", new Date().toISOString())
|
||||
.first();
|
||||
|
||||
if (!video) {
|
||||
return res.status(404).json({ error: "Video not found" });
|
||||
}
|
||||
|
||||
// Fetch models
|
||||
const models = await database
|
||||
.select("u.*")
|
||||
.from("sexy_videos_models as vm")
|
||||
.leftJoin("directus_users as u", "vm.directus_users_id", "u.id")
|
||||
.where("vm.sexy_videos_id", video.id);
|
||||
|
||||
video.models = models;
|
||||
|
||||
// Fetch movie file
|
||||
if (video.movie) {
|
||||
const movie = await database
|
||||
.select("*")
|
||||
.from("directus_files")
|
||||
.where("id", video.movie)
|
||||
.first();
|
||||
video.movie = movie;
|
||||
}
|
||||
|
||||
res.json(video);
|
||||
} catch (error: any) {
|
||||
console.error("Video by slug error:", error);
|
||||
res.status(500).json({ error: error.message || "Failed to fetch video" });
|
||||
}
|
||||
});
|
||||
|
||||
// GET /sexy/articles - List articles
|
||||
router.get("/articles", async (req, res) => {
|
||||
try {
|
||||
|
||||
@@ -242,41 +242,13 @@ export async function getVideoBySlug(
|
||||
return loggedApiCall(
|
||||
"getVideoBySlug",
|
||||
async () => {
|
||||
const fetchFn = fetch || globalThis.fetch;
|
||||
return fetchFn(
|
||||
`${directusApiUrl}/items/sexy_videos?${new URLSearchParams({
|
||||
filter: JSON.stringify({ slug: { _eq: slug } }),
|
||||
fields: JSON.stringify([
|
||||
"*",
|
||||
{
|
||||
models: [
|
||||
"*",
|
||||
{
|
||||
directus_users_id: ["*"],
|
||||
},
|
||||
],
|
||||
},
|
||||
"movie.*",
|
||||
]),
|
||||
})}`,
|
||||
)
|
||||
.then((res) => res.json())
|
||||
.then((response) => {
|
||||
const videos = response.data;
|
||||
if (!videos || videos.length === 0) {
|
||||
throw new Error("Video not found");
|
||||
}
|
||||
// Handle models array - filter out null/undefined and map to user objects
|
||||
if (Array.isArray(videos[0].models)) {
|
||||
videos[0].models = videos[0].models
|
||||
.filter((u) => u && u.directus_users_id)
|
||||
.map((u) => u.directus_users_id!);
|
||||
} else {
|
||||
videos[0].models = [];
|
||||
}
|
||||
|
||||
return videos[0];
|
||||
});
|
||||
const directus = getDirectusInstance(fetch);
|
||||
return directus.request<Video>(
|
||||
customEndpoint({
|
||||
method: "GET",
|
||||
path: `/sexy/videos/${slug}`,
|
||||
}),
|
||||
);
|
||||
},
|
||||
{ slug },
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user