@guuey/widget-auth 0.7.2 → 0.8.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
@@ -1,6 +1,7 @@
1
1
  # @guuey/widget-auth
2
2
 
3
- Mint end-user identity tokens for a [guuey](https://guuey.com) embeddable widget, from your own backend.
3
+ Mint end-user identity tokens for a [guuey](https://guuey.com) embeddable widget or for any
4
+ surface you build on `@guuey/agent-client` / `@guuey/chat` — from your own backend.
4
5
 
5
6
  Zero runtime dependencies. Node 18+.
6
7
 
@@ -81,6 +82,39 @@ export async function GET() {
81
82
 
82
83
  Your endpoint is called by the browser; the app secret stays on your server.
83
84
 
85
+ ## Using the token on your own surface
86
+
87
+ The token is not widget-specific: it is a plain signed JWT bound to your app's own issuer
88
+ and audience, and every guuey surface verifies it the same way and derives the same
89
+ end-user identity from `userId`. So the same token endpoint also signs users into a page
90
+ you build yourself with [`@guuey/agent-client`](https://www.npmjs.com/package/@guuey/agent-client)
91
+ or [`@guuey/chat`](https://www.npmjs.com/package/@guuey/chat) — hand it to `getAccessToken`:
92
+
93
+ ```ts
94
+ import { createWebAdapters } from "@guuey/agent-client";
95
+
96
+ const adapters = createWebAdapters({
97
+ apiBaseUrl: "https://api.us-east-1.guuey.com/v1",
98
+ getAccessToken: async ({ forceRefresh } = {}) => {
99
+ // `forceRefresh` is the SDK's "that token was rejected" signal — the same
100
+ // as the widget's reason "expired". Mint fresh, ignoring any cache.
101
+ const res = await fetch(`/api/guuey-token?reason=${forceRefresh ? "expired" : "initial"}`);
102
+ if (!res.ok) throw new Error(`token endpoint failed: ${res.status}`);
103
+ return res.text();
104
+ },
105
+ });
106
+ ```
107
+
108
+ **Throw on failure — never return `null`.** To the SDK, `null` means "signed out on
109
+ purpose", and a signed-in surface would silently continue as an anonymous visitor.
110
+
111
+ A user is **the same identity on every surface** — widget embed, standalone agent page,
112
+ your own page — as long as your backend sends the same `userId`. Conversations, memory,
113
+ files and profile follow them across all three. Add your page's origin to the app's
114
+ allowed domains (`guuey apps update <appId> --domains yourapp.com`) so the browser can
115
+ reach the agent from it. The full walkthrough is at
116
+ [docs.guuey.com/surface-identity](https://docs.guuey.com/surface-identity/).
117
+
84
118
  ## The app secret is server-side only
85
119
 
86
120
  `appSecret` authorizes minting an identity for **any user of your app**. If it reaches a
@@ -237,12 +271,12 @@ id, an editable email) silently orphans all of it and the user reappears as a st
237
271
 
238
272
  **Returns `WidgetToken`**
239
273
 
240
- | Field | Type | |
241
- | ---------------- | -------- | ----------------------------------------------- |
242
- | `token` | `string` | The signed JWT to hand to the widget. |
243
- | `expiresAtEpoch` | `number` | Unix epoch seconds. Use it to drive your cache. |
244
- | `issuer` | `string` | The issuer that signed it. |
245
- | `kid` | `string` | The signing key's id. |
274
+ | Field | Type | |
275
+ | ---------------- | -------- | ------------------------------------------------------------------------ |
276
+ | `token` | `string` | The signed JWT for the widget, or your own surface's `getAccessToken`. |
277
+ | `expiresAtEpoch` | `number` | Unix epoch seconds. Use it to drive your cache. |
278
+ | `issuer` | `string` | The issuer that signed it. |
279
+ | `kid` | `string` | The signing key's id. |
246
280
 
247
281
  ## License
248
282
 
package/dist/index.d.ts CHANGED
@@ -11,6 +11,18 @@
11
11
  * );
12
12
  * ```
13
13
  *
14
+ * ## One token, every surface
15
+ *
16
+ * The token is a plain RS256 JWT bound to your app's own issuer and audience —
17
+ * `iss`, `sub` (= `userId`), `aud`, `iat`/`nbf`/`exp`, optional `name`/`email` —
18
+ * with nothing widget-specific in it. Every guuey consumer verifies it the same
19
+ * way and derives the same end-user identity from `userId`, so the widget
20
+ * embed, a standalone agent page and **your own page built on
21
+ * `@guuey/agent-client` / `@guuey/chat`** (`createWebAdapters({ getAccessToken })`)
22
+ * all see one user with one history, memory and profile. "widget" in this
23
+ * package's name is the name of the app's per-app issuer, not a limit on where
24
+ * the token may be presented (guuey#206).
25
+ *
14
26
  * ## What this package does NOT do, and why that matters
15
27
  *
16
28
  * It holds no key material and assembles no claims. The app's RSA private key
@@ -93,9 +105,13 @@ export interface WidgetAuthConfig {
93
105
  /** Override the HTTP client. Intended for tests. */
94
106
  fetch?: FetchLike;
95
107
  }
96
- /** A minted token, exactly as the mint route returns it. */
108
+ /**
109
+ * A minted token, exactly as the mint route returns it — a hand mirror of
110
+ * `@guuey-private/cli-wire`'s `AppUserTokenMintResponse`, pinned by
111
+ * `wire-sync.test.ts`.
112
+ */
97
113
  export interface WidgetToken {
98
- /** The signed JWT to hand to the widget. */
114
+ /** The signed JWT hand it to the widget, or to your own surface's `getAccessToken`. */
99
115
  token: string;
100
116
  /** Unix epoch seconds at which `token` stops verifying. */
101
117
  expiresAtEpoch: number;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,OAAO,EAGL,+BAA+B,EAC/B,qBAAqB,EACrB,yBAAyB,EACzB,eAAe,EACf,sBAAsB,EACtB,sBAAsB,EACtB,sBAAsB,EACvB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,+BAA+B,EAC/B,qBAAqB,EACrB,yBAAyB,EACzB,eAAe,EACf,sBAAsB,EACtB,sBAAsB,EACtB,sBAAsB,GACvB,CAAC;AA4BF,gDAAgD;AAChD,MAAM,WAAW,UAAU;IACzB;;;;;;;;OAQG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,kCAAkC;AAClC,MAAM,WAAW,gBAAgB;IAC/B,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0BAA0B;IAC1B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,oDAAoD;IACpD,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAED,4DAA4D;AAC5D,MAAM,WAAW,WAAW;IAC1B,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,cAAc,EAAE,MAAM,CAAC;IACvB,iCAAiC;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,4BAA4B;IAC5B,GAAG,EAAE,MAAM,CAAC;CACb;AAED,4CAA4C;AAC5C,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,yDAAyD;AACzD,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CAC1B;AAED;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,CACtB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,qBAAqB,KACxB,OAAO,CAAC,uBAAuB,CAAC,CAAC;AAWtC;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC,WAAW,CAAC,CAmEtB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,OAAO,EAGL,+BAA+B,EAC/B,qBAAqB,EACrB,yBAAyB,EACzB,eAAe,EACf,sBAAsB,EACtB,sBAAsB,EACtB,sBAAsB,EACvB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,+BAA+B,EAC/B,qBAAqB,EACrB,yBAAyB,EACzB,eAAe,EACf,sBAAsB,EACtB,sBAAsB,EACtB,sBAAsB,GACvB,CAAC;AA4BF,gDAAgD;AAChD,MAAM,WAAW,UAAU;IACzB;;;;;;;;OAQG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,kCAAkC;AAClC,MAAM,WAAW,gBAAgB;IAC/B,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0BAA0B;IAC1B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,oDAAoD;IACpD,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAED;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,yFAAyF;IACzF,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,cAAc,EAAE,MAAM,CAAC;IACvB,iCAAiC;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,4BAA4B;IAC5B,GAAG,EAAE,MAAM,CAAC;CACb;AAED,4CAA4C;AAC5C,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,yDAAyD;AACzD,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CAC1B;AAED;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,CACtB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,qBAAqB,KACxB,OAAO,CAAC,uBAAuB,CAAC,CAAC;AAgBtC;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC,WAAW,CAAC,CAmEtB"}
package/dist/index.js CHANGED
@@ -11,6 +11,18 @@
11
11
  * );
12
12
  * ```
13
13
  *
14
+ * ## One token, every surface
15
+ *
16
+ * The token is a plain RS256 JWT bound to your app's own issuer and audience —
17
+ * `iss`, `sub` (= `userId`), `aud`, `iat`/`nbf`/`exp`, optional `name`/`email` —
18
+ * with nothing widget-specific in it. Every guuey consumer verifies it the same
19
+ * way and derives the same end-user identity from `userId`, so the widget
20
+ * embed, a standalone agent page and **your own page built on
21
+ * `@guuey/agent-client` / `@guuey/chat`** (`createWebAdapters({ getAccessToken })`)
22
+ * all see one user with one history, memory and profile. "widget" in this
23
+ * package's name is the name of the app's per-app issuer, not a limit on where
24
+ * the token may be presented (guuey#206).
25
+ *
14
26
  * ## What this package does NOT do, and why that matters
15
27
  *
16
28
  * It holds no key material and assembles no claims. The app's RSA private key
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@guuey/widget-auth",
3
- "version": "0.7.2",
3
+ "version": "0.8.0",
4
4
  "description": "Mint end-user identity tokens for a guuey embeddable widget from your own backend. One call, zero runtime dependencies — your app secret stays on your server and the platform holds the signing key.",
5
5
  "license": "MIT",
6
6
  "type": "module",