bigbluebutton-Github/bigbluebutton-html5/imports/ui/services/auth/index.js

190 lines
4.5 KiB
JavaScript
Raw Normal View History

/* eslint prefer-promise-reject-errors: 0 */
2017-03-11 02:33:46 +08:00
import { Tracker } from 'meteor/tracker';
2016-07-07 20:50:32 +08:00
import Storage from '/imports/ui/services/storage/session';
2017-03-11 02:33:46 +08:00
import Users from '/imports/api/users';
2017-10-24 20:58:46 +08:00
import { makeCall, log } from '/imports/ui/services/api';
2017-05-05 22:30:15 +08:00
const CONNECTION_TIMEOUT = Meteor.settings.public.app.connectionTimeout;
class Auth {
constructor() {
this._meetingID = Storage.getItem('meetingID');
this._userID = Storage.getItem('userID');
this._authToken = Storage.getItem('authToken');
2017-07-19 20:44:47 +08:00
this._sessionToken = Storage.getItem('sessionToken');
2017-07-15 00:59:02 +08:00
this._logoutURL = Storage.getItem('logoutURL');
2017-03-11 02:33:46 +08:00
this._loggedIn = {
value: false,
2017-06-03 03:25:02 +08:00
tracker: new Tracker.Dependency(),
2017-03-11 02:33:46 +08:00
};
}
get meetingID() {
return this._meetingID;
}
set meetingID(meetingID) {
this._meetingID = meetingID;
Storage.setItem('meetingID', this._meetingID);
}
2017-07-19 20:44:47 +08:00
set sessionToken(sessionToken) {
this._sessionToken = sessionToken;
Storage.setItem('sessionToken', this._sessionToken);
}
get sessionToken() {
return this._sessionToken;
}
get userID() {
return this._userID;
}
set userID(userID) {
this._userID = userID;
Storage.setItem('userID', this._userID);
}
2016-06-18 06:15:11 +08:00
get token() {
return this._authToken;
2016-06-25 07:09:32 +08:00
}
2016-06-18 06:15:11 +08:00
set token(authToken) {
this._authToken = authToken;
Storage.setItem('authToken', this._authToken);
}
2017-07-15 00:59:02 +08:00
set logoutURL(logoutURL) {
this._logoutURL = logoutURL;
Storage.setItem('logoutURL', this._logoutURL);
}
get logoutURL() {
return this._logoutURL;
}
2017-03-10 03:50:21 +08:00
get loggedIn() {
2017-03-11 02:33:46 +08:00
this._loggedIn.tracker.depend();
return this._loggedIn.value;
2017-03-10 03:50:21 +08:00
}
2017-03-11 02:33:46 +08:00
set loggedIn(value) {
this._loggedIn.value = value;
this._loggedIn.tracker.changed();
}
get credentials() {
return {
meetingId: this.meetingID,
requesterUserId: this.userID,
requesterToken: this.token,
2017-07-15 00:59:02 +08:00
logoutURL: this.logoutURL,
2017-07-19 20:44:47 +08:00
sessionToken: this.sessionToken,
};
}
2017-07-19 20:44:47 +08:00
set(meetingId, requesterUserId, requesterToken, logoutURL, sessionToken) {
2017-04-27 03:56:29 +08:00
this.meetingID = meetingId;
this.userID = requesterUserId;
this.token = requesterToken;
2017-07-15 00:59:02 +08:00
this.logoutURL = logoutURL;
2017-07-19 20:44:47 +08:00
this.sessionToken = sessionToken;
2017-04-27 03:56:29 +08:00
}
2017-07-15 00:59:02 +08:00
clearCredentials(...args) {
this.meetingID = null;
this.userID = null;
this.token = null;
this.loggedIn = false;
2017-07-15 00:59:02 +08:00
this.logoutURL = null;
2017-07-19 20:44:47 +08:00
this.sessionToken = null;
2017-07-15 00:59:02 +08:00
return Promise.resolve(...args);
2017-06-03 03:25:02 +08:00
}
logout() {
if (!this.loggedIn) {
return Promise.resolve();
}
2017-07-15 00:59:02 +08:00
return new Promise((resolve) => {
const credentialsSnapshot = {
meetingId: this.meetingID,
requesterUserId: this.userID,
requesterToken: this.token,
};
// make sure users who did not connect are not added to the meeting
// do **not** use the custom call - it relies on expired data
2017-07-15 00:59:02 +08:00
Meteor.call('userLogout', credentialsSnapshot, (error) => {
if (error) {
2017-10-24 20:58:46 +08:00
log('error', error, { credentials: credentialsSnapshot });
} else {
this.fetchLogoutUrl()
2017-07-15 00:59:02 +08:00
.then(this.clearCredentials)
.then(resolve);
}
});
});
2017-06-03 03:25:02 +08:00
}
2017-04-27 03:56:29 +08:00
authenticate(force) {
if (this.loggedIn && !force) return Promise.resolve();
2017-04-18 01:14:31 +08:00
if (!(this.meetingID && this.userID && this.token)) {
return Promise.reject({
error: 401,
description: 'Authentication failed due to missing credentials.',
2017-03-11 02:33:46 +08:00
});
}
return this.validateAuthToken();
2017-03-11 02:33:46 +08:00
}
validateAuthToken() {
2017-03-11 02:33:46 +08:00
return new Promise((resolve, reject) => {
let computation = null;
2017-03-11 02:33:46 +08:00
const validationTimeout = setTimeout(() => {
computation.stop();
2017-04-18 01:14:31 +08:00
reject({
error: 401,
2017-04-18 01:14:31 +08:00
description: 'Authentication timeout.',
});
2017-05-05 22:30:15 +08:00
}, CONNECTION_TIMEOUT);
2017-03-11 02:33:46 +08:00
Tracker.autorun((c) => {
computation = c;
const subscription = Meteor.subscribe('current-user', this.credentials);
if (!subscription.ready()) return;
2017-03-11 02:33:46 +08:00
const selector = { meetingId: this.meetingID, userId: this.userID };
const User = Users.findOne(selector);
// Skip in case the user is not in the collection yet or is a dummy user
if (!User || !('intId' in User)) return;
if (User.validated === true) {
computation.stop();
clearTimeout(validationTimeout);
this.loggedIn = true;
resolve();
}
2017-03-11 02:33:46 +08:00
});
makeCall('validateAuthToken');
2017-03-11 02:33:46 +08:00
});
}
fetchLogoutUrl() {
2017-07-15 00:59:02 +08:00
return Promise.resolve(this._logoutURL);
}
2017-06-03 03:25:02 +08:00
}
2016-06-29 02:50:44 +08:00
2017-06-03 03:25:02 +08:00
const AuthSingleton = new Auth();
export default AuthSingleton;