179 lines
5.7 KiB
TypeScript
179 lines
5.7 KiB
TypeScript
/*
|
|
* https://github.com/morethanwords/tweb
|
|
* Copyright (C) 2019-2021 Eduard Kuzmenko
|
|
* https://github.com/morethanwords/tweb/blob/master/LICENSE
|
|
*/
|
|
|
|
import { SliderSuperTab } from "../../slider";
|
|
import { SettingSection } from "..";
|
|
import Button from "../../button";
|
|
import Row from "../../row";
|
|
import { Authorization } from "../../../layer";
|
|
import { formatDateAccordingToTodayNew } from "../../../helpers/date";
|
|
import { attachContextMenuListener, openBtnMenu, positionMenu } from "../../misc";
|
|
import ButtonMenu from "../../buttonMenu";
|
|
import apiManager from "../../../lib/mtproto/mtprotoworker";
|
|
import { toast } from "../../toast";
|
|
import AppPrivacyAndSecurityTab from "./privacyAndSecurity";
|
|
import I18n from "../../../lib/langPack";
|
|
import PopupPeer from "../../popups/peer";
|
|
import findUpClassName from "../../../helpers/dom/findUpClassName";
|
|
import { attachClickEvent } from "../../../helpers/dom/clickEvent";
|
|
import toggleDisability from "../../../helpers/dom/toggleDisability";
|
|
|
|
export default class AppActiveSessionsTab extends SliderSuperTab {
|
|
public privacyTab: AppPrivacyAndSecurityTab;
|
|
public authorizations: Authorization.authorization[];
|
|
private menuElement: HTMLElement;
|
|
|
|
protected init() {
|
|
this.container.classList.add('active-sessions-container');
|
|
this.setTitle('SessionsTitle');
|
|
|
|
const Session = (auth: Authorization.authorization) => {
|
|
const row = new Row({
|
|
title: [auth.app_name, auth.app_version].join(' '),
|
|
subtitle: [auth.ip, auth.country].join(' - '),
|
|
clickable: true,
|
|
titleRight: auth.pFlags.current ? undefined : formatDateAccordingToTodayNew(new Date(Math.max(auth.date_active, auth.date_created) * 1000))
|
|
});
|
|
|
|
row.container.dataset.hash = '' + auth.hash;
|
|
|
|
const midtitle = document.createElement('div');
|
|
midtitle.classList.add('row-midtitle');
|
|
midtitle.innerHTML = [auth.device_model, auth.system_version || auth.platform].filter(Boolean).join(', ');
|
|
|
|
row.subtitle.parentElement.insertBefore(midtitle, row.subtitle);
|
|
|
|
return row;
|
|
};
|
|
|
|
const authorizations = this.authorizations.slice();
|
|
|
|
{
|
|
const section = new SettingSection({
|
|
name: 'CurrentSession'
|
|
});
|
|
|
|
const auth = authorizations.findAndSplice(auth => auth.pFlags.current);
|
|
const session = Session(auth);
|
|
|
|
section.content.append(session.container);
|
|
|
|
if(authorizations.length) {
|
|
const btnTerminate = Button('btn-primary btn-transparent danger', {icon: 'stop', text: 'TerminateAllSessions'});
|
|
attachClickEvent(btnTerminate, (e) => {
|
|
new PopupPeer('revoke-session', {
|
|
buttons: [{
|
|
langKey: 'Terminate',
|
|
isDanger: true,
|
|
callback: () => {
|
|
const toggle = toggleDisability([btnTerminate], true);
|
|
apiManager.invokeApi('auth.resetAuthorizations').then(value => {
|
|
//toggleDisability([btnTerminate], false);
|
|
btnTerminate.remove();
|
|
otherSection.container.remove();
|
|
this.privacyTab.updateActiveSessions();
|
|
}, onError).finally(() => {
|
|
toggle();
|
|
});
|
|
}
|
|
}],
|
|
titleLangKey: 'AreYouSureSessionsTitle',
|
|
descriptionLangKey: 'AreYouSureSessions'
|
|
}).show();
|
|
});
|
|
|
|
section.content.append(btnTerminate);
|
|
}
|
|
|
|
this.scrollable.append(section.container);
|
|
}
|
|
|
|
if(!authorizations.length) {
|
|
return;
|
|
}
|
|
|
|
const otherSection = new SettingSection({
|
|
name: 'OtherSessions'
|
|
});
|
|
|
|
authorizations.forEach(auth => {
|
|
otherSection.content.append(Session(auth).container);
|
|
});
|
|
|
|
this.scrollable.append(otherSection.container);
|
|
|
|
const onError = (err: any) => {
|
|
if(err.type === 'FRESH_RESET_AUTHORISATION_FORBIDDEN') {
|
|
toast(I18n.format('RecentSessions.Error.FreshReset', true));
|
|
}
|
|
};
|
|
|
|
let target: HTMLElement;
|
|
const onTerminateClick = () => {
|
|
const hash = target.dataset.hash;
|
|
|
|
new PopupPeer('revoke-session', {
|
|
buttons: [{
|
|
langKey: 'Terminate',
|
|
isDanger: true,
|
|
callback: () => {
|
|
apiManager.invokeApi('account.resetAuthorization', {hash})
|
|
.then(value => {
|
|
if(value) {
|
|
target.remove();
|
|
this.privacyTab.updateActiveSessions();
|
|
}
|
|
}, onError);
|
|
}
|
|
}],
|
|
titleLangKey: 'AreYouSureSessionTitle',
|
|
descriptionLangKey: 'TerminateSessionText'
|
|
}).show();
|
|
};
|
|
|
|
const element = this.menuElement = ButtonMenu([{
|
|
icon: 'stop',
|
|
text: 'Terminate',
|
|
onClick: onTerminateClick
|
|
}]);
|
|
element.id = 'active-sessions-contextmenu';
|
|
element.classList.add('contextmenu');
|
|
|
|
document.getElementById('page-chats').append(element);
|
|
|
|
attachContextMenuListener(this.scrollable.container, (e) => {
|
|
target = findUpClassName(e.target, 'row');
|
|
if(!target || target.dataset.hash === '0') {
|
|
return;
|
|
}
|
|
|
|
if(e instanceof MouseEvent) e.preventDefault();
|
|
// smth
|
|
if(e instanceof MouseEvent) e.cancelBubble = true;
|
|
|
|
positionMenu(e, element);
|
|
openBtnMenu(element);
|
|
});
|
|
|
|
attachClickEvent(this.scrollable.container, (e) => {
|
|
target = findUpClassName(e.target, 'row');
|
|
if(!target || target.dataset.hash === '0') {
|
|
return;
|
|
}
|
|
|
|
onTerminateClick();
|
|
});
|
|
}
|
|
|
|
onCloseAfterTimeout() {
|
|
if(this.menuElement) {
|
|
this.menuElement.remove();
|
|
}
|
|
|
|
return super.onCloseAfterTimeout();
|
|
}
|
|
}
|