mirror of
https://github.com/rgrgogu/new_starr.git
synced 2026-09-27 00:12:54 +08:00
@@ -13,37 +13,10 @@
|
||||
"use strict";
|
||||
|
||||
const { Op } = require("sequelize");
|
||||
const jwt = require("jsonwebtoken");
|
||||
|
||||
const R = require("../../utils/response.util");
|
||||
const mdl_Assets = require("../../models/assets/assets.mdl");
|
||||
const s3 = require("../../services/s3.service");
|
||||
|
||||
const MEDIA_SECRET = process.env.MEDIA_JWT_SECRET ?? process.env.JWT_SECRET;
|
||||
const TOKEN_TTL_SEC = 30 * 60; // 30 min — admin preview session
|
||||
|
||||
const SUPPORTED_TYPES = ["video", "audio", "document", "image"];
|
||||
|
||||
function resolveIp(req) {
|
||||
const forwarded = req.headers["x-forwarded-for"];
|
||||
if (forwarded) return forwarded.split(",")[0].trim();
|
||||
return req.ip ?? req.socket?.remoteAddress ?? "unknown";
|
||||
}
|
||||
|
||||
function signToken(asset, userId, ip) {
|
||||
return jwt.sign(
|
||||
{
|
||||
asset_id: asset.asset_id,
|
||||
user_id: userId,
|
||||
storage_key: asset.storage_key,
|
||||
file_type: asset.file_type,
|
||||
mime_type: asset.mime_type,
|
||||
ip,
|
||||
},
|
||||
MEDIA_SECRET,
|
||||
{ expiresIn: TOKEN_TTL_SEC }
|
||||
);
|
||||
}
|
||||
const R = require("../../utils/response.util");
|
||||
const mdl_Assets = require("../../models/assets/assets.mdl");
|
||||
const mediaToken = require("../../services/mediaToken.service");
|
||||
|
||||
// ─── POST /admin/media/token ──────────────────────────────────────────────────
|
||||
|
||||
@@ -59,7 +32,7 @@ exports.issueToken = async (req, res) => {
|
||||
|
||||
if (!asset) return R.error(res, "Asset not found.", 404);
|
||||
|
||||
if (!SUPPORTED_TYPES.includes(asset.file_type)) {
|
||||
if (!mediaToken.SUPPORTED_TYPES.includes(asset.file_type)) {
|
||||
return R.error(res, `Asset type "${asset.file_type}" is not supported.`, 400);
|
||||
}
|
||||
|
||||
@@ -67,18 +40,8 @@ exports.issueToken = async (req, res) => {
|
||||
return R.error(res, "Token flow is for S3 assets only. Use the raw file_url for other providers.", 400);
|
||||
}
|
||||
|
||||
const ip = resolveIp(req);
|
||||
const token = signToken(asset, req.user.user_id, ip);
|
||||
|
||||
// ── Presign thumbnail URL so the browser can load it directly ─────────────
|
||||
let thumbnail_url = null;
|
||||
if (asset.thumbnail_storage_key) {
|
||||
try {
|
||||
thumbnail_url = await s3.getSignedDownloadUrl(asset.thumbnail_storage_key, TOKEN_TTL_SEC);
|
||||
} catch {
|
||||
// Non-fatal — thumbnail is cosmetic
|
||||
}
|
||||
}
|
||||
const ip = mediaToken.resolveIp(req);
|
||||
const { token, thumbnail_url } = await mediaToken.issueForAsset(asset, req.user.user_id, ip);
|
||||
|
||||
return R.success(res, "Token issued.", {
|
||||
token,
|
||||
@@ -116,26 +79,15 @@ exports.issueTokensBatch = async (req, res) => {
|
||||
attributes: ["asset_id", "file_type", "storage_key", "mime_type", "thumbnail_storage_key"],
|
||||
});
|
||||
|
||||
const ip = resolveIp(req);
|
||||
const ip = mediaToken.resolveIp(req);
|
||||
const tokens = {};
|
||||
const thumbnails = {};
|
||||
|
||||
for (const asset of assets) {
|
||||
tokens[String(asset.asset_id)] = signToken(asset, req.user.user_id, ip);
|
||||
|
||||
// For image/video assets with a thumbnail — presign it so the browser can
|
||||
// load it directly from Garage without going through the stream proxy.
|
||||
if (asset.thumbnail_storage_key) {
|
||||
try {
|
||||
thumbnails[String(asset.asset_id)] = await s3.getSignedDownloadUrl(
|
||||
asset.thumbnail_storage_key,
|
||||
TOKEN_TTL_SEC,
|
||||
);
|
||||
} catch {
|
||||
// Non-fatal — stream token is the fallback
|
||||
}
|
||||
}
|
||||
}
|
||||
await Promise.all(assets.map(async (asset) => {
|
||||
const { token, thumbnail_url } = await mediaToken.issueForAsset(asset, req.user.user_id, ip);
|
||||
tokens[String(asset.asset_id)] = token;
|
||||
if (thumbnail_url) thumbnails[String(asset.asset_id)] = thumbnail_url;
|
||||
}));
|
||||
|
||||
return R.success(res, "Tokens issued.", { tokens, thumbnails });
|
||||
} catch (err) {
|
||||
|
||||
Reference in New Issue
Block a user