You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AuthHandler.js 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. // @flow
  2. import Logger from 'jitsi-meet-logger';
  3. import { openConnection } from '../../../connection';
  4. import {
  5. isTokenAuthEnabled,
  6. getTokenAuthUrl
  7. } from '../../../react/features/authentication/functions';
  8. import { setJWT } from '../../../react/features/base/jwt';
  9. import UIUtil from '../util/UIUtil';
  10. import LoginDialog from './LoginDialog';
  11. let externalAuthWindow;
  12. declare var APP: Object;
  13. const logger = Logger.getLogger(__filename);
  14. /**
  15. * Authenticate using external service or just focus
  16. * external auth window if there is one already.
  17. *
  18. * @param {JitsiConference} room
  19. * @param {string} [lockPassword] password to use if the conference is locked
  20. */
  21. function doExternalAuth(room, lockPassword) {
  22. const config = APP.store.getState()['features/base/config'];
  23. if (externalAuthWindow) {
  24. externalAuthWindow.focus();
  25. return;
  26. }
  27. if (room.isJoined()) {
  28. let getUrl;
  29. if (isTokenAuthEnabled(config)) {
  30. getUrl = Promise.resolve(getTokenAuthUrl(config)(room.getName(), true));
  31. initJWTTokenListener(room);
  32. } else {
  33. getUrl = room.getExternalAuthUrl(true);
  34. }
  35. getUrl.then(url => {
  36. externalAuthWindow = LoginDialog.showExternalAuthDialog(
  37. url,
  38. () => {
  39. externalAuthWindow = null;
  40. if (!isTokenAuthEnabled(config)) {
  41. room.join(lockPassword);
  42. }
  43. }
  44. );
  45. });
  46. } else if (isTokenAuthEnabled(config)) {
  47. redirectToTokenAuthService(room.getName());
  48. } else {
  49. room.getExternalAuthUrl().then(UIUtil.redirect);
  50. }
  51. }
  52. /**
  53. * Redirect the user to the token authentication service for the login to be
  54. * performed. Once complete it is expected that the service will bring the user
  55. * back with "?jwt={the JWT token}" query parameter added.
  56. * @param {string} [roomName] the name of the conference room.
  57. */
  58. export function redirectToTokenAuthService(roomName: string) {
  59. const config = APP.store.getState()['features/base/config'];
  60. // FIXME: This method will not preserve the other URL params that were
  61. // originally passed.
  62. UIUtil.redirect(getTokenAuthUrl(config)(roomName, false));
  63. }
  64. /**
  65. * Initializes 'message' listener that will wait for a JWT token to be received
  66. * from the token authentication service opened in a popup window.
  67. * @param room the name of the conference room.
  68. */
  69. function initJWTTokenListener(room) {
  70. /**
  71. *
  72. */
  73. function listener({ data, source }) {
  74. if (externalAuthWindow !== source) {
  75. logger.warn('Ignored message not coming '
  76. + 'from external authnetication window');
  77. return;
  78. }
  79. let jwt;
  80. if (data && (jwt = data.jwtToken)) {
  81. logger.info('Received JSON Web Token (JWT):', jwt);
  82. APP.store.dispatch(setJWT(jwt));
  83. const roomName = room.getName();
  84. openConnection({
  85. retry: false,
  86. roomName
  87. }).then(connection => {
  88. // Start new connection
  89. const newRoom = connection.initJitsiConference(
  90. roomName, APP.conference._getConferenceOptions());
  91. // Authenticate from the new connection to get
  92. // the session-ID from the focus, which will then be used
  93. // to upgrade current connection's user role
  94. newRoom.room.moderator.authenticate()
  95. .then(() => {
  96. connection.disconnect();
  97. // At this point we'll have session-ID stored in
  98. // the settings. It will be used in the call below
  99. // to upgrade user's role
  100. room.room.moderator.authenticate()
  101. .then(() => {
  102. logger.info('User role upgrade done !');
  103. // eslint-disable-line no-use-before-define
  104. unregister();
  105. })
  106. .catch((err, errCode) => {
  107. logger.error('Authentication failed: ',
  108. err, errCode);
  109. unregister();
  110. });
  111. })
  112. .catch((error, code) => {
  113. unregister();
  114. connection.disconnect();
  115. logger.error(
  116. 'Authentication failed on the new connection',
  117. error, code);
  118. });
  119. }, err => {
  120. unregister();
  121. logger.error('Failed to open new connection', err);
  122. });
  123. }
  124. }
  125. /**
  126. *
  127. */
  128. function unregister() {
  129. window.removeEventListener('message', listener);
  130. }
  131. if (window.addEventListener) {
  132. window.addEventListener('message', listener, false);
  133. }
  134. }
  135. /**
  136. * Uses external service for auth if conference supports that.
  137. * @param {JitsiConference} room
  138. * @param {string} [lockPassword] password to use if the conference is locked
  139. */
  140. function authenticateExternal(room: Object, lockPassword: string) {
  141. const config = APP.store.getState()['features/base/config'];
  142. if (isTokenAuthEnabled(config) || room.isExternalAuthEnabled()) {
  143. doExternalAuth(room, lockPassword);
  144. }
  145. }
  146. /**
  147. * De-authenticate local user.
  148. *
  149. * @param {JitsiConference} room
  150. * @param {string} [lockPassword] password to use if the conference is locked
  151. * @returns {Promise}
  152. */
  153. function logout(room: Object) {
  154. return new Promise(resolve => {
  155. room.room.moderator.logout(resolve);
  156. }).then(url => {
  157. // de-authenticate conference on the fly
  158. if (room.isJoined()) {
  159. room.join();
  160. }
  161. return url;
  162. });
  163. }
  164. export default {
  165. authenticateExternal,
  166. logout
  167. };