@peerbit/server 1.1.2 → 3.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.
Files changed (54) hide show
  1. package/lib/esm/cli.js +518 -144
  2. package/lib/esm/cli.js.map +1 -1
  3. package/lib/esm/client.d.ts +11 -3
  4. package/lib/esm/client.js +61 -27
  5. package/lib/esm/client.js.map +1 -1
  6. package/lib/esm/config.d.ts +8 -5
  7. package/lib/esm/config.js +44 -19
  8. package/lib/esm/config.js.map +1 -1
  9. package/lib/esm/peerbit.d.ts +4 -0
  10. package/lib/esm/peerbit.js +15 -2
  11. package/lib/esm/peerbit.js.map +1 -1
  12. package/lib/esm/remotes.browser.d.ts +0 -0
  13. package/lib/esm/remotes.browser.js +3 -0
  14. package/lib/esm/remotes.browser.js.map +1 -0
  15. package/lib/esm/remotes.d.ts +16 -0
  16. package/lib/esm/remotes.js +51 -0
  17. package/lib/esm/remotes.js.map +1 -0
  18. package/lib/esm/routes.d.ts +3 -0
  19. package/lib/esm/routes.js +3 -0
  20. package/lib/esm/routes.js.map +1 -1
  21. package/lib/esm/server.d.ts +14 -4
  22. package/lib/esm/server.js +297 -144
  23. package/lib/esm/server.js.map +1 -1
  24. package/lib/esm/session.d.ts +19 -0
  25. package/lib/esm/session.js +49 -0
  26. package/lib/esm/session.js.map +1 -0
  27. package/lib/esm/signes-request.d.ts +5 -0
  28. package/lib/esm/signes-request.js +54 -0
  29. package/lib/esm/signes-request.js.map +1 -0
  30. package/lib/esm/trust.browser.d.ts +0 -0
  31. package/lib/esm/trust.browser.js +3 -0
  32. package/lib/esm/trust.browser.js.map +1 -0
  33. package/lib/esm/trust.d.ts +9 -0
  34. package/lib/esm/trust.js +36 -0
  35. package/lib/esm/trust.js.map +1 -0
  36. package/lib/esm/types.d.ts +10 -0
  37. package/lib/ui/assets/index-cac7195d.js +77 -0
  38. package/lib/ui/index.html +1 -1
  39. package/package.json +9 -5
  40. package/src/cli.ts +705 -271
  41. package/src/client.ts +105 -30
  42. package/src/config.ts +52 -25
  43. package/src/peerbit.ts +27 -3
  44. package/src/remotes.browser.ts +1 -0
  45. package/src/remotes.ts +63 -0
  46. package/src/routes.ts +3 -1
  47. package/src/server.ts +381 -190
  48. package/src/session.ts +69 -0
  49. package/src/signes-request.ts +84 -0
  50. package/src/trust.browser.ts +1 -0
  51. package/src/trust.ts +39 -0
  52. package/src/types.ts +13 -0
  53. package/lib/ui/assets/config.browser-4ed993c7.js +0 -1
  54. package/lib/ui/assets/index-a8188422.js +0 -53
