azirid-react 0.11.3 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1353,6 +1353,28 @@ function createAccessClient(
1353
1353
 
1354
1354
  ---
1355
1355
 
1356
+ ## Device Tracking
1357
+
1358
+ The SDK automatically generates a persistent device ID (UUIDv4) and stores it in `localStorage` under the key `__az_device_id`. This ID is sent as an `X-Device-Id` header on every auth request (login, signup, refresh, bootstrap).
1359
+
1360
+ **How it works:**
1361
+ - On first use, `crypto.randomUUID()` generates a unique ID per browser profile
1362
+ - The ID persists across tabs, page reloads, and browser restarts
1363
+ - Different browsers or incognito windows get different device IDs
1364
+ - The backend uses this to deduplicate sessions per device: re-logging from the same browser replaces the previous session instead of creating duplicates
1365
+
1366
+ **Storage keys used by the SDK:**
1367
+
1368
+ | Key | Storage | Purpose |
1369
+ |-----|---------|---------|
1370
+ | `__az_device_id` | `localStorage` | Persistent device identity (survives browser restarts) |
1371
+ | `__azrt` | `sessionStorage` | Refresh token (per-tab, survives page refresh) |
1372
+ | `__azxc` | `sessionStorage` | CSRF token (per-tab) |
1373
+
1374
+ > **Note:** In SSR or environments where `localStorage` is unavailable, the device ID header is omitted and the backend falls back to user-agent-based fingerprinting.
1375
+
1376
+ ---
1377
+
1356
1378
  ## Next.js Integration
1357
1379
 
1358
1380
  `azirid-react` supports **Next.js 14, 15, and 16+** with full compatibility for each version's API conventions.
package/dist/index.cjs CHANGED
@@ -149,6 +149,20 @@ function createAccessClient(config, appContext) {
149
149
  const paths = config.basePath ? buildPaths(config.basePath) : PATHS;
150
150
  const storageKeyRt = "__azrt";
151
151
  const storageKeyCsrf = "__azxc";
152
+ const storageKeyDeviceId = "__az_device_id";
153
+ function getOrCreateDeviceId() {
154
+ try {
155
+ if (typeof localStorage === "undefined") return null;
156
+ let id = localStorage.getItem(storageKeyDeviceId);
157
+ if (!id) {
158
+ id = crypto.randomUUID();
159
+ localStorage.setItem(storageKeyDeviceId, id);
160
+ }
161
+ return id;
162
+ } catch {
163
+ return null;
164
+ }
165
+ }
152
166
  function ssGet(key) {
153
167
  try {
154
168
  return typeof sessionStorage !== "undefined" ? sessionStorage.getItem(key) : null;
@@ -229,6 +243,8 @@ function createAccessClient(config, appContext) {
229
243
  }
230
244
  const csrf = getCsrfToken();
231
245
  if (csrf) reqHeaders["X-CSRF-Token"] = csrf;
246
+ const devId = getOrCreateDeviceId();
247
+ if (devId) reqHeaders["X-Device-Id"] = devId;
232
248
  const bodyPayload = {};
233
249
  if (refreshToken) {
234
250
  bodyPayload["rt"] = refreshToken;
@@ -291,6 +307,10 @@ function createAccessClient(config, appContext) {
291
307
  if (csrf) {
292
308
  headers["X-CSRF-Token"] = csrf;
293
309
  }
310
+ const devId = getOrCreateDeviceId();
311
+ if (devId) {
312
+ headers["X-Device-Id"] = devId;
313
+ }
294
314
  let requestBody = body;
295
315
  if (isSessionPath && refreshToken) {
296
316
  const existing = typeof body === "object" && body !== null ? body : {};
@@ -337,6 +357,10 @@ function createAccessClient(config, appContext) {
337
357
  if (retryCsrf) {
338
358
  retryHeaders["X-CSRF-Token"] = retryCsrf;
339
359
  }
360
+ const retryDevId = getOrCreateDeviceId();
361
+ if (retryDevId) {
362
+ retryHeaders["X-Device-Id"] = retryDevId;
363
+ }
340
364
  res = await fetch(`${baseUrl}${path}`, {
341
365
  method,
342
366
  headers: retryHeaders,
@@ -4746,7 +4770,7 @@ function usePasswordToggle() {
4746
4770
  }
4747
4771
 
4748
4772
  // src/index.ts
4749
- var SDK_VERSION = "0.11.3";
4773
+ var SDK_VERSION = "0.12.0";
4750
4774
 
4751
4775
  exports.AuthForm = AuthForm;
4752
4776
  exports.AziridProvider = AziridProvider;