Files
kopia/app/public/config.js
Jarek Kowalski 3b87902433 Kopia UI improvements for repository management (#592)
* cli: added --tls-print-server-cert flag

This prints complete server certificate that is base64 and PEM-encoded.

It is needed for Electron to securely connect to the server outside of
the browser, since there's no way to trust certificate by fingerprint.

* server: added repo/exists API

* server: added ClientOptions to create and connect API

* server: exposed current-user API

* server: API to change description of a repository

* htmlui: refactored connect/create flow

This cleaned up the code a lot and made UX more obvious.

* kopia-ui: simplified repository management UX

Removed repository configuration window which was confusing due to
the notion of 'server'.

Now KopiaUI will automatically launch 'kopia server --ui' for each
config found in the kopia config directory and shut it down every
time repository is disconnected.

See https://youtu.be/P4Ll_LR4UVM for a quick demo.

Fixes #583
2020-09-07 08:00:19 -07:00

156 lines
3.7 KiB
JavaScript

const fs = require('fs');
const path = require('path');
const Electron = require('electron');
const log = require("electron-log");
let configs = {};
const configFileSuffix = ".config";
let configDir = "";
let isPortable = false;
let firstRun = false;
// returns the list of directories to be checked for portable configurations
function portableConfigDirs() {
let result = [];
if (process.env.KOPIA_UI_PORTABLE_CONFIG_DIR) {
result.push(process.env.KOPIA_UI_PORTABLE_CONFIG_DIR);
}
if (process.platform == "darwin") {
// on Mac support 'repositories' directory next to the KopiaUI.app
result.push(path.join(path.dirname(Electron.app.getPath("exe")), "..", "..", "..", "repositories"));
} else {
// on other platforms support 'repositories' directory next to directory
// containing executable or 'repositories' subdirectory.
result.push(path.join(path.dirname(Electron.app.getPath("exe")), "repositories"));
result.push(path.join(path.dirname(Electron.app.getPath("exe")), "..", "repositories"));
}
return result;
}
function globalConfigDir() {
if (!configDir) {
// try portable config dirs in order.
portableConfigDirs().forEach(d => {
if (configDir) {
return;
}
d = path.normalize(d)
if (!fs.existsSync(d)) {
return;
}
configDir = d;
isPortable = true;
});
// still not set, fall back to per-user config dir.
// we use the same directory that is used by Kopia CLI.
if (!configDir) {
configDir = path.join(Electron.app.getPath("appData"), "kopia");
}
}
return configDir;
}
function allConfigs() {
let result = [];
for (let k in configs) {
result.push(k);
}
return result;
}
function addNewConfig() {
let id;
if (!configs) {
// first repository is always named "repository" to match Kopia CLI.
id = "repository";
} else {
id = "repository-" + new Date().valueOf();
}
configs[id] = true;
return id;
}
Electron.ipcMain.on('config-list-fetch', (event, arg) => {
emitConfigListUpdated();
});
function emitConfigListUpdated() {
Electron.ipcMain.emit('config-list-updated-event', allConfigs());
};
function deleteConfigIfDisconnected(repoID) {
if (repoID === "repository") {
// never delete default repository config
return false;
}
if (!fs.existsSync(path.join(globalConfigDir(), repoID + configFileSuffix))) {
delete (configs[repoID]);
emitConfigListUpdated();
return true;
}
return false;
}
module.exports = {
loadConfigs() {
fs.mkdirSync(globalConfigDir(), { recursive: true, mode: 0700 });
let entries = fs.readdirSync(globalConfigDir());
let count = 0;
entries.filter(e => path.extname(e) == configFileSuffix).forEach(v => {
const repoID = v.replace(configFileSuffix, "");
configs[repoID] = true;
count++;
});
if (!configs["repository"]) {
configs["repository"] = true;
firstRun = true;
}
},
isPortableConfig() {
globalConfigDir();
return isPortable;
},
isFirstRun() {
return firstRun;
},
configDir() {
return globalConfigDir();
},
deleteConfigIfDisconnected,
addNewConfig,
allConfigs,
configForRepo(repoID) {
let c = configs[repoID];
if (c) {
return c;
}
configs[repoID] = true;
emitConfigListUpdated();
return c;
}
}