Merge branch 'main' into ts

This commit is contained in:
Spencer Woo
2022-01-26 15:42:41 +08:00
committed by GitHub
12 changed files with 254 additions and 70 deletions
+15 -3
View File
@@ -12,8 +12,14 @@ import { getOdAuthTokens, storeOdAuthTokens } from '../../utils/odAuthTokenStore
const basePath = pathPosix.resolve('/', siteConfig.baseDirectory)
const clientSecret = revealObfuscatedToken(apiConfig.obfuscatedClientSecret)
/**
* Encode the path of the file relative to the base directory
*
* @param path Relative path of the file to the base directory
* @returns Absolute path of the file inside OneDrive
*/
export function encodePath(path: string): string {
let encodedPath = pathPosix.join(basePath, pathPosix.resolve('/', path))
let encodedPath = pathPosix.join(basePath, path)
if (encodedPath === '/' || encodedPath === '') {
return ''
}
@@ -21,6 +27,11 @@ export function encodePath(path: string): string {
return `:${encodeURIComponent(encodedPath)}`
}
/**
* Fetch the access token from Redis storage and check if the token requires a renew
*
* @returns Access token for OneDrive API
*/
export async function getAccessToken(): Promise<string> {
const { accessToken, refreshToken } = await getOdAuthTokens()
@@ -98,6 +109,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
res.status(400).json({ error: 'Path query invalid.' })
return
}
const cleanPath = pathPosix.resolve('/', pathPosix.normalize(path))
const accessToken = await getAccessToken()
@@ -111,7 +123,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
const protectedRoutes = siteConfig.protectedRoutes
let authTokenPath = ''
for (const r of protectedRoutes) {
if (path.startsWith(r)) {
if (cleanPath.startsWith(r)) {
authTokenPath = `${r}/.password`
break
}
@@ -150,7 +162,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
}
}
const requestPath = encodePath(path)
const requestPath = encodePath(cleanPath)
// Handle response from OneDrive API
const requestUrl = `${apiConfig.driveApi}/root${requestPath}`
// Whether path is root, which requires some special treatment
+32
View File
@@ -0,0 +1,32 @@
import axios from 'axios'
import type { NextApiRequest, NextApiResponse } from 'next'
import { getAccessToken } from '.'
import apiConfig from '../../config/api.json'
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
// Get access token from storage
const accessToken = await getAccessToken()
// Get item details (specifically, its path) by its unique ID in OneDrive
const { id = '' } = req.query
if (typeof id === 'string') {
const itemApi = `${apiConfig.driveApi}/items/${id}`
try {
const { data } = await axios.get(itemApi, {
headers: { Authorization: `Bearer ${accessToken}` },
params: {
select: 'id,name,parentReference',
},
})
res.status(200).json(data)
} catch (error: any) {
res.status(error.response.status).json({ error: error.response.data })
}
} else {
res.status(400).json({ error: 'Invalid driveItem ID.' })
}
return
}
+18 -3
View File
@@ -3,6 +3,18 @@ import type { NextApiRequest, NextApiResponse } from 'next'
import { encodePath, getAccessToken } from '.'
import apiConfig from '../../config/api.json'
import siteConfig from '../../config/site.json'
/**
* Sanitize the search query
*
* @param query User search query, which may contain special characters
* @returns Sanitised query string which replaces non-alphanumeric characters with ' '
*/
function sanitiseQuery(query: string): string {
const sanitisedQuery = query.replace(/[^a-zA-Z0-9]/g, ' ')
return encodeURIComponent(sanitisedQuery)
}
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
// Get access token from storage
@@ -12,15 +24,18 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
const { q: searchQuery = '' } = req.query
if (typeof searchQuery === 'string') {
// Construct Microsoft Graph Search API URL, and perform search only under the base dir
const encodedPath = encodePath('/') === '' ? encodePath('/') : encodePath('/') + ':'
const searchApi = `${apiConfig.driveApi}/root${encodedPath}/search(q='${encodeURIComponent(searchQuery)}')`
// Construct Microsoft Graph Search API URL, and perform search only under the base directory
const searchRootPath = encodePath('/')
const encodedPath = searchRootPath === '' ? searchRootPath : searchRootPath + ':'
const searchApi = `${apiConfig.driveApi}/root${encodedPath}/search(q='${sanitiseQuery(searchQuery)}')`
try {
const { data } = await axios.get(searchApi, {
headers: { Authorization: `Bearer ${accessToken}` },
params: {
select: 'id,name,file,folder,parentReference',
top: siteConfig.maxItems,
},
})
res.status(200).json(data.value)