Passcode: Display error if passcode wasn't created (#3149)
This commit is contained in:
parent
c8d64dc929
commit
cc0e00ad2d
@ -31,6 +31,7 @@ import { formatDateToString } from '../../../util/dateFormat';
|
||||
import { setPermanentWebVersion } from '../../../util/permanentWebVersion';
|
||||
import { clearWebsync } from '../../../util/websync';
|
||||
import {
|
||||
selectCanSetPasscode,
|
||||
selectCurrentMessageList, selectIsCurrentUserPremium, selectTabState, selectTheme,
|
||||
} from '../../../global/selectors';
|
||||
import useLang from '../../../hooks/useLang';
|
||||
@ -82,7 +83,7 @@ type StateProps =
|
||||
isConnectionStatusMinimized: ISettings['isConnectionStatusMinimized'];
|
||||
areChatsLoaded?: boolean;
|
||||
hasPasscode?: boolean;
|
||||
isAuthRememberMe?: boolean;
|
||||
canSetPasscode?: boolean;
|
||||
}
|
||||
& Pick<GlobalState, 'connectionState' | 'isSyncing' | 'archiveSettings'>
|
||||
& Pick<TabState, 'canInstall'>;
|
||||
@ -114,7 +115,7 @@ const LeftMainHeader: FC<OwnProps & StateProps> = ({
|
||||
isConnectionStatusMinimized,
|
||||
areChatsLoaded,
|
||||
hasPasscode,
|
||||
isAuthRememberMe,
|
||||
canSetPasscode,
|
||||
canInstall,
|
||||
archiveSettings,
|
||||
}) => {
|
||||
@ -158,7 +159,7 @@ const LeftMainHeader: FC<OwnProps & StateProps> = ({
|
||||
}
|
||||
}, [hasPasscode]);
|
||||
|
||||
useHotkeys(isAuthRememberMe ? {
|
||||
useHotkeys(canSetPasscode ? {
|
||||
'Ctrl+Shift+L': handleLockScreenHotkey,
|
||||
'Alt+Shift+L': handleLockScreenHotkey,
|
||||
'Meta+Shift+L': handleLockScreenHotkey,
|
||||
@ -481,7 +482,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
hasPasscode: Boolean(global.passcode.hasPasscode),
|
||||
canInstall: Boolean(tabState.canInstall),
|
||||
archiveSettings,
|
||||
isAuthRememberMe: global.authRememberMe,
|
||||
canSetPasscode: selectCanSetPasscode(global),
|
||||
};
|
||||
},
|
||||
)(LeftMainHeader));
|
||||
|
||||
@ -5,7 +5,7 @@ import { getActions, withGlobal } from '../../../global';
|
||||
import type { ApiPrivacySettings } from '../../../types';
|
||||
import { SettingsScreens } from '../../../types';
|
||||
|
||||
import { selectIsCurrentUserPremium } from '../../../global/selectors';
|
||||
import { selectCanSetPasscode, selectIsCurrentUserPremium } from '../../../global/selectors';
|
||||
|
||||
import useLang from '../../../hooks/useLang';
|
||||
import useHistoryBack from '../../../hooks/useHistoryBack';
|
||||
@ -23,7 +23,7 @@ type StateProps = {
|
||||
isCurrentUserPremium?: boolean;
|
||||
hasPassword?: boolean;
|
||||
hasPasscode?: boolean;
|
||||
isAuthRememberMe?: boolean;
|
||||
canSetPasscode?: boolean;
|
||||
blockedCount: number;
|
||||
webAuthCount: number;
|
||||
isSensitiveEnabled?: boolean;
|
||||
@ -63,7 +63,7 @@ const SettingsPrivacy: FC<OwnProps & StateProps> = ({
|
||||
privacyPhoneP2P,
|
||||
onScreenSelect,
|
||||
onReset,
|
||||
isAuthRememberMe,
|
||||
canSetPasscode,
|
||||
}) => {
|
||||
const {
|
||||
loadPrivacySettings,
|
||||
@ -160,7 +160,7 @@ const SettingsPrivacy: FC<OwnProps & StateProps> = ({
|
||||
{lang('BlockedUsers')}
|
||||
<span className="settings-item__current-value">{blockedCount || ''}</span>
|
||||
</ListItem>
|
||||
{isAuthRememberMe && (
|
||||
{canSetPasscode && (
|
||||
<ListItem
|
||||
icon="key"
|
||||
narrow
|
||||
@ -394,7 +394,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
privacyPhoneCall: privacy.phoneCall,
|
||||
privacyPhoneP2P: privacy.phoneP2P,
|
||||
canDisplayChatInTitle,
|
||||
isAuthRememberMe: global.authRememberMe,
|
||||
canSetPasscode: selectCanSetPasscode(global),
|
||||
};
|
||||
},
|
||||
)(SettingsPrivacy));
|
||||
|
||||
@ -3,14 +3,15 @@ import { addActionHandler, setGlobal, getGlobal } from '../../index';
|
||||
import { clearPasscodeSettings, updatePasscodeSettings } from '../../reducers';
|
||||
import { clearStoredSession, loadStoredSession, storeSession } from '../../../util/sessions';
|
||||
import {
|
||||
clearEncryptedSession, decryptSession, encryptSession, setupPasscode,
|
||||
clearEncryptedSession, decryptSession, encryptSession, forgetPasscode, setupPasscode,
|
||||
} from '../../../util/passcode';
|
||||
import { forceUpdateCache, migrateCache, serializeGlobal } from '../../cache';
|
||||
import { onBeforeUnload } from '../../../util/schedulers';
|
||||
import { cloneDeep } from '../../../util/iteratees';
|
||||
import { INITIAL_GLOBAL_STATE } from '../../initialState';
|
||||
import type { ActionReturnType } from '../../types';
|
||||
import { signalPasscodeHash } from '../../../util/establishMultitabRole';
|
||||
import { getCurrentTabId, signalPasscodeHash } from '../../../util/establishMultitabRole';
|
||||
import { SettingsScreens } from '../../../types';
|
||||
|
||||
let noLockOnUnload = false;
|
||||
onBeforeUnload(() => {
|
||||
@ -21,7 +22,7 @@ onBeforeUnload(() => {
|
||||
});
|
||||
|
||||
addActionHandler('setPasscode', async (global, actions, payload): Promise<void> => {
|
||||
const { passcode } = payload;
|
||||
const { passcode, tabId = getCurrentTabId() } = payload;
|
||||
global = updatePasscodeSettings(global, {
|
||||
isLoading: true,
|
||||
});
|
||||
@ -36,18 +37,34 @@ addActionHandler('setPasscode', async (global, actions, payload): Promise<void>
|
||||
isLoading: false,
|
||||
}));
|
||||
|
||||
await encryptSession(sessionJson, globalJson);
|
||||
try {
|
||||
await encryptSession(sessionJson, globalJson);
|
||||
|
||||
signalPasscodeHash();
|
||||
global = getGlobal();
|
||||
global = updatePasscodeSettings(global, {
|
||||
hasPasscode: true,
|
||||
error: undefined,
|
||||
isLoading: false,
|
||||
});
|
||||
setGlobal(global);
|
||||
signalPasscodeHash();
|
||||
global = getGlobal();
|
||||
global = updatePasscodeSettings(global, {
|
||||
hasPasscode: true,
|
||||
error: undefined,
|
||||
isLoading: false,
|
||||
});
|
||||
setGlobal(global);
|
||||
|
||||
forceUpdateCache(true);
|
||||
forceUpdateCache(true);
|
||||
} catch (err: any) {
|
||||
forgetPasscode();
|
||||
|
||||
global = getGlobal();
|
||||
global = updatePasscodeSettings(global, {
|
||||
isLoading: false,
|
||||
});
|
||||
setGlobal(global);
|
||||
|
||||
actions.showNotification({
|
||||
message: 'Failed to set passcode',
|
||||
tabId,
|
||||
});
|
||||
actions.requestNextSettingsScreen({ screen: SettingsScreens.PasscodeDisabled, tabId });
|
||||
}
|
||||
});
|
||||
|
||||
addActionHandler('clearPasscode', (global): ActionReturnType => {
|
||||
|
||||
@ -16,6 +16,7 @@ import { getCurrentTabId, reestablishMasterToSelf } from '../util/establishMulti
|
||||
import { updateTabState } from './reducers/tabs';
|
||||
import type { ActionReturnType, GlobalState } from './types';
|
||||
import { isLocalMessageId } from './helpers';
|
||||
import { isCacheApiSupported } from '../util/cacheApi';
|
||||
|
||||
initCache();
|
||||
|
||||
@ -129,6 +130,12 @@ addActionHandler('init', (global, actions, payload): ActionReturnType => {
|
||||
actions.initApi();
|
||||
}
|
||||
|
||||
isCacheApiSupported().then((isSupported) => {
|
||||
global = getGlobal();
|
||||
global.isCacheApiSupported = isSupported;
|
||||
setGlobal(global);
|
||||
});
|
||||
|
||||
return updateTabState(global, {
|
||||
messageLists: parsedMessageList ? [parsedMessageList] : initialTabState.messageLists,
|
||||
}, tabId);
|
||||
|
||||
@ -11,3 +11,7 @@ export function selectNotifyExceptions<T extends GlobalState>(global: T) {
|
||||
export function selectLanguageCode<T extends GlobalState>(global: T) {
|
||||
return global.settings.byKey.language.replace('-raw', '');
|
||||
}
|
||||
|
||||
export function selectCanSetPasscode<T extends GlobalState>(global: T) {
|
||||
return global.authRememberMe && global.isCacheApiSupported;
|
||||
}
|
||||
|
||||
@ -579,6 +579,7 @@ export type GlobalState = {
|
||||
appConfig?: ApiAppConfig;
|
||||
hasWebAuthTokenFailed?: boolean;
|
||||
hasWebAuthTokenPasswordRequired?: true;
|
||||
isCacheApiSupported?: boolean;
|
||||
connectionState?: ApiUpdateConnectionStateType;
|
||||
currentUserId?: string;
|
||||
isSyncing?: boolean;
|
||||
@ -2334,7 +2335,7 @@ export interface ActionPayloads {
|
||||
connectToActivePhoneCall: undefined;
|
||||
|
||||
// Passcode
|
||||
setPasscode: { passcode: string };
|
||||
setPasscode: { passcode: string } & WithTabId;
|
||||
clearPasscode: undefined;
|
||||
lockScreen: undefined;
|
||||
decryptSession: { passcode: string };
|
||||
|
||||
@ -1,6 +1,13 @@
|
||||
// eslint-disable-next-line no-restricted-globals
|
||||
const cacheApi = self.caches;
|
||||
|
||||
let isSupported: boolean | undefined;
|
||||
|
||||
export async function isCacheApiSupported() {
|
||||
isSupported = isSupported ?? await cacheApi.has('test').then(() => true).catch(() => false);
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
export enum Type {
|
||||
Text,
|
||||
Blob,
|
||||
@ -67,7 +74,7 @@ export async function fetch(
|
||||
|
||||
export async function save(cacheName: string, key: string, data: AnyLiteral | Blob | ArrayBuffer | string) {
|
||||
if (!cacheApi) {
|
||||
return undefined;
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
@ -78,11 +85,12 @@ export async function save(cacheName: string, key: string, data: AnyLiteral | Bl
|
||||
const request = new Request(key.replace(/:/g, '_'));
|
||||
const response = new Response(cacheData);
|
||||
const cache = await cacheApi.open(cacheName);
|
||||
return await cache.put(request, response);
|
||||
await cache.put(request, response);
|
||||
return true;
|
||||
} catch (err) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(err);
|
||||
return undefined;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -117,7 +117,12 @@ function sha256(plaintext: string) {
|
||||
}
|
||||
|
||||
async function store(key: string, value: ArrayBuffer) {
|
||||
await cacheApi.save(PASSCODE_CACHE_NAME, key, value);
|
||||
const isSuccessful = await cacheApi.save(PASSCODE_CACHE_NAME, key, value);
|
||||
if (isSuccessful) {
|
||||
return;
|
||||
}
|
||||
|
||||
throw new Error('Failed to save to cache');
|
||||
}
|
||||
|
||||
function load(key: string) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user