@freesignal/protocol 0.2.4 → 0.2.5

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/api.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Crypto, LocalStorage } from "@freesignal/interfaces";
1
+ import { Crypto, KeyExchangeData, KeyExchangeDataBundle, KeyExchangeSynMessage, LocalStorage } from "@freesignal/interfaces";
2
2
  import { KeySession } from "./double-ratchet";
3
3
  import { KeyExchange } from "./x3dh";
4
4
  import { Datagram, IdentityKeys, EncryptedData, UserId } from "./types";
@@ -10,6 +10,7 @@ export declare class FreeSignalAPI {
10
10
  protected readonly sessions: LocalStorage<UserId, KeySession>;
11
11
  protected readonly keyExchange: KeyExchange;
12
12
  protected readonly users: LocalStorage<UserId, IdentityKeys>;
13
+ readonly userId: UserId;
13
14
  constructor(opts: {
14
15
  secretSignKey: Uint8Array;
15
16
  secretBoxKey: Uint8Array;
@@ -17,10 +18,13 @@ export declare class FreeSignalAPI {
17
18
  keyExchange: LocalStorage<string, Crypto.KeyPair>;
18
19
  users: LocalStorage<UserId, IdentityKeys>;
19
20
  });
20
- get userId(): Uint8Array;
21
21
  get identityKeys(): IdentityKeys;
22
22
  encryptData(data: Uint8Array, userId: string): Promise<EncryptedData>;
23
23
  decryptData(data: Uint8Array, userId: string): Promise<Uint8Array>;
24
+ getHandshake(url: string, userId?: UserId): Promise<KeyExchangeData>;
25
+ postHandshake(url: string, message: KeyExchangeSynMessage): Promise<boolean>;
26
+ putHandshake(url: string, publicKey: string | Uint8Array, bundle: KeyExchangeDataBundle): Promise<boolean>;
27
+ deleteHandshake(url: string, publicKey: string | Uint8Array): Promise<boolean>;
24
28
  getDatagrams(publicKey: string | Uint8Array, url: string): Promise<Datagram[]>;
25
29
  postDatagrams(datagrams: Datagram[], publicKey: string | Uint8Array, url: string): Promise<number>;
26
30
  deleteDatagrams(datagramIds: DatagramId[], publicKey: string | Uint8Array, url: string): Promise<number>;
package/api.js CHANGED
@@ -27,9 +27,7 @@ class FreeSignalAPI {
27
27
  this.sessions = sessions;
28
28
  this.keyExchange = new x3dh_1.KeyExchange(secretSignKey, secretBoxKey, keyExchange);
29
29
  this.users = users;
30
- }
31
- get userId() {
32
- return crypto_1.default.hash(this.signKey.publicKey);
30
+ this.userId = types_1.UserId.getUserId(this.signKey.publicKey).toString();
33
31
  }
34
32
  get identityKeys() {
35
33
  return {
@@ -59,6 +57,50 @@ class FreeSignalAPI {
59
57
  return decrypted;
60
58
  });
61
59
  }
60
+ getHandshake(url, userId) {
61
+ return __awaiter(this, void 0, void 0, function* () {
62
+ const res = yield fetch(`${url}/${userId !== null && userId !== void 0 ? userId : ''}`, {
63
+ method: 'GET'
64
+ });
65
+ return (0, utils_1.decodeJSON)(new Uint8Array(yield res.arrayBuffer()));
66
+ });
67
+ }
68
+ postHandshake(url, message) {
69
+ return __awaiter(this, void 0, void 0, function* () {
70
+ const res = yield fetch(url, {
71
+ method: 'POST',
72
+ headers: {
73
+ 'Content-Type': exports.FREESIGNAL_MIME
74
+ },
75
+ body: (0, utils_1.encodeJSON)(message)
76
+ });
77
+ return res.status === 200;
78
+ });
79
+ }
80
+ putHandshake(url, publicKey, bundle) {
81
+ return __awaiter(this, void 0, void 0, function* () {
82
+ const res = yield fetch(url, {
83
+ method: 'PUT',
84
+ headers: {
85
+ 'Content-Type': exports.FREESIGNAL_MIME,
86
+ authorization: this.createToken(publicKey instanceof Uint8Array ? publicKey : (0, utils_1.encodeBase64)(publicKey))
87
+ },
88
+ body: (0, utils_1.encodeJSON)(bundle)
89
+ });
90
+ return res.status === 201;
91
+ });
92
+ }
93
+ deleteHandshake(url, publicKey) {
94
+ return __awaiter(this, void 0, void 0, function* () {
95
+ const res = yield fetch(url, {
96
+ method: 'DELETE',
97
+ headers: {
98
+ authorization: this.createToken(publicKey instanceof Uint8Array ? publicKey : (0, utils_1.encodeBase64)(publicKey))
99
+ }
100
+ });
101
+ return res.status === 200;
102
+ });
103
+ }
62
104
  getDatagrams(publicKey, url) {
63
105
  return __awaiter(this, void 0, void 0, function* () {
64
106
  const res = yield fetch(url, {
@@ -99,18 +141,18 @@ class FreeSignalAPI {
99
141
  });
100
142
  }
101
143
  createToken(publicKey) {
102
- const sharedId = crypto_1.default.hash(crypto_1.default.ECDH.scalarMult(publicKey, this.boxKey.secretKey));
103
- return `Bearer ${(0, utils_1.decodeBase64)(this.userId)}:${(0, utils_1.decodeBase64)(sharedId)}`;
144
+ const signature = crypto_1.default.EdDSA.sign(crypto_1.default.hash(crypto_1.default.ECDH.scalarMult(publicKey, this.boxKey.secretKey)), this.signKey.secretKey);
145
+ return `Bearer ${this.userId}:${(0, utils_1.decodeBase64)(signature)}`;
104
146
  }
105
147
  ;
106
148
  digestToken(auth) {
107
149
  return __awaiter(this, void 0, void 0, function* () {
108
150
  if (auth && auth.startsWith("Bearer ")) {
109
- const [userId, sharedId] = auth.substring(7).split(":");
151
+ const [userId, signature] = auth.substring(7).split(":");
110
152
  const identityKeys = yield this.users.get(userId);
111
153
  if (!identityKeys)
112
154
  throw new Error('User not found or invalid auth token');
113
- if ((0, utils_1.verifyUint8Array)(crypto_1.default.hash(crypto_1.default.ECDH.scalarMult((0, utils_1.encodeBase64)(identityKeys.publicKey), this.boxKey.secretKey)), (0, utils_1.encodeBase64)(sharedId)))
155
+ if (crypto_1.default.EdDSA.verify(crypto_1.default.hash(crypto_1.default.ECDH.scalarMult((0, utils_1.encodeBase64)(identityKeys.identityKey), this.boxKey.secretKey)), (0, utils_1.encodeBase64)(signature), (0, utils_1.encodeBase64)(identityKeys.publicKey)))
114
156
  return { identityKeys, userId: auth };
115
157
  else
116
158
  throw new Error('Authorization token not valid');
@@ -83,14 +83,14 @@ export declare class KeySession {
83
83
  /**
84
84
  * Export the state of the session;
85
85
  */
86
- export(): ExportedKeySession;
86
+ toJSON(): ExportedKeySession;
87
87
  /**
88
88
  * Import a state.
89
89
  *
90
90
  * @param json string returned by `export()` method.
91
91
  * @returns session with the state parsed.
92
92
  */
93
- static import(json: string): KeySession;
93
+ static parse(json: string): KeySession;
94
94
  /**
95
95
  * The fixed key length (in bytes) used throughout the Double Ratchet session.
96
96
  * Typically 32 bytes (256 bits) for symmetric keys.
package/double-ratchet.js CHANGED
@@ -141,7 +141,7 @@ class KeySession {
141
141
  /**
142
142
  * Export the state of the session;
143
143
  */
144
- export() {
144
+ toJSON() {
145
145
  return {
146
146
  secretKey: (0, utils_1.decodeBase64)((0, utils_1.concatUint8Array)(this.keyPair.secretKey)),
147
147
  remoteKey: (0, utils_1.decodeBase64)(this._remoteKey),
@@ -160,7 +160,7 @@ class KeySession {
160
160
  * @param json string returned by `export()` method.
161
161
  * @returns session with the state parsed.
162
162
  */
163
- static import(json) {
163
+ static parse(json) {
164
164
  const data = JSON.parse(json);
165
165
  const session = new KeySession({ secretKey: (0, utils_1.encodeBase64)(data.secretKey), rootKey: (0, utils_1.encodeBase64)(data.rootKey) });
166
166
  session._remoteKey = (0, utils_1.encodeBase64)(data.remoteKey);
package/index.d.ts CHANGED
@@ -21,12 +21,13 @@ import { LocalStorage, Crypto } from "@freesignal/interfaces";
21
21
  import { KeySession } from "./double-ratchet";
22
22
  import { KeyExchange } from "./x3dh";
23
23
  /**
24
- * Creates a new Double Ratchet session.
24
+ * Creates a new Double Ratchet session for secure message exchange.
25
25
  *
26
- * @param opts.remoteKey The public key of the remote party.
27
- * @param opts.preSharedKey An optional pre-shared key to initialize the session.
28
- *
29
- * @returns A new Double Ratchet session.
26
+ * @param opts - Optional parameters for session initialization.
27
+ * @param opts.secretKey - The local party's secret key as a Uint8Array.
28
+ * @param opts.remoteKey - The remote party's public key as a Uint8Array.
29
+ * @param opts.rootKey - An optional root key to initialize the session.
30
+ * @returns A new instance of {@link KeySession}.
30
31
  */
31
32
  export declare function createKeySession(opts?: {
32
33
  secretKey?: Uint8Array;
@@ -34,15 +35,23 @@ export declare function createKeySession(opts?: {
34
35
  rootKey?: Uint8Array;
35
36
  }): KeySession;
36
37
  /**
37
- * Creates a new X3DH session.
38
+ * Creates a new X3DH (Extended Triple Diffie-Hellman) key exchange session.
38
39
  *
39
- * @param signKeyPair
40
- * @param bundleStore
41
- * @returns A new X3DH session.
40
+ * @param signSecretKey - The EdDSA signing secret key as a Uint8Array.
41
+ * @param boxSecretKey - The ECDH box secret key as a Uint8Array.
42
+ * @param bundleStore - Optional local storage for key bundles.
43
+ * @returns A new instance of {@link KeyExchange}.
42
44
  */
43
45
  export declare function createKeyExchange(signSecretKey: Uint8Array, boxSecretKey: Uint8Array, bundleStore?: LocalStorage<string, crypto.KeyPair>): KeyExchange;
46
+ /**
47
+ * Generates identity key pairs for signing and encryption.
48
+ *
49
+ * @param signSecretKey - Optional secret key for EdDSA signing.
50
+ * @param boxSecretKey - Optional secret key for ECDH encryption.
51
+ * @returns An object containing readonly signing and box key pairs.
52
+ */
44
53
  export declare function createIdentityKeys(signSecretKey?: Uint8Array, boxSecretKey?: Uint8Array): {
45
- sign: Crypto.KeyPair;
46
- box: Crypto.KeyPair;
54
+ readonly sign: Crypto.KeyPair;
55
+ readonly box: Crypto.KeyPair;
47
56
  };
48
- export { IdentityKeys, Protocols, EncryptedData, Datagram } from "./types";
57
+ export { UserId, IdentityKeys, Protocols, Datagram, EncryptedData } from "./types";
package/index.js CHANGED
@@ -21,7 +21,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
21
21
  return (mod && mod.__esModule) ? mod : { "default": mod };
22
22
  };
23
23
  Object.defineProperty(exports, "__esModule", { value: true });
24
- exports.Datagram = exports.EncryptedData = exports.Protocols = exports.IdentityKeys = void 0;
24
+ exports.EncryptedData = exports.Datagram = exports.Protocols = exports.IdentityKeys = exports.UserId = void 0;
25
25
  exports.createKeySession = createKeySession;
26
26
  exports.createKeyExchange = createKeyExchange;
27
27
  exports.createIdentityKeys = createIdentityKeys;
@@ -29,31 +29,37 @@ const crypto_1 = __importDefault(require("@freesignal/crypto"));
29
29
  const double_ratchet_1 = require("./double-ratchet");
30
30
  const x3dh_1 = require("./x3dh");
31
31
  /**
32
- * Creates a new Double Ratchet session.
32
+ * Creates a new Double Ratchet session for secure message exchange.
33
33
  *
34
- * @param opts.remoteKey The public key of the remote party.
35
- * @param opts.preSharedKey An optional pre-shared key to initialize the session.
36
- *
37
- * @returns A new Double Ratchet session.
34
+ * @param opts - Optional parameters for session initialization.
35
+ * @param opts.secretKey - The local party's secret key as a Uint8Array.
36
+ * @param opts.remoteKey - The remote party's public key as a Uint8Array.
37
+ * @param opts.rootKey - An optional root key to initialize the session.
38
+ * @returns A new instance of {@link KeySession}.
38
39
  */
39
40
  function createKeySession(opts) {
40
41
  return new double_ratchet_1.KeySession(opts);
41
42
  }
42
43
  /**
43
- * Creates a new X3DH session.
44
+ * Creates a new X3DH (Extended Triple Diffie-Hellman) key exchange session.
44
45
  *
45
- * @param signKeyPair
46
- * @param bundleStore
47
- * @returns A new X3DH session.
46
+ * @param signSecretKey - The EdDSA signing secret key as a Uint8Array.
47
+ * @param boxSecretKey - The ECDH box secret key as a Uint8Array.
48
+ * @param bundleStore - Optional local storage for key bundles.
49
+ * @returns A new instance of {@link KeyExchange}.
48
50
  */
49
51
  function createKeyExchange(signSecretKey, boxSecretKey, bundleStore) {
50
52
  return new x3dh_1.KeyExchange(signSecretKey, boxSecretKey, bundleStore);
51
53
  }
54
+ /**
55
+ * Generates identity key pairs for signing and encryption.
56
+ *
57
+ * @param signSecretKey - Optional secret key for EdDSA signing.
58
+ * @param boxSecretKey - Optional secret key for ECDH encryption.
59
+ * @returns An object containing readonly signing and box key pairs.
60
+ */
52
61
  function createIdentityKeys(signSecretKey, boxSecretKey) {
53
- return {
54
- sign: crypto_1.default.EdDSA.keyPair(signSecretKey),
55
- box: crypto_1.default.ECDH.keyPair(boxSecretKey)
56
- };
62
+ return { sign: crypto_1.default.EdDSA.keyPair(signSecretKey), box: crypto_1.default.ECDH.keyPair(boxSecretKey) };
57
63
  }
58
64
  /*export function createAPI(opts: {
59
65
  secretSignKey: Uint8Array;
@@ -65,7 +71,8 @@ function createIdentityKeys(signSecretKey, boxSecretKey) {
65
71
  return new FreeSignalAPI(opts);
66
72
  }*/
67
73
  var types_1 = require("./types");
74
+ Object.defineProperty(exports, "UserId", { enumerable: true, get: function () { return types_1.UserId; } });
68
75
  Object.defineProperty(exports, "IdentityKeys", { enumerable: true, get: function () { return types_1.IdentityKeys; } });
69
76
  Object.defineProperty(exports, "Protocols", { enumerable: true, get: function () { return types_1.Protocols; } });
70
- Object.defineProperty(exports, "EncryptedData", { enumerable: true, get: function () { return types_1.EncryptedData; } });
71
77
  Object.defineProperty(exports, "Datagram", { enumerable: true, get: function () { return types_1.Datagram; } });
78
+ Object.defineProperty(exports, "EncryptedData", { enumerable: true, get: function () { return types_1.EncryptedData; } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@freesignal/protocol",
3
- "version": "0.2.4",
3
+ "version": "0.2.5",
4
4
  "description": "Signal Protocol implementation in javascript",
5
5
  "license": "GPL-3.0-or-later",
6
6
  "author": "Christian Braghette",
@@ -13,7 +13,7 @@
13
13
  "dependencies": {
14
14
  "@freesignal/crypto": "^0.3.0",
15
15
  "@freesignal/interfaces": "^0.1.1",
16
- "@freesignal/utils": "^1.0.2",
16
+ "@freesignal/utils": "^1.1.0",
17
17
  "base64-js": "^1.5.1",
18
18
  "fflate": "^0.8.2",
19
19
  "js-sha3": "^0.9.3",
package/test.js CHANGED
@@ -24,7 +24,6 @@ bob.digestMessage(aliceack).then(({ session: bobsession, identityKeys }) => {
24
24
  console.log("Error during handshake");
25
25
  const longmsg = _1.Datagram.create(alice.signatureKey, bob.signatureKey, _1.Protocols.MESSAGE, alicesession.encrypt(new Uint8Array(1000000).fill(33).map(val => val + Math.floor(Math.random() * 93))));
26
26
  console.log(longmsg.encode().length);
27
- console.log(longmsg.encode(false).length);
28
27
  }
29
28
  else
30
29
  console.log("Error");
package/types.d.ts CHANGED
@@ -23,6 +23,7 @@ export declare namespace UserId {
23
23
  private readonly array;
24
24
  constructor(array: Uint8Array);
25
25
  toString(): string;
26
+ toJSON(): string;
26
27
  toUint8Array(): Uint8Array;
27
28
  }
28
29
  export function getUserId(publicKey: string | Uint8Array): UserIdConstructor;
@@ -49,9 +50,9 @@ export declare namespace IdentityKeys {
49
50
  }
50
51
  export declare enum Protocols {
51
52
  NULL = "",
52
- MESSAGE = "/freesignal/message/1.0.0",
53
- RELAY = "/freesignal/relay/1.0.0",
54
- HANDSHAKE = "/freesignal/handshake/1.0.0"
53
+ MESSAGE = "/freesignal/message",
54
+ RELAY = "/freesignal/relay",
55
+ HANDSHAKE = "/freesignal/handshake"
55
56
  }
56
57
  export declare namespace Protocols {
57
58
  function isProtocol(protocol: any): boolean;
@@ -68,6 +69,7 @@ export interface Datagram {
68
69
  readonly protocol: Protocols;
69
70
  readonly createdAt: number;
70
71
  payload?: Uint8Array;
72
+ readonly signature?: string;
71
73
  }
72
74
  export declare namespace Datagram {
73
75
  export const version = 1;
@@ -78,12 +80,18 @@ export declare namespace Datagram {
78
80
  readonly receiver: UserId;
79
81
  readonly protocol: Protocols;
80
82
  readonly createdAt: number;
81
- payload?: Uint8Array;
83
+ _payload?: Uint8Array;
84
+ _signature?: Uint8Array;
85
+ private secretKey?;
82
86
  private static headerOffset;
83
87
  constructor(sender: Uint8Array | string, receiver: Uint8Array | string, protocol: Protocols, payload?: Uint8Array | Encodable);
84
88
  constructor(data: Uint8Array | Datagram);
85
- encode(compression?: boolean): Uint8Array;
86
- encodeSigned(secretKey: Uint8Array, compression?: boolean): Uint8Array;
89
+ get signed(): boolean;
90
+ get signature(): string | undefined;
91
+ set payload(data: Uint8Array);
92
+ get payload(): Uint8Array | undefined;
93
+ encode(): Uint8Array;
94
+ sign(secretKey: Uint8Array): this;
87
95
  toString(): string;
88
96
  toJSON(): string;
89
97
  }
@@ -165,14 +173,6 @@ export declare class EncryptedDataConstructor implements EncryptedData {
165
173
  get nonce(): Uint8Array;
166
174
  get ciphertext(): Uint8Array;
167
175
  encode(): Uint8Array;
168
- decode(): {
169
- version: number;
170
- count: number;
171
- previous: number;
172
- publicKey: string;
173
- nonce: string;
174
- ciphertext: string;
175
- };
176
176
  toString(): string;
177
177
  toJSON(): string;
178
178
  }
package/types.js CHANGED
@@ -24,7 +24,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
24
24
  exports.EncryptedDataConstructor = exports.EncryptedData = exports.Datagram = exports.Protocols = exports.IdentityKeys = exports.UserId = void 0;
25
25
  const utils_1 = require("@freesignal/utils");
26
26
  const crypto_1 = __importDefault(require("@freesignal/crypto"));
27
- const fflate_1 = __importDefault(require("fflate"));
28
27
  const double_ratchet_1 = require("./double-ratchet");
29
28
  var UserId;
30
29
  (function (UserId) {
@@ -36,6 +35,9 @@ var UserId;
36
35
  toString() {
37
36
  return (0, utils_1.decodeBase64)(this.array);
38
37
  }
38
+ toJSON() {
39
+ return JSON.stringify(this.toString());
40
+ }
39
41
  toUint8Array() {
40
42
  return this.array;
41
43
  }
@@ -72,7 +74,7 @@ var IdentityKeys;
72
74
  throw (0, utils_1.decodeBase64)(this.encode());
73
75
  }
74
76
  toJSON() {
75
- throw this.toString();
77
+ throw JSON.stringify(this.toString());
76
78
  }
77
79
  }
78
80
  function isIdentityKeys(obj) {
@@ -87,9 +89,9 @@ var IdentityKeys;
87
89
  var Protocols;
88
90
  (function (Protocols) {
89
91
  Protocols["NULL"] = "";
90
- Protocols["MESSAGE"] = "/freesignal/message/1.0.0";
91
- Protocols["RELAY"] = "/freesignal/relay/1.0.0";
92
- Protocols["HANDSHAKE"] = "/freesignal/handshake/1.0.0";
92
+ Protocols["MESSAGE"] = "/freesignal/message";
93
+ Protocols["RELAY"] = "/freesignal/relay";
94
+ Protocols["HANDSHAKE"] = "/freesignal/handshake";
93
95
  })(Protocols || (exports.Protocols = Protocols = {}));
94
96
  (function (Protocols) {
95
97
  function isProtocol(protocol) {
@@ -105,15 +107,10 @@ var Protocols;
105
107
  }
106
108
  Protocols.toCode = toCode;
107
109
  function encode(protocol, length) {
108
- /*const raw = numberToUint8Array(Protocols.toCode(protocol), length).reverse();
109
- raw[0] |= (raw.length - 1) << 6;
110
- return raw;*/
111
110
  return (0, utils_1.numberToUint8Array)(Protocols.toCode(protocol), length);
112
111
  }
113
112
  Protocols.encode = encode;
114
113
  function decode(array) {
115
- //array[0] &= 63;
116
- //array = array.reverse();
117
114
  return Protocols.fromCode((0, utils_1.numberFromUint8Array)(array));
118
115
  }
119
116
  Protocols.decode = decode;
@@ -125,21 +122,15 @@ var Datagram;
125
122
  constructor(data, receiver, protocol, payload) {
126
123
  if (!receiver && !protocol && !payload) {
127
124
  if (data instanceof Uint8Array) {
128
- this.version = data[0] & 63;
125
+ this.version = data[0] & 127;
129
126
  this.protocol = Protocols.decode(data.subarray(1, 2));
130
127
  this.id = crypto_1.default.UUID.stringify(data.subarray(2, 18));
131
128
  this.createdAt = (0, utils_1.numberFromUint8Array)(data.subarray(18, 26));
132
129
  this.sender = (0, utils_1.decodeBase64)(data.subarray(26, 26 + crypto_1.default.EdDSA.publicKeyLength));
133
130
  this.receiver = (0, utils_1.decodeBase64)(data.subarray(26 + crypto_1.default.EdDSA.publicKeyLength, DatagramConstructor.headerOffset));
134
- if (data[0] & 128) {
135
- const signature = data.subarray(data.length - crypto_1.default.EdDSA.signatureLength);
136
- if (!crypto_1.default.EdDSA.verify(data.subarray(0, data.length - crypto_1.default.EdDSA.signatureLength), signature, data.subarray(26, 26 + crypto_1.default.EdDSA.publicKeyLength)))
137
- throw new Error('Invalid signature for Datagram');
138
- }
139
- if (data[0] & 64)
140
- this.payload = fflate_1.default.inflateSync(data.subarray(DatagramConstructor.headerOffset, data.length));
141
- else
142
- this.payload = data.subarray(DatagramConstructor.headerOffset, data.length);
131
+ if (data[0] & 128)
132
+ this._signature = data.subarray(data.length - crypto_1.default.EdDSA.signatureLength);
133
+ this._payload = data.subarray(DatagramConstructor.headerOffset, data.length);
143
134
  }
144
135
  else if (Datagram.isDatagram(data)) {
145
136
  const datagram = data;
@@ -149,7 +140,8 @@ var Datagram;
149
140
  this.receiver = datagram.receiver;
150
141
  this.protocol = datagram.protocol;
151
142
  this.createdAt = datagram.createdAt;
152
- this.payload = datagram.payload;
143
+ this._payload = datagram.payload;
144
+ this._signature = (0, utils_1.encodeBase64)(datagram.signature);
153
145
  }
154
146
  else
155
147
  throw new Error('Invalid constructor arguments for Datagram');
@@ -161,45 +153,50 @@ var Datagram;
161
153
  this.receiver = typeof receiver === 'string' ? receiver : (0, utils_1.decodeBase64)(receiver);
162
154
  this.protocol = protocol;
163
155
  this.createdAt = Date.now();
164
- this.payload = payload instanceof Uint8Array ? payload : payload === null || payload === void 0 ? void 0 : payload.encode();
156
+ this._payload = payload instanceof Uint8Array ? payload : payload === null || payload === void 0 ? void 0 : payload.encode();
165
157
  }
166
158
  else
167
159
  throw new Error('Invalid constructor arguments for Datagram');
168
160
  }
169
- encode(compression = true) {
170
- var _a;
171
- compression = compression && this.payload != undefined && this.payload.length > 1024;
172
- return (0, utils_1.concatUint8Array)(new Uint8Array(1).fill(this.version | (compression ? 64 : 0)), //1
161
+ get signed() {
162
+ return !this._signature && !this.secretKey ? false : true;
163
+ }
164
+ get signature() {
165
+ if (this.signed) {
166
+ if (!this._signature)
167
+ this.encode();
168
+ return (0, utils_1.decodeBase64)(this._signature);
169
+ }
170
+ }
171
+ set payload(data) {
172
+ this._signature = undefined;
173
+ this._payload = data;
174
+ }
175
+ get payload() {
176
+ return this._payload;
177
+ }
178
+ encode() {
179
+ var _a, _b, _c;
180
+ const data = (0, utils_1.concatUint8Array)(new Uint8Array(1).fill(this.version | (this.secretKey ? 128 : 0)), //1
173
181
  Protocols.encode(this.protocol), //1
174
182
  (_a = crypto_1.default.UUID.parse(this.id)) !== null && _a !== void 0 ? _a : [], //16
175
183
  (0, utils_1.numberToUint8Array)(this.createdAt, 8), //8
176
184
  (0, utils_1.encodeBase64)(this.sender), //32
177
185
  (0, utils_1.encodeBase64)(this.receiver), //32
178
- ...(this.payload ? [compression ? fflate_1.default.deflateSync(this.payload) : this.payload] : []));
186
+ (_b = this._payload) !== null && _b !== void 0 ? _b : new Uint8Array());
187
+ if (this.secretKey)
188
+ this._signature = crypto_1.default.EdDSA.sign(data, this.secretKey);
189
+ return (0, utils_1.concatUint8Array)(data, (_c = this._signature) !== null && _c !== void 0 ? _c : new Uint8Array());
179
190
  }
180
- encodeSigned(secretKey, compression) {
181
- //if (!this.payload) throw new Error('Cannot sign a datagram without payload');
182
- const header = this.encode(compression);
183
- header[0] |= 128; // Set the sign bit
184
- const signature = crypto_1.default.EdDSA.sign(header, secretKey);
185
- return (0, utils_1.concatUint8Array)(header, signature);
191
+ sign(secretKey) {
192
+ this.secretKey = secretKey;
193
+ return this;
186
194
  }
187
195
  toString() {
188
196
  return (0, utils_1.decodeBase64)(this.encode());
189
197
  }
190
198
  toJSON() {
191
- /*return JSON.stringify({
192
- id: this.id,
193
- version: this.version,
194
- senderKey: this.senderKey,
195
- senderRelay: this.senderRelay,
196
- receiverKey: this.receiverKey,
197
- receiverRelay: this.receiverRelay,
198
- protocol: this.protocol,
199
- createdAt: this.createdAt,
200
- payload: this.payload ? encodeBase64(this.payload) : undefined
201
- });*/
202
- return this.toString();
199
+ return JSON.stringify(this.toString());
203
200
  }
204
201
  }
205
202
  DatagramConstructor.headerOffset = 26 + crypto_1.default.EdDSA.publicKeyLength * 2;
@@ -263,21 +260,18 @@ class EncryptedDataConstructor {
263
260
  encode() {
264
261
  return this.raw;
265
262
  }
266
- decode() {
267
- return {
263
+ toString() {
264
+ return (0, utils_1.decodeBase64)(this.raw);
265
+ }
266
+ toJSON() {
267
+ return JSON.stringify({
268
268
  version: this.version,
269
269
  count: this.count,
270
270
  previous: this.previous,
271
271
  publicKey: (0, utils_1.decodeBase64)(this.publicKey),
272
272
  nonce: (0, utils_1.decodeBase64)(this.nonce),
273
273
  ciphertext: (0, utils_1.decodeBase64)(this.ciphertext)
274
- };
275
- }
276
- toString() {
277
- return (0, utils_1.decodeBase64)(this.raw);
278
- }
279
- toJSON() {
280
- return JSON.stringify(this.decode());
274
+ });
281
275
  }
282
276
  }
283
277
  exports.EncryptedDataConstructor = EncryptedDataConstructor;