This repository was archived by the owner on Aug 15, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathaccount.ts
158 lines (138 loc) · 4.15 KB
/
account.ts
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
import bs58 from 'bs58';
import * as t from 'io-ts';
import nacl from 'tweetnacl';
import { HandshakeResponse } from '../../models/HandshakeBody';
import db from '../db';
import file from '../file';
import log from '../logger';
import { ServerLookup, LocalLookup } from '../models/Message';
import UserSettings from '../models/UserSettings';
import { LoadOpts } from './sync';
export interface KeyPair {
publicKey: string;
secretKey: string;
}
export const FIXED_USER_NAME = 'local';
// defaults of the settings stored in 'config' and controlled by popup
const DEFAULT_SETTINGS = {
active: true,
ux: false,
};
/**
* Create publicKey and secretKey
*/
export function initializeKey(): KeyPair {
// use publicKey and secretKey from process.env when available
if (process.env.PUBLIC_KEY && process.env.SECRET_KEY) {
log.info(
'Found PUBLIC and SECRET keys in environment, returning those and skipping generation %j',
process.env
);
return {
publicKey: process.env.PUBLIC_KEY,
secretKey: process.env.SECRET_KEY,
};
}
const newKeypair = nacl.sign.keyPair();
const publicKey = bs58.encode(newKeypair.publicKey);
const secretKey = bs58.encode(newKeypair.secretKey);
const rv = { publicKey, secretKey };
log.info('initializing new key pair: %O', rv);
return rv;
}
interface WithUserId {
userId: string;
}
const readOrDefault = async <T extends t.Mixed>(
fn: string,
codec: T,
defaults: any
): Promise<T['_O']> => {
try {
const result = await file.readJSON(fn, codec);
return {
...defaults,
...result,
};
} catch (err) {
log.info('Error caught while checking settings.json: %s', err);
return defaults;
}
};
/**
* Load settings from `settings.json`
*/
export async function handleSettingsLookup(
{ userId }: WithUserId,
sendResponse: (response: Partial<UserSettings>) => void
): Promise<void> {
const settingsJson = await readOrDefault(
'settings.json',
t.partial(UserSettings.props),
DEFAULT_SETTINGS
);
log.info('Loaded configuration from file settings.json: %j', settingsJson);
const experimentInfo = await readOrDefault('experiment.json', t.any, {});
log.info(
'Loaded experiment info from file experiment.json: %j',
experimentInfo
);
const settings = { ...DEFAULT_SETTINGS, ...settingsJson, ...experimentInfo };
log.info('Final settings: %j', settings);
return sendResponse(settings);
}
/**
* Get settings from chrome.storage
*
* Then `publicKey` and `secretKey` creation is defined by the variable `initKeys`.
*/
export async function handleLocalLookup(
{ userId }: LocalLookup['payload'],
sendResponse: (response: Partial<UserSettings>) => void
): Promise<void> {
let settings;
try {
settings = await db.getValid(t.partial(UserSettings.props))(userId);
log.info('Loaded correctly settings from localStorage %j', settings);
} catch (err) {
log.info('Settings in db is not well formed %O', err);
const initialSettings: Partial<UserSettings> = {
...DEFAULT_SETTINGS,
};
settings = await db.set(userId, initialSettings);
}
return sendResponse(settings);
}
/**
* handleServerLookup will be used to fetch settings from the server
* after the default settings have been obtained from the local storage
*
*/
export const handleServerLookup =
(opts: LoadOpts) =>
async (
{ href, ...config }: ServerLookup['payload'],
sendResponse: (response: HandshakeResponse) => void
): Promise<void> => {
log.info('handshake body %O', config);
void opts.api.v2.Public.Handshake({
Body: { config, href },
} as any)().then((response: any) => {
log.info('handshake response %O', response);
if (response._tag === 'Right') {
sendResponse(response.right);
} else {
// TODO: handle error here
sendResponse(response.left);
}
});
};
export async function handleConfigUpdate(
payload: Partial<UserSettings>,
sendResponse: (response: Partial<UserSettings>) => void
): Promise<void> {
const userId = FIXED_USER_NAME;
const settings = await db.update(userId, payload);
log.info('completed ConfigUpdate, user settings now', settings);
sendResponse(settings);
}