scorezilla 0.3.0-next.3 → 0.3.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/CHANGELOG.md CHANGED
@@ -1,5 +1,164 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#45](https://github.com/isco-tec/scorezilla-js/pull/45) [`1a1e625`](https://github.com/isco-tec/scorezilla-js/commit/1a1e625cc6aff058071f922c7c5a619efa80ddc8) Thanks [@isco-tec](https://github.com/isco-tec)! - feat(identity): ship the GitHub provider for `useAuthProvider` (scorezilla#194)
8
+
9
+ The GitHub option is real (and final, per ADR 0009): a popup OAuth web flow
10
+ on the client plus a turnkey server-side token exchange.
11
+ - `useAuthProvider({ provider: 'github', clientId, exchangeUrl, storageKey })`
12
+ — opens the GitHub sign-in popup, validates the callback by origin + state,
13
+ resolves `github:<id>` (or `null` on decline). The provisional option shape
14
+ is finalized: `clientId`, `exchangeUrl`, and `storageKey` are all required.
15
+ - `createGitHubOAuthHandler({ clientId, clientSecret, allowedOrigin })` (new
16
+ in `scorezilla/server`) — the deployable callback endpoint: exchanges the
17
+ code (secret stays server-side), resolves the user id, posts it back to the
18
+ game's origin, closes the popup. The access token never reaches the browser.
19
+ - size-limit: server caps 7 → 8 KB (documented); new tree-shaking proof pins
20
+ that adapter-only consumers pay for neither factory.
21
+
22
+ - [#39](https://github.com/isco-tec/scorezilla-js/pull/39) [`608137f`](https://github.com/isco-tec/scorezilla-js/commit/608137f2a880fd3b9031cde8de765a5262d6c334) Thanks [@isco-tec](https://github.com/isco-tec)! - feat(identity): ship the Google provider for `useAuthProvider`
23
+
24
+ `useAuthProvider({ provider: 'google', clientId, storageKey })` is now
25
+ implemented and **stable**. It wraps Google Identity Services ("One Tap"),
26
+ derives a stable, opaque player id from the account's `sub` claim
27
+ (`google:<sub>`), and persists it in `localStorage` so returning visitors are
28
+ recognized without signing in again.
29
+
30
+ ```ts
31
+ import { Scorezilla } from 'scorezilla';
32
+ import { useAuthProvider } from 'scorezilla/identity';
33
+
34
+ const player = await useAuthProvider({
35
+ provider: 'google',
36
+ clientId: 'YOUR_CLIENT_ID.apps.googleusercontent.com',
37
+ storageKey: 'mygame:player',
38
+ });
39
+
40
+ if (player) {
41
+ const sz = new Scorezilla({ publicKey: 'pk_…' });
42
+ await sz.submitScore({ boardId, playerId: player.id, score: 42 });
43
+ // player.signOut() clears the persisted id and disables Google auto-select.
44
+ }
45
+ ```
46
+
47
+ - **Resolves `null` when the player declines** or One Tap can't be shown — a
48
+ dismissed sign-in is not an error. It **rejects** only on genuine failures
49
+ (invalid args, script load failure, malformed credential).
50
+ - **`handle.source`** is `'signed-in'` for a fresh sign-in or `'restored'` when
51
+ the id was rehydrated from `localStorage` (a restored id is not a re-verified
52
+ live session).
53
+ - **Bring your own client ID.** The SDK never bundles Scorezilla-owned OAuth
54
+ credentials, so revocation and consent stay under your control.
55
+ - **Privacy.** Only the derived `sub`-based id is stored and transmitted on
56
+ score submission — never the Google credential, email, or profile.
57
+ - **Bundle.** The Google provider tree-shakes out for consumers who don't call
58
+ `useAuthProvider`; the Google Identity Services library is loaded at runtime
59
+ from `accounts.google.com`, never bundled.
60
+ - `useAuthProvider` is now async (replacing the `0.3.0-next.0` preview stub that
61
+ threw synchronously). Despite the `use*` name it is **not** a React hook.
62
+ Identity errors are plain `Error`/`TypeError` (not `ScorezillaError`), keeping
63
+ the `scorezilla/identity` subpath dependency-free. The host page's CSP must
64
+ allow `https://accounts.google.com`.
65
+ - The **GitHub** provider is not available yet — it ships in a follow-up and
66
+ will require a server-side token exchange (your backend or a Scorezilla
67
+ Workers proxy). Calling `useAuthProvider({ provider: 'github' })` rejects
68
+ with guidance until then.
69
+
70
+ - [#36](https://github.com/isco-tec/scorezilla-js/pull/36) [`19c2dcc`](https://github.com/isco-tec/scorezilla-js/commit/19c2dcc14d2000551d80498813b075172c8f4d66) Thanks [@isco-tec](https://github.com/isco-tec)! - feat(identity): preset helpers for `scorezilla/identity` (Phase 1)
71
+
72
+ New subpath export: `scorezilla/identity`. Three identity-strategy
73
+ presets ship as `stable`; one OAuth helper ships as a preview stub.
74
+
75
+ **Stable in this release:**
76
+ - `useAnonymousPlayer({ storageKey })` — generates a UUID, persists in
77
+ localStorage, same browser keeps the same id across reloads. Returns
78
+ `{ id, forget() }`. Privacy-safe by default (no PII).
79
+ - `usePromptedPlayer({ storageKey, prompt })` — `window.prompt()` on
80
+ first run, persists to localStorage. Returns `{ id, forget() } | null`
81
+ (null when SSR, no `prompt`, or user cancels).
82
+ - `useServerAuthoritative()` — no-op marker for snippets using the
83
+ HMAC-signed secure path (`scorezilla/server`). The browser SDK does
84
+ no identity work; the server picks the value.
85
+
86
+ **Preview stub in this release (throws on call):**
87
+ - `useAuthProvider({ provider: 'google' | 'github' })` — OAuth-backed
88
+ identity. Full implementation (Google + GitHub for v1) ships in a
89
+ follow-up `next` release before the 0.3.0 latest promote.
90
+
91
+ Per [ADR 0003](https://github.com/isco-tec/scorezilla/blob/main/docs/adr/0003-mcp-identity-axis.md). All helpers document where data is stored and
92
+ what `forget()` / `signOut()` does NOT do (server-side history is
93
+ retained — call admin delete-player for full erasure).
94
+
95
+ Closes upstream tracking issue isco-tec/scorezilla#125 (Phase 1).
96
+
97
+ - [#41](https://github.com/isco-tec/scorezilla-js/pull/41) [`e48a5a2`](https://github.com/isco-tec/scorezilla-js/commit/e48a5a2f09cd0f098e8466b51586bd4108bb5678) Thanks [@isco-tec](https://github.com/isco-tec)! - feat(server): `createScoreSubmitHandler()` — turnkey secure score submissions
98
+
99
+ A framework-agnostic factory in `scorezilla/server` that collapses the secure
100
+ (HMAC-signed) submission path from ~150 lines of boilerplate into a few. It
101
+ returns a standard `(Request) => Promise<Response>` handler — drop it into a
102
+ Cloudflare Worker, a Next.js route handler, Hono, Deno, or Bun.
103
+
104
+ ```ts
105
+ import { createScoreSubmitHandler } from 'scorezilla/server';
106
+
107
+ export const POST = createScoreSubmitHandler({
108
+ secretKey: process.env.SCOREZILLA_SECRET_KEY!,
109
+ boardId: process.env.SCOREZILLA_BOARD_ID!,
110
+ verify: async (req) => {
111
+ // your auth — any provider; return the trusted playerId
112
+ const user = await myAuth(req);
113
+ return user ? { playerId: user.id } : null;
114
+ },
115
+ });
116
+ ```
117
+
118
+ - The submitted `playerId` always comes from `verify` (the verified request),
119
+ never the request body — so ranking-sensitive boards aren't subject to the
120
+ client-authoritative submission of the public-key path.
121
+ - Owns body parsing/validation, HMAC signing, and `ScorezillaError` → HTTP
122
+ status mapping. Optional `cors` (OPTIONS preflight + reflected origin) and a
123
+ pre-verify `rateLimit` gate.
124
+ - Works with **any** auth via the `verify` callback (Supabase / Clerk / Auth0 /
125
+ Firebase JWTs, Lucia / opaque sessions, or a provider backend SDK). First-class
126
+ one-line verifiers (`verifySupabaseJwt`, `verifyJwt`) follow.
127
+
128
+ - [#42](https://github.com/isco-tec/scorezilla-js/pull/42) [`7ca5976`](https://github.com/isco-tec/scorezilla-js/commit/7ca5976857cfff44cc3a3c155181cd9f6276aea0) Thanks [@isco-tec](https://github.com/isco-tec)! - feat(server): built-in `verifyJwt` + `verifySupabaseJwt` for `createScoreSubmitHandler`
129
+
130
+ Turn the common "verify a JWT, derive the player id" step into a one-liner.
131
+ Both return a `verify` function you drop straight into `createScoreSubmitHandler`.
132
+
133
+ ```ts
134
+ import { createScoreSubmitHandler, verifySupabaseJwt } from 'scorezilla/server';
135
+
136
+ export const POST = createScoreSubmitHandler({
137
+ secretKey: process.env.SCOREZILLA_SECRET_KEY!,
138
+ boardId: process.env.SCOREZILLA_BOARD_ID!,
139
+ verify: verifySupabaseJwt({ supabaseUrl: process.env.SUPABASE_URL! }),
140
+ });
141
+ ```
142
+
143
+ - `verifyJwt({ jwksUrl, issuer, audience, claim? })` — generic JWKS verifier,
144
+ plus first-class presets for the popular providers: `verifySupabaseJwt({
145
+ supabaseUrl })`, `verifyClerkJwt({ issuer })`, `verifyAuth0Jwt({ domain,
146
+ audience })`, and `verifyFirebaseIdToken({ projectId })`.
147
+ - **`jose` is an optional peer dependency**, loaded lazily via dynamic
148
+ `import()` — consumers who use the public-key client, the factory with their
149
+ own `verify`, or a provider backend SDK never install or load it.
150
+
151
+ ### Patch Changes
152
+
153
+ - [#44](https://github.com/isco-tec/scorezilla-js/pull/44) [`e7fcc42`](https://github.com/isco-tec/scorezilla-js/commit/e7fcc4262b5d0a706d29f05333335f746307cb47) Thanks [@isco-tec](https://github.com/isco-tec)! - docs: make the `useAuthProvider` trust boundary explicit (scorezilla#213)
154
+
155
+ Client OAuth identity is sign-in convenience, not anti-forgery — the derived
156
+ id is computed client-side and submitted with the public key. New
157
+ trust-boundary notes on the `useAuthProvider` JSDoc and `AuthPlayerHandle`, a
158
+ "Player identity" section in the README, and a RECIPES.md recipe ("OAuth
159
+ identity and the secure path") routing ranking-sensitive boards to
160
+ `createScoreSubmitHandler` with a server-verified identity.
161
+
3
162
  ## 0.3.0-next.3
4
163
 
5
164
  ### Minor Changes
package/dist/index.cjs CHANGED
@@ -633,7 +633,7 @@ function validateMetadata(metadata) {
633
633
  }
634
634
  var Scorezilla = class _Scorezilla {
635
635
  /** The package version, injected at build time from `package.json`. */
636
- static version = "0.3.0-next.3";
636
+ static version = "0.3.0";
637
637
  #config;
638
638
  #userAgent;
639
639
  #authHeader;
@@ -818,7 +818,7 @@ function createClient(config) {
818
818
  }
819
819
 
820
820
  // src/index.ts
821
- var SDK_VERSION = "0.3.0-next.3";
821
+ var SDK_VERSION = "0.3.0";
822
822
 
823
823
  exports.SDK_VERSION = SDK_VERSION;
824
824
  exports.Scorezilla = Scorezilla;