2017-02-24 02:15:13 +08:00
|
|
|
import { check } from 'meteor/check';
|
|
|
|
import Logger from '/imports/startup/server/logger';
|
2017-10-12 10:00:28 +08:00
|
|
|
import Users from '/imports/api/users';
|
2020-02-07 04:47:28 +08:00
|
|
|
import userJoin from './userJoin';
|
2020-04-29 11:33:45 +08:00
|
|
|
import pendingAuthenticationsStore from '../store/pendingAuthentications';
|
|
|
|
import createDummyUser from '../modifiers/createDummyUser';
|
2022-05-14 03:18:51 +08:00
|
|
|
import updateUserConnectionId from '../modifiers/updateUserConnectionId';
|
2021-01-27 03:22:32 +08:00
|
|
|
import ClientConnections from '/imports/startup/server/ClientConnections';
|
2017-10-12 09:02:23 +08:00
|
|
|
|
2020-09-01 20:07:56 +08:00
|
|
|
import upsertValidationState from '/imports/api/auth-token-validation/server/modifiers/upsertValidationState';
|
|
|
|
import { ValidationStates } from '/imports/api/auth-token-validation';
|
|
|
|
|
2018-02-20 22:21:51 +08:00
|
|
|
const clearOtherSessions = (sessionUserId, current = false) => {
|
|
|
|
const serverSessions = Meteor.server.sessions;
|
|
|
|
Object.keys(serverSessions)
|
|
|
|
.filter(i => serverSessions[i].userId === sessionUserId)
|
|
|
|
.filter(i => i !== current)
|
|
|
|
.forEach(i => serverSessions[i].close());
|
|
|
|
};
|
|
|
|
|
2023-03-15 21:18:31 +08:00
|
|
|
export default async function handleValidateAuthToken({ body }, meetingId) {
|
2020-06-13 00:24:11 +08:00
|
|
|
const {
|
|
|
|
userId,
|
|
|
|
valid,
|
|
|
|
authToken,
|
|
|
|
waitForApproval,
|
2021-02-17 01:46:30 +08:00
|
|
|
registeredOn,
|
2021-02-26 03:52:20 +08:00
|
|
|
authTokenValidatedOn,
|
2021-03-30 21:09:25 +08:00
|
|
|
reasonCode,
|
2020-06-13 00:24:11 +08:00
|
|
|
} = body;
|
2017-02-24 02:15:13 +08:00
|
|
|
|
|
|
|
check(userId, String);
|
2020-04-29 11:33:45 +08:00
|
|
|
check(authToken, String);
|
2017-10-12 09:02:23 +08:00
|
|
|
check(valid, Boolean);
|
|
|
|
check(waitForApproval, Boolean);
|
2021-02-17 20:20:55 +08:00
|
|
|
check(registeredOn, Number);
|
2021-02-26 03:52:20 +08:00
|
|
|
check(authTokenValidatedOn, Number);
|
2021-03-30 21:09:25 +08:00
|
|
|
check(reasonCode, String);
|
2017-02-24 02:15:13 +08:00
|
|
|
|
2020-04-29 11:33:45 +08:00
|
|
|
const pendingAuths = pendingAuthenticationsStore.take(meetingId, userId, authToken);
|
2021-02-06 01:47:46 +08:00
|
|
|
Logger.info(`PendingAuths length [${pendingAuths.length}]`);
|
|
|
|
if (pendingAuths.length === 0) return;
|
|
|
|
|
2020-06-13 00:24:11 +08:00
|
|
|
if (!valid) {
|
2023-03-15 21:18:31 +08:00
|
|
|
await Promise.all(pendingAuths.map(
|
|
|
|
async (pendingAuth) => {
|
2020-04-29 11:33:45 +08:00
|
|
|
try {
|
2020-06-13 00:24:11 +08:00
|
|
|
const { methodInvocationObject } = pendingAuth;
|
2020-04-29 11:33:45 +08:00
|
|
|
const connectionId = methodInvocationObject.connection.id;
|
|
|
|
|
2023-03-15 21:18:31 +08:00
|
|
|
await upsertValidationState(
|
|
|
|
meetingId,
|
|
|
|
userId,
|
|
|
|
ValidationStates.INVALID,
|
|
|
|
connectionId,
|
|
|
|
reasonCode,
|
|
|
|
);
|
|
|
|
|
|
|
|
// Schedule socket disconnection for this user
|
|
|
|
// giving some time for client receiving the reason of disconnection
|
|
|
|
new Promise((resolve) => {
|
|
|
|
setTimeout(() => {
|
|
|
|
methodInvocationObject.connection.close();
|
|
|
|
Logger.info(`Closed connection ${connectionId} due to invalid auth token.`);
|
|
|
|
resolve();
|
|
|
|
}, 2000);
|
|
|
|
});
|
2020-04-29 11:33:45 +08:00
|
|
|
} catch (e) {
|
|
|
|
Logger.error(`Error closing socket for meetingId '${meetingId}', userId '${userId}', authToken ${authToken}`);
|
|
|
|
}
|
2020-06-13 00:24:11 +08:00
|
|
|
},
|
2023-03-15 21:18:31 +08:00
|
|
|
));
|
2020-06-13 00:24:11 +08:00
|
|
|
|
2020-04-29 11:33:45 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-05-19 20:20:28 +08:00
|
|
|
// Define user ID on connections
|
2023-03-15 21:18:31 +08:00
|
|
|
await Promise.all(pendingAuths.map(
|
|
|
|
async (pendingAuth) => {
|
2021-05-19 20:20:28 +08:00
|
|
|
const { methodInvocationObject } = pendingAuth;
|
2020-06-13 00:24:11 +08:00
|
|
|
|
2023-03-15 21:18:31 +08:00
|
|
|
/* Logic migrated from validateAuthToken method
|
|
|
|
( postponed to only run in case of success response ) - Begin */
|
2021-05-19 20:20:28 +08:00
|
|
|
const sessionId = `${meetingId}--${userId}`;
|
2020-09-30 05:02:03 +08:00
|
|
|
|
2021-05-19 20:20:28 +08:00
|
|
|
methodInvocationObject.setUserId(sessionId);
|
2020-06-13 00:24:11 +08:00
|
|
|
|
2023-03-15 21:18:31 +08:00
|
|
|
const User = await Users.findOneAsync({
|
2021-05-19 20:20:28 +08:00
|
|
|
meetingId,
|
|
|
|
userId,
|
|
|
|
});
|
2020-06-13 00:24:11 +08:00
|
|
|
|
2021-05-19 20:20:28 +08:00
|
|
|
if (!User) {
|
2023-03-15 21:18:31 +08:00
|
|
|
await createDummyUser(meetingId, userId, authToken);
|
|
|
|
} else {
|
|
|
|
await updateUserConnectionId(meetingId, userId, methodInvocationObject.connection.id);
|
2021-05-19 20:20:28 +08:00
|
|
|
}
|
2020-06-13 00:24:11 +08:00
|
|
|
|
2021-05-19 20:20:28 +08:00
|
|
|
ClientConnections.add(sessionId, methodInvocationObject.connection);
|
2023-03-15 21:18:31 +08:00
|
|
|
await upsertValidationState(
|
|
|
|
meetingId,
|
|
|
|
userId,
|
|
|
|
ValidationStates.VALIDATED,
|
|
|
|
methodInvocationObject.connection.id,
|
|
|
|
);
|
2020-09-01 20:07:56 +08:00
|
|
|
|
2021-05-19 20:20:28 +08:00
|
|
|
/* End of logic migrated from validateAuthToken */
|
|
|
|
},
|
2023-03-15 21:18:31 +08:00
|
|
|
));
|
2020-04-29 11:33:45 +08:00
|
|
|
|
2017-02-24 02:15:13 +08:00
|
|
|
const selector = {
|
|
|
|
meetingId,
|
|
|
|
userId,
|
2018-06-15 04:24:55 +08:00
|
|
|
clientType: 'HTML5',
|
2017-02-24 02:15:13 +08:00
|
|
|
};
|
|
|
|
|
2023-03-15 21:18:31 +08:00
|
|
|
const User = await Users.findOneAsync(selector);
|
2017-03-08 01:18:02 +08:00
|
|
|
|
2017-03-11 02:33:46 +08:00
|
|
|
// If we dont find the user on our collection is a flash user and we can skip
|
|
|
|
if (!User) return;
|
2017-03-08 01:18:02 +08:00
|
|
|
|
2017-10-12 09:02:23 +08:00
|
|
|
// Publish user join message
|
2021-05-19 20:20:28 +08:00
|
|
|
if (!waitForApproval) {
|
2019-02-14 03:44:21 +08:00
|
|
|
Logger.info('User=', User);
|
2017-10-12 09:02:23 +08:00
|
|
|
userJoin(meetingId, userId, User.authToken);
|
|
|
|
}
|
|
|
|
|
2017-02-24 02:15:13 +08:00
|
|
|
const modifier = {
|
|
|
|
$set: {
|
2017-10-12 09:02:23 +08:00
|
|
|
validated: valid,
|
|
|
|
approved: !waitForApproval,
|
2021-02-17 20:20:55 +08:00
|
|
|
loginTime: registeredOn,
|
2021-02-26 03:52:20 +08:00
|
|
|
authTokenValidatedTime: authTokenValidatedOn,
|
2019-02-27 01:40:01 +08:00
|
|
|
inactivityCheck: false,
|
2017-02-24 02:15:13 +08:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2020-11-23 21:13:46 +08:00
|
|
|
try {
|
2023-03-15 21:18:31 +08:00
|
|
|
const numberAffected = await Users.updateAsync(selector, modifier);
|
2017-02-24 02:15:13 +08:00
|
|
|
|
2020-11-23 21:13:46 +08:00
|
|
|
if (numberAffected) {
|
2021-05-19 20:20:28 +08:00
|
|
|
const sessionUserId = `${meetingId}-${userId}`;
|
|
|
|
const currentConnectionId = User.connectionId ? User.connectionId : false;
|
|
|
|
clearOtherSessions(sessionUserId, currentConnectionId);
|
2017-02-24 04:16:10 +08:00
|
|
|
|
2020-11-23 21:13:46 +08:00
|
|
|
Logger.info(`Validated auth token as ${valid} user=${userId} meeting=${meetingId}`);
|
|
|
|
} else {
|
|
|
|
Logger.info('No auth to validate');
|
2017-02-24 02:15:13 +08:00
|
|
|
}
|
2020-11-23 21:13:46 +08:00
|
|
|
} catch (err) {
|
|
|
|
Logger.error(`Validating auth token: ${err}`);
|
|
|
|
}
|
2020-06-13 03:51:22 +08:00
|
|
|
}
|