mirror of
https://github.com/transloadit/uppy.git
synced 2026-07-17 16:50:22 +00:00
parent
489d76717c
commit
d9742ba4e4
27 changed files with 2332 additions and 439 deletions
|
|
@ -662,11 +662,10 @@ export default class AwsS3Multipart<
|
|||
querify: true,
|
||||
})
|
||||
|
||||
const query = new URLSearchParams({
|
||||
filename,
|
||||
...(type != null && { type }),
|
||||
...metadata,
|
||||
})
|
||||
const query = new URLSearchParams({ filename, type, ...metadata } as Record<
|
||||
string,
|
||||
string
|
||||
>)
|
||||
|
||||
return this.#client.get(`s3/params?${query}`, options)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,9 +47,9 @@
|
|||
"cors": "^2.8.5",
|
||||
"escape-goat": "3.0.0",
|
||||
"escape-string-regexp": "4.0.0",
|
||||
"express": "^5.2.1",
|
||||
"express": "4.21.2",
|
||||
"express-interceptor": "1.2.0",
|
||||
"express-prom-bundle": "^8.0.0",
|
||||
"express-prom-bundle": "7",
|
||||
"express-session": "1.18.1",
|
||||
"fast-safe-stringify": "^2.1.1",
|
||||
"formdata-node": "^6.0.3",
|
||||
|
|
|
|||
|
|
@ -125,9 +125,6 @@ export function app(optionsArg: CompanionInitOptions) {
|
|||
|
||||
const app = express()
|
||||
|
||||
// Needed for e.g. s3 `/params` endpoint metadata, like `metadata[key]=value` to be parsed into a metadata object
|
||||
app.set('query parser', 'extended')
|
||||
|
||||
if (options.metrics) {
|
||||
app.use(middlewares.metrics({ path: options.server.path }))
|
||||
}
|
||||
|
|
@ -139,10 +136,10 @@ export function app(optionsArg: CompanionInitOptions) {
|
|||
app.use(interceptGrantErrorResponse)
|
||||
|
||||
// override provider credentials at request time
|
||||
// Making `POST` request to the `/connect/:provider{/:override}` route requires a form body parser middleware:
|
||||
// Making `POST` request to the `/connect/:provider/:override?` route requires a form body parser middleware:
|
||||
// See https://github.com/simov/grant#dynamic-http
|
||||
app.use(
|
||||
'/connect/:oauthProvider{/:override}',
|
||||
'/connect/:oauthProvider/:override?',
|
||||
express.urlencoded({ extended: false }),
|
||||
getCredentialsOverrideMiddleware(
|
||||
providers as Record<string, typeof Provider>,
|
||||
|
|
@ -162,7 +159,7 @@ export function app(optionsArg: CompanionInitOptions) {
|
|||
app.use(middlewares.cors(options))
|
||||
|
||||
// add uppy options to the request object so it can be accessed by subsequent handlers.
|
||||
app.use(middlewares.getCompanionMiddleware(options))
|
||||
app.use('*', middlewares.getCompanionMiddleware(options))
|
||||
app.use('/s3', s3(options.s3))
|
||||
if (options.enableUrlEndpoint) app.use('/url', url())
|
||||
if (options.enableGooglePickerEndpoint)
|
||||
|
|
@ -235,7 +232,7 @@ export function app(optionsArg: CompanionInitOptions) {
|
|||
)
|
||||
|
||||
app.get(
|
||||
'/:providerName/list{/:id}',
|
||||
'/:providerName/list/:id?',
|
||||
middlewares.hasSessionAndProvider,
|
||||
middlewares.verifyToken,
|
||||
controllers.list,
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ export default function callback(
|
|||
const providerName = req.params['providerName']
|
||||
const { companion } = req
|
||||
|
||||
if (typeof providerName !== 'string' || providerName.length === 0) {
|
||||
if (providerName == null || providerName.length === 0) {
|
||||
res.sendStatus(400)
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,9 +7,8 @@ export default async function list(
|
|||
next: NextFunction,
|
||||
): Promise<void> {
|
||||
const { query, params, companion } = req
|
||||
const id = params['id']
|
||||
const { providerUserSession, provider } = companion
|
||||
if (!provider || (typeof id !== 'string' && id != null)) {
|
||||
if (!provider) {
|
||||
res.sendStatus(400)
|
||||
return
|
||||
}
|
||||
|
|
@ -18,7 +17,7 @@ export default async function list(
|
|||
const data = await provider.list({
|
||||
companion,
|
||||
providerUserSession,
|
||||
directory: id,
|
||||
directory: params['id'],
|
||||
query,
|
||||
})
|
||||
res.json(data)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ export default function preauth(req: Request, res: Response): void {
|
|||
}
|
||||
|
||||
const providerName = req.params['providerName']
|
||||
if (typeof providerName !== 'string' || providerName.length === 0) {
|
||||
if (providerName == null || providerName.length === 0) {
|
||||
res.sendStatus(400)
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ export default async function refreshToken(
|
|||
next: NextFunction,
|
||||
): Promise<void> {
|
||||
const providerName = req.params['providerName']
|
||||
if (typeof providerName !== 'string' || providerName.length === 0) {
|
||||
if (providerName == null) {
|
||||
res.sendStatus(400)
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import assert from 'node:assert'
|
||||
import type { Part, S3Client } from '@aws-sdk/client-s3'
|
||||
import {
|
||||
AbortMultipartUploadCommand,
|
||||
|
|
@ -248,11 +247,6 @@ export default function s3(
|
|||
const { uploadId } = req.params
|
||||
const { key } = req.query
|
||||
|
||||
assert(
|
||||
typeof uploadId === 'string' && uploadId.length > 0,
|
||||
's3: uploadId must be provided.',
|
||||
)
|
||||
|
||||
if (typeof key !== 'string') {
|
||||
res.status(400).json({
|
||||
error:
|
||||
|
|
@ -266,7 +260,7 @@ export default function s3(
|
|||
|
||||
const parts: Part[] = []
|
||||
|
||||
const listPartsPage = (startAt?: string) => {
|
||||
function listPartsPage(startAt?: string) {
|
||||
s3Client
|
||||
.send(
|
||||
new ListPartsCommand({
|
||||
|
|
@ -309,7 +303,7 @@ export default function s3(
|
|||
const partNumber = req.params['partNumber']
|
||||
const key = req.query['key']
|
||||
|
||||
if (typeof uploadId !== 'string' || uploadId.length === 0) {
|
||||
if (uploadId == null || uploadId.length === 0) {
|
||||
res.status(400).json({ error: 's3: uploadId must be provided.' })
|
||||
return
|
||||
}
|
||||
|
|
@ -320,7 +314,7 @@ export default function s3(
|
|||
})
|
||||
return
|
||||
}
|
||||
if (typeof partNumber !== 'string' || !parseInt(partNumber, 10)) {
|
||||
if (partNumber == null || !parseInt(partNumber, 10)) {
|
||||
res.status(400).json({
|
||||
error: 's3: the part number must be a number between 1 and 10000.',
|
||||
})
|
||||
|
|
@ -369,7 +363,7 @@ export default function s3(
|
|||
const key = req.query['key']
|
||||
const partNumbers = req.query['partNumbers']
|
||||
|
||||
if (typeof uploadId !== 'string' || uploadId.length === 0) {
|
||||
if (uploadId == null || uploadId.length === 0) {
|
||||
res.status(400).json({ error: 's3: uploadId must be provided.' })
|
||||
return
|
||||
}
|
||||
|
|
@ -449,11 +443,6 @@ export default function s3(
|
|||
const { uploadId } = req.params
|
||||
const { key } = req.query
|
||||
|
||||
assert(
|
||||
typeof uploadId === 'string' && uploadId.length > 0,
|
||||
's3: uploadId must be provided.',
|
||||
)
|
||||
|
||||
if (typeof key !== 'string') {
|
||||
res.status(400).json({
|
||||
error:
|
||||
|
|
@ -499,11 +488,6 @@ export default function s3(
|
|||
const { key } = req.query
|
||||
const { parts }: { parts: unknown } = req.body
|
||||
|
||||
assert(
|
||||
typeof uploadId === 'string' && uploadId.length > 0,
|
||||
's3: uploadId must be provided.',
|
||||
)
|
||||
|
||||
if (typeof key !== 'string') {
|
||||
res.status(400).json({
|
||||
error:
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ export default async function simpleAuth(
|
|||
next: NextFunction,
|
||||
): Promise<void> {
|
||||
const providerName = req.params['providerName']
|
||||
if (typeof providerName !== 'string' || providerName.length === 0) {
|
||||
if (providerName == null || providerName.length === 0) {
|
||||
res.sendStatus(400)
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ async function thumbnail(
|
|||
next: NextFunction,
|
||||
): Promise<void> {
|
||||
const id = req.params['id']
|
||||
if (typeof id !== 'string' || id.length === 0) {
|
||||
if (id == null) {
|
||||
res.sendStatus(400)
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ export const verifyToken: RequestHandler = (req, res, next) => {
|
|||
}
|
||||
const { secret } = req.companion.options
|
||||
const providerName = req.params['providerName']
|
||||
if (typeof providerName !== 'string' || providerName.length === 0) {
|
||||
if (providerName == null || providerName.length === 0) {
|
||||
res.sendStatus(400)
|
||||
return
|
||||
}
|
||||
|
|
@ -124,9 +124,7 @@ export const verifyToken: RequestHandler = (req, res, next) => {
|
|||
const { providerOptions } = req.companion.options
|
||||
const providerName = req.params['providerName']
|
||||
const providerOption =
|
||||
typeof providerName === 'string'
|
||||
? providerOptions?.[providerName]
|
||||
: undefined
|
||||
providerName != null ? providerOptions?.[providerName] : undefined
|
||||
const key = providerOption?.key
|
||||
if (!key) {
|
||||
logger.info(
|
||||
|
|
@ -148,7 +146,7 @@ export const verifyToken: RequestHandler = (req, res, next) => {
|
|||
// does not fail if token is invalid
|
||||
export const gentleVerifyToken: RequestHandler = (req, res, next) => {
|
||||
const providerName = req.params['providerName']
|
||||
if (typeof providerName !== 'string' || providerName.length === 0) {
|
||||
if (providerName == null || providerName.length === 0) {
|
||||
next()
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,9 +9,7 @@ const port: string | number =
|
|||
|
||||
const { app, companionOptions } = standalone()
|
||||
|
||||
const server = app.listen(port, () => {
|
||||
logger.info(`Welcome to Companion! v${packageJson.version}`)
|
||||
logger.info(`Listening on http://localhost:${port}`)
|
||||
companion.socket(app.listen(port), companionOptions)
|
||||
|
||||
companion.socket(server, companionOptions)
|
||||
})
|
||||
logger.info(`Welcome to Companion! v${packageJson.version}`)
|
||||
logger.info(`Listening on http://localhost:${port}`)
|
||||
|
|
|
|||
|
|
@ -426,26 +426,4 @@ describe('S3 controller', () => {
|
|||
),
|
||||
)
|
||||
})
|
||||
|
||||
test('getUploadParameters supports bracket metadata query format', async () => {
|
||||
const server = await getServer({
|
||||
COMPANION_AWS_KEY: 'test_key',
|
||||
COMPANION_AWS_SECRET: 'test_secret',
|
||||
COMPANION_AWS_BUCKET: 'test-bucket',
|
||||
COMPANION_AWS_REGION: 'us-east-1',
|
||||
})
|
||||
|
||||
return request(server)
|
||||
.get('/s3/params')
|
||||
.query({
|
||||
filename: 'test.txt',
|
||||
type: 'text/plain',
|
||||
'metadata[name]': 'demo-file',
|
||||
})
|
||||
.expect(200)
|
||||
.then((res) => {
|
||||
const fields = res.body.fields as Record<string, string>
|
||||
expect(fields['x-amz-meta-name']).toBe('demo-file')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ async function run({
|
|||
next()
|
||||
})
|
||||
app.use(cors(corsOptions))
|
||||
app.options('/{*splat}', (_req, res) => {
|
||||
app.options('*', (_req, res) => {
|
||||
res.status(204).end()
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ export const getServerWithEmitter = async (
|
|||
authServer.use(
|
||||
session({ secret: 'grant', resave: true, saveUninitialized: true }),
|
||||
)
|
||||
authServer.all('{*splat}/callback', (req, res, next) => {
|
||||
authServer.all('*/callback', (req, res, next) => {
|
||||
if (req.session) {
|
||||
req.session['grant'] = {
|
||||
response: { access_token: grantToken },
|
||||
|
|
@ -109,19 +109,16 @@ export const getServerWithEmitter = async (
|
|||
}
|
||||
next()
|
||||
})
|
||||
authServer.all(
|
||||
['{*splat}/send-token', '{*splat}/redirect'],
|
||||
(req, res, next) => {
|
||||
const state =
|
||||
typeof req.query['state'] === 'string' ? req.query['state'] : null
|
||||
if (req.session) {
|
||||
req.session['grant'] = {
|
||||
dynamic: { state: state ?? 'non-empty-value' },
|
||||
}
|
||||
authServer.all(['*/send-token', '*/redirect'], (req, res, next) => {
|
||||
const state =
|
||||
typeof req.query['state'] === 'string' ? req.query['state'] : null
|
||||
if (req.session) {
|
||||
req.session['grant'] = {
|
||||
dynamic: { state: state ?? 'non-empty-value' },
|
||||
}
|
||||
next()
|
||||
},
|
||||
)
|
||||
}
|
||||
next()
|
||||
})
|
||||
|
||||
const { app, emitter } = standalone()
|
||||
authServer.use(app)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue