Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 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
11 changes: 11 additions & 0 deletions app/lib/rocketchat/rocketchat.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,17 @@ const RocketChat = {
message: I18n.t('Not_RC_Server', { contact: I18n.t('Contact_your_server_admin') })
};
},
async getServerTimeSync(server) {
Comment thread
reinaldonetof marked this conversation as resolved.
Outdated
try {
const response = await RNFetchBlob.fetch('GET', `${server}/_timesync`);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just realized we should do a race here.
This request might take some time to happen in some cases (poor connection fast enough to try to make the request, but not slow enough to be offline).
In such cases, it'd be better to just try for some time and show the lock screen than hanging for 10s.

I think a race of 2 seconds should be ok.
DM me if you're in doubt.

if (response?.data) {
return parseInt(response.data);
}
return null;
} catch {
return null;
}
},
stopListener(listener) {
return listener && listener.stop();
},
Expand Down
20 changes: 14 additions & 6 deletions app/utils/localAuthentication.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import * as LocalAuthentication from 'expo-local-authentication';
import moment from 'moment';
import RNBootSplash from 'react-native-bootsplash';
import AsyncStorage from '@react-native-community/async-storage';
import { sha256 } from 'js-sha256';
import moment from 'moment';

import UserPreferences from '../lib/userPreferences';
import { store } from '../lib/auxStore';
import database from '../lib/database';
import RocketChat from '../lib/rocketchat';
import {
ATTEMPTS_KEY,
BIOMETRY_ENABLED_KEY,
Expand All @@ -22,15 +23,19 @@ import EventEmitter from './events';
import { isIOS } from './deviceInfo';

export const saveLastLocalAuthenticationSession = async (server: string, serverRecord?: TServerModel): Promise<void> => {
// We need to get the timesync again because this function is been called when we turn the app to background too
const timesync = await RocketChat.getServerTimeSync(server);

const serversDB = database.servers;
const serversCollection = serversDB.get('servers');
await serversDB.write(async () => {
try {
if (!serverRecord) {
serverRecord = (await serversCollection.find(server)) as TServerModel;
serverRecord = await serversCollection.find(server);
}
const time = timesync || 0;
await serverRecord.update(record => {
record.lastLocalAuthenticatedSession = new Date();
record.lastLocalAuthenticatedSession = new Date(time);
});
} catch (e) {
// Do nothing
Expand Down Expand Up @@ -103,6 +108,9 @@ export const localAuthenticate = async (server: string): Promise<void> => {

// if screen lock is enabled
if (serverRecord?.autoLock) {
// Get time from server
const timesync = await RocketChat.getServerTimeSync(server);

// Make sure splash screen has been hidden
try {
await RNBootSplash.hide();
Expand All @@ -116,10 +124,10 @@ export const localAuthenticate = async (server: string): Promise<void> => {
// `checkHasPasscode` results newPasscode = true if a passcode has been set
if (!result?.newPasscode) {
// diff to last authenticated session
const diffToLastSession = moment().diff(serverRecord?.lastLocalAuthenticatedSession, 'seconds');
const diffToLastSession = moment(timesync).diff(serverRecord?.lastLocalAuthenticatedSession, 'seconds');

// if last authenticated session is older than configured auto lock time, authentication is required
if (diffToLastSession >= serverRecord.autoLockTime!) {
// if can't receive the timesync value from the server or last authenticated session is older than configured auto lock time, authentication is required
Comment thread
reinaldonetof marked this conversation as resolved.
Outdated
if (!timesync || (serverRecord?.autoLockTime && diffToLastSession >= serverRecord.autoLockTime)) {
// set isLocalAuthenticated to false
store.dispatch(setLocalAuthenticated(false));

Expand Down