123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422 |
- /* global jest:false, test:false, expect:false, describe:false */
- jest.mock('tus-js-client')
- jest.mock('purest')
- jest.mock('../../src/server/helpers/oauth-state', () => {
- return {
- generateState: () => 'some-cool-nice-encrytpion',
- addToState: () => 'some-cool-nice-encrytpion',
- getFromState: (state, key) => {
- if (state === 'state-with-invalid-instance-url') {
- return 'http://localhost:3452'
- }
- if (state === 'state-with-older-version' && key === 'clientVersion') {
- return '@uppy/companion-client=1.0.1'
- }
- if (state === 'state-with-newer-version' && key === 'clientVersion') {
- return '@uppy/companion-client=1.0.3'
- }
- if (state === 'state-with-newer-version-old-style' && key === 'clientVersion') {
- return 'companion-client:1.0.2'
- }
- return 'http://localhost:3020'
- }
- }
- })
- const request = require('supertest')
- const tokenService = require('../../src/server/helpers/jwt')
- const { getServer } = require('../mockserver')
- const authServer = getServer()
- const authData = {
- dropbox: 'token value',
- drive: 'token value'
- }
- const token = tokenService.generateToken(authData, process.env.COMPANION_SECRET)
- const OAUTH_STATE = 'some-cool-nice-encrytpion'
- describe('set i-am header', () => {
- test('set i-am header in response', () => {
- return request(authServer)
- .get('/dropbox/list/')
- .set('uppy-auth-token', token)
- .expect(200)
- .then((res) => expect(res.header['i-am']).toBe('http://localhost:3020'))
- })
- })
- describe('list provider files', () => {
- test('list files for dropbox', () => {
- return request(authServer)
- .get('/dropbox/list/')
- .set('uppy-auth-token', token)
- .expect(200)
- .then((res) => expect(res.body.username).toBe('foo@bar.com'))
- })
- test('list files for google drive', () => {
- return request(authServer)
- .get('/drive/list/')
- .set('uppy-auth-token', token)
- .expect(200)
- .then((res) => expect(res.body.username).toBe('ife@bala.com'))
- })
- })
- describe('validate upload data', () => {
- test('invalid upload protocol gets rejected', () => {
- return request(authServer)
- .post('/drive/get/README.md')
- .set('uppy-auth-token', token)
- .set('Content-Type', 'application/json')
- .send({
- endpoint: 'http://url.myendpoint.com/files',
- protocol: 'tusInvalid'
- })
- .expect(400)
- .then((res) => expect(res.body.message).toBe('unsupported protocol specified'))
- })
- test('invalid upload fieldname gets rejected', () => {
- return request(authServer)
- .post('/drive/get/README.md')
- .set('uppy-auth-token', token)
- .set('Content-Type', 'application/json')
- .send({
- endpoint: 'http://url.myendpoint.com/files',
- protocol: 'tus',
- fieldname: 390
- })
- .expect(400)
- .then((res) => expect(res.body.message).toBe('fieldname must be a string'))
- })
- test('invalid upload metadata gets rejected', () => {
- return request(authServer)
- .post('/drive/get/README.md')
- .set('uppy-auth-token', token)
- .set('Content-Type', 'application/json')
- .send({
- endpoint: 'http://url.myendpoint.com/files',
- protocol: 'tus',
- metadata: 'I am a string instead of object'
- })
- .expect(400)
- .then((res) => expect(res.body.message).toBe('metadata must be an object'))
- })
- test('invalid upload headers get rejected', () => {
- return request(authServer)
- .post('/drive/get/README.md')
- .set('uppy-auth-token', token)
- .set('Content-Type', 'application/json')
- .send({
- endpoint: 'http://url.myendpoint.com/files',
- protocol: 'tus',
- headers: 'I am a string instead of object'
- })
- .expect(400)
- .then((res) => expect(res.body.message).toBe('headers must be an object'))
- })
- test('invalid upload HTTP Method gets rejected', () => {
- return request(authServer)
- .post('/drive/get/README.md')
- .set('uppy-auth-token', token)
- .set('Content-Type', 'application/json')
- .send({
- endpoint: 'http://url.myendpoint.com/files',
- protocol: 'tus',
- httpMethod: 'DELETE'
- })
- .expect(400)
- .then((res) => expect(res.body.message).toBe('unsupported HTTP METHOD specified'))
- })
- test('valid upload data is allowed - tus', () => {
- return request(authServer)
- .post('/drive/get/README.md')
- .set('uppy-auth-token', token)
- .set('Content-Type', 'application/json')
- .send({
- endpoint: 'http://url.myendpoint.com/files',
- protocol: 'tus',
- httpMethod: 'POST',
- headers: {
- customheader: 'header value'
- },
- metadata: {
- mymetadata: 'matadata value'
- },
- fieldname: 'uploadField'
- })
- .expect(200)
- })
- test('valid upload data is allowed - s3-multipart', () => {
- return request(authServer)
- .post('/drive/get/README.md')
- .set('uppy-auth-token', token)
- .set('Content-Type', 'application/json')
- .send({
- endpoint: 'http://url.myendpoint.com/files',
- protocol: 's3-multipart',
- httpMethod: 'PUT',
- headers: {
- customheader: 'header value'
- },
- metadata: {
- mymetadata: 'matadata value'
- },
- fieldname: 'uploadField'
- })
- .expect(200)
- })
- })
- describe('download provdier file', () => {
- test('specified file gets downloaded from provider', () => {
- return request(authServer)
- .post('/drive/get/README.md')
- .set('uppy-auth-token', token)
- .set('Content-Type', 'application/json')
- .send({
- endpoint: 'http://master.tus.io/files',
- protocol: 'tus'
- })
- .expect(200)
- .then((res) => expect(res.body.token).toBeTruthy())
- })
- })
- describe('test authentication', () => {
- test('authentication callback redirects to send-token url', () => {
- return request(authServer)
- .get('/drive/callback')
- .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', () => {
- // see mock ../../src/server/helpers/oauth-state above for state values
- return request(authServer)
- .get(`/dropbox/send-token?uppyAuthToken=${token}&state=state-with-newer-version`)
- .expect(200)
- .expect((res) => {
- const authToken = res.header['set-cookie'][0].split(';')[0].split('uppyAuthToken--dropbox=')[1]
- expect(authToken).toEqual(token)
- const body = `
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8" />
- <script>
- window.opener.postMessage(JSON.stringify({token: "${token}"}), "http://localhost:3020")
- window.close()
- </script>
- </head>
- <body></body>
- </html>`
- expect(res.text).toBe(body)
- })
- })
- test('the token gets to older clients without stringify', () => {
- // see mock ../../src/server/helpers/oauth-state above for state values
- return request(authServer)
- .get(`/drive/send-token?uppyAuthToken=${token}&state=state-with-older-version`)
- .expect(200)
- .expect((res) => {
- const body = `
- <!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)
- })
- })
- test('the token gets sent to newer clients with old version style', () => {
- // see mock ../../src/server/helpers/oauth-state above for state values
- return request(authServer)
- .get(`/drive/send-token?uppyAuthToken=${token}&state=state-with-newer-version-old-style`)
- .expect(200)
- .expect((res) => {
- const body = `
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8" />
- <script>
- window.opener.postMessage(JSON.stringify({token: "${token}"}), "http://localhost:3020")
- window.close()
- </script>
- </head>
- <body></body>
- </html>`
- expect(res.text).toBe(body)
- })
- })
- test('logout provider', () => {
- return request(authServer)
- .get('/drive/logout/')
- .set('uppy-auth-token', token)
- .expect(200)
- .then((res) => expect(res.body.ok).toBe(true))
- })
- })
- describe('connect to provider', () => {
- test('connect to dropbox via grant.js endpoint', () => {
- return request(authServer)
- .get('/dropbox/connect?foo=bar')
- .set('uppy-auth-token', token)
- .expect(302)
- .expect('Location', `http://localhost:3020/connect/dropbox?state=${OAUTH_STATE}`)
- })
- test('connect to drive via grant.js endpoint', () => {
- return request(authServer)
- .get('/drive/connect?foo=bar')
- .set('uppy-auth-token', token)
- .expect(302)
- .expect('Location', `http://localhost:3020/connect/google?state=${OAUTH_STATE}`)
- })
- })
- describe('handle master oauth redirect', () => {
- const serverWithMasterOauth = getServer({
- COMPANION_OAUTH_DOMAIN: 'localhost:3040'
- })
- test('redirect to a valid uppy instance', () => {
- return request(serverWithMasterOauth)
- .get(`/dropbox/redirect?state=${OAUTH_STATE}`)
- .set('uppy-auth-token', token)
- .expect(302)
- .expect('Location', `http://localhost:3020/connect/dropbox/callback?state=${OAUTH_STATE}`)
- })
- test('do not redirect to invalid uppy instances', () => {
- const state = 'state-with-invalid-instance-url' // see mock ../../src/server/helpers/oauth-state above
- return request(serverWithMasterOauth)
- .get(`/dropbox/redirect?state=${state}`)
- .set('uppy-auth-token', token)
- .expect(400)
- })
- })
- // @todo consider moving this to a separate test file (zoom.js maybe)
- // in general, we should consider testing all providers endpoints separately
- describe('handle deauthorization callback', () => {
- test('providers without support for callback endpoint', () => {
- return request(authServer)
- .post('/dropbox/deauthorization/callback')
- .set('Content-Type', 'application/json')
- .send({
- foo: 'bar'
- })
- // @todo consider receiving 501 instead
- .expect(500)
- })
- test('validate that request credentials match', () => {
- return request(authServer)
- .post('/zoom/deauthorization/callback')
- .set('Content-Type', 'application/json')
- .set('Authorization', 'wrong-verfication-token')
- .send({
- event: 'app_deauthorized',
- payload: {
- user_data_retention: 'false',
- account_id: 'EabCDEFghiLHMA',
- user_id: 'z9jkdsfsdfjhdkfjQ',
- signature: '827edc3452044f0bc86bdd5684afb7d1e6becfa1a767f24df1b287853cf73000',
- deauthorization_time: '2019-06-17T13:52:28.632Z',
- client_id: 'ADZ9k9bTWmGUoUbECUKU_a'
- }
- })
- .expect(400)
- })
- test('validate request credentials is present', () => {
- // Authorization header is absent
- return request(authServer)
- .post('/zoom/deauthorization/callback')
- .set('Content-Type', 'application/json')
- .send({
- event: 'app_deauthorized',
- payload: {
- user_data_retention: 'false',
- account_id: 'EabCDEFghiLHMA',
- user_id: 'z9jkdsfsdfjhdkfjQ',
- signature: '827edc3452044f0bc86bdd5684afb7d1e6becfa1a767f24df1b287853cf73000',
- deauthorization_time: '2019-06-17T13:52:28.632Z',
- client_id: 'ADZ9k9bTWmGUoUbECUKU_a'
- }
- })
- .expect(400)
- })
- test('validate request content', () => {
- return request(authServer)
- .post('/zoom/deauthorization/callback')
- .set('Content-Type', 'application/json')
- .set('Authorization', 'zoom_verfication_token')
- .send({
- invalid: 'content'
- })
- .expect(400)
- })
- test('validate request content (event name)', () => {
- return request(authServer)
- .post('/zoom/deauthorization/callback')
- .set('Content-Type', 'application/json')
- .set('Authorization', 'zoom_verfication_token')
- .send({
- event: 'wrong_event_name',
- payload: {
- user_data_retention: 'false',
- account_id: 'EabCDEFghiLHMA',
- user_id: 'z9jkdsfsdfjhdkfjQ',
- signature: '827edc3452044f0bc86bdd5684afb7d1e6becfa1a767f24df1b287853cf73000',
- deauthorization_time: '2019-06-17T13:52:28.632Z',
- client_id: 'ADZ9k9bTWmGUoUbECUKU_a'
- }
- })
- .expect(400)
- })
- test('allow valid request', () => {
- return request(authServer)
- .post('/zoom/deauthorization/callback')
- .set('Content-Type', 'application/json')
- .set('Authorization', 'zoom_verfication_token')
- .send({
- event: 'app_deauthorized',
- payload: {
- user_data_retention: 'false',
- account_id: 'EabCDEFghiLHMA',
- user_id: 'z9jkdsfsdfjhdkfjQ',
- signature: '827edc3452044f0bc86bdd5684afb7d1e6becfa1a767f24df1b287853cf73000',
- deauthorization_time: '2019-06-17T13:52:28.632Z',
- client_id: 'ADZ9k9bTWmGUoUbECUKU_a'
- }
- })
- .expect(200)
- })
- })
|