134 lines
6.5 KiB
TypeScript
134 lines
6.5 KiB
TypeScript
import * as electronRemote from '@electron/remote';
|
|
const electronConsole = electronRemote.getGlobal('console') as Console;
|
|
import Logger from '../../../logger/logger';
|
|
const LOG = Logger.create(__filename, electronConsole);
|
|
|
|
import * as moment from 'moment';
|
|
|
|
import BaseElements from './require/base-elements';
|
|
import ElementsUtil from './require/elements-util';
|
|
|
|
import Util from '../util';
|
|
|
|
import { $, $$, $$$, $$$$ } from './require/q-module';
|
|
|
|
import IState from './require/elements-state';
|
|
import ClientController from '../client-controller';
|
|
import { Member } from '../data-types';
|
|
|
|
export default function createTokenLogOverlay(state: IState, server: ClientController): HTMLElement {
|
|
const { document } = state;
|
|
$.setDocument(document);
|
|
|
|
let element = BaseElements.createOverlay(document, {
|
|
class: 'content token-log', content: [
|
|
{ class: 'tokens', content: { tag: 'img', src: './img/loading.svg', alt: 'loading...' } },
|
|
]
|
|
});
|
|
|
|
(async () => {
|
|
Util.withPotentialErrorWarnOnCancel({
|
|
taskFunc: async () => {
|
|
let tokens = await server.queryTokens();
|
|
$.clearChildren($$$(element, '.tokens'));
|
|
let displayed = 0;
|
|
for (let token of tokens) {
|
|
// if (token.member != null) {
|
|
// continue;
|
|
// }
|
|
let expired = token.expires < new Date();
|
|
// NOTE: It may be nice to be able to click-to-copy the token
|
|
let memberText: string;
|
|
if (token.member instanceof Member) {
|
|
memberText = token.member.displayName;
|
|
} else if (token.member) {
|
|
memberText = '#' + token.member.id;
|
|
} else {
|
|
memberText = 'Unused Token';
|
|
}
|
|
let displayElement = $.create({
|
|
class: 'token-display', content: [
|
|
{ class: 'instance', content: [
|
|
{ class: 'left', content: [
|
|
{ class: 'member', content: memberText },
|
|
{ class: 'token', content: token.token },
|
|
] },
|
|
{ class: 'right', content: [
|
|
{ class: 'created', content: 'Created ' + moment(token.created).fromNow() },
|
|
{ class: 'expires', content: (expired ? 'Expired ' : 'Expires ') + moment(token.expires).fromNow() },
|
|
] }
|
|
] },
|
|
{ class: 'buttons', content: [
|
|
{ class: 'revoke', content: BaseElements.TRASHCAN }
|
|
] }
|
|
]
|
|
}) as HTMLElement;
|
|
let revokeElement = $$$(displayElement, '.buttons .revoke');
|
|
let contextElement = $.create({ class: 'context', content: {
|
|
class: 'above', content: [
|
|
{ class: 'tab', content: BaseElements.TAB_ABOVE },
|
|
{ class: 'content text', content: 'Revoke' },
|
|
] }
|
|
}) as HTMLElement;
|
|
let alignment = { centerX: 'centerX', top: 'bottom' };
|
|
ElementsUtil.bindHoverableContextElement(
|
|
revokeElement,
|
|
contextElement,
|
|
revokeElement,
|
|
alignment
|
|
);
|
|
let revoking = false;
|
|
let hoverTimeout: any | null = null;
|
|
revokeElement.addEventListener('click', async () => {
|
|
if (revoking) return;
|
|
revoking = true;
|
|
if (hoverTimeout) clearTimeout(hoverTimeout);
|
|
(contextElement as any).manualRemoval = true;
|
|
$$$(contextElement, '.content').innerText = 'Revoking...';
|
|
ElementsUtil.alignContextElement(contextElement, revokeElement, alignment);
|
|
try {
|
|
await server.revokeToken(token.token);
|
|
} catch (e) {
|
|
LOG.error('unable to revoke token', e);
|
|
$$$(contextElement, '.content').innerText = 'Unable to Revoke';
|
|
ElementsUtil.alignContextElement(contextElement, revokeElement, alignment);
|
|
await ElementsUtil.shakeElement(revokeElement, 400);
|
|
hoverTimeout = setTimeout(() => {
|
|
(contextElement as any).manualRemoval = false;
|
|
contextElement.parentElement?.removeChild(contextElement);
|
|
$$$(contextElement, '.content').innerText = 'Revoke';
|
|
}, 2000);
|
|
return;
|
|
} finally {
|
|
revoking = false;
|
|
}
|
|
contextElement.parentElement?.removeChild(contextElement);
|
|
displayElement.parentElement?.removeChild(displayElement);
|
|
displayed -= 1;
|
|
if (displayed == 0) {
|
|
$$$(element, '.tokens').appendChild($.create({
|
|
class: 'empty', content: 'No outstanding tokens'
|
|
}));
|
|
}
|
|
});
|
|
$$$(element, '.tokens').appendChild(displayElement);
|
|
displayed += 1;
|
|
}
|
|
if (displayed == 0) {
|
|
$$$(element, '.tokens').appendChild($.create({
|
|
class: 'empty', content: 'No outstanding tokens'
|
|
}));
|
|
}
|
|
},
|
|
errorIndicatorAddFunc: async (errorIndicatorElement) => {
|
|
$.clearChildren($$$(element, '.tokens'));
|
|
$$$(element, '.tokens').appendChild(errorIndicatorElement);
|
|
},
|
|
errorContainer: $$$(element, '.tokens'),
|
|
errorMessage: 'Error fetching tokens'
|
|
});
|
|
})();
|
|
|
|
return element;
|
|
}
|