session management in settings

pull/1856/head
antelle 2 years ago
parent 47153e41d3
commit 9826965803
No known key found for this signature in database
GPG Key ID: 63C9777AAB7C563C

@ -216,6 +216,20 @@ const BrowserExtensionConnector = {
}
this.sendSocketResult(socketId, result);
},
get sessions() {
return ProtocolImpl.sessions;
},
terminateConnection(connectionId) {
connectionId = +connectionId;
if (Launcher) {
const { ipcRenderer } = Launcher.electron();
ipcRenderer.invoke('browserExtensionConnectorCloseSocket', connectionId);
} else {
ProtocolImpl.deleteConnection(connectionId);
}
}
};

@ -183,10 +183,13 @@ function checkContentRequestPermissions(request) {
clearTimeout(inactivityTimer);
RuntimeDataModel.extensionConnectConfig = extensionConnectView.config;
client.permissions = extensionConnectView.config;
Events.emit('browser-extension-sessions-changed');
resolve();
},
cancel: () => {
client.permissionsDenied = true;
clearTimeout(inactivityTimer);
Events.emit('browser-extension-sessions-changed');
reject(makeError(Errors.userRejected));
}
});
@ -242,7 +245,13 @@ const ProtocolHandlers = {
const keys = tweetnaclBox.keyPair();
publicKey = kdbxweb.ByteUtils.base64ToBytes(publicKey);
connectedClients.set(clientId, { connection, publicKey, version, keys });
const stats = {
connectedDate: new Date()
};
connectedClients.set(clientId, { connection, publicKey, version, keys, stats });
Events.emit('browser-extension-sessions-changed');
logger.info('New client key created', clientId, version);
@ -420,15 +429,22 @@ const ProtocolImpl = {
},
cleanup() {
const wasNotEmpty = connectedClients.size;
connectedClients.clear();
if (wasNotEmpty) {
Events.emit('browser-extension-sessions-changed');
}
},
deleteConnection(connectionId) {
for (const client of connectedClients.values()) {
for (const [clientId, client] of connectedClients.entries()) {
if (client.connection.connectionId === connectionId) {
connectedClients.delete(client);
connectedClients.delete(clientId);
}
}
Events.emit('browser-extension-sessions-changed');
},
errorToResponse(e, request) {
@ -449,6 +465,22 @@ const ProtocolImpl = {
} catch (e) {
return this.errorToResponse(e, request);
}
},
get sessions() {
return [...connectedClients.entries()]
.map(([clientId, client]) => ({
clientId,
connectionId: client.connection.connectionId,
appName: client.connection.appName,
extensionName: client.connection.extensionName,
connectedDate: client.stats.connectedDate,
passwordsRead: client.stats.passwordsRead,
passwordsWritten: client.stats.passwordsWritten,
permissions: client.permissions,
permissionsDenied: client.permissionsDenied
}))
.sort((x, y) => y.connectedDate - x.connectedDate);
}
};

@ -657,6 +657,17 @@
"setBrowserExtensionKPXCWarnHeader": "{} will stop working",
"setBrowserExtensionKPXCWarnBody1": "Unfortunately it's not possible to connect one extension to several apps. If you connect the extension to KeeWeb, we'll overwrite its app association, which means that integration with {} will stop working. Even if you uncheck this checkbox, the association with {} won't be restored. To make it work again, configure browser integration in {} settings.",
"setBrowserExtensionKPXCWarnBody2": "Configure the extension to use KeeWeb?",
"setBrowserSessions": "Sessions",
"setBrowserSessionsEmpty": "No connected sessions.",
"setBrowserSessionsIntro": "These extensions are now connected to KeeWeb.",
"setBrowserSessionsActiveTooltip": "Active session",
"setBrowserSessionsActiveText": "This session is active. It can exchange data with KeeWeb based on the following permissions:",
"setBrowserSessionsInactiveTooltip": "Inactive session",
"setBrowserSessionsInactiveText": "This session is inactive. The extension is connected to KeeWeb, however, it hasn't tried to exchange data. When the extension requests anything, you will be able to choose what you want to share.",
"setBrowserSessionsDeniedTooltip": "Access denied",
"setBrowserSessionsDeniedText": "This session is inactive. The extension is connected to KeeWeb, however, you denied access to data.",
"setBrowserConnectedDate": "Connected",
"setBrowserTerminateSession": "Terminate this session",
"setDevicesTitle": "Devices",
"setDevicesEnableUsb": "Enable interaction with USB devices",

@ -1,3 +1,4 @@
import { Events } from 'framework/events';
import { View } from 'framework/views/view';
import template from 'templates/settings/settings-browser.hbs';
import { Features } from 'util/features';
@ -11,20 +12,32 @@ import {
SupportedExtensions
} from 'comp/extension/browser-extension-connector';
import { Alerts } from 'comp/ui/alerts';
import { DateFormat } from 'comp/i18n/date-format';
class SettingsBrowserView extends View {
template = template;
events = {
'change .check-enable-for-browser': 'changeEnableForBrowser',
'change .settings__browser-focus-if-locked': 'changeFocusIfLocked'
'change .settings__browser-focus-if-locked': 'changeFocusIfLocked',
'click .settings__browser-btn-terminate-session': 'terminateSession'
};
constructor(model, options) {
super(model, options);
this.listenTo(Events, 'browser-extension-sessions-changed', this.render);
}
render() {
const data = {
desktop: Features.isDesktop,
icon: Features.browserIcon,
focusIfLocked: AppSettingsModel.extensionFocusIfLocked
focusIfLocked: AppSettingsModel.extensionFocusIfLocked,
sessions: BrowserExtensionConnector.sessions.map((session) => ({
...session,
connectedDate: DateFormat.dtStr(session.connectedDate)
}))
};
if (Features.isDesktop) {
data.extensionNames = ['KeeWeb Connect', 'KeePassXC-Browser'];
@ -103,6 +116,11 @@ class SettingsBrowserView extends View {
AppSettingsModel.extensionFocusIfLocked = e.target.checked;
this.render();
}
terminateSession(e) {
const connectionId = e.target.dataset.connectionId;
BrowserExtensionConnector.terminateConnection(connectionId);
}
}
export { SettingsBrowserView };

@ -314,6 +314,17 @@
padding: $base-padding;
}
}
&-extension-status {
display: inline-block;
width: 0;
height: 0;
border-radius: 100%;
border: 5px solid;
margin-right: 0.2em;
}
&-session-buttons {
margin-top: $base-padding-h;
}
}
&__donate-btn {
background: #fff;

@ -73,4 +73,47 @@
{{#if focusIfLocked}}checked{{/if}} />
<label for="settings__browser-focus-if-locked">{{res 'setBrowserFocusIfLocked'}}</label>
</div>
<h2>{{res 'setBrowserSessions'}}</h2>
{{#if sessions.length}}
<p>{{res 'setBrowserSessionsIntro'}}</p>
{{#each sessions as |session|}}
<h3>
<div class="settings__browser-extension-status
{{#if session.permissions}}
green-color
{{else if session.permissionsDenied}}
red-color
{{else}}
muted-color
{{/if}}"
title="
{{~#if session.permissions~}}
{{res 'setBrowserSessionsActiveTooltip'}}
{{~else if session.permissionsDenied~}}
{{res 'setBrowserSessionsDeniedTooltip'}}
{{~else~}}
{{res 'setBrowserSessionsInactiveTooltip'}}
{{/if}}"
></div>
{{session.extensionName}} ({{session.appName}})
</h3>
<p>{{res 'setBrowserConnectedDate'}}: {{session.connectedDate}}</p>
{{#if session.permissions}}
{{res 'setBrowserSessionsActiveText'}}
{{else if session.permissionsDenied}}
{{res 'setBrowserSessionsDeniedText'}}
{{else}}
{{res 'setBrowserSessionsInactiveText'}}
{{/if}}
<div class="settings__browser-session-buttons">
<button class="btn btn-error settings__browser-btn-terminate-session"
data-connection-id="{{session.connectionId}}"
>{{res 'setBrowserTerminateSession'}}</button>
</div>
{{/each}}
{{else}}
<p>{{res 'setBrowserSessionsEmpty'}}</p>
{{/if}}
</div>

@ -12,6 +12,7 @@ ipcMain.handle('browserExtensionConnectorStop', browserExtensionConnectorStop);
ipcMain.handle('browserExtensionConnectorEnable', browserExtensionConnectorEnable);
ipcMain.handle('browserExtensionConnectorSocketResult', browserExtensionConnectorSocketResult);
ipcMain.handle('browserExtensionConnectorSocketEvent', browserExtensionConnectorSocketEvent);
ipcMain.handle('browserExtensionConnectorCloseSocket', browserExtensionConnectorCloseSocket);
const logger = new Logger('browser-extension-connector');
@ -105,6 +106,11 @@ function browserExtensionConnectorSocketEvent(e, data) {
sendEventToAllSockets(data);
}
function browserExtensionConnectorCloseSocket(e, socketId) {
const socket = connectedSockets.get(socketId);
socket?.destroy();
}
function getBrowserExtensionSocketName(config) {
const { username, uid } = os.userInfo();
if (process.platform === 'darwin') {

Loading…
Cancel
Save