import type { OdThumbnail } from '../../types' import { posix as pathPosix } from 'path' import axios from 'axios' import type { NextApiRequest, NextApiResponse } from 'next' import { checkAuthRoute, encodePath, getAccessToken } from '.' import apiConfig from '../../config/api.config' export default async function handler(req: NextApiRequest, res: NextApiResponse) { const accessToken = await getAccessToken() if (!accessToken) { res.status(403).json({ error: 'No access token.' }) return } // Get item thumbnails by its path since we will later check if it is protected const { path = '', size = 'medium', odpt = '' } = req.query // Set edge function caching for faster load times, if route is not protected, check docs: // https://vercel.com/docs/concepts/functions/edge-caching if (odpt === '') res.setHeader('Cache-Control', apiConfig.cacheControlHeader) // Check whether the size is valid - must be one of 'large', 'medium', or 'small' if (size !== 'large' && size !== 'medium' && size !== 'small') { res.status(400).json({ error: 'Invalid size' }) return } // Sometimes the path parameter is defaulted to '[...path]' which we need to handle if (path === '[...path]') { res.status(400).json({ error: 'No path specified.' }) return } // If the path is not a valid path, return 400 if (typeof path !== 'string') { res.status(400).json({ error: 'Path query invalid.' }) return } const cleanPath = pathPosix.resolve('/', pathPosix.normalize(path)) const { code, message } = await checkAuthRoute(cleanPath, accessToken, odpt as string) // Status code other than 200 means user has not authenticated yet if (code !== 200) { res.status(code).json({ error: message }) return } // If message is empty, then the path is not protected. // Conversely, protected routes are not allowed to serve from cache. if (message !== '') { res.setHeader('Cache-Control', 'no-cache') } const requestPath = encodePath(cleanPath) // Handle response from OneDrive API const requestUrl = `${apiConfig.driveApi}/root${requestPath}` // Whether path is root, which requires some special treatment const isRoot = requestPath === '' try { const { data } = await axios.get(`${requestUrl}${isRoot ? '' : ':'}/thumbnails`, { headers: { Authorization: `Bearer ${accessToken}` }, }) const thumbnailUrl = data.value && data.value.length > 0 ? (data.value[0] as OdThumbnail)[size].url : null if (thumbnailUrl) { res.redirect(thumbnailUrl) } else { res.status(400).json({ error: "The item doesn't have a valid thumbnail." }) } } catch (error: any) { res.status(error?.response?.status).json({ error: error?.response?.data ?? 'Internal server error.' }) } return }