@proveanything/smartlinks 1.13.14 → 1.13.15

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.
@@ -1,6 +1,6 @@
1
1
  # Smartlinks API Summary
2
2
 
3
- Version: 1.13.14 | Generated: 2026-05-15T11:37:00.944Z
3
+ Version: 1.13.15 | Generated: 2026-05-15T14:02:11.202Z
4
4
 
5
5
  This is a concise summary of all available API functions and types.
6
6
 
@@ -309,6 +309,7 @@ Now that you understand the core concepts, see the implementation guides:
309
309
  - **[mpa.md](./mpa.md)** — Multi-page app architecture (optional)
310
310
  - **[iframe-responder.md](./iframe-responder.md)** — Parent-side iframe integration
311
311
  - **[portal-back-button.md](./portal-back-button.md)** — Embedded-app "up" navigation and portal back-button behaviour
312
+ - **[portal-auth-broadcast.md](./portal-auth-broadcast.md)** — Publishing custom auth flows to the portal
312
313
 
313
314
  ---
314
315
 
@@ -318,4 +319,5 @@ Now that you understand the core concepts, see the implementation guides:
318
319
  - [ai.md](./ai.md) — AI assistant integration
319
320
  - [deep-link-discovery.md](./deep-link-discovery.md) — Deep linking patterns
320
321
  - [portal-back-button.md](./portal-back-button.md) — Portal shell back-button behavior for hierarchical embeds
322
+ - [portal-auth-broadcast.md](./portal-auth-broadcast.md) — Custom authentication and session broadcast
321
323
  - [manifests.md](./manifests.md) — App manifest configuration
@@ -74,6 +74,7 @@ The SmartLinks SDK (`@proveanything/smartlinks`) includes comprehensive document
74
74
  | **AI Guide Template** | `docs/ai-guide-template.md` | Template for creating `public/ai-guide.md` — customise per app |
75
75
  | **Forms** | `docs/forms.md` | Form definitions, schema-driven rendering, submission patterns |
76
76
  | **Auth Kit** | `docs/auth-kit.md` | End-user sign-in: email/password, magic links, phone OTP, Google OAuth |
77
+ | **Portal Auth Broadcast** | `docs/portal-auth-broadcast.md` | Publishing custom auth flows to the portal; syncing sessions across containers and iframes |
77
78
  | **App Records Pattern** | `docs/app-records-pattern.md` | Standard pattern for per-product/facet/variant/batch admin + public widget UIs |
78
79
  | **UI Utils** | `docs/ui-utils.md` | `@proveanything/smartlinks-utils-ui` — React shells, hooks, and primitives for records-based apps |
79
80
 
