companion.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /* global jest:false, test:false, expect:false, describe:false */
  2. jest.mock('tus-js-client')
  3. jest.mock('purest')
  4. jest.mock('../../src/server/helpers/oauth-state', () => {
  5. return {
  6. generateState: () => 'some-cool-nice-encrytpion',
  7. addToState: () => 'some-cool-nice-encrytpion',
  8. getFromState: (state, key) => {
  9. if (state === 'state-with-invalid-instance-url') {
  10. return 'http://localhost:3452'
  11. }
  12. if (state === 'state-with-older-version' && key === 'clientVersion') {
  13. return '@uppy/companion-client:1.0.1'
  14. }
  15. if (state === 'state-with-newer-version' && key === 'clientVersion') {
  16. return '@uppy/companion-client:1.0.3'
  17. }
  18. return 'http://localhost:3020'
  19. }
  20. }
  21. })
  22. const request = require('supertest')
  23. const tokenService = require('../../src/server/helpers/jwt')
  24. const { authServer } = require('../mockserver')
  25. const authData = {
  26. dropbox: 'token value',
  27. drive: 'token value'
  28. }
  29. const token = tokenService.generateToken(authData, process.env.COMPANION_SECRET)
  30. const OAUTH_STATE = 'some-cool-nice-encrytpion'
  31. describe('set i-am header', () => {
  32. test('set i-am header in response', () => {
  33. return request(authServer)
  34. .get('/dropbox/list/')
  35. .set('uppy-auth-token', token)
  36. .expect(200)
  37. .then((res) => expect(res.header['i-am']).toBe('http://localhost:3020'))
  38. })
  39. })
  40. describe('list provider files', () => {
  41. test('list files for dropbox', () => {
  42. return request(authServer)
  43. .get('/dropbox/list/')
  44. .set('uppy-auth-token', token)
  45. .expect(200)
  46. .then((res) => expect(res.body.username).toBe('foo@bar.com'))
  47. })
  48. test('list files for google drive', () => {
  49. return request(authServer)
  50. .get('/drive/list/')
  51. .set('uppy-auth-token', token)
  52. .expect(200)
  53. .then((res) => expect(res.body.username).toBe('ife@bala.com'))
  54. })
  55. })
  56. describe('download provdier file', () => {
  57. test('specified file gets downloaded from provider', () => {
  58. return request(authServer)
  59. .post('/drive/get/README.md')
  60. .set('uppy-auth-token', token)
  61. .set('Content-Type', 'application/json')
  62. .send({
  63. endpoint: 'http://master.tus.com/files',
  64. protocol: 'tus'
  65. })
  66. .expect(200)
  67. .then((res) => expect(res.body.token).toBeTruthy())
  68. })
  69. })
  70. describe('test authentication', () => {
  71. test('authentication callback redirects to send-token url', () => {
  72. return request(authServer)
  73. .get('/drive/callback')
  74. .expect(302)
  75. .expect((res) => {
  76. expect(res.header['location']).toContain('http://localhost:3020/drive/send-token?uppyAuthToken=')
  77. })
  78. })
  79. test('the token gets sent via cookie and html', () => {
  80. // see mock ../../src/server/helpers/oauth-state above for state values
  81. return request(authServer)
  82. .get(`/drive/send-token?uppyAuthToken=${token}&state=state-with-newer-version`)
  83. .expect(200)
  84. .expect((res) => {
  85. const authToken = res.header['set-cookie'][0].split(';')[0].split('uppyAuthToken--google=')[1]
  86. expect(authToken).toEqual(token)
  87. const body = `
  88. <!DOCTYPE html>
  89. <html>
  90. <head>
  91. <meta charset="utf-8" />
  92. <script>
  93. window.opener.postMessage(JSON.stringify({token: "${token}"}), "http://localhost:3020")
  94. window.close()
  95. </script>
  96. </head>
  97. <body></body>
  98. </html>`
  99. expect(res.text).toBe(body)
  100. })
  101. })
  102. test('the token gets sent to html based on version', () => {
  103. // see mock ../../src/server/helpers/oauth-state above for state values
  104. return request(authServer)
  105. .get(`/drive/send-token?uppyAuthToken=${token}&state=state-with-older-version`)
  106. .expect(200)
  107. .expect((res) => {
  108. const body = `
  109. <!DOCTYPE html>
  110. <html>
  111. <head>
  112. <meta charset="utf-8" />
  113. <script>
  114. window.opener.postMessage({token: "${token}"}, "http://localhost:3020")
  115. window.close()
  116. </script>
  117. </head>
  118. <body></body>
  119. </html>`
  120. expect(res.text).toBe(body)
  121. })
  122. })
  123. test('logout provider', () => {
  124. return request(authServer)
  125. .get('/drive/logout/')
  126. .set('uppy-auth-token', token)
  127. .expect(200)
  128. .then((res) => expect(res.body.ok).toBe(true))
  129. })
  130. })
  131. describe('connect to provider', () => {
  132. test('connect to dropbox via grant.js endpoint', () => {
  133. return request(authServer)
  134. .get('/dropbox/connect?foo=bar')
  135. .set('uppy-auth-token', token)
  136. .expect(302)
  137. .expect('Location', `http://localhost:3020/connect/dropbox?state=${OAUTH_STATE}`)
  138. })
  139. test('connect to drive via grant.js endpoint', () => {
  140. return request(authServer)
  141. .get('/drive/connect?foo=bar')
  142. .set('uppy-auth-token', token)
  143. .expect(302)
  144. .expect('Location', `http://localhost:3020/connect/google?state=${OAUTH_STATE}`)
  145. })
  146. })
  147. describe('handle oauth redirect', () => {
  148. test('redirect to a valid uppy instance', () => {
  149. return request(authServer)
  150. .get(`/dropbox/redirect?state=${OAUTH_STATE}`)
  151. .set('uppy-auth-token', token)
  152. .expect(302)
  153. .expect('Location', `http://localhost:3020/connect/dropbox/callback?state=${OAUTH_STATE}`)
  154. })
  155. test('do not redirect to invalid uppy instances', () => {
  156. const state = 'state-with-invalid-instance-url' // see mock ../../src/server/helpers/oauth-state above
  157. return request(authServer)
  158. .get(`/dropbox/redirect?state=${state}`)
  159. .set('uppy-auth-token', token)
  160. .expect(400)
  161. })
  162. })