Password hint
Moved password manager from worker
This commit is contained in:
parent
e99955e798
commit
65dc6b6ea4
@ -15,7 +15,7 @@ ctx.onmessage = function(e) {
|
|||||||
result = null;
|
result = null;
|
||||||
|
|
||||||
switch(e.data.task) {
|
switch(e.data.task) {
|
||||||
case 'unzip':
|
case 'gzipUncompress':
|
||||||
result = gzipUncompress.apply(null, e.data.args);
|
result = gzipUncompress.apply(null, e.data.args);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -41,6 +41,10 @@ export default abstract class CryptoWorkerMethods {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public gzipUncompress<T>(bytes: ArrayBuffer, toString?: boolean) {
|
public gzipUncompress<T>(bytes: ArrayBuffer, toString?: boolean) {
|
||||||
return this.performTaskWorker<T>('unzip', bytes, toString);
|
return this.performTaskWorker<T>('gzipUncompress', bytes, toString);
|
||||||
|
}
|
||||||
|
|
||||||
|
public computeSRP(password: string, state: any) {
|
||||||
|
return this.performTaskWorker('computeSRP', password, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -38,8 +38,12 @@ class CryptoWorker extends CryptoWorkerMethods {
|
|||||||
'rsa-encrypt': utils.rsaEncrypt,
|
'rsa-encrypt': utils.rsaEncrypt,
|
||||||
'factorize': utils.pqPrimeFactorization,
|
'factorize': utils.pqPrimeFactorization,
|
||||||
'mod-pow': utils.bytesModPow,
|
'mod-pow': utils.bytesModPow,
|
||||||
'unzip': utils.gzipUncompress
|
'gzipUncompress': utils.gzipUncompress,
|
||||||
});
|
});
|
||||||
|
}),
|
||||||
|
|
||||||
|
import('./srp').then(srp => {
|
||||||
|
this.utils.computeSRP = srp.computeSRP;
|
||||||
})/* ,
|
})/* ,
|
||||||
|
|
||||||
import('../bin_utils').then(utils => {
|
import('../bin_utils').then(utils => {
|
||||||
|
@ -5,6 +5,7 @@ import {str2bigInt, isZero,
|
|||||||
bigInt2str, powMod, int2bigInt, mult, mod, sub, bitSize, negative, add, greater} from 'leemon';
|
bigInt2str, powMod, int2bigInt, mult, mod, sub, bitSize, negative, add, greater} from 'leemon';
|
||||||
|
|
||||||
import {logger, LogLevels} from '../logger';
|
import {logger, LogLevels} from '../logger';
|
||||||
|
import { AccountPassword } from "../../types";
|
||||||
|
|
||||||
const log = logger('SRP', LogLevels.error);
|
const log = logger('SRP', LogLevels.error);
|
||||||
|
|
||||||
@ -31,27 +32,7 @@ export async function makePasswordHash(password: string, client_salt: Uint8Array
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
type Algo = {
|
export async function computeSRP(password: string, state: AccountPassword) {
|
||||||
salt1: Uint8Array,
|
|
||||||
salt2: Uint8Array,
|
|
||||||
p: Uint8Array,
|
|
||||||
g: number
|
|
||||||
};
|
|
||||||
|
|
||||||
export async function computeCheck(password: string, state: {
|
|
||||||
_?: 'accont.password',
|
|
||||||
flags?: number,
|
|
||||||
pFlags?: Partial<{
|
|
||||||
has_recovery: true,
|
|
||||||
has_password: true
|
|
||||||
}>,
|
|
||||||
current_algo: Algo,
|
|
||||||
new_algo?: Algo,
|
|
||||||
new_secure_algo?: Algo,
|
|
||||||
srp_B: Uint8Array,
|
|
||||||
srp_id: string,
|
|
||||||
secure_random: Uint8Array
|
|
||||||
}) {
|
|
||||||
//console.log('computeCheck:', password, state);
|
//console.log('computeCheck:', password, state);
|
||||||
|
|
||||||
let algo = state.current_algo;
|
let algo = state.current_algo;
|
||||||
|
@ -9,7 +9,6 @@ import {App, Modes} from './mtproto_config';
|
|||||||
import dcConfigurator from './dcConfigurator';
|
import dcConfigurator from './dcConfigurator';
|
||||||
import HTTP from './transports/http';
|
import HTTP from './transports/http';
|
||||||
import { logger } from '../logger';
|
import { logger } from '../logger';
|
||||||
import passwordManager from './passwordManager';
|
|
||||||
|
|
||||||
/// #if !MTPROTO_WORKER
|
/// #if !MTPROTO_WORKER
|
||||||
import { $rootScope } from '../utils';
|
import { $rootScope } from '../utils';
|
||||||
@ -329,13 +328,6 @@ export class ApiManager {
|
|||||||
return auth.id || 0;
|
return auth.id || 0;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public checkPassword(value: string): Promise<any> {
|
|
||||||
return passwordManager.getState()
|
|
||||||
.then(state => {
|
|
||||||
return passwordManager.check(state, value);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new ApiManager();
|
export default new ApiManager();
|
||||||
|
@ -85,8 +85,9 @@ ctx.onmessage = function(e) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch(e.data.task) {
|
switch(e.data.task) {
|
||||||
case 'unzip':
|
case 'computeSRP':
|
||||||
return cryptoWorker.gzipUncompress.apply(cryptoWorker, e.data.args).then(result => {
|
case 'gzipUncompress':
|
||||||
|
return cryptoWorker[e.data.task].apply(cryptoWorker, e.data.args).then(result => {
|
||||||
//ctx.postMessage({taskID: taskID, result: result});
|
//ctx.postMessage({taskID: taskID, result: result});
|
||||||
reply({taskID: taskID, result: result});
|
reply({taskID: taskID, result: result});
|
||||||
});
|
});
|
||||||
|
@ -145,10 +145,6 @@ class ApiManagerProxy extends CryptoWorkerMethods {
|
|||||||
public logOut(): Promise<void> {
|
public logOut(): Promise<void> {
|
||||||
return this.performTaskWorker('logOut');
|
return this.performTaskWorker('logOut');
|
||||||
}
|
}
|
||||||
|
|
||||||
public checkPassword(value: string): Promise<any> {
|
|
||||||
return this.performTaskWorker('checkPassword', value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const apiManagerProxy = new ApiManagerProxy();
|
const apiManagerProxy = new ApiManagerProxy();
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import apiManager from "./apiManager";
|
import apiManager from './mtprotoworker';
|
||||||
import { computeCheck } from "../crypto/srp";
|
import { AccountPassword } from '../../types';
|
||||||
|
//import { computeCheck } from "../crypto/srp";
|
||||||
|
|
||||||
export class PasswordManager {
|
export class PasswordManager {
|
||||||
public getState(options: any = {}) {
|
public getState(options: any = {}): Promise<AccountPassword> {
|
||||||
return apiManager.invokeApi('account.getPassword', {}, options).then((result) => {
|
return apiManager.invokeApi('account.getPassword', {}, options).then((result) => {
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
@ -55,8 +56,8 @@ export class PasswordManager {
|
|||||||
});
|
});
|
||||||
} */
|
} */
|
||||||
|
|
||||||
public check(state: any, password: string, options: any = {}) {
|
public check(password: string, state: AccountPassword, options: any = {}) {
|
||||||
return computeCheck(password, state).then((inputCheckPassword) => {
|
return apiManager.computeSRP(password, state).then((inputCheckPassword) => {
|
||||||
return apiManager.invokeApi('auth.checkPassword', {
|
return apiManager.invokeApi('auth.checkPassword', {
|
||||||
password: inputCheckPassword
|
password: inputCheckPassword
|
||||||
}, options);
|
}, options);
|
||||||
|
@ -8,6 +8,8 @@ import LottieLoader, { RLottiePlayer } from '../lib/lottieLoader';
|
|||||||
import apiManager from '../lib/mtproto/mtprotoworker';
|
import apiManager from '../lib/mtproto/mtprotoworker';
|
||||||
import Page from './page';
|
import Page from './page';
|
||||||
import { mediaSizes } from '../lib/config';
|
import { mediaSizes } from '../lib/config';
|
||||||
|
import passwordManager from '../lib/mtproto/passwordManager';
|
||||||
|
import { AccountPassword } from '../types';
|
||||||
|
|
||||||
let onFirstMount = (): Promise<any> => {
|
let onFirstMount = (): Promise<any> => {
|
||||||
let needFrame = 0;
|
let needFrame = 0;
|
||||||
@ -17,9 +19,17 @@ let onFirstMount = (): Promise<any> => {
|
|||||||
|
|
||||||
const btnNext = page.pageEl.querySelector('button') as HTMLButtonElement;
|
const btnNext = page.pageEl.querySelector('button') as HTMLButtonElement;
|
||||||
const passwordInput = document.getElementById('password') as HTMLInputElement;
|
const passwordInput = document.getElementById('password') as HTMLInputElement;
|
||||||
//const passwordInputLabel = passwordInput.nextElementSibling as HTMLLabelElement;
|
const passwordInputLabel = passwordInput.nextElementSibling as HTMLLabelElement;
|
||||||
const toggleVisible = page.pageEl.querySelector('.toggle-visible') as HTMLSpanElement;
|
const toggleVisible = page.pageEl.querySelector('.toggle-visible') as HTMLSpanElement;
|
||||||
|
|
||||||
|
let getState = () => {
|
||||||
|
return passwordManager.getState().then(_state => {
|
||||||
|
state = _state;
|
||||||
|
|
||||||
|
passwordInputLabel.innerText = state.hint ?? 'Password';
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
let handleError = (err: any) => {
|
let handleError = (err: any) => {
|
||||||
btnNext.removeAttribute('disabled');
|
btnNext.removeAttribute('disabled');
|
||||||
|
|
||||||
@ -28,6 +38,8 @@ let onFirstMount = (): Promise<any> => {
|
|||||||
btnNext.innerText = err.type;
|
btnNext.innerText = err.type;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getState();
|
||||||
};
|
};
|
||||||
|
|
||||||
toggleVisible.addEventListener('click', function(this, e) {
|
toggleVisible.addEventListener('click', function(this, e) {
|
||||||
@ -50,6 +62,8 @@ let onFirstMount = (): Promise<any> => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let state: AccountPassword;
|
||||||
|
|
||||||
btnNext.addEventListener('click', function(this, e) {
|
btnNext.addEventListener('click', function(this, e) {
|
||||||
if(!passwordInput.value.length) {
|
if(!passwordInput.value.length) {
|
||||||
passwordInput.classList.add('error');
|
passwordInput.classList.add('error');
|
||||||
@ -62,7 +76,7 @@ let onFirstMount = (): Promise<any> => {
|
|||||||
this.textContent = 'PLEASE WAIT...';
|
this.textContent = 'PLEASE WAIT...';
|
||||||
putPreloader(this);
|
putPreloader(this);
|
||||||
|
|
||||||
apiManager.checkPassword(value).then((response: any) => {
|
passwordManager.check(value, state).then((response: any) => {
|
||||||
//console.log('passwordManager response:', response);
|
//console.log('passwordManager response:', response);
|
||||||
|
|
||||||
switch(response._) {
|
switch(response._) {
|
||||||
@ -118,7 +132,9 @@ let onFirstMount = (): Promise<any> => {
|
|||||||
|
|
||||||
needFrame = 49;
|
needFrame = 49;
|
||||||
//animation.play();
|
//animation.play();
|
||||||
})
|
}),
|
||||||
|
|
||||||
|
getState()
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { salt1, salt2, g, p, srp_id, secure_random, srp_B, password, A, M1, passwordHashed } from '../mock/srp';
|
import { salt1, salt2, g, p, srp_id, secure_random, srp_B, password, A, M1, passwordHashed } from '../mock/srp';
|
||||||
import { computeCheck, makePasswordHash } from '../lib/crypto/srp';
|
import { computeSRP, makePasswordHash } from '../lib/crypto/srp';
|
||||||
|
|
||||||
test('2FA hash', async() => {
|
test('2FA hash', async() => {
|
||||||
const bytes = await makePasswordHash(password, salt1, salt2);
|
const bytes = await makePasswordHash(password, salt1, salt2);
|
||||||
@ -7,7 +7,7 @@ test('2FA hash', async() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('2FA whole (with negative)', async() => {
|
test('2FA whole (with negative)', async() => {
|
||||||
return await computeCheck(password, {
|
return await computeSRP(password, {
|
||||||
current_algo: {
|
current_algo: {
|
||||||
salt1,
|
salt1,
|
||||||
salt2,
|
salt2,
|
||||||
|
27
src/types.d.ts
vendored
27
src/types.d.ts
vendored
@ -62,4 +62,29 @@ export type InvokeApiOptions = Partial<{
|
|||||||
waitTime: number,
|
waitTime: number,
|
||||||
stopTime: number,
|
stopTime: number,
|
||||||
rawError: any
|
rawError: any
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
type Algo = {
|
||||||
|
salt1: Uint8Array,
|
||||||
|
salt2: Uint8Array,
|
||||||
|
p: Uint8Array,
|
||||||
|
g: number
|
||||||
|
};
|
||||||
|
|
||||||
|
export type AccountPassword = {
|
||||||
|
_?: 'accont.password',
|
||||||
|
flags?: number,
|
||||||
|
pFlags?: Partial<{
|
||||||
|
has_recovery: true,
|
||||||
|
has_secure_values: true,
|
||||||
|
has_password: true
|
||||||
|
}>,
|
||||||
|
current_algo: Algo,
|
||||||
|
new_algo?: Algo,
|
||||||
|
new_secure_algo?: Algo,
|
||||||
|
hint?: string,
|
||||||
|
email_unconfirmed_pattern?: string,
|
||||||
|
srp_B?: Uint8Array,
|
||||||
|
srp_id?: string,
|
||||||
|
secure_random: Uint8Array,
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user