Skip to content

Commit

Permalink
update "fs-json-store"
Browse files Browse the repository at this point in the history
* decrease chances of getting settings file corrupted by enabling atomic file write
  • Loading branch information
vladimiry committed Jul 16, 2018
1 parent 1b726ed commit 51540e8
Show file tree
Hide file tree
Showing 13 changed files with 144 additions and 85 deletions.
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,14 @@
"electron-rpc-api": "0.2.1",
"electron-unhandled": "1.1.0",
"electron-updater": "2.23.3",
"fs-json-store": "2.0.0",
"fs-json-store": "2.0.2",
"fs-json-store-encryption-adapter": "0.0.3",
"jimp": "0.2.28",
"keepasshttp-client": "2.2.6",
"keytar": "4.2.1",
"rolling-rate-limiter": "0.1.11",
"rxjs": "6.2.2",
"tslib": "1.9.3",
"valid-url": "1.0.9"
},
"devDependencies": {
Expand Down Expand Up @@ -145,15 +146,14 @@
"cssnano": "4.0.2",
"devtron": "1.4.0",
"electron": "2.0.5",
"electron-builder": "20.20.4",
"electron-builder": "20.21.2",
"exports-loader": "0.7.0",
"file-loader": "1.1.11",
"font-awesome": "4.7.0",
"glob": "7.1.2",
"gulp": "3.9.1",
"html-loader": "0.5.5",
"html-webpack-plugin": "4.0.0-alpha",
"hydux-mutator": "0.1.11",
"immer": "1.3.1",
"jasmine": "3.1.0",
"karma": "2.0.4",
Expand Down
1 change: 1 addition & 0 deletions src/@types/memdown/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
declare module "memdown";
4 changes: 2 additions & 2 deletions src/electron-main/api/endpoints-builders/general.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export async function buildGeneralEndpoints(
openAboutWindow: () => {
aboutWindow({
icon_path: ctx.locations.icon,
package_json_dir: path.join(ctx.locations.app, ".."),
package_json_dir: path.join(ctx.locations.appDir, ".."),
});
return EMPTY;
},
Expand All @@ -33,7 +33,7 @@ export async function buildGeneralEndpoints(
})()),

openSettingsFolder: () => {
shell.openItem(ctx.locations.userData);
shell.openItem(ctx.locations.userDataDir);
return EMPTY;
},

Expand Down
2 changes: 1 addition & 1 deletion src/electron-main/api/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ const tests: Record<keyof Endpoints, (t: ExecutionContext<TestContext>) => Imple
openSettingsFolder: async (t) => {
const openItemSpy: sinon.SinonSpy = t.context.mocks.electron.shell.openItem;
await t.context.endpoints.openSettingsFolder().toPromise();
t.true(openItemSpy.alwaysCalledWith(t.context.ctx.locations.userData));
t.true(openItemSpy.alwaysCalledWith(t.context.ctx.locations.userDataDir));
},