@@ -0,0 +1,160 @@
1
+ # Publishing Auth State to the Portal
2
+
3
+ > **For sub-app authors.** This guide explains how to broadcast authentication state changes to the portal so the header, account UI, and sibling apps stay in sync.
4
+
5
+ A SmartLinks micro-app may need to run its own custom authentication flow —
6
+ typical cases: an auction app that calls a bidder API, a competition app
7
+ that exchanges a magic code for a session, a partner SSO. When that flow
8
+ completes the app holds a `token` + `user` of its own, and the **portal**
9
+ needs to know about it so the header, the account UI, and every sibling
10
+ app pick up the new session.
11
+
12
+ This doc describes the contract the portal framework already implements.
13
+
14
+ ---
15
+
16
+ ## Container / Widget Apps (Same React Tree)
17
+
18
+ These run inside the portal's React context and share its `AuthProvider`.
19
+ Call `useAuth()` directly:
20
+
21
+ ```tsx
22
+ import { useAuth } from '@proveanything/smartlinks-auth-ui';
23
+
24
+ function BidButton() {
25
+ const { login, logout, isAuthenticated, user } = useAuth();
26
+
27
+ async function placeBid() {
28
+ if (!isAuthenticated) {
29
+ // Run your own auth flow…
30
+ const { token, user, expiresAt } = await api.signInBidder(...);
31
+ // Publish to the portal — this is the *only* call you need:
32
+ await login(token, user, { source: 'auction' }, /* isNewUser */ false, expiresAt);
33
+ }
34
+ await api.placeBid(...);
35
+ }
36
+
37
+ return <button onClick={placeBid}>Bid</button>;
38
+ }
39
+ ```
40
+
41
+ `useAuth().login(token, user, accountData?, isNewUser?, expiresAt?)` will:
42
+
43
+ - Persist the session (cookie/storage as configured).
44
+ - Call `setBearerToken(token)` on the SDK so subsequent API calls are
45
+ authenticated.
46
+ - Re-render every consumer of `useAuth()` / `useSafeAuth()` —
47
+ including the portal header.
48
+
49
+ `useAuth().logout()` clears all of the above.
50
+
51
+ ---
52
+
53
+ ## Iframe Apps (Cross-Origin)
54
+
55
+ Iframe apps don't share React context. Use the SDK's `authKit` helper —
56
+ it posts the framework-recognised messages on `window.parent`:
57
+
58
+ ```ts
59
+ import { authKit } from '@proveanything/smartlinks';
60
+
61
+ // After your custom flow succeeds:
62
+ await authKit.publishLogin({
63
+ token, // string — your API's bearer token
64
+ user: { // mirrors AuthUser
65
+ uid: 'usr_123',
66
+ email: 'bidder@example.com',
67
+ displayName: 'Jane Bidder',
68
+ },
69
+ accountData: { tier: 'gold' }, // optional, free-form
70
+ });
71
+
72
+ // On sign-out:
73
+ await authKit.publishLogout();
74
+ ```
75
+
76
+ ### Raw postMessage (fallback)
77
+
78
+ If you can't use the helper (e.g. you're outside the SDK), post the raw
79
+ messages from the iframe to its parent. The portal's `IframeResponder`
80
+ listens for these:
81
+
82
+ ```ts
83
+ // LOGIN
84
+ window.parent.postMessage({
85
+ _smartlinksIframeMessage: true,
86
+ type: 'smartlinks:authkit:login',
87
+ payload: {
88
+ token: '<bearer>',
89
+ user: { uid: 'usr_123', email: 'bidder@example.com', displayName: 'Jane' },
90
+ accountData: { /* optional */ },
91
+ },
92
+ }, '*');
93
+
94
+ // LOGOUT
95
+ window.parent.postMessage({
96
+ _smartlinksIframeMessage: true,
97
+ type: 'smartlinks:authkit:logout',
98
+ payload: {},
99
+ }, '*');
100
+ ```
101
+
102
+ The portal-framework's `AppIframeRenderer` translates these into:
103
+
104
+ ```ts
105
+ PortalAuthProvider.login(token, user, accountData);
106
+ // or
107
+ PortalAuthProvider.logout();
108
+ ```
109
+
110
+ — the **same** call the built-in `AuthModal` makes when the user logs in
111
+ through the standard portal UI.
112
+
113
+ ---
114
+
115
+ ## What the Portal Does on Receipt
116
+
117
+ 1. Updates the `IframeResponder` cache so future context syncs carry the
118
+ user.
119
+ 2. Calls `PortalAuthProvider`'s bridged `login` / `logout`.
120
+ 3. `setBearerToken` runs against the parent SDK instance — your API
121
+ calls are now authenticated.
122
+ 4. The portal header avatar swaps in (or out).
123
+ 5. Every other container/widget/iframe app observes the new session via
124
+ its own `useAuth()` / context-refresh.
125
+
126
+ ---
127
+
128
+ ## Anti-Patterns
129
+
130
+ ❌ Storing your own auth token in `localStorage` and ignoring the portal —
131
+ the user will see a logged-out header above your "logged in" app.
132
+
133
+ ❌ Posting `smartlinks-auth-login` (with a hyphen). The correct event
134
+ name is `smartlinks:authkit:login` (colon-separated, namespaced).
135
+
136
+ ❌ Calling `setBearerToken` directly without notifying the portal —
137
+ your token will work until the portal next refreshes auth, then be
138
+ wiped.
139
+
140
+ ❌ Implementing logout by just clearing your own state. Always call
141
+ `useAuth().logout()` (container/widget) or `authKit.publishLogout()`
142
+ (iframe) so the whole portal session ends cleanly.
143
+
144
+ ---
145
+
146
+ ## Reading the Current Portal Session
147
+
148
+ You don't need to broadcast just to *read* the session — that comes for
149
+ free:
150
+
151
+ ```tsx
152
+ // Container / widget apps
153
+ import { useAuth } from '@proveanything/smartlinks-auth-ui';
154
+ const { user, token, isAuthenticated } = useAuth();
155
+ ```
156
+
157
+ ```ts
158
+ // Iframe apps — the IframeResponder caches the parent's user under
159
+ // `cache.user`. Read it via the SDK's standard hooks/helpers.
160
+ ```
@@ -1,6 +1,6 @@
1
1
  # Smartlinks API Summary
