Companion broker (server-side OAuth)

Keep cloud credentials server-side with a self-hosted broker

The in-browser cloud pickers (Drive, Dropbox, OneDrive, Box) use implicit OAuth - the access token lives in client JavaScript. The Companion broker moves the whole OAuth exchange to your own server: the provider client secret and access token never reach the browser, and remote files are proxied through the broker. It is a Node/Express middleware modeled on Uppy Companion, shipped as multipleupload/server/companion with zero new dependencies.

1. Mount the broker (Node / Express)
const express = require('express');
const { createCompanion } = require('multipleupload/server/companion');

app.use(createCompanion({
    basePath: '/companion',
    secret: process.env.COMPANION_SECRET,        // signs state + session cookie
    providers: {
        dropbox:     { clientId: '...', clientSecret: '...', redirectUri: 'https://app/companion/dropbox/callback' },
        box:         { clientId: '...', clientSecret: '...', redirectUri: 'https://app/companion/box/callback' },
        googledrive: { clientId: '...', clientSecret: '...', redirectUri: 'https://app/companion/googledrive/callback' },
        onedrive:    { clientId: '...', clientSecret: '...', redirectUri: 'https://app/companion/onedrive/callback' },
    },
}));
2. Point the client at it
AjaxUploader.configureRemoteSource('companion', {
    companionUrl: '/companion',
    providers: ['dropbox', 'box', 'googledrive', 'onedrive']
});
AjaxUploader.create('#uploader', { remoteSources: ['companion'] });
What the broker guarantees
  • Provider client secret stays on your server - never sent to the browser.
  • OAuth access token is stored server-side (pluggable token store); the browser only holds a signed, HttpOnly session cookie.
  • OAuth state is HMAC-signed for CSRF protection.
  • Remote file bytes are proxied through the broker (server-to-server fetch), then handed to the normal upload pipeline.

Built-in providers: Dropbox, Box, Google Drive, and OneDrive. Add more via the same providers config shape.