Browse Source

add test endpoint for dynamic oauth creds (#4667)

* add test endpoint for dynamic oauth creds

this allows us to test it on uppy.io (we can enable it for one provider like google drive for example)

* add to env.example
Mikael Finstad 1 year ago
parent
commit
b910f84fe2

+ 9 - 0
.env.example

@@ -54,6 +54,12 @@ COMPANION_UNSPLASH_SECRET=***
 COMPANION_ONEDRIVE_KEY=***
 COMPANION_ONEDRIVE_SECRET=****
 
+# To test dynamic Oauth against local companion (which is pointless but allows us to test it without Transloadit's servers), enable these:
+#COMPANION_GOOGLE_KEYS_ENDPOINT=http://localhost:3020/drive/test-dynamic-oauth-credentials?secret=development
+#COMPANION_TEST_DYNAMIC_OAUTH_CREDENTIALS=true
+#COMPANION_TEST_DYNAMIC_OAUTH_CREDENTIALS_SECRET=development
+
+
 # Development environment
 # =======================
 
@@ -73,6 +79,9 @@ VITE_COMPANION_ALLOWED_HOSTS="\.transloadit\.com$"
 VITE_TUS_ENDPOINT=https://tusd.tusdemo.net/files/
 VITE_XHR_ENDPOINT=https://xhr-server.herokuapp.com/upload
 
+# If you want to test dynamic Oauth
+# VITE_COMPANION_GOOGLE_DRIVE_KEYS_PARAMS_CREDENTIALS_NAME=companion-google-drive
+
 VITE_TRANSLOADIT_KEY=***
 VITE_TRANSLOADIT_TEMPLATE=***
 VITE_TRANSLOADIT_SERVICE_URL=https://api2.transloadit.com

+ 21 - 0
packages/@uppy/companion/src/companion.js

@@ -136,6 +136,27 @@ module.exports.app = (optionsArg = {}) => {
 
   app.get('/:providerName/thumbnail/:id', middlewares.hasSessionAndProvider, middlewares.hasOAuthProvider, middlewares.cookieAuthToken, middlewares.verifyToken, controllers.thumbnail)
 
+  // Used for testing dynamic credentials only, normally this would run on a separate server.
+  if (options.testDynamicOauthCredentials) {
+    app.post('/:providerName/test-dynamic-oauth-credentials', (req, res) => {
+      if (req.query.secret !== options.testDynamicOauthCredentialsSecret) throw new Error('Invalid secret')
+      logger.info('Returning dynamic OAuth2 credentials')
+      const { providerName } = req.params
+      // for simplicity, we just return the normal credentials for the provider, but in a real-world scenario,
+      // we would query based on parameters
+      const { key, secret } = options.providerOptions[providerName]
+      res.send({
+        credentials: {
+          key,
+          secret,
+          redirect_uri: providerManager.getGrantConfigForProvider({
+            providerName, companionOptions: options, grantConfig,
+          })?.redirect_uri,
+        },
+      })
+    })
+  }
+
   app.param('providerName', providerManager.getProviderMiddleware(providers, grantConfig))
 
   if (app.get('env') !== 'test') {

+ 9 - 0
packages/@uppy/companion/src/server/provider/index.js

@@ -36,6 +36,15 @@ const providerNameToAuthName = (name, options) => { // eslint-disable-line no-un
   return (providers[name] || {}).authProvider
 }
 
+function getGrantConfigForProvider ({ providerName, companionOptions, grantConfig }) {
+  const authProvider = providerNameToAuthName(providerName, companionOptions)
+
+  if (!isOAuthProvider(authProvider)) return undefined
+  return grantConfig[authProvider]
+}
+
+module.exports.getGrantConfigForProvider = getGrantConfigForProvider
+
 /**
  * adds the desired provider module to the request object,
  * based on the providerName parameter specified

+ 2 - 0
packages/@uppy/companion/src/standalone/helper.js

@@ -176,6 +176,8 @@ const getConfigFromEnv = () => {
     metrics: process.env.COMPANION_HIDE_METRICS !== 'true',
     loggerProcessName: process.env.COMPANION_LOGGER_PROCESS_NAME,
     corsOrigins: getCorsOrigins(),
+    testDynamicOauthCredentials: process.env.COMPANION_TEST_DYNAMIC_OAUTH_CREDENTIALS === 'true',
+    testDynamicOauthCredentialsSecret: process.env.COMPANION_TEST_DYNAMIC_OAUTH_CREDENTIALS_SECRET,
   }
 }
 

+ 22 - 2
private/dev/Dashboard.js

@@ -16,6 +16,7 @@ import ImageEditor from '@uppy/image-editor'
 import DropTarget from '@uppy/drop-target'
 import Audio from '@uppy/audio'
 import Compressor from '@uppy/compressor'
+import GoogleDrive from '@uppy/google-drive'
 /* eslint-enable import/no-extraneous-dependencies */
 
 import generateSignatureIfSecret from './generateSignatureIfSecret.js'
@@ -55,6 +56,25 @@ async function assemblyOptions () {
   })
 }
 
+function getCompanionKeysParams (name) {
+  const {
+    [`VITE_COMPANION_${name}_KEYS_PARAMS_CREDENTIALS_NAME`]: credentialsName,
+    [`VITE_COMPANION_${name}_KEYS_PARAMS_KEY`]: key,
+  } = import.meta.env
+
+  if (credentialsName && key) {
+    // https://github.com/transloadit/uppy/pull/2802#issuecomment-1023093616
+    return {
+      companionKeysParams: {
+        key,
+        credentialsName,
+      },
+    }
+  }
+
+  return {}
+}
+
 // Rest is implementation! Obviously edit as necessary...
 
 export default () => {
@@ -82,7 +102,7 @@ export default () => {
       proudlyDisplayPoweredByUppy: true,
       note: `${JSON.stringify(restrictions)}`,
     })
-    // .use(GoogleDrive, { target: Dashboard, companionUrl: COMPANION_URL, companionAllowedHosts })
+    .use(GoogleDrive, { target: Dashboard, companionUrl: COMPANION_URL, companionAllowedHosts, ...getCompanionKeysParams('GOOGLE_DRIVE') })
     // .use(Instagram, { target: Dashboard, companionUrl: COMPANION_URL, companionAllowedHosts })
     // .use(Dropbox, { target: Dashboard, companionUrl: COMPANION_URL, companionAllowedHosts })
     // .use(Box, { target: Dashboard, companionUrl: COMPANION_URL, companionAllowedHosts })
@@ -93,7 +113,7 @@ export default () => {
     // .use(Unsplash, { target: Dashboard, companionUrl: COMPANION_URL, companionAllowedHosts })
     .use(RemoteSources, {
       companionUrl: COMPANION_URL,
-      sources: ['Box', 'Dropbox', 'Facebook', 'GoogleDrive', 'Instagram', 'OneDrive', 'Unsplash', 'Zoom', 'Url'],
+      sources: ['Box', 'Dropbox', 'Facebook', 'Instagram', 'OneDrive', 'Unsplash', 'Zoom', 'Url'],
       companionAllowedHosts,
     })
     .use(Webcam, {