2
2
 
3
- Version: 1.13.14 | Generated: 2026-05-15T11:37:00.944Z
3
+ Version: 1.13.15 | Generated: 2026-05-15T14:02:11.202Z
4
4
 
5
5
  This is a concise summary of all available API functions and types.
6
6
 
@@ -309,6 +309,7 @@ Now that you understand the core concepts, see the implementation guides:
309
309
  - **[mpa.md](./mpa.md)** — Multi-page app architecture (optional)
310
310
  - **[iframe-responder.md](./iframe-responder.md)** — Parent-side iframe integration
311
311
  - **[portal-back-button.md](./portal-back-button.md)** — Embedded-app "up" navigation and portal back-button behaviour
312
+ - **[portal-auth-broadcast.md](./portal-auth-broadcast.md)** — Publishing custom auth flows to the portal
312
313
 
313
314
  ---
314
315
 
@@ -318,4 +319,5 @@ Now that you understand the core concepts, see the implementation guides:
318
319
  - [ai.md](./ai.md) — AI assistant integration
319
320
  - [deep-link-discovery.md](./deep-link-discovery.md) — Deep linking patterns
320
321
  - [portal-back-button.md](./portal-back-button.md) — Portal shell back-button behavior for hierarchical embeds
322
+ - [portal-auth-broadcast.md](./portal-auth-broadcast.md) — Custom authentication and session broadcast
321
323
  - [manifests.md](./manifests.md) — App manifest configuration
package/docs/overview.md CHANGED
@@ -74,6 +74,7 @@ The SmartLinks SDK (`@proveanything/smartlinks`) includes comprehensive document
74
74
  | **AI Guide Template** | `docs/ai-guide-template.md` | Template for creating `public/ai-guide.md` — customise per app |
75
75
  | **Forms** | `docs/forms.md` | Form definitions, schema-driven rendering, submission patterns |
76
76
  | **Auth Kit** | `docs/auth-kit.md` | End-user sign-in: email/password, magic links, phone OTP, Google OAuth |
77
+ | **Portal Auth Broadcast** | `docs/portal-auth-broadcast.md` | Publishing custom auth flows to the portal; syncing sessions across containers and iframes |
77
78
  | **App Records Pattern** | `docs/app-records-pattern.md` | Standard pattern for per-product/facet/variant/batch admin + public widget UIs |
78
79
  | **UI Utils** | `docs/ui-utils.md` | `@proveanything/smartlinks-utils-ui` — React shells, hooks, and primitives for records-based apps |
79
80
 
