@terminal3/t3n-sdk 0.12.1 → 0.13.1

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 CHANGED
@@ -129,7 +129,7 @@ new T3nClient(config: T3nClientConfig)
129
129
 
130
130
  - `startHandshake(): Promise<void>` - Establish secure session with the node
131
131
  - `authenticate(authInput: AuthInput): Promise<Did>` - Authenticate using provided credentials
132
- - `getSessionId(): SessionId` - Get current session ID
132
+ - `getSessionId(): SessionId | null` - Get the server-minted session ID (`null` until handshake completes; pentest M-1 / MAT-983 moved session-id minting from the client to the server)
133
133
  - `getStatus(): SessionStatus` - Get current session status
134
134
  - `getDid(): Did | null` - Get authenticated DID (null if not authenticated)
135
135
  - `isAuthenticated(): boolean` - Check if client is authenticated
package/dist/demo.d.ts CHANGED
@@ -12,7 +12,7 @@ declare global {
12
12
  interface DemoResult {
13
13
  sessionId: {
14
14
  value: string;
15
- };
15
+ } | null;
16
16
  status: SessionStatus;
17
17
  wasmLoaded: boolean;
18
18
  authenticated: boolean;
package/dist/index.d.ts CHANGED
@@ -444,15 +444,25 @@ declare class HttpTransport implements Transport {
444
444
  */
445
445
  declare class MockTransport implements Transport {
446
446
  private responses;
447
+ private responseHeaders;
448
+ private lastResponseHeaders;
447
449
  private requests;
448
450
  /**
449
451
  * Mock a response for a specific method
450
452
  */
451
453
  mockResponse(method: string, response: Partial<JsonRpcResponse>): void;
454
+ /**
455
+ * Mock response headers for a specific method. Used by tests to
456
+ * simulate the server-minted `Session-Id` header the SDK picks up
457
+ * from the `auth.handshake` response (MAT-983). Unset methods
458
+ * default to no headers.
459
+ */
460
+ mockResponseHeaders(method: string, headers: Record<string, string>): void;
452
461
  /**
453
462
  * Mock an error response for a specific method
454
463
  */
455
464
  mockError(method: string, code: number, message: string, data?: unknown): void;
465
+ getLastResponseHeaders(): Record<string, string>;
456
466
  /**
457
467
  * Get all requests that were sent
458
468
  */
@@ -488,8 +498,6 @@ interface T3nClientConfig {
488
498
  wasmComponent: WasmComponent;
489
499
  /** Optional transport layer - if not provided, uses HttpTransport with baseUrl */
490
500
  transport?: Transport;
491
- /** Optional session ID - will be generated if not provided */
492
- sessionId?: SessionId;
493
501
  /** Optional request timeout in milliseconds (default: 30000) - used for HttpTransport */
494
502
  timeout?: number;
495
503
  /** Optional custom headers to include in requests */
@@ -520,7 +528,22 @@ interface T3nClientConfig {
520
528
  declare class T3nClient {
521
529
  private readonly config;
522
530
  private readonly transport;
523
- private readonly sessionId;
531
+ /**
532
+ * Server-minted session ID, set by {@link handshake} from the
533
+ * `Session-Id` response header (pentest M-1 / MAT-983). `null`
534
+ * until the handshake completes. Client code cannot set it — the
535
+ * former `config.sessionId` hook was the session-fixation vector
536
+ * this fix closes.
537
+ */
538
+ private sessionId;
539
+ /**
540
+ * Set by {@link sendRpcRequest} when an `auth.handshake` RPC is
541
+ * actually issued. Decouples the "flow completed without talking
542
+ * to a server" case (unit-test mocks that only exercise handler
543
+ * delegation) from the real "server must mint the id" invariant:
544
+ * we only enforce the mint requirement when a round-trip happened.
545
+ */
546
+ private handshakeSentRpc;
524
547
  private readonly logger;
525
548
  private readonly encryption;
526
549
  private status;
@@ -579,7 +602,11 @@ declare class T3nClient {
579
602
  * Execute an action on the T3n node
580
603
  */
581
604
  execute(payload: unknown): Promise<string>;
582
- getSessionId(): SessionId;
605
+ /**
606
+ * The server-minted session ID once handshake has completed, or
607
+ * `null` beforehand (pentest M-1 / MAT-983).
608
+ */
609
+ getSessionId(): SessionId | null;
583
610
  getStatus(): SessionStatus;
584
611
  getDid(): Did | null;
585
612
  getLastSetCookie(): string | null;
@@ -637,6 +664,16 @@ declare class T3nClient {
637
664
  * Send an RPC request with automatic encryption/decryption
638
665
  */
639
666
  private sendRpcRequest;
667
+ /**
668
+ * Capture the server-minted `Session-Id` from the last handshake
669
+ * response headers (pentest M-1 / MAT-983). Validates shape so a
670
+ * broken or MITM'd response fails loudly instead of leaving a
671
+ * garbage value in the client. Idempotent: only the first valid
672
+ * mint per session is honoured — subsequent handshake RPC legs
673
+ * (none exist today, but the state-machine loop can iterate) do
674
+ * not overwrite an already-set value.
675
+ */
676
+ private captureMintedSessionId;
640
677
  /**
641
678
  * Get the finalized session blob (for `session.encrypt` calls).
642
679
  * Populated by `tryFinalize` once the handshake state machine