import FileService from "../Services/FileService";
import Response from "../Utils/Response";
import BaseAPI from "./BaseAPI";
import NotFoundException from "../../Types/Exception/NotFoundException";
import ObjectID from "../../Types/ObjectID";
import File from "../../Models/DatabaseModels/File";
import UserMiddleware from "../Middleware/UserAuthorization";
import JSONWebToken from "../Utils/JsonWebToken";
import logger from "../Utils/Logger";
const isAuthenticatedRequest = (req) => {
    const accessToken = UserMiddleware.getAccessTokenFromExpressRequest(req);
    if (!accessToken) {
        return false;
    }
    try {
        const decoded = JSONWebToken.decode(accessToken);
        return Boolean(decoded === null || decoded === void 0 ? void 0 : decoded.userId);
    }
    catch (err) {
        logger.error(err);
        return false;
    }
};
export default class FileAPI extends BaseAPI {
    constructor() {
        var _a, _b;
        super(File, FileService);
        /*
         * Token-based image route. Used for inline images embedded in
         * markdown (post-mortems, internal notes, etc.) where we don't want
         * the file's ObjectID to be enumerable. Anonymous requests are
         * served only when the file is explicitly marked public; otherwise
         * the request must carry a valid OneUptime session.
         *
         * Registered before the id-based route so the longer path matches
         * first.
         */
        this.router.get(`${(_a = new this.entityType().getCrudApiPath()) === null || _a === void 0 ? void 0 : _a.toString()}/image/access-token/:token`, async (req, res, _next) => {
            const token = req.params["token"];
            if (!token) {
                return Response.sendErrorResponse(req, res, new NotFoundException("File not found"));
            }
            const file = await FileService.findOneBy({
                query: {
                    imageAccessToken: token,
                },
                props: {
                    isRoot: true,
                    ignoreHooks: true,
                },
                select: {
                    file: true,
                    fileType: true,
                    isPublic: true,
                },
            });
            if (!file || !file.file || !file.fileType) {
                return Response.sendErrorResponse(req, res, new NotFoundException("File not found"));
            }
            if (!file.isPublic && !isAuthenticatedRequest(req)) {
                return Response.sendErrorResponse(req, res, new NotFoundException("File not found"));
            }
            return Response.sendFileResponse(req, res, file);
        });
        /*
         * Legacy id-based image route. Kept for assets that are intentionally
         * public (probe icons, AI agent icons). Now requires isPublic=true
         * so private inline-upload images cannot be fetched by guessing or
         * leaking an ObjectID.
         */
        this.router.get(`${(_b = new this.entityType().getCrudApiPath()) === null || _b === void 0 ? void 0 : _b.toString()}/image/:imageId`, async (req, res, _next) => {
            const file = await FileService.findOneById({
                id: new ObjectID(req.params["imageId"]),
                props: {
                    isRoot: true,
                    ignoreHooks: true,
                },
                select: {
                    file: true,
                    fileType: true,
                    isPublic: true,
                },
            });
            if (!file || !file.file || !file.fileType || !file.isPublic) {
                return Response.sendErrorResponse(req, res, new NotFoundException("File not found"));
            }
            return Response.sendFileResponse(req, res, file);
        });
    }
}
//# sourceMappingURL=FileAPI.js.map