Skip to content

Commit

Permalink
@uppy/companion: pass dynamic parameters to grant
Browse files Browse the repository at this point in the history
This allows to define dynamic properties for grant providers.
E.g. `[subdomain]` can be automatically replaced in `authorize_url` and `access_url`.
For that to work we need to include the dynamic property in the redirect
to the grant middleware. We merge the grantConfig back to the providerConfig,
so we can determine the required query params based on the `dynamic` property.
This avoids an attacker overriding unexpected properties (if we simply
serialize and pass along `query`)
  • Loading branch information
dschmidt committed Jul 6, 2023
1 parent bb0df7c commit 1da5c7d
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 1 deletion.
1 change: 1 addition & 0 deletions packages/@uppy/companion/src/companion.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ module.exports.app = (optionsArg = {}) => {
const providers = providerManager.getDefaultProviders()

providerManager.addProviderOptions(options, grantConfig)
options.providerOptions = merge(options.providerOptions, grantConfig)

const { customProviders } = options
if (customProviders) {
Expand Down
12 changes: 11 additions & 1 deletion packages/@uppy/companion/src/server/controllers/connect.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
const atob = require('atob')
const oAuthState = require('../helpers/oauth-state')

const queryString = (params, prefix = '') => {
const str = new URLSearchParams(params).toString()
return str ? `${prefix}${str}` : ''
}

/**
* initializes the oAuth flow for a provider.
*
Expand All @@ -27,5 +32,10 @@ module.exports = function connect (req, res) {
state = oAuthState.addToState(state, { preAuthToken: req.query.uppyPreAuthToken }, secret)
}

res.redirect(req.companion.buildURL(`/connect/${req.companion.provider.authProvider}?state=${state}`, true))
const providerName = req.companion.provider.authProvider
const qs = queryString(Object.fromEntries(
req.companion.options.providerOptions[providerName]?.dynamic?.map(p => [p, req.query[p]]) || [],
), '&')

res.redirect(req.companion.buildURL(`/connect/${providerName}?state=${state}${qs}`, true))
}

0 comments on commit 1da5c7d

Please sign in to comment.