"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.oembedValidator = void 0;
const tslib_1 = require("tslib");
const express_validator_1 = require("express-validator");
const path_1 = require("path");
const model_loaders_1 = require("../../lib/model-loaders");
const video_playlist_1 = require("../../models/video/video-playlist");
const core_utils_1 = require("../../helpers/core-utils");
const misc_1 = require("../../helpers/custom-validators/misc");
const constants_1 = require("../../initializers/constants");
const shared_1 = require("./shared");
const playlistPaths = [
    (0, path_1.join)('videos', 'watch', 'playlist'),
    (0, path_1.join)('w', 'p')
];
const videoPaths = [
    (0, path_1.join)('videos', 'watch'),
    'w'
];
function buildUrls(paths) {
    return paths.map(p => constants_1.WEBSERVER.SCHEME + '://' + (0, path_1.join)(constants_1.WEBSERVER.HOST, p) + '/');
}
const startPlaylistURLs = buildUrls(playlistPaths);
const startVideoURLs = buildUrls(videoPaths);
const isURLOptions = {
    require_host: true,
    require_tld: true
};
if ((0, core_utils_1.isTestOrDevInstance)()) {
    isURLOptions.require_tld = false;
}
const oembedValidator = [
    (0, express_validator_1.query)('url')
        .isURL(isURLOptions),
    (0, express_validator_1.query)('maxwidth')
        .optional()
        .isInt(),
    (0, express_validator_1.query)('maxheight')
        .optional()
        .isInt(),
    (0, express_validator_1.query)('format')
        .optional()
        .isIn(['xml', 'json']),
    (req, res, next) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
        if ((0, shared_1.areValidationErrors)(req, res))
            return;
        if (req.query.format !== undefined && req.query.format !== 'json') {
            return res.fail({
                status: 501,
                message: 'Requested format is not implemented on server.',
                data: {
                    format: req.query.format
                }
            });
        }
        const url = req.query.url;
        let urlPath;
        try {
            urlPath = new URL(url).pathname;
        }
        catch (err) {
            return res.fail({
                status: 400,
                message: err.message,
                data: {
                    url
                }
            });
        }
        const isPlaylist = startPlaylistURLs.some(u => url.startsWith(u));
        const isVideo = isPlaylist ? false : startVideoURLs.some(u => url.startsWith(u));
        const startIsOk = isVideo || isPlaylist;
        const parts = urlPath.split('/');
        if (startIsOk === false || parts.length === 0) {
            return res.fail({
                status: 400,
                message: 'Invalid url.',
                data: {
                    url
                }
            });
        }
        const elementId = (0, misc_1.toCompleteUUID)(parts.pop());
        if ((0, misc_1.isIdOrUUIDValid)(elementId) === false) {
            return res.fail({ message: 'Invalid video or playlist id.' });
        }
        if (isVideo) {
            const video = yield (0, model_loaders_1.loadVideo)(elementId, 'all');
            if (!video) {
                return res.fail({
                    status: 404,
                    message: 'Video not found'
                });
            }
            if (video.privacy === 1 ||
                (video.privacy === 2 && (0, misc_1.isUUIDValid)(elementId) === true)) {
                res.locals.videoAll = video;
                return next();
            }
            return res.fail({
                status: 403,
                message: 'Video is not publicly available'
            });
        }
        const videoPlaylist = yield video_playlist_1.VideoPlaylistModel.loadWithAccountAndChannelSummary(elementId, undefined);
        if (!videoPlaylist) {
            return res.fail({
                status: 404,
                message: 'Video playlist not found'
            });
        }
        if (videoPlaylist.privacy === 1 ||
            (videoPlaylist.privacy === 2 && (0, misc_1.isUUIDValid)(elementId))) {
            res.locals.videoPlaylistSummary = videoPlaylist;
            return next();
        }
        return res.fail({
            status: 403,
            message: 'Playlist is not public'
        });
    })
];
exports.oembedValidator = oembedValidator;
//# sourceMappingURL=oembed.js.map