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 21, 2023
1 parent ca3b12c commit 968fe8a
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 968fe8a

Please sign in to comment.