mirror of https://github.com/Fabio286/antares.git
feat: better security connections credentials storage
This commit is contained in:
parent
65ad0e954d
commit
fc35f271d7
|
@ -1 +1,6 @@
|
||||||
* text eol=lf
|
* text eol=lf
|
||||||
|
*.jpg binary
|
||||||
|
*.png binary
|
||||||
|
*.gif binary
|
||||||
|
*.ico binary
|
||||||
|
*.icns binary
|
|
@ -36,6 +36,7 @@ An application created with minimalism and semplicity in mind, with features in
|
||||||
- Query suggestions.
|
- Query suggestions.
|
||||||
- Native dark theme.
|
- Native dark theme.
|
||||||
- Multi language.
|
- Multi language.
|
||||||
|
- Secure password storage.
|
||||||
- Auto updates.
|
- Auto updates.
|
||||||
|
|
||||||
## Coming soon
|
## Coming soon
|
||||||
|
@ -44,7 +45,6 @@ This is a roadmap with major features will come in near future.
|
||||||
|
|
||||||
- Stored procedures, views, schedulers and triggers support.
|
- Stored procedures, views, schedulers and triggers support.
|
||||||
- Users management (add/edit/delete).
|
- Users management (add/edit/delete).
|
||||||
- More secure password storage.
|
|
||||||
- Database tools (variables, process list...).
|
- Database tools (variables, process list...).
|
||||||
- SSL and SSH tunnel support.
|
- SSL and SSH tunnel support.
|
||||||
- Support for other databases.
|
- Support for other databases.
|
||||||
|
|
|
@ -49,7 +49,9 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@mdi/font": "^5.8.55",
|
"@mdi/font": "^5.8.55",
|
||||||
"electron-log": "^4.3.0",
|
"electron-log": "^4.3.0",
|
||||||
|
"electron-store": "^6.0.1",
|
||||||
"electron-updater": "^4.3.5",
|
"electron-updater": "^4.3.5",
|
||||||
|
"keytar": "^7.3.0",
|
||||||
"lodash": "^4.17.20",
|
"lodash": "^4.17.20",
|
||||||
"moment": "^2.29.1",
|
"moment": "^2.29.1",
|
||||||
"monaco-editor": "^0.20.0",
|
"monaco-editor": "^0.20.0",
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
|
|
||||||
import { app, BrowserWindow, nativeImage } from 'electron';
|
import { app, BrowserWindow, nativeImage } from 'electron';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
import crypto from 'crypto';
|
||||||
import { format as formatUrl } from 'url';
|
import { format as formatUrl } from 'url';
|
||||||
|
import keytar from 'keytar';
|
||||||
import ipcHandlers from './ipc-handlers';
|
import ipcHandlers from './ipc-handlers';
|
||||||
|
|
||||||
const isDevelopment = process.env.NODE_ENV !== 'production';
|
const isDevelopment = process.env.NODE_ENV !== 'production';
|
||||||
|
@ -89,7 +91,14 @@ else {
|
||||||
});
|
});
|
||||||
|
|
||||||
// create main BrowserWindow when electron is ready
|
// create main BrowserWindow when electron is ready
|
||||||
app.on('ready', () => {
|
app.on('ready', async () => {
|
||||||
|
let key = await keytar.getPassword('antares', 'user');
|
||||||
|
|
||||||
|
if (!key) {
|
||||||
|
key = crypto.randomBytes(16).toString('hex');
|
||||||
|
keytar.setPassword('antares', 'user', key);
|
||||||
|
}
|
||||||
|
|
||||||
mainWindow = createMainWindow();
|
mainWindow = createMainWindow();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,13 @@
|
||||||
|
import keytar from 'keytar';
|
||||||
import { app, ipcMain } from 'electron';
|
import { app, ipcMain } from 'electron';
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
ipcMain.on('close-app', () => {
|
ipcMain.on('close-app', () => {
|
||||||
app.exit();
|
app.exit();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ipcMain.on('get-key', async event => {
|
||||||
|
const key = await keytar.getPassword('antares', 'user');
|
||||||
|
event.returnValue = key;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
'use strict';
|
||||||
|
import { ipcRenderer } from 'electron';
|
||||||
|
|
||||||
|
export default class {
|
||||||
|
static getKey (params) {
|
||||||
|
return ipcRenderer.sendSync('get-key', params);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,10 +1,20 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
import Store from 'electron-store';
|
||||||
|
import Application from '../../ipc-api/Application';
|
||||||
|
const key = Application.getKey();
|
||||||
|
|
||||||
|
console.log(key);
|
||||||
|
|
||||||
|
const persistentStore = new Store({
|
||||||
|
name: 'connections',
|
||||||
|
encryptionKey: key
|
||||||
|
});
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
namespaced: true,
|
namespaced: true,
|
||||||
strict: true,
|
strict: true,
|
||||||
state: {
|
state: {
|
||||||
connections: []
|
connections: persistentStore.get('connections') || []
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
getConnections: state => state.connections,
|
getConnections: state => state.connections,
|
||||||
|
@ -20,9 +30,11 @@ export default {
|
||||||
mutations: {
|
mutations: {
|
||||||
ADD_CONNECTION (state, connection) {
|
ADD_CONNECTION (state, connection) {
|
||||||
state.connections.push(connection);
|
state.connections.push(connection);
|
||||||
|
persistentStore.set('connections', state.connections);
|
||||||
},
|
},
|
||||||
DELETE_CONNECTION (state, connection) {
|
DELETE_CONNECTION (state, connection) {
|
||||||
state.connections = state.connections.filter(el => el.uid !== connection.uid);
|
state.connections = state.connections.filter(el => el.uid !== connection.uid);
|
||||||
|
persistentStore.set('connections', state.connections);
|
||||||
},
|
},
|
||||||
EDIT_CONNECTION (state, connection) {
|
EDIT_CONNECTION (state, connection) {
|
||||||
const editedConnections = state.connections.map(conn => {
|
const editedConnections = state.connections.map(conn => {
|
||||||
|
@ -31,9 +43,11 @@ export default {
|
||||||
});
|
});
|
||||||
state.connections = editedConnections;
|
state.connections = editedConnections;
|
||||||
state.selected_conection = {};
|
state.selected_conection = {};
|
||||||
|
persistentStore.set('connections', state.connections);
|
||||||
},
|
},
|
||||||
UPDATE_CONNECTIONS (state, connections) {
|
UPDATE_CONNECTIONS (state, connections) {
|
||||||
state.connections = connections;
|
state.connections = connections;
|
||||||
|
persistentStore.set('connections', state.connections);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
import i18n from '@/i18n';
|
import i18n from '@/i18n';
|
||||||
|
import Store from 'electron-store';
|
||||||
|
const persistentStore = new Store({ name: 'settings' });
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
namespaced: true,
|
namespaced: true,
|
||||||
strict: true,
|
strict: true,
|
||||||
state: {
|
state: {
|
||||||
locale: 'en-US',
|
locale: persistentStore.get('locale') || 'en-US',
|
||||||
explorebar_size: null,
|
explorebar_size: persistentStore.get('explorebar_size') || null,
|
||||||
notifications_timeout: 5
|
notifications_timeout: persistentStore.get('notifications_timeout') || 5
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
getLocale: state => state.locale,
|
getLocale: state => state.locale,
|
||||||
|
@ -18,12 +20,15 @@ export default {
|
||||||
SET_LOCALE (state, locale) {
|
SET_LOCALE (state, locale) {
|
||||||
state.locale = locale;
|
state.locale = locale;
|
||||||
i18n.locale = locale;
|
i18n.locale = locale;
|
||||||
|
persistentStore.set('locale', state.locale);
|
||||||
},
|
},
|
||||||
SET_NOTIFICATIONS_TIMEOUT (state, timeout) {
|
SET_NOTIFICATIONS_TIMEOUT (state, timeout) {
|
||||||
state.notifications_timeout = timeout;
|
state.notifications_timeout = timeout;
|
||||||
|
persistentStore.set('notifications_timeout', state.notifications_timeout);
|
||||||
},
|
},
|
||||||
SET_EXPLOREBAR_SIZE (state, size) {
|
SET_EXPLOREBAR_SIZE (state, size) {
|
||||||
state.explorebar_size = size;
|
state.explorebar_size = size;
|
||||||
|
persistentStore.set('explorebar_size', state.explorebar_size);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
|
|
Loading…
Reference in New Issue