Fix the html5 2.0 user logout

This commit is contained in:
Klaus 2017-07-14 13:59:02 -03:00
parent 665e24c131
commit baf36d9d5f
3 changed files with 71 additions and 67 deletions

View File

@ -10,7 +10,7 @@ const OFFLINE_CONNECTION_STATUS = 'offline';
export default function userLeaving(credentials, userId) {
const REDIS_CONFIG = Meteor.settings.redis;
const CHANNEL = REDIS_CONFIG.channels.toBBBApps.users;
const CHANNEL = REDIS_CONFIG.channels.toAkkaApps;
const EVENT_NAME = 'UserLeaveReqMsg';
const { meetingId, requesterUserId } = credentials;
@ -31,7 +31,7 @@ export default function userLeaving(credentials, userId) {
}
if (User.user.connection_status === OFFLINE_CONNECTION_STATUS) {
return;
return null;
}
if (User.user.listenOnly) {
@ -45,24 +45,29 @@ export default function userLeaving(credentials, userId) {
},
};
const cb = (err, numChanged) => {
const cb = (err) => {
if (err) {
return Logger.error(`Invalidating user: ${err}`);
}
if (numChanged) {
return Logger.info(`Invalidate user=${userId} meeting=${meetingId}`);
}
return Logger.info(`Invalidate user=${userId} meeting=${meetingId}`);
};
Users.update(selector, modifier, cb);
}
const payload = {
const header = {
name: EVENT_NAME,
meetingId,
userId: requesterUserId,
};
const payload = {
userId,
sessionId: meetingId,
};
Logger.verbose(`User '${requesterUserId}' left meeting '${meetingId}'`);
return RedisPubSub.publish(CHANNEL, EVENT_NAME, payload);
return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header);
}

View File

