mirror of
https://github.com/Foundry376/Mailspring.git
synced 2024-09-22 16:26:08 +08:00
117 lines
3.4 KiB
JavaScript
117 lines
3.4 KiB
JavaScript
import { remote } from 'electron';
|
|
import keytar from 'keytar';
|
|
|
|
/**
|
|
* A basic wrap around keytar's secure key management. Consolidates all of
|
|
* our keys under a single namespaced keymap and provides migration
|
|
* support.
|
|
*
|
|
* Consolidating this prevents a ton of key authorization popups for each
|
|
* and every key we want to access.
|
|
*/
|
|
class KeyManager {
|
|
constructor() {
|
|
this.SERVICE_NAME = AppEnv.inDevMode() ? 'Mailspring Dev' : 'Mailspring';
|
|
this.KEY_NAME = 'Mailspring Keys';
|
|
}
|
|
|
|
async deleteAccountSecrets(account) {
|
|
try {
|
|
const keys = await this._getKeyHash();
|
|
delete keys[`${account.emailAddress}-imap`];
|
|
delete keys[`${account.emailAddress}-smtp`];
|
|
delete keys[`${account.emailAddress}-refresh-token`];
|
|
await this._writeKeyHash(keys);
|
|
} catch (err) {
|
|
this._reportFatalError(err);
|
|
}
|
|
}
|
|
|
|
async extractAccountSecrets(account) {
|
|
try {
|
|
const keys = await this._getKeyHash();
|
|
keys[`${account.emailAddress}-imap`] = account.settings.imap_password;
|
|
keys[`${account.emailAddress}-smtp`] = account.settings.smtp_password;
|
|
keys[`${account.emailAddress}-refresh-token`] = account.settings.refresh_token;
|
|
await this._writeKeyHash(keys);
|
|
} catch (err) {
|
|
this._reportFatalError(err);
|
|
}
|
|
const next = account.clone();
|
|
delete next.settings.imap_password;
|
|
delete next.settings.smtp_password;
|
|
delete next.settings.refresh_token;
|
|
return next;
|
|
}
|
|
|
|
async insertAccountSecrets(account) {
|
|
const next = account.clone();
|
|
const keys = await this._getKeyHash();
|
|
next.settings.imap_password = keys[`${account.emailAddress}-imap`];
|
|
next.settings.smtp_password = keys[`${account.emailAddress}-smtp`];
|
|
next.settings.refresh_token = keys[`${account.emailAddress}-refresh-token`];
|
|
return next;
|
|
}
|
|
|
|
async replacePassword(keyName, newVal) {
|
|
try {
|
|
const keys = await this._getKeyHash();
|
|
keys[keyName] = newVal;
|
|
await this._writeKeyHash(keys);
|
|
} catch (err) {
|
|
this._reportFatalError(err);
|
|
}
|
|
}
|
|
|
|
async deletePassword(keyName) {
|
|
try {
|
|
const keys = await this._getKeyHash();
|
|
delete keys[keyName];
|
|
await this._writeKeyHash(keys);
|
|
} catch (err) {
|
|
this._reportFatalError(err);
|
|
}
|
|
}
|
|
|
|
async getPassword(keyName) {
|
|
try {
|
|
const keys = await this._getKeyHash();
|
|
return keys[keyName];
|
|
} catch (err) {
|
|
this._reportFatalError(err);
|
|
}
|
|
}
|
|
|
|
async _getKeyHash() {
|
|
const raw = (await keytar.getPassword(this.SERVICE_NAME, this.KEY_NAME)) || '{}';
|
|
try {
|
|
return JSON.parse(raw);
|
|
} catch (err) {
|
|
return {};
|
|
}
|
|
}
|
|
|
|
async _writeKeyHash(keys) {
|
|
await keytar.setPassword(this.SERVICE_NAME, this.KEY_NAME, JSON.stringify(keys));
|
|
}
|
|
|
|
_reportFatalError(err) {
|
|
let more = '';
|
|
if (process.platform === 'linux') {
|
|
more = 'Make sure you have `libsecret` installed and a keyring is present. ';
|
|
}
|
|
remote.dialog.showMessageBox({
|
|
type: 'error',
|
|
buttons: ['Quit'],
|
|
message: `Mailspring could not store your password securely. ${more} For more information, visit http://support.getmailspring.com/hc/en-us/articles/115001875571`,
|
|
});
|
|
|
|
// tell the app to exit and rethrow the error to ensure code relying
|
|
// on the passwords being saved never runs (saving identity for example)
|
|
remote.app.quit();
|
|
throw err;
|
|
}
|
|
}
|
|
|
|
export default new KeyManager();
|