feat(auth): Google/Apple login, named custom providers, identity link/unlink
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: rudder-web-sdk
|
||||
description: Use when working with the Rudder TypeScript/JavaScript SDK (@rudder/js-sdk) — the browser/player-facing SDK for the Rudder LiveOps platform. Covers client setup, device/custom auth, observable domains (player, inventory, catalog, stores, remote config, storage), leaderboards, quests, battle pass, scenario effects, and error handling. Load this whenever code imports from @rudder/js-sdk or RudderClient appears.
|
||||
description: Use when working with the Rudder TypeScript/JavaScript SDK (@rudder/js-sdk) — the browser/player-facing SDK for the Rudder LiveOps platform. Covers client setup, device/google/apple/custom auth, identity linking, observable domains (player, inventory, catalog, stores, remote config, storage), leaderboards, quests, battle pass, scenario effects, and error handling. Load this whenever code imports from @rudder/js-sdk or RudderClient appears.
|
||||
---
|
||||
|
||||
# Rudder Web SDK (@rudder/js-sdk)
|
||||
@@ -51,12 +51,22 @@ drop cached state.
|
||||
|
||||
```ts
|
||||
await client.auth.loginWithDevice({ region, language, nickname }); // device id auto-generated/persisted
|
||||
await client.auth.loginWithCustom({ customData, region, language, nickname });
|
||||
await client.auth.loginWithGoogle({ idToken, region, language, nickname });
|
||||
await client.auth.loginWithApple({ idToken, region, language, nickname });
|
||||
await client.auth.loginWithCustom({ customData, provider?, region, language, nickname });
|
||||
// identity linking (requires an active session):
|
||||
await client.auth.linkWithGoogle(idToken);
|
||||
await client.auth.linkWithApple(idToken);
|
||||
await client.auth.linkWithCustom({ customData, provider? });
|
||||
await client.auth.unlinkIdentity(provider); // 'device' | 'google' | 'apple' | 'custom' | 'custom:<name>'
|
||||
client.auth.logout();
|
||||
client.auth.isAuthenticated; // boolean
|
||||
client.auth.onAuthStateChange(cb); // fires immediately, returns unsubscribe
|
||||
```
|
||||
|
||||
Linked identities are listed on the profile: `client.player.data.identities`
|
||||
(`PlayerProfileIdentity { provider, subject, createdAt }`).
|
||||
|
||||
Tokens are saved to the `TokenStore` automatically. The transport injects
|
||||
`Authorization: Bearer <token>`, retries GETs, and single-flight refreshes on
|
||||
401; a failed refresh clears tokens and emits `signed-out`. Details:
|
||||
|
||||
@@ -1,14 +1,20 @@
|
||||
# Auth — `client.auth`
|
||||
|
||||
`AuthService` (source: `src/auth/AuthService.ts`). Player authentication:
|
||||
device ID login (primary for game clients), custom webhook login, logout, and
|
||||
auth state observation.
|
||||
device ID login (primary for game clients), Google / Apple sign-in, custom
|
||||
webhook login, identity linking/unlinking, logout, and auth state observation.
|
||||
|
||||
## Methods
|
||||
|
||||
```ts
|
||||
loginWithDevice(options?: LoginWithDeviceOptions): Promise<LoginViaDeviceResponse>
|
||||
loginWithGoogle(options: LoginWithGoogleOptions): Promise<LoginViaGoogleResponse>
|
||||
loginWithApple(options: LoginWithAppleOptions): Promise<LoginViaAppleResponse>
|
||||
loginWithCustom(options: LoginWithCustomOptions): Promise<LoginViaCustomResponse>
|
||||
linkWithGoogle(idToken: string): Promise<void>
|
||||
linkWithApple(idToken: string): Promise<void>
|
||||
linkWithCustom(options: LinkWithCustomOptions): Promise<void>
|
||||
unlinkIdentity(provider: string): Promise<void>
|
||||
logout(): void
|
||||
get isAuthenticated(): boolean
|
||||
onAuthStateChange(listener: AuthStateListener): () => void
|
||||
@@ -28,11 +34,27 @@ The device ID is auto-generated on first call and persisted in localStorage
|
||||
(`src/device/DeviceId.ts`). The request also carries the client's
|
||||
`projectKey`.
|
||||
|
||||
### `LoginWithGoogleOptions` / `LoginWithAppleOptions`
|
||||
|
||||
```ts
|
||||
{
|
||||
idToken: string; // required — Google ID token / Apple identity token
|
||||
region?: string; // default 'global'
|
||||
language?: string; // default 'en'
|
||||
nickname?: string; // omitted from the request when not set
|
||||
}
|
||||
```
|
||||
|
||||
The client obtains the `idToken` from the provider's own sign-in flow
|
||||
(Google Identity Services, Sign in with Apple) and forwards it to
|
||||
`POST /sdk/v1/authorization/google` or `/sdk/v1/authorization/apple`.
|
||||
|
||||
### `LoginWithCustomOptions`
|
||||
|
||||
```ts
|
||||
{
|
||||
customData: Record<string, unknown>; // required — forwarded to the project's custom auth webhook
|
||||
provider?: string; // custom provider name; omitted = the default provider
|
||||
region?: string; // default 'global'
|
||||
language?: string; // default 'en'
|
||||
nickname?: string;
|
||||
@@ -43,6 +65,8 @@ The device ID is auto-generated on first call and persisted in localStorage
|
||||
|
||||
```ts
|
||||
interface LoginViaDeviceResponse { accessToken?: string; refreshToken?: string }
|
||||
interface LoginViaGoogleResponse { accessToken?: string; refreshToken?: string }
|
||||
interface LoginViaAppleResponse { accessToken?: string; refreshToken?: string }
|
||||
interface LoginViaCustomResponse { accessToken?: string; refreshToken?: string }
|
||||
```
|
||||
|
||||
@@ -50,6 +74,36 @@ On success both tokens are saved to the client's `TokenStore`, the runtime
|
||||
starts (domains warmed, scenario engine restored, `player_login` event fired),
|
||||
and the state flips to `'signed-in'`.
|
||||
|
||||
## Identity linking
|
||||
|
||||
`linkWithGoogle` / `linkWithApple` / `linkWithCustom` attach an additional
|
||||
identity to the currently signed-in player; `unlinkIdentity` detaches one.
|
||||
All four require an active session — the access token is sent automatically
|
||||
(transport level). They return nothing (HTTP 204).
|
||||
|
||||
```ts
|
||||
await client.auth.linkWithGoogle(idToken);
|
||||
await client.auth.linkWithApple(idToken);
|
||||
await client.auth.linkWithCustom({ customData, provider }); // provider optional
|
||||
await client.auth.unlinkIdentity('custom:my-backend');
|
||||
```
|
||||
|
||||
### `LinkWithCustomOptions`
|
||||
|
||||
```ts
|
||||
{
|
||||
customData: Record<string, unknown>; // required
|
||||
provider?: string; // custom provider name; omitted = the default provider
|
||||
}
|
||||
```
|
||||
|
||||
`unlinkIdentity(provider)` takes the full provider string: `device`,
|
||||
`google`, `apple`, `custom`, or `custom:<name>`.
|
||||
|
||||
Linked identities appear on the player profile:
|
||||
`client.player.data.identities: PlayerProfileIdentity[]` with
|
||||
`{ provider: string; subject: string; createdAt: string }`.
|
||||
|
||||
## Environments
|
||||
|
||||
A project has two environments, `staging` and `prod`. The SDK key you pass as
|
||||
|
||||
@@ -23,10 +23,17 @@ await client.player.reload(); // force refetch
|
||||
|
||||
```ts
|
||||
interface PlayerProfile {
|
||||
identities?: PlayerProfileIdentity[];
|
||||
player?: Player;
|
||||
wallets?: Wallet[];
|
||||
}
|
||||
|
||||
interface PlayerProfileIdentity {
|
||||
createdAt: string;
|
||||
provider: string; // 'device' | 'google' | 'apple' | 'custom' | 'custom:<name>'
|
||||
subject: string;
|
||||
}
|
||||
|
||||
interface Player {
|
||||
createdAt?: string;
|
||||
id?: string;
|
||||
|
||||
Reference in New Issue
Block a user