Chore: Dehydrate share extension from rocketchat.js (#3753)
Co-authored-by: Gleidson Daniel Silva <gleidson10daniel@hotmail.com>
This commit is contained in:
parent
e792f2a49b
commit
a754983ac8
|
@ -37,6 +37,21 @@ class AvatarContainer extends React.Component<IAvatar, any> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shouldComponentUpdate(nextProps: IAvatar, nextState: { avatarETag: string }) {
|
||||||
|
const { avatarETag } = this.state;
|
||||||
|
const { text, type } = this.props;
|
||||||
|
if (nextState.avatarETag !== avatarETag) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (nextProps.text !== text) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (nextProps.type !== type) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
if (this.subscription?.unsubscribe) {
|
if (this.subscription?.unsubscribe) {
|
||||||
this.subscription.unsubscribe();
|
this.subscription.unsubscribe();
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
export interface ICredentials {
|
export interface ICredentials {
|
||||||
|
resume?: string;
|
||||||
user?: string;
|
user?: string;
|
||||||
password?: string;
|
password?: string;
|
||||||
username?: string;
|
username?: string;
|
||||||
|
|
|
@ -66,7 +66,7 @@ export const getDatabase = (database = ''): Database => {
|
||||||
};
|
};
|
||||||
|
|
||||||
interface IDatabases {
|
interface IDatabases {
|
||||||
shareDB?: TAppDatabase;
|
shareDB?: TAppDatabase | null;
|
||||||
serversDB: TServerDatabase;
|
serversDB: TServerDatabase;
|
||||||
activeDB?: TAppDatabase;
|
activeDB?: TAppDatabase;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,10 @@ import { Q } from '@nozbe/watermelondb';
|
||||||
import AsyncStorage from '@react-native-community/async-storage';
|
import AsyncStorage from '@react-native-community/async-storage';
|
||||||
import { InteractionManager } from 'react-native';
|
import { InteractionManager } from 'react-native';
|
||||||
import { setActiveUsers } from '../../actions/activeUsers';
|
import { setActiveUsers } from '../../actions/activeUsers';
|
||||||
import { encryptionInit } from '../../actions/encryption';
|
|
||||||
import { setUser } from '../../actions/login';
|
import { setUser } from '../../actions/login';
|
||||||
import { shareSelectServer, shareSetSettings, shareSetUser } from '../../actions/share';
|
|
||||||
import defaultSettings from '../../constants/settings';
|
import defaultSettings from '../../constants/settings';
|
||||||
import { getDeviceToken } from '../../notifications/push';
|
import { getDeviceToken } from '../../notifications/push';
|
||||||
import log from '../../utils/log';
|
import log from '../../utils/log';
|
||||||
import SSLPinning from '../../utils/sslPinning';
|
|
||||||
import database from '../database';
|
import database from '../database';
|
||||||
import triggerBlockAction, { triggerCancel, triggerSubmitView } from '../methods/actions';
|
import triggerBlockAction, { triggerCancel, triggerSubmitView } from '../methods/actions';
|
||||||
import callJitsi, { callJitsiWithoutServer } from '../methods/callJitsi';
|
import callJitsi, { callJitsiWithoutServer } from '../methods/callJitsi';
|
||||||
|
@ -65,7 +62,8 @@ import {
|
||||||
stopListener,
|
stopListener,
|
||||||
connect
|
connect
|
||||||
} from './services/connect';
|
} from './services/connect';
|
||||||
import * as restAPis from './services/restApi';
|
import { shareExtensionInit, closeShareExtension } from './services/shareExtension';
|
||||||
|
import * as restApis from './services/restApi';
|
||||||
|
|
||||||
const TOKEN_KEY = 'reactnativemeteor_usertoken';
|
const TOKEN_KEY = 'reactnativemeteor_usertoken';
|
||||||
const CURRENT_SERVER = 'currentServer';
|
const CURRENT_SERVER = 'currentServer';
|
||||||
|
@ -81,7 +79,7 @@ const RocketChat = {
|
||||||
TOKEN_KEY,
|
TOKEN_KEY,
|
||||||
CURRENT_SERVER,
|
CURRENT_SERVER,
|
||||||
CERTIFICATE_KEY,
|
CERTIFICATE_KEY,
|
||||||
...restAPis,
|
...restApis,
|
||||||
...search,
|
...search,
|
||||||
callJitsi,
|
callJitsi,
|
||||||
callJitsiWithoutServer,
|
callJitsiWithoutServer,
|
||||||
|
@ -109,81 +107,11 @@ const RocketChat = {
|
||||||
checkAndReopen,
|
checkAndReopen,
|
||||||
disconnect,
|
disconnect,
|
||||||
connect,
|
connect,
|
||||||
async shareExtensionInit(server) {
|
shareExtensionInit,
|
||||||
database.setShareDB(server);
|
closeShareExtension,
|
||||||
|
|
||||||
try {
|
|
||||||
const certificate = UserPreferences.getString(`${RocketChat.CERTIFICATE_KEY}-${server}`);
|
|
||||||
SSLPinning.setCertificate(certificate, server);
|
|
||||||
} catch {
|
|
||||||
// Do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
this.shareSDK = sdk.disconnect();
|
|
||||||
this.shareSDK = sdk.initialize(server);
|
|
||||||
|
|
||||||
// set Server
|
|
||||||
const currentServer = { server };
|
|
||||||
const serversDB = database.servers;
|
|
||||||
const serversCollection = serversDB.get('servers');
|
|
||||||
try {
|
|
||||||
const serverRecord = await serversCollection.find(server);
|
|
||||||
currentServer.version = serverRecord.version;
|
|
||||||
} catch {
|
|
||||||
// Record not found
|
|
||||||
}
|
|
||||||
reduxStore.dispatch(shareSelectServer(currentServer));
|
|
||||||
|
|
||||||
RocketChat.setCustomEmojis();
|
|
||||||
|
|
||||||
try {
|
|
||||||
// set Settings
|
|
||||||
const settings = ['Accounts_AvatarBlockUnauthenticatedAccess'];
|
|
||||||
const db = database.active;
|
|
||||||
const settingsCollection = db.get('settings');
|
|
||||||
const settingsRecords = await settingsCollection.query(Q.where('id', Q.oneOf(settings))).fetch();
|
|
||||||
const parsed = Object.values(settingsRecords).map(item => ({
|
|
||||||
_id: item.id,
|
|
||||||
valueAsString: item.valueAsString,
|
|
||||||
valueAsBoolean: item.valueAsBoolean,
|
|
||||||
valueAsNumber: item.valueAsNumber,
|
|
||||||
valueAsArray: item.valueAsArray,
|
|
||||||
_updatedAt: item._updatedAt
|
|
||||||
}));
|
|
||||||
reduxStore.dispatch(shareSetSettings(this.parseSettings(parsed)));
|
|
||||||
|
|
||||||
// set User info
|
|
||||||
const userId = UserPreferences.getString(`${RocketChat.TOKEN_KEY}-${server}`);
|
|
||||||
const userCollections = serversDB.get('users');
|
|
||||||
let user = null;
|
|
||||||
if (userId) {
|
|
||||||
const userRecord = await userCollections.find(userId);
|
|
||||||
user = {
|
|
||||||
id: userRecord.id,
|
|
||||||
token: userRecord.token,
|
|
||||||
username: userRecord.username,
|
|
||||||
roles: userRecord.roles
|
|
||||||
};
|
|
||||||
}
|
|
||||||
reduxStore.dispatch(shareSetUser(user));
|
|
||||||
await RocketChat.login({ resume: user.token });
|
|
||||||
reduxStore.dispatch(encryptionInit());
|
|
||||||
} catch (e) {
|
|
||||||
log(e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
closeShareExtension() {
|
|
||||||
this.shareSDK = sdk.disconnect();
|
|
||||||
database.share = null;
|
|
||||||
|
|
||||||
reduxStore.dispatch(shareSelectServer({}));
|
|
||||||
reduxStore.dispatch(shareSetUser({}));
|
|
||||||
reduxStore.dispatch(shareSetSettings({}));
|
|
||||||
},
|
|
||||||
|
|
||||||
async e2eFetchMyKeys() {
|
async e2eFetchMyKeys() {
|
||||||
// RC 0.70.0
|
// RC 0.70.0
|
||||||
const sdk = this.shareSDK || this.sdk;
|
|
||||||
const result = await sdk.get('e2e.fetchMyKeys');
|
const result = await sdk.get('e2e.fetchMyKeys');
|
||||||
// snake_case -> camelCase
|
// snake_case -> camelCase
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
|
|
|
@ -9,19 +9,27 @@ import { Serialized, MatchPathPattern, OperationParams, PathFor, ResultFor } fro
|
||||||
|
|
||||||
class Sdk {
|
class Sdk {
|
||||||
private sdk: typeof Rocketchat;
|
private sdk: typeof Rocketchat;
|
||||||
|
private shareSdk?: typeof Rocketchat;
|
||||||
private code: any;
|
private code: any;
|
||||||
|
|
||||||
|
private initializeSdk(server: string): typeof Rocketchat {
|
||||||
|
// The app can't reconnect if reopen interval is 5s while in development
|
||||||
|
return new Rocketchat({ host: server, protocol: 'ddp', useSsl: useSsl(server), reopen: __DEV__ ? 20000 : 5000 });
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: We need to stop returning the SDK after all methods are dehydrated
|
// TODO: We need to stop returning the SDK after all methods are dehydrated
|
||||||
initialize(server: string) {
|
initialize(server: string) {
|
||||||
this.code = null;
|
this.code = null;
|
||||||
|
this.sdk = this.initializeSdk(server);
|
||||||
// The app can't reconnect if reopen interval is 5s while in development
|
|
||||||
this.sdk = new Rocketchat({ host: server, protocol: 'ddp', useSsl: useSsl(server), reopen: __DEV__ ? 20000 : 5000 });
|
|
||||||
return this.sdk;
|
return this.sdk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initializeShareExtension(server: string) {
|
||||||
|
this.shareSdk = this.initializeSdk(server);
|
||||||
|
}
|
||||||
|
|
||||||
get current() {
|
get current() {
|
||||||
return this.sdk;
|
return this.shareSdk || this.sdk;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -29,6 +37,11 @@ class Sdk {
|
||||||
* I'm returning "null" because we need to remove both instances of this.sdk here and on rocketchat.js
|
* I'm returning "null" because we need to remove both instances of this.sdk here and on rocketchat.js
|
||||||
*/
|
*/
|
||||||
disconnect() {
|
disconnect() {
|
||||||
|
if (this.shareSdk) {
|
||||||
|
this.shareSdk.disconnect();
|
||||||
|
this.shareSdk = null;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
if (this.sdk) {
|
if (this.sdk) {
|
||||||
this.sdk.disconnect();
|
this.sdk.disconnect();
|
||||||
this.sdk = null;
|
this.sdk = null;
|
||||||
|
@ -47,7 +60,7 @@ class Sdk {
|
||||||
? void
|
? void
|
||||||
: Serialized<OperationParams<'GET', MatchPathPattern<TPath>>>
|
: Serialized<OperationParams<'GET', MatchPathPattern<TPath>>>
|
||||||
): Promise<Serialized<ResultFor<'GET', MatchPathPattern<TPath>>>> {
|
): Promise<Serialized<ResultFor<'GET', MatchPathPattern<TPath>>>> {
|
||||||
return this.sdk.get(endpoint, params);
|
return this.current.get(endpoint, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
post<TPath extends PathFor<'POST'>>(
|
post<TPath extends PathFor<'POST'>>(
|
||||||
|
@ -64,7 +77,7 @@ class Sdk {
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
const isMethodCall = endpoint?.startsWith('method.call/');
|
const isMethodCall = endpoint?.startsWith('method.call/');
|
||||||
try {
|
try {
|
||||||
const result = await this.sdk.post(endpoint, params);
|
const result = await this.current.post(endpoint, params);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* if API_Use_REST_For_DDP_Calls is enabled and it's a method call,
|
* if API_Use_REST_For_DDP_Calls is enabled and it's a method call,
|
||||||
|
@ -101,7 +114,7 @@ class Sdk {
|
||||||
methodCall(...args: any[]): Promise<any> {
|
methodCall(...args: any[]): Promise<any> {
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
const result = await this.sdk?.methodCall(...args, this.code || '');
|
const result = await this.current.methodCall(...args, this.code || '');
|
||||||
return resolve(result);
|
return resolve(result);
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
if (e.error && (e.error === 'totp-required' || e.error === 'totp-invalid')) {
|
if (e.error && (e.error === 'totp-required' || e.error === 'totp-invalid')) {
|
||||||
|
@ -140,23 +153,23 @@ class Sdk {
|
||||||
}
|
}
|
||||||
|
|
||||||
subscribe(...args: any[]) {
|
subscribe(...args: any[]) {
|
||||||
return this.sdk.subscribe(...args);
|
return this.current.subscribe(...args);
|
||||||
}
|
}
|
||||||
|
|
||||||
subscribeRaw(...args: any[]) {
|
subscribeRaw(...args: any[]) {
|
||||||
return this.sdk.subscribeRaw(...args);
|
return this.current.subscribeRaw(...args);
|
||||||
}
|
}
|
||||||
|
|
||||||
subscribeRoom(...args: any[]) {
|
subscribeRoom(...args: any[]) {
|
||||||
return this.sdk.subscribeRoom(...args);
|
return this.current.subscribeRoom(...args);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsubscribe(subscription: any[]) {
|
unsubscribe(subscription: any[]) {
|
||||||
return this.sdk.unsubscribe(subscription);
|
return this.current.unsubscribe(subscription);
|
||||||
}
|
}
|
||||||
|
|
||||||
onStreamData(...args: any[]) {
|
onStreamData(...args: any[]) {
|
||||||
return this.sdk.onStreamData(...args);
|
return this.current.onStreamData(...args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
import { Q } from '@nozbe/watermelondb';
|
||||||
|
|
||||||
|
import { shareSetSettings, shareSelectServer, shareSetUser } from '../../../actions/share';
|
||||||
|
import SSLPinning from '../../../utils/sslPinning';
|
||||||
|
import log from '../../../utils/log';
|
||||||
|
import { IShareServer, IShareUser } from '../../../reducers/share';
|
||||||
|
import UserPreferences from '../../userPreferences';
|
||||||
|
import database from '../../database';
|
||||||
|
import RocketChat from '../rocketchat';
|
||||||
|
import { encryptionInit } from '../../../actions/encryption';
|
||||||
|
import { store } from '../../auxStore';
|
||||||
|
import sdk from './sdk';
|
||||||
|
|
||||||
|
export async function shareExtensionInit(server: string) {
|
||||||
|
database.setShareDB(server);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const certificate = UserPreferences.getString(`${RocketChat.CERTIFICATE_KEY}-${server}`);
|
||||||
|
if (SSLPinning && certificate) {
|
||||||
|
await SSLPinning.setCertificate(certificate, server);
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
// sdk.current.disconnect();
|
||||||
|
sdk.initializeShareExtension(server);
|
||||||
|
|
||||||
|
// set Server
|
||||||
|
const currentServer: IShareServer = {
|
||||||
|
server,
|
||||||
|
version: ''
|
||||||
|
};
|
||||||
|
const serversDB = database.servers;
|
||||||
|
const serversCollection = serversDB.get('servers');
|
||||||
|
try {
|
||||||
|
const serverRecord = await serversCollection.find(server);
|
||||||
|
currentServer.version = serverRecord.version;
|
||||||
|
} catch {
|
||||||
|
// Record not found
|
||||||
|
}
|
||||||
|
store.dispatch(shareSelectServer(currentServer));
|
||||||
|
|
||||||
|
RocketChat.setCustomEmojis();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// set Settings
|
||||||
|
const settings = ['Accounts_AvatarBlockUnauthenticatedAccess'];
|
||||||
|
const db = database.active;
|
||||||
|
const settingsCollection = db.get('settings');
|
||||||
|
const settingsRecords = await settingsCollection.query(Q.where('id', Q.oneOf(settings))).fetch();
|
||||||
|
const parsed = Object.values(settingsRecords).map(item => ({
|
||||||
|
_id: item.id,
|
||||||
|
valueAsString: item.valueAsString,
|
||||||
|
valueAsBoolean: item.valueAsBoolean,
|
||||||
|
valueAsNumber: item.valueAsNumber,
|
||||||
|
valueAsArray: item.valueAsArray,
|
||||||
|
_updatedAt: item._updatedAt
|
||||||
|
}));
|
||||||
|
store.dispatch(shareSetSettings(RocketChat.parseSettings(parsed)));
|
||||||
|
|
||||||
|
// set User info
|
||||||
|
const userId = UserPreferences.getString(`${RocketChat.TOKEN_KEY}-${server}`);
|
||||||
|
const userCollections = serversDB.get('users');
|
||||||
|
let user = null;
|
||||||
|
if (userId) {
|
||||||
|
const userRecord = await userCollections.find(userId);
|
||||||
|
user = {
|
||||||
|
id: userRecord.id,
|
||||||
|
token: userRecord.token,
|
||||||
|
username: userRecord.username,
|
||||||
|
roles: userRecord.roles
|
||||||
|
};
|
||||||
|
}
|
||||||
|
store.dispatch(shareSetUser(user as IShareUser));
|
||||||
|
if (user) {
|
||||||
|
await RocketChat.login({ resume: user.token });
|
||||||
|
}
|
||||||
|
store.dispatch(encryptionInit());
|
||||||
|
} catch (e) {
|
||||||
|
log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function closeShareExtension() {
|
||||||
|
sdk.disconnect();
|
||||||
|
database.share = null;
|
||||||
|
|
||||||
|
store.dispatch(shareSelectServer({}));
|
||||||
|
store.dispatch(shareSetUser({}));
|
||||||
|
store.dispatch(shareSetSettings({}));
|
||||||
|
}
|
|
@ -2,17 +2,17 @@ import { TActionsShare } from '../actions/share';
|
||||||
import { SHARE } from '../actions/actionsTypes';
|
import { SHARE } from '../actions/actionsTypes';
|
||||||
|
|
||||||
export interface IShareServer {
|
export interface IShareServer {
|
||||||
server: string;
|
server?: string;
|
||||||
version: string;
|
version?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TShareSettings = Record<string, string | number | boolean>;
|
export type TShareSettings = Record<string, string | number | boolean>;
|
||||||
|
|
||||||
export interface IShareUser {
|
export interface IShareUser {
|
||||||
id: string;
|
id?: string;
|
||||||
token: string;
|
token?: string;
|
||||||
username: string;
|
username?: string;
|
||||||
roles: string[];
|
roles?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IShare {
|
export interface IShare {
|
||||||
|
@ -22,8 +22,8 @@ export interface IShare {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const initialState: IShare = {
|
export const initialState: IShare = {
|
||||||
user: {} as IShareUser,
|
user: {},
|
||||||
server: {} as IShareServer,
|
server: {},
|
||||||
settings: {}
|
settings: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import UserPreferences from './lib/userPreferences';
|
||||||
import Navigation from './lib/ShareNavigation';
|
import Navigation from './lib/ShareNavigation';
|
||||||
import store from './lib/createStore';
|
import store from './lib/createStore';
|
||||||
import { initStore } from './lib/auxStore';
|
import { initStore } from './lib/auxStore';
|
||||||
|
import { closeShareExtension, shareExtensionInit } from './lib/rocketchat/services/shareExtension';
|
||||||
import { defaultHeader, getActiveRouteName, navigationTheme, themedHeader } from './utils/navigation';
|
import { defaultHeader, getActiveRouteName, navigationTheme, themedHeader } from './utils/navigation';
|
||||||
import RocketChat from './lib/rocketchat';
|
import RocketChat from './lib/rocketchat';
|
||||||
import { ThemeContext } from './theme';
|
import { ThemeContext } from './theme';
|
||||||
|
@ -107,7 +108,7 @@ class Root extends React.Component<{}, IState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount(): void {
|
componentWillUnmount(): void {
|
||||||
RocketChat.closeShareExtension();
|
closeShareExtension();
|
||||||
unsubscribeTheme();
|
unsubscribeTheme();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +118,7 @@ class Root extends React.Component<{}, IState> {
|
||||||
if (currentServer) {
|
if (currentServer) {
|
||||||
await localAuthenticate(currentServer);
|
await localAuthenticate(currentServer);
|
||||||
this.setState({ root: 'inside' });
|
this.setState({ root: 'inside' });
|
||||||
await RocketChat.shareExtensionInit(currentServer);
|
await shareExtensionInit(currentServer);
|
||||||
} else {
|
} else {
|
||||||
this.setState({ root: 'outside' });
|
this.setState({ root: 'outside' });
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { Q, Model } from '@nozbe/watermelondb';
|
||||||
import I18n from '../i18n';
|
import I18n from '../i18n';
|
||||||
import StatusBar from '../containers/StatusBar';
|
import StatusBar from '../containers/StatusBar';
|
||||||
import ServerItem, { ROW_HEIGHT } from '../presentation/ServerItem';
|
import ServerItem, { ROW_HEIGHT } from '../presentation/ServerItem';
|
||||||
import RocketChat from '../lib/rocketchat';
|
import { shareExtensionInit } from '../lib/rocketchat/services/shareExtension';
|
||||||
import database from '../lib/database';
|
import database from '../lib/database';
|
||||||
import SafeAreaView from '../containers/SafeAreaView';
|
import SafeAreaView from '../containers/SafeAreaView';
|
||||||
import * as List from '../containers/List';
|
import * as List from '../containers/List';
|
||||||
|
@ -50,7 +50,7 @@ class SelectServerView extends React.Component<ISelectServerViewProps, ISelectSe
|
||||||
|
|
||||||
navigation.navigate('ShareListView');
|
navigation.navigate('ShareListView');
|
||||||
if (currentServer !== server) {
|
if (currentServer !== server) {
|
||||||
await RocketChat.shareExtensionInit(server);
|
await shareExtensionInit(server);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue