Authentication state
Handle SESSION_REVOKED on password page
This commit is contained in:
parent
f4fa88308c
commit
1d9bd1f620
@ -12,6 +12,7 @@ import VideoPlayer from "../lib/mediaPlayer";
|
||||
import { RichTextProcessor } from "../lib/richtextprocessor";
|
||||
import $rootScope from "../lib/rootScope";
|
||||
import { cancelEvent, fillPropertyValue, findUpClassName, generatePathData } from "../lib/utils";
|
||||
import animationIntersector from "./animationIntersector";
|
||||
import appMediaPlaybackController from "./appMediaPlaybackController";
|
||||
import AvatarElement from "./avatar";
|
||||
import ButtonIcon from "./buttonIcon";
|
||||
@ -244,6 +245,7 @@ class AppMediaViewerBase<ContentAdditionType extends string, ButtonsAdditionType
|
||||
promise.finally(() => {
|
||||
this.wholeDiv.remove();
|
||||
$rootScope.overlayIsActive = false;
|
||||
animationIntersector.checkAnimations(false);
|
||||
});
|
||||
|
||||
return promise;
|
||||
@ -846,6 +848,7 @@ class AppMediaViewerBase<ContentAdditionType extends string, ButtonsAdditionType
|
||||
void this.wholeDiv.offsetLeft; // reflow
|
||||
this.wholeDiv.classList.add('active');
|
||||
$rootScope.overlayIsActive = true;
|
||||
animationIntersector.checkAnimations(true);
|
||||
}
|
||||
|
||||
////////this.log('wasActive:', wasActive);
|
||||
|
@ -140,7 +140,7 @@ export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTai
|
||||
|
||||
let img: HTMLImageElement;
|
||||
if(message) {
|
||||
if(!canAutoplay && doc.thumbs?.length) {
|
||||
if(!canAutoplay) {
|
||||
return wrapPhoto(doc, message, container, boxWidth, boxHeight, withTail, isOut, lazyLoadQueue, middleware);
|
||||
}
|
||||
|
||||
@ -485,6 +485,10 @@ export function wrapPhoto(photo: MyPhoto | MyDocument, message: any, container:
|
||||
}
|
||||
}
|
||||
|
||||
if(!((photo as MyPhoto).sizes || (photo as MyDocument).thumbs)) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
//console.log('wrapPhoto downloaded:', photo, photo.downloaded, container);
|
||||
|
||||
const cacheContext = appPhotosManager.getCacheContext(photo);
|
||||
|
@ -16,7 +16,7 @@ export default class EventListenerBase<Listeners extends {[name: string]: Functi
|
||||
(this.listeners[name] ?? (this.listeners[name] = [])).push({callback, once});
|
||||
|
||||
if(this.listenerResults.hasOwnProperty(name)) {
|
||||
callback(this.listenerResults[name]);
|
||||
callback(...this.listenerResults[name]);
|
||||
|
||||
if(once) {
|
||||
this.removeListener(name, callback);
|
||||
|
3
src/layer.d.ts
vendored
3
src/layer.d.ts
vendored
@ -1239,7 +1239,8 @@ export namespace AuthSentCode {
|
||||
type: AuthSentCodeType,
|
||||
phone_code_hash: string,
|
||||
next_type?: AuthCodeType,
|
||||
timeout?: number
|
||||
timeout?: number,
|
||||
phone_number?: string
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
import type { Dialog, DialogsStorage, FiltersStorage } from './appMessagesManager';
|
||||
import type { AppStickersManager } from './appStickersManager';
|
||||
import type { AppPeersManager } from './appPeersManager';
|
||||
import { App, MOUNT_CLASS_TO, UserAuth } from '../mtproto/mtproto_config';
|
||||
import EventListenerBase from '../../helpers/eventListenerBase';
|
||||
import $rootScope from '../rootScope';
|
||||
@ -8,6 +7,7 @@ import AppStorage from '../storage';
|
||||
import { logger } from '../logger';
|
||||
import type { AppUsersManager } from './appUsersManager';
|
||||
import type { AppChatsManager } from './appChatsManager';
|
||||
import type { AuthState } from '../../types';
|
||||
|
||||
const REFRESH_EVERY = 24 * 60 * 60 * 1000; // 1 day
|
||||
const STATE_VERSION = App.version;
|
||||
@ -28,7 +28,8 @@ type State = Partial<{
|
||||
topPeers: number[],
|
||||
recentSearch: number[],
|
||||
stickerSets: AppStickersManager['stickerSets'],
|
||||
version: typeof STATE_VERSION
|
||||
version: typeof STATE_VERSION,
|
||||
authState: AuthState
|
||||
}>;
|
||||
|
||||
const REFRESH_KEYS = ['dialogs', 'allDialogsLoaded', 'messages', 'contactsList', 'stateCreatedTime',
|
||||
@ -80,7 +81,11 @@ export class AppStateManager extends EventListenerBase<{
|
||||
//return resolve();
|
||||
|
||||
if(auth?.id) {
|
||||
// ! Warning ! DON'T delete this
|
||||
this.state.authState = {_: 'authStateSignedIn'};
|
||||
$rootScope.$broadcast('user_auth', {id: auth.id});
|
||||
} else if(!this.state.authState) {
|
||||
this.state.authState = {_: 'authStateSignIn'};
|
||||
}
|
||||
|
||||
//console.timeEnd('load state');
|
||||
|
@ -1,4 +1,6 @@
|
||||
import mediaSizes from '../helpers/mediaSizes';
|
||||
import { AuthSentCode, AuthSentCodeType } from '../layer';
|
||||
import appStateManager from '../lib/appManagers/appStateManager';
|
||||
import LottieLoader, { RLottiePlayer } from '../lib/lottieLoader';
|
||||
//import CryptoWorker from '../lib/crypto/cryptoworker';
|
||||
//import apiManager from '../lib/mtproto/apiManager';
|
||||
@ -10,19 +12,9 @@ import pagePassword from './pagePassword';
|
||||
import pageSignIn from './pageSignIn';
|
||||
import pageSignUp from './pageSignUp';
|
||||
|
||||
let authCode: {
|
||||
_: string, // 'auth.sentCode'
|
||||
pFlags: any, // {}
|
||||
flags: number,
|
||||
type: {
|
||||
_: string, // 'auth.sentCodeTypeSms',
|
||||
length: number
|
||||
},
|
||||
phone_code_hash: string,
|
||||
phone_number: string
|
||||
} = null;
|
||||
let authCode: AuthSentCode.authSentCode = null;
|
||||
|
||||
const EDITONSAMEPAGE = false;
|
||||
//const EDITONSAMEPAGE = false;
|
||||
|
||||
let headerElement: HTMLHeadElement = null;
|
||||
let sentTypeElement: HTMLParagraphElement = null;
|
||||
@ -34,13 +26,13 @@ let onFirstMount = (): Promise<any> => {
|
||||
let animation: RLottiePlayer;
|
||||
let idleAnimation: RLottiePlayer;
|
||||
|
||||
const CODELENGTH = authCode.type.length;
|
||||
const CODELENGTH = (authCode.type as AuthSentCodeType.authSentCodeTypeApp).length;
|
||||
|
||||
codeInput = page.pageEl.querySelector('#code') as HTMLInputElement;
|
||||
const codeInputLabel = codeInput.nextElementSibling as HTMLLabelElement;
|
||||
const editButton = page.pageEl.querySelector('.phone-edit') as HTMLElement;
|
||||
|
||||
if(EDITONSAMEPAGE) {
|
||||
/* if(EDITONSAMEPAGE) {
|
||||
let editable = false;
|
||||
let changePhonePromise: Promise<unknown>;
|
||||
|
||||
@ -59,7 +51,7 @@ let onFirstMount = (): Promise<any> => {
|
||||
settings: {
|
||||
_: 'codeSettings' // that's how we sending Type
|
||||
}
|
||||
/* lang_code: navigator.language || 'en' */
|
||||
//lang_code: navigator.language || 'en'
|
||||
}).then((code: any) => {
|
||||
console.log('got code 2', code);
|
||||
|
||||
@ -109,11 +101,11 @@ let onFirstMount = (): Promise<any> => {
|
||||
|
||||
if(!editable) changePhone();
|
||||
});
|
||||
} else {
|
||||
} else { */
|
||||
editButton.addEventListener('click', function() {
|
||||
return pageSignIn.mount();
|
||||
});
|
||||
}
|
||||
//}
|
||||
|
||||
let cleanup = () => {
|
||||
setTimeout(() => {
|
||||
@ -186,6 +178,7 @@ let onFirstMount = (): Promise<any> => {
|
||||
// end symbol = frame 165
|
||||
codeInput.addEventListener('input', function(this: typeof codeInput, e) {
|
||||
this.classList.remove('error');
|
||||
codeInputLabel.innerText = 'Code';
|
||||
|
||||
this.value = this.value.replace(/\D/g, '');
|
||||
if(this.value.length > CODELENGTH) {
|
||||
@ -201,20 +194,38 @@ let onFirstMount = (): Promise<any> => {
|
||||
|
||||
lastLength = length;
|
||||
|
||||
playAnimation(length);
|
||||
});
|
||||
|
||||
const playAnimation = (length: number) => {
|
||||
if(!animation) return;
|
||||
|
||||
let frame: number;
|
||||
if(length) {
|
||||
frame = Math.round(Math.min(max, length) * (165 / max) + 11.33);
|
||||
|
||||
idleAnimation.canvas.style.display = 'none';
|
||||
if(idleAnimation) {
|
||||
idleAnimation.stop(true);
|
||||
idleAnimation.canvas.style.display = 'none';
|
||||
}
|
||||
|
||||
animation.canvas.style.display = '';
|
||||
} else {
|
||||
/* const cb = (frameNo: number) => {
|
||||
if(frameNo <= 1) { */
|
||||
/* idleAnimation.play();
|
||||
idleAnimation.canvas.style.display = '';
|
||||
animation.canvas.style.display = 'none'; */
|
||||
/* animation.removeListener('enterFrame', cb);
|
||||
}
|
||||
};
|
||||
animation.addListener('enterFrame', cb); */
|
||||
|
||||
frame = 0;
|
||||
}
|
||||
//animation.playSegments([1, 2]);
|
||||
|
||||
let direction = needFrame > frame ? -1 : 1;
|
||||
const direction = needFrame > frame ? -1 : 1;
|
||||
//console.log('keydown', length, frame, direction);
|
||||
|
||||
animation.setDirection(direction);
|
||||
@ -229,6 +240,14 @@ let onFirstMount = (): Promise<any> => {
|
||||
|
||||
/* animation.goToAndStop(15, true); */
|
||||
//animation.goToAndStop(length / max * );
|
||||
};
|
||||
|
||||
codeInput.addEventListener('focus', () => {
|
||||
playAnimation(Math.max(codeInput.value.length, 1));
|
||||
});
|
||||
|
||||
codeInput.addEventListener('blur', () => {
|
||||
playAnimation(0);
|
||||
});
|
||||
|
||||
let imageDiv = page.pageEl.querySelector('.auth-image') as HTMLDivElement;
|
||||
@ -242,6 +261,11 @@ let onFirstMount = (): Promise<any> => {
|
||||
height: size
|
||||
}, 'assets/img/TwoFactorSetupMonkeyIdle.tgs').then(animation => {
|
||||
idleAnimation = animation;
|
||||
|
||||
// ! animationIntersector will stop animation instantly
|
||||
if(!codeInput.value.length) {
|
||||
animation.play();
|
||||
}
|
||||
}),
|
||||
|
||||
LottieLoader.loadAnimationFromURL({
|
||||
@ -268,12 +292,12 @@ let onFirstMount = (): Promise<any> => {
|
||||
}
|
||||
|
||||
if(currentFrame == 0 && needFrame == 0) {
|
||||
animation.curFrame = 0;
|
||||
//animation.curFrame = 0;
|
||||
|
||||
if(idleAnimation) {
|
||||
animation.canvas.style.display = 'none';
|
||||
idleAnimation.canvas.style.display = '';
|
||||
idleAnimation.restart();
|
||||
idleAnimation.play();
|
||||
animation.canvas.style.display = 'none';
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -288,6 +312,12 @@ const page = new Page('page-authCode', true, onFirstMount, (_authCode: typeof au
|
||||
if(!headerElement) {
|
||||
headerElement = page.pageEl.getElementsByClassName('phone')[0] as HTMLHeadElement;
|
||||
sentTypeElement = page.pageEl.getElementsByClassName('sent-type')[0] as HTMLParagraphElement;
|
||||
} else {
|
||||
codeInput.value = '';
|
||||
|
||||
const evt = document.createEvent('HTMLEvents');
|
||||
evt.initEvent('input', false, true);
|
||||
codeInput.dispatchEvent(evt);
|
||||
}
|
||||
|
||||
//let LottieLoader = (await import('../lib/lottieLoader')).default;
|
||||
@ -307,6 +337,9 @@ const page = new Page('page-authCode', true, onFirstMount, (_authCode: typeof au
|
||||
sentTypeElement.innerHTML = `Please check everything<br>for a code (type: ${authCode.type._})`;
|
||||
break;
|
||||
}
|
||||
|
||||
appStateManager.pushToState('authState', {_: 'authStateAuthCode', sentCode: _authCode});
|
||||
appStateManager.saveState();
|
||||
}, () => {
|
||||
codeInput.focus();
|
||||
});
|
||||
|
@ -1,9 +1,14 @@
|
||||
//import {stackBlurImage} from '../lib/StackBlur';
|
||||
//import appStateManager from "../lib/appManagers/appStateManager";
|
||||
import appStateManager from "../lib/appManagers/appStateManager";
|
||||
import { DEBUG } from "../lib/mtproto/mtproto_config";
|
||||
import Page from "./page";
|
||||
|
||||
let onFirstMount = () => {
|
||||
//return;
|
||||
appStateManager.pushToState('authState', {_: 'authStateSignedIn'});
|
||||
// ! TOO SLOW
|
||||
/* appStateManager.saveState(); */
|
||||
|
||||
const promise = import('../lib/appManagers/appDialogsManager');
|
||||
promise.finally(async() => {
|
||||
|
@ -4,6 +4,7 @@ import { putPreloader } from '../components/misc';
|
||||
import mediaSizes from '../helpers/mediaSizes';
|
||||
import { isAppleMobile, isSafari } from '../helpers/userAgent';
|
||||
import { AccountPassword } from '../layer';
|
||||
import appStateManager from '../lib/appManagers/appStateManager';
|
||||
import LottieLoader, { RLottiePlayer } from '../lib/lottieLoader';
|
||||
//import passwordManager from '../lib/mtproto/passwordManager';
|
||||
import apiManager from '../lib/mtproto/mtprotoworker';
|
||||
@ -25,8 +26,14 @@ let onFirstMount = (): Promise<any> => {
|
||||
passwordInput = document.getElementById('password') as HTMLInputElement;
|
||||
const passwordInputLabel = passwordInput.nextElementSibling as HTMLLabelElement;
|
||||
const toggleVisible = page.pageEl.querySelector('.toggle-visible') as HTMLSpanElement;
|
||||
let getStateInterval: number;
|
||||
|
||||
let getState = () => {
|
||||
// * just to check session relevance
|
||||
if(!getStateInterval) {
|
||||
getStateInterval = window.setInterval(getState, 10e3);
|
||||
}
|
||||
|
||||
return !TEST && passwordManager.getState().then(_state => {
|
||||
state = _state;
|
||||
|
||||
@ -92,6 +99,7 @@ let onFirstMount = (): Promise<any> => {
|
||||
id: response.user.id
|
||||
});
|
||||
|
||||
clearInterval(getStateInterval);
|
||||
pageIm.mount();
|
||||
if(animation) animation.remove();
|
||||
break;
|
||||
@ -149,6 +157,9 @@ const page = new Page('page-password', true, onFirstMount, null, () => {
|
||||
//if(!isAppleMobile) {
|
||||
passwordInput.focus();
|
||||
//}
|
||||
|
||||
appStateManager.pushToState('authState', {_: 'authStatePassword'});
|
||||
appStateManager.saveState();
|
||||
});
|
||||
|
||||
export default page;
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { formatPhoneNumber, putPreloader } from "../components/misc";
|
||||
import Scrollable from '../components/scrollable';
|
||||
import Countries, { Country as _Country } from "../countries";
|
||||
import appStateManager from "../lib/appManagers/appStateManager";
|
||||
import apiManager from "../lib/mtproto/mtprotoworker";
|
||||
import { App, Modes } from "../lib/mtproto/mtproto_config";
|
||||
import { RichTextProcessor } from '../lib/richtextprocessor';
|
||||
@ -222,7 +223,7 @@ let onFirstMount = () => {
|
||||
}); */
|
||||
|
||||
telEl.addEventListener('keypress', function(this: typeof telEl, e) {
|
||||
console.log('keypress', this.value);
|
||||
//console.log('keypress', this.value);
|
||||
if(!btnNext.style.visibility &&/* this.value.length >= 9 && */ e.key == 'Enter') {
|
||||
return btnNext.click();
|
||||
} else if(/\D/.test(e.key)) {
|
||||
@ -322,6 +323,9 @@ const page = new Page('page-sign', true, onFirstMount, () => {
|
||||
|
||||
btnNext.textContent = 'NEXT';
|
||||
btnNext.removeAttribute('disabled');
|
||||
|
||||
appStateManager.pushToState('authState', {_: 'authStateSignIn'});
|
||||
appStateManager.saveState();
|
||||
});
|
||||
|
||||
export default page;
|
||||
|
@ -1,14 +1,13 @@
|
||||
import { putPreloader } from '../components/misc';
|
||||
import PopupAvatar from '../components/popupAvatar';
|
||||
import appStateManager from '../lib/appManagers/appStateManager';
|
||||
//import apiManager from '../lib/mtproto/apiManager';
|
||||
import apiManager from '../lib/mtproto/mtprotoworker';
|
||||
import { AuthState } from '../types';
|
||||
import Page from './page';
|
||||
import pageIm from './pageIm';
|
||||
|
||||
let authCode: {
|
||||
'phone_number': string,
|
||||
'phone_code_hash': string
|
||||
} = null;
|
||||
let authCode: AuthState.signUp['authCode'] = null;
|
||||
|
||||
let onFirstMount = () => import('../lib/appManagers/appProfileManager').then(imported => {
|
||||
const pageElement = page.pageEl;
|
||||
@ -116,6 +115,9 @@ let onFirstMount = () => import('../lib/appManagers/appProfileManager').then(imp
|
||||
|
||||
const page = new Page('page-signUp', true, onFirstMount, (_authCode: typeof authCode) => {
|
||||
authCode = _authCode;
|
||||
|
||||
appStateManager.pushToState('authState', {_: 'authStateSignUp', authCode: _authCode});
|
||||
appStateManager.saveState();
|
||||
});
|
||||
|
||||
export default page;
|
||||
|
@ -222,4 +222,9 @@
|
||||
{"name": "sortStatus", "type": "number"},
|
||||
{"name": "num", "type": "number"}
|
||||
]
|
||||
}, {
|
||||
"predicate": "auth.sentCode",
|
||||
"params": [
|
||||
{"name": "phone_number", "type": "string"}
|
||||
]
|
||||
}]
|
31
src/types.d.ts
vendored
31
src/types.d.ts
vendored
@ -1,3 +1,4 @@
|
||||
import { AuthSentCode } from "./layer";
|
||||
import type { ApiError } from "./lib/mtproto/apiManager";
|
||||
|
||||
export type InvokeApiOptions = Partial<{
|
||||
@ -32,4 +33,32 @@ export type Modify<T, R> = Omit<T, keyof R> & R;
|
||||
|
||||
//export type Parameters<T> = T extends (... args: infer T) => any ? T : never;
|
||||
|
||||
export type ArgumentTypes<F extends Function> = F extends (...args: infer A) => any ? A : never;
|
||||
export type ArgumentTypes<F extends Function> = F extends (...args: infer A) => any ? A : never;
|
||||
|
||||
export type AuthState = AuthState.signIn | AuthState.authCode | AuthState.password | AuthState.signUp | AuthState.signedIn;
|
||||
export namespace AuthState {
|
||||
export type signIn = {
|
||||
_: 'authStateSignIn'
|
||||
};
|
||||
|
||||
export type authCode = {
|
||||
_: 'authStateAuthCode',
|
||||
sentCode: AuthSentCode.authSentCode
|
||||
};
|
||||
|
||||
export type password = {
|
||||
_: 'authStatePassword'
|
||||
};
|
||||
|
||||
export type signUp = {
|
||||
_: 'authStateSignUp',
|
||||
authCode: {
|
||||
phone_number: string,
|
||||
phone_code_hash: string
|
||||
}
|
||||
};
|
||||
|
||||
export type signedIn = {
|
||||
_: 'authStateSignedIn'
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue
Block a user