Support exporting legacy session
This commit is contained in:
parent
19ef014068
commit
f5086002bb
@ -105,10 +105,11 @@ export function onAuthError(err: Error) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function onAuthReady(sessionId: string) {
|
export function onAuthReady(sessionId: string, sessionJson: string) {
|
||||||
onUpdate({
|
onUpdate({
|
||||||
...buildAuthStateUpdate('authorizationStateReady'),
|
...buildAuthStateUpdate('authorizationStateReady'),
|
||||||
sessionId,
|
sessionId,
|
||||||
|
sessionJson,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -68,6 +68,7 @@ export async function init(sessionInfo: string, _onUpdate: OnApiUpdate) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const newSessionId = await session.save();
|
const newSessionId = await session.save();
|
||||||
|
const sessionJson = JSON.stringify(session.getSessionData(true));
|
||||||
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
@ -76,7 +77,7 @@ export async function init(sessionInfo: string, _onUpdate: OnApiUpdate) {
|
|||||||
console.log('[GramJs/client] CONNECTED as ', newSessionId);
|
console.log('[GramJs/client] CONNECTED as ', newSessionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
onAuthReady(newSessionId);
|
onAuthReady(newSessionId, sessionJson);
|
||||||
onUpdate({ '@type': 'updateApiReady' });
|
onUpdate({ '@type': 'updateApiReady' });
|
||||||
|
|
||||||
void fetchCurrentUser();
|
void fetchCurrentUser();
|
||||||
|
|||||||
@ -36,6 +36,7 @@ export type ApiUpdateAuthorizationState = {
|
|||||||
'@type': 'updateAuthorizationState';
|
'@type': 'updateAuthorizationState';
|
||||||
authorizationState: ApiUpdateAuthorizationStateType;
|
authorizationState: ApiUpdateAuthorizationStateType;
|
||||||
sessionId?: string;
|
sessionId?: string;
|
||||||
|
sessionJson?: string;
|
||||||
isCodeViaApp?: boolean;
|
isCodeViaApp?: boolean;
|
||||||
hint?: string;
|
hint?: string;
|
||||||
qrCode?: { token: string; expires: number };
|
qrCode?: { token: string; expires: number };
|
||||||
|
|||||||
@ -15,7 +15,7 @@ export const DEBUG_ALERT_MSG = 'Shoot!\nSomething went wrong, please see the err
|
|||||||
export const DEBUG_GRAMJS = false;
|
export const DEBUG_GRAMJS = false;
|
||||||
|
|
||||||
export const GRAMJS_SESSION_ID_KEY = 'GramJs:sessionId';
|
export const GRAMJS_SESSION_ID_KEY = 'GramJs:sessionId';
|
||||||
export const LEGACY_SESSION_KEY = 'dc';
|
export const LEGACY_SESSION_KEY = 'user_auth';
|
||||||
|
|
||||||
export const GLOBAL_STATE_CACHE_DISABLED = false;
|
export const GLOBAL_STATE_CACHE_DISABLED = false;
|
||||||
export const GLOBAL_STATE_CACHE_KEY = 'tt-global-state';
|
export const GLOBAL_STATE_CACHE_KEY = 'tt-global-state';
|
||||||
|
|||||||
@ -12,7 +12,7 @@ class StorageSession extends MemorySession {
|
|||||||
this._authKeys = {};
|
this._authKeys = {};
|
||||||
|
|
||||||
if (sessionInfo && sessionInfo.startsWith(SESSION_DATA_PREFIX)) {
|
if (sessionInfo && sessionInfo.startsWith(SESSION_DATA_PREFIX)) {
|
||||||
this._sessionData = sessionInfo;
|
this._sessionString = sessionInfo;
|
||||||
} else if (sessionInfo) {
|
} else if (sessionInfo) {
|
||||||
this._storageKey = sessionInfo;
|
this._storageKey = sessionInfo;
|
||||||
}
|
}
|
||||||
@ -27,8 +27,8 @@ class StorageSession extends MemorySession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async load() {
|
async load() {
|
||||||
if (this._sessionData) {
|
if (this._sessionString) {
|
||||||
await this._loadFromSessionData();
|
await this._loadFromSessionString();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,8 +99,26 @@ class StorageSession extends MemorySession {
|
|||||||
void this._updateStorage();
|
void this._updateStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
async _loadFromSessionData() {
|
getSessionData(asHex) {
|
||||||
const [, mainDcIdStr, mainDcKey] = this._sessionData.split(':');
|
const sessionData = {
|
||||||
|
mainDcId: this._dcId,
|
||||||
|
keys: {},
|
||||||
|
hashes: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
Object
|
||||||
|
.keys(this._authKeys)
|
||||||
|
.forEach((dcId) => {
|
||||||
|
const authKey = this._authKeys[dcId];
|
||||||
|
sessionData.keys[dcId] = asHex ? authKey._key.toString('hex') : authKey._key;
|
||||||
|
sessionData.hashes[dcId] = asHex ? authKey._hash.toString('hex') : authKey._hash;
|
||||||
|
});
|
||||||
|
|
||||||
|
return sessionData;
|
||||||
|
}
|
||||||
|
|
||||||
|
async _loadFromSessionString() {
|
||||||
|
const [, mainDcIdStr, mainDcKey] = this._sessionString.split(':');
|
||||||
const mainDcId = Number(mainDcIdStr);
|
const mainDcId = Number(mainDcIdStr);
|
||||||
const {
|
const {
|
||||||
ipAddress,
|
ipAddress,
|
||||||
@ -117,22 +135,8 @@ class StorageSession extends MemorySession {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const sessionData = {
|
|
||||||
mainDcId: this._dcId,
|
|
||||||
keys: {},
|
|
||||||
hashes: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
Object.keys(this._authKeys)
|
|
||||||
.map((dcId) => {
|
|
||||||
const authKey = this._authKeys[dcId];
|
|
||||||
sessionData.keys[dcId] = authKey._key;
|
|
||||||
sessionData.hashes[dcId] = authKey._hash;
|
|
||||||
return undefined;
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this._saveToCache(JSON.stringify(sessionData));
|
await this._saveToCache(JSON.stringify(this.getSessionData()));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.warn('Failed to update session in storage');
|
console.warn('Failed to update session in storage');
|
||||||
|
|||||||
@ -22,12 +22,12 @@ addReducer('initApi', (global: GlobalState, actions) => {
|
|||||||
let sessionInfo = localStorage.getItem(GRAMJS_SESSION_ID_KEY) || undefined;
|
let sessionInfo = localStorage.getItem(GRAMJS_SESSION_ID_KEY) || undefined;
|
||||||
|
|
||||||
if (!sessionInfo) {
|
if (!sessionInfo) {
|
||||||
const legacySessionMainDcRaw = localStorage.getItem(LEGACY_SESSION_KEY);
|
const legacySessionJson = localStorage.getItem(LEGACY_SESSION_KEY);
|
||||||
if (legacySessionMainDcRaw) {
|
if (legacySessionJson) {
|
||||||
const legacySessionMainDc = legacySessionMainDcRaw.replace(/"/g, '');
|
const { dcID: legacySessionMainDc } = JSON.parse(legacySessionJson);
|
||||||
const legacySessionMainDcKeyRaw = localStorage.getItem(`dc${legacySessionMainDc}_auth_key`);
|
const legacySessionMainKeyRaw = localStorage.getItem(`dc${legacySessionMainDc}_auth_key`);
|
||||||
if (legacySessionMainDcKeyRaw) {
|
if (legacySessionMainKeyRaw) {
|
||||||
const legacySessionMainDcKey = legacySessionMainDcKeyRaw.replace(/"/g, '');
|
const legacySessionMainDcKey = legacySessionMainKeyRaw.replace(/"/g, '');
|
||||||
sessionInfo = `session:${legacySessionMainDc}:${legacySessionMainDcKey}`;
|
sessionInfo = `session:${legacySessionMainDc}:${legacySessionMainDcKey}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -110,8 +110,10 @@ addReducer('gotToAuthQrCode', (global) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
addReducer('saveSession', (global, actions, payload) => {
|
addReducer('saveSession', (global, actions, payload) => {
|
||||||
const { sessionId } = payload!;
|
const { sessionId, sessionJson } = payload!;
|
||||||
localStorage.setItem(GRAMJS_SESSION_ID_KEY, sessionId);
|
localStorage.setItem(GRAMJS_SESSION_ID_KEY, sessionId);
|
||||||
|
|
||||||
|
exportLegacySession(sessionJson, global.currentUserId!);
|
||||||
});
|
});
|
||||||
|
|
||||||
addReducer('signOut', () => {
|
addReducer('signOut', () => {
|
||||||
@ -125,8 +127,7 @@ addReducer('signOut', () => {
|
|||||||
|
|
||||||
addReducer('reset', () => {
|
addReducer('reset', () => {
|
||||||
localStorage.removeItem(GRAMJS_SESSION_ID_KEY);
|
localStorage.removeItem(GRAMJS_SESSION_ID_KEY);
|
||||||
localStorage.removeItem(LEGACY_SESSION_KEY);
|
clearLegacySession();
|
||||||
updateAppBadge(0);
|
|
||||||
|
|
||||||
cacheApi.clear(MEDIA_CACHE_NAME);
|
cacheApi.clear(MEDIA_CACHE_NAME);
|
||||||
cacheApi.clear(MEDIA_CACHE_NAME_AVATARS);
|
cacheApi.clear(MEDIA_CACHE_NAME_AVATARS);
|
||||||
@ -140,6 +141,8 @@ addReducer('reset', () => {
|
|||||||
cacheApi.clear(`${langChachePrefix}${i === 0 ? '' : i}`);
|
cacheApi.clear(`${langChachePrefix}${i === 0 ? '' : i}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateAppBadge(0);
|
||||||
|
|
||||||
getDispatch().init();
|
getDispatch().init();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -180,3 +183,23 @@ addReducer('deleteDeviceToken', (global) => {
|
|||||||
delete newGlobal.push;
|
delete newGlobal.push;
|
||||||
setGlobal(newGlobal);
|
setGlobal(newGlobal);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function exportLegacySession(sessionJson: string, currentUserId: number) {
|
||||||
|
const { mainDcId, keys } = JSON.parse(sessionJson);
|
||||||
|
const legacySession = { dcID: mainDcId, id: currentUserId };
|
||||||
|
localStorage.setItem(LEGACY_SESSION_KEY, JSON.stringify(legacySession));
|
||||||
|
localStorage.setItem('dc', mainDcId);
|
||||||
|
Object.keys(keys).forEach((dcId) => {
|
||||||
|
localStorage.setItem(`dc${dcId}_auth_key`, `"${keys[dcId]}"`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearLegacySession() {
|
||||||
|
localStorage.removeItem('dc5_auth_key');
|
||||||
|
localStorage.removeItem('dc4_auth_key');
|
||||||
|
localStorage.removeItem('dc3_auth_key');
|
||||||
|
localStorage.removeItem('dc2_auth_key');
|
||||||
|
localStorage.removeItem('dc1_auth_key');
|
||||||
|
localStorage.removeItem('dc');
|
||||||
|
localStorage.removeItem(LEGACY_SESSION_KEY);
|
||||||
|
}
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import {
|
|||||||
ApiUpdateConnectionState,
|
ApiUpdateConnectionState,
|
||||||
ApiUpdateCurrentUser,
|
ApiUpdateCurrentUser,
|
||||||
} from '../../../api/types';
|
} from '../../../api/types';
|
||||||
import { DEBUG } from '../../../config';
|
import { DEBUG, LEGACY_SESSION_KEY } from '../../../config';
|
||||||
import { subscribe } from '../../../util/notifications';
|
import { subscribe } from '../../../util/notifications';
|
||||||
import { updateUser } from '../../reducers';
|
import { updateUser } from '../../reducers';
|
||||||
import { setLanguage } from '../../../util/langProvider';
|
import { setLanguage } from '../../../util/langProvider';
|
||||||
@ -102,6 +102,11 @@ function onUpdateAuthorizationState(update: ApiUpdateAuthorizationState) {
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case 'authorizationStateReady': {
|
case 'authorizationStateReady': {
|
||||||
|
const { sessionId, sessionJson } = update;
|
||||||
|
if (sessionId && global.authRememberMe) {
|
||||||
|
getDispatch().saveSession({ sessionId, sessionJson });
|
||||||
|
}
|
||||||
|
|
||||||
if (wasAuthReady) {
|
if (wasAuthReady) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -112,11 +117,6 @@ function onUpdateAuthorizationState(update: ApiUpdateAuthorizationState) {
|
|||||||
lastSyncTime: Date.now(),
|
lastSyncTime: Date.now(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const { sessionId } = update;
|
|
||||||
if (sessionId && global.authRememberMe) {
|
|
||||||
getDispatch().saveSession({ sessionId });
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -152,4 +152,16 @@ function onUpdateCurrentUser(update: ApiUpdateCurrentUser) {
|
|||||||
...updateUser(getGlobal(), currentUser.id, currentUser),
|
...updateUser(getGlobal(), currentUser.id, currentUser),
|
||||||
currentUserId: currentUser.id,
|
currentUserId: currentUser.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
updateLegacySessionUserId(currentUser.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateLegacySessionUserId(currentUserId: number) {
|
||||||
|
const legacySessionJson = localStorage.getItem(LEGACY_SESSION_KEY);
|
||||||
|
if (!legacySessionJson) return;
|
||||||
|
|
||||||
|
const legacySession = JSON.parse(legacySessionJson);
|
||||||
|
legacySession.id = currentUserId;
|
||||||
|
|
||||||
|
localStorage.setItem(LEGACY_SESSION_KEY, JSON.stringify(legacySession));
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user