@antzsoft/chat-core 1.4.7 → 1.4.8

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/dist/index.d.cts CHANGED
@@ -12,6 +12,15 @@ declare const authApi: {
12
12
  login(credentials: LoginCredentials): Promise<AuthResponse>;
13
13
  register(payload: RegisterData): Promise<AuthResponse>;
14
14
  refresh(refreshToken: string): Promise<AuthTokens>;
15
+ /**
16
+ * Ends the session. Never blocks on the transit handshake: logout has to work
17
+ * on a degraded channel, which is exactly when it matters most.
18
+ *
19
+ * The refreshToken is dropped when no transit session exists, so it is never
20
+ * sent in the clear. Losing it costs nothing meaningful — the server revokes
21
+ * against the JWT's own user id either way; passing it only lets the server
22
+ * target that one refresh token instead of the caller's session set.
23
+ */
15
24
  logout(refreshToken?: string): Promise<void>;
16
25
  logoutAll(): Promise<void>;
17
26
  getMe(): Promise<User>;
@@ -327,6 +336,28 @@ type TokenStore = {
327
336
  };
328
337
  declare function setAuthReadyPromise(promise: Promise<unknown> | null): void;
329
338
  declare function isApiClientConfigured(): boolean;
339
+ /**
340
+ * Per-request opt-out of the transit GATE (not of transit itself).
341
+ *
342
+ * Set via `{ headers: { [TRANSIT_OPTIONAL_HEADER]: '1' } }` on the axios call.
343
+ * A request marked this way still encrypts normally whenever a session happens
344
+ * to be ready — it simply refuses to BLOCK waiting for one, and goes out
345
+ * unencrypted rather than failing when the channel is down.
346
+ *
347
+ * This exists for teardown calls (logout, logout-all, device de-registration).
348
+ * Those must succeed precisely when the secure channel is degraded: a control
349
+ * that prevents a user from ending their own session is inverted. Their server
350
+ * routes are marked @PreTransit() so they accept an unencrypted request, and
351
+ * JwtAuthGuard still authenticates them — transit is a confidentiality layer,
352
+ * never an authenticity one (POST /crypto/session is itself unauthenticated, so
353
+ * holding a transit session proves nothing about the caller).
354
+ *
355
+ * Do NOT add this to ordinary routes: they are not @PreTransit() server-side and
356
+ * would 403 with "Transit encryption required" the moment the gate is skipped.
357
+ *
358
+ * The marker header is stripped before the request leaves the client.
359
+ */
360
+ declare const TRANSIT_OPTIONAL_HEADER = "x-antz-transit-optional";
330
361
  declare function initApiClient(config: ResolvedConfig, tokenStore: TokenStore): AxiosInstance;
331
362
  declare function setApiClientInstance(instance: AxiosInstance): void;
332
363
  declare function getApiClient(): AxiosInstance;
@@ -856,4 +887,4 @@ declare class AntzChatClient {
856
887
  uploadIcon(conversationId: string, file: UploadableFile): Promise<Conversation>;
857
888
  }
858
889
 
859
- export { AntzChatAuthError, AntzChatClient, AntzChatConfig, AntzChatError, AntzChatNetworkError, AntzChatPermissionError, AntzChatServerError, AntzChatValidationError, AppConfig, AuthResponse, AuthTokens, BatchUploadResult, CompletedPart, Conversation, ConversationListParams, ConversationSyncResponse, ConversationUnreadCount, type CreateDirectData, type CreateGroupData, CrossConversationSyncResponse, CursorPaginatedResponse, FileResponse, FileType, ForwardAckPayload, ForwardMessagePayload, type ForwardResult, HIGHLY_FORWARDED_DEPTH_THRESHOLD, type LastReadEntry, type ListMessagesParams, LoginCredentials, MAX_FORWARD_TARGETS, type MentionPart, type MentionSegment, Message, MessageReactionsResponse, MessageReceiptsResponse, type MobileDeviceToken, PaginatedResponse, type ParsedMention, Participant, PersistStorage, PresignedUrlRequest, PresignedUrlResponse, RegisterData, type RegisterDeviceTokenPayload, ResolvedCompressionConfig, ResolvedConfig, type SearchParams, type SendData, SendMessagePayload, type SocketStatus, type StatusListener, type TokenStore, type TransitIdentity, TransitRateLimitedError, UnreadSummary, type UpdateConversationData, type UpdateProfilePayload, UploadableFile, User, UserPreferences, type WebPushDeviceToken, appConfigApi, authApi, buildMentionText, connectSocket, conversationsApi, createAuthStore, createRestTransitSession, decryptPayload, devicesApi, disconnectSocket, encryptPayload, extractMentionIds, fetchServerKeys, generateEphemeralKey, getApiClient, getAuthStore, getCompressionStrategy, getSessionId, getSessionKey, getSocket, getSocketStatus, initApiClient, initAuthStore, isApiClientConfigured, isMentionAll, isTransitEnvelope, messagesApi, normalizeAxiosError, normalizeConversation, onSocketStatus, parseMentions, performHandshake, readRetryAfterMs, reconnectSocket, refreshSocketAuth, registerTeardownHook, renderMentionParts, resetAuthStore, resetTrackedRooms, resetTypingThrottle, resolveSystemMessageText, setApiClientInstance, setAuthReadyPromise, setTransitSession, socketEmit, syncApi, tryGetSocket, useChatStore, usersApi };
890
+ export { AntzChatAuthError, AntzChatClient, AntzChatConfig, AntzChatError, AntzChatNetworkError, AntzChatPermissionError, AntzChatServerError, AntzChatValidationError, AppConfig, AuthResponse, AuthTokens, BatchUploadResult, CompletedPart, Conversation, ConversationListParams, ConversationSyncResponse, ConversationUnreadCount, type CreateDirectData, type CreateGroupData, CrossConversationSyncResponse, CursorPaginatedResponse, FileResponse, FileType, ForwardAckPayload, ForwardMessagePayload, type ForwardResult, HIGHLY_FORWARDED_DEPTH_THRESHOLD, type LastReadEntry, type ListMessagesParams, LoginCredentials, MAX_FORWARD_TARGETS, type MentionPart, type MentionSegment, Message, MessageReactionsResponse, MessageReceiptsResponse, type MobileDeviceToken, PaginatedResponse, type ParsedMention, Participant, PersistStorage, PresignedUrlRequest, PresignedUrlResponse, RegisterData, type RegisterDeviceTokenPayload, ResolvedCompressionConfig, ResolvedConfig, type SearchParams, type SendData, SendMessagePayload, type SocketStatus, type StatusListener, TRANSIT_OPTIONAL_HEADER, type TokenStore, type TransitIdentity, TransitRateLimitedError, UnreadSummary, type UpdateConversationData, type UpdateProfilePayload, UploadableFile, User, UserPreferences, type WebPushDeviceToken, appConfigApi, authApi, buildMentionText, connectSocket, conversationsApi, createAuthStore, createRestTransitSession, decryptPayload, devicesApi, disconnectSocket, encryptPayload, extractMentionIds, fetchServerKeys, generateEphemeralKey, getApiClient, getAuthStore, getCompressionStrategy, getSessionId, getSessionKey, getSocket, getSocketStatus, initApiClient, initAuthStore, isApiClientConfigured, isMentionAll, isTransitEnvelope, messagesApi, normalizeAxiosError, normalizeConversation, onSocketStatus, parseMentions, performHandshake, readRetryAfterMs, reconnectSocket, refreshSocketAuth, registerTeardownHook, renderMentionParts, resetAuthStore, resetTrackedRooms, resetTypingThrottle, resolveSystemMessageText, setApiClientInstance, setAuthReadyPromise, setTransitSession, socketEmit, syncApi, tryGetSocket, useChatStore, usersApi };
package/dist/index.d.ts CHANGED
@@ -12,6 +12,15 @@ declare const authApi: {
12
12
  login(credentials: LoginCredentials): Promise<AuthResponse>;
13
13
  register(payload: RegisterData): Promise<AuthResponse>;
14
14
  refresh(refreshToken: string): Promise<AuthTokens>;
15
+ /**
16
+ * Ends the session. Never blocks on the transit handshake: logout has to work
17
+ * on a degraded channel, which is exactly when it matters most.
18
+ *
19
+ * The refreshToken is dropped when no transit session exists, so it is never
20
+ * sent in the clear. Losing it costs nothing meaningful — the server revokes
21
+ * against the JWT's own user id either way; passing it only lets the server
22
+ * target that one refresh token instead of the caller's session set.
23
+ */
15
24
  logout(refreshToken?: string): Promise<void>;
16
25
  logoutAll(): Promise<void>;
17
26
  getMe(): Promise<User>;
@@ -327,6 +336,28 @@ type TokenStore = {
327
336
  };
328
337
  declare function setAuthReadyPromise(promise: Promise<unknown> | null): void;
329
338
  declare function isApiClientConfigured(): boolean;
339
+ /**
340
+ * Per-request opt-out of the transit GATE (not of transit itself).
341
+ *
342
+ * Set via `{ headers: { [TRANSIT_OPTIONAL_HEADER]: '1' } }` on the axios call.
343
+ * A request marked this way still encrypts normally whenever a session happens
344
+ * to be ready — it simply refuses to BLOCK waiting for one, and goes out
345
+ * unencrypted rather than failing when the channel is down.
346
+ *
347
+ * This exists for teardown calls (logout, logout-all, device de-registration).
348
+ * Those must succeed precisely when the secure channel is degraded: a control
349
+ * that prevents a user from ending their own session is inverted. Their server
350
+ * routes are marked @PreTransit() so they accept an unencrypted request, and
351
+ * JwtAuthGuard still authenticates them — transit is a confidentiality layer,
352
+ * never an authenticity one (POST /crypto/session is itself unauthenticated, so
353
+ * holding a transit session proves nothing about the caller).
354
+ *
355
+ * Do NOT add this to ordinary routes: they are not @PreTransit() server-side and
356
+ * would 403 with "Transit encryption required" the moment the gate is skipped.
357
+ *
358
+ * The marker header is stripped before the request leaves the client.
359
+ */
360
+ declare const TRANSIT_OPTIONAL_HEADER = "x-antz-transit-optional";
330
361
  declare function initApiClient(config: ResolvedConfig, tokenStore: TokenStore): AxiosInstance;
331
362
  declare function setApiClientInstance(instance: AxiosInstance): void;
332
363
  declare function getApiClient(): AxiosInstance;
@@ -856,4 +887,4 @@ declare class AntzChatClient {
856
887
  uploadIcon(conversationId: string, file: UploadableFile): Promise<Conversation>;
857
888
  }
858
889
 
859
- export { AntzChatAuthError, AntzChatClient, AntzChatConfig, AntzChatError, AntzChatNetworkError, AntzChatPermissionError, AntzChatServerError, AntzChatValidationError, AppConfig, AuthResponse, AuthTokens, BatchUploadResult, CompletedPart, Conversation, ConversationListParams, ConversationSyncResponse, ConversationUnreadCount, type CreateDirectData, type CreateGroupData, CrossConversationSyncResponse, CursorPaginatedResponse, FileResponse, FileType, ForwardAckPayload, ForwardMessagePayload, type ForwardResult, HIGHLY_FORWARDED_DEPTH_THRESHOLD, type LastReadEntry, type ListMessagesParams, LoginCredentials, MAX_FORWARD_TARGETS, type MentionPart, type MentionSegment, Message, MessageReactionsResponse, MessageReceiptsResponse, type MobileDeviceToken, PaginatedResponse, type ParsedMention, Participant, PersistStorage, PresignedUrlRequest, PresignedUrlResponse, RegisterData, type RegisterDeviceTokenPayload, ResolvedCompressionConfig, ResolvedConfig, type SearchParams, type SendData, SendMessagePayload, type SocketStatus, type StatusListener, type TokenStore, type TransitIdentity, TransitRateLimitedError, UnreadSummary, type UpdateConversationData, type UpdateProfilePayload, UploadableFile, User, UserPreferences, type WebPushDeviceToken, appConfigApi, authApi, buildMentionText, connectSocket, conversationsApi, createAuthStore, createRestTransitSession, decryptPayload, devicesApi, disconnectSocket, encryptPayload, extractMentionIds, fetchServerKeys, generateEphemeralKey, getApiClient, getAuthStore, getCompressionStrategy, getSessionId, getSessionKey, getSocket, getSocketStatus, initApiClient, initAuthStore, isApiClientConfigured, isMentionAll, isTransitEnvelope, messagesApi, normalizeAxiosError, normalizeConversation, onSocketStatus, parseMentions, performHandshake, readRetryAfterMs, reconnectSocket, refreshSocketAuth, registerTeardownHook, renderMentionParts, resetAuthStore, resetTrackedRooms, resetTypingThrottle, resolveSystemMessageText, setApiClientInstance, setAuthReadyPromise, setTransitSession, socketEmit, syncApi, tryGetSocket, useChatStore, usersApi };
890
+ export { AntzChatAuthError, AntzChatClient, AntzChatConfig, AntzChatError, AntzChatNetworkError, AntzChatPermissionError, AntzChatServerError, AntzChatValidationError, AppConfig, AuthResponse, AuthTokens, BatchUploadResult, CompletedPart, Conversation, ConversationListParams, ConversationSyncResponse, ConversationUnreadCount, type CreateDirectData, type CreateGroupData, CrossConversationSyncResponse, CursorPaginatedResponse, FileResponse, FileType, ForwardAckPayload, ForwardMessagePayload, type ForwardResult, HIGHLY_FORWARDED_DEPTH_THRESHOLD, type LastReadEntry, type ListMessagesParams, LoginCredentials, MAX_FORWARD_TARGETS, type MentionPart, type MentionSegment, Message, MessageReactionsResponse, MessageReceiptsResponse, type MobileDeviceToken, PaginatedResponse, type ParsedMention, Participant, PersistStorage, PresignedUrlRequest, PresignedUrlResponse, RegisterData, type RegisterDeviceTokenPayload, ResolvedCompressionConfig, ResolvedConfig, type SearchParams, type SendData, SendMessagePayload, type SocketStatus, type StatusListener, TRANSIT_OPTIONAL_HEADER, type TokenStore, type TransitIdentity, TransitRateLimitedError, UnreadSummary, type UpdateConversationData, type UpdateProfilePayload, UploadableFile, User, UserPreferences, type WebPushDeviceToken, appConfigApi, authApi, buildMentionText, connectSocket, conversationsApi, createAuthStore, createRestTransitSession, decryptPayload, devicesApi, disconnectSocket, encryptPayload, extractMentionIds, fetchServerKeys, generateEphemeralKey, getApiClient, getAuthStore, getCompressionStrategy, getSessionId, getSessionKey, getSocket, getSocketStatus, initApiClient, initAuthStore, isApiClientConfigured, isMentionAll, isTransitEnvelope, messagesApi, normalizeAxiosError, normalizeConversation, onSocketStatus, parseMentions, performHandshake, readRetryAfterMs, reconnectSocket, refreshSocketAuth, registerTeardownHook, renderMentionParts, resetAuthStore, resetTrackedRooms, resetTypingThrottle, resolveSystemMessageText, setApiClientInstance, setAuthReadyPromise, setTransitSession, socketEmit, syncApi, tryGetSocket, useChatStore, usersApi };
package/dist/index.js CHANGED
@@ -5,6 +5,7 @@ import {
5
5
  AntzChatPermissionError,
6
6
  AntzChatServerError,
7
7
  AntzChatValidationError,
8
+ TRANSIT_OPTIONAL_HEADER,
8
9
  TransitRateLimitedError,
9
10
  awaitTransitReadyOr,
10
11
  clearTransitSession,
@@ -38,7 +39,7 @@ import {
38
39
  setTransitSession,
39
40
  storageApi,
40
41
  uploadBatch
41
- } from "./chunk-U637W5MD.js";
42
+ } from "./chunk-L537XWRD.js";
42
43
  import {
43
44
  useChatStore
44
45
  } from "./chunk-QHELYVNT.js";
@@ -105,6 +106,7 @@ function resolveConfig(config) {
105
106
  }
106
107
 
107
108
  // src/api/auth.ts
109
+ var teardownRequest = { headers: { [TRANSIT_OPTIONAL_HEADER]: "1" } };
108
110
  var authApi = {
109
111
  async login(credentials) {
110
112
  const { data } = await getApiClient().post("/auth/login", credentials);
@@ -118,11 +120,22 @@ var authApi = {
118
120
  const { data } = await getApiClient().post("/auth/refresh", { refreshToken });
119
121
  return data;
120
122
  },
123
+ /**
124
+ * Ends the session. Never blocks on the transit handshake: logout has to work
125
+ * on a degraded channel, which is exactly when it matters most.
126
+ *
127
+ * The refreshToken is dropped when no transit session exists, so it is never
128
+ * sent in the clear. Losing it costs nothing meaningful — the server revokes
129
+ * against the JWT's own user id either way; passing it only lets the server
130
+ * target that one refresh token instead of the caller's session set.
131
+ */
121
132
  async logout(refreshToken) {
122
- await getApiClient().post("/auth/logout", refreshToken ? { refreshToken } : {});
133
+ const encrypted = getTransitSession() != null;
134
+ const body = refreshToken && encrypted ? { refreshToken } : {};
135
+ await getApiClient().post("/auth/logout", body, teardownRequest);
123
136
  },
124
137
  async logoutAll() {
125
- await getApiClient().post("/auth/logout-all");
138
+ await getApiClient().post("/auth/logout-all", {}, teardownRequest);
126
139
  },
127
140
  async getMe() {
128
141
  const { data } = await getApiClient().get("/users/me");
@@ -1202,7 +1215,9 @@ var devicesApi = {
1202
1215
  * Call this on logout so the user stops receiving push notifications on this device.
1203
1216
  */
1204
1217
  async remove(deviceId) {
1205
- await getApiClient().post(`/users/me/devices/${deviceId}/remove`);
1218
+ await getApiClient().post(`/users/me/devices/${deviceId}/remove`, {}, {
1219
+ headers: { [TRANSIT_OPTIONAL_HEADER]: "1" }
1220
+ });
1206
1221
  }
1207
1222
  };
1208
1223
 
@@ -1388,6 +1403,7 @@ export {
1388
1403
  HIGHLY_FORWARDED_DEPTH_THRESHOLD,
1389
1404
  MAX_FORWARD_TARGETS,
1390
1405
  MENTION_ALL_ID,
1406
+ TRANSIT_OPTIONAL_HEADER,
1391
1407
  TransitRateLimitedError,
1392
1408
  appConfigApi,
1393
1409
  authApi,