rehive 4.2.0 → 4.2.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.
Files changed (274) hide show
  1. package/README.md +17 -0
  2. package/dist/admin.d.mts +614 -116
  3. package/dist/admin.d.ts +614 -116
  4. package/dist/admin.js +1 -1
  5. package/dist/admin.mjs +1 -1
  6. package/dist/auth.d.mts +2 -2
  7. package/dist/auth.d.ts +2 -2
  8. package/dist/auth.js +1 -1
  9. package/dist/auth.mjs +1 -1
  10. package/dist/{chunk-PCR54D6A.mjs → chunk-A53KSFBA.mjs} +1 -1
  11. package/dist/chunk-CRNPJD3E.js +6 -0
  12. package/dist/{chunk-ERD2XKSM.js → chunk-HXAEBUQM.js} +1 -1
  13. package/dist/chunk-IJBXROTB.mjs +6 -0
  14. package/dist/chunk-OV77OD2G.js +1 -0
  15. package/dist/chunk-RO2QGTSG.mjs +1 -0
  16. package/dist/chunk-TAABJLJG.mjs +6 -0
  17. package/dist/chunk-Y33FT632.js +6 -0
  18. package/dist/{create-api-client-B4Q01gHp.d.mts → create-api-client-Bkkri-AM.d.mts} +1 -1
  19. package/dist/{create-api-client-ADSlg8HX.d.ts → create-api-client-CgvKBlQ_.d.ts} +1 -1
  20. package/dist/{create-auth-CT_IFt3T.d.mts → create-auth-ChOASbvo.d.mts} +111 -100
  21. package/dist/{create-auth-CT_IFt3T.d.ts → create-auth-ChOASbvo.d.ts} +111 -100
  22. package/dist/extensions/alchemy.d.mts +175 -41
  23. package/dist/extensions/alchemy.d.ts +175 -41
  24. package/dist/extensions/alchemy.js +5 -6
  25. package/dist/extensions/alchemy.mjs +5 -6
  26. package/dist/extensions/app.d.mts +11 -10
  27. package/dist/extensions/app.d.ts +11 -10
  28. package/dist/extensions/app.js +5 -6
  29. package/dist/extensions/app.mjs +5 -6
  30. package/dist/extensions/billing.d.mts +11 -10
  31. package/dist/extensions/billing.d.ts +11 -10
  32. package/dist/extensions/billing.js +5 -6
  33. package/dist/extensions/billing.mjs +5 -6
  34. package/dist/extensions/bridge.d.mts +537 -38
  35. package/dist/extensions/bridge.d.ts +537 -38
  36. package/dist/extensions/bridge.js +5 -6
  37. package/dist/extensions/bridge.mjs +5 -6
  38. package/dist/extensions/builder.d.mts +8 -7
  39. package/dist/extensions/builder.d.ts +8 -7
  40. package/dist/extensions/builder.js +5 -6
  41. package/dist/extensions/builder.mjs +5 -6
  42. package/dist/extensions/business.d.mts +99 -63
  43. package/dist/extensions/business.d.ts +99 -63
  44. package/dist/extensions/business.js +5 -6
  45. package/dist/extensions/business.mjs +5 -6
  46. package/dist/extensions/conversion.d.mts +10 -9
  47. package/dist/extensions/conversion.d.ts +10 -9
  48. package/dist/extensions/conversion.js +5 -6
  49. package/dist/extensions/conversion.mjs +5 -6
  50. package/dist/extensions/mass-send.d.mts +8 -7
  51. package/dist/extensions/mass-send.d.ts +8 -7
  52. package/dist/extensions/mass-send.js +5 -6
  53. package/dist/extensions/mass-send.mjs +5 -6
  54. package/dist/extensions/notifications.d.mts +16 -15
  55. package/dist/extensions/notifications.d.ts +16 -15
  56. package/dist/extensions/notifications.js +5 -6
  57. package/dist/extensions/notifications.mjs +5 -6
  58. package/dist/extensions/payment-requests.d.mts +15 -10
  59. package/dist/extensions/payment-requests.d.ts +15 -10
  60. package/dist/extensions/payment-requests.js +5 -6
  61. package/dist/extensions/payment-requests.mjs +5 -6
  62. package/dist/extensions/products.d.mts +43 -42
  63. package/dist/extensions/products.d.ts +43 -42
  64. package/dist/extensions/products.js +5 -6
  65. package/dist/extensions/products.mjs +5 -6
  66. package/dist/extensions/rain.d.mts +22 -21
  67. package/dist/extensions/rain.d.ts +22 -21
  68. package/dist/extensions/rain.js +5 -6
  69. package/dist/extensions/rain.mjs +5 -6
  70. package/dist/extensions/rewards.d.mts +8 -7
  71. package/dist/extensions/rewards.d.ts +8 -7
  72. package/dist/extensions/rewards.js +5 -6
  73. package/dist/extensions/rewards.mjs +5 -6
  74. package/dist/extensions/stellar-testnet.d.mts +16 -15
  75. package/dist/extensions/stellar-testnet.d.ts +16 -15
  76. package/dist/extensions/stellar-testnet.js +5 -6
  77. package/dist/extensions/stellar-testnet.mjs +5 -6
  78. package/dist/extensions/stellar.d.mts +16 -15
  79. package/dist/extensions/stellar.d.ts +16 -15
  80. package/dist/extensions/stellar.js +5 -6
  81. package/dist/extensions/stellar.mjs +5 -6
  82. package/dist/index.d.mts +2 -2
  83. package/dist/index.d.ts +2 -2
  84. package/dist/index.js +1 -1
  85. package/dist/index.mjs +1 -1
  86. package/dist/react.d.mts +3 -11
  87. package/dist/react.d.ts +3 -11
  88. package/dist/react.js +1 -1
  89. package/dist/react.mjs +1 -1
  90. package/dist/user.d.mts +21 -10
  91. package/dist/user.d.ts +21 -10
  92. package/dist/user.js +1 -1
  93. package/dist/user.mjs +1 -1
  94. package/package.json +1 -1
  95. package/src/auth/create-auth.ts +184 -781
  96. package/src/auth/index.ts +2 -25
  97. package/src/auth/types/index.ts +0 -48
  98. package/src/extensions/alchemy/openapi-ts/client/client.gen.ts +17 -7
  99. package/src/extensions/alchemy/openapi-ts/client/types.gen.ts +2 -1
  100. package/src/extensions/alchemy/openapi-ts/client/utils.gen.ts +1 -1
  101. package/src/extensions/alchemy/openapi-ts/core/bodySerializer.gen.ts +6 -8
  102. package/src/extensions/alchemy/openapi-ts/core/params.gen.ts +1 -1
  103. package/src/extensions/alchemy/openapi-ts/core/serverSentEvents.gen.ts +4 -5
  104. package/src/extensions/alchemy/openapi-ts/core/types.gen.ts +1 -1
  105. package/src/extensions/alchemy/openapi-ts/core/utils.gen.ts +1 -1
  106. package/src/extensions/alchemy/openapi-ts/index.ts +2 -2
  107. package/src/extensions/alchemy/openapi-ts/sdk.gen.ts +44 -2
  108. package/src/extensions/alchemy/openapi-ts/types.gen.ts +177 -34
  109. package/src/extensions/app/openapi-ts/client/client.gen.ts +17 -7
  110. package/src/extensions/app/openapi-ts/client/types.gen.ts +2 -1
  111. package/src/extensions/app/openapi-ts/client/utils.gen.ts +1 -1
  112. package/src/extensions/app/openapi-ts/core/bodySerializer.gen.ts +6 -8
  113. package/src/extensions/app/openapi-ts/core/params.gen.ts +1 -1
  114. package/src/extensions/app/openapi-ts/core/serverSentEvents.gen.ts +4 -5
  115. package/src/extensions/app/openapi-ts/core/types.gen.ts +1 -1
  116. package/src/extensions/app/openapi-ts/core/utils.gen.ts +1 -1
  117. package/src/extensions/app/openapi-ts/sdk.gen.ts +1 -1
  118. package/src/extensions/app/openapi-ts/types.gen.ts +3 -3
  119. package/src/extensions/billing/openapi-ts/client/client.gen.ts +17 -7
  120. package/src/extensions/billing/openapi-ts/client/types.gen.ts +2 -1
  121. package/src/extensions/billing/openapi-ts/client/utils.gen.ts +1 -1
  122. package/src/extensions/billing/openapi-ts/core/bodySerializer.gen.ts +6 -8
  123. package/src/extensions/billing/openapi-ts/core/params.gen.ts +1 -1
  124. package/src/extensions/billing/openapi-ts/core/serverSentEvents.gen.ts +4 -5
  125. package/src/extensions/billing/openapi-ts/core/types.gen.ts +1 -1
  126. package/src/extensions/billing/openapi-ts/core/utils.gen.ts +1 -1
  127. package/src/extensions/billing/openapi-ts/sdk.gen.ts +1 -1
  128. package/src/extensions/billing/openapi-ts/types.gen.ts +3 -3
  129. package/src/extensions/bridge/openapi-ts/client/client.gen.ts +17 -7
  130. package/src/extensions/bridge/openapi-ts/client/types.gen.ts +2 -1
  131. package/src/extensions/bridge/openapi-ts/client/utils.gen.ts +1 -1
  132. package/src/extensions/bridge/openapi-ts/core/bodySerializer.gen.ts +6 -8
  133. package/src/extensions/bridge/openapi-ts/core/params.gen.ts +1 -1
  134. package/src/extensions/bridge/openapi-ts/core/serverSentEvents.gen.ts +4 -5
  135. package/src/extensions/bridge/openapi-ts/core/types.gen.ts +1 -1
  136. package/src/extensions/bridge/openapi-ts/core/utils.gen.ts +1 -1
  137. package/src/extensions/bridge/openapi-ts/index.ts +2 -2
  138. package/src/extensions/bridge/openapi-ts/sdk.gen.ts +90 -2
  139. package/src/extensions/bridge/openapi-ts/types.gen.ts +572 -29
  140. package/src/extensions/builder/openapi-ts/client/client.gen.ts +17 -7
  141. package/src/extensions/builder/openapi-ts/client/types.gen.ts +2 -1
  142. package/src/extensions/builder/openapi-ts/client/utils.gen.ts +1 -1
  143. package/src/extensions/builder/openapi-ts/core/bodySerializer.gen.ts +6 -8
  144. package/src/extensions/builder/openapi-ts/core/params.gen.ts +1 -1
  145. package/src/extensions/builder/openapi-ts/core/serverSentEvents.gen.ts +4 -5
  146. package/src/extensions/builder/openapi-ts/core/types.gen.ts +1 -1
  147. package/src/extensions/builder/openapi-ts/core/utils.gen.ts +1 -1
  148. package/src/extensions/builder/openapi-ts/sdk.gen.ts +1 -1
  149. package/src/extensions/business/openapi-ts/client/client.gen.ts +17 -7
  150. package/src/extensions/business/openapi-ts/client/types.gen.ts +2 -1
  151. package/src/extensions/business/openapi-ts/client/utils.gen.ts +1 -1
  152. package/src/extensions/business/openapi-ts/core/bodySerializer.gen.ts +6 -8
  153. package/src/extensions/business/openapi-ts/core/params.gen.ts +1 -1
  154. package/src/extensions/business/openapi-ts/core/serverSentEvents.gen.ts +4 -5
  155. package/src/extensions/business/openapi-ts/core/types.gen.ts +1 -1
  156. package/src/extensions/business/openapi-ts/core/utils.gen.ts +1 -1
  157. package/src/extensions/business/openapi-ts/sdk.gen.ts +1 -1
  158. package/src/extensions/business/openapi-ts/types.gen.ts +91 -56
  159. package/src/extensions/conversion/openapi-ts/client/client.gen.ts +17 -7
  160. package/src/extensions/conversion/openapi-ts/client/types.gen.ts +2 -1
  161. package/src/extensions/conversion/openapi-ts/client/utils.gen.ts +1 -1
  162. package/src/extensions/conversion/openapi-ts/core/bodySerializer.gen.ts +6 -8
  163. package/src/extensions/conversion/openapi-ts/core/params.gen.ts +1 -1
  164. package/src/extensions/conversion/openapi-ts/core/serverSentEvents.gen.ts +4 -5
  165. package/src/extensions/conversion/openapi-ts/core/types.gen.ts +1 -1
  166. package/src/extensions/conversion/openapi-ts/core/utils.gen.ts +1 -1
  167. package/src/extensions/conversion/openapi-ts/sdk.gen.ts +1 -1
  168. package/src/extensions/conversion/openapi-ts/types.gen.ts +2 -2
  169. package/src/extensions/mass-send/openapi-ts/client/client.gen.ts +17 -7
  170. package/src/extensions/mass-send/openapi-ts/client/types.gen.ts +2 -1
  171. package/src/extensions/mass-send/openapi-ts/client/utils.gen.ts +1 -1
  172. package/src/extensions/mass-send/openapi-ts/core/bodySerializer.gen.ts +6 -8
  173. package/src/extensions/mass-send/openapi-ts/core/params.gen.ts +1 -1
  174. package/src/extensions/mass-send/openapi-ts/core/serverSentEvents.gen.ts +4 -5
  175. package/src/extensions/mass-send/openapi-ts/core/types.gen.ts +1 -1
  176. package/src/extensions/mass-send/openapi-ts/core/utils.gen.ts +1 -1
  177. package/src/extensions/mass-send/openapi-ts/sdk.gen.ts +1 -1
  178. package/src/extensions/notifications/openapi-ts/client/client.gen.ts +17 -7
  179. package/src/extensions/notifications/openapi-ts/client/types.gen.ts +2 -1
  180. package/src/extensions/notifications/openapi-ts/client/utils.gen.ts +1 -1
  181. package/src/extensions/notifications/openapi-ts/core/bodySerializer.gen.ts +6 -8
  182. package/src/extensions/notifications/openapi-ts/core/params.gen.ts +1 -1
  183. package/src/extensions/notifications/openapi-ts/core/serverSentEvents.gen.ts +4 -5
  184. package/src/extensions/notifications/openapi-ts/core/types.gen.ts +1 -1
  185. package/src/extensions/notifications/openapi-ts/core/utils.gen.ts +1 -1
  186. package/src/extensions/notifications/openapi-ts/sdk.gen.ts +1 -1
  187. package/src/extensions/notifications/openapi-ts/types.gen.ts +8 -8
  188. package/src/extensions/payment-requests/openapi-ts/client/client.gen.ts +17 -7
  189. package/src/extensions/payment-requests/openapi-ts/client/types.gen.ts +2 -1
  190. package/src/extensions/payment-requests/openapi-ts/client/utils.gen.ts +1 -1
  191. package/src/extensions/payment-requests/openapi-ts/core/bodySerializer.gen.ts +6 -8
  192. package/src/extensions/payment-requests/openapi-ts/core/params.gen.ts +1 -1
  193. package/src/extensions/payment-requests/openapi-ts/core/serverSentEvents.gen.ts +4 -5
  194. package/src/extensions/payment-requests/openapi-ts/core/types.gen.ts +1 -1
  195. package/src/extensions/payment-requests/openapi-ts/core/utils.gen.ts +1 -1
  196. package/src/extensions/payment-requests/openapi-ts/sdk.gen.ts +1 -1
  197. package/src/extensions/payment-requests/openapi-ts/types.gen.ts +7 -3
  198. package/src/extensions/products/openapi-ts/client/client.gen.ts +17 -7
  199. package/src/extensions/products/openapi-ts/client/types.gen.ts +2 -1
  200. package/src/extensions/products/openapi-ts/client/utils.gen.ts +1 -1
  201. package/src/extensions/products/openapi-ts/core/bodySerializer.gen.ts +6 -8
  202. package/src/extensions/products/openapi-ts/core/params.gen.ts +1 -1
  203. package/src/extensions/products/openapi-ts/core/serverSentEvents.gen.ts +4 -5
  204. package/src/extensions/products/openapi-ts/core/types.gen.ts +1 -1
  205. package/src/extensions/products/openapi-ts/core/utils.gen.ts +1 -1
  206. package/src/extensions/products/openapi-ts/sdk.gen.ts +1 -1
  207. package/src/extensions/products/openapi-ts/types.gen.ts +35 -35
  208. package/src/extensions/rain/openapi-ts/client/client.gen.ts +17 -7
  209. package/src/extensions/rain/openapi-ts/client/types.gen.ts +2 -1
  210. package/src/extensions/rain/openapi-ts/client/utils.gen.ts +1 -1
  211. package/src/extensions/rain/openapi-ts/core/bodySerializer.gen.ts +6 -8
  212. package/src/extensions/rain/openapi-ts/core/params.gen.ts +1 -1
  213. package/src/extensions/rain/openapi-ts/core/serverSentEvents.gen.ts +4 -5
  214. package/src/extensions/rain/openapi-ts/core/types.gen.ts +1 -1
  215. package/src/extensions/rain/openapi-ts/core/utils.gen.ts +1 -1
  216. package/src/extensions/rain/openapi-ts/sdk.gen.ts +1 -1
  217. package/src/extensions/rain/openapi-ts/types.gen.ts +14 -14
  218. package/src/extensions/rewards/openapi-ts/client/client.gen.ts +17 -7
  219. package/src/extensions/rewards/openapi-ts/client/types.gen.ts +2 -1
  220. package/src/extensions/rewards/openapi-ts/client/utils.gen.ts +1 -1
  221. package/src/extensions/rewards/openapi-ts/core/bodySerializer.gen.ts +6 -8
  222. package/src/extensions/rewards/openapi-ts/core/params.gen.ts +1 -1
  223. package/src/extensions/rewards/openapi-ts/core/serverSentEvents.gen.ts +4 -5
  224. package/src/extensions/rewards/openapi-ts/core/types.gen.ts +1 -1
  225. package/src/extensions/rewards/openapi-ts/core/utils.gen.ts +1 -1
  226. package/src/extensions/rewards/openapi-ts/sdk.gen.ts +1 -1
  227. package/src/extensions/stellar/openapi-ts/client/client.gen.ts +17 -7
  228. package/src/extensions/stellar/openapi-ts/client/types.gen.ts +2 -1
  229. package/src/extensions/stellar/openapi-ts/client/utils.gen.ts +1 -1
  230. package/src/extensions/stellar/openapi-ts/core/bodySerializer.gen.ts +6 -8
  231. package/src/extensions/stellar/openapi-ts/core/params.gen.ts +1 -1
  232. package/src/extensions/stellar/openapi-ts/core/serverSentEvents.gen.ts +4 -5
  233. package/src/extensions/stellar/openapi-ts/core/types.gen.ts +1 -1
  234. package/src/extensions/stellar/openapi-ts/core/utils.gen.ts +1 -1
  235. package/src/extensions/stellar/openapi-ts/sdk.gen.ts +1 -1
  236. package/src/extensions/stellar/openapi-ts/types.gen.ts +8 -8
  237. package/src/extensions/stellar-testnet/openapi-ts/client/client.gen.ts +17 -7
  238. package/src/extensions/stellar-testnet/openapi-ts/client/types.gen.ts +2 -1
  239. package/src/extensions/stellar-testnet/openapi-ts/client/utils.gen.ts +1 -1
  240. package/src/extensions/stellar-testnet/openapi-ts/core/bodySerializer.gen.ts +6 -8
  241. package/src/extensions/stellar-testnet/openapi-ts/core/params.gen.ts +1 -1
  242. package/src/extensions/stellar-testnet/openapi-ts/core/serverSentEvents.gen.ts +4 -5
  243. package/src/extensions/stellar-testnet/openapi-ts/core/types.gen.ts +1 -1
  244. package/src/extensions/stellar-testnet/openapi-ts/core/utils.gen.ts +1 -1
  245. package/src/extensions/stellar-testnet/openapi-ts/sdk.gen.ts +1 -1
  246. package/src/extensions/stellar-testnet/openapi-ts/types.gen.ts +8 -8
  247. package/src/platform/admin/openapi-ts/client/client.gen.ts +17 -7
  248. package/src/platform/admin/openapi-ts/client/types.gen.ts +2 -1
  249. package/src/platform/admin/openapi-ts/client/utils.gen.ts +1 -1
  250. package/src/platform/admin/openapi-ts/core/bodySerializer.gen.ts +6 -8
  251. package/src/platform/admin/openapi-ts/core/params.gen.ts +1 -1
  252. package/src/platform/admin/openapi-ts/core/serverSentEvents.gen.ts +4 -5
  253. package/src/platform/admin/openapi-ts/core/types.gen.ts +1 -1
  254. package/src/platform/admin/openapi-ts/core/utils.gen.ts +1 -1
  255. package/src/platform/admin/openapi-ts/index.ts +2 -2
  256. package/src/platform/admin/openapi-ts/sdk.gen.ts +54 -12
  257. package/src/platform/admin/openapi-ts/types.gen.ts +623 -107
  258. package/src/platform/user/openapi-ts/client/client.gen.ts +17 -7
  259. package/src/platform/user/openapi-ts/client/types.gen.ts +2 -1
  260. package/src/platform/user/openapi-ts/client/utils.gen.ts +1 -1
  261. package/src/platform/user/openapi-ts/core/bodySerializer.gen.ts +6 -8
  262. package/src/platform/user/openapi-ts/core/params.gen.ts +1 -1
  263. package/src/platform/user/openapi-ts/core/serverSentEvents.gen.ts +4 -5
  264. package/src/platform/user/openapi-ts/core/types.gen.ts +1 -1
  265. package/src/platform/user/openapi-ts/core/utils.gen.ts +1 -1
  266. package/src/platform/user/openapi-ts/index.ts +2 -2
  267. package/src/platform/user/openapi-ts/sdk.gen.ts +30 -4
  268. package/src/platform/user/openapi-ts/types.gen.ts +116 -52
  269. package/dist/chunk-7USVOK77.js +0 -7
  270. package/dist/chunk-G3M5QMRX.js +0 -1
  271. package/dist/chunk-HSPTEN45.mjs +0 -1
  272. package/dist/chunk-HWXE5WBF.js +0 -7
  273. package/dist/chunk-MUN3POSM.mjs +0 -7
  274. package/dist/chunk-ZUZHOLAX.mjs +0 -7
