@n24q02m/mcp-relay-core 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/build/crypto/aes.d.ts +8 -0
- package/build/crypto/aes.d.ts.map +1 -0
- package/build/crypto/aes.js +25 -0
- package/build/crypto/aes.js.map +1 -0
- package/build/crypto/ecdh.d.ts +5 -0
- package/build/crypto/ecdh.d.ts.map +1 -0
- package/build/crypto/ecdh.js +16 -0
- package/build/crypto/ecdh.js.map +1 -0
- package/build/crypto/index.d.ts +4 -0
- package/build/crypto/index.d.ts.map +1 -0
- package/build/crypto/index.js +4 -0
- package/build/crypto/index.js.map +1 -0
- package/build/crypto/kdf.d.ts +2 -0
- package/build/crypto/kdf.d.ts.map +1 -0
- package/build/crypto/kdf.js +7 -0
- package/build/crypto/kdf.js.map +1 -0
- package/build/index.d.ts +6 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +5 -0
- package/build/index.js.map +1 -0
- package/build/relay/client.d.ts +11 -0
- package/build/relay/client.d.ts.map +1 -0
- package/build/relay/client.js +54 -0
- package/build/relay/client.js.map +1 -0
- package/build/relay/wordlist.d.ts +2 -0
- package/build/relay/wordlist.d.ts.map +1 -0
- package/build/relay/wordlist.js +978 -0
- package/build/relay/wordlist.js.map +1 -0
- package/build/schema/types.d.ts +42 -0
- package/build/schema/types.d.ts.map +1 -0
- package/build/schema/types.js +2 -0
- package/build/schema/types.js.map +1 -0
- package/build/storage/config-file.d.ts +8 -0
- package/build/storage/config-file.d.ts.map +1 -0
- package/build/storage/config-file.js +99 -0
- package/build/storage/config-file.js.map +1 -0
- package/build/storage/encryption.d.ts +5 -0
- package/build/storage/encryption.d.ts.map +1 -0
- package/build/storage/encryption.js +25 -0
- package/build/storage/encryption.js.map +1 -0
- package/build/storage/index.d.ts +5 -0
- package/build/storage/index.d.ts.map +1 -0
- package/build/storage/index.js +5 -0
- package/build/storage/index.js.map +1 -0
- package/build/storage/machine-id.d.ts +3 -0
- package/build/storage/machine-id.d.ts.map +1 -0
- package/build/storage/machine-id.js +44 -0
- package/build/storage/machine-id.js.map +1 -0
- package/build/storage/resolver.d.ts +7 -0
- package/build/storage/resolver.d.ts.map +1 -0
- package/build/storage/resolver.js +37 -0
- package/build/storage/resolver.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface EncryptResult {
|
|
2
|
+
ciphertext: Uint8Array;
|
|
3
|
+
iv: Uint8Array;
|
|
4
|
+
tag: Uint8Array;
|
|
5
|
+
}
|
|
6
|
+
export declare function encrypt(key: CryptoKey, plaintext: string): Promise<EncryptResult>;
|
|
7
|
+
export declare function decrypt(key: CryptoKey, ciphertext: Uint8Array, iv: Uint8Array, tag?: Uint8Array): Promise<string>;
|
|
8
|
+
//# sourceMappingURL=aes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aes.d.ts","sourceRoot":"","sources":["../../src/crypto/aes.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,UAAU,CAAA;IACtB,EAAE,EAAE,UAAU,CAAA;IACd,GAAG,EAAE,UAAU,CAAA;CAChB;AAED,wBAAsB,OAAO,CAAC,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAWvF;AAED,wBAAsB,OAAO,CAC3B,GAAG,EAAE,SAAS,EACd,UAAU,EAAE,UAAU,EACtB,EAAE,EAAE,UAAU,EACd,GAAG,CAAC,EAAE,UAAU,GACf,OAAO,CAAC,MAAM,CAAC,CAYjB"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export async function encrypt(key, plaintext) {
|
|
2
|
+
const iv = crypto.getRandomValues(new Uint8Array(12));
|
|
3
|
+
const encoded = new TextEncoder().encode(plaintext);
|
|
4
|
+
const encrypted = await crypto.subtle.encrypt({ name: 'AES-GCM', iv }, key, encoded);
|
|
5
|
+
// WebCrypto appends 16-byte GCM tag to ciphertext
|
|
6
|
+
const combined = new Uint8Array(encrypted);
|
|
7
|
+
const ciphertext = combined.slice(0, combined.length - 16);
|
|
8
|
+
const tag = combined.slice(combined.length - 16);
|
|
9
|
+
return { ciphertext, iv, tag };
|
|
10
|
+
}
|
|
11
|
+
export async function decrypt(key, ciphertext, iv, tag) {
|
|
12
|
+
let data;
|
|
13
|
+
if (tag) {
|
|
14
|
+
data = new Uint8Array(ciphertext.length + tag.length);
|
|
15
|
+
data.set(ciphertext, 0);
|
|
16
|
+
data.set(tag, ciphertext.length);
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
data = new Uint8Array(ciphertext);
|
|
20
|
+
}
|
|
21
|
+
const ivCopy = new Uint8Array(iv);
|
|
22
|
+
const decrypted = await crypto.subtle.decrypt({ name: 'AES-GCM', iv: ivCopy }, key, data);
|
|
23
|
+
return new TextDecoder().decode(decrypted);
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=aes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aes.js","sourceRoot":"","sources":["../../src/crypto/aes.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,GAAc,EAAE,SAAiB;IAC7D,MAAM,EAAE,GAAG,MAAM,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,CAAA;IACrD,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;IACnD,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;IAEpF,kDAAkD;IAClD,MAAM,QAAQ,GAAG,IAAI,UAAU,CAAC,SAAS,CAAC,CAAA;IAC1C,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,MAAM,GAAG,EAAE,CAAC,CAAA;IAC1D,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,EAAE,CAAC,CAAA;IAEhD,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,GAAG,EAAE,CAAA;AAChC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,GAAc,EACd,UAAsB,EACtB,EAAc,EACd,GAAgB;IAEhB,IAAI,IAA6B,CAAA;IACjC,IAAI,GAAG,EAAE,CAAC;QACR,IAAI,GAAG,IAAI,UAAU,CAAC,UAAU,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAAA;QACrD,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,CAAA;QACvB,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,MAAM,CAAC,CAAA;IAClC,CAAC;SAAM,CAAC;QACN,IAAI,GAAG,IAAI,UAAU,CAAC,UAAU,CAAC,CAAA;IACnC,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAA;IACjC,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IACzF,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;AAC5C,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function generateKeyPair(): Promise<CryptoKeyPair>;
|
|
2
|
+
export declare function exportPublicKey(key: CryptoKey): Promise<string>;
|
|
3
|
+
export declare function importPublicKey(base64url: string): Promise<CryptoKey>;
|
|
4
|
+
export declare function deriveSharedSecret(privateKey: CryptoKey, publicKey: CryptoKey): Promise<ArrayBuffer>;
|
|
5
|
+
//# sourceMappingURL=ecdh.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ecdh.d.ts","sourceRoot":"","sources":["../../src/crypto/ecdh.ts"],"names":[],"mappings":"AAEA,wBAAsB,eAAe,IAAI,OAAO,CAAC,aAAa,CAAC,CAE9D;AAED,wBAAsB,eAAe,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAGrE;AAED,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAG3E;AAED,wBAAsB,kBAAkB,CAAC,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CAE1G"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const ALGORITHM = { name: 'ECDH', namedCurve: 'P-256' };
|
|
2
|
+
export async function generateKeyPair() {
|
|
3
|
+
return crypto.subtle.generateKey(ALGORITHM, true, ['deriveKey', 'deriveBits']);
|
|
4
|
+
}
|
|
5
|
+
export async function exportPublicKey(key) {
|
|
6
|
+
const raw = await crypto.subtle.exportKey('raw', key);
|
|
7
|
+
return Buffer.from(raw).toString('base64url');
|
|
8
|
+
}
|
|
9
|
+
export async function importPublicKey(base64url) {
|
|
10
|
+
const raw = Buffer.from(base64url, 'base64url');
|
|
11
|
+
return crypto.subtle.importKey('raw', raw, ALGORITHM, true, []);
|
|
12
|
+
}
|
|
13
|
+
export async function deriveSharedSecret(privateKey, publicKey) {
|
|
14
|
+
return crypto.subtle.deriveBits({ name: 'ECDH', public: publicKey }, privateKey, 256);
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=ecdh.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ecdh.js","sourceRoot":"","sources":["../../src/crypto/ecdh.ts"],"names":[],"mappings":"AAAA,MAAM,SAAS,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,CAAA;AAEvD,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,OAAO,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAAA;AAChF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,GAAc;IAClD,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;IACrD,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;AAC/C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,SAAiB;IACrD,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAA;IAC/C,OAAO,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC,CAAA;AACjE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,UAAqB,EAAE,SAAoB;IAClF,OAAO,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,UAAU,EAAE,GAAG,CAAC,CAAA;AACvF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/crypto/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,aAAa,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AAC/D,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AACjG,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/crypto/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAsB,OAAO,EAAE,MAAM,UAAU,CAAA;AAC/D,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AACjG,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kdf.d.ts","sourceRoot":"","sources":["../../src/crypto/kdf.ts"],"names":[],"mappings":"AAEA,wBAAsB,YAAY,CAAC,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAWpG"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
const INFO = new TextEncoder().encode('mcp-relay');
|
|
2
|
+
export async function deriveAesKey(sharedSecret, passphrase) {
|
|
3
|
+
const salt = new TextEncoder().encode(passphrase);
|
|
4
|
+
const keyMaterial = await crypto.subtle.importKey('raw', sharedSecret, 'HKDF', false, ['deriveKey']);
|
|
5
|
+
return crypto.subtle.deriveKey({ name: 'HKDF', hash: 'SHA-256', salt, info: INFO }, keyMaterial, { name: 'AES-GCM', length: 256 }, true, ['encrypt', 'decrypt']);
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=kdf.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kdf.js","sourceRoot":"","sources":["../../src/crypto/kdf.ts"],"names":[],"mappings":"AAAA,MAAM,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;AAElD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,YAAyB,EAAE,UAAkB;IAC9E,MAAM,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;IACjD,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,WAAW,CAAC,CAAC,CAAA;IAEpG,OAAO,MAAM,CAAC,MAAM,CAAC,SAAS,CAC5B,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EACnD,WAAW,EACX,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,EAChC,IAAI,EACJ,CAAC,SAAS,EAAE,SAAS,CAAC,CACvB,CAAA;AACH,CAAC"}
|
package/build/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export * from './crypto/index.js';
|
|
2
|
+
export * from './storage/resolver.js';
|
|
3
|
+
export { readConfig, writeConfig, deleteConfig, listConfigs, exportConfig, importConfig, } from './storage/config-file.js';
|
|
4
|
+
export { createSession, pollForResult, generatePassphrase, type RelaySession, } from './relay/client.js';
|
|
5
|
+
export type * from './schema/types.js';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAA;AACjC,cAAc,uBAAuB,CAAA;AACrC,OAAO,EACL,UAAU,EACV,WAAW,EACX,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,YAAY,GACb,MAAM,0BAA0B,CAAA;AACjC,OAAO,EACL,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,KAAK,YAAY,GAClB,MAAM,mBAAmB,CAAA;AAC1B,mBAAmB,mBAAmB,CAAA"}
|
package/build/index.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export * from './crypto/index.js';
|
|
2
|
+
export * from './storage/resolver.js';
|
|
3
|
+
export { readConfig, writeConfig, deleteConfig, listConfigs, exportConfig, importConfig, } from './storage/config-file.js';
|
|
4
|
+
export { createSession, pollForResult, generatePassphrase, } from './relay/client.js';
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAA;AACjC,cAAc,uBAAuB,CAAA;AACrC,OAAO,EACL,UAAU,EACV,WAAW,EACX,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,YAAY,GACb,MAAM,0BAA0B,CAAA;AACjC,OAAO,EACL,aAAa,EACb,aAAa,EACb,kBAAkB,GAEnB,MAAM,mBAAmB,CAAA"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { RelayConfigSchema } from '../schema/types.js';
|
|
2
|
+
export declare function generatePassphrase(wordCount?: number): string;
|
|
3
|
+
export interface RelaySession {
|
|
4
|
+
sessionId: string;
|
|
5
|
+
keyPair: CryptoKeyPair;
|
|
6
|
+
passphrase: string;
|
|
7
|
+
relayUrl: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function createSession(relayBaseUrl: string, serverName: string, schema: RelayConfigSchema): Promise<RelaySession>;
|
|
10
|
+
export declare function pollForResult(relayBaseUrl: string, session: RelaySession, intervalMs?: number, timeoutMs?: number): Promise<Record<string, string>>;
|
|
11
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/relay/client.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAG3D,wBAAgB,kBAAkB,CAAC,SAAS,SAAI,GAAG,MAAM,CAWxD;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,aAAa,CAAA;IACtB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,wBAAsB,aAAa,CACjC,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,iBAAiB,GACxB,OAAO,CAAC,YAAY,CAAC,CAgBvB;AAED,wBAAsB,aAAa,CACjC,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,YAAY,EACrB,UAAU,SAAO,EACjB,SAAS,SAAU,GAClB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAgCjC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { generateKeyPair, exportPublicKey, importPublicKey, deriveSharedSecret } from '../crypto/ecdh.js';
|
|
2
|
+
import { deriveAesKey } from '../crypto/kdf.js';
|
|
3
|
+
import { decrypt } from '../crypto/aes.js';
|
|
4
|
+
import { WORDLIST } from './wordlist.js';
|
|
5
|
+
export function generatePassphrase(wordCount = 4) {
|
|
6
|
+
const words = [];
|
|
7
|
+
const max = Math.floor(0x10000 / WORDLIST.length) * WORDLIST.length; // rejection threshold
|
|
8
|
+
for (let i = 0; i < wordCount; i++) {
|
|
9
|
+
let index;
|
|
10
|
+
do {
|
|
11
|
+
index = crypto.getRandomValues(new Uint16Array(1))[0];
|
|
12
|
+
} while (index >= max); // reject biased values
|
|
13
|
+
words.push(WORDLIST[index % WORDLIST.length]);
|
|
14
|
+
}
|
|
15
|
+
return words.join('-');
|
|
16
|
+
}
|
|
17
|
+
export async function createSession(relayBaseUrl, serverName, schema) {
|
|
18
|
+
const sessionId = Buffer.from(crypto.getRandomValues(new Uint8Array(32))).toString('hex');
|
|
19
|
+
const keyPair = await generateKeyPair();
|
|
20
|
+
const passphrase = generatePassphrase();
|
|
21
|
+
const response = await fetch(`${relayBaseUrl}/api/sessions`, {
|
|
22
|
+
method: 'POST',
|
|
23
|
+
headers: { 'Content-Type': 'application/json' },
|
|
24
|
+
body: JSON.stringify({ sessionId, serverName, schema }),
|
|
25
|
+
});
|
|
26
|
+
if (!response.ok)
|
|
27
|
+
throw new Error(`Relay session creation failed: ${response.status}`);
|
|
28
|
+
const pubKeyBase64 = await exportPublicKey(keyPair.publicKey);
|
|
29
|
+
const relayUrl = `${relayBaseUrl}/setup?s=${sessionId}#k=${pubKeyBase64}&p=${encodeURIComponent(passphrase)}`;
|
|
30
|
+
return { sessionId, keyPair, passphrase, relayUrl };
|
|
31
|
+
}
|
|
32
|
+
export async function pollForResult(relayBaseUrl, session, intervalMs = 2000, timeoutMs = 600_000) {
|
|
33
|
+
const deadline = Date.now() + timeoutMs;
|
|
34
|
+
while (Date.now() < deadline) {
|
|
35
|
+
const response = await fetch(`${relayBaseUrl}/api/sessions/${session.sessionId}`);
|
|
36
|
+
if (response.status === 200) {
|
|
37
|
+
const { browserPub, ciphertext, iv, tag } = await response.json();
|
|
38
|
+
const browserKey = await importPublicKey(browserPub);
|
|
39
|
+
const sharedSecret = await deriveSharedSecret(session.keyPair.privateKey, browserKey);
|
|
40
|
+
const aesKey = await deriveAesKey(sharedSecret, session.passphrase);
|
|
41
|
+
const plaintext = await decrypt(aesKey, new Uint8Array(Buffer.from(ciphertext, 'base64')), new Uint8Array(Buffer.from(iv, 'base64')), new Uint8Array(Buffer.from(tag, 'base64')));
|
|
42
|
+
// Cleanup session
|
|
43
|
+
await fetch(`${relayBaseUrl}/api/sessions/${session.sessionId}`, { method: 'DELETE' }).catch(() => { });
|
|
44
|
+
return JSON.parse(plaintext);
|
|
45
|
+
}
|
|
46
|
+
if (response.status === 404)
|
|
47
|
+
throw new Error('Session expired or not found');
|
|
48
|
+
if (response.status !== 202)
|
|
49
|
+
throw new Error(`Unexpected status: ${response.status}`);
|
|
50
|
+
await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
|
51
|
+
}
|
|
52
|
+
throw new Error('Relay setup timed out');
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/relay/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AACzG,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAE1C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAExC,MAAM,UAAU,kBAAkB,CAAC,SAAS,GAAG,CAAC;IAC9C,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAA,CAAC,sBAAsB;IAC1F,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,IAAI,KAAa,CAAA;QACjB,GAAG,CAAC;YACF,KAAK,GAAG,MAAM,CAAC,eAAe,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QACvD,CAAC,QAAQ,KAAK,IAAI,GAAG,EAAC,CAAC,uBAAuB;QAC9C,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAA;IAC/C,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AACxB,CAAC;AASD,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,YAAoB,EACpB,UAAkB,EAClB,MAAyB;IAEzB,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IACzF,MAAM,OAAO,GAAG,MAAM,eAAe,EAAE,CAAA;IACvC,MAAM,UAAU,GAAG,kBAAkB,EAAE,CAAA;IAEvC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,YAAY,eAAe,EAAE;QAC3D,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;KACxD,CAAC,CAAA;IACF,IAAI,CAAC,QAAQ,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;IAEtF,MAAM,YAAY,GAAG,MAAM,eAAe,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IAC7D,MAAM,QAAQ,GAAG,GAAG,YAAY,YAAY,SAAS,MAAM,YAAY,MAAM,kBAAkB,CAAC,UAAU,CAAC,EAAE,CAAA;IAE7G,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAA;AACrD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,YAAoB,EACpB,OAAqB,EACrB,UAAU,GAAG,IAAI,EACjB,SAAS,GAAG,OAAO;IAEnB,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAA;IAEvC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,YAAY,iBAAiB,OAAO,CAAC,SAAS,EAAE,CAAC,CAAA;QACjF,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5B,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;YAEjE,MAAM,UAAU,GAAG,MAAM,eAAe,CAAC,UAAU,CAAC,CAAA;YACpD,MAAM,YAAY,GAAG,MAAM,kBAAkB,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,UAAU,CAAC,CAAA;YACrF,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,UAAU,CAAC,CAAA;YACnE,MAAM,SAAS,GAAG,MAAM,OAAO,CAC7B,MAAM,EACN,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,EACjD,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC,EACzC,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAC3C,CAAA;YAED,kBAAkB;YAClB,MAAM,KAAK,CAAC,GAAG,YAAY,iBAAiB,OAAO,CAAC,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,KAAK,CAC1F,GAAG,EAAE,GAAE,CAAC,CACT,CAAA;YAED,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;QAC9B,CAAC;QACD,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAA;QAC5E,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;QAErF,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAA;IACjE,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAA;AAC1C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wordlist.d.ts","sourceRoot":"","sources":["../../src/relay/wordlist.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,QAAQ,EAAE,MAAM,EA68B5B,CAAA"}
|