Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 19 additions & 26 deletions app/e2e/client/rocketchat.e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Tracker } from 'meteor/tracker';
import { EJSON } from 'meteor/ejson';
import { FlowRouter } from 'meteor/kadira:flow-router';
import { TAPi18n } from 'meteor/rocketchat:tap-i18n';
import { Emitter } from '@rocket.chat/emitter';

import { E2ERoom } from './rocketchat.e2e.room';
import {
Expand Down Expand Up @@ -32,24 +33,28 @@ import './events.js';
import './tabbar';

let failedToDecodeKey = false;
let showingE2EAlert = false;

const waitUntilFind = (fn) => new Promise((resolve) => {
Tracker.autorun((c) => {
const result = fn();
return result && resolve(result) && c.stop();
});
});

class E2E {
class E2E extends Emitter {
constructor() {
super();
this.started = false;
this.enabled = new ReactiveVar(false);
this._ready = new ReactiveVar(false);
this.instancesByRoomId = {};
this.readyPromise = new Deferred();
this.readyPromise.then(() => {

this.on('ready', () => {
this._ready.set(true);
this.log('startClient -> Done');
this.log('decryptPendingSubscriptions');
this.decryptPendingSubscriptions();
this.log('decryptPendingSubscriptions -> Done');
});
}

Expand Down Expand Up @@ -187,20 +192,17 @@ class E2E {
});
}

this.readyPromise.resolve();
this.log('startClient -> Done');
this.log('decryptPendingSubscriptions');
this.log('decryptSubscriptions');

this.decryptPendingSubscriptions();
this.log('decryptPendingSubscriptions -> Done');
this.decryptSubscriptions();
this.log('decryptSubscriptions -> Done');
this.emit('ready');
}

async stopClient() {
this.log('-> Stop Client');
// This flag is used to avoid closing unrelated alerts.
if (showingE2EAlert) {
banners.close();
}
this.closeAlert();

Meteor._localStorage.removeItem('public_key');
Meteor._localStorage.removeItem('private_key');
Expand All @@ -209,11 +211,6 @@ class E2E {
this.enabled.set(false);
this._ready.set(false);
this.started = false;

this.readyPromise = new Deferred();
this.readyPromise.then(() => {
this._ready.set(true);
});
}

async changePassword(newPassword) {
Expand Down Expand Up @@ -417,26 +414,22 @@ class E2E {

async decryptSubscription(rid) {
const e2eRoom = await this.getInstanceByRoomId(rid);
this.log('decryptPendingSubscriptions ->', rid);
this.log('decryptSubscription ->', rid);
e2eRoom?.decryptPendingSubscription();
}

async decryptPendingSubscriptions() {
async decryptSubscriptions() {
Subscriptions.find({
encrypted: true,
}).forEach((room) => this.decryptSubscription(room._id));
}

openAlert(config) {
showingE2EAlert = true;
banners.open(config);
banners.open({ id: 'e2e', ...config });
}

closeAlert() {
if (showingE2EAlert) {
banners.close();
}
showingE2EAlert = false;
banners.closeById('e2e');
}
}

Expand Down Expand Up @@ -491,7 +484,7 @@ Meteor.startup(function() {
}


doc.encrypted ? e2eRoom.enable() : e2eRoom.pause();
doc.encrypted ? e2eRoom.unPause() : e2eRoom.pause();

// Cover private groups and direct messages
if (!e2eRoom.isSupportedRoomType(doc.t)) {
Expand Down
48 changes: 17 additions & 31 deletions app/e2e/client/rocketchat.e2e.room.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ export const E2E_ROOM_STATES = {
NO_PASSWORD_SET: 'NO_PASSWORD_SET',
NOT_STARTED: 'NOT_STARTED',
DISABLED: 'DISABLED',
PAUSED: 'PAUSED',
HANDSHAKE: 'HANDSHAKE',
ESTABLISHING: 'ESTABLISHING',
CREATING_KEYS: 'CREATING_KEYS',
Expand All @@ -42,41 +41,24 @@ export const E2E_ROOM_STATES = {
};

const KEY_ID = Symbol('keyID');
const PAUSED = Symbol('PAUSED');

const reduce = (prev, next) => {
if (prev === next) {
return next === E2E_ROOM_STATES.ERROR;
}


switch (next) {
case E2E_ROOM_STATES.READY:
if (prev === E2E_ROOM_STATES.PAUSED) {
return E2E_ROOM_STATES.READY;
}
return E2E_ROOM_STATES.DISABLED;
case E2E_ROOM_STATES.PAUSED:
if (prev === E2E_ROOM_STATES.READY) {
return E2E_ROOM_STATES.PAUSED;
}
return E2E_ROOM_STATES.DISABLED;
}
switch (prev) {
case E2E_ROOM_STATES.PAUSED:
if (next === E2E_ROOM_STATES.READY) {
return E2E_ROOM_STATES.READY;
}
return false;
case E2E_ROOM_STATES.NOT_STARTED:
return [E2E_ROOM_STATES.ESTABLISHING, E2E_ROOM_STATES.PAUSED, E2E_ROOM_STATES.DISABLED, E2E_ROOM_STATES.KEYS_RECEIVED].includes(next) && next;
return [E2E_ROOM_STATES.ESTABLISHING, E2E_ROOM_STATES.DISABLED, E2E_ROOM_STATES.KEYS_RECEIVED].includes(next) && next;
case E2E_ROOM_STATES.READY:
return [E2E_ROOM_STATES.PAUSED, E2E_ROOM_STATES.DISABLED].includes(next) && next;
case E2E_ROOM_STATES.ERROR:
return [E2E_ROOM_STATES.KEYS_RECEIVED, E2E_ROOM_STATES.NOT_STARTED].includes(next) && next;
case E2E_ROOM_STATES.WAITING_KEYS:
return [E2E_ROOM_STATES.KEYS_RECEIVED, E2E_ROOM_STATES.ERROR, E2E_ROOM_STATES.PAUSED, E2E_ROOM_STATES.DISABLED].includes(next) && next;
return [E2E_ROOM_STATES.KEYS_RECEIVED, E2E_ROOM_STATES.ERROR, E2E_ROOM_STATES.DISABLED].includes(next) && next;
case E2E_ROOM_STATES.ESTABLISHING:
return [E2E_ROOM_STATES.READY, E2E_ROOM_STATES.KEYS_RECEIVED, E2E_ROOM_STATES.ERROR, E2E_ROOM_STATES.PAUSED, E2E_ROOM_STATES.DISABLED, E2E_ROOM_STATES.WAITING_KEYS].includes(next) && next;
return [E2E_ROOM_STATES.READY, E2E_ROOM_STATES.KEYS_RECEIVED, E2E_ROOM_STATES.ERROR, E2E_ROOM_STATES.DISABLED, E2E_ROOM_STATES.WAITING_KEYS].includes(next) && next;
default:
return next;
}
Expand Down Expand Up @@ -119,7 +101,7 @@ export class E2ERoom extends Emitter {
this.typeOfRoom = t;

this.once(E2E_ROOM_STATES.READY, () => this.decryptPendingMessages());
this.once(E2E_ROOM_STATES.READY, () => this.decryptPendingSubscription());
this.once(E2E_ROOM_STATES.READY, () => this.decryptSubscription());
this.on('STATE_CHANGED', (prev) => {
if (this.roomId === Session.get('openedRoom')) {
this.log(`[PREV: ${ prev }]`, 'State CHANGED');
Expand All @@ -139,7 +121,15 @@ export class E2ERoom extends Emitter {
}

pause() {
![E2E_ROOM_STATES.PAUSED, E2E_ROOM_STATES.DISABLED].includes(this.state) && this.setState(this.state === E2E_ROOM_STATES.READY ? E2E_ROOM_STATES.PAUSED : E2E_ROOM_STATES.DISABLED);
this[PAUSED] = true;
}

unPause() {
this[PAUSED] = false;
}

isPaused() {
return this[PAUSED];
}

enable() {
Expand All @@ -158,10 +148,6 @@ export class E2ERoom extends Emitter {
return [E2E_ROOM_STATES.DISABLED].includes(this.state);
}

isPaused() {
return [E2E_ROOM_STATES.PAUSED].includes(this.state);
}

wait(state) {
return new Promise((resolve) => (state === this.state ? resolve(this) : this.once(state, () => resolve(this)))).then((el) => {
this.log(this.state, el);
Expand All @@ -185,14 +171,14 @@ export class E2ERoom extends Emitter {
this[KEY_ID] = keyID;
}

async decryptPendingSubscription() {
async decryptSubscription() {
const subscription = Subscriptions.findOne({
rid: this.roomId,
});

const data = await (subscription.lastMessage?.msg && this.decrypt(subscription.lastMessage.msg));
if (!data?.text) {
this.log('decryptPendingSubscriptions nothing to do');
this.log('decryptSubscriptions nothing to do');
return;
}

Expand All @@ -204,7 +190,7 @@ export class E2ERoom extends Emitter {
'lastMessage.e2e': 'done',
},
});
this.log('decryptPendingSubscriptions Done');
this.log('decryptSubscriptions Done');
}

async decryptPendingMessages() {
Expand Down
1 change: 1 addition & 0 deletions app/version-check/client/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Meteor.startup(function() {
firstBanner.textArguments = firstBanner.textArguments || [];

banners.open({
id: firstBanner.id,
title: TAPi18n.__(firstBanner.title),
text: TAPi18n.__(firstBanner.text, ...firstBanner.textArguments),
modifiers: firstBanner.modifiers,
Expand Down
26 changes: 17 additions & 9 deletions client/lib/banners.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { mountRoot } from '../reactAdapters';
import { UiKitBannerPayload } from '../../definition/UIKit';

export type LegacyBannerPayload = {
id: string;
closable?: boolean;
title?: string;
text?: string;
Expand All @@ -31,13 +32,14 @@ export const firstSubscription: Subscription<BannerPayload | null> = {
export const open = (payload: BannerPayload): void => {
mountRoot();

let index = -1;
let index = queue.findIndex((_payload) => {
if (isLegacyPayload(_payload)) {
return _payload.id === (payload as LegacyBannerPayload).id;
}
return (_payload as UiKitBannerPayload).viewId === (payload as UiKitBannerPayload).viewId;
});

if (!isLegacyPayload(payload)) {
index = queue.findIndex((_payload) => !isLegacyPayload(_payload) && _payload.viewId === payload.viewId);
}

if (index < 0) {
if (index === -1) {
index = queue.length;
}

Expand All @@ -51,15 +53,21 @@ export const open = (payload: BannerPayload): void => {
};


export const closeById = (viewId: string): void => {
const index = queue.findIndex((banner) => !isLegacyPayload(banner) && banner.viewId === viewId);
export const closeById = (id: string): void => {
const index = queue.findIndex((banner) => {
if (!isLegacyPayload(banner)) {
return banner.viewId === id;
}
return banner.id === id;
});

if (index < 0) {
return;
}

queue.splice(index, 1);
emitter.emit('update');
emitter.emit('update-first');
index === 0 && emitter.emit('update-first');
};

export const close = (): void => {
Expand Down
1 change: 1 addition & 0 deletions client/startup/startup.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ Meteor.startup(function() {
const { connectToCloud = false, workspaceRegistered = false } = data;
if (connectToCloud === true && workspaceRegistered !== true) {
banners.open({
id: 'cloud-registration',
title: t('Cloud_registration_pending_title'),
html: t('Cloud_registration_pending_html'),
modifiers: ['large', 'danger'],
Expand Down
25 changes: 13 additions & 12 deletions client/startup/unread.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,22 @@ Meteor.startup(() => {

let unreadAlert = false;

const unreadCount = fetchSubscriptions().reduce((ret, subscription) => {
const room = ChatRoom.findOne({ _id: subscription.rid }, { fields: { usersCount: 1 } });
fireGlobalEvent('unread-changed-by-subscription', { ...subscription, usersCount: room && room.usersCount });
const unreadCount = fetchSubscriptions().reduce((ret, subscription) =>
Tracker.nonreactive(() => {
const room = ChatRoom.findOne({ _id: subscription.rid }, { fields: { usersCount: 1 } });
fireGlobalEvent('unread-changed-by-subscription', { ...subscription, usersCount: room && room.usersCount });

if (subscription.alert || subscription.unread > 0) {
// Increment the total unread count.
if (subscription.alert === true && subscription.unreadAlert !== 'nothing') {
if (subscription.unreadAlert === 'all' || userUnreadAlert !== false) {
unreadAlert = '•';
if (subscription.alert || subscription.unread > 0) {
// Increment the total unread count.
if (subscription.alert === true && subscription.unreadAlert !== 'nothing') {
if (subscription.unreadAlert === 'all' || userUnreadAlert !== false) {
unreadAlert = '•';
}
}
return ret + subscription.unread;
}
return ret + subscription.unread;
}
return ret;
}, 0);
return ret;
}), 0);

menu.updateUnreadBars();

Expand Down