@@ -14,16 +14,10 @@ import type {
14
14
  import { WebStorageAdapter, MemoryStorageAdapter } from './core/storage-adapters.js';
15
15
  import { ApiError, normalizeFetch } from '../shared/api-utils.js';
16
16
  import type {
17
- AuthEvent,
18
- AuthEventListener,
19
- AuthRecoveryState,
20
17
  AuthSession,
21
- AuthSnapshot,
22
18
  AuthState,
23
- AuthStateListener,
24
- AuthStatus,
25
- ErrorListener,
26
19
  SessionListener,
20
+ ErrorListener,
27
21
  StorageAdapter,
28
22
  } from './types/index.js';
29
23
 
@@ -31,7 +25,7 @@ export type LoginParams = {
31
25
  user: string;
32
26
  password: string;
33
27
  company: string;
34
- session_duration?: number;
28
+ session_duration?: number | null;
35
29
  };
36
30
 
37
31
  export type RegisterParams = {
@@ -44,26 +38,11 @@ export type RegisterParams = {
44
38
  last_name?: string;
45
39
  terms_and_conditions?: boolean;
46
40
  privacy_policy?: boolean;
47
- session_duration?: number;
41
+ session_duration?: number | null;
48
42
  };
49
43
 
50
44
  export type RegisterCompanyParams = RegisterCompanyRequestWritable;
51
45
 
52
- export interface ImportTokenOptions {
53
- company?: string;
54
- expires?: number;
55
- sessionDuration?: number;
56
- }
57
-
58
- export interface ValidateSessionOptions {
59
- retryCount?: number;
60
- retryDelayMs?: number;
61
- }
62
-
63
- export type SessionPatch =
64
- | Partial<AuthSession>
65
- | ((session: AuthSession) => AuthSession);
66
-
67
46
  export interface AuthConfig {
68
47
  baseUrl?: string;
69
48
  storage?: 'local' | 'memory' | StorageAdapter;
@@ -82,25 +61,11 @@ export interface Auth {
82
61
  getActiveSession(): AuthSession | null;
83
62
  getSessions(): AuthSession[];
84
63
  getSessionsByCompany(company: string): AuthSession[];
85
- getState(): AuthSnapshot;
86
- getStatus(): AuthStatus;
87
- getRecoveryState(): AuthRecoveryState;
88
64
  switchToSession(userId: string, company?: string): Promise<AuthSession | null>;
89
65
  clearAllSessions(): Promise<void>;
90
66
  deleteChallenge(challengeId: string): Promise<void>;
91
- importToken(token: string, options?: ImportTokenOptions): Promise<AuthSession>;
92
- validateActiveSession(options?: ValidateSessionOptions): Promise<boolean>;
93
- syncActiveSessionUser(): Promise<AuthSession | null>;
94
- updateSession(
95
- userId: string,
96
- company: string | undefined,
97
- patch: SessionPatch,
98
- ): Promise<AuthSession | null>;
99
- expireActiveSession(): Promise<AuthRecoveryState>;
100
67
  subscribe(listener: SessionListener): () => void;
101
68
  subscribeToErrors(listener: ErrorListener): () => void;
102
- subscribeToState(listener: AuthStateListener): () => void;
103
- subscribeToEvents(listener: AuthEventListener): () => void;
104
69
  readonly baseUrl: string;
105
70
  }
106
71
 
@@ -141,195 +106,46 @@ function errorHandlingFetch(baseFetch: typeof fetch): typeof fetch {
141
106
  };
142
107
  }
143
108
 
144
- function sleep(ms: number): Promise<void> {
145
- return new Promise((resolve) => setTimeout(resolve, ms));
146
- }
147
-
148
- function getSessionCompany(session: AuthSession): string | undefined {
149
- return session.company ?? session.user?.company;
150
- }
151
-
152
- function cloneSessions(sessions: AuthSession[]): AuthSession[] {
153
- return [...sessions];
154
- }
155
-
156
109
  export function createAuth(config: AuthConfig = {}): Auth {
157
110
  const baseUrl = config.baseUrl || 'https://api.rehive.com';
158
111
  const storage = resolveStorage(config.storage);
159
112
  const permanentToken = config.token;
160
113
  const enableCrossTabSync = config.enableCrossTabSync ?? true;
161
114
  const storageKey = 'rehive_auth_state';
162
- const baseFetch = normalizeFetch(globalThis.fetch);
163
115
 
164
116
  const client = createClient({
165
117
  baseUrl,
166
118
  responseStyle: 'data' as const,
167
- fetch: errorHandlingFetch(baseFetch),
119
+ fetch: errorHandlingFetch(normalizeFetch(globalThis.fetch)),
168
120
  });
169
121
 
170
122
  let sessions: AuthSession[] = [];
171
123
  let activeSessionIndex = -1;
172
124
  let sessionListeners: SessionListener[] = [];
173
125
  let errorListeners: ErrorListener[] = [];
174
- let stateListeners: AuthStateListener[] = [];
175
- let eventListeners: AuthEventListener[] = [];
176
126
  let refreshPromise: Promise<void> | null = null;
177
127
  let isRefreshing = false;
178
128
  let loadAuthStatePromise: Promise<AuthState> | null = null;
179
129
  let initialized = false;
180
- let initializePromise: Promise<void> | null = null;
181
- let cachedSnapshot: AuthSnapshot | null = null;
182
- let lastError: Error | null = null;
183
- let lastExpiredSession: AuthSession | null = null;
184
130
 
185
131
  function isTokenExpired(expires: number): boolean {
186
132
  return Date.now() >= expires - 30 * 1000;
187
133
  }
188
134
 
189
- function getActiveSessionFromState(state: AuthState): AuthSession | null {
190
- if (
191
- state.activeSessionIndex >= 0 &&
192
- state.activeSessionIndex < state.sessions.length
193
- ) {
194
- return state.sessions[state.activeSessionIndex];
195
- }
196
- return null;
197
- }
198
-
199
- function getCurrentState(): AuthState {
200
- return {
201
- sessions: cloneSessions(sessions),
202
- activeSessionIndex,
203
- };
204
- }
205
-
206
135
  function getActiveSession(): AuthSession | null {
207
- return getActiveSessionFromState(getCurrentState());
208
- }
209
-
210
- function buildRecoveryState(state: AuthState = getCurrentState()): AuthRecoveryState {
211
- const session = getActiveSessionFromState(state);
212
- const pending = !permanentToken && !session && state.sessions.length > 0;
213
-
214
- return {
215
- pending,
216
- expiredSession: pending ? lastExpiredSession : null,
217
- remainingSessions: pending ? cloneSessions(state.sessions) : [],
218
- };
219
- }
220
-
221
- function getStatus(state: AuthState = getCurrentState()): AuthStatus {
222
- if (!initialized && !permanentToken) {
223
- return 'loading';
224
- }
225
- if (isRefreshing) {
226
- return 'refreshing';
227
- }
228
- if (permanentToken) {
229
- return 'authenticated';
230
- }
231
- if (getActiveSessionFromState(state)) {
232
- return 'authenticated';
233
- }
234
- if (state.sessions.length > 0) {
235
- return 'recoverable';
136
+ if (activeSessionIndex >= 0 && activeSessionIndex < sessions.length) {
137
+ return sessions[activeSessionIndex];
236
138
  }
237
- return 'unauthenticated';
238
- }
239
-
240
- function getState(): AuthSnapshot {
241
- if (cachedSnapshot) {
242
- return cachedSnapshot;
243
- }
244
- const state = getCurrentState();
245
- cachedSnapshot = {
246
- status: getStatus(state),
247
- session: getActiveSessionFromState(state),
248
- sessions: state.sessions,
249
- activeSessionIndex: state.activeSessionIndex,
250
- isRefreshing,
251
- initialized: initialized || !!permanentToken,
252
- error: lastError,
253
- recovery: buildRecoveryState(state),
254
- };
255
- return cachedSnapshot;
256
- }
257
-
258
- function invalidateSnapshot(): void {
259
- cachedSnapshot = null;
260
- }
261
-
262
- function emit(event: Omit<AuthEvent, 'snapshot'>): void {
263
- const snapshot = getState();
264
- const payload: AuthEvent = {
265
- ...event,
266
- snapshot,
267
- };
268
- eventListeners.forEach((listener) => listener(payload));
269
- }
270
-
271
- function notifyAll(event?: Omit<AuthEvent, 'snapshot'>): void {
272
- invalidateSnapshot();
273
- const snapshot = getState();
274
- sessionListeners.forEach((listener) => listener(snapshot.session));
275
- errorListeners.forEach((listener) => listener(snapshot.error));
276
- stateListeners.forEach((listener) => listener(snapshot));
277
-
278
- if (event) {
279
- emit(event);
280
- }
281
- }
282
-
283
- function setError(error: Error | null): void {
284
- lastError = error;
139
+ return null;
285
140
  }
286
141
 
287
- async function persistState(state: AuthState): Promise<void> {
288
- if (permanentToken) {
289
- return;
290
- }
291
-
292
- await storage.setItem(storageKey, JSON.stringify(state));
142
+ function notifySessionListeners(): void {
143
+ const session = getActiveSession();
144
+ sessionListeners.forEach((listener) => listener(session));
293
145
  }
294
146
 
295
- async function applyState(
296
- state: AuthState,
297
- options: {
298
- clearExpiredSession?: boolean;
299
- expiredSession?: AuthSession | null;
300
- error?: Error | null;
301
- event?: Omit<AuthEvent, 'snapshot'>;
302
- } = {},
303
- ): Promise<void> {
304
- sessions = cloneSessions(state.sessions);
305
- activeSessionIndex =
306
- state.activeSessionIndex >= 0 && state.activeSessionIndex < sessions.length
307
- ? state.activeSessionIndex
308
- : -1;
309
-
310
- if (options.clearExpiredSession || activeSessionIndex >= 0 || sessions.length === 0) {
311
- lastExpiredSession = null;
312
- }
313
- if (Object.prototype.hasOwnProperty.call(options, 'expiredSession')) {
314
- lastExpiredSession = options.expiredSession ?? null;
315
- }
316
- if (Object.prototype.hasOwnProperty.call(options, 'error')) {
317
- setError(options.error ?? null);
318
- }
319
-
320
- try {
321
- await persistState({
322
- sessions,
323
- activeSessionIndex,
324
- });
325
- } catch (error) {
326
- console.error('Failed to save auth state:', error);
327
- if (!lastError && error instanceof Error) {
328
- setError(error);
329
- }
330
- }
331
-
332
- notifyAll(options.event);
147
+ function notifyErrorListeners(error: Error | null): void {
148
+ errorListeners.forEach((listener) => listener(error));
333
149
  }
334
150
 
335
151
  async function loadAuthState(): Promise<AuthState> {
@@ -352,17 +168,9 @@ export function createAuth(config: AuthConfig = {}): Auth {
352
168
  } catch (error) {
353
169
  console.error('Failed to load auth state:', error);
354
170
  }
355
-
356
171
  sessions = state.sessions;
357
- activeSessionIndex =
358
- state.activeSessionIndex >= 0 && state.activeSessionIndex < state.sessions.length
359
- ? state.activeSessionIndex
360
- : -1;
361
-
362
- return {
363
- sessions: cloneSessions(sessions),
364
- activeSessionIndex,
365
- };
172
+ activeSessionIndex = state.activeSessionIndex;
173
+ return state;
366
174
  })();
367
175
 
368
176
  try {
@@ -372,133 +180,51 @@ export function createAuth(config: AuthConfig = {}): Auth {
372
180
  }
373
181
  }
374
182
 
183
+ async function saveAuthState(state: AuthState): Promise<void> {
184
+ try {
185
+ await storage.setItem(storageKey, JSON.stringify(state));
186
+ sessions = state.sessions;
187
+ activeSessionIndex = state.activeSessionIndex;
188
+ notifySessionListeners();
189
+ } catch (error) {
190
+ console.error('Failed to save auth state:', error);
191
+ }
192
+ }
193
+
375
194
  function setupCrossTabSync(): void {
376
195
  if (typeof window !== 'undefined') {
377
196
  window.addEventListener('storage', (event: StorageEvent) => {
378
- if (event.key !== storageKey) {
379
- return;
380
- }
381
-
382
- if (!event.newValue) {
383
- void applyState(
384
- { sessions: [], activeSessionIndex: -1 },
385
- { clearExpiredSession: true },
386
- );
387
- return;
388
- }
389
-
390
- try {
391
- const newState = JSON.parse(event.newValue);
392
- void applyState(
393
- {
394
- sessions: Array.isArray(newState.sessions) ? newState.sessions : [],
395
- activeSessionIndex:
396
- typeof newState.activeSessionIndex === 'number'
397
- ? newState.activeSessionIndex
398
- : -1,
399
- },
400
- {},
401
- );
402
- } catch (error) {
403
- console.error('Failed to sync auth state from storage event:', error);
197
+ if (event.key === storageKey && event.newValue) {
198
+ try {
199
+ const newState = JSON.parse(event.newValue);
200
+ sessions = Array.isArray(newState.sessions) ? newState.sessions : [];
201
+ activeSessionIndex =
202
+ typeof newState.activeSessionIndex === 'number'
203
+ ? newState.activeSessionIndex
204
+ : -1;
205
+ notifySessionListeners();
206
+ } catch (error) {
207
+ console.error('Failed to sync auth state from storage event:', error);
208
+ }
404
209
  }
405
210
  });
406
211
  }
407
212
  }
408
213
 
409
214
  async function initialize(): Promise<void> {
410
- if (initialized) {
411
- return;
412
- }
413
- if (initializePromise) {
414
- return initializePromise;
415
- }
215
+ if (initialized) return;
216
+ initialized = true;
416
217
 
417
- initializePromise = (async () => {
418
- if (!permanentToken) {
419
- if (enableCrossTabSync) {
420
- setupCrossTabSync();
421
- }
422
- await loadAuthState();
218
+ if (!permanentToken) {
219
+ if (enableCrossTabSync) {
220
+ setupCrossTabSync();
423
221
  }
424
- initialized = true;
425
- notifyAll({ type: 'initialized' });
426
- })();
427
-
428
- return initializePromise;
429
- }
430
-
431
- async function fetchUserForToken(token: string): Promise<any> {
432
- const response = await baseFetch(`${baseUrl.replace(/\/$/, '')}/3/user/`, {
433
- headers: {
434
- Authorization: `Token ${token}`,
435
- 'Content-Type': 'application/json',
436
- },
437
- });
438
-
439
- if (!response.ok) {
440
- const errorText = await response.text();
441
- let errorJson: any = null;
442
- try {
443
- errorJson = JSON.parse(errorText);
444
- } catch {
445
- // not JSON
446
- }
447
-
448
- throw new ApiError({
449
- status: response.status,
450
- error: errorJson || errorText,
451
- message:
452
- errorJson?.error ||
453
- errorJson?.message ||
454
- 'A server error occurred. HTTPStatus: ' + response.status,
455
- });
222
+ await loadAuthState();
223
+ notifySessionListeners();
456
224
  }
457
-
458
- const payload = await response.json();
459
- return payload?.data ?? payload;
460
- }
461
-
462
- async function upsertSession(
463
- newSession: AuthSession,
464
- eventType: AuthEvent['type'],
465
- ): Promise<AuthSession> {
466
- await initialize();
467
- const currentState = await loadAuthState();
468
- const sessionCompany = getSessionCompany(newSession);
469
- const existingIdx = currentState.sessions.findIndex(
470
- (session) =>
471
- session.user.id === newSession.user.id &&
472
- getSessionCompany(session) === sessionCompany,
473
- );
474
-
475
- let nextState: AuthState;
476
- if (existingIdx >= 0) {
477
- const updatedSessions = cloneSessions(currentState.sessions);
478
- updatedSessions[existingIdx] = newSession;
479
- nextState = {
480
- sessions: updatedSessions,
481
- activeSessionIndex: existingIdx,
482
- };
483
- } else {
484
- nextState = {
485
- sessions: [...currentState.sessions, newSession],
486
- activeSessionIndex: currentState.sessions.length,
487
- };
488
- }
489
-
490
- await applyState(nextState, {
491
- clearExpiredSession: true,
492
- error: null,
493
- event: {
494
- type: eventType,
495
- session: newSession,
496
- },
497
- });
498
-
499
- return newSession;
500
225
  }
501
226
 
227
+ // Kick off initialization (non-blocking)
502
228
  if (!permanentToken) {
503
229
  initialize().catch(console.error);
504
230
  }
@@ -506,37 +232,55 @@ export function createAuth(config: AuthConfig = {}): Auth {
506
232
  async function login(params: LoginParams): Promise<AuthSession> {
507
233
  await initialize();
508
234
  try {
509
- const sessionDuration = params.session_duration ?? 900;
235
+ // Default to 900s unless explicitly set to null (no custom duration)
236
+ const sessionDuration = params.session_duration === null
237
+ ? undefined
238
+ : (params.session_duration ?? 900);
510
239
  const body: LoginRequestWritable = {
511
240
  user: params.user,
512
241
  password: params.password,
513
242
  company: params.company,
514
- session_duration: sessionDuration,
243
+ ...(sessionDuration != null && { session_duration: sessionDuration }),
515
244
  auth_method: 'token',
516
245
  };
517
246
 
518
247
  const result: any = await authLogin({ client, body, throwOnError: true });
519
248
  const data = result?.data ?? result;
520
249
 
521
- return await upsertSession(
522
- {
523
- user: data.user,
524
- token: data.token,
525
- refresh_token: data.refresh_token,
526
- challenges: data.challenges,
527
- expires: data.expires,
528
- session_duration: sessionDuration,
529
- company: params.company,
530
- },
531
- 'login',
250
+ const newSession: AuthSession = {
251
+ user: data.user,
252
+ token: data.token,
253
+ refresh_token: data.refresh_token,
254
+ challenges: data.challenges,
255
+ expires: data.expires,
256
+ session_duration: sessionDuration ?? 900,
257
+ company: params.company,
258
+ };
259
+
260
+ const currentState = await loadAuthState();
261
+ const existingIdx = currentState.sessions.findIndex(
262
+ (s: AuthSession) =>
263
+ s.user.id === newSession.user.id && s.company === newSession.company,
532
264
  );
265
+
266
+ let newState: AuthState;
267
+ if (existingIdx !== -1) {
268
+ const updated = [...currentState.sessions];
269
+ updated[existingIdx] = newSession;
270
+ newState = { ...currentState, sessions: updated, activeSessionIndex: existingIdx };
271
+ } else {
272
+ newState = {
273
+ sessions: [...currentState.sessions, newSession],
274
+ activeSessionIndex: currentState.sessions.length,
275
+ };
276
+ }
277
+
278
+ await saveAuthState(newState);
279
+ notifyErrorListeners(null);
280
+ return newSession;
533
281
  } catch (e) {
534
282
  const error = e instanceof ApiError ? e : new Error('Login failed');
535
- setError(error);
536
- notifyAll({
537
- type: 'error',
538
- error,
539
- });
283
+ notifyErrorListeners(error);
540
284
  throw e;
541
285
  }
542
286
  }
@@ -544,7 +288,10 @@ export function createAuth(config: AuthConfig = {}): Auth {
544
288
  async function register(params: RegisterParams): Promise<AuthSession> {
545
289
  await initialize();
546
290
  try {
547
- const sessionDuration = params.session_duration ?? 900;
291
+ // Default to 900s unless explicitly set to null (no custom duration)
292
+ const sessionDuration = params.session_duration === null
293
+ ? undefined
294
+ : (params.session_duration ?? 900);
548
295
  const body: RegisterRequestWritable = {
549
296
  email: params.email,
550
297
  mobile: params.mobile,
@@ -556,31 +303,34 @@ export function createAuth(config: AuthConfig = {}): Auth {
556
303
  last_name: params.last_name,
557
304
  terms_and_conditions: params.terms_and_conditions,
558
305
  privacy_policy: params.privacy_policy,
559
- session_duration: sessionDuration,
306
+ ...(sessionDuration != null && { session_duration: sessionDuration }),
560
307
  };
561
308
 
562
309
  const result: any = await authRegister({ client, body, throwOnError: true });
563
310
  const data = result?.data ?? result;
564
311
 
565
- return await upsertSession(
566
- {
567
- user: data.user,
568
- token: data.token,
569
- refresh_token: data.refresh_token,
570
- challenges: data.challenges,
571
- expires: data.expires,
572
- session_duration: sessionDuration,
573
- company: params.company,
574
- },
575
- 'register',
576
- );
312
+ const newSession: AuthSession = {
313
+ user: data.user,
314
+ token: data.token,
315
+ refresh_token: data.refresh_token,
316
+ challenges: data.challenges,
317
+ expires: data.expires,
318
+ session_duration: sessionDuration ?? 900,
319
+ company: params.company,
320
+ };
321
+
322
+ const currentState = await loadAuthState();
323
+ const newState: AuthState = {
324
+ sessions: [...currentState.sessions, newSession],
325
+ activeSessionIndex: currentState.sessions.length,
326
+ };
327
+
328
+ await saveAuthState(newState);
329
+ notifyErrorListeners(null);
330
+ return newSession;
577
331
  } catch (e) {
578
332
  const error = e instanceof ApiError ? e : new Error('Registration failed');
579
- setError(error);
580
- notifyAll({
581
- type: 'error',
582
- error,
583
- });
333
+ notifyErrorListeners(error);
584
334
  throw e;
585
335
  }
586
336
  }
@@ -588,45 +338,47 @@ export function createAuth(config: AuthConfig = {}): Auth {
588
338
  async function registerCompanyFn(params: RegisterCompanyParams): Promise<AuthSession> {
589
339
  await initialize();
590
340
  try {
591
- const result: any = await authRegisterCompany({
592
- client,
593
- body: params,
594
- throwOnError: true,
595
- });
341
+ const body: RegisterCompanyRequestWritable = params;
342
+ const result: any = await authRegisterCompany({ client, body, throwOnError: true });
596
343
  const data = result?.data ?? result;
597
- const company =
598
- typeof params.company === 'string'
599
- ? params.company
600
- : (params.company as any)?.id;
601
-
602
- return await upsertSession(
603
- {
604
- user: data.user,
605
- token: data.token,
606
- refresh_token: data.refresh_token,
607
- challenges: data.challenges,
608
- expires: data.expires,
609
- session_duration: 900,
610
- company,
611
- },
612
- 'register-company',
613
- );
344
+
345
+ const newSession: AuthSession = {
346
+ user: data.user,
347
+ token: data.token,
348
+ refresh_token: data.refresh_token,
349
+ challenges: data.challenges,
350
+ expires: data.expires,
351
+ session_duration: 900,
352
+ company: typeof params.company === 'string' ? params.company : (params.company as any)?.id,
353
+ };
354
+
355
+ const currentState = await loadAuthState();
356
+ const newState: AuthState = {
357
+ sessions: [...currentState.sessions, newSession],
358
+ activeSessionIndex: currentState.sessions.length,
359
+ };
360
+
361
+ await saveAuthState(newState);
362
+ notifyErrorListeners(null);
363
+ return newSession;
614
364
  } catch (e) {
615
- const error =
616
- e instanceof ApiError ? e : new Error('Company registration failed');
617
- setError(error);
618
- notifyAll({
619
- type: 'error',
620
- error,
621
- });
365
+ const error = e instanceof ApiError ? e : new Error('Company registration failed');
366
+ notifyErrorListeners(error);
622
367
  throw e;
623
368
  }
624
369
  }
625
370
 
626
371
  async function logout(): Promise<void> {
627
- await initialize();
628
372
  const currentState = await loadAuthState();
629
- const session = getActiveSessionFromState(currentState);
373
+ const session = currentState.sessions[currentState.activeSessionIndex];
374
+
375
+ const newState: AuthState = {
376
+ ...currentState,
377
+ sessions: currentState.sessions.filter(
378
+ (_: AuthSession, i: number) => i !== currentState.activeSessionIndex,
379
+ ),
380
+ activeSessionIndex: -1,
381
+ };
630
382
 
631
383
  if (session?.token) {
632
384
  try {
@@ -637,34 +389,19 @@ export function createAuth(config: AuthConfig = {}): Auth {
637
389
  throwOnError: true,
638
390
  });
639
391
  } catch {
640
- // Continue with local logout even if API call fails.
392
+ // Continue with local logout even if API call fails
641
393
  }
642
394
  }
643
395
 
644
- await applyState(
645
- {
646
- sessions: currentState.sessions.filter(
647
- (_session, index) => index !== currentState.activeSessionIndex,
648
- ),
649
- activeSessionIndex: -1,
650
- },
651
- {
652
- clearExpiredSession: true,
653
- error: null,
654
- event: {
655
- type: 'logout',
656
- session,
657
- },
658
- },
659
- );
396
+ await saveAuthState(newState);
397
+ notifyErrorListeners(null);
660
398
  }
661
399
 
662
400
  async function logoutAll(): Promise<void> {
663
- await initialize();
664
401
  const currentState = await loadAuthState();
665
402
 
666
403
  await Promise.all(
667
- currentState.sessions.map(async (session) => {
404
+ currentState.sessions.map(async (session: AuthSession) => {
668
405
  try {
669
406
  await authLogout({
670
407
  client,
@@ -673,109 +410,65 @@ export function createAuth(config: AuthConfig = {}): Auth {
673
410
  throwOnError: true,
674
411
  });
675
412
  } catch {
676
- // Continue clearing local sessions even if API logout fails.
413
+ // Log but continue
677
414
  }
678
415
  }),
679
416
  );
680
417
 
681
- await applyState(
682
- {
683
- sessions: [],
684
- activeSessionIndex: -1,
685
- },
686
- {
687
- clearExpiredSession: true,
688
- error: null,
689
- event: {
690
- type: 'logout-all',
691
- },
692
- },
693
- );
418
+ await saveAuthState({ sessions: [], activeSessionIndex: -1 });
419
+ notifyErrorListeners(null);
694
420
  }
695
421
 
696
422
  async function refresh(): Promise<void> {
697
- if (refreshPromise) {
698
- return refreshPromise;
699
- }
423
+ if (refreshPromise) return refreshPromise;
700
424
 
701
425
  refreshPromise = (async () => {
702
426
  isRefreshing = true;
703
- notifyAll();
704
-
705
- let sessionBeforeRefresh: AuthSession | null = null;
706
-
707
427
  try {
708
428
  const currentState = await loadAuthState();
709
429
  const idx = currentState.activeSessionIndex;
710
- const session = getActiveSessionFromState(currentState);
711
- sessionBeforeRefresh = session;
430
+ const session = currentState.sessions[idx];
712
431
 
713
- if (idx < 0 || !session?.token || !session.refresh_token) {
432
+ if (!session?.token || !session?.refresh_token) {
714
433
  throw new Error('No active session, token, or refresh token found');
715
434
  }
716
435
 
436
+ const refreshDuration = session.session_duration ?? 900;
717
437
  const result: any = await authRefreshCreate({
718
438
  client,
719
- body: { session_duration: session.session_duration ?? 900 },
439
+ body: { ...(refreshDuration != null && { session_duration: refreshDuration }) },
720
440
  headers: { Authorization: `Refresh-Token ${session.refresh_token}` },
721
441
  throwOnError: true,
722
442
  });
723
443
  const data = result?.data ?? result;
724
444
 
725
- const updatedSessions = cloneSessions(currentState.sessions);
445
+ const updatedSessions = [...currentState.sessions];
726
446
  updatedSessions[idx] = {
727
447
  ...session,
728
- token: data.token ?? session.token,
729
- refresh_token: data.refresh_token ?? session.refresh_token,
730
- expires: data.expires ?? session.expires,
731
- session_duration: session.session_duration ?? 900,
732
- company: getSessionCompany(session),
448
+ refresh_token: data.refresh_token,
449
+ expires: data.expires,
450
+ session_duration: refreshDuration,
451
+ company: session.company,
733
452
  };
734
453
 
735
- await applyState(
736
- {
737
- sessions: updatedSessions,
738
- activeSessionIndex: idx,
739
- },
740
- {
741
- clearExpiredSession: true,
742
- error: null,
743
- event: {
744
- type: 'refresh',
745
- session: updatedSessions[idx],
746
- },
747
- },
748
- );
454
+ await saveAuthState({ ...currentState, sessions: updatedSessions });
455
+ notifyErrorListeners(null);
749
456
  } catch (e) {
750
457
  const error = e instanceof ApiError ? e : new Error('Refresh failed');
458
+ notifyErrorListeners(error);
459
+
751
460
  const currentState = await loadAuthState();
752
- const expiredSession =
753
- sessionBeforeRefresh ??
754
- getActiveSessionFromState(currentState);
755
- const nextSessions = currentState.sessions.filter(
756
- (_session, index) => index !== currentState.activeSessionIndex,
757
- );
758
-
759
- await applyState(
760
- {
761
- sessions: nextSessions,
762
- activeSessionIndex: -1,
763
- },
764
- {
765
- expiredSession: expiredSession ?? null,
766
- error,
767
- event: {
768
- type: 'session-expired',
769
- session: expiredSession,
770
- error,
771
- },
772
- },
773
- );
461
+ await saveAuthState({
462
+ ...currentState,
463
+ sessions: currentState.sessions.filter(
464
+ (_: AuthSession, i: number) => i !== currentState.activeSessionIndex,
465
+ ),
466
+ activeSessionIndex: -1,
467
+ });
774
468
  throw e;
775
469
  } finally {
776
470
  isRefreshing = false;
777
471
  refreshPromise = null;
778
- notifyAll();
779
472
  }
780
473
  })();
781
474
 
@@ -783,15 +476,11 @@ export function createAuth(config: AuthConfig = {}): Auth {
783
476
  }
784
477
 
785
478
  async function getToken(): Promise<string | undefined> {
786
- if (permanentToken) {
787
- return permanentToken;
788
- }
479
+ if (permanentToken) return permanentToken;
789
480
 
790
481
  await initialize();
791
482
  const session = getActiveSession();
792
- if (!session) {
793
- return undefined;
794
- }
483
+ if (!session) return undefined;
795
484
 
796
485
  if (session.expires && isTokenExpired(session.expires)) {
797
486
  try {
@@ -809,34 +498,17 @@ export function createAuth(config: AuthConfig = {}): Auth {
809
498
  userId: string,
810
499
  company?: string,
811
500
  ): Promise<AuthSession | null> {
812
- await initialize();
813
501
  const currentState = await loadAuthState();
814
502
  const idx = currentState.sessions.findIndex(
815
- (session) =>
816
- session.user.id === userId && getSessionCompany(session) === company,
503
+ (s: AuthSession) => s.user.id === userId && s.company === company,
817
504
  );
818
505
 
819
- if (idx === -1) {
820
- return null;
821
- }
506
+ if (idx === -1) return null;
822
507
 
823
- await applyState(
824
- {
825
- sessions: currentState.sessions,
826
- activeSessionIndex: idx,
827
- },
828
- {
829
- clearExpiredSession: true,
830
- error: null,
831
- event: {
832
- type: 'session-switched',
833
- session: currentState.sessions[idx],
834
- },
835
- },
836
- );
508
+ const session = currentState.sessions[idx];
509
+ await saveAuthState({ ...currentState, activeSessionIndex: idx });
837
510
 
838
- const session = getActiveSession();
839
- if (session?.expires && isTokenExpired(session.expires)) {
511
+ if (session.expires && isTokenExpired(session.expires)) {
840
512
  await refresh();
841
513
  return getActiveSession();
842
514
  }
@@ -845,272 +517,23 @@ export function createAuth(config: AuthConfig = {}): Auth {
845
517
  }
846
518
 
847
519
  async function clearAllSessions(): Promise<void> {
848
- await initialize();
849
- await applyState(
850
- {
851
- sessions: [],
852
- activeSessionIndex: -1,
853
- },
854
- {
855
- clearExpiredSession: true,
856
- error: null,
857
- event: {
858
- type: 'session-cleared',
859
- },
860
- },
861
- );
520
+ await saveAuthState({ sessions: [], activeSessionIndex: -1 });
521
+ notifyErrorListeners(null);
862
522
  }
863
523
 
864
524
  async function deleteChallenge(challengeId: string): Promise<void> {
865
- await initialize();
866
525
  const currentState = await loadAuthState();
867
526
  const idx = currentState.activeSessionIndex;
868
-
869
- if (idx < 0 || idx >= currentState.sessions.length) {
870
- return;
871
- }
527
+ if (idx < 0 || idx >= currentState.sessions.length) return;
872
528
 
873
529
  const session = currentState.sessions[idx];
874
- const updatedSessions = cloneSessions(currentState.sessions);
530
+ const updatedSessions = [...currentState.sessions];
875
531
  updatedSessions[idx] = {
876
532
  ...session,
877
- challenges:
878
- session.challenges?.filter((challenge: any) => challenge.id !== challengeId) ||
879
- [],
880
- };
881
-
882
- await applyState(
883
- {
884
- sessions: updatedSessions,
885
- activeSessionIndex: idx,
886
- },
887
- {
888
- error: null,
889
- },
890
- );
891
- }
892
-
893
- async function importToken(
894
- token: string,
895
- options: ImportTokenOptions = {},
896
- ): Promise<AuthSession> {
897
- await initialize();
898
- const user = await fetchUserForToken(token);
899
- const sessionDuration = options.sessionDuration ?? 900;
900
-
901
- return upsertSession(
902
- {
903
- user,
904
- token,
905
- refresh_token: '',
906
- challenges: [],
907
- expires: options.expires ?? Date.now() + 30 * 24 * 60 * 60 * 1000,
908
- session_duration: sessionDuration,
909
- company: options.company ?? user?.company,
910
- },
911
- 'session-imported',
912
- );
913
- }
914
-
915
- async function validateActiveSession(
916
- options: ValidateSessionOptions = {},
917
- ): Promise<boolean> {
918
- await initialize();
919
- if (!getActiveSession()?.token) {
920
- return false;
921
- }
922
-
923
- const retryCount = options.retryCount ?? 1;
924
- const retryDelayMs = options.retryDelayMs ?? 400;
925
- let refreshAttempted = false;
926
-
927
- for (let attempt = 0; attempt <= retryCount; attempt += 1) {
928
- const activeSession = getActiveSession();
929
-
930
- if (!activeSession?.token) {
931
- return false;
932
- }
933
-
934
- try {
935
- await fetchUserForToken(activeSession.token);
936
- return true;
937
- } catch (error) {
938
- const status =
939
- error instanceof ApiError
940
- ? error.status
941
- : typeof error === 'object' &&
942
- error &&
943
- 'status' in error &&
944
- typeof (error as any).status === 'number'
945
- ? (error as any).status
946
- : undefined;
947
-
948
- if (status === 401 || status === 403) {
949
- if (!refreshAttempted && activeSession.refresh_token) {
950
- refreshAttempted = true;
951
-
952
- try {
953
- await refresh();
954
- } catch {
955
- await expireActiveSession();
956
- return false;
957
- }
958
-
959
- const refreshedSession = getActiveSession();
960
- if (!refreshedSession?.token) {
961
- return false;
962
- }
963
-
964
- try {
965
- await fetchUserForToken(refreshedSession.token);
966
- return true;
967
- } catch {
968
- await expireActiveSession();
969
- return false;
970
- }
971
- }
972
-
973
- if (attempt < retryCount) {
974
- await sleep(retryDelayMs);
975
- continue;
976
- }
977
- await expireActiveSession();
978
- return false;
979
- }
980
-
981
- if (attempt < retryCount) {
982
- await sleep(retryDelayMs);
983
- continue;
984
- }
985
-
986
- return false;
987
- }
988
- }
989
-
990
- return false;
991
- }
992
-
993
- async function syncActiveSessionUser(): Promise<AuthSession | null> {
994
- await initialize();
995
- const currentState = await loadAuthState();
996
- const idx = currentState.activeSessionIndex;
997
- const session = getActiveSessionFromState(currentState);
998
-
999
- if (idx < 0 || !session?.token) {
1000
- return null;
1001
- }
1002
-
1003
- const user = await fetchUserForToken(session.token);
1004
- const updatedSession: AuthSession = {
1005
- ...session,
1006
- user: {
1007
- ...session.user,
1008
- ...user,
1009
- },
1010
- company: user?.company ?? getSessionCompany(session),
1011
- };
1012
-
1013
- const updatedSessions = cloneSessions(currentState.sessions);
1014
- updatedSessions[idx] = updatedSession;
1015
-
1016
- await applyState(
1017
- {
1018
- sessions: updatedSessions,
1019
- activeSessionIndex: idx,
1020
- },
1021
- {
1022
- error: null,
1023
- event: {
1024
- type: 'session-updated',
1025
- session: updatedSession,
1026
- },
1027
- },
1028
- );
1029
-
1030
- return updatedSession;
1031
- }
1032
-
1033
- async function updateSession(
1034
- userId: string,
1035
- company: string | undefined,
1036
- patch: SessionPatch,
1037
- ): Promise<AuthSession | null> {
1038
- await initialize();
1039
- const currentState = await loadAuthState();
1040
- const idx = currentState.sessions.findIndex(
1041
- (session) =>
1042
- session.user.id === userId && getSessionCompany(session) === company,
1043
- );
1044
-
1045
- if (idx === -1) {
1046
- return null;
1047
- }
1048
-
1049
- const currentSession = currentState.sessions[idx];
1050
- const updatedSession =
1051
- typeof patch === 'function'
1052
- ? patch(currentSession)
1053
- : {
1054
- ...currentSession,
1055
- ...patch,
1056
- user: patch.user
1057
- ? {
1058
- ...currentSession.user,
1059
- ...patch.user,
1060
- }
1061
- : currentSession.user,
1062
- company:
1063
- patch.company ??
1064
- patch.user?.company ??
1065
- getSessionCompany(currentSession),
1066
- };
1067
-
1068
- const updatedSessions = cloneSessions(currentState.sessions);
1069
- updatedSessions[idx] = updatedSession;
1070
-
1071
- await applyState(
1072
- {
1073
- sessions: updatedSessions,
1074
- activeSessionIndex: currentState.activeSessionIndex,
1075
- },
1076
- {
1077
- error: null,
1078
- event: {
1079
- type: 'session-updated',
1080
- session: updatedSession,
1081
- },
1082
- },
1083
- );
1084
-
1085
- return updatedSession;
1086
- }
1087
-
1088
- async function expireActiveSession(): Promise<AuthRecoveryState> {
1089
- await initialize();
1090
- const currentState = await loadAuthState();
1091
- const session = getActiveSessionFromState(currentState);
1092
-
1093
- if (!session) {
1094
- return buildRecoveryState(currentState);
1095
- }
1096
-
1097
- const nextState: AuthState = {
1098
- sessions: currentState.sessions.filter(
1099
- (_entry, index) => index !== currentState.activeSessionIndex,
1100
- ),
1101
- activeSessionIndex: -1,
533
+ challenges: session.challenges?.filter((c: any) => c.id !== challengeId) || [],
1102
534
  };
1103
535
 
1104
- await applyState(nextState, {
1105
- expiredSession: session,
1106
- error: null,
1107
- event: {
1108
- type: 'session-expired',
1109
- session,
1110
- },
1111
- });
1112
-
1113
- return buildRecoveryState();
536
+ await saveAuthState({ ...currentState, sessions: updatedSessions });
1114
537
  }
1115
538
 
1116
539
  return {
@@ -1122,42 +545,22 @@ export function createAuth(config: AuthConfig = {}): Auth {
1122
545
  refresh,
1123
546
  getToken,
1124
547
  getActiveSession,
1125
- getSessions: () => cloneSessions(sessions),
548
+ getSessions: () => [...sessions],
1126
549
  getSessionsByCompany: (company: string) =>
1127
- sessions.filter((session) => getSessionCompany(session) === company),
1128
- getState,
1129
- getStatus: () => getStatus(),
1130
- getRecoveryState: () => buildRecoveryState(),
550
+ sessions.filter((s) => s.company === company),
1131
551
  switchToSession,
1132
552
  clearAllSessions,
1133
553
  deleteChallenge,
1134
- importToken,
1135
- validateActiveSession,
1136
- syncActiveSessionUser,
1137
- updateSession,
1138
- expireActiveSession,
1139
554
  subscribe(listener: SessionListener): () => void {
1140
555
  sessionListeners.push(listener);
1141
556
  return () => {
1142
- sessionListeners = sessionListeners.filter((entry) => entry !== listener);
557
+ sessionListeners = sessionListeners.filter((l) => l !== listener);
1143
558
  };
1144
559
  },
1145
560
  subscribeToErrors(listener: ErrorListener): () => void {
1146
561
  errorListeners.push(listener);
1147
562
  return () => {
1148
- errorListeners = errorListeners.filter((entry) => entry !== listener);
1149
- };
1150
- },
1151
- subscribeToState(listener: AuthStateListener): () => void {
1152
- stateListeners.push(listener);
1153
- return () => {
1154
- stateListeners = stateListeners.filter((entry) => entry !== listener);
1155
- };
1156
- },
1157
- subscribeToEvents(listener: AuthEventListener): () => void {
1158
- eventListeners.push(listener);
1159
- return () => {
1160
- eventListeners = eventListeners.filter((entry) => entry !== listener);
563
+ errorListeners = errorListeners.filter((l) => l !== listener);
1161
564
  };
1162
565
  },
1163
566
  get baseUrl() {