forked from pingdotgg/t3code
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathElectronSafeStorage.ts
More file actions
82 lines (74 loc) · 2.47 KB
/
Copy pathElectronSafeStorage.ts
File metadata and controls
82 lines (74 loc) · 2.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import * as Context from "effect/Context";
import * as Data from "effect/Data";
import * as Effect from "effect/Effect";
import * as Layer from "effect/Layer";
import * as Option from "effect/Option";
import * as Electron from "electron";
export class ElectronSafeStorageAvailabilityError extends Data.TaggedError(
"ElectronSafeStorageAvailabilityError",
)<{
readonly cause: unknown;
}> {
override get message() {
return "Electron safe storage failed to check encryption availability.";
}
}
export class ElectronSafeStorageEncryptError extends Data.TaggedError(
"ElectronSafeStorageEncryptError",
)<{
readonly cause: unknown;
}> {
override get message() {
return "Electron safe storage failed to encrypt a string.";
}
}
export class ElectronSafeStorageDecryptError extends Data.TaggedError(
"ElectronSafeStorageDecryptError",
)<{
readonly cause: unknown;
}> {
override get message() {
return "Electron safe storage failed to decrypt a string.";
}
}
export interface ElectronSafeStorageShape {
readonly isEncryptionAvailable: Effect.Effect<boolean, ElectronSafeStorageAvailabilityError>;
readonly selectedStorageBackend: Effect.Effect<Option.Option<string>>;
readonly encryptString: (
value: string,
) => Effect.Effect<Uint8Array, ElectronSafeStorageEncryptError>;
readonly decryptString: (
value: Uint8Array,
) => Effect.Effect<string, ElectronSafeStorageDecryptError>;
}
export class ElectronSafeStorage extends Context.Service<
ElectronSafeStorage,
ElectronSafeStorageShape
>()("@t3tools/desktop/ElectronSafeStorage") {}
const make = ElectronSafeStorage.of({
isEncryptionAvailable: Effect.try({
try: () => Electron.safeStorage.isEncryptionAvailable(),
catch: (cause) => new ElectronSafeStorageAvailabilityError({ cause }),
}),
selectedStorageBackend: Effect.sync(() => {
if (process.platform !== "linux") {
return Option.none();
}
try {
return Option.fromNullishOr(Electron.safeStorage.getSelectedStorageBackend());
} catch {
return Option.none();
}
}),
encryptString: (value) =>
Effect.try({
try: () => Electron.safeStorage.encryptString(value),
catch: (cause) => new ElectronSafeStorageEncryptError({ cause }),
}),
decryptString: (value) =>
Effect.try({
try: () => Electron.safeStorage.decryptString(Buffer.from(value)),
catch: (cause) => new ElectronSafeStorageDecryptError({ cause }),
}),
});
export const layer = Layer.succeed(ElectronSafeStorage, make);