@peerbit/server 2.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 +614 -299
- package/lib/esm/cli.js.map +1 -1
- package/lib/esm/client.d.ts +13 -1
- package/lib/esm/client.js +101 -31
- package/lib/esm/client.js.map +1 -1
- package/lib/esm/config.d.ts +3 -3
- package/lib/esm/config.js +18 -16
- package/lib/esm/config.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 +2 -0
- package/lib/esm/peerbit.js +1 -0
- package/lib/esm/peerbit.js.map +1 -1
- package/lib/esm/remotes.d.ts +15 -3
- package/lib/esm/remotes.js +8 -9
- package/lib/esm/remotes.js.map +1 -1
- package/lib/esm/routes.d.ts +4 -2
- package/lib/esm/routes.js +6 -4
- package/lib/esm/routes.js.map +1 -1
- package/lib/esm/server.d.ts +5 -7
- package/lib/esm/server.js +183 -185
- package/lib/esm/server.js.map +1 -1
- package/lib/esm/signes-request.d.ts +5 -0
- package/lib/esm/signes-request.js +54 -0
- package/lib/esm/signes-request.js.map +1 -0
- package/lib/esm/trust.browser.d.ts +0 -0
- package/lib/esm/trust.browser.js +3 -0
- package/lib/esm/trust.browser.js.map +1 -0
- package/lib/esm/trust.d.ts +9 -0
- package/lib/esm/trust.js +36 -0
- package/lib/esm/trust.js.map +1 -0
- 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 +726 -348
- package/src/client.ts +145 -38
- package/src/config.ts +21 -23
- package/src/docker.browser.ts +1 -0
- package/src/domain.ts +1 -1
- package/src/peerbit.ts +3 -0
- package/src/remotes.ts +24 -12
- package/src/routes.ts +6 -5
- package/src/server.ts +238 -254
- package/src/signes-request.ts +84 -0
- package/src/trust.browser.ts +1 -0
- package/src/trust.ts +39 -0
- package/lib/ui/assets/index-73eaa3bc.js +0 -53
package/lib/esm/remotes.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
|
+
export const DEFAULT_REMOTE_GROUP = "default";
|
|
2
3
|
export class Remotes {
|
|
3
4
|
path;
|
|
4
5
|
data;
|
|
@@ -19,21 +20,19 @@ export class Remotes {
|
|
|
19
20
|
getByName(name) {
|
|
20
21
|
return this.data.remotes.find((x) => x.name === name);
|
|
21
22
|
}
|
|
23
|
+
getByGroup(group) {
|
|
24
|
+
return this.data.remotes.filter((x) => x.group === group);
|
|
25
|
+
}
|
|
22
26
|
getByAddress(address) {
|
|
23
27
|
return this.data.remotes.find((x) => x.address === address);
|
|
24
28
|
}
|
|
25
|
-
add(
|
|
26
|
-
const
|
|
27
|
-
address,
|
|
28
|
-
name,
|
|
29
|
-
password,
|
|
30
|
-
};
|
|
31
|
-
const existing = this.data.remotes.findIndex((x) => x.name === name);
|
|
29
|
+
add(remote) {
|
|
30
|
+
const existing = this.data.remotes.findIndex((x) => x.name === remote.name);
|
|
32
31
|
if (existing >= 0) {
|
|
33
|
-
this.data.remotes[existing] =
|
|
32
|
+
this.data.remotes[existing] = remote;
|
|
34
33
|
}
|
|
35
34
|
else {
|
|
36
|
-
this.data.remotes.push(
|
|
35
|
+
this.data.remotes.push(remote);
|
|
37
36
|
}
|
|
38
37
|
this.save();
|
|
39
38
|
}
|
package/lib/esm/remotes.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remotes.js","sourceRoot":"","sources":["../../src/remotes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"remotes.js","sourceRoot":"","sources":["../../src/remotes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AAUpB,MAAM,CAAC,MAAM,oBAAoB,GAAG,SAAS,CAAC;AAa9C,MAAM,OAAO,OAAO;IAGE;IAFb,IAAI,CAAgB;IAE5B,YAAqB,IAAY;QAAZ,SAAI,GAAJ,IAAI,CAAQ;QAChC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;YACxB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CACrB,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CACtB,CAAC;SACnB;aAAM;YACN,IAAI,CAAC,IAAI,GAAG;gBACX,OAAO,EAAE,EAAE;aACX,CAAC;SACF;IACF,CAAC;IAED,IAAI;QACH,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,SAAS,CAAC,IAAY;QACrB,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IACvD,CAAC;IAED,UAAU,CAAC,KAAa;QACvB,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC;IAC3D,CAAC;IAED,YAAY,CAAC,OAAe;QAC3B,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC;IAC7D,CAAC;IAED,GAAG,CAAC,MAAoB;QACvB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC;QAC5E,IAAI,QAAQ,IAAI,CAAC,EAAE;YAClB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC;SACrC;aAAM;YACN,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;SAC/B;QACD,IAAI,CAAC,IAAI,EAAE,CAAC;IACb,CAAC;IAED,MAAM,CAAC,IAAY;QAClB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;QACrE,IAAI,QAAQ,IAAI,CAAC,EAAE;YAClB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;YACtC,OAAO,IAAI,CAAC;SACZ;QACD,OAAO,KAAK,CAAC;IACd,CAAC;IAED,KAAK,CAAC,GAAG;QACR,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;IAC1B,CAAC;CACD"}
|
package/lib/esm/routes.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export declare const getPort: (protocol: string) => 9002 | 8082;
|
|
2
|
-
export declare const
|
|
3
|
-
export declare const
|
|
2
|
+
export declare const REMOTE_API_PORT = 9002;
|
|
3
|
+
export declare const LOCAL_API_PORT = 8082;
|
|
4
|
+
export declare const TRUST_PATH = "/trust";
|
|
4
5
|
export declare const PEER_ID_PATH = "/peer/id";
|
|
5
6
|
export declare const ADDRESS_PATH = "/peer/address";
|
|
6
7
|
export declare const PROGRAM_PATH = "/program";
|
|
@@ -9,3 +10,4 @@ export declare const INSTALL_PATH = "/install";
|
|
|
9
10
|
export declare const BOOTSTRAP_PATH = "/network/bootstrap";
|
|
10
11
|
export declare const RESTART_PATH = "/restart";
|
|
11
12
|
export declare const TERMINATE_PATH = "/terminate";
|
|
13
|
+
export declare const STOP_PATH = "/path";
|
package/lib/esm/routes.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
export const getPort = (protocol) => {
|
|
2
2
|
if (protocol === "https:") {
|
|
3
|
-
return
|
|
3
|
+
return REMOTE_API_PORT;
|
|
4
4
|
}
|
|
5
5
|
if (protocol === "http:") {
|
|
6
|
-
return
|
|
6
|
+
return LOCAL_API_PORT;
|
|
7
7
|
}
|
|
8
8
|
throw new Error("Unsupported protocol: " + protocol);
|
|
9
9
|
};
|
|
10
|
-
export const
|
|
11
|
-
export const
|
|
10
|
+
export const REMOTE_API_PORT = 9002;
|
|
11
|
+
export const LOCAL_API_PORT = 8082;
|
|
12
|
+
export const TRUST_PATH = "/trust";
|
|
12
13
|
export const PEER_ID_PATH = "/peer/id";
|
|
13
14
|
export const ADDRESS_PATH = "/peer/address";
|
|
14
15
|
export const PROGRAM_PATH = "/program";
|
|
@@ -17,4 +18,5 @@ export const INSTALL_PATH = "/install";
|
|
|
17
18
|
export const BOOTSTRAP_PATH = "/network/bootstrap";
|
|
18
19
|
export const RESTART_PATH = "/restart";
|
|
19
20
|
export const TERMINATE_PATH = "/terminate";
|
|
21
|
+
export const STOP_PATH = "/path";
|
|
20
22
|
//# sourceMappingURL=routes.js.map
|
package/lib/esm/routes.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/routes.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,QAAgB,EAAE,EAAE;IAC3C,IAAI,QAAQ,KAAK,QAAQ,EAAE;QAC1B,OAAO,
|
|
1
|
+
{"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/routes.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,QAAgB,EAAE,EAAE;IAC3C,IAAI,QAAQ,KAAK,QAAQ,EAAE;QAC1B,OAAO,eAAe,CAAC;KACvB;IAED,IAAI,QAAQ,KAAK,OAAO,EAAE;QACzB,OAAO,cAAc,CAAC;KACtB;IAED,MAAM,IAAI,KAAK,CAAC,wBAAwB,GAAG,QAAQ,CAAC,CAAC;AACtD,CAAC,CAAC;AACF,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC;AACpC,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,CAAC;AACnC,MAAM,CAAC,MAAM,UAAU,GAAG,QAAQ,CAAC;AACnC,MAAM,CAAC,MAAM,YAAY,GAAG,UAAU,CAAC;AACvC,MAAM,CAAC,MAAM,YAAY,GAAG,eAAe,CAAC;AAC5C,MAAM,CAAC,MAAM,YAAY,GAAG,UAAU,CAAC;AACvC,MAAM,CAAC,MAAM,aAAa,GAAG,WAAW,CAAC;AACzC,MAAM,CAAC,MAAM,YAAY,GAAG,UAAU,CAAC;AACvC,MAAM,CAAC,MAAM,cAAc,GAAG,oBAAoB,CAAC;AACnD,MAAM,CAAC,MAAM,YAAY,GAAG,UAAU,CAAC;AACvC,MAAM,CAAC,MAAM,cAAc,GAAG,YAAY,CAAC;AAC3C,MAAM,CAAC,MAAM,SAAS,GAAG,OAAO,CAAC"}
|
package/lib/esm/server.d.ts
CHANGED
|
@@ -3,15 +3,14 @@ import http from "http";
|
|
|
3
3
|
import { ProgramClient } from "@peerbit/program";
|
|
4
4
|
import { Peerbit } from "peerbit";
|
|
5
5
|
import { Session } from "./session.js";
|
|
6
|
+
import { Trust } from "./trust.js";
|
|
6
7
|
export declare const stopAndWait: (server: http.Server) => Promise<boolean | undefined>;
|
|
7
|
-
export declare const createPassword: (configDirectory: string, password?: string) => Promise<string>;
|
|
8
|
-
export declare const loadOrCreatePassword: (configDirectory: string, password?: string) => Promise<string>;
|
|
9
8
|
export declare const startServerWithNode: (properties: {
|
|
10
|
-
directory
|
|
9
|
+
directory: string;
|
|
11
10
|
domain?: string;
|
|
12
11
|
bootstrap?: boolean;
|
|
13
12
|
newSession?: boolean;
|
|
14
|
-
|
|
13
|
+
grantAccess?: string[];
|
|
15
14
|
ports?: {
|
|
16
15
|
node: number;
|
|
17
16
|
api: number;
|
|
@@ -21,9 +20,8 @@ export declare const startServerWithNode: (properties: {
|
|
|
21
20
|
server: http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>;
|
|
22
21
|
node: Peerbit;
|
|
23
22
|
}>;
|
|
24
|
-
export declare const startApiServer: (client: ProgramClient,
|
|
25
|
-
|
|
23
|
+
export declare const startApiServer: (client: ProgramClient, properties: {
|
|
24
|
+
trust: Trust;
|
|
26
25
|
session?: Session;
|
|
27
26
|
port?: number;
|
|
28
|
-
password?: string;
|
|
29
27
|
}) => Promise<http.Server>;
|
package/lib/esm/server.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import http from "http";
|
|
2
|
-
import { fromBase64 } from "@peerbit/crypto";
|
|
2
|
+
import { fromBase64, getPublicKeyFromPeerId, } from "@peerbit/crypto";
|
|
3
3
|
import { deserialize } from "@dao-xyz/borsh";
|
|
4
4
|
import { Program, getProgramFromVariant, getProgramFromVariants, } from "@peerbit/program";
|
|
5
5
|
import { waitFor } from "@peerbit/time";
|
|
6
6
|
import { v4 as uuid } from "uuid";
|
|
7
|
-
import {
|
|
7
|
+
import { getNodePath, getKeypair, getTrustPath, } from "./config.js";
|
|
8
8
|
import { setMaxListeners } from "events";
|
|
9
9
|
import { create } from "./peerbit.js";
|
|
10
10
|
import { Peerbit } from "peerbit";
|
|
11
11
|
import { getSchema } from "@dao-xyz/borsh";
|
|
12
|
-
import { ADDRESS_PATH, BOOTSTRAP_PATH,
|
|
12
|
+
import { ADDRESS_PATH, BOOTSTRAP_PATH, INSTALL_PATH, LOCAL_API_PORT, PEER_ID_PATH, PROGRAMS_PATH, PROGRAM_PATH, RESTART_PATH, TRUST_PATH, STOP_PATH, } from "./routes.js";
|
|
13
13
|
import { Session } from "./session.js";
|
|
14
14
|
import fs from "fs";
|
|
15
15
|
import { exit } from "process";
|
|
@@ -21,6 +21,9 @@ import { dirname } from "path";
|
|
|
21
21
|
import { fileURLToPath } from "url";
|
|
22
22
|
import { Level } from "level";
|
|
23
23
|
import { MemoryLevel } from "memory-level";
|
|
24
|
+
import { Trust } from "./trust.js";
|
|
25
|
+
import { getBody, verifyRequest } from "./signes-request.js";
|
|
26
|
+
import { peerIdFromString } from "@libp2p/peer-id";
|
|
24
27
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
25
28
|
export const stopAndWait = (server) => {
|
|
26
29
|
let closed = false;
|
|
@@ -30,44 +33,19 @@ export const stopAndWait = (server) => {
|
|
|
30
33
|
server.close();
|
|
31
34
|
return waitFor(() => closed);
|
|
32
35
|
};
|
|
33
|
-
export const createPassword = async (configDirectory, password) => {
|
|
34
|
-
const configDir = configDirectory ?? (await getHomeConfigDir());
|
|
35
|
-
const credentialsPath = await getCredentialsPath(configDir);
|
|
36
|
-
if (!password && (await checkExistPath(credentialsPath))) {
|
|
37
|
-
throw new Error("Config path for credentials: " + credentialsPath + ", already exist");
|
|
38
|
-
}
|
|
39
|
-
console.log(`Creating config folder ${configDir}`);
|
|
40
|
-
fs.mkdirSync(configDir, { recursive: true });
|
|
41
|
-
await waitFor(() => fs.existsSync(configDir));
|
|
42
|
-
console.log(`Created config folder ${configDir}`);
|
|
43
|
-
password = password || uuid();
|
|
44
|
-
fs.writeFileSync(credentialsPath, JSON.stringify({ username: "admin", password }));
|
|
45
|
-
console.log(`Created credentials at ${credentialsPath}`);
|
|
46
|
-
return password;
|
|
47
|
-
};
|
|
48
|
-
export const loadOrCreatePassword = async (configDirectory, password) => {
|
|
49
|
-
if (!password) {
|
|
50
|
-
try {
|
|
51
|
-
return await loadPassword(configDirectory);
|
|
52
|
-
}
|
|
53
|
-
catch (error) {
|
|
54
|
-
if (error instanceof NotFoundError) {
|
|
55
|
-
return createPassword(configDirectory, password);
|
|
56
|
-
}
|
|
57
|
-
throw error;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
else {
|
|
61
|
-
return createPassword(configDirectory, password);
|
|
62
|
-
}
|
|
63
|
-
};
|
|
64
36
|
export const startServerWithNode = async (properties) => {
|
|
37
|
+
if (!fs.existsSync(properties.directory)) {
|
|
38
|
+
fs.mkdirSync(properties.directory, { recursive: true });
|
|
39
|
+
}
|
|
40
|
+
const trustPeerIds = properties.grantAccess && properties.grantAccess.length > 0
|
|
41
|
+
? properties.grantAccess.map((x) => peerIdFromString(x))
|
|
42
|
+
: [];
|
|
43
|
+
const keypair = await getKeypair(properties.directory);
|
|
65
44
|
const peer = await create({
|
|
66
|
-
directory: properties.directory
|
|
67
|
-
? getNodePath(properties.directory)
|
|
68
|
-
: undefined,
|
|
45
|
+
directory: getNodePath(properties.directory),
|
|
69
46
|
domain: properties.domain,
|
|
70
47
|
listenPort: properties.ports?.node,
|
|
48
|
+
peerId: await keypair.toPeerId(),
|
|
71
49
|
});
|
|
72
50
|
if (properties.bootstrap) {
|
|
73
51
|
await peer.bootstrap();
|
|
@@ -98,13 +76,11 @@ export const startServerWithNode = async (properties) => {
|
|
|
98
76
|
else {
|
|
99
77
|
await session.clear();
|
|
100
78
|
}
|
|
79
|
+
const trust = new Trust(getTrustPath(properties.directory));
|
|
101
80
|
const server = await startApiServer(peer, {
|
|
102
81
|
port: properties.ports?.api,
|
|
103
|
-
|
|
104
|
-
? path.join(properties.directory, "server")
|
|
105
|
-
: undefined || getHomeConfigDir(),
|
|
82
|
+
trust,
|
|
106
83
|
session,
|
|
107
|
-
password: properties.password,
|
|
108
84
|
});
|
|
109
85
|
const printNodeInfo = async () => {
|
|
110
86
|
console.log("Starting node with address(es): ");
|
|
@@ -138,9 +114,14 @@ export const startServerWithNode = async (properties) => {
|
|
|
138
114
|
});
|
|
139
115
|
};
|
|
140
116
|
await shutDownHook(peer, server);
|
|
117
|
+
if (trustPeerIds.length > 0) {
|
|
118
|
+
for (const id of trustPeerIds) {
|
|
119
|
+
trust.add(getPublicKeyFromPeerId(id).hashcode());
|
|
120
|
+
}
|
|
121
|
+
}
|
|
141
122
|
return { server, node: peer };
|
|
142
123
|
};
|
|
143
|
-
const
|
|
124
|
+
const getPathValue = (req, pathIndex) => {
|
|
144
125
|
if (!req.url) {
|
|
145
126
|
throw new Error("Missing url");
|
|
146
127
|
}
|
|
@@ -152,7 +133,7 @@ const getProgramFromPath = (client, req, pathIndex) => {
|
|
|
152
133
|
throw new Error("Invalid path");
|
|
153
134
|
}
|
|
154
135
|
const address = decodeURIComponent(path[pathIndex]);
|
|
155
|
-
return
|
|
136
|
+
return address;
|
|
156
137
|
};
|
|
157
138
|
function findPeerbitProgramFolder(inputDirectory) {
|
|
158
139
|
let currentDir = path.resolve(inputDirectory);
|
|
@@ -171,9 +152,8 @@ function findPeerbitProgramFolder(inputDirectory) {
|
|
|
171
152
|
}
|
|
172
153
|
return null;
|
|
173
154
|
}
|
|
174
|
-
export const startApiServer = async (client,
|
|
175
|
-
const port =
|
|
176
|
-
const password = await loadOrCreatePassword(options.configDirectory, options?.password);
|
|
155
|
+
export const startApiServer = async (client, properties) => {
|
|
156
|
+
const port = properties?.port ?? LOCAL_API_PORT;
|
|
177
157
|
const restart = async () => {
|
|
178
158
|
await client.stop();
|
|
179
159
|
await stopAndWait(server);
|
|
@@ -187,37 +167,21 @@ export const startApiServer = async (client, options) => {
|
|
|
187
167
|
stdio: "inherit",
|
|
188
168
|
gid: process.getgid(),
|
|
189
169
|
});
|
|
190
|
-
/* process.on("exit", async () => {
|
|
191
|
-
child.kill("SIGINT")
|
|
192
|
-
});
|
|
193
|
-
process.on("SIGINT", async () => {
|
|
194
|
-
child.kill("SIGINT")
|
|
195
|
-
}); */
|
|
196
170
|
process.exit(0);
|
|
197
171
|
};
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
const
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
return false;
|
|
172
|
+
if (!client.peerId.equals(await client.identity.publicKey.toPeerId())) {
|
|
173
|
+
throw new Error("Expecting node identity to equal peerId");
|
|
174
|
+
}
|
|
175
|
+
const getVerifiedBody = async (req) => {
|
|
176
|
+
const body = await getBody(req);
|
|
177
|
+
const result = await verifyRequest(req.headers, req.method, req.url, body);
|
|
178
|
+
if (result.equals(client.identity.publicKey)) {
|
|
179
|
+
return body;
|
|
207
180
|
}
|
|
208
|
-
if (
|
|
209
|
-
return
|
|
181
|
+
if (properties.trust.isTrusted(result.hashcode())) {
|
|
182
|
+
return body;
|
|
210
183
|
}
|
|
211
|
-
|
|
212
|
-
};
|
|
213
|
-
const getBody = (req, callback) => {
|
|
214
|
-
let body = "";
|
|
215
|
-
req.on("data", function (d) {
|
|
216
|
-
body += d;
|
|
217
|
-
});
|
|
218
|
-
req.on("end", function () {
|
|
219
|
-
callback(body);
|
|
220
|
-
});
|
|
184
|
+
throw new Error("Not trusted");
|
|
221
185
|
};
|
|
222
186
|
const e404 = "404";
|
|
223
187
|
const endpoints = (client) => {
|
|
@@ -232,14 +196,20 @@ export const startApiServer = async (client, options) => {
|
|
|
232
196
|
};
|
|
233
197
|
try {
|
|
234
198
|
if (req.url) {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
199
|
+
let body;
|
|
200
|
+
try {
|
|
201
|
+
body =
|
|
202
|
+
req.url.startsWith(PEER_ID_PATH) ||
|
|
203
|
+
req.url.startsWith(ADDRESS_PATH)
|
|
204
|
+
? await getBody(req)
|
|
205
|
+
: await getVerifiedBody(req);
|
|
206
|
+
}
|
|
207
|
+
catch (error) {
|
|
238
208
|
res.writeHead(401);
|
|
239
|
-
res.end("Not authorized");
|
|
209
|
+
res.end("Not authorized: " + error.toString());
|
|
240
210
|
return;
|
|
241
211
|
}
|
|
242
|
-
|
|
212
|
+
if (req.url.startsWith(PROGRAMS_PATH)) {
|
|
243
213
|
if (client instanceof Peerbit === false) {
|
|
244
214
|
res.writeHead(400);
|
|
245
215
|
res.end("Server node is not running a native client");
|
|
@@ -273,7 +243,7 @@ export const startApiServer = async (client, options) => {
|
|
|
273
243
|
switch (req.method) {
|
|
274
244
|
case "HEAD":
|
|
275
245
|
try {
|
|
276
|
-
const program =
|
|
246
|
+
const program = client.handler?.items.get(getPathValue(req, 1));
|
|
277
247
|
if (program) {
|
|
278
248
|
res.writeHead(200);
|
|
279
249
|
res.end();
|
|
@@ -292,7 +262,7 @@ export const startApiServer = async (client, options) => {
|
|
|
292
262
|
try {
|
|
293
263
|
const url = new URL(req.url, "http://localhost:" + 1234);
|
|
294
264
|
const queryData = url.searchParams.get("delete");
|
|
295
|
-
const program =
|
|
265
|
+
const program = client.handler?.items.get(getPathValue(req, 1));
|
|
296
266
|
if (program) {
|
|
297
267
|
let closed = false;
|
|
298
268
|
if (queryData === "true") {
|
|
@@ -302,7 +272,7 @@ export const startApiServer = async (client, options) => {
|
|
|
302
272
|
closed = await program.close();
|
|
303
273
|
}
|
|
304
274
|
if (closed) {
|
|
305
|
-
await
|
|
275
|
+
await properties?.session?.programs.remove(program.address);
|
|
306
276
|
}
|
|
307
277
|
res.writeHead(200);
|
|
308
278
|
res.end();
|
|
@@ -318,42 +288,40 @@ export const startApiServer = async (client, options) => {
|
|
|
318
288
|
}
|
|
319
289
|
break;
|
|
320
290
|
case "PUT":
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
if (!P) {
|
|
328
|
-
res.writeHead(400);
|
|
329
|
-
res.end("Missing program with variant: " +
|
|
330
|
-
startArguments.variant);
|
|
331
|
-
return;
|
|
332
|
-
}
|
|
333
|
-
program = new P();
|
|
334
|
-
}
|
|
335
|
-
else {
|
|
336
|
-
program = deserialize(fromBase64(startArguments.base64), Program);
|
|
337
|
-
}
|
|
338
|
-
client
|
|
339
|
-
.open(program) // TODO all users to pass args
|
|
340
|
-
.then(async (program) => {
|
|
341
|
-
// TODO what if this is a reopen?
|
|
342
|
-
console.log("OPEN ADDRESS", program.address, client.directory, await client.services.blocks.has(program.address));
|
|
343
|
-
await options?.session?.programs.add(program.address, new Uint8Array());
|
|
344
|
-
res.writeHead(200);
|
|
345
|
-
res.end(program.address.toString());
|
|
346
|
-
})
|
|
347
|
-
.catch((error) => {
|
|
291
|
+
try {
|
|
292
|
+
const startArguments = JSON.parse(body);
|
|
293
|
+
let program;
|
|
294
|
+
if (startArguments.variant) {
|
|
295
|
+
const P = getProgramFromVariant(startArguments.variant);
|
|
296
|
+
if (!P) {
|
|
348
297
|
res.writeHead(400);
|
|
349
|
-
res.end("
|
|
350
|
-
|
|
298
|
+
res.end("Missing program with variant: " +
|
|
299
|
+
startArguments.variant);
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
program = new P();
|
|
351
303
|
}
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
res.end(error.toString());
|
|
304
|
+
else {
|
|
305
|
+
program = deserialize(fromBase64(startArguments.base64), Program);
|
|
355
306
|
}
|
|
356
|
-
|
|
307
|
+
client
|
|
308
|
+
.open(program) // TODO all users to pass args
|
|
309
|
+
.then(async (program) => {
|
|
310
|
+
// TODO what if this is a reopen?
|
|
311
|
+
console.log("OPEN ADDRESS", program.address, client.directory, await client.services.blocks.has(program.address));
|
|
312
|
+
await properties?.session?.programs.add(program.address, new Uint8Array());
|
|
313
|
+
res.writeHead(200);
|
|
314
|
+
res.end(program.address.toString());
|
|
315
|
+
})
|
|
316
|
+
.catch((error) => {
|
|
317
|
+
res.writeHead(400);
|
|
318
|
+
res.end("Failed to open program: " + error.toString());
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
catch (error) {
|
|
322
|
+
res.writeHead(400);
|
|
323
|
+
res.end(error.toString());
|
|
324
|
+
}
|
|
357
325
|
break;
|
|
358
326
|
default:
|
|
359
327
|
r404();
|
|
@@ -362,85 +330,85 @@ export const startApiServer = async (client, options) => {
|
|
|
362
330
|
}
|
|
363
331
|
else if (req.url.startsWith(INSTALL_PATH)) {
|
|
364
332
|
switch (req.method) {
|
|
365
|
-
case "PUT":
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
if (!installDir) {
|
|
396
|
-
res.writeHead(400);
|
|
397
|
-
res.end("Missing installation directory");
|
|
398
|
-
return;
|
|
399
|
-
}
|
|
400
|
-
try {
|
|
401
|
-
fs.accessSync(installDir, fs.constants.W_OK);
|
|
402
|
-
}
|
|
403
|
-
catch (error) {
|
|
404
|
-
permission = "sudo";
|
|
405
|
-
}
|
|
406
|
-
console.log("Installing package: " + installName);
|
|
407
|
-
execSync(`${permission} npm install ${installName} --prefix ${installDir} --no-save --no-package-lock`); // TODO omit=dev ? but this makes breaks the tests after running once?
|
|
408
|
-
}
|
|
409
|
-
catch (error) {
|
|
333
|
+
case "PUT": {
|
|
334
|
+
const installArgs = JSON.parse(body);
|
|
335
|
+
const packageName = installArgs.name; // @abc/123
|
|
336
|
+
let installName = installArgs.name; // abc123.tgz or @abc/123 (npm package name)
|
|
337
|
+
let clear;
|
|
338
|
+
if (installArgs.type === "tgz") {
|
|
339
|
+
const binary = fromBase64(installArgs.base64);
|
|
340
|
+
const tempFile = tmp.fileSync({
|
|
341
|
+
name: base58btc.encode(Buffer.from(installName)) +
|
|
342
|
+
uuid() +
|
|
343
|
+
".tgz",
|
|
344
|
+
});
|
|
345
|
+
fs.writeFileSync(tempFile.fd, binary);
|
|
346
|
+
clear = () => tempFile.removeCallback();
|
|
347
|
+
installName = tempFile.name;
|
|
348
|
+
}
|
|
349
|
+
else {
|
|
350
|
+
clear = undefined;
|
|
351
|
+
}
|
|
352
|
+
if (!installName || installName.length === 0) {
|
|
353
|
+
res.writeHead(400);
|
|
354
|
+
res.end("Invalid package: " + packageName);
|
|
355
|
+
}
|
|
356
|
+
else {
|
|
357
|
+
try {
|
|
358
|
+
// TODO do this without sudo. i.e. for servers provide arguments so that this app folder is writeable by default by the user
|
|
359
|
+
const installDir = process.env.PEERBIT_MODULES_PATH ||
|
|
360
|
+
findPeerbitProgramFolder(__dirname);
|
|
361
|
+
let permission = "";
|
|
362
|
+
if (!installDir) {
|
|
410
363
|
res.writeHead(400);
|
|
411
|
-
res.end("
|
|
412
|
-
packageName +
|
|
413
|
-
". " +
|
|
414
|
-
error.toString());
|
|
415
|
-
clear?.();
|
|
364
|
+
res.end("Missing installation directory");
|
|
416
365
|
return;
|
|
417
366
|
}
|
|
418
367
|
try {
|
|
419
|
-
|
|
420
|
-
await import(
|
|
421
|
-
/* webpackIgnore: true */ /* @vite-ignore */ packageName);
|
|
422
|
-
await options?.session?.imports.add(packageName, new Uint8Array());
|
|
423
|
-
const programsPost = getProgramFromVariants()?.map((x) => getSchema(x));
|
|
424
|
-
const newPrograms = [];
|
|
425
|
-
for (const p of programsPost) {
|
|
426
|
-
if (!programsPre.has(p.variant)) {
|
|
427
|
-
newPrograms.push(p);
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
res.writeHead(200);
|
|
431
|
-
res.end(JSON.stringify(newPrograms.map((x) => x.variant)));
|
|
368
|
+
fs.accessSync(installDir, fs.constants.W_OK);
|
|
432
369
|
}
|
|
433
|
-
catch (
|
|
434
|
-
|
|
435
|
-
res.end(e.message.toString?.());
|
|
436
|
-
clear?.();
|
|
370
|
+
catch (error) {
|
|
371
|
+
permission = "sudo";
|
|
437
372
|
}
|
|
373
|
+
console.log("Installing package: " + installName);
|
|
374
|
+
execSync(`${permission} npm install ${installName} --prefix ${installDir} --no-save --no-package-lock`); // TODO omit=dev ? but this makes breaks the tests after running once?
|
|
375
|
+
}
|
|
376
|
+
catch (error) {
|
|
377
|
+
res.writeHead(400);
|
|
378
|
+
res.end("Failed to install library: " +
|
|
379
|
+
packageName +
|
|
380
|
+
". " +
|
|
381
|
+
error.toString());
|
|
382
|
+
clear?.();
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
try {
|
|
386
|
+
const programsPre = new Set(getProgramFromVariants().map((x) => getSchema(x).variant));
|
|
387
|
+
await import(
|
|
388
|
+
/* webpackIgnore: true */ /* @vite-ignore */ packageName);
|
|
389
|
+
await properties?.session?.imports.add(packageName, new Uint8Array());
|
|
390
|
+
const programsPost = getProgramFromVariants()?.map((x) => getSchema(x));
|
|
391
|
+
const newPrograms = [];
|
|
392
|
+
for (const p of programsPost) {
|
|
393
|
+
if (!programsPre.has(p.variant)) {
|
|
394
|
+
newPrograms.push(p);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
res.writeHead(200);
|
|
398
|
+
res.end(JSON.stringify(newPrograms.map((x) => x.variant)));
|
|
399
|
+
}
|
|
400
|
+
catch (e) {
|
|
401
|
+
res.writeHead(400);
|
|
402
|
+
res.end(e.message.toString?.());
|
|
403
|
+
clear?.();
|
|
438
404
|
}
|
|
439
|
-
}
|
|
405
|
+
}
|
|
440
406
|
break;
|
|
441
|
-
|
|
407
|
+
}
|
|
408
|
+
default: {
|
|
442
409
|
r404();
|
|
443
410
|
break;
|
|
411
|
+
}
|
|
444
412
|
}
|
|
445
413
|
}
|
|
446
414
|
else if (req.url.startsWith(BOOTSTRAP_PATH)) {
|
|
@@ -460,6 +428,25 @@ export const startApiServer = async (client, options) => {
|
|
|
460
428
|
break;
|
|
461
429
|
}
|
|
462
430
|
}
|
|
431
|
+
else if (req.url.startsWith(TRUST_PATH)) {
|
|
432
|
+
switch (req.method) {
|
|
433
|
+
case "PUT": {
|
|
434
|
+
properties.trust.add(getPathValue(req, 1));
|
|
435
|
+
res.writeHead(200);
|
|
436
|
+
res.end();
|
|
437
|
+
break;
|
|
438
|
+
}
|
|
439
|
+
case "DELETE": {
|
|
440
|
+
const removed = properties.trust.remove(getPathValue(req, 1));
|
|
441
|
+
res.writeHead(200);
|
|
442
|
+
res.end(removed);
|
|
443
|
+
break;
|
|
444
|
+
}
|
|
445
|
+
default:
|
|
446
|
+
r404();
|
|
447
|
+
break;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
463
450
|
else if (req.url.startsWith(RESTART_PATH)) {
|
|
464
451
|
switch (req.method) {
|
|
465
452
|
case "POST":
|
|
@@ -472,7 +459,7 @@ export const startApiServer = async (client, options) => {
|
|
|
472
459
|
break;
|
|
473
460
|
}
|
|
474
461
|
}
|
|
475
|
-
else if (req.url.startsWith(
|
|
462
|
+
else if (req.url.startsWith(STOP_PATH)) {
|
|
476
463
|
switch (req.method) {
|
|
477
464
|
case "POST":
|
|
478
465
|
res.writeHead(200);
|
|
@@ -483,7 +470,18 @@ export const startApiServer = async (client, options) => {
|
|
|
483
470
|
r404();
|
|
484
471
|
break;
|
|
485
472
|
}
|
|
486
|
-
}
|
|
473
|
+
} /* else if (req.url.startsWith(TERMINATE_PATH)) {
|
|
474
|
+
switch (req.method) {
|
|
475
|
+
case "POST":
|
|
476
|
+
execSync("shutdown -h now")
|
|
477
|
+
process.exit(0);
|
|
478
|
+
break;
|
|
479
|
+
|
|
480
|
+
default:
|
|
481
|
+
r404();
|
|
482
|
+
break;
|
|
483
|
+
}
|
|
484
|
+
} */
|
|
487
485
|
else if (req.url.startsWith(PEER_ID_PATH)) {
|
|
488
486
|
res.writeHead(200);
|
|
489
487
|
res.end(client.peerId.toString());
|