connect.js 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. const atob = require('atob')
  2. const oAuthState = require('../helpers/oauth-state')
  3. const queryString = (params, prefix = '?') => {
  4. const str = new URLSearchParams(params).toString()
  5. return str ? `${prefix}${str}` : ''
  6. }
  7. /**
  8. * initializes the oAuth flow for a provider.
  9. *
  10. * @param {object} req
  11. * @param {object} res
  12. */
  13. module.exports = function connect(req, res) {
  14. const { secret } = req.companion.options
  15. const stateObj = oAuthState.generateState()
  16. if (req.query.state) {
  17. const { origin } = JSON.parse(atob(req.query.state))
  18. stateObj.origin = origin
  19. }
  20. if (req.companion.options.server.oauthDomain) {
  21. stateObj.companionInstance = req.companion.buildURL('', true)
  22. }
  23. if (req.query.uppyPreAuthToken) {
  24. stateObj.preAuthToken = req.query.uppyPreAuthToken
  25. }
  26. const state = oAuthState.encodeState(stateObj, secret)
  27. const { providerClass, providerGrantConfig } = req.companion
  28. // pass along grant's dynamic config (if specified for the provider in its grant config `dynamic` section)
  29. // this is needed for things like custom oauth domain (e.g. webdav)
  30. const grantDynamicConfig = Object.fromEntries(providerGrantConfig.dynamic?.flatMap((dynamicKey) => {
  31. const queryValue = req.query[dynamicKey];
  32. // note: when using credentialsURL (dynamic oauth credentials), dynamic has ['key', 'secret', 'redirect_uri']
  33. // but in that case, query string is empty, so we need to only fetch these parameters from QS if they exist.
  34. if (!queryValue) return []
  35. return [[
  36. dynamicKey, queryValue
  37. ]]
  38. }) || [])
  39. const { authProvider } = providerClass
  40. const qs = queryString({
  41. ...grantDynamicConfig,
  42. state,
  43. })
  44. // Now we redirect to grant's /connect endpoint, see `app.use(Grant(grantConfig))`
  45. res.redirect(req.companion.buildURL(`/connect/${authProvider}${qs}`, true))
  46. }