@sendoracloud/sdk-react-native 1.25.0 → 1.27.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/dist/index.cjs +67 -1
- package/dist/index.d.cts +49 -1
- package/dist/index.d.ts +49 -1
- package/dist/index.js +67 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -202,7 +202,7 @@ var Storage = class {
|
|
|
202
202
|
// package.json
|
|
203
203
|
var package_default = {
|
|
204
204
|
name: "@sendoracloud/sdk-react-native",
|
|
205
|
-
version: "1.
|
|
205
|
+
version: "1.27.0",
|
|
206
206
|
description: "Sendora Cloud React Native + Expo SDK \u2014 analytics, identity, push-token registration, auth (incl. Game Center / Play Games), deep links (Branch / Firebase Dynamic Links parity). Auth + analytics + deep links work in Expo Go; push-token registration and the no-arg Game Center / Play Games sign-in require a Dev Client (EAS Build or `npx expo prebuild`).",
|
|
207
207
|
type: "module",
|
|
208
208
|
main: "./dist/index.cjs",
|
|
@@ -510,6 +510,8 @@ var Auth = class {
|
|
|
510
510
|
this.refreshFailureCount = 0;
|
|
511
511
|
this.refreshCooldownUntil = 0;
|
|
512
512
|
this.takeoverListeners = /* @__PURE__ */ new Set();
|
|
513
|
+
this.deletionCancelledListeners = /* @__PURE__ */ new Set();
|
|
514
|
+
this.lastDeletionCancelled = null;
|
|
513
515
|
this.lastTakeover = null;
|
|
514
516
|
/**
|
|
515
517
|
* Anon refresh token captured at `signIn()` time, stashed keyed to the
|
|
@@ -622,6 +624,36 @@ var Auth = class {
|
|
|
622
624
|
}
|
|
623
625
|
}
|
|
624
626
|
}
|
|
627
|
+
/**
|
|
628
|
+
* Subscribe to deletion-cancelled events (s58.269): fires when a sign-in
|
|
629
|
+
* cancelled a pending self-service account deletion within its grace window
|
|
630
|
+
* (the account is restored, same user_id). Use it to show "your account
|
|
631
|
+
* deletion was cancelled" + reconcile local state. Fires from signIn /
|
|
632
|
+
* loginSocial / signInWithGameCenter / signInWithPlayGames. Returns an
|
|
633
|
+
* unsubscribe function; listener errors are swallowed (best-effort).
|
|
634
|
+
*/
|
|
635
|
+
onDeletionCancelled(listener) {
|
|
636
|
+
this.deletionCancelledListeners.add(listener);
|
|
637
|
+
return () => {
|
|
638
|
+
this.deletionCancelledListeners.delete(listener);
|
|
639
|
+
};
|
|
640
|
+
}
|
|
641
|
+
/** The most recent deletion-cancelled event this session, or null. Cleared on signOut. */
|
|
642
|
+
getLastDeletionCancelled() {
|
|
643
|
+
return this.lastDeletionCancelled;
|
|
644
|
+
}
|
|
645
|
+
/** Internal — fan out deletion-cancelled to subscribers + cache the latest. */
|
|
646
|
+
fireDeletionCancelled(userId) {
|
|
647
|
+
const evt = { userId, at: /* @__PURE__ */ new Date() };
|
|
648
|
+
this.lastDeletionCancelled = evt;
|
|
649
|
+
for (const fn of this.deletionCancelledListeners) {
|
|
650
|
+
try {
|
|
651
|
+
fn(evt);
|
|
652
|
+
} catch (err) {
|
|
653
|
+
if (this.hooks.debug) console.warn("[sendoracloud] onDeletionCancelled listener threw", err);
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
}
|
|
625
657
|
/**
|
|
626
658
|
* Returns a VALID (non-expired) access token, or null.
|
|
627
659
|
*
|
|
@@ -952,6 +984,36 @@ var Auth = class {
|
|
|
952
984
|
this.user = user;
|
|
953
985
|
this.hooks.storage.set(USER_KEY, JSON.stringify(user));
|
|
954
986
|
}
|
|
987
|
+
/**
|
|
988
|
+
* List the auth methods/identities linked to the current account (ADR-030
|
|
989
|
+
* read side, s58.270). Returns every social/gaming identity on this account
|
|
990
|
+
* plus a `hasPassword` flag — the cross-device / reinstall-durable source of
|
|
991
|
+
* truth for a "Connected: Game Center · Google" UI (an on-device tracker
|
|
992
|
+
* misses a link made on another device). Bearer-gated network read (NOT a
|
|
993
|
+
* cache read — `getUserSync()` only holds the primary `signupMethod`/
|
|
994
|
+
* `lastLoginMethod`). Resolves a FRESH access token first (mirrors
|
|
995
|
+
* `deleteAccount`). Firebase `user.providerData` / Supabase `user.identities`.
|
|
996
|
+
*/
|
|
997
|
+
async listLinkedIdentities() {
|
|
998
|
+
const token = await this.getAccessToken();
|
|
999
|
+
if (!token) throw new AuthError("NOT_SIGNED_IN", "Sign in before listing linked identities");
|
|
1000
|
+
const res = await getJson(
|
|
1001
|
+
{ apiUrl: this.hooks.apiUrl, publicKey: this.hooks.publicKey, debug: this.hooks.debug },
|
|
1002
|
+
"/api/v1/auth-service/me/identities",
|
|
1003
|
+
{ Authorization: `Bearer ${token}` }
|
|
1004
|
+
);
|
|
1005
|
+
if (!res || !res.ok) throw new AuthError("NETWORK_ERROR", "Failed to list linked identities");
|
|
1006
|
+
let parsed;
|
|
1007
|
+
try {
|
|
1008
|
+
parsed = await res.json();
|
|
1009
|
+
} catch {
|
|
1010
|
+
throw new AuthError("PARSE_ERROR", `HTTP ${res.status}`);
|
|
1011
|
+
}
|
|
1012
|
+
if (!parsed.success || !parsed.data) {
|
|
1013
|
+
throw new AuthError(parsed.error?.code ?? "IDENTITIES_FAILED", parsed.error?.message ?? "Failed to list linked identities");
|
|
1014
|
+
}
|
|
1015
|
+
return { identities: parsed.data.identities ?? [], hasPassword: Boolean(parsed.data.hasPassword) };
|
|
1016
|
+
}
|
|
955
1017
|
/**
|
|
956
1018
|
* Shared gaming-identity sign-in. Mirrors `loginSocial`'s anon-takeover +
|
|
957
1019
|
* ADR-025 link-in-place handling: reads the anon refresh BEFORE wiping local
|
|
@@ -1599,12 +1661,16 @@ var Auth = class {
|
|
|
1599
1661
|
if (data.retiredAnonUserId) {
|
|
1600
1662
|
this.fireDeviceTakeover(data.retiredAnonUserId, data.user.id);
|
|
1601
1663
|
}
|
|
1664
|
+
if (data.reactivatedFromDeletion) {
|
|
1665
|
+
this.fireDeletionCancelled(data.user.id);
|
|
1666
|
+
}
|
|
1602
1667
|
}
|
|
1603
1668
|
async wipeLocalIdentity() {
|
|
1604
1669
|
this.user = null;
|
|
1605
1670
|
this.accessToken = null;
|
|
1606
1671
|
this.accessExpiresAt = 0;
|
|
1607
1672
|
this.lastTakeover = null;
|
|
1673
|
+
this.lastDeletionCancelled = null;
|
|
1608
1674
|
this.pendingAnonTakeover = null;
|
|
1609
1675
|
this.hooks.storage.remove(USER_KEY);
|
|
1610
1676
|
this.hooks.storage.remove(TOKEN_KEY);
|
package/dist/index.d.cts
CHANGED
|
@@ -310,6 +310,17 @@ declare class AlreadyIdentifiedError extends Error {
|
|
|
310
310
|
declare class CredentialInUseError extends Error {
|
|
311
311
|
constructor(message?: string);
|
|
312
312
|
}
|
|
313
|
+
/** One credential linked to an account (ADR-030 read side, s58.270). */
|
|
314
|
+
type LinkedIdentity = {
|
|
315
|
+
provider: string;
|
|
316
|
+
email: string | null;
|
|
317
|
+
linkedAt: string;
|
|
318
|
+
};
|
|
319
|
+
/** Response of `auth.listLinkedIdentities()` — the full connected-account set. */
|
|
320
|
+
type LinkedIdentitiesResponse = {
|
|
321
|
+
identities: LinkedIdentity[];
|
|
322
|
+
hasPassword: boolean;
|
|
323
|
+
};
|
|
313
324
|
declare class AuthError extends Error {
|
|
314
325
|
code: string;
|
|
315
326
|
constructor(code: string, message: string);
|
|
@@ -344,6 +355,17 @@ interface DeviceTakeoverEvent {
|
|
|
344
355
|
/** Local clock at the time the SDK observed the event. */
|
|
345
356
|
at: Date;
|
|
346
357
|
}
|
|
358
|
+
/**
|
|
359
|
+
* Detail handed to `onDeletionCancelled` subscribers (s58.269). Fires once
|
|
360
|
+
* per sign-in that cancelled a pending self-service deletion within grace —
|
|
361
|
+
* the account is restored with the SAME user_id.
|
|
362
|
+
*/
|
|
363
|
+
interface DeletionCancelledEvent {
|
|
364
|
+
/** The restored user_id (unchanged — this is a status flip, not a remap). */
|
|
365
|
+
userId: string;
|
|
366
|
+
/** Local clock at the time the SDK observed the event. */
|
|
367
|
+
at: Date;
|
|
368
|
+
}
|
|
347
369
|
declare class Auth {
|
|
348
370
|
private hooks;
|
|
349
371
|
private user;
|
|
@@ -365,6 +387,8 @@ declare class Auth {
|
|
|
365
387
|
private refreshFailureCount;
|
|
366
388
|
private refreshCooldownUntil;
|
|
367
389
|
private takeoverListeners;
|
|
390
|
+
private deletionCancelledListeners;
|
|
391
|
+
private lastDeletionCancelled;
|
|
368
392
|
private lastTakeover;
|
|
369
393
|
/**
|
|
370
394
|
* Anon refresh token captured at `signIn()` time, stashed keyed to the
|
|
@@ -434,6 +458,19 @@ declare class Auth {
|
|
|
434
458
|
getLastDeviceTakeover(): DeviceTakeoverEvent | null;
|
|
435
459
|
/** Internal — fan out to subscribers + cache the latest. */
|
|
436
460
|
private fireDeviceTakeover;
|
|
461
|
+
/**
|
|
462
|
+
* Subscribe to deletion-cancelled events (s58.269): fires when a sign-in
|
|
463
|
+
* cancelled a pending self-service account deletion within its grace window
|
|
464
|
+
* (the account is restored, same user_id). Use it to show "your account
|
|
465
|
+
* deletion was cancelled" + reconcile local state. Fires from signIn /
|
|
466
|
+
* loginSocial / signInWithGameCenter / signInWithPlayGames. Returns an
|
|
467
|
+
* unsubscribe function; listener errors are swallowed (best-effort).
|
|
468
|
+
*/
|
|
469
|
+
onDeletionCancelled(listener: (evt: DeletionCancelledEvent) => void): () => void;
|
|
470
|
+
/** The most recent deletion-cancelled event this session, or null. Cleared on signOut. */
|
|
471
|
+
getLastDeletionCancelled(): DeletionCancelledEvent | null;
|
|
472
|
+
/** Internal — fan out deletion-cancelled to subscribers + cache the latest. */
|
|
473
|
+
private fireDeletionCancelled;
|
|
437
474
|
/**
|
|
438
475
|
* Returns a VALID (non-expired) access token, or null.
|
|
439
476
|
*
|
|
@@ -650,6 +687,17 @@ declare class Auth {
|
|
|
650
687
|
* user object + its storage copy are updated (no token/identity rotation).
|
|
651
688
|
*/
|
|
652
689
|
private updateLocalUser;
|
|
690
|
+
/**
|
|
691
|
+
* List the auth methods/identities linked to the current account (ADR-030
|
|
692
|
+
* read side, s58.270). Returns every social/gaming identity on this account
|
|
693
|
+
* plus a `hasPassword` flag — the cross-device / reinstall-durable source of
|
|
694
|
+
* truth for a "Connected: Game Center · Google" UI (an on-device tracker
|
|
695
|
+
* misses a link made on another device). Bearer-gated network read (NOT a
|
|
696
|
+
* cache read — `getUserSync()` only holds the primary `signupMethod`/
|
|
697
|
+
* `lastLoginMethod`). Resolves a FRESH access token first (mirrors
|
|
698
|
+
* `deleteAccount`). Firebase `user.providerData` / Supabase `user.identities`.
|
|
699
|
+
*/
|
|
700
|
+
listLinkedIdentities(): Promise<LinkedIdentitiesResponse>;
|
|
653
701
|
/**
|
|
654
702
|
* Shared gaming-identity sign-in. Mirrors `loginSocial`'s anon-takeover +
|
|
655
703
|
* ADR-025 link-in-place handling: reads the anon refresh BEFORE wiping local
|
|
@@ -1625,4 +1673,4 @@ declare class SendoraSDK {
|
|
|
1625
1673
|
}
|
|
1626
1674
|
declare const SendoraCloud: SendoraSDK;
|
|
1627
1675
|
|
|
1628
|
-
export { AlreadyIdentifiedError, type AttachLinkingApiOptions, Auth, AuthError, type AuthTokens, type AuthUser, CredentialInUseError, EmailAlreadyTakenError, type IdentifyTraits, type LinkCreateInput, type LinkCreateResult, type LinkData, LinkError, type LinkErrorCode, type LinkMatchInput, type LinkOpenedEvent, type LinkOpenedHandler, type LinkStats, Links, type PushTokenReceipt, type PushTokenRegistration, SendoraCloud, type SendoraConfig, type TrackProperties, computeDeviceFingerprint, SendoraCloud as default, extractShortcodeFromUrl, getPlayInstallReferrer };
|
|
1676
|
+
export { AlreadyIdentifiedError, type AttachLinkingApiOptions, Auth, AuthError, type AuthTokens, type AuthUser, CredentialInUseError, EmailAlreadyTakenError, type IdentifyTraits, type LinkCreateInput, type LinkCreateResult, type LinkData, LinkError, type LinkErrorCode, type LinkMatchInput, type LinkOpenedEvent, type LinkOpenedHandler, type LinkStats, type LinkedIdentitiesResponse, type LinkedIdentity, Links, type PushTokenReceipt, type PushTokenRegistration, SendoraCloud, type SendoraConfig, type TrackProperties, computeDeviceFingerprint, SendoraCloud as default, extractShortcodeFromUrl, getPlayInstallReferrer };
|
package/dist/index.d.ts
CHANGED
|
@@ -310,6 +310,17 @@ declare class AlreadyIdentifiedError extends Error {
|
|
|
310
310
|
declare class CredentialInUseError extends Error {
|
|
311
311
|
constructor(message?: string);
|
|
312
312
|
}
|
|
313
|
+
/** One credential linked to an account (ADR-030 read side, s58.270). */
|
|
314
|
+
type LinkedIdentity = {
|
|
315
|
+
provider: string;
|
|
316
|
+
email: string | null;
|
|
317
|
+
linkedAt: string;
|
|
318
|
+
};
|
|
319
|
+
/** Response of `auth.listLinkedIdentities()` — the full connected-account set. */
|
|
320
|
+
type LinkedIdentitiesResponse = {
|
|
321
|
+
identities: LinkedIdentity[];
|
|
322
|
+
hasPassword: boolean;
|
|
323
|
+
};
|
|
313
324
|
declare class AuthError extends Error {
|
|
314
325
|
code: string;
|
|
315
326
|
constructor(code: string, message: string);
|
|
@@ -344,6 +355,17 @@ interface DeviceTakeoverEvent {
|
|
|
344
355
|
/** Local clock at the time the SDK observed the event. */
|
|
345
356
|
at: Date;
|
|
346
357
|
}
|
|
358
|
+
/**
|
|
359
|
+
* Detail handed to `onDeletionCancelled` subscribers (s58.269). Fires once
|
|
360
|
+
* per sign-in that cancelled a pending self-service deletion within grace —
|
|
361
|
+
* the account is restored with the SAME user_id.
|
|
362
|
+
*/
|
|
363
|
+
interface DeletionCancelledEvent {
|
|
364
|
+
/** The restored user_id (unchanged — this is a status flip, not a remap). */
|
|
365
|
+
userId: string;
|
|
366
|
+
/** Local clock at the time the SDK observed the event. */
|
|
367
|
+
at: Date;
|
|
368
|
+
}
|
|
347
369
|
declare class Auth {
|
|
348
370
|
private hooks;
|
|
349
371
|
private user;
|
|
@@ -365,6 +387,8 @@ declare class Auth {
|
|
|
365
387
|
private refreshFailureCount;
|
|
366
388
|
private refreshCooldownUntil;
|
|
367
389
|
private takeoverListeners;
|
|
390
|
+
private deletionCancelledListeners;
|
|
391
|
+
private lastDeletionCancelled;
|
|
368
392
|
private lastTakeover;
|
|
369
393
|
/**
|
|
370
394
|
* Anon refresh token captured at `signIn()` time, stashed keyed to the
|
|
@@ -434,6 +458,19 @@ declare class Auth {
|
|
|
434
458
|
getLastDeviceTakeover(): DeviceTakeoverEvent | null;
|
|
435
459
|
/** Internal — fan out to subscribers + cache the latest. */
|
|
436
460
|
private fireDeviceTakeover;
|
|
461
|
+
/**
|
|
462
|
+
* Subscribe to deletion-cancelled events (s58.269): fires when a sign-in
|
|
463
|
+
* cancelled a pending self-service account deletion within its grace window
|
|
464
|
+
* (the account is restored, same user_id). Use it to show "your account
|
|
465
|
+
* deletion was cancelled" + reconcile local state. Fires from signIn /
|
|
466
|
+
* loginSocial / signInWithGameCenter / signInWithPlayGames. Returns an
|
|
467
|
+
* unsubscribe function; listener errors are swallowed (best-effort).
|
|
468
|
+
*/
|
|
469
|
+
onDeletionCancelled(listener: (evt: DeletionCancelledEvent) => void): () => void;
|
|
470
|
+
/** The most recent deletion-cancelled event this session, or null. Cleared on signOut. */
|
|
471
|
+
getLastDeletionCancelled(): DeletionCancelledEvent | null;
|
|
472
|
+
/** Internal — fan out deletion-cancelled to subscribers + cache the latest. */
|
|
473
|
+
private fireDeletionCancelled;
|
|
437
474
|
/**
|
|
438
475
|
* Returns a VALID (non-expired) access token, or null.
|
|
439
476
|
*
|
|
@@ -650,6 +687,17 @@ declare class Auth {
|
|
|
650
687
|
* user object + its storage copy are updated (no token/identity rotation).
|
|
651
688
|
*/
|
|
652
689
|
private updateLocalUser;
|
|
690
|
+
/**
|
|
691
|
+
* List the auth methods/identities linked to the current account (ADR-030
|
|
692
|
+
* read side, s58.270). Returns every social/gaming identity on this account
|
|
693
|
+
* plus a `hasPassword` flag — the cross-device / reinstall-durable source of
|
|
694
|
+
* truth for a "Connected: Game Center · Google" UI (an on-device tracker
|
|
695
|
+
* misses a link made on another device). Bearer-gated network read (NOT a
|
|
696
|
+
* cache read — `getUserSync()` only holds the primary `signupMethod`/
|
|
697
|
+
* `lastLoginMethod`). Resolves a FRESH access token first (mirrors
|
|
698
|
+
* `deleteAccount`). Firebase `user.providerData` / Supabase `user.identities`.
|
|
699
|
+
*/
|
|
700
|
+
listLinkedIdentities(): Promise<LinkedIdentitiesResponse>;
|
|
653
701
|
/**
|
|
654
702
|
* Shared gaming-identity sign-in. Mirrors `loginSocial`'s anon-takeover +
|
|
655
703
|
* ADR-025 link-in-place handling: reads the anon refresh BEFORE wiping local
|
|
@@ -1625,4 +1673,4 @@ declare class SendoraSDK {
|
|
|
1625
1673
|
}
|
|
1626
1674
|
declare const SendoraCloud: SendoraSDK;
|
|
1627
1675
|
|
|
1628
|
-
export { AlreadyIdentifiedError, type AttachLinkingApiOptions, Auth, AuthError, type AuthTokens, type AuthUser, CredentialInUseError, EmailAlreadyTakenError, type IdentifyTraits, type LinkCreateInput, type LinkCreateResult, type LinkData, LinkError, type LinkErrorCode, type LinkMatchInput, type LinkOpenedEvent, type LinkOpenedHandler, type LinkStats, Links, type PushTokenReceipt, type PushTokenRegistration, SendoraCloud, type SendoraConfig, type TrackProperties, computeDeviceFingerprint, SendoraCloud as default, extractShortcodeFromUrl, getPlayInstallReferrer };
|
|
1676
|
+
export { AlreadyIdentifiedError, type AttachLinkingApiOptions, Auth, AuthError, type AuthTokens, type AuthUser, CredentialInUseError, EmailAlreadyTakenError, type IdentifyTraits, type LinkCreateInput, type LinkCreateResult, type LinkData, LinkError, type LinkErrorCode, type LinkMatchInput, type LinkOpenedEvent, type LinkOpenedHandler, type LinkStats, type LinkedIdentitiesResponse, type LinkedIdentity, Links, type PushTokenReceipt, type PushTokenRegistration, SendoraCloud, type SendoraConfig, type TrackProperties, computeDeviceFingerprint, SendoraCloud as default, extractShortcodeFromUrl, getPlayInstallReferrer };
|
package/dist/index.js
CHANGED
|
@@ -157,7 +157,7 @@ var Storage = class {
|
|
|
157
157
|
// package.json
|
|
158
158
|
var package_default = {
|
|
159
159
|
name: "@sendoracloud/sdk-react-native",
|
|
160
|
-
version: "1.
|
|
160
|
+
version: "1.27.0",
|
|
161
161
|
description: "Sendora Cloud React Native + Expo SDK \u2014 analytics, identity, push-token registration, auth (incl. Game Center / Play Games), deep links (Branch / Firebase Dynamic Links parity). Auth + analytics + deep links work in Expo Go; push-token registration and the no-arg Game Center / Play Games sign-in require a Dev Client (EAS Build or `npx expo prebuild`).",
|
|
162
162
|
type: "module",
|
|
163
163
|
main: "./dist/index.cjs",
|
|
@@ -465,6 +465,8 @@ var Auth = class {
|
|
|
465
465
|
this.refreshFailureCount = 0;
|
|
466
466
|
this.refreshCooldownUntil = 0;
|
|
467
467
|
this.takeoverListeners = /* @__PURE__ */ new Set();
|
|
468
|
+
this.deletionCancelledListeners = /* @__PURE__ */ new Set();
|
|
469
|
+
this.lastDeletionCancelled = null;
|
|
468
470
|
this.lastTakeover = null;
|
|
469
471
|
/**
|
|
470
472
|
* Anon refresh token captured at `signIn()` time, stashed keyed to the
|
|
@@ -577,6 +579,36 @@ var Auth = class {
|
|
|
577
579
|
}
|
|
578
580
|
}
|
|
579
581
|
}
|
|
582
|
+
/**
|
|
583
|
+
* Subscribe to deletion-cancelled events (s58.269): fires when a sign-in
|
|
584
|
+
* cancelled a pending self-service account deletion within its grace window
|
|
585
|
+
* (the account is restored, same user_id). Use it to show "your account
|
|
586
|
+
* deletion was cancelled" + reconcile local state. Fires from signIn /
|
|
587
|
+
* loginSocial / signInWithGameCenter / signInWithPlayGames. Returns an
|
|
588
|
+
* unsubscribe function; listener errors are swallowed (best-effort).
|
|
589
|
+
*/
|
|
590
|
+
onDeletionCancelled(listener) {
|
|
591
|
+
this.deletionCancelledListeners.add(listener);
|
|
592
|
+
return () => {
|
|
593
|
+
this.deletionCancelledListeners.delete(listener);
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
/** The most recent deletion-cancelled event this session, or null. Cleared on signOut. */
|
|
597
|
+
getLastDeletionCancelled() {
|
|
598
|
+
return this.lastDeletionCancelled;
|
|
599
|
+
}
|
|
600
|
+
/** Internal — fan out deletion-cancelled to subscribers + cache the latest. */
|
|
601
|
+
fireDeletionCancelled(userId) {
|
|
602
|
+
const evt = { userId, at: /* @__PURE__ */ new Date() };
|
|
603
|
+
this.lastDeletionCancelled = evt;
|
|
604
|
+
for (const fn of this.deletionCancelledListeners) {
|
|
605
|
+
try {
|
|
606
|
+
fn(evt);
|
|
607
|
+
} catch (err) {
|
|
608
|
+
if (this.hooks.debug) console.warn("[sendoracloud] onDeletionCancelled listener threw", err);
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
}
|
|
580
612
|
/**
|
|
581
613
|
* Returns a VALID (non-expired) access token, or null.
|
|
582
614
|
*
|
|
@@ -907,6 +939,36 @@ var Auth = class {
|
|
|
907
939
|
this.user = user;
|
|
908
940
|
this.hooks.storage.set(USER_KEY, JSON.stringify(user));
|
|
909
941
|
}
|
|
942
|
+
/**
|
|
943
|
+
* List the auth methods/identities linked to the current account (ADR-030
|
|
944
|
+
* read side, s58.270). Returns every social/gaming identity on this account
|
|
945
|
+
* plus a `hasPassword` flag — the cross-device / reinstall-durable source of
|
|
946
|
+
* truth for a "Connected: Game Center · Google" UI (an on-device tracker
|
|
947
|
+
* misses a link made on another device). Bearer-gated network read (NOT a
|
|
948
|
+
* cache read — `getUserSync()` only holds the primary `signupMethod`/
|
|
949
|
+
* `lastLoginMethod`). Resolves a FRESH access token first (mirrors
|
|
950
|
+
* `deleteAccount`). Firebase `user.providerData` / Supabase `user.identities`.
|
|
951
|
+
*/
|
|
952
|
+
async listLinkedIdentities() {
|
|
953
|
+
const token = await this.getAccessToken();
|
|
954
|
+
if (!token) throw new AuthError("NOT_SIGNED_IN", "Sign in before listing linked identities");
|
|
955
|
+
const res = await getJson(
|
|
956
|
+
{ apiUrl: this.hooks.apiUrl, publicKey: this.hooks.publicKey, debug: this.hooks.debug },
|
|
957
|
+
"/api/v1/auth-service/me/identities",
|
|
958
|
+
{ Authorization: `Bearer ${token}` }
|
|
959
|
+
);
|
|
960
|
+
if (!res || !res.ok) throw new AuthError("NETWORK_ERROR", "Failed to list linked identities");
|
|
961
|
+
let parsed;
|
|
962
|
+
try {
|
|
963
|
+
parsed = await res.json();
|
|
964
|
+
} catch {
|
|
965
|
+
throw new AuthError("PARSE_ERROR", `HTTP ${res.status}`);
|
|
966
|
+
}
|
|
967
|
+
if (!parsed.success || !parsed.data) {
|
|
968
|
+
throw new AuthError(parsed.error?.code ?? "IDENTITIES_FAILED", parsed.error?.message ?? "Failed to list linked identities");
|
|
969
|
+
}
|
|
970
|
+
return { identities: parsed.data.identities ?? [], hasPassword: Boolean(parsed.data.hasPassword) };
|
|
971
|
+
}
|
|
910
972
|
/**
|
|
911
973
|
* Shared gaming-identity sign-in. Mirrors `loginSocial`'s anon-takeover +
|
|
912
974
|
* ADR-025 link-in-place handling: reads the anon refresh BEFORE wiping local
|
|
@@ -1554,12 +1616,16 @@ var Auth = class {
|
|
|
1554
1616
|
if (data.retiredAnonUserId) {
|
|
1555
1617
|
this.fireDeviceTakeover(data.retiredAnonUserId, data.user.id);
|
|
1556
1618
|
}
|
|
1619
|
+
if (data.reactivatedFromDeletion) {
|
|
1620
|
+
this.fireDeletionCancelled(data.user.id);
|
|
1621
|
+
}
|
|
1557
1622
|
}
|
|
1558
1623
|
async wipeLocalIdentity() {
|
|
1559
1624
|
this.user = null;
|
|
1560
1625
|
this.accessToken = null;
|
|
1561
1626
|
this.accessExpiresAt = 0;
|
|
1562
1627
|
this.lastTakeover = null;
|
|
1628
|
+
this.lastDeletionCancelled = null;
|
|
1563
1629
|
this.pendingAnonTakeover = null;
|
|
1564
1630
|
this.hooks.storage.remove(USER_KEY);
|
|
1565
1631
|
this.hooks.storage.remove(TOKEN_KEY);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sendoracloud/sdk-react-native",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.27.0",
|
|
4
4
|
"description": "Sendora Cloud React Native + Expo SDK — analytics, identity, push-token registration, auth (incl. Game Center / Play Games), deep links (Branch / Firebase Dynamic Links parity). Auth + analytics + deep links work in Expo Go; push-token registration and the no-arg Game Center / Play Games sign-in require a Dev Client (EAS Build or `npx expo prebuild`).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|