@ -16,35 +16,60 @@ export function joinRouteHandler(nextState, replace, callback) {
// use enter api to get params for the client
const url = `/bigbluebutton/api/enter?sessionToken=${sessionToken}`;
let BBBParameters;
fetch(url)
.then(response => response.json())
.then((data) => {
BBBParameters = data.response;
console.log(BBBParameters);
const { meetingID, internalUserID, authToken, logoutUrl } = data.response;
const { meetingID, internalUserID, authToken } = BBBParameters;
Auth.set(meetingID, internalUserID, authToken);
Auth.set(meetingID, internalUserID, authToken, logoutUrl);
replace({ pathname: '/' });
callback();
});
}
export function logoutRouteHandler(nextState, replace, callback) {
const { meetingID, userID, authToken } = nextState.params;
Auth.logout()
.then((logoutURL) => {
window.location = logoutURL || window.location.origin;
callback();
})
.catch((reason) => {
.catch(() => {
replace({ pathname: '/error/500' });
callback();
});
}
/**
* Check if should revalidate the auth
* @param {Object} status
* @param {String} lastStatus
*/
export function shouldAuthenticate(status, lastStatus) {
return lastStatus != null && lastStatus === STATUS_CONNECTING && status.connected;
}
/**
* Check if the isn't the first connection try, preventing to authenticate on login.
* @param {Object} status
* @param {string} lastStatus
*/
export function updateStatus(status, lastStatus) {
return status.retryCount > 0 && lastStatus !== STATUS_CONNECTING ? status.status : lastStatus;
}
function _addReconnectObservable() {
let lastStatus = null;
Tracker.autorun(() => {
lastStatus = updateStatus(Meteor.status(), lastStatus);
if (shouldAuthenticate(Meteor.status(), lastStatus)) {
Auth.authenticate(true);
lastStatus = Meteor.status().status;
}
});
}
export function authenticatedRouteHandler(nextState, replace, callback) {
const credentialsSnapshot = {
meetingId: Auth.meetingID,
@ -69,7 +94,7 @@ export function authenticatedRouteHandler(nextState, replace, callback) {
// make sure users who did not connect are not added to the meeting
// do **not** use the custom call - it relies on expired data
Meteor.call('userLogout', credentialsSnapshot, (error, result) => {
Meteor.call('userLogout', credentialsSnapshot, (error) => {
if (error) {
console.error('error');
}
@ -79,34 +104,3 @@ export function authenticatedRouteHandler(nextState, replace, callback) {
callback();
});
}
function _addReconnectObservable() {
let lastStatus = null;
Tracker.autorun(() => {
lastStatus = updateStatus(Meteor.status(), lastStatus);
if (shouldAuthenticate(Meteor.status(), lastStatus)) {
Auth.authenticate(true);
lastStatus = Meteor.status().status;
}
});
}
/**
* Check if should revalidate the auth
* @param {Object} status
* @param {String} lastStatus
*/
export function shouldAuthenticate(status, lastStatus) {
return lastStatus != null && lastStatus === STATUS_CONNECTING && status.connected;
}
/**
* Check if the isn't the first connection try, preventing to authenticate on login.
* @param {Object} status
* @param {string} lastStatus
*/
export function updateStatus(status, lastStatus) {
return status.retryCount > 0 && lastStatus !== STATUS_CONNECTING ? status.status : lastStatus;
}

View File

@ -13,6 +13,7 @@ class Auth {
this._meetingID = Storage.getItem('meetingID');
this._userID = Storage.getItem('userID');
this._authToken = Storage.getItem('authToken');
this._logoutURL = Storage.getItem('logoutURL');
this._loggedIn = {
value: false,
tracker: new Tracker.Dependency(),
@ -46,6 +47,15 @@ class Auth {
Storage.setItem('authToken', this._authToken);
}
set logoutURL(logoutURL) {
this._logoutURL = logoutURL;
Storage.setItem('logoutURL', this._logoutURL);
}
get logoutURL() {
return this._logoutURL;
}
get loggedIn() {
this._loggedIn.tracker.depend();
return this._loggedIn.value;
@ -61,26 +71,25 @@ class Auth {
meetingId: this.meetingID,
requesterUserId: this.userID,
requesterToken: this.token,
logoutURL: this.logoutURL,
};
}
set(meetingId, requesterUserId, requesterToken) {
set(meetingId, requesterUserId, requesterToken, logoutURL) {
this.meetingID = meetingId;
this.userID = requesterUserId;
this.token = requesterToken;
this.logoutURL = logoutURL;
}
set credentials(value) {
throw 'Credentials are read-only';
}
clearCredentials() {
clearCredentials(...args) {
this.meetingID = null;
this.userID = null;
this.token = null;
this.loggedIn = false;
this.logoutURL = null;
return Promise.resolve(...arguments);
return Promise.resolve(...args);
}
logout() {
@ -88,7 +97,7 @@ class Auth {
return Promise.resolve();
}
return new Promise((resolve, reject) => {
return new Promise((resolve) => {
const credentialsSnapshot = {
meetingId: this.meetingID,
requesterUserId: this.userID,
@ -97,13 +106,13 @@ class Auth {
// make sure users who did not connect are not added to the meeting
// do **not** use the custom call - it relies on expired data
Meteor.call('userLogout', credentialsSnapshot, (error, result) => {
Meteor.call('userLogout', credentialsSnapshot, (error) => {
if (error) {
logClient('error', { error, method: 'userLogout', credentialsSnapshot });
} else {
this.fetchLogoutUrl()
.then(this.clearCredentials)
.then(resolve);
.then(this.clearCredentials)
.then(resolve);
}
});
});
@ -122,7 +131,7 @@ class Auth {
return new Promise((resolve, reject) => {
Tracker.autorun((c) => {
if (!(credentials.meetingId && credentials.requesterToken && credentials.requesterUserId)) {
return reject({
reject({
error: 500,
description: 'Authentication subscription failed due to missing credentials.',
});
@ -167,7 +176,7 @@ class Auth {
const selector = { meetingId: this.meetingID, userId: this.userID };
const query = Users2x.find(selector);
const handle = query.observeChanges({
query.observeChanges({
changed: (id, fields) => {
if (fields.validated === true) {
c.stop();
@ -191,11 +200,7 @@ class Auth {
}
fetchLogoutUrl() {
const url = '/bigbluebutton/api/enter';
return fetch(url)
.then(response => response.json())
.then(data => Promise.resolve(data.response.logoutURL));
return Promise.resolve(this._logoutURL);
}
}