@nopeek/chat 0.1.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/README.md ADDED
@@ -0,0 +1,17 @@
1
+ # @nopeek/chat
2
+
3
+ Official client SDK for **NoPeek** — end-to-end-encrypted messaging. The server
4
+ only ever sees ciphertext; message bodies, attachments, and key backups are all
5
+ encrypted on-device (MLS-style per-channel AES-256-GCM).
6
+
7
+ ```ts
8
+ import { NoPeek } from "@nopeek/chat";
9
+
10
+ const np = await NoPeek.connect({ apiUrl, appId, userId, sessionToken });
11
+ const ch = await np.channels.create({ channelTypeKey: "direct", memberIds: [userId, peerId] });
12
+ ch.on?.("message", (m) => console.log(m.body?.text));
13
+ await ch.send({ text: "encrypted before it leaves this device" });
14
+ ```
15
+
16
+ See the NoPeek API reference for the full surface (channels, messages, recovery,
17
+ backups, bots). Used by the NoPeek messenger and by `@nopeek/agent-bridge`.
@@ -0,0 +1,80 @@
1
+ /**
2
+ * NoPeek dev cipher suite ("npdev-1").
3
+ *
4
+ * Real client-side E2EE: per-channel AES-256-GCM content keys, distributed to
5
+ * member devices by wrapping under ECDH(P-256) shared secrets, riding the
6
+ * MLS delivery-service rails (key packages / welcome / commit) as opaque
7
+ * payloads. The server never sees key material or plaintext.
8
+ *
9
+ * Honest limitations vs. full MLS (RFC 9420), which this slot is shaped for
10
+ * (swap in mls-rs WASM without changing the wire contract): no ratcheting,
11
+ * so no forward secrecy / post-compromise security yet; membership changes
12
+ * SHOULD rotate the channel key (rotateKey() is provided; the SDK calls it on
13
+ * member removal).
14
+ */
15
+ export declare const b64: {
16
+ enc: (buf: ArrayBuffer | Uint8Array) => string;
17
+ dec: (s: string) => Uint8Array<ArrayBuffer>;
18
+ };
19
+ export interface DeviceKeyPair {
20
+ publicKeyJwk: JsonWebKey;
21
+ privateKeyJwk: JsonWebKey;
22
+ }
23
+ export declare function generateDeviceKeys(): Promise<DeviceKeyPair>;
24
+ /** Key-package payload published to the registry (opaque to the server). */
25
+ export declare function keyPackageData(deviceId: string, publicKeyJwk: JsonWebKey): string;
26
+ export declare function sha256hex(data: string): Promise<string>;
27
+ export declare function generateChannelKey(): Promise<CryptoKey>;
28
+ /**
29
+ * Derive an AES-256-GCM backup key from a human recovery code (PBKDF2-SHA-256,
30
+ * WebCrypto-native, no argon2 wasm dependency). The recovery code is shown to
31
+ * the user ONCE; NoPeek never sees it or the derived key — this is what makes
32
+ * WhatsApp-style restore work without Matrix-grade key management.
33
+ */
34
+ export declare function deriveBackupKey(recoveryCode: string, saltB64: string, iterations?: number): Promise<CryptoKey>;
35
+ /** A friendly recovery code: 4 groups of 4 crockford-base32 chars (e.g. K7QP-3M9X-...). */
36
+ export declare function generateRecoveryCode(): string;
37
+ /**
38
+ * OPTIONAL key escrow: wrap raw key bytes under a server-published RSA public
39
+ * key (base64 SPKI, RSA-OAEP with SHA-256 — matches Erlang
40
+ * :rsa_pkcs1_oaep_padding + rsa_oaep_md/rsa_mgf1_md :sha256 on the unwrap
41
+ * side; parity-tested). A 32-byte data key fits RSA-2048-OAEP (~190B limit).
42
+ * The escrow PRIVATE key never reaches clients — only the workspace-opt-in
43
+ * server endpoint can unwrap (email+password-only recovery; see backup()).
44
+ */
45
+ export declare function rsaOaepWrapB64(spkiB64: string, raw: Uint8Array<ArrayBuffer>): Promise<string>;
46
+ export declare function generateContentKey(): Promise<CryptoKey>;
47
+ export declare function exportRawKeyB64(key: CryptoKey): Promise<string>;
48
+ export declare function importRawKeyB64(raw: string): Promise<CryptoKey>;
49
+ /** Encrypt raw bytes with a content key. Returns the IV (b64) and ciphertext bytes. */
50
+ export declare function encryptBytes(key: CryptoKey, bytes: ArrayBuffer): Promise<{
51
+ iv: string;
52
+ data: Uint8Array<ArrayBuffer>;
53
+ }>;
54
+ export declare function decryptBytes(keyB64: string, ivB64: string, ct: ArrayBuffer): Promise<ArrayBuffer>;
55
+ /**
56
+ * Deterministically derive an AES-256-GCM channel key from a shared secret and
57
+ * the channel id (HKDF-SHA-256). Every member holding `secret` derives the same
58
+ * key with no key distribution — used by preshared-key mode. The secret never
59
+ * leaves the client, so the server still only sees ciphertext.
60
+ */
61
+ export declare function deriveSharedChannelKey(secret: string, channelId: string): Promise<CryptoKey>;
62
+ export declare function exportChannelKey(key: CryptoKey): Promise<string>;
63
+ export declare function importChannelKey(raw: string): Promise<CryptoKey>;
64
+ export interface WrappedKey {
65
+ deviceId: string;
66
+ /** Ephemeral sender public key for this wrap. */
67
+ epk: JsonWebKey;
68
+ iv: string;
69
+ ct: string;
70
+ }
71
+ /** Wrap a channel key to a set of recipient devices (one ECDH each, fresh ephemeral key per wrap). */
72
+ export declare function wrapChannelKey(channelKey: CryptoKey, recipients: {
73
+ deviceId: string;
74
+ publicKeyJwk: JsonWebKey;
75
+ }[]): Promise<WrappedKey[]>;
76
+ export declare function unwrapChannelKey(wrapped: WrappedKey, devicePrivateJwk: JsonWebKey): Promise<CryptoKey>;
77
+ /** Encrypt an application payload (the EncryptedPayload JSON) for a channel. */
78
+ export declare function encryptPayload(channelKey: CryptoKey, payload: unknown): Promise<string>;
79
+ export declare function decryptPayload<T = unknown>(channelKey: CryptoKey, ciphertext: string): Promise<T>;
80
+ //# sourceMappingURL=crypto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"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"}
package/dist/crypto.js ADDED
@@ -0,0 +1,161 @@
1
+ /**
2
+ * NoPeek dev cipher suite ("npdev-1").
3
+ *
4
+ * Real client-side E2EE: per-channel AES-256-GCM content keys, distributed to
5
+ * member devices by wrapping under ECDH(P-256) shared secrets, riding the
6
+ * MLS delivery-service rails (key packages / welcome / commit) as opaque
7
+ * payloads. The server never sees key material or plaintext.
8
+ *
9
+ * Honest limitations vs. full MLS (RFC 9420), which this slot is shaped for
10
+ * (swap in mls-rs WASM without changing the wire contract): no ratcheting,
11
+ * so no forward secrecy / post-compromise security yet; membership changes
12
+ * SHOULD rotate the channel key (rotateKey() is provided; the SDK calls it on
13
+ * member removal).
14
+ */
15
+ const subtle = globalThis.crypto.subtle;
16
+ export const b64 = {
17
+ enc: (buf) => {
18
+ const bytes = buf instanceof Uint8Array ? buf : new Uint8Array(buf);
19
+ let s = "";
20
+ for (const b of bytes)
21
+ s += String.fromCharCode(b);
22
+ return btoa(s);
23
+ },
24
+ dec: (s) => {
25
+ const bin = atob(s);
26
+ const out = new Uint8Array(new ArrayBuffer(bin.length));
27
+ for (let i = 0; i < bin.length; i++)
28
+ out[i] = bin.charCodeAt(i);
29
+ return out;
30
+ },
31
+ };
32
+ const te = new TextEncoder();
33
+ const td = new TextDecoder();
34
+ export async function generateDeviceKeys() {
35
+ const pair = await subtle.generateKey({ name: "ECDH", namedCurve: "P-256" }, true, ["deriveKey", "deriveBits"]);
36
+ return {
37
+ publicKeyJwk: await subtle.exportKey("jwk", pair.publicKey),
38
+ privateKeyJwk: await subtle.exportKey("jwk", pair.privateKey),
39
+ };
40
+ }
41
+ /** Key-package payload published to the registry (opaque to the server). */
42
+ export function keyPackageData(deviceId, publicKeyJwk) {
43
+ return b64.enc(te.encode(JSON.stringify({ suite: "npdev-1", deviceId, pub: publicKeyJwk })));
44
+ }
45
+ export async function sha256hex(data) {
46
+ const digest = await subtle.digest("SHA-256", te.encode(data));
47
+ return [...new Uint8Array(digest)].map((x) => x.toString(16).padStart(2, "0")).join("");
48
+ }
49
+ export async function generateChannelKey() {
50
+ return subtle.generateKey({ name: "AES-GCM", length: 256 }, true, ["encrypt", "decrypt"]);
51
+ }
52
+ /**
53
+ * Derive an AES-256-GCM backup key from a human recovery code (PBKDF2-SHA-256,
54
+ * WebCrypto-native, no argon2 wasm dependency). The recovery code is shown to
55
+ * the user ONCE; NoPeek never sees it or the derived key — this is what makes
56
+ * WhatsApp-style restore work without Matrix-grade key management.
57
+ */
58
+ export async function deriveBackupKey(recoveryCode, saltB64, iterations = 210_000) {
59
+ const ikm = await subtle.importKey("raw", te.encode(recoveryCode), "PBKDF2", false, ["deriveKey"]);
60
+ return subtle.deriveKey({ name: "PBKDF2", salt: b64.dec(saltB64), iterations, hash: "SHA-256" }, ikm, { name: "AES-GCM", length: 256 }, true, ["encrypt", "decrypt"]);
61
+ }
62
+ /** A friendly recovery code: 4 groups of 4 crockford-base32 chars (e.g. K7QP-3M9X-...). */
63
+ export function generateRecoveryCode() {
64
+ const alphabet = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
65
+ const bytes = globalThis.crypto.getRandomValues(new Uint8Array(10));
66
+ const chars = [...bytes].map((b) => alphabet[b % 32]).join("");
67
+ return chars.match(/.{1,4}/g).join("-");
68
+ }
69
+ /**
70
+ * OPTIONAL key escrow: wrap raw key bytes under a server-published RSA public
71
+ * key (base64 SPKI, RSA-OAEP with SHA-256 — matches Erlang
72
+ * :rsa_pkcs1_oaep_padding + rsa_oaep_md/rsa_mgf1_md :sha256 on the unwrap
73
+ * side; parity-tested). A 32-byte data key fits RSA-2048-OAEP (~190B limit).
74
+ * The escrow PRIVATE key never reaches clients — only the workspace-opt-in
75
+ * server endpoint can unwrap (email+password-only recovery; see backup()).
76
+ */
77
+ export async function rsaOaepWrapB64(spkiB64, raw) {
78
+ const pub = await subtle.importKey("spki", b64.dec(spkiB64), { name: "RSA-OAEP", hash: "SHA-256" }, false, ["encrypt"]);
79
+ return b64.enc(await subtle.encrypt({ name: "RSA-OAEP" }, pub, raw));
80
+ }
81
+ // --- attachment (blob) encryption: fresh per-file AES key, key travels inside
82
+ // the E2EE message payload; only ciphertext is uploaded to S3 -----------
83
+ export async function generateContentKey() {
84
+ return subtle.generateKey({ name: "AES-GCM", length: 256 }, true, ["encrypt", "decrypt"]);
85
+ }
86
+ export async function exportRawKeyB64(key) {
87
+ return b64.enc(await subtle.exportKey("raw", key));
88
+ }
89
+ export async function importRawKeyB64(raw) {
90
+ return subtle.importKey("raw", b64.dec(raw), { name: "AES-GCM" }, true, ["encrypt", "decrypt"]);
91
+ }
92
+ /** Encrypt raw bytes with a content key. Returns the IV (b64) and ciphertext bytes. */
93
+ export async function encryptBytes(key, bytes) {
94
+ const iv = globalThis.crypto.getRandomValues(new Uint8Array(12));
95
+ const ct = await subtle.encrypt({ name: "AES-GCM", iv }, key, bytes);
96
+ return { iv: b64.enc(iv), data: new Uint8Array(ct) };
97
+ }
98
+ export async function decryptBytes(keyB64, ivB64, ct) {
99
+ const key = await importRawKeyB64(keyB64);
100
+ return subtle.decrypt({ name: "AES-GCM", iv: b64.dec(ivB64) }, key, ct);
101
+ }
102
+ /**
103
+ * Deterministically derive an AES-256-GCM channel key from a shared secret and
104
+ * the channel id (HKDF-SHA-256). Every member holding `secret` derives the same
105
+ * key with no key distribution — used by preshared-key mode. The secret never
106
+ * leaves the client, so the server still only sees ciphertext.
107
+ */
108
+ export async function deriveSharedChannelKey(secret, channelId) {
109
+ const ikm = await subtle.importKey("raw", te.encode(secret), "HKDF", false, ["deriveKey"]);
110
+ return subtle.deriveKey({ name: "HKDF", hash: "SHA-256", salt: te.encode("nopeek/channel/v1"), info: te.encode(channelId) }, ikm, { name: "AES-GCM", length: 256 }, true, ["encrypt", "decrypt"]);
111
+ }
112
+ export async function exportChannelKey(key) {
113
+ return b64.enc(await subtle.exportKey("raw", key));
114
+ }
115
+ export async function importChannelKey(raw) {
116
+ return subtle.importKey("raw", b64.dec(raw), { name: "AES-GCM" }, true, ["encrypt", "decrypt"]);
117
+ }
118
+ async function deriveWrapKey(privateJwk, publicJwk) {
119
+ const priv = await subtle.importKey("jwk", privateJwk, { name: "ECDH", namedCurve: "P-256" }, false, ["deriveKey"]);
120
+ const pub = await subtle.importKey("jwk", publicJwk, { name: "ECDH", namedCurve: "P-256" }, false, []);
121
+ return subtle.deriveKey({ name: "ECDH", public: pub }, priv, { name: "AES-GCM", length: 256 }, false, [
122
+ "encrypt",
123
+ "decrypt",
124
+ ]);
125
+ }
126
+ /** Wrap a channel key to a set of recipient devices (one ECDH each, fresh ephemeral key per wrap). */
127
+ export async function wrapChannelKey(channelKey, recipients) {
128
+ const raw = await exportChannelKey(channelKey);
129
+ const out = [];
130
+ for (const r of recipients) {
131
+ const eph = await subtle.generateKey({ name: "ECDH", namedCurve: "P-256" }, true, ["deriveKey"]);
132
+ const ephPrivJwk = await subtle.exportKey("jwk", eph.privateKey);
133
+ const wrapKey = await deriveWrapKey(ephPrivJwk, r.publicKeyJwk);
134
+ const iv = globalThis.crypto.getRandomValues(new Uint8Array(12));
135
+ const ct = await subtle.encrypt({ name: "AES-GCM", iv }, wrapKey, te.encode(raw));
136
+ out.push({ deviceId: r.deviceId, epk: await subtle.exportKey("jwk", eph.publicKey), iv: b64.enc(iv), ct: b64.enc(ct) });
137
+ }
138
+ return out;
139
+ }
140
+ export async function unwrapChannelKey(wrapped, devicePrivateJwk) {
141
+ const wrapKey = await deriveWrapKey(devicePrivateJwk, wrapped.epk);
142
+ const raw = await subtle.decrypt({ name: "AES-GCM", iv: b64.dec(wrapped.iv) }, wrapKey, b64.dec(wrapped.ct));
143
+ return importChannelKey(td.decode(raw));
144
+ }
145
+ /** Encrypt an application payload (the EncryptedPayload JSON) for a channel. */
146
+ export async function encryptPayload(channelKey, payload) {
147
+ const iv = globalThis.crypto.getRandomValues(new Uint8Array(12));
148
+ const ct = await subtle.encrypt({ name: "AES-GCM", iv }, channelKey, te.encode(JSON.stringify(payload)));
149
+ const framed = new Uint8Array(iv.length + ct.byteLength);
150
+ framed.set(iv, 0);
151
+ framed.set(new Uint8Array(ct), iv.length);
152
+ return b64.enc(framed);
153
+ }
154
+ export async function decryptPayload(channelKey, ciphertext) {
155
+ const framed = b64.dec(ciphertext);
156
+ const iv = framed.slice(0, 12);
157
+ const ct = framed.slice(12);
158
+ const pt = await subtle.decrypt({ name: "AES-GCM", iv }, channelKey, ct);
159
+ return JSON.parse(td.decode(pt));
160
+ }
161
+ //# sourceMappingURL=crypto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"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"}