@peerbit/server 3.0.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/esm/aws.browser.d.ts +0 -0
- package/lib/esm/aws.browser.js +3 -0
- package/lib/esm/aws.browser.js.map +1 -0
- package/lib/esm/aws.d.ts +19 -0
- package/lib/esm/aws.js +185 -1
- package/lib/esm/aws.js.map +1 -1
- package/lib/esm/cli.js +592 -324
- package/lib/esm/cli.js.map +1 -1
- package/lib/esm/client.d.ts +11 -5
- package/lib/esm/client.js +64 -11
- package/lib/esm/client.js.map +1 -1
- package/lib/esm/docker.browser.d.ts +0 -0
- package/lib/esm/docker.browser.js +3 -0
- package/lib/esm/docker.browser.js.map +1 -0
- package/lib/esm/domain.js +1 -1
- package/lib/esm/domain.js.map +1 -1
- package/lib/esm/peerbit.d.ts +1 -1
- package/lib/esm/remotes.d.ts +15 -2
- package/lib/esm/remotes.js +8 -8
- package/lib/esm/remotes.js.map +1 -1
- package/lib/esm/routes.d.ts +3 -2
- package/lib/esm/routes.js +5 -4
- package/lib/esm/routes.js.map +1 -1
- package/lib/esm/server.d.ts +3 -1
- package/lib/esm/server.js +32 -19
- package/lib/esm/server.js.map +1 -1
- package/lib/esm/trust.d.ts +1 -1
- package/lib/esm/trust.js.map +1 -1
- package/lib/ui/assets/aws.browser-4ed993c7.js +1 -0
- package/lib/ui/assets/index-5ed0229d.js +77 -0
- package/lib/ui/index.html +1 -1
- package/package.json +13 -7
- package/src/aws.browser.ts +1 -0
- package/src/aws.ts +250 -1
- package/src/cli.ts +676 -354
- package/src/client.ts +76 -11
- package/src/docker.browser.ts +1 -0
- package/src/domain.ts +1 -1
- package/src/peerbit.ts +1 -1
- package/src/remotes.ts +24 -10
- package/src/routes.ts +5 -4
- package/src/server.ts +43 -23
- package/src/trust.ts +1 -1
- package/lib/ui/assets/index-cac7195d.js +0 -77
package/src/client.ts
CHANGED
|
@@ -2,31 +2,56 @@ import { InstallDependency, StartProgram } from "./types.js";
|
|
|
2
2
|
import {
|
|
3
3
|
ADDRESS_PATH,
|
|
4
4
|
BOOTSTRAP_PATH,
|
|
5
|
-
|
|
5
|
+
STOP_PATH,
|
|
6
6
|
INSTALL_PATH,
|
|
7
|
-
|
|
7
|
+
LOCAL_API_PORT,
|
|
8
8
|
PEER_ID_PATH,
|
|
9
9
|
PROGRAMS_PATH,
|
|
10
10
|
PROGRAM_PATH,
|
|
11
11
|
RESTART_PATH,
|
|
12
12
|
TRUST_PATH,
|
|
13
|
+
REMOTE_API_PORT,
|
|
13
14
|
} from "./routes.js";
|
|
14
15
|
import { Address } from "@peerbit/program";
|
|
15
16
|
import { multiaddr } from "@multiformats/multiaddr";
|
|
16
17
|
import { signRequest } from "./signes-request.js";
|
|
17
18
|
import {
|
|
19
|
+
Ed25519Keypair,
|
|
18
20
|
Ed25519PublicKey,
|
|
19
21
|
Identity,
|
|
20
22
|
PublicSignKey,
|
|
21
23
|
getPublicKeyFromPeerId,
|
|
22
24
|
} from "@peerbit/crypto";
|
|
23
|
-
import { PeerId } from "@libp2p/interface
|
|
25
|
+
import { PeerId } from "@libp2p/interface/peer-id";
|
|
26
|
+
import { waitForResolved } from "@peerbit/time";
|
|
27
|
+
import { RemoteOrigin } from "./remotes.js";
|
|
24
28
|
|
|
25
|
-
export const
|
|
29
|
+
export const createClient = async (
|
|
26
30
|
keypair: Identity<Ed25519PublicKey>,
|
|
27
|
-
|
|
31
|
+
remote: { address: string; origin?: RemoteOrigin } = {
|
|
32
|
+
address: "http://localhost:" + LOCAL_API_PORT,
|
|
33
|
+
}
|
|
28
34
|
) => {
|
|
35
|
+
// Add missing protocol
|
|
36
|
+
let endpoint = remote.address;
|
|
37
|
+
if (!endpoint.startsWith("http://") && !endpoint.startsWith("https://")) {
|
|
38
|
+
if (endpoint.endsWith("localhost:") || endpoint.endsWith("localhost")) {
|
|
39
|
+
endpoint = "http://" + endpoint;
|
|
40
|
+
} else {
|
|
41
|
+
endpoint = "https://" + endpoint;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Add missing port
|
|
29
46
|
const isLocalHost = endpoint.startsWith("http://localhost");
|
|
47
|
+
if (new URL(endpoint).port === "" && !endpoint.endsWith(":80")) {
|
|
48
|
+
if (isLocalHost) {
|
|
49
|
+
endpoint = endpoint + ":" + LOCAL_API_PORT;
|
|
50
|
+
} else {
|
|
51
|
+
endpoint = endpoint + ":" + REMOTE_API_PORT;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
30
55
|
const { default: axios } = await import("axios");
|
|
31
56
|
const axiosInstance = axios.create();
|
|
32
57
|
axiosInstance.interceptors.request.use(async (config) => {
|
|
@@ -92,14 +117,17 @@ export const client = async (
|
|
|
92
117
|
},
|
|
93
118
|
},
|
|
94
119
|
},
|
|
95
|
-
|
|
96
|
-
|
|
120
|
+
|
|
121
|
+
access: {
|
|
122
|
+
allow: async (key: PublicSignKey | PeerId | string) => {
|
|
97
123
|
const result = await axiosInstance.put(
|
|
98
124
|
endpoint +
|
|
99
125
|
TRUST_PATH +
|
|
100
126
|
"/" +
|
|
101
127
|
encodeURIComponent(
|
|
102
|
-
key
|
|
128
|
+
typeof key === "string"
|
|
129
|
+
? key
|
|
130
|
+
: key instanceof PublicSignKey
|
|
103
131
|
? key.hashcode()
|
|
104
132
|
: getPublicKeyFromPeerId(key).hashcode()
|
|
105
133
|
),
|
|
@@ -111,7 +139,7 @@ export const client = async (
|
|
|
111
139
|
}
|
|
112
140
|
return result.status === 200 ? true : false;
|
|
113
141
|
},
|
|
114
|
-
|
|
142
|
+
deny: async (key: PublicSignKey | PeerId) => {
|
|
115
143
|
const result = await axiosInstance.delete(
|
|
116
144
|
endpoint +
|
|
117
145
|
TRUST_PATH +
|
|
@@ -221,6 +249,7 @@ export const client = async (
|
|
|
221
249
|
);
|
|
222
250
|
},
|
|
223
251
|
},
|
|
252
|
+
|
|
224
253
|
restart: async (): Promise<void> => {
|
|
225
254
|
throwIfNot200(
|
|
226
255
|
await axiosInstance.post(endpoint + RESTART_PATH, undefined, {
|
|
@@ -228,12 +257,48 @@ export const client = async (
|
|
|
228
257
|
})
|
|
229
258
|
);
|
|
230
259
|
},
|
|
231
|
-
|
|
260
|
+
stop: async (): Promise<void> => {
|
|
232
261
|
throwIfNot200(
|
|
233
|
-
await axiosInstance.post(endpoint +
|
|
262
|
+
await axiosInstance.post(endpoint + STOP_PATH, undefined, {
|
|
234
263
|
validateStatus,
|
|
235
264
|
})
|
|
236
265
|
);
|
|
237
266
|
},
|
|
267
|
+
terminate: async () => {
|
|
268
|
+
const { terminateNode } = await import("./aws.js");
|
|
269
|
+
if (remote.origin?.type === "aws") {
|
|
270
|
+
await terminateNode({
|
|
271
|
+
instanceId: remote.origin.instanceId,
|
|
272
|
+
region: remote.origin.region,
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
},
|
|
238
276
|
};
|
|
239
277
|
};
|
|
278
|
+
|
|
279
|
+
export const waitForDomain = async (
|
|
280
|
+
ip: string,
|
|
281
|
+
timeout: number = 5 * 60 * 1000
|
|
282
|
+
): Promise<string> => {
|
|
283
|
+
const c = await createClient(await Ed25519Keypair.create(), {
|
|
284
|
+
address: "http://" + ip + ":" + LOCAL_API_PORT,
|
|
285
|
+
});
|
|
286
|
+
const result = await waitForResolved(
|
|
287
|
+
async () => {
|
|
288
|
+
const addresses = await c.peer.addresses.get();
|
|
289
|
+
const domain = multiaddr(addresses[0]).nodeAddress().address;
|
|
290
|
+
if (!domain) {
|
|
291
|
+
throw new Error("Not ready");
|
|
292
|
+
}
|
|
293
|
+
return domain;
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
delayInterval: 5000,
|
|
297
|
+
timeout,
|
|
298
|
+
}
|
|
299
|
+
);
|
|
300
|
+
if (!result) {
|
|
301
|
+
throw new Error("Failed to resolve domain");
|
|
302
|
+
}
|
|
303
|
+
return result;
|
|
304
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// Unsupported
|
package/src/domain.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { waitFor, waitForAsync } from "@peerbit/time";
|
|
2
|
-
import { installDocker, startContainer } from "./docker.js";
|
|
3
2
|
|
|
4
3
|
const isNode = typeof window === undefined || typeof window === "undefined";
|
|
5
4
|
|
|
@@ -146,6 +145,7 @@ export const startCertbot = async (
|
|
|
146
145
|
if (!validateEmail(email)) {
|
|
147
146
|
throw new Error("Email for SSL renenewal is invalid");
|
|
148
147
|
}
|
|
148
|
+
const { installDocker, startContainer } = await import("./docker.js");
|
|
149
149
|
|
|
150
150
|
const nginxConfigPath = await getNginxFolderPath();
|
|
151
151
|
await createConfig(nginxConfigPath, domain);
|
package/src/peerbit.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { DirectBlock } from "@peerbit/blocks";
|
|
|
2
2
|
import { DirectSub } from "@peerbit/pubsub";
|
|
3
3
|
import { Peerbit } from "peerbit";
|
|
4
4
|
import path from "path";
|
|
5
|
-
import { PeerId } from "@libp2p/interface
|
|
5
|
+
import { PeerId } from "@libp2p/interface/peer-id";
|
|
6
6
|
|
|
7
7
|
export const LIBP2P_LISTEN_PORT = 8001;
|
|
8
8
|
export const create = (properties: {
|
package/src/remotes.ts
CHANGED
|
@@ -1,11 +1,23 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
2
|
|
|
3
|
-
interface
|
|
3
|
+
interface AWSOrigin {
|
|
4
|
+
type: "aws";
|
|
5
|
+
region: string;
|
|
6
|
+
instanceId: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export type RemoteOrigin = AWSOrigin;
|
|
10
|
+
|
|
11
|
+
export const DEFAULT_REMOTE_GROUP = "default";
|
|
12
|
+
|
|
13
|
+
export interface RemoteObject {
|
|
4
14
|
address: string;
|
|
5
15
|
name: string;
|
|
16
|
+
group: string;
|
|
17
|
+
origin?: RemoteOrigin;
|
|
6
18
|
}
|
|
7
19
|
|
|
8
|
-
interface RemotesObject {
|
|
20
|
+
export interface RemotesObject {
|
|
9
21
|
remotes: RemoteObject[];
|
|
10
22
|
}
|
|
11
23
|
|
|
@@ -31,19 +43,21 @@ export class Remotes {
|
|
|
31
43
|
getByName(name: string) {
|
|
32
44
|
return this.data.remotes.find((x) => x.name === name);
|
|
33
45
|
}
|
|
46
|
+
|
|
47
|
+
getByGroup(group: string) {
|
|
48
|
+
return this.data.remotes.filter((x) => x.group === group);
|
|
49
|
+
}
|
|
50
|
+
|
|
34
51
|
getByAddress(address: string) {
|
|
35
52
|
return this.data.remotes.find((x) => x.address === address);
|
|
36
53
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
name,
|
|
41
|
-
};
|
|
42
|
-
const existing = this.data.remotes.findIndex((x) => x.name === name);
|
|
54
|
+
|
|
55
|
+
add(remote: RemoteObject) {
|
|
56
|
+
const existing = this.data.remotes.findIndex((x) => x.name === remote.name);
|
|
43
57
|
if (existing >= 0) {
|
|
44
|
-
this.data.remotes[existing] =
|
|
58
|
+
this.data.remotes[existing] = remote;
|
|
45
59
|
} else {
|
|
46
|
-
this.data.remotes.push(
|
|
60
|
+
this.data.remotes.push(remote);
|
|
47
61
|
}
|
|
48
62
|
this.save();
|
|
49
63
|
}
|
package/src/routes.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
export const getPort = (protocol: string) => {
|
|
2
2
|
if (protocol === "https:") {
|
|
3
|
-
return
|
|
3
|
+
return REMOTE_API_PORT;
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
if (protocol === "http:") {
|
|
7
|
-
return
|
|
7
|
+
return LOCAL_API_PORT;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
throw new Error("Unsupported protocol: " + protocol);
|
|
11
11
|
};
|
|
12
|
-
export const
|
|
13
|
-
export const
|
|
12
|
+
export const REMOTE_API_PORT = 9002;
|
|
13
|
+
export const LOCAL_API_PORT = 8082;
|
|
14
14
|
export const TRUST_PATH = "/trust";
|
|
15
15
|
export const PEER_ID_PATH = "/peer/id";
|
|
16
16
|
export const ADDRESS_PATH = "/peer/address";
|
|
@@ -20,3 +20,4 @@ export const INSTALL_PATH = "/install";
|
|
|
20
20
|
export const BOOTSTRAP_PATH = "/network/bootstrap";
|
|
21
21
|
export const RESTART_PATH = "/restart";
|
|
22
22
|
export const TERMINATE_PATH = "/terminate";
|
|
23
|
+
export const STOP_PATH = "/path";
|
package/src/server.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import http from "http";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
fromBase64,
|
|
4
|
+
getKeypairFromPeerId,
|
|
5
|
+
getPublicKeyFromPeerId,
|
|
6
|
+
} from "@peerbit/crypto";
|
|
3
7
|
import { deserialize } from "@dao-xyz/borsh";
|
|
4
8
|
import {
|
|
5
9
|
Program,
|
|
@@ -28,14 +32,14 @@ import {
|
|
|
28
32
|
import {
|
|
29
33
|
ADDRESS_PATH,
|
|
30
34
|
BOOTSTRAP_PATH,
|
|
31
|
-
TERMINATE_PATH,
|
|
32
35
|
INSTALL_PATH,
|
|
33
|
-
|
|
36
|
+
LOCAL_API_PORT,
|
|
34
37
|
PEER_ID_PATH,
|
|
35
38
|
PROGRAMS_PATH,
|
|
36
39
|
PROGRAM_PATH,
|
|
37
40
|
RESTART_PATH,
|
|
38
41
|
TRUST_PATH,
|
|
42
|
+
STOP_PATH,
|
|
39
43
|
} from "./routes.js";
|
|
40
44
|
import { Session } from "./session.js";
|
|
41
45
|
import fs from "fs";
|
|
@@ -51,6 +55,7 @@ import { MemoryLevel } from "memory-level";
|
|
|
51
55
|
import { Trust } from "./trust.js";
|
|
52
56
|
import { getBody, verifyRequest } from "./signes-request.js";
|
|
53
57
|
import { cli } from "./cli.js";
|
|
58
|
+
import { peerIdFromString } from "@libp2p/peer-id";
|
|
54
59
|
|
|
55
60
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
56
61
|
|
|
@@ -68,6 +73,7 @@ export const startServerWithNode = async (properties: {
|
|
|
68
73
|
domain?: string;
|
|
69
74
|
bootstrap?: boolean;
|
|
70
75
|
newSession?: boolean;
|
|
76
|
+
grantAccess?: string[];
|
|
71
77
|
ports?: {
|
|
72
78
|
node: number;
|
|
73
79
|
api: number;
|
|
@@ -77,12 +83,16 @@ export const startServerWithNode = async (properties: {
|
|
|
77
83
|
if (!fs.existsSync(properties.directory)) {
|
|
78
84
|
fs.mkdirSync(properties.directory, { recursive: true });
|
|
79
85
|
}
|
|
86
|
+
|
|
87
|
+
const trustPeerIds =
|
|
88
|
+
properties.grantAccess && properties.grantAccess.length > 0
|
|
89
|
+
? properties.grantAccess.map((x) => peerIdFromString(x))
|
|
90
|
+
: [];
|
|
91
|
+
|
|
80
92
|
const keypair = await getKeypair(properties.directory);
|
|
93
|
+
|
|
81
94
|
const peer = await create({
|
|
82
|
-
directory:
|
|
83
|
-
properties.directory != null
|
|
84
|
-
? getNodePath(properties.directory)
|
|
85
|
-
: undefined,
|
|
95
|
+
directory: getNodePath(properties.directory),
|
|
86
96
|
domain: properties.domain,
|
|
87
97
|
listenPort: properties.ports?.node,
|
|
88
98
|
peerId: await keypair.toPeerId(),
|
|
@@ -120,12 +130,10 @@ export const startServerWithNode = async (properties: {
|
|
|
120
130
|
await session.clear();
|
|
121
131
|
}
|
|
122
132
|
|
|
133
|
+
const trust = new Trust(getTrustPath(properties.directory));
|
|
123
134
|
const server = await startApiServer(peer, {
|
|
124
135
|
port: properties.ports?.api,
|
|
125
|
-
|
|
126
|
-
properties.directory != null
|
|
127
|
-
? path.join(properties.directory, "server")
|
|
128
|
-
: undefined || getHomeConfigDir(),
|
|
136
|
+
trust,
|
|
129
137
|
session,
|
|
130
138
|
});
|
|
131
139
|
const printNodeInfo = async () => {
|
|
@@ -164,6 +172,12 @@ export const startServerWithNode = async (properties: {
|
|
|
164
172
|
});
|
|
165
173
|
};
|
|
166
174
|
await shutDownHook(peer, server);
|
|
175
|
+
|
|
176
|
+
if (trustPeerIds.length > 0) {
|
|
177
|
+
for (const id of trustPeerIds) {
|
|
178
|
+
trust.add(getPublicKeyFromPeerId(id).hashcode());
|
|
179
|
+
}
|
|
180
|
+
}
|
|
167
181
|
return { server, node: peer };
|
|
168
182
|
};
|
|
169
183
|
|
|
@@ -212,17 +226,12 @@ function findPeerbitProgramFolder(inputDirectory: string): string | null {
|
|
|
212
226
|
export const startApiServer = async (
|
|
213
227
|
client: ProgramClient,
|
|
214
228
|
properties: {
|
|
215
|
-
|
|
229
|
+
trust: Trust;
|
|
216
230
|
session?: Session;
|
|
217
231
|
port?: number;
|
|
218
232
|
}
|
|
219
233
|
): Promise<http.Server> => {
|
|
220
|
-
const port = properties?.port ??
|
|
221
|
-
if (!fs.existsSync(properties.configDirectory)) {
|
|
222
|
-
fs.mkdirSync(properties.configDirectory, { recursive: true });
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
const trust = new Trust(getTrustPath(properties.configDirectory));
|
|
234
|
+
const port = properties?.port ?? LOCAL_API_PORT;
|
|
226
235
|
|
|
227
236
|
const restart = async () => {
|
|
228
237
|
await client.stop();
|
|
@@ -259,7 +268,7 @@ export const startApiServer = async (
|
|
|
259
268
|
if (result.equals(client.identity.publicKey)) {
|
|
260
269
|
return body;
|
|
261
270
|
}
|
|
262
|
-
if (trust.isTrusted(result.hashcode())) {
|
|
271
|
+
if (properties.trust.isTrusted(result.hashcode())) {
|
|
263
272
|
return body;
|
|
264
273
|
}
|
|
265
274
|
throw new Error("Not trusted");
|
|
@@ -547,13 +556,13 @@ export const startApiServer = async (
|
|
|
547
556
|
} else if (req.url.startsWith(TRUST_PATH)) {
|
|
548
557
|
switch (req.method) {
|
|
549
558
|
case "PUT": {
|
|
550
|
-
trust.add(getPathValue(req, 1));
|
|
559
|
+
properties.trust.add(getPathValue(req, 1));
|
|
551
560
|
res.writeHead(200);
|
|
552
561
|
res.end();
|
|
553
562
|
break;
|
|
554
563
|
}
|
|
555
564
|
case "DELETE": {
|
|
556
|
-
const removed = trust.remove(getPathValue(req, 1));
|
|
565
|
+
const removed = properties.trust.remove(getPathValue(req, 1));
|
|
557
566
|
res.writeHead(200);
|
|
558
567
|
res.end(removed);
|
|
559
568
|
break;
|
|
@@ -574,7 +583,7 @@ export const startApiServer = async (
|
|
|
574
583
|
r404();
|
|
575
584
|
break;
|
|
576
585
|
}
|
|
577
|
-
} else if (req.url.startsWith(
|
|
586
|
+
} else if (req.url.startsWith(STOP_PATH)) {
|
|
578
587
|
switch (req.method) {
|
|
579
588
|
case "POST":
|
|
580
589
|
res.writeHead(200);
|
|
@@ -586,7 +595,18 @@ export const startApiServer = async (
|
|
|
586
595
|
r404();
|
|
587
596
|
break;
|
|
588
597
|
}
|
|
589
|
-
} else if (req.url.startsWith(
|
|
598
|
+
} /* else if (req.url.startsWith(TERMINATE_PATH)) {
|
|
599
|
+
switch (req.method) {
|
|
600
|
+
case "POST":
|
|
601
|
+
execSync("shutdown -h now")
|
|
602
|
+
process.exit(0);
|
|
603
|
+
break;
|
|
604
|
+
|
|
605
|
+
default:
|
|
606
|
+
r404();
|
|
607
|
+
break;
|
|
608
|
+
}
|
|
609
|
+
} */ else if (req.url.startsWith(PEER_ID_PATH)) {
|
|
590
610
|
res.writeHead(200);
|
|
591
611
|
res.end(client.peerId.toString());
|
|
592
612
|
} else if (req.url.startsWith(ADDRESS_PATH)) {
|