Skip to content

Commit

Permalink
Extend dropbox provider to support teams folders
Browse files Browse the repository at this point in the history
  • Loading branch information
vikas-rajvanshy committed Feb 5, 2025
1 parent daa7d1d commit 2982136
Showing 1 changed file with 48 additions and 14 deletions.
62 changes: 48 additions & 14 deletions packages/@uppy/companion/src/server/provider/dropbox/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,22 @@ function httpHeaderSafeJson (v) {
})
}

const getClient = async ({ token }) => (await got).extend({
const getClient = async ({ token, rootNamespaceId }) => (await got).extend({
prefixUrl: 'https://api.dropboxapi.com/2',
headers: {
authorization: `Bearer ${token}`,
authorization: `Bearer ${token}`,
...(rootNamespaceId && {
'Dropbox-API-Path-Root': httpHeaderSafeJson({ ".tag": "root", "root": rootNamespaceId })
}),
},
})

const getOauthClient = async () => (await got).extend({
prefixUrl: 'https://api.dropboxapi.com/oauth2',
})

async function list ({ directory, query, token }) {
const client = await getClient({ token })
async function list({ directory, query, token, rootNamespaceId }) {
const client = await getClient({ token, rootNamespaceId })
if (query.cursor) {
return client.post('files/list_folder/continue', { json: { cursor: query.cursor }, responseType: 'json' }).json()
}
Expand Down Expand Up @@ -58,6 +61,7 @@ class DropBox extends Provider {
constructor (options) {
super(options)
this.needsCookieAuth = true
this.rootNamespaceId = null
}

static get oauthProvider () {
Expand All @@ -74,19 +78,31 @@ class DropBox extends Provider {
*/
async list (options) {
return this.#withErrorHandling('provider.dropbox.list.error', async () => {
const responses = await Promise.all([
list(options),
userInfo(options),
])
// @ts-ignore
const [stats, { email }] = responses
const userInfoResponse = await userInfo(options)
const { email, root_info } = userInfoResponse

// Store rootNamespaceId as class member
this.rootNamespaceId = root_info?.root_namespace_id

// Then call list with the directory path and root namespace
const stats = await list({
...options,
rootNamespaceId: this.rootNamespaceId,
})

return adaptData(stats, email, options.companion.buildURL)
})
}

async download ({ id, token }) {
return this.#withErrorHandling('provider.dropbox.download.error', async () => {
const stream = (await getClient({ token })).stream.post('files/download', {
// Fetch rootNamespaceId if not already set
if (!this.rootNamespaceId) {
const userInfoResponse = await userInfo({ token })
this.rootNamespaceId = userInfoResponse.root_info?.root_namespace_id
}

const stream = (await getClient({ token, rootNamespaceId: this.rootNamespaceId })).stream.post('files/download', {
prefixUrl: 'https://content.dropboxapi.com/2',
headers: {
'Dropbox-API-Arg': httpHeaderSafeJson({ path: String(id) }),
Expand All @@ -103,7 +119,13 @@ class DropBox extends Provider {

async thumbnail ({ id, token }) {
return this.#withErrorHandling('provider.dropbox.thumbnail.error', async () => {
const stream = (await getClient({ token })).stream.post('files/get_thumbnail_v2', {
// Fetch rootNamespaceId if not already set
if (!this.rootNamespaceId) {
const userInfoResponse = await userInfo({ token })
this.rootNamespaceId = userInfoResponse.root_info?.root_namespace_id
}

const stream = (await getClient({ token, rootNamespaceId: this.rootNamespaceId })).stream.post('files/get_thumbnail_v2', {
prefixUrl: 'https://content.dropboxapi.com/2',
headers: { 'Dropbox-API-Arg': httpHeaderSafeJson({ resource: { '.tag': 'path', path: `${id}` }, size: 'w256h256', format: 'jpeg' }) },
body: Buffer.alloc(0),
Expand All @@ -117,14 +139,26 @@ class DropBox extends Provider {

async size ({ id, token }) {
return this.#withErrorHandling('provider.dropbox.size.error', async () => {
const { size } = await (await getClient({ token })).post('files/get_metadata', { json: { path: id }, responseType: 'json' }).json()
// Fetch rootNamespaceId if not already set
if (!this.rootNamespaceId) {
const userInfoResponse = await userInfo({ token })
this.rootNamespaceId = userInfoResponse.root_info?.root_namespace_id
}

const { size } = await (await getClient({ token, rootNamespaceId: this.rootNamespaceId })).post('files/get_metadata', { json: { path: id }, responseType: 'json' }).json()
return parseInt(size, 10)
})
}

async logout ({ token }) {
return this.#withErrorHandling('provider.dropbox.logout.error', async () => {
await (await getClient({ token })).post('auth/token/revoke', { responseType: 'json' })
// Fetch rootNamespaceId if not already set
if (!this.rootNamespaceId) {
const userInfoResponse = await userInfo({ token })
this.rootNamespaceId = userInfoResponse.root_info?.root_namespace_id
}
await (await getClient({ token, rootNamespaceId: this.rootNamespaceId })).post('auth/token/revoke', { responseType: 'json' })

return { revoked: true }
})
}
Expand Down

0 comments on commit 2982136

Please sign in to comment.