diff --git a/app/definitions/IServer.ts b/app/definitions/IServer.ts index a3ac17e0b..62664cd87 100644 --- a/app/definitions/IServer.ts +++ b/app/definitions/IServer.ts @@ -81,6 +81,7 @@ export interface IServer { E2E_Enable: boolean; supportedVersions?: ISupportedVersionsData; supportedVersionsWarningAt?: Date; + supportedVersionsUpdatedAt?: Date; } export type TServerModel = IServer & Model; diff --git a/app/lib/database/model/servers/Server.js b/app/lib/database/model/servers/Server.js index 11718cd98..2d57113e4 100644 --- a/app/lib/database/model/servers/Server.js +++ b/app/lib/database/model/servers/Server.js @@ -38,4 +38,6 @@ export default class Server extends Model { @json('supported_versions', sanitizer) supportedVersions; @date('supported_versions_warning_at') supportedVersionsWarningAt; + + @date('supported_versions_updated_at') supportedVersionsUpdatedAt; } diff --git a/app/lib/database/model/servers/migrations.js b/app/lib/database/model/servers/migrations.js index 31d28ee41..5a3fa8ff9 100644 --- a/app/lib/database/model/servers/migrations.js +++ b/app/lib/database/model/servers/migrations.js @@ -131,6 +131,21 @@ export default schemaMigrations({ ] }) ] + }, + { + toVersion: 15, + steps: [ + addColumns({ + table: 'servers', + columns: [ + { + name: 'supported_versions_updated_at', + type: 'number', + isOptional: true + } + ] + }) + ] } ] }); diff --git a/app/lib/database/schema/servers.js b/app/lib/database/schema/servers.js index 911566a9c..4aedcd93f 100644 --- a/app/lib/database/schema/servers.js +++ b/app/lib/database/schema/servers.js @@ -1,7 +1,7 @@ import { appSchema, tableSchema } from '@nozbe/watermelondb'; export default appSchema({ - version: 14, + version: 15, tables: [ tableSchema({ name: 'users', @@ -40,7 +40,8 @@ export default appSchema({ { name: 'enterprise_modules', type: 'string', isOptional: true }, { name: 'e2e_enable', type: 'boolean', isOptional: true }, { name: 'supported_versions', type: 'string', isOptional: true }, - { name: 'supported_versions_warning_at', type: 'number', isOptional: true } + { name: 'supported_versions_warning_at', type: 'number', isOptional: true }, + { name: 'supported_versions_updated_at', type: 'number', isOptional: true } ] }), tableSchema({ diff --git a/app/lib/methods/getServerInfo.ts b/app/lib/methods/getServerInfo.ts index ecb95354e..4954c01dd 100644 --- a/app/lib/methods/getServerInfo.ts +++ b/app/lib/methods/getServerInfo.ts @@ -1,6 +1,7 @@ import RNFetchBlob from 'rn-fetch-blob'; import { settings as RocketChatSettings } from '@rocket.chat/sdk'; import { KJUR } from 'jsrsasign'; +import moment from 'moment'; import { getSupportedVersionsCloud } from '../services/restApi'; import { TCloudInfo, IServerInfo, ISupportedVersions, ISupportedVersionsData, IApiServerInfo } from '../../definitions'; @@ -8,6 +9,7 @@ import { selectServerFailure } from '../../actions/server'; import { store } from '../store/auxStore'; import I18n from '../../i18n'; import { SIGNED_SUPPORTED_VERSIONS_PUBLIC_KEY } from '../constants'; +import { getServerById } from '../database/services/Server'; interface IServerInfoFailure { success: false; @@ -20,6 +22,8 @@ interface IServerInfoSuccess extends IServerInfo { export type TServerInfoResult = IServerInfoSuccess | IServerInfoFailure; +const SV_CLOUD_UPDATE_INTERVAL = 12; // hours + // Verifies if JWT is valid and returns the payload const verifyJWT = (jwt?: string): ISupportedVersionsData | null => { try { @@ -57,6 +61,18 @@ export async function getServerInfo(server: string): Promise // if backend doesn't have supported versions or JWT is invalid, request from cloud if (!supportedVersions) { + // fetches from cloud only every 12h + const serverRecord = await getServerById(server); + if ( + serverRecord?.supportedVersionsUpdatedAt && + moment(new Date()).diff(serverRecord?.supportedVersionsUpdatedAt, 'hours') <= SV_CLOUD_UPDATE_INTERVAL + ) { + return { + ...jsonRes, + success: true + }; + } + const cloudInfo = await getCloudInfo(server); // Makes use of signed JWT to get supported versions diff --git a/app/sagas/deepLinking.js b/app/sagas/deepLinking.js index 474e4a7f2..4be3cf8e7 100644 --- a/app/sagas/deepLinking.js +++ b/app/sagas/deepLinking.js @@ -14,7 +14,7 @@ import { loginRequest } from '../actions/login'; import log from '../lib/methods/helpers/log'; import { RootEnum } from '../definitions'; import { CURRENT_SERVER, TOKEN_KEY } from '../lib/constants'; -import { callJitsi, callJitsiWithoutServer, canOpenRoom } from '../lib/methods'; +import { callJitsi, callJitsiWithoutServer, canOpenRoom, getServerInfo } from '../lib/methods'; import { Services } from '../lib/services'; const roomTypes = { @@ -163,7 +163,7 @@ const handleOpen = function* handleOpen({ params }) { // do nothing? } // if deep link is from a different server - const result = yield Services.getServerInfo(host); + const result = yield getServerInfo(host); if (!result.success) { // Fallback to prevent the app from being stuck on splash screen yield fallbackNavigation(); diff --git a/app/sagas/selectServer.ts b/app/sagas/selectServer.ts index cfb26697b..40ec2ebec 100644 --- a/app/sagas/selectServer.ts +++ b/app/sagas/selectServer.ts @@ -73,6 +73,7 @@ const upsertServer = async function ({ server, serverInfo }: { server: string; s r.version = serverVersion; if (serverInfo.supportedVersions) { r.supportedVersions = serverInfo.supportedVersions; + r.supportedVersionsUpdatedAt = new Date(); } }); }); @@ -83,10 +84,11 @@ const upsertServer = async function ({ server, serverInfo }: { server: string; s await serversDB.write(async () => { newRecord = await serversCollection.create(r => { r._raw = sanitizedRaw({ id: server }, serversCollection.schema); + r.version = serverVersion; if (serverInfo.supportedVersions) { r.supportedVersions = serverInfo.supportedVersions; + r.supportedVersionsUpdatedAt = new Date(); } - r.version = serverVersion; }); }); if (newRecord) {