package/src/session.ts ADDED
@@ -0,0 +1,69 @@
1
+ import { AbstractLevel } from "abstract-level";
2
+
3
+ export class Session {
4
+ programs: KV;
5
+ imports: KV;
6
+ constructor(
7
+ readonly level: AbstractLevel<
8
+ string | Buffer | Uint8Array,
9
+ string,
10
+ Uint8Array
11
+ >
12
+ ) {
13
+ this.imports = new KV(
14
+ this.level.sublevel<string, Uint8Array>("imports", {
15
+ keyEncoding: "utf8",
16
+ valueEncoding: "view",
17
+ })
18
+ );
19
+ this.programs = new KV(
20
+ this.level.sublevel<string, Uint8Array>("programs", {
21
+ keyEncoding: "utf8",
22
+ valueEncoding: "view",
23
+ })
24
+ );
25
+ }
26
+
27
+ async clear() {
28
+ await this.imports.clear();
29
+ await this.programs.clear();
30
+ }
31
+ }
32
+
33
+ export class KV {
34
+ constructor(
35
+ readonly level: AbstractLevel<
36
+ string | Buffer | Uint8Array,
37
+ string,
38
+ Uint8Array
39
+ >
40
+ ) {}
41
+
42
+ add(key: string, arg: Uint8Array) {
43
+ return this.level.put(key, arg);
44
+ }
45
+
46
+ remove(key: string) {
47
+ return this.level.del(key);
48
+ }
49
+
50
+ async all(): Promise<[string, Uint8Array][]> {
51
+ const res: [string, Uint8Array][] = [];
52
+ for await (const [key, value] of this.level.iterator()) {
53
+ res.push([key, value]);
54
+ }
55
+ return res;
56
+ }
57
+
58
+ async open() {
59
+ await this.level.open();
60
+ }
61
+
62
+ async close() {
63
+ await this.level.close();
64
+ }
65
+
66
+ async clear() {
67
+ await this.level.clear();
68
+ }
69
+ }
@@ -0,0 +1,84 @@
1
+ import {
2
+ Identity,
3
+ PublicSignKey,
4
+ SignatureWithKey,
5
+ fromBase64,
6
+ toBase64,
7
+ verify,
8
+ Ed25519PublicKey,
9
+ } from "@peerbit/crypto";
10
+ import { deserialize, serialize, BinaryWriter } from "@dao-xyz/borsh";
11
+ import http from "http";
12
+
13
+ const SIGNATURE_KEY = "X-Peerbit-Signature";
14
+ const SIGNATURE_TIME_KEY = "X-Peerbit-Signature-Time";
15
+
16
+ export const signRequest = async (
17
+ headers: Record<string, string>,
18
+ method: string,
19
+ path: string,
20
+ data: string | undefined,
21
+ keypair: Identity<Ed25519PublicKey>
22
+ ) => {
23
+ const sigTimestamp = Math.round(new Date().getTime() / 1000).toString();
24
+ const write = new BinaryWriter();
25
+ if (!method) {
26
+ throw new Error("Expecting method");
27
+ }
28
+ if (!path) {
29
+ throw new Error("Expecting path");
30
+ }
31
+
32
+ write.string(
33
+ method.toLowerCase() + path.toLowerCase() + sigTimestamp + (data || "")
34
+ );
35
+ const signature = await keypair.sign(write.finalize());
36
+ headers[SIGNATURE_TIME_KEY] = sigTimestamp;
37
+ headers[SIGNATURE_KEY] = toBase64(serialize(signature));
38
+ };
39
+
40
+ export const getBody = (req: http.IncomingMessage): Promise<string> => {
41
+ return new Promise((resolve, reject) => {
42
+ let body = "";
43
+ req.on("data", (d) => {
44
+ body += d;
45
+ });
46
+ req.on("end", () => {
47
+ resolve(body);
48
+ });
49
+ req.on("error", (e) => reject(e));
50
+ });
51
+ };
52
+
53
+ export const verifyRequest = async (
54
+ headers: Record<string, string | string[] | undefined>,
55
+ method: string,
56
+ path: string,
57
+ body = ""
58
+ ): Promise<PublicSignKey> => {
59
+ const timestamp =
60
+ headers[SIGNATURE_TIME_KEY] || headers[SIGNATURE_TIME_KEY.toLowerCase()];
61
+ if (typeof timestamp !== "string") {
62
+ throw new Error("Unexpected timestamp type: " + typeof timestamp);
63
+ }
64
+
65
+ const write = new BinaryWriter();
66
+ if (!method) {
67
+ throw new Error("Expecting method");
68
+ }
69
+ if (!path) {
70
+ throw new Error("Expecting path");
71
+ }
72
+
73
+ write.string(method.toLowerCase() + path.toLowerCase() + timestamp + body);
74
+ const signature =
75
+ headers[SIGNATURE_KEY] || headers[SIGNATURE_KEY.toLowerCase()];
76
+ if (typeof signature !== "string") {
77
+ throw new Error("Unexpected signature type: " + typeof signature);
78
+ }
79
+ const signatureWithKey = deserialize(fromBase64(signature), SignatureWithKey);
80
+ if (await verify(signatureWithKey, write.finalize())) {
81
+ return signatureWithKey.publicKey;
82
+ }
83
+ throw new Error("Invalid signature");
84
+ };
@@ -0,0 +1 @@
1
+ // Not supported
package/src/trust.ts ADDED
@@ -0,0 +1,39 @@
1
+ import fs from "fs";
2
+
3
+ export class Trust {
4
+ private trusted: string[];
5
+ constructor(readonly path: string) {
6
+ if (fs.existsSync(path)) {
7
+ this.trusted = JSON.parse(
8
+ fs.readFileSync(path).toString("utf-8")
9
+ ) as string[];
10
+ } else {
11
+ this.trusted = [];
12
+ }
13
+ }
14
+
15
+ save() {
16
+ fs.writeFileSync(this.path, JSON.stringify(this.trusted));
17
+ }
18
+
19
+ isTrusted(hashcode: string) {
20
+ return this.trusted.includes(hashcode);
21
+ }
22
+
23
+ add(key: string) {
24
+ if (this.isTrusted(key)) {
25
+ return;
26
+ }
27
+ this.trusted.push(key);
28
+ this.save();
29
+ }
30
+
31
+ remove(hashcode: string) {
32
+ const existing = this.trusted.findIndex((x) => (x = hashcode));
33
+ if (existing >= 0) {
34
+ this.trusted.splice(existing, 1);
35
+ return true;
36
+ }
37
+ return false;
38
+ }
39
+ }
package/src/types.ts CHANGED
@@ -5,3 +5,16 @@ export interface StartByBase64 {
5
5
  base64: string;
6
6
  }
7
7
  export type StartProgram = StartByVariant | StartByBase64;
8
+
9
+ export interface InstallWithTGZ {
10
+ type: "tgz";
11
+ name: string;
12
+ base64: string;
13
+ }
14
+
15
+ export interface InstallWithNPM {
16
+ type: "npm";
17
+ name: string;
18
+ }
19
+
20
+ export type InstallDependency = InstallWithTGZ | InstallWithNPM;