Skip to content

Commit

Permalink
Onedrive refresh tokens (#4655)
Browse files Browse the repository at this point in the history
* handle google drive refresh token revoked

* implement onedrive refresh tokens #2721
  • Loading branch information
mifi authored Sep 6, 2023
1 parent a4b8683 commit 682ae7f
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 5 deletions.
2 changes: 1 addition & 1 deletion packages/@uppy/companion/src/companion.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ module.exports.app = (optionsArg = {}) => {

app.get('/:providerName/thumbnail/:id', middlewares.hasSessionAndProvider, middlewares.hasOAuthProvider, middlewares.cookieAuthToken, middlewares.verifyToken, controllers.thumbnail)

app.param('providerName', providerManager.getProviderMiddleware(providers))
app.param('providerName', providerManager.getProviderMiddleware(providers, grantConfig))

if (app.get('env') !== 'test') {
jobs.startCleanUpJob(options.filePath)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ async function refreshToken (req, res, next) {
const { providerName } = req.params

const { key: clientId, secret: clientSecret } = req.companion.options.providerOptions[providerName]
const { redirect_uri: redirectUri } = req.companion.providerGrantConfig

const providerTokens = req.companion.allProvidersTokens[providerName]

Expand All @@ -20,7 +21,7 @@ async function refreshToken (req, res, next) {

try {
const data = await req.companion.provider.refreshToken({
clientId, clientSecret, refreshToken: providerTokens.refreshToken,
redirectUri, clientId, clientSecret, refreshToken: providerTokens.refreshToken,
})

const newAllProvidersTokens = {
Expand Down
7 changes: 5 additions & 2 deletions packages/@uppy/companion/src/server/provider/drive/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ class Drive extends Provider {

async refreshToken ({ clientId, clientSecret, refreshToken }) {
return this.#withErrorHandling('provider.drive.token.refresh.error', async () => {
const { access_token: accessToken } = await getOauthClient().post('token', { form: { refresh_token: refreshToken, grant_type: 'refresh_token', client_id: clientId, client_secret: clientSecret } }).json()
const { access_token: accessToken } = await getOauthClient().post('token', { responseType: 'json', form: { refresh_token: refreshToken, grant_type: 'refresh_token', client_id: clientId, client_secret: clientSecret } }).json()
return { accessToken }
})
}
Expand All @@ -181,7 +181,10 @@ class Drive extends Provider {
fn,
tag,
providerName: this.authProvider,
isAuthError: (response) => response.statusCode === 401,
isAuthError: (response) => (
response.statusCode === 401
|| (response.statusCode === 400 && response.body?.error === 'invalid_grant') // Refresh token has expired or been revoked
),
getJsonErrorMessage: (body) => body?.error?.message,
})
}
Expand Down
3 changes: 2 additions & 1 deletion packages/@uppy/companion/src/server/provider/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const providerNameToAuthName = (name, options) => { // eslint-disable-line no-un
*
* @param {Record<string, typeof Provider>} providers
*/
module.exports.getProviderMiddleware = (providers) => {
module.exports.getProviderMiddleware = (providers, grantConfig) => {
/**
*
* @param {object} req
Expand All @@ -56,6 +56,7 @@ module.exports.getProviderMiddleware = (providers) => {
const { allowLocalUrls } = req.companion.options
req.companion.provider = new ProviderClass({ providerName, allowLocalUrls })
req.companion.providerClass = ProviderClass
req.companion.providerGrantConfig = grantConfig[ProviderClass.authProvider]

if (isOAuthProvider(ProviderClass.authProvider)) {
req.companion.getProviderCredentials = getCredentialsResolver(providerName, req.companion.options, req)
Expand Down
12 changes: 12 additions & 0 deletions packages/@uppy/companion/src/server/provider/onedrive/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ const getClient = ({ token }) => got.extend({
},
})

const getOauthClient = () => got.extend({
prefixUrl: 'https://login.live.com',
})

const getRootPath = (query) => (query.driveId ? `drives/${query.driveId}` : 'me/drive')

/**
Expand Down Expand Up @@ -81,9 +85,17 @@ class OneDrive extends Provider {

// eslint-disable-next-line class-methods-use-this
async logout () {
// apparently M$ doesn't support programmatic oauth2 revoke
return { revoked: false, manual_revoke_url: 'https://account.live.com/consent/Manage' }
}

async refreshToken ({ clientId, clientSecret, refreshToken, redirectUri }) {
return this.#withErrorHandling('provider.onedrive.token.refresh.error', async () => {
const { access_token: accessToken } = await getOauthClient().post('oauth20_token.srf', { responseType: 'json', form: { refresh_token: refreshToken, grant_type: 'refresh_token', client_id: clientId, client_secret: clientSecret, redirect_uri: redirectUri } }).json()
return { accessToken }
})
}

async #withErrorHandling (tag, fn) {
return withProviderErrorHandling({
fn,
Expand Down

0 comments on commit 682ae7f

Please sign in to comment.