patchBaseSettings: async (t) => {
Expand Down
42 changes: 22 additions & 20 deletions src/electron-main/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,27 @@ import {Options as EncryptionAdapterOptions} from "fs-json-store-encryption-adap

import {APP_NAME} from "src/shared/constants";

const encryptionPreset: EncryptionAdapterOptions = {
keyDerivation: {type: "sodium.crypto_pwhash", preset: "mode:interactive|algorithm:default"},
encryption: {type: "sodium.crypto_secretbox_easy", preset: "algorithm:default"},
};

export const INITIAL_STORES = Object.freeze({
config: {
encryptionPreset,
startMinimized: true,
compactLayout: false,
closeToTray: true,
unreadNotifications: true,
checkForUpdatesAndNotify: true,
window: {
bounds: {width: 1024, height: 768},
},
},
settings: {accounts: []},
});

export const KEYTAR_SERVICE_NAME = APP_NAME;
export const KEYTAR_MASTER_PASSWORD_ACCOUNT = "master-password";

export const INITIAL_STORES = (() => {
const encryptionPreset: EncryptionAdapterOptions = {
keyDerivation: {type: "sodium.crypto_pwhash", preset: "mode:interactive|algorithm:default"},
encryption: {type: "sodium.crypto_secretbox_easy", preset: "algorithm:default"},
};

return Object.freeze({
config: {
encryptionPreset,
startMinimized: true,
compactLayout: false,
closeToTray: true,
unreadNotifications: true,
checkForUpdatesAndNotify: true,
window: {
bounds: {width: 1024, height: 768},
},
},
settings: {accounts: []},
});
})();
5 changes: 3 additions & 2 deletions src/electron-main/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@ export interface ContextInitOptions {
}

export interface Context {
readonly storeFs: StoreModel.StoreFs;
readonly runtimeEnvironment: RuntimeEnvironment;
readonly locations: ElectronContextLocations;
initialStores: {
readonly initialStores: {
config: Config;
settings: Settings;
};
configStore: StoreModel.Store<Config>;
readonly configStore: StoreModel.Store<Config>;
settingsStore: StoreModel.Store<Settings>;
uiContext?: UIContext;
}
Expand Down
19 changes: 10 additions & 9 deletions src/electron-main/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import path from "path";
import url from "url";
import {app} from "electron";
import {EncryptionAdapter} from "fs-json-store-encryption-adapter";
import {Model as StoreModel, Store} from "fs-json-store";
import {Fs as StoreFs, Model as StoreModel, Store} from "fs-json-store";

import {BuildEnvironment} from "src/shared/model/common";
import {Config, configEncryptionPresetValidator, Settings, settingsAccountLoginUniquenessValidator} from "src/shared/model/options";
Expand All @@ -18,26 +18,27 @@ export async function initContext(options: ContextInitOptions = {}): Promise<Con
const runtimeEnvironment: RuntimeEnvironment = Boolean(process.env[RUNTIME_ENV_E2E]) ? "e2e" : "production";
const locations = initLocations(runtimeEnvironment, options.paths);
const initialStores = options.initialStores || INITIAL_STORES;
const fsOption = options.storeFs ? {fs: options.storeFs} : {};
const storeFs = options.storeFs ? options.storeFs : StoreFs.Fs.fs;
const configStore = new Store<Config>({
...fsOption,
fs: storeFs,
optimisticLocking: true,
file: path.join(locations.userData, "config.json"),
file: path.join(locations.userDataDir, "config.json"),
validators: [configEncryptionPresetValidator],
});

logger.transports.file.file = path.join(locations.userData, "./log.log");
logger.transports.file.file = path.join(locations.userDataDir, "./log.log");
logger.transports.file.level = "info";

return {
storeFs,
runtimeEnvironment,
locations,
initialStores,
configStore,
settingsStore: new Store<Settings>({
...fsOption,
fs: storeFs,
optimisticLocking: true,
file: path.join(locations.userData, "settings.bin"),
file: path.join(locations.userDataDir, "settings.bin"),
validators: [settingsAccountLoginUniquenessValidator],
}),
};
Expand All @@ -62,8 +63,8 @@ function initLocations(runtimeEnvironment: RuntimeEnvironment, paths?: ContextIn
const formatFileUrl = (pathname: string) => url.format({pathname, protocol: "file:", slashes: true});

return {
app: appRelativePath(),
userData: userDataDir,
appDir,
userDataDir,
icon: appRelativePath(largeIcon),
trayIcon: appRelativePath(os.platform() === "darwin" ? "./assets/icons/mac/icon.png" : largeIcon),
trayIconUnreadOverlay: appRelativePath("./assets/icons/tray-icon-unread-overlay.png"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ export interface BaseEntity {
_id: Id | IdTuple;
}

export type NumberString = string;

export type Id<T extends BaseEntity = BaseEntity> = string;

export type IdTuple<ID1 extends BaseEntity = BaseEntity, ID2 extends BaseEntity = BaseEntity> = [Id<ID1>, Id<ID2>];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {BaseEntity, GroupType, Id, IdTuple, MailFolderType} from "./common";
import {BaseEntity, GroupType, Id, IdTuple, MailFolderType, NumberString} from "./common";

export interface User extends BaseEntity {
memberships: GroupMembership[];
Expand Down Expand Up @@ -54,7 +54,9 @@ export interface MailAddress extends BaseEntity {
}

export interface File extends BaseEntity {

mimeType?: string;
name: string;
size: NumberString;
}

export interface MailBody extends BaseEntity {
Expand Down
4 changes: 2 additions & 2 deletions src/shared/model/electron.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ export interface ElectronWindow {
}

export interface ElectronContextLocations {
readonly app: string;
readonly appDir: string;
readonly browserWindowPage: string;
readonly icon: string;
readonly trayIcon: string;
readonly trayIconUnreadOverlay: string;
readonly trayIconLoggedOutOverlay: string;
readonly userData: string;
readonly userDataDir: string;
readonly preload: {
browserWindow: string;
browserWindowE2E: string;
Expand Down
4 changes: 2 additions & 2 deletions src/webpack/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ const buildBaseConfig: BuildConfig = (config, options = {}) => {
uglifyOptions: {
compress: false,
mangle: false,
ecma: 6,
ecma: 7,
output: {
comments: true,
beautify: true,
beautify: false,
},
},
}),
Expand Down
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"noEmitOnError": true,
"importHelpers": true,
"declaration": false,
"sourceMap": true,
"lib": [
Expand Down
Loading

0 comments on commit 51540e8

Please sign in to comment.