Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@uppy/companion: upgrade got to 12 #4353

Closed
wants to merge 4 commits into from
Closed
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
2 changes: 1 addition & 1 deletion .github/workflows/companion.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x, 16.x, 18.x]
node-version: [16.x, 18.x]
steps:
- name: Checkout sources
uses: actions/checkout@v3
Expand Down
6 changes: 3 additions & 3 deletions packages/@uppy/companion/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"express-request-id": "1.4.1",
"express-session": "1.17.3",
"form-data": "^3.0.0",
"got": "11",
"got": "^12.6.0",
"grant": "5.4.21",
"helmet": "^4.6.0",
"ipaddr.js": "^2.0.1",
Expand Down Expand Up @@ -107,10 +107,10 @@
"deploy": "kubectl apply -f infra/kube/companion-kube.yml",
"prepublishOnly": "yarn run build",
"start": "node ./lib/standalone/start-server.js",
"test": "jest"
"test": "NODE_OPTIONS=--experimental-vm-modules jest"
},
"engines": {
"node": "^14.19.0 || ^16.15.0 || >=18.0.0"
"node": "^16.15.0 || >=18.0.0"
},
"installConfig": {
"hoistingLimits": "workspaces"
Expand Down
5 changes: 3 additions & 2 deletions packages/@uppy/companion/src/server/Uploader.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
const tus = require('tus-js-client')
const { randomUUID } = require('node:crypto')
const validator = require('validator')
const got = require('got').default
const { pipeline: pipelineCb } = require('node:stream')
const { join } = require('node:path')
const fs = require('node:fs')
const { promisify } = require('node:util')
const FormData = require('form-data')
const throttle = require('lodash.throttle')

const got = require('./got')

// TODO move to `require('streams/promises').pipeline` when dropping support for Node.js 14.x.
const pipeline = promisify(pipelineCb)

Expand Down Expand Up @@ -605,7 +606,7 @@ class Uploader {

try {
const httpMethod = (this.options.httpMethod || '').toLowerCase() === 'put' ? 'put' : 'post'
const runRequest = got[httpMethod]
const runRequest = (await got)[httpMethod]

const response = await runRequest(url, reqOptions)

Expand Down
2 changes: 1 addition & 1 deletion packages/@uppy/companion/src/server/controllers/url.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const validateURL = (url, ignoreTld) => {
*/
const downloadURL = async (url, blockLocalIPs, traceId) => {
try {
const protectedGot = getProtectedGot({ url, blockLocalIPs })
const protectedGot = await getProtectedGot({ url, blockLocalIPs })
const stream = protectedGot.stream.get(url, { responseType: 'json' })
await prepareStream(stream)
return stream
Expand Down
3 changes: 3 additions & 0 deletions packages/@uppy/companion/src/server/got.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const gotPromise = import('got')

module.exports = gotPromise.then((got) => got.default)
9 changes: 5 additions & 4 deletions packages/@uppy/companion/src/server/helpers/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ const https = require('node:https')
const { URL } = require('node:url')
const dns = require('node:dns')
const ipaddr = require('ipaddr.js')
const got = require('got').default

const logger = require('../logger')

const got = require('../got')

const FORBIDDEN_IP_ADDRESS = 'Forbidden IP address'

// Example scary IPs that should return false (ipv6-to-ipv4 mapped):
Expand Down Expand Up @@ -91,7 +92,7 @@ module.exports.getProtectedHttpAgent = (protocol) => {
return protocol.startsWith('https') ? HttpsAgent : HttpAgent
}

function getProtectedGot ({ url, blockLocalIPs }) {
async function getProtectedGot ({ url, blockLocalIPs }) {
const httpAgent = new (module.exports.getProtectedHttpAgent('http'))()
const httpsAgent = new (module.exports.getProtectedHttpAgent('https'))()

Expand All @@ -105,7 +106,7 @@ function getProtectedGot ({ url, blockLocalIPs }) {
}

// @ts-ignore
return got.extend({ hooks: { beforeRedirect: [beforeRedirect] }, agent: { http: httpAgent, https: httpsAgent } })
return (await got).extend({ hooks: { beforeRedirect: [beforeRedirect] }, agent: { http: httpAgent, https: httpsAgent } })
}

module.exports.getProtectedGot = getProtectedGot
Expand All @@ -119,7 +120,7 @@ module.exports.getProtectedGot = getProtectedGot
*/
exports.getURLMeta = async (url, blockLocalIPs = false) => {
async function requestWithMethod (method) {
const protectedGot = getProtectedGot({ url, blockLocalIPs })
const protectedGot = await getProtectedGot({ url, blockLocalIPs })
const stream = protectedGot.stream(url, { method, throwHttpErrors: false })

return new Promise((resolve, reject) => (
Expand Down
5 changes: 3 additions & 2 deletions packages/@uppy/companion/src/server/jobs.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ const schedule = require('node-schedule')
const fs = require('node:fs')
const path = require('node:path')
const { promisify } = require('node:util')
const got = require('got').default

const got = require('./got')

const { FILE_NAME_PREFIX } = require('./Uploader')
const logger = require('./logger')
Expand Down Expand Up @@ -65,7 +66,7 @@ async function runPeriodicPing ({ urls, payload, requestTimeout }) {
// Run requests in parallel
await Promise.all(urls.map(async (url) => {
try {
await got.post(url, { json: payload, timeout: { request: requestTimeout } })
await (await got).post(url, { json: payload, timeout: { request: requestTimeout } })
} catch (err) {
logger.warn(err, 'jobs.periodic.ping')
}
Expand Down
18 changes: 9 additions & 9 deletions packages/@uppy/companion/src/server/provider/box/index.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
const got = require('got').default

const Provider = require('../Provider')
const adaptData = require('./adapter')
const { withProviderErrorHandling } = require('../providerErrors')
const { prepareStream } = require('../../helpers/utils')

const got = require('../../got')

const BOX_FILES_FIELDS = 'id,modified_at,name,permissions,size,type'
const BOX_THUMBNAIL_SIZE = 256

const getClient = ({ token }) => got.extend({
const getClient = async ({ token }) => (await got).extend({
prefixUrl: 'https://api.box.com/2.0',
headers: {
authorization: `Bearer ${token}`,
},
})

async function getUserInfo ({ token }) {
return getClient({ token }).get('users/me', { responseType: 'json' }).json()
return (await getClient({ token })).get('users/me', { responseType: 'json' }).json()
}

async function list ({ directory, query, token }) {
const rootFolderID = '0'
return getClient({ token }).get(`folders/${directory || rootFolderID}/items`, { searchParams: { fields: BOX_FILES_FIELDS, offset: query.cursor }, responseType: 'json' }).json()
return (await getClient({ token })).get(`folders/${directory || rootFolderID}/items`, { searchParams: { fields: BOX_FILES_FIELDS, offset: query.cursor }, responseType: 'json' }).json()
}

/**
Expand Down Expand Up @@ -61,7 +61,7 @@ class Box extends Provider {

async download ({ id, token }) {
return this.#withErrorHandling('provider.box.download.error', async () => {
const stream = getClient({ token }).stream.get(`files/${id}/content`, { responseType: 'json' })
const stream = (await getClient({ token })).stream.get(`files/${id}/content`, { responseType: 'json' })

await prepareStream(stream)
return { stream }
Expand All @@ -81,7 +81,7 @@ class Box extends Provider {
// At that time, retry this endpoint to retrieve the thumbnail.
//
// This can be reproduced more easily by changing extension to png and trying on a newly uploaded image
const stream = getClient({ token }).stream.get(`files/${id}/thumbnail.${extension}`, {
const stream = (await getClient({ token })).stream.get(`files/${id}/thumbnail.${extension}`, {
searchParams: { max_height: BOX_THUMBNAIL_SIZE, max_width: BOX_THUMBNAIL_SIZE },
responseType: 'json',
})
Expand All @@ -93,15 +93,15 @@ class Box extends Provider {

async size ({ id, token }) {
return this.#withErrorHandling('provider.box.size.error', async () => {
const { size } = await getClient({ token }).get(`files/${id}`, { responseType: 'json' }).json()
const { size } = await (await getClient({ token })).get(`files/${id}`, { responseType: 'json' }).json()
return parseInt(size, 10)
})
}

logout ({ companion, token }) {
return this.#withErrorHandling('provider.box.logout.error', async () => {
const { key, secret } = companion.options.providerOptions.box
await getClient({ token }).post('oauth2/revoke', {
await (await getClient({ token })).post('oauth2/revoke', {
prefixUrl: 'https://api.box.com',
form: {
client_id: key,
Expand Down
5 changes: 3 additions & 2 deletions packages/@uppy/companion/src/server/provider/credentials.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
const got = require('got').default
const atob = require('atob')
const { htmlEscape } = require('escape-goat')
const logger = require('../logger')
Expand All @@ -7,14 +6,16 @@ const tokenService = require('../helpers/jwt')
// eslint-disable-next-line
const Provider = require('./Provider')

const got = require('../got')

/**
* @param {string} url
* @param {string} providerName
* @param {object|null} credentialRequestParams - null asks for default credentials.
*/
async function fetchKeys (url, providerName, credentialRequestParams) {
try {
const { credentials } = await got.post(url, {
const { credentials } = await (await got).post(url, {
json: { provider: providerName, parameters: credentialRequestParams },
}).json()

Expand Down
14 changes: 7 additions & 7 deletions packages/@uppy/companion/src/server/provider/drive/index.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
const got = require('got').default

const Provider = require('../Provider')
const logger = require('../../logger')
const { VIRTUAL_SHARED_DIR, adaptData, isShortcut, isGsuiteFile, getGsuiteExportType } = require('./adapter')
const { withProviderErrorHandling } = require('../providerErrors')
const { prepareStream } = require('../../helpers/utils')

const got = require('../../got')

const DRIVE_FILE_FIELDS = 'kind,id,imageMediaMetadata,name,mimeType,ownedByMe,permissions(role,emailAddress),size,modifiedTime,iconLink,thumbnailLink,teamDriveId,videoMediaMetadata,shortcutDetails(targetId,targetMimeType)'
const DRIVE_FILES_FIELDS = `kind,nextPageToken,incompleteSearch,files(${DRIVE_FILE_FIELDS})`
// using wildcard to get all 'drive' fields because specifying fields seems no to work for the /drives endpoint
const SHARED_DRIVE_FIELDS = '*'

const getClient = ({ token }) => got.extend({
const getClient = async ({ token }) => (await got).extend({
prefixUrl: 'https://www.googleapis.com/drive/v3',
headers: {
authorization: `Bearer ${token}`,
},
})

async function getStats ({ id, token }) {
const client = getClient({ token })
const client = await getClient({ token })

const getStatsInner = async (statsOfId) => (
client.get(`files/${encodeURIComponent(statsOfId)}`, { searchParams: { fields: DRIVE_FILE_FIELDS, supportsAllDrives: true }, responseType: 'json' }).json()
Expand Down Expand Up @@ -54,7 +54,7 @@ class Drive extends Provider {
const isRoot = directory === 'root'
const isVirtualSharedDirRoot = directory === VIRTUAL_SHARED_DIR

const client = getClient({ token })
const client = await getClient({ token })

async function fetchSharedDrives (pageToken = null) {
const shouldListSharedDrives = isRoot && !query.cursor
Expand Down Expand Up @@ -106,7 +106,7 @@ class Drive extends Provider {

async download ({ id: idIn, token }) {
return this.#withErrorHandling('provider.drive.download.error', async () => {
const client = getClient({ token })
const client = await getClient({ token })

const { mimeType, id } = await getStats({ id: idIn, token })

Expand Down Expand Up @@ -148,7 +148,7 @@ class Drive extends Provider {

logout ({ token }) {
return this.#withErrorHandling('provider.drive.logout.error', async () => {
await got.post('https://accounts.google.com/o/oauth2/revoke', {
await (await got).post('https://accounts.google.com/o/oauth2/revoke', {
searchParams: { token },
responseType: 'json',
})
Expand Down
21 changes: 11 additions & 10 deletions packages/@uppy/companion/src/server/provider/dropbox/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
const got = require('got').default

const Provider = require('../Provider')
const adaptData = require('./adapter')
const { withProviderErrorHandling } = require('../providerErrors')
const { prepareStream } = require('../../helpers/utils')

const got = require('../../got')

// From https://www.dropbox.com/developers/reference/json-encoding:
//
// This function is simple and has OK performance compared to more
Expand All @@ -17,23 +17,24 @@ function httpHeaderSafeJson (v) {
})
}

const getClient = ({ token }) => got.extend({
const getClient = async ({ token }) => (await got).extend({
prefixUrl: 'https://api.dropboxapi.com/2',
headers: {
authorization: `Bearer ${token}`,
},
})

async function list ({ directory, query, token }) {
const client = await getClient({ token })
if (query.cursor) {
return getClient({ token }).post('files/list_folder/continue', { json: { cursor: query.cursor }, responseType: 'json' }).json()
return client.post('files/list_folder/continue', { json: { cursor: query.cursor }, responseType: 'json' }).json()
}

return getClient({ token }).post('files/list_folder', { searchParams: query, json: { path: `${directory || ''}`, include_non_downloadable_files: false }, responseType: 'json' }).json()
return client.post('files/list_folder', { searchParams: query, json: { path: `${directory || ''}`, include_non_downloadable_files: false }, responseType: 'json' }).json()
}

async function userInfo ({ token }) {
return getClient({ token }).post('users/get_current_account', { responseType: 'json' }).json()
return (await getClient({ token })).post('users/get_current_account', { responseType: 'json' }).json()
}

/**
Expand Down Expand Up @@ -69,7 +70,7 @@ class DropBox extends Provider {

async download ({ id, token }) {
return this.#withErrorHandling('provider.dropbox.download.error', async () => {
const stream = getClient({ token }).stream.post('files/download', {
const stream = (await getClient({ token })).stream.post('files/download', {
prefixUrl: 'https://content.dropboxapi.com/2',
headers: {
'Dropbox-API-Arg': httpHeaderSafeJson({ path: String(id) }),
Expand All @@ -85,7 +86,7 @@ class DropBox extends Provider {

async thumbnail ({ id, token }) {
return this.#withErrorHandling('provider.dropbox.thumbnail.error', async () => {
const stream = getClient({ token }).stream.post('files/get_thumbnail_v2', {
const stream = (await getClient({ token })).stream.post('files/get_thumbnail_v2', {
prefixUrl: 'https://content.dropboxapi.com/2',
headers: { 'Dropbox-API-Arg': httpHeaderSafeJson({ resource: { '.tag': 'path', path: `${id}` }, size: 'w256h256' }) },
body: Buffer.alloc(0),
Expand All @@ -99,14 +100,14 @@ class DropBox extends Provider {

async size ({ id, token }) {
return this.#withErrorHandling('provider.dropbox.size.error', async () => {
const { size } = await getClient({ token }).post('files/get_metadata', { json: { path: id }, responseType: 'json' }).json()
const { size } = await (await getClient({ token })).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 getClient({ token }).post('auth/token/revoke', { responseType: 'json' })
await (await getClient({ token })).post('auth/token/revoke', { responseType: 'json' })
return { revoked: true }
})
}
Expand Down
Loading