Skip to content
This repository has been archived by the owner on Jul 26, 2023. It is now read-only.

Filter out protected ones from search results #648

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 1 addition & 22 deletions components/SearchModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,7 @@ import { LoadingIcon } from './Loading'

import { getFileIcon } from '../utils/getFileIcon'
import { fetcher } from '../utils/fetchWithSWR'
import siteConfig from '../config/site.config'

/**
* Extract the searched item's path in field 'parentReference' and convert it to the
* absolute path represented in onedrive-vercel-index
*
* @param path Path returned from the parentReference field of the driveItem
* @returns The absolute path of the driveItem in the search result
*/
function mapAbsolutePath(path: string): string {
// path is in the format of '/drive/root:/path/to/file', if baseDirectory is '/' then we split on 'root:',
// otherwise we split on the user defined 'baseDirectory'
const absolutePath = path.split(siteConfig.baseDirectory === '/' ? 'root:' : siteConfig.baseDirectory)
// path returned by the API may contain #, by doing a decodeURIComponent and then encodeURIComponent we can
// replace URL sensitive characters such as the # with %23
return absolutePath.length > 1 // solve https://github.com/spencerwooo/onedrive-vercel-index/issues/539
? absolutePath[1]
.split('/')
.map(p => encodeURIComponent(decodeURIComponent(p)))
.join('/')
: ''
}
import { mapAbsolutePath } from '../utils/mapAbsolutePath'

/**
* Implements a debounced search function that returns a promise that resolves to an array of
Expand Down
13 changes: 12 additions & 1 deletion pages/api/item.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import axios from 'axios'
import type { NextApiRequest, NextApiResponse } from 'next'

import { getAccessToken } from '.'
import { getAccessToken, getAuthTokenPath } from '.'
import apiConfig from '../../config/api.config'
import type { OdDriveItem } from '../../types'
import { mapAbsolutePath } from '../../utils/mapAbsolutePath'

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
// Get access token from storage
Expand All @@ -25,6 +27,15 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
select: 'id,name,parentReference',
},
})

// Check if path of the item are protected
const item = data as OdDriveItem
const path = `${decodeURIComponent(mapAbsolutePath(item.parentReference.path))}/${item.name}`
if (getAuthTokenPath(path) !== '') {
res.status(403).json({ error: 'The driveItem is password protected.' })
return
}

res.status(200).json(data)
} catch (error: any) {
res.status(error?.response?.status ?? 500).json({ error: error?.response?.data ?? 'Internal server error.' })
Expand Down
18 changes: 16 additions & 2 deletions pages/api/search.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import axios from 'axios'
import type { NextApiRequest, NextApiResponse } from 'next'

import { encodePath, getAccessToken } from '.'
import { encodePath, getAccessToken, getAuthTokenPath } from '.'
import { mapAbsolutePath } from '../../utils/mapAbsolutePath'
import apiConfig from '../../config/api.config'
import siteConfig from '../../config/site.config'
import type { OdSearchResult } from '../../types'

/**
* Sanitize the search query
Expand Down Expand Up @@ -51,7 +53,19 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
top: siteConfig.maxItems,
},
})
res.status(200).json(data.value)

// Check if paths of search items are protected
let items = data.value as OdSearchResult
if (items && 'path' in items[0].parentReference) {
// OneDrive International have the path returned in the parentReference field
// OneDrive for Business/Education does not, so we skip it and leave the check to item API
items = items.filter(item => {
const path = `${decodeURIComponent(mapAbsolutePath(item.parentReference.path))}/${item.name}`
return getAuthTokenPath(path) === ''
})
}

res.status(200).json(items)
} catch (error: any) {
res.status(error?.response?.status ?? 500).json({ error: error?.response?.data ?? 'Internal server error.' })
}
Expand Down
22 changes: 22 additions & 0 deletions utils/mapAbsolutePath.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import siteConfig from '../config/site.config'

/**
* Extract the searched item's path in field 'parentReference' and convert it to the
* absolute path represented in onedrive-vercel-index
*
* @param path Path returned from the parentReference field of the driveItem
* @returns The absolute path of the driveItem in the search result
*/
export function mapAbsolutePath(path: string): string {
// path is in the format of '/drive/root:/path/to/file', if baseDirectory is '/' then we split on 'root:',
// otherwise we split on the user defined 'baseDirectory'
const absolutePath = path.split(siteConfig.baseDirectory === '/' ? 'root:' : siteConfig.baseDirectory)
// path returned by the API may contain #, by doing a decodeURIComponent and then encodeURIComponent we can
// replace URL sensitive characters such as the # with %23
return absolutePath.length > 1 // solve https://github.com/spencerwooo/onedrive-vercel-index/issues/539
? absolutePath[1]
.split('/')
.map(p => encodeURIComponent(decodeURIComponent(p)))
.join('/')
: ''
}