Remove: presentation upload token subscription
This commit is contained in:
parent
db3e46b711
commit
f5fdc915cf
@ -1,7 +1,6 @@
|
||||
import AbstractCollection from '/imports/ui/services/LocalCollectionSynchronizer/LocalCollectionSynchronizer';
|
||||
|
||||
// Collections
|
||||
import PresentationUploadToken from '/imports/api/presentation-upload-token';
|
||||
import Screenshare from '/imports/api/screenshare';
|
||||
import UserInfos from '/imports/api/users-infos';
|
||||
import UserSettings from '/imports/api/users-settings';
|
||||
@ -17,10 +16,6 @@ import Users from '/imports/api/users';
|
||||
|
||||
// Custom Publishers
|
||||
export const localCollectionRegistry = {
|
||||
localPresentationUploadTokenSync: new AbstractCollection(
|
||||
PresentationUploadToken,
|
||||
PresentationUploadToken,
|
||||
),
|
||||
localScreenshareSync: new AbstractCollection(Screenshare, Screenshare),
|
||||
localUserInfosSync: new AbstractCollection(UserInfos, UserInfos),
|
||||
localUserSettingsSync: new AbstractCollection(UserSettings, UserSettings),
|
||||
|
@ -1,7 +0,0 @@
|
||||
const collectionOptions = Meteor.isClient ? {
|
||||
connection: null,
|
||||
} : {};
|
||||
|
||||
const PresentationUploadToken = new Mongo.Collection('presentation-upload-token', collectionOptions);
|
||||
|
||||
export default PresentationUploadToken;
|
@ -1,8 +0,0 @@
|
||||
import RedisPubSub from '/imports/startup/server/redis';
|
||||
import { processForHTML5ServerOnly } from '/imports/api/common/server/helpers';
|
||||
|
||||
import handlePresentationUploadTokenPass from './handlers/presentationUploadTokenPass';
|
||||
import handlePresentationUploadTokenFail from './handlers/presentationUploadTokenFail';
|
||||
|
||||
RedisPubSub.on('PresentationUploadTokenPassRespMsg', processForHTML5ServerOnly(handlePresentationUploadTokenPass));
|
||||
RedisPubSub.on('PresentationUploadTokenFailRespMsg', processForHTML5ServerOnly(handlePresentationUploadTokenFail));
|
@ -1,32 +0,0 @@
|
||||
import { check } from 'meteor/check';
|
||||
import Logger from '/imports/startup/server/logger';
|
||||
import PresentationUploadToken from '/imports/api/presentation-upload-token';
|
||||
|
||||
export default async function handlePresentationUploadTokenFail({ body, header }, meetingId) {
|
||||
check(body, Object);
|
||||
|
||||
const { userId } = header;
|
||||
const { podId, filename } = body;
|
||||
|
||||
check(userId, String);
|
||||
check(podId, String);
|
||||
check(filename, String);
|
||||
|
||||
const selector = {
|
||||
meetingId,
|
||||
userId,
|
||||
podId,
|
||||
filename,
|
||||
};
|
||||
|
||||
try {
|
||||
const { numberAffected } = await PresentationUploadToken
|
||||
.upsertAsync(selector, { failed: true, authzToken: null });
|
||||
|
||||
if (numberAffected) {
|
||||
Logger.info(`Removing presentationToken filename=${filename} podId=${podId} meeting=${meetingId}`);
|
||||
}
|
||||
} catch (err) {
|
||||
Logger.error(`Removing presentationToken from collection: ${err}`);
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
import { check } from 'meteor/check';
|
||||
import Logger from '/imports/startup/server/logger';
|
||||
import PresentationUploadToken from '/imports/api/presentation-upload-token';
|
||||
|
||||
export default async function handlePresentationUploadTokenPass({ body, header }, meetingId) {
|
||||
check(body, Object);
|
||||
|
||||
const { userId } = header;
|
||||
const { podId, authzToken, filename, temporaryPresentationId } = body;
|
||||
|
||||
check(userId, String);
|
||||
check(podId, String);
|
||||
check(authzToken, String);
|
||||
check(filename, String);
|
||||
check(temporaryPresentationId, String)
|
||||
|
||||
const selector = {
|
||||
meetingId,
|
||||
podId,
|
||||
userId,
|
||||
filename,
|
||||
temporaryPresentationId,
|
||||
};
|
||||
|
||||
const modifier = {
|
||||
meetingId,
|
||||
podId,
|
||||
userId,
|
||||
filename,
|
||||
authzToken,
|
||||
temporaryPresentationId,
|
||||
failed: false,
|
||||
used: false,
|
||||
};
|
||||
|
||||
try {
|
||||
const { insertedId } = await PresentationUploadToken.upsertAsync(selector, modifier);
|
||||
|
||||
if (insertedId) {
|
||||
Logger.info(`Inserting presentationToken filename=${filename} podId=${podId} meeting=${meetingId}`);
|
||||
}
|
||||
} catch (err) {
|
||||
Logger.error(`Inserting presentationToken from collection: ${err}`);
|
||||
}
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
import './eventHandlers';
|
||||
import './methods';
|
||||
import './publishers';
|
@ -1,8 +0,0 @@
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import requestPresentationUploadToken from './methods/requestPresentationUploadToken';
|
||||
import setUsedToken from './methods/setUsedToken';
|
||||
|
||||
Meteor.methods({
|
||||
requestPresentationUploadToken,
|
||||
setUsedToken,
|
||||
});
|
@ -1,34 +0,0 @@
|
||||
import RedisPubSub from '/imports/startup/server/redis';
|
||||
import { check } from 'meteor/check';
|
||||
import { extractCredentials } from '/imports/api/common/server/helpers';
|
||||
import Logger from '/imports/startup/server/logger';
|
||||
|
||||
export default async function requestPresentationUploadToken(
|
||||
podId,
|
||||
filename,
|
||||
temporaryPresentationId,
|
||||
) {
|
||||
const REDIS_CONFIG = Meteor.settings.private.redis;
|
||||
const CHANNEL = REDIS_CONFIG.channels.toAkkaApps;
|
||||
const EVENT_NAME = 'PresentationUploadTokenReqMsg';
|
||||
|
||||
try {
|
||||
const { meetingId, requesterUserId } = extractCredentials(this.userId);
|
||||
|
||||
check(meetingId, String);
|
||||
check(requesterUserId, String);
|
||||
check(podId, String);
|
||||
check(filename, String);
|
||||
check(temporaryPresentationId, String);
|
||||
|
||||
const payload = {
|
||||
podId,
|
||||
filename,
|
||||
uploadTemporaryId: temporaryPresentationId,
|
||||
};
|
||||
|
||||
RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, requesterUserId, payload);
|
||||
} catch (err) {
|
||||
Logger.error(`Exception while invoking method requestPresentationUploadToken ${err.stack}`);
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
import PresentationUploadToken from '/imports/api/presentation-upload-token';
|
||||
import Logger from '/imports/startup/server/logger';
|
||||
import { extractCredentials } from '/imports/api/common/server/helpers';
|
||||
import { check } from 'meteor/check';
|
||||
|
||||
export default async function setUsedToken(authzToken) {
|
||||
try {
|
||||
const { meetingId, requesterUserId } = extractCredentials(this.userId);
|
||||
|
||||
check(meetingId, String);
|
||||
check(requesterUserId, String);
|
||||
check(authzToken, String);
|
||||
|
||||
const payload = {
|
||||
$set: {
|
||||
used: true,
|
||||
},
|
||||
};
|
||||
|
||||
const numberAffected = await PresentationUploadToken.updateAsync({
|
||||
meetingId,
|
||||
userId: requesterUserId,
|
||||
authzToken,
|
||||
}, payload);
|
||||
|
||||
if (numberAffected) {
|
||||
Logger.info(`Token: ${authzToken} has been set as used in meeting=${meetingId}`);
|
||||
}
|
||||
} catch (err) {
|
||||
Logger.error(`Exception while invoking method setUsedToken ${err.stack}`);
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
import PresentationUploadToken from '/imports/api/presentation-upload-token';
|
||||
import Logger from '/imports/startup/server/logger';
|
||||
|
||||
export default async function clearPresentationUploadToken(
|
||||
meetingId,
|
||||
podId,
|
||||
) {
|
||||
if (meetingId && podId) {
|
||||
try {
|
||||
const numberAffected = await PresentationUploadToken.removeAsync({ meetingId, podId });
|
||||
|
||||
if (numberAffected) {
|
||||
Logger.info(`Cleared Presentations Upload Token (${meetingId}, ${podId})`);
|
||||
return true;
|
||||
}
|
||||
} catch (err) {
|
||||
Logger.info(`Error on clearing Presentations Upload Token (${meetingId}, ${podId}). ${err}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (meetingId) {
|
||||
try {
|
||||
const numberAffected = await PresentationUploadToken.removeAsync({ meetingId });
|
||||
|
||||
if (numberAffected) {
|
||||
Logger.info(`Cleared Presentations Upload Token (${meetingId})`);
|
||||
}
|
||||
} catch (err) {
|
||||
Logger.info(`Error on clearing Presentations Upload Token (${meetingId}). ${err}`);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
// clearing presentations for the whole server
|
||||
const numberAffected = await PresentationUploadToken.removeAsync({});
|
||||
|
||||
if (numberAffected) {
|
||||
Logger.info('Cleared Presentations Upload Token (all)');
|
||||
}
|
||||
} catch (err) {
|
||||
Logger.info(`Error on clearing Presentations Upload Token (all). ${err}`);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { check } from 'meteor/check';
|
||||
import PresentationUploadToken from '/imports/api/presentation-upload-token';
|
||||
import Logger from '/imports/startup/server/logger';
|
||||
import AuthTokenValidation, { ValidationStates } from '/imports/api/auth-token-validation';
|
||||
|
||||
async function presentationUploadToken(podId, filename, temporaryPresentationId) {
|
||||
const tokenValidation = await AuthTokenValidation
|
||||
.findOneAsync({ connectionId: this.connection.id });
|
||||
|
||||
if (!tokenValidation || tokenValidation.validationStatus !== ValidationStates.VALIDATED) {
|
||||
Logger.warn(`Publishing PresentationUploadToken was requested by unauth connection ${this.connection.id}`);
|
||||
return PresentationUploadToken.find({ meetingId: '' });
|
||||
}
|
||||
|
||||
const { meetingId, userId } = tokenValidation;
|
||||
|
||||
check(podId, String);
|
||||
check(filename, String);
|
||||
check(temporaryPresentationId, String);
|
||||
|
||||
const selector = {
|
||||
meetingId,
|
||||
podId,
|
||||
userId,
|
||||
filename,
|
||||
temporaryPresentationId,
|
||||
};
|
||||
|
||||
Logger.debug('Publishing PresentationUploadToken', { meetingId, userId });
|
||||
|
||||
return PresentationUploadToken.find(selector);
|
||||
}
|
||||
|
||||
function publish(...args) {
|
||||
const boundPresentationUploadToken = presentationUploadToken.bind(this);
|
||||
return boundPresentationUploadToken(...args);
|
||||
}
|
||||
|
||||
Meteor.publish('presentation-upload-token', publish);
|
@ -6,6 +6,7 @@ import { SubscriptionClient } from 'subscriptions-transport-ws';
|
||||
import React, { useContext, useEffect } from 'react';
|
||||
import { LoadingContext } from '/imports/ui/components/common/loading-screen/loading-screen-HOC/component';
|
||||
import logger from '/imports/startup/client/logger';
|
||||
import apolloContextHolder from '../../core/graphql/apolloContextHolder/apolloContextHolder';
|
||||
|
||||
interface ConnectionManagerProps {
|
||||
children: React.ReactNode;
|
||||
@ -115,6 +116,7 @@ const ConnectionManager: React.FC<ConnectionManagerProps> = ({ children }): Reac
|
||||
connectToDevTools: true,
|
||||
});
|
||||
setApolloClient(client);
|
||||
apolloContextHolder.setClient(client);
|
||||
} catch (error) {
|
||||
loadingContextInfo.setLoading(false, '');
|
||||
throw new Error('Error creating Apollo Client: '.concat(JSON.stringify(error) || ''));
|
||||
|
@ -0,0 +1,15 @@
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
export const requestPresentationUploadTokenMutation = gql`
|
||||
mutation RequestPresentationUploadToken($podId: String!, $filename: String!, $uploadTemporaryId: String!) {
|
||||
presentationRequestUploadToken(
|
||||
podId: $podId,
|
||||
filename: $filename,
|
||||
uploadTemporaryId: $uploadTemporaryId,
|
||||
)
|
||||
}
|
||||
`;
|
||||
|
||||
export default {
|
||||
requestPresentationUploadTokenMutation,
|
||||
};
|
@ -0,0 +1,15 @@
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
export const getPresentationUploadToken = gql`
|
||||
query getPresentationUploadToken ($uploadTemporaryId: String!){
|
||||
pres_presentation_uploadToken(where: {uploadTemporaryId: {_eq: $uploadTemporaryId}}) {
|
||||
presentationId
|
||||
uploadTemporaryId
|
||||
uploadToken
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export default {
|
||||
getPresentationUploadToken,
|
||||
};
|
@ -1,8 +1,5 @@
|
||||
import { UploadingPresentations } from '/imports/api/presentations';
|
||||
import PresentationUploadToken from '/imports/api/presentation-upload-token';
|
||||
import Auth from '/imports/ui/services/auth';
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { makeCall } from '/imports/ui/services/api';
|
||||
import logger from '/imports/startup/client/logger';
|
||||
import { partition } from '/imports/utils/array-utils';
|
||||
import update from 'immutability-helper';
|
||||
@ -11,8 +8,10 @@ import Meetings from '/imports/api/meetings';
|
||||
import { uniqueId } from '/imports/utils/string-utils';
|
||||
import { isPresentationEnabled } from '/imports/ui/services/features';
|
||||
import { notify } from '/imports/ui/services/notification';
|
||||
import apolloContextHolder from '/imports/ui/core/graphql/apolloContextHolder/apolloContextHolder';
|
||||
import { getPresentationUploadToken } from './queries';
|
||||
import { requestPresentationUploadTokenMutation } from './mutation';
|
||||
|
||||
const CONVERSION_TIMEOUT = 300000;
|
||||
const TOKEN_TIMEOUT = 5000;
|
||||
const PRESENTATION_CONFIG = window.meetingClientSettings.public.presentation;
|
||||
|
||||
@ -46,37 +45,41 @@ const requestPresentationUploadToken = (
|
||||
meetingId,
|
||||
filename,
|
||||
) => new Promise((resolve, reject) => {
|
||||
makeCall('requestPresentationUploadToken', POD_ID, filename, temporaryPresentationId);
|
||||
const client = apolloContextHolder.getClient();
|
||||
client.mutate({
|
||||
mutation: requestPresentationUploadTokenMutation,
|
||||
variables: {
|
||||
podId: POD_ID,
|
||||
filename,
|
||||
uploadTemporaryId: temporaryPresentationId,
|
||||
},
|
||||
});
|
||||
|
||||
let computation = null;
|
||||
const timeout = setTimeout(() => {
|
||||
computation.stop();
|
||||
reject(new Error({ code: 408, message: 'requestPresentationUploadToken timeout' }));
|
||||
}, TOKEN_TIMEOUT);
|
||||
|
||||
Tracker.autorun((c) => {
|
||||
computation = c;
|
||||
const sub = Meteor.subscribe('presentation-upload-token', POD_ID, filename, temporaryPresentationId);
|
||||
if (!sub.ready()) return;
|
||||
|
||||
const PresentationToken = PresentationUploadToken.findOne({
|
||||
podId: POD_ID,
|
||||
meetingId,
|
||||
temporaryPresentationId,
|
||||
used: false,
|
||||
const getData = (n = 0) => {
|
||||
if (n > 10) return;
|
||||
let recursiveTimeout = null;
|
||||
client.query({
|
||||
query: getPresentationUploadToken,
|
||||
variables: {
|
||||
uploadTemporaryId: temporaryPresentationId,
|
||||
},
|
||||
fetchPolicy: 'network-only',
|
||||
}).then((result) => {
|
||||
if (result.data.pres_presentation_uploadToken.length > 0) {
|
||||
clearTimeout(recursiveTimeout);
|
||||
clearTimeout(timeout);
|
||||
resolve(result.data.pres_presentation_uploadToken[0].uploadToken);
|
||||
}
|
||||
});
|
||||
|
||||
if (!PresentationToken || !('failed' in PresentationToken)) return;
|
||||
|
||||
if (!PresentationToken.failed) {
|
||||
clearTimeout(timeout);
|
||||
resolve(PresentationToken.authzToken);
|
||||
}
|
||||
|
||||
if (PresentationToken.failed) {
|
||||
reject(new Error({ code: 401, message: `requestPresentationUploadToken token ${PresentationToken.authzToken} failed` }));
|
||||
}
|
||||
});
|
||||
recursiveTimeout = setTimeout(() => {
|
||||
getData(n + 1);
|
||||
}, 1000);
|
||||
};
|
||||
setTimeout(getData, 100);
|
||||
});
|
||||
|
||||
const uploadAndConvertPresentation = (
|
||||
@ -131,7 +134,6 @@ const uploadAndConvertPresentation = (
|
||||
|
||||
return requestPresentationUploadToken(temporaryPresentationId, meetingId, file.name)
|
||||
.then((token) => {
|
||||
makeCall('setUsedToken', token);
|
||||
UploadingPresentations.upsert({
|
||||
temporaryPresentationId,
|
||||
}, {
|
||||
|
@ -0,0 +1,18 @@
|
||||
import { ApolloClient, NormalizedCacheObject } from '@apollo/client';
|
||||
|
||||
class ApolloContextHolder {
|
||||
private client: ApolloClient<NormalizedCacheObject> | null = null;
|
||||
|
||||
public setClient(client: ApolloClient<NormalizedCacheObject>): void {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public getClient(): ApolloClient<NormalizedCacheObject> {
|
||||
if (!this.client) {
|
||||
throw new Error('ApolloClient has not been initialized yet');
|
||||
}
|
||||
return this.client;
|
||||
}
|
||||
}
|
||||
|
||||
export default new ApolloContextHolder();
|
@ -3,7 +3,6 @@ import '/imports/startup/server';
|
||||
// 2x
|
||||
import '/imports/api/meetings/server';
|
||||
import '/imports/api/users/server';
|
||||
import '/imports/api/presentation-upload-token/server';
|
||||
import '/imports/api/breakouts/server';
|
||||
import '/imports/api/screenshare/server';
|
||||
import '/imports/api/users-settings/server';
|
||||
|
Loading…
Reference in New Issue
Block a user