sitepong 0.1.12 → 0.2.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
@@ -602,7 +602,7 @@ Native APNs (iOS) and FCM (Android) push notifications, plus iOS Live Activity u
602
602
 
603
603
  #### Token lifecycle
604
604
 
605
- There are two halves to push: the **client SDK** registers device tokens with the SitePong ingest server, and the **server-side Push API** sends notifications to those tokens.
605
+ There are two halves to push: the **client SDK** registers device tokens with the SitePong ingest server, and the **server-side Push API** sends notifications and binds tokens to authenticated users.
606
606
 
607
607
  ```
608
608
  [App launches]
@@ -611,15 +611,19 @@ There are two halves to push: the **client SDK** registers device tokens with th
611
611
 
612
612
  [registerDeviceToken(token, opts)] ← SDK POSTs to /api/push/tokens
613
613
  ↓ with X-API-Key: sp_live_xxx
614
- [Token stored in SitePong]
614
+ [Token stored anonymously in SitePong]
615
615
 
616
- [identify('user-123')] ← SDK auto re-registers token
617
- with user_id (via lazy hook)
618
- [Your backend → POST /api/push/send] server-only sp_push_xxx key
616
+ [User logs in with your backend]
617
+
618
+ [Your backend → POST /api/push/tokens/associate] ← sp_push_xxx + { token, user_id }
619
+
620
+ [Your backend → POST /api/push/send] ← sp_push_xxx + target user_ids
619
621
 
620
622
  [SitePong → APNs / FCM → Device]
621
623
  ```
622
624
 
625
+ > **Why two steps?** Publishable SDK keys (`sp_live_xxx`) are embedded in your app binary and can be extracted by anyone who decompiles the APK/IPA. If the client controlled `user_id`, a leaked SDK key would let an attacker register their own device under your users' IDs and silently receive their push notifications (password resets, OTP codes, order details). User attribution therefore only happens server-to-server with the privileged `sp_push_xxx` key — which stays on your backend.
626
+
623
627
  #### 1. Install permission and get the native token
624
628
 
625
629
  ```bash
@@ -649,26 +653,25 @@ import { Platform } from 'react-native';
649
653
  registerDeviceToken(token, {
650
654
  platform: Platform.OS as 'ios' | 'android',
651
655
  environment: __DEV__ ? 'sandbox' : 'production',
652
- userId: 'user-123', // optional — can be set later via identify()
653
656
  });
654
657
  ```
655
658
 
656
- This makes a `POST /api/push/tokens` request to the ingest server with `X-API-Key: <your SDK key>`. The body includes the token, `token_type` (`apns`/`fcm`), `device_id`, `user_id`, `platform`, app version, device model, and OS version. The server upserts by `(token, environment)` so re-registration is idempotent.
659
+ This makes a `POST /api/push/tokens` request to the ingest server with `X-API-Key: <your SDK key>`. The body includes the token, `token_type` (`apns`/`fcm`), `device_id`, `platform`, app version, device model, and OS version — no `user_id`. The server upserts by `(project_id, token)` so re-registration is idempotent.
657
660
 
658
- #### 3. User identification (automatic)
661
+ #### 3. Associate the token with a user (server-side)
659
662
 
660
- When you call `identify(userId)`, the SDK automatically re-registers all cached push, Live Activity, and push-to-start tokens with the new `user_id`. **You do not need to call `registerDeviceToken()` again after login.**
661
-
662
- ```typescript
663
- import { identify } from '@sitepong/sdk/react-native';
663
+ Once your own backend has authenticated the user, have it POST to SitePong's associate endpoint with your `sp_push_xxx` key. Your app should forward the push token to your backend as part of the login flow.
664
664
 
665
- // Token already registered anonymously at app launch
666
- // Now user logs in:
667
- identify('user-123');
668
- // → SDK re-POSTs /api/push/tokens with user_id: "user-123"
665
+ ```bash
666
+ curl -X POST https://api.sitepong.com/api/push/tokens/associate \
667
+ -H "Authorization: Bearer sp_push_xxxxxxxxxxxxxxxx" \
668
+ -H "Content-Type: application/json" \
669
+ -d '{ "token": "<expo_or_native_token>", "user_id": "user-123" }'
669
670
  ```
670
671
 
671
- The hook is installed lazily the first time any `register*` function is called, so it works whether you use `SitePongRNProvider` or call `initRN()` directly.
672
+ On sign-out, POST the same endpoint with `"user_id": null` to clear the association. Because this call is server-authenticated, an attacker who has scraped the SDK key out of your app cannot impersonate a user.
673
+
674
+ > The older pattern of passing `userId` to `registerDeviceToken()` or `pushUserId` to `SitePongRNProvider` still type-checks for backwards compatibility, but the values are silently ignored on both the client and the server. Migrate to the associate endpoint.
672
675
 
673
676
  #### 4. Send notifications from your backend
674
677
 
@@ -794,6 +797,7 @@ When APNs or FCM reports a token as invalid (app uninstalled, notifications disa
794
797
  | POST | `/api/push/live-activity-tokens` | `X-API-Key: sp_live_*` | `registerLiveActivityToken()` |
795
798
  | POST | `/api/push/push-to-start-tokens` | `X-API-Key: sp_live_*` | `registerPushToStartToken()` |
796
799
  | DELETE | `/api/push/live-activity-tokens` | `X-API-Key: sp_live_*` | `endLiveActivity()` |
800
+ | POST | `/api/push/tokens/associate` | `Authorization: Bearer sp_push_*` | (server-side only) |
797
801
  | POST | `/api/push/send` | `Authorization: Bearer sp_push_*` | (server-side only) |
798
802
  | POST | `/api/push/live-activity` | `Authorization: Bearer sp_push_*` | (server-side only) |
799
803