companion.js 6.2 KB

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