@@ -0,0 +1,160 @@
1
+ # Publishing Auth State to the Portal
2
+
3
+ > **For sub-app authors.** This guide explains how to broadcast authentication state changes to the portal so the header, account UI, and sibling apps stay in sync.
4
+
5
+ A SmartLinks micro-app may need to run its own custom authentication flow —
6
+ typical cases: an auction app that calls a bidder API, a competition app
7
+ that exchanges a magic code for a session, a partner SSO. When that flow
8
+ completes the app holds a `token` + `user` of its own, and the **portal**
9
+ needs to know about it so the header, the account UI, and every sibling
10
+ app pick up the new session.
11
+
12
+ This doc describes the contract the portal framework already implements.
13
+
14
+ ---
15
+
16
+ ## Container / Widget Apps (Same React Tree)
17
+
18
+ These run inside the portal's React context and share its `AuthProvider`.
19
+ Call `useAuth()` directly:
20
+
21
+ ```tsx
22
+ import { useAuth } from '@proveanything/smartlinks-auth-ui';
23
+
24
+ function BidButton() {
25
+ const { login, logout, isAuthenticated, user } = useAuth();
26
+
27
+ async function placeBid() {
28
+ if (!isAuthenticated) {
29
+ // Run your own auth flow…
30
+ const { token, user, expiresAt } = await api.signInBidder(...);
31
+ // Publish to the portal — this is the *only* call you need:
32
+ await login(token, user, { source: 'auction' }, /* isNewUser */ false, expiresAt);
33
+ }
34
+ await api.placeBid(...);
35
+ }
36
+
37
+ return <button onClick={placeBid}>Bid</button>;
38
+ }
39
+ ```
40
+
41
+ `useAuth().login(token, user, accountData?, isNewUser?, expiresAt?)` will:
42
+
43
+ - Persist the session (cookie/storage as configured).
44
+ - Call `setBearerToken(token)` on the SDK so subsequent API calls are
45
+ authenticated.
46
+ - Re-render every consumer of `useAuth()` / `useSafeAuth()` —
47
+ including the portal header.
48
+
49
+ `useAuth().logout()` clears all of the above.
50
+
51
+ ---
52
+
53
+ ## Iframe Apps (Cross-Origin)
54
+
55
+ Iframe apps don't share React context. Use the SDK's `authKit` helper —
56
+ it posts the framework-recognised messages on `window.parent`:
57
+
58
+ ```ts
59
+ import { authKit } from '@proveanything/smartlinks';
60
+
61
+ // After your custom flow succeeds:
62
+ await authKit.publishLogin({
63
+ token, // string — your API's bearer token
64
+ user: { // mirrors AuthUser
65
+ uid: 'usr_123',
66
+ email: 'bidder@example.com',
67
+ displayName: 'Jane Bidder',
68
+ },
69
+ accountData: { tier: 'gold' }, // optional, free-form
70
+ });
71
+
72
+ // On sign-out:
73
+ await authKit.publishLogout();
74
+ ```
75
+
76
+ ### Raw postMessage (fallback)
77
+
78
+ If you can't use the helper (e.g. you're outside the SDK), post the raw
79
+ messages from the iframe to its parent. The portal's `IframeResponder`
80
+ listens for these:
81
+
82
+ ```ts
83
+ // LOGIN
84
+ window.parent.postMessage({
85
+ _smartlinksIframeMessage: true,
86
+ type: 'smartlinks:authkit:login',
87
+ payload: {
88
+ token: '<bearer>',
89
+ user: { uid: 'usr_123', email: 'bidder@example.com', displayName: 'Jane' },
90
+ accountData: { /* optional */ },
91
+ },
92
+ }, '*');
93
+
94
+ // LOGOUT
95
+ window.parent.postMessage({
96
+ _smartlinksIframeMessage: true,
97
+ type: 'smartlinks:authkit:logout',
98
+ payload: {},
99
+ }, '*');
100
+ ```
101
+
102
+ The portal-framework's `AppIframeRenderer` translates these into:
103
+
104
+ ```ts
105
+ PortalAuthProvider.login(token, user, accountData);
106
+ // or
107
+ PortalAuthProvider.logout();
108
+ ```
109
+
110
+ — the **same** call the built-in `AuthModal` makes when the user logs in
111
+ through the standard portal UI.
112
+
113
+ ---
114
+
115
+ ## What the Portal Does on Receipt
116
+
117
+ 1. Updates the `IframeResponder` cache so future context syncs carry the
118
+ user.
119
+ 2. Calls `PortalAuthProvider`'s bridged `login` / `logout`.
120
+ 3. `setBearerToken` runs against the parent SDK instance — your API
121
+ calls are now authenticated.
122
+ 4. The portal header avatar swaps in (or out).
123
+ 5. Every other container/widget/iframe app observes the new session via
124
+ its own `useAuth()` / context-refresh.
125
+
126
+ ---
127
+
128
+ ## Anti-Patterns
129
+
130
+ ❌ Storing your own auth token in `localStorage` and ignoring the portal —
131
+ the user will see a logged-out header above your "logged in" app.
132
+
133
+ ❌ Posting `smartlinks-auth-login` (with a hyphen). The correct event
134
+ name is `smartlinks:authkit:login` (colon-separated, namespaced).
135
+
136
+ ❌ Calling `setBearerToken` directly without notifying the portal —
137
+ your token will work until the portal next refreshes auth, then be
138
+ wiped.
139
+
140
+ ❌ Implementing logout by just clearing your own state. Always call
141
+ `useAuth().logout()` (container/widget) or `authKit.publishLogout()`
142
+ (iframe) so the whole portal session ends cleanly.
143
+
144
+ ---
145
+
146
+ ## Reading the Current Portal Session
147
+
148
+ You don't need to broadcast just to *read* the session — that comes for
149
+ free:
150
+
151
+ ```tsx
152
+ // Container / widget apps
153
+ import { useAuth } from '@proveanything/smartlinks-auth-ui';
154
+ const { user, token, isAuthenticated } = useAuth();
155
+ ```
156
+
157
+ ```ts
158
+ // Iframe apps — the IframeResponder caches the parent's user under
159
+ // `cache.user`. Read it via the SDK's standard hooks/helpers.
160
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proveanything/smartlinks",
3
- "version": "1.13.14",
3
+ "version": "1.13.15",
4
4
  "description": "Official JavaScript/TypeScript SDK for the Smartlinks API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",