mirror of
https://github.com/transloadit/uppy.git
synced 2026-07-27 20:27:13 +00:00
send authtoken via query param
This commit is contained in:
parent
eabf6f6576
commit
e8813a8b33
7 changed files with 79 additions and 59 deletions
|
|
@ -1,11 +1,7 @@
|
|||
/**
|
||||
* oAuth callback. Encrypts the access token and sends the new token with the response,
|
||||
* and redirects to redirect url.
|
||||
*/
|
||||
const tokenService = require('../helpers/jwt')
|
||||
const parseUrl = require('url').parse
|
||||
const { hasMatch, sanitizeHtml } = require('../helpers/utils')
|
||||
const oAuthState = require('../helpers/oauth-state')
|
||||
const logger = require('../logger')
|
||||
|
||||
/**
|
||||
|
|
@ -25,43 +21,5 @@ module.exports = function callback (req, res, next) {
|
|||
req.uppy.providerTokens[providerName] = req.query.access_token
|
||||
logger.debug(`Generating auth token for provider ${providerName}.`)
|
||||
const uppyAuthToken = tokenService.generateToken(req.uppy.providerTokens, req.uppy.options.secret)
|
||||
// add the token to cookies for thumbnail/image requests
|
||||
tokenService.addToCookies(res, uppyAuthToken, req.uppy.options)
|
||||
|
||||
const state = (req.session.grant || {}).state
|
||||
if (state) {
|
||||
const origin = oAuthState.getFromState(state, 'origin', req.uppy.options.secret)
|
||||
const allowedClients = req.uppy.options.clients
|
||||
// if no preset clients then allow any client
|
||||
if (!allowedClients || hasMatch(origin, allowedClients) || hasMatch(parseUrl(origin).host, allowedClients)) {
|
||||
const redirect = oAuthState.getFromState(state, 'redirect', req.uppy.options.secret)
|
||||
if (redirect) {
|
||||
// if a redirect value is specified from the client, then redirect there instead
|
||||
const query = (parseUrl(redirect).query ? `&` : `?`) + `uppyAuthToken=${uppyAuthToken}`
|
||||
return res.redirect(`${redirect}${query}`)
|
||||
}
|
||||
return res.send(htmlContent(uppyAuthToken, origin))
|
||||
}
|
||||
}
|
||||
next()
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} token uppy auth token
|
||||
* @param {string} origin url string
|
||||
*/
|
||||
const htmlContent = (token, origin) => {
|
||||
return `
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<script>
|
||||
window.opener.postMessage({token: "${token}"}, "${sanitizeHtml(origin)}")
|
||||
window.close()
|
||||
</script>
|
||||
</head>
|
||||
<body></body>
|
||||
</html>`
|
||||
return res.redirect(req.uppy.buildURL(`/${providerName}/send-token?uppyAuthToken=${uppyAuthToken}`, true))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
module.exports = {
|
||||
authorized: require('./authorized'),
|
||||
callback: require('./callback'),
|
||||
sendToken: require('./send-token'),
|
||||
get: require('./get'),
|
||||
thumbnail: require('./thumbnail'),
|
||||
list: require('./list'),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
/**
|
||||
*
|
||||
* sends auth token to uppy client
|
||||
*/
|
||||
const tokenService = require('../helpers/jwt')
|
||||
const parseUrl = require('url').parse
|
||||
const { hasMatch, sanitizeHtml } = require('../helpers/utils')
|
||||
const oAuthState = require('../helpers/oauth-state')
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {object} req
|
||||
* @param {object} res
|
||||
* @param {function} next
|
||||
*/
|
||||
module.exports = function sendToken (req, res, next) {
|
||||
const uppyAuthToken = req.uppy.authToken
|
||||
// add the token to cookies for thumbnail/image requests
|
||||
tokenService.addToCookies(res, uppyAuthToken, req.uppy.options)
|
||||
|
||||
const state = (req.session.grant || {}).state
|
||||
if (state) {
|
||||
const origin = oAuthState.getFromState(state, 'origin', req.uppy.options.secret)
|
||||
const allowedClients = req.uppy.options.clients
|
||||
// if no preset clients then allow any client
|
||||
if (!allowedClients || hasMatch(origin, allowedClients) || hasMatch(parseUrl(origin).host, allowedClients)) {
|
||||
return res.send(htmlContent(uppyAuthToken, origin))
|
||||
}
|
||||
}
|
||||
next()
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} token uppy auth token
|
||||
* @param {string} origin url string
|
||||
*/
|
||||
const htmlContent = (token, origin) => {
|
||||
return `
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<script>
|
||||
window.opener.postMessage({token: "${token}"}, "${sanitizeHtml(origin)}")
|
||||
window.close()
|
||||
</script>
|
||||
</head>
|
||||
<body></body>
|
||||
</html>`
|
||||
}
|
||||
|
|
@ -87,6 +87,7 @@ module.exports.app = (options = {}) => {
|
|||
app.get('/:providerName/redirect', middlewares.hasSessionAndProvider, controllers.redirect)
|
||||
app.get('/:providerName/logout', middlewares.hasSessionAndProvider, middlewares.gentleVerifyToken, controllers.logout)
|
||||
app.get('/:providerName/authorized', middlewares.hasSessionAndProvider, middlewares.gentleVerifyToken, controllers.authorized)
|
||||
app.get('/:providerName/send-token', middlewares.hasSessionAndProvider, middlewares.verifyToken, controllers.sendToken)
|
||||
app.get('/:providerName/list/:id?', middlewares.hasSessionAndProvider, middlewares.verifyToken, controllers.list)
|
||||
app.post('/:providerName/get/:id', middlewares.hasSessionAndProvider, middlewares.verifyToken, controllers.get)
|
||||
app.get('/:providerName/thumbnail/:id', middlewares.hasSessionAndProvider, middlewares.cookieAuthToken, middlewares.verifyToken, controllers.thumbnail)
|
||||
|
|
@ -217,7 +218,7 @@ const getOptionsMiddleware = (options) => {
|
|||
req.uppy = {
|
||||
options,
|
||||
s3Client,
|
||||
authToken: req.header('uppy-auth-token'),
|
||||
authToken: req.header('uppy-auth-token') || req.query.uppyAuthToken,
|
||||
buildURL: getURLBuilder(options)
|
||||
}
|
||||
next()
|
||||
|
|
|
|||
|
|
@ -66,26 +66,35 @@ describe('download provdier file', () => {
|
|||
})
|
||||
|
||||
describe('test authentication', () => {
|
||||
test('authentication callback redirects to specified url', () => {
|
||||
test('authentication callback redirects to send-token url', () => {
|
||||
return request(authServer)
|
||||
.get('/drive/callback')
|
||||
.set('uppy-auth-token', token)
|
||||
.expect(302)
|
||||
.expect((res) => {
|
||||
expect(res.header['location']).toContain('http://localhost:3020/drive/send-token?uppyAuthToken=')
|
||||
})
|
||||
})
|
||||
|
||||
test('the token gets sent via cookie and html', () => {
|
||||
return request(authServer)
|
||||
.get(`/drive/send-token?uppyAuthToken=${token}`)
|
||||
.expect(200)
|
||||
.expect((res) => {
|
||||
const authToken = res.header['set-cookie'][0].split(';')[0].split('uppyAuthToken=')[1]
|
||||
expect(authToken).toEqual(token)
|
||||
// see mock ../../src/server/helpers/oauth-state above for http://localhost:3020
|
||||
const body = `
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<script>
|
||||
window.opener.postMessage({token: "${authToken}"}, "http://localhost:3020")
|
||||
window.close()
|
||||
</script>
|
||||
</head>
|
||||
<body></body>
|
||||
</html>`
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<script>
|
||||
window.opener.postMessage({token: "${token}"}, "http://localhost:3020")
|
||||
window.close()
|
||||
</script>
|
||||
</head>
|
||||
<body></body>
|
||||
</html>`
|
||||
expect(res.text).toBe(body)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ const session = require('express-session')
|
|||
var authServer = express()
|
||||
|
||||
authServer.use(session({ secret: 'grant', resave: true, saveUninitialized: true }))
|
||||
authServer.all('/drive/callback', (req, res, next) => {
|
||||
authServer.all('/drive/send-token', (req, res, next) => {
|
||||
req.session.grant = {
|
||||
state: 'non-empty-value' }
|
||||
next()
|
||||
|
|
|
|||
|
|
@ -422,7 +422,7 @@ module.exports = class ProviderView {
|
|||
}
|
||||
|
||||
handleAuth () {
|
||||
const authState = btoa(JSON.stringify({ origin: location.origin }))
|
||||
const authState = btoa(JSON.stringify({ origin: location.origin, redirect: 'http://localhost:3' }))
|
||||
const link = `${this.provider.authUrl()}?state=${authState}`
|
||||
|
||||
const authWindow = window.open(link, '_blank')
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue