diff --git a/src/App.tsx b/src/App.tsx index 393346f4b..cb4ddfaff 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -181,7 +181,7 @@ export default withGlobal( authState: global.authState, isScreenLocked: global.passcode?.isScreenLocked, hasPasscode: global.passcode?.hasPasscode, - hasWebAuthTokenFailed: global.hasWebAuthTokenFailed, + hasWebAuthTokenFailed: global.hasWebAuthTokenFailed || global.hasWebAuthTokenPasswordRequired, }; }, )(App); diff --git a/src/api/gramjs/methods/auth.ts b/src/api/gramjs/methods/auth.ts index c540fecc3..9f1b6847f 100644 --- a/src/api/gramjs/methods/auth.ts +++ b/src/api/gramjs/methods/auth.ts @@ -54,10 +54,11 @@ export function onRequestCode(isCodeViaApp = false) { }); } -export function onRequestPassword(hint?: string) { +export function onRequestPassword(hint?: string, noReset?: boolean) { onUpdate({ ...buildAuthStateUpdate('authorizationStateWaitPassword'), hint, + noReset, }); return new Promise((resolve) => { diff --git a/src/api/types/updates.ts b/src/api/types/updates.ts index 244ed5f66..a79b3ce1d 100644 --- a/src/api/types/updates.ts +++ b/src/api/types/updates.ts @@ -61,6 +61,7 @@ export type ApiUpdateAuthorizationState = { authorizationState: ApiUpdateAuthorizationStateType; isCodeViaApp?: boolean; hint?: string; + noReset?: boolean; qrCode?: { token: string; expires: number }; }; diff --git a/src/components/auth/Auth.tsx b/src/components/auth/Auth.tsx index bec4418e3..354e65a30 100644 --- a/src/components/auth/Auth.tsx +++ b/src/components/auth/Auth.tsx @@ -24,21 +24,21 @@ type OwnProps = { isActive: boolean; }; -type StateProps = Pick; +type StateProps = Pick; const Auth: FC = ({ - isActive, authState, + isActive, authState, hasWebAuthTokenPasswordRequired, }) => { const { reset, initApi, returnToAuthPhoneNumber, goToAuthQrCode, } = getActions(); useEffect(() => { - if (isActive) { + if (isActive && !hasWebAuthTokenPasswordRequired) { reset(); initApi(); } - }, [isActive, reset, initApi]); + }, [isActive, reset, initApi, hasWebAuthTokenPasswordRequired]); const isMobile = PLATFORM_ENV === 'iOS' || PLATFORM_ENV === 'Android'; @@ -113,5 +113,5 @@ const Auth: FC = ({ }; export default memo(withGlobal( - (global): StateProps => pick(global, ['authState']), + (global): StateProps => pick(global, ['authState', 'hasWebAuthTokenPasswordRequired']), )(Auth)); diff --git a/src/global/actions/apiUpdaters/initial.ts b/src/global/actions/apiUpdaters/initial.ts index 742a34bb6..296f64cbd 100644 --- a/src/global/actions/apiUpdaters/initial.ts +++ b/src/global/actions/apiUpdaters/initial.ts @@ -114,6 +114,7 @@ function onUpdateAuthorizationState(update: ApiUpdateAuthorizationState) { setGlobal({ ...global, authHint: update.hint, + hasWebAuthTokenPasswordRequired: update.noReset, }); break; case 'authorizationStateWaitQrCode': diff --git a/src/global/types.ts b/src/global/types.ts index 3e20f8f9c..f34d5815f 100644 --- a/src/global/types.ts +++ b/src/global/types.ts @@ -141,6 +141,7 @@ export type GlobalState = { appConfig?: ApiAppConfig; canInstall?: boolean; hasWebAuthTokenFailed?: boolean; + hasWebAuthTokenPasswordRequired?: boolean; isChatInfoShown: boolean; isStatisticsShown?: boolean; isLeftColumnShown: boolean; diff --git a/src/lib/gramjs/client/auth.ts b/src/lib/gramjs/client/auth.ts index c7aae74df..ecb7d17be 100644 --- a/src/lib/gramjs/client/auth.ts +++ b/src/lib/gramjs/client/auth.ts @@ -6,9 +6,9 @@ import { computeCheck as computePasswordSrpCheck } from '../Password'; export interface UserAuthParams { phoneNumber: string | (() => Promise); - webAuthTokenFailed: VoidFunction; + webAuthTokenFailed: () => void; phoneCode: (isCodeViaApp?: boolean) => Promise; - password: (hint?: string) => Promise; + password: (hint?: string, noReset?: boolean) => Promise; firstAndLastNames: () => Promise<[string, string?]>; qrCode: (qrCode: { token: Buffer; expires: number }) => Promise; onError: (err: Error) => void; @@ -87,11 +87,11 @@ async function signInUserWithWebToken( throw new Error('SIGN_UP_REQUIRED'); } } catch (err: any) { - authParams.webAuthTokenFailed(); - client._log.error(`Failed to login with web token: ${err}`); if (err.message === 'SESSION_PASSWORD_NEEDED') { - return signInWithPassword(client, apiCredentials, authParams); + return signInWithPassword(client, apiCredentials, authParams, true); } else { + client._log.error(`Failed to login with web token: ${err}`); + authParams.webAuthTokenFailed(); return signInUserWithPreferredMethod(client, apiCredentials, { ...authParams, webAuthToken: undefined, @@ -344,13 +344,13 @@ async function sendCode( } async function signInWithPassword( - client: TelegramClient, apiCredentials: ApiCredentials, authParams: UserAuthParams, + client: TelegramClient, apiCredentials: ApiCredentials, authParams: UserAuthParams, noReset = false, ): Promise { // eslint-disable-next-line no-constant-condition while (1) { try { const passwordSrpResult = await client.invoke(new Api.account.GetPassword()); - const password = await authParams.password(passwordSrpResult.hint); + const password = await authParams.password(passwordSrpResult.hint, noReset); if (!password) { throw new Error('Password is empty'); }