UNPKG

payload

Version:

Node, React, Headless CMS and Application Framework built on Next.js

73 lines (72 loc) 3.33 kB
import { APIError } from '../errors/index.js'; import { isURLAllowed } from '../utilities/isURLAllowed.js'; import { safeFetch } from './safeFetch.js'; export const getExternalFile = async ({ data, req, uploadConfig })=>{ const { filename, url } = data; let trimAuthCookies = true; if (typeof url === 'string') { let fileURL = url; if (!url.startsWith('http')) { // URL points to the same server - we can send any cookies safely to our server. trimAuthCookies = false; const baseUrl = req.headers.get('origin') || `${req.protocol}://${req.headers.get('host')}`; fileURL = `${baseUrl}${url}`; } let cookies = (req.headers.get('cookie') ?? '').split(';'); if (trimAuthCookies) { cookies = cookies.filter((cookie)=>!cookie.trim().startsWith(req.payload.config.cookiePrefix)); } const headers = uploadConfig.externalFileHeaderFilter ? uploadConfig.externalFileHeaderFilter(Object.fromEntries(new Headers(req.headers))) : { cookie: cookies.join(';') }; let res; let redirectCount = 0; const maxRedirects = 3; while(redirectCount <= maxRedirects){ const skipSafeFetch = uploadConfig.skipSafeFetch === true ? uploadConfig.skipSafeFetch : Array.isArray(uploadConfig.skipSafeFetch) && isURLAllowed(fileURL, uploadConfig.skipSafeFetch); const isAllowedPasteUrl = uploadConfig.pasteURL && uploadConfig.pasteURL.allowList && isURLAllowed(fileURL, uploadConfig.pasteURL.allowList); if (skipSafeFetch || isAllowedPasteUrl) { res = await fetch(fileURL, { credentials: 'include', headers, method: 'GET', redirect: 'manual' }); } else { // Default res = await safeFetch(fileURL, { credentials: 'include', headers, method: 'GET' }); } if (res.status >= 300 && res.status < 400) { redirectCount++; if (redirectCount > maxRedirects) { throw new APIError(`Too many redirects (max ${maxRedirects})`, 403); } const location = res.headers.get('location'); if (location) { fileURL = new URL(location, fileURL).toString(); if (uploadConfig.pasteURL && uploadConfig.pasteURL.allowList && !isURLAllowed(fileURL, uploadConfig.pasteURL.allowList)) { throw new APIError('Redirect target is not allowed.', 400); } continue; } } break; } if (!res || !res.ok) { throw new APIError(`Failed to fetch file from ${fileURL}`, res?.status); } const data = await res.arrayBuffer(); return { name: filename, data: Buffer.from(data), mimetype: res.headers.get('content-type') || undefined, size: Number(res.headers.get('content-length')) || 0 }; } throw new APIError('Invalid file url', 400); }; //# sourceMappingURL=getExternalFile.js.map