@jamroast/jamauth-react 0.0.0-stage → 0.0.2
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 +92 -2
- package/dist/index.cjs +356 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +218 -0
- package/dist/index.d.ts +218 -0
- package/dist/index.js +332 -0
- package/dist/index.js.map +1 -0
- package/package.json +54 -4
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode, CSSProperties } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Framework-agnostic OIDC authorization-code (PKCE) + embedded-iframe
|
|
6
|
+
* `postMessage` bridge for `@jamroast/jamauth-react`.
|
|
7
|
+
*
|
|
8
|
+
* Generalizes the PKCE S256 + `localStorage` token pattern from jamauth's own
|
|
9
|
+
* SPA (`web/src/lib/oidc-capture.ts`) so any client app (Next/Vite/Remix/etc.)
|
|
10
|
+
* can render a branded `SignIn`/`SignUp` on its own domain while every
|
|
11
|
+
* credential form (email+password, MFA, forgot/reset/verify) stays on the
|
|
12
|
+
* jamauth authority inside an embedded `<iframe>` that completes the OIDC
|
|
13
|
+
* authorization-code flow and relays `{ code, state }` to the parent via
|
|
14
|
+
* `postMessage`.
|
|
15
|
+
*
|
|
16
|
+
* Pure React + `window`/`postMessage`/`localStorage` with `typeof window`
|
|
17
|
+
* guards so it is SSR-safe. No credential inputs live here — credentials are
|
|
18
|
+
* typed only inside the jamauth frame (server-rendered interaction HTML).
|
|
19
|
+
*/
|
|
20
|
+
declare const STORAGE_KEYS: {
|
|
21
|
+
readonly userToken: "jamauth.userToken";
|
|
22
|
+
readonly refreshToken: "jamauth.refreshToken";
|
|
23
|
+
readonly tokenExpiresIn: "jamauth.tokenExpiresIn";
|
|
24
|
+
readonly pkceVerifier: "jamauth.pkceVerifier";
|
|
25
|
+
};
|
|
26
|
+
/** Custom event fired whenever the stored session changes (sign-in/sign-out). */
|
|
27
|
+
declare const SESSION_CHANGED_EVENT = "jamauth:session-changed";
|
|
28
|
+
/** Caller-supplied OIDC client identity (never a hardcoded first-party default). */
|
|
29
|
+
interface OidcClientParams {
|
|
30
|
+
/** The jamauth issuer/authority origin, e.g. `https://jamauth.net`. */
|
|
31
|
+
authority: string;
|
|
32
|
+
clientId: string;
|
|
33
|
+
redirectUri: string;
|
|
34
|
+
/** RFC 8707 resource indicator; only needed for RS256 human-token minting. */
|
|
35
|
+
resource?: string;
|
|
36
|
+
/** OIDC `login_hint` — the invitee email, prefilled on sign-in. */
|
|
37
|
+
loginHint?: string;
|
|
38
|
+
/** OIDC scope; defaults to `openid profile email offline_access`. */
|
|
39
|
+
scope?: string;
|
|
40
|
+
/** Token endpoint override; defaults to `${authority}/token`. */
|
|
41
|
+
tokenEndpoint?: string;
|
|
42
|
+
/** OIDC `prompt` value (e.g. `'register'` for the sign-up surface). */
|
|
43
|
+
prompt?: string;
|
|
44
|
+
}
|
|
45
|
+
interface TokenResponse {
|
|
46
|
+
access_token: string;
|
|
47
|
+
refresh_token?: string;
|
|
48
|
+
expires_in?: number;
|
|
49
|
+
}
|
|
50
|
+
type AuthorizeMessage = {
|
|
51
|
+
type: 'jamauth:authorize';
|
|
52
|
+
code: string;
|
|
53
|
+
state: string;
|
|
54
|
+
};
|
|
55
|
+
type ReadyMessage = {
|
|
56
|
+
type: 'jamauth:ready';
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Derive the configured authority origin. The handshake validates incoming
|
|
60
|
+
* `postMessage` events against this origin — never a hardcoded `jamauth.net`
|
|
61
|
+
* literal.
|
|
62
|
+
*/
|
|
63
|
+
declare function authorityOrigin(authority: string): string;
|
|
64
|
+
/** Build the top-level `/auth` authorization URL (PKCE S256, `response_type=code`). */
|
|
65
|
+
declare function buildAuthorizeUrl(params: OidcClientParams): Promise<URL>;
|
|
66
|
+
/** Build the embedded `/embed/authorize` iframe URL (same PKCE S256 params). */
|
|
67
|
+
declare function buildEmbedUrl(params: OidcClientParams): Promise<URL>;
|
|
68
|
+
/**
|
|
69
|
+
* Validate an incoming `postMessage` event against the configured authority
|
|
70
|
+
* origin (never hardcoded) AND the iframe's `contentWindow` (so a same-origin
|
|
71
|
+
* event from an unexpected frame is ignored).
|
|
72
|
+
*/
|
|
73
|
+
declare function isTrustedBridgeMessage(event: MessageEvent, authority: string, iframe: HTMLIFrameElement): boolean;
|
|
74
|
+
/** Parse a `jamauth:authorize` relay payload; returns `null` for other types. */
|
|
75
|
+
declare function parseAuthorizeMessage(data: unknown): {
|
|
76
|
+
code: string;
|
|
77
|
+
state: string;
|
|
78
|
+
} | null;
|
|
79
|
+
/** Parse a `jamauth:ready` handshake payload; returns `true` for the handshake. */
|
|
80
|
+
declare function isReadyMessage(data: unknown): data is ReadyMessage;
|
|
81
|
+
/** Store a minted token response (mirrors `oidc-capture.ts`). */
|
|
82
|
+
declare function storeTokenResponse(response: TokenResponse): void;
|
|
83
|
+
/** Clear the stored session tokens (sign-out). */
|
|
84
|
+
declare function clearStoredTokens(): void;
|
|
85
|
+
/**
|
|
86
|
+
* Exchange an authorization `code` for tokens via a PUBLIC PKCE request
|
|
87
|
+
* (`grant_type=authorization_code`, no client_secret, no Authorization header).
|
|
88
|
+
* The token endpoint defaults to `${authority}/token` (CORS-allowed for the
|
|
89
|
+
* registered client origin via `clientBasedCORS`).
|
|
90
|
+
*/
|
|
91
|
+
declare function exchangeCodeForToken(params: OidcClientParams, code: string): Promise<TokenResponse>;
|
|
92
|
+
/**
|
|
93
|
+
* Fallback to a top-level redirect with a fresh PKCE `authorizeUrl`. Used when
|
|
94
|
+
* the embedded iframe is blocked (or fails to handshake) — idempotent and
|
|
95
|
+
* correct, so a false positive degrades to the top-level flow rather than a
|
|
96
|
+
* broken UX.
|
|
97
|
+
*/
|
|
98
|
+
declare function fallbackToTopLevelRedirect(authorizeUrl: URL): void;
|
|
99
|
+
|
|
100
|
+
/** Configuration carried by `JamauthProvider`. */
|
|
101
|
+
interface JamauthConfig {
|
|
102
|
+
/** The jamauth issuer/authority origin, e.g. `https://jamauth.net`. */
|
|
103
|
+
authority: string;
|
|
104
|
+
clientId: string;
|
|
105
|
+
redirectUri: string;
|
|
106
|
+
resource?: string;
|
|
107
|
+
scope?: string;
|
|
108
|
+
tokenEndpoint?: string;
|
|
109
|
+
loginHint?: string;
|
|
110
|
+
/** Blocked-iframe handshake timeout in ms (default 5000). */
|
|
111
|
+
handshakeTimeoutMs?: number;
|
|
112
|
+
/** Called once the authorization code is exchanged for tokens. */
|
|
113
|
+
onToken?: (response: TokenResponse) => void;
|
|
114
|
+
}
|
|
115
|
+
/** Provide the jamauth authority + client identity to the embedded auth surface. */
|
|
116
|
+
declare function JamauthProvider({ config, children, }: {
|
|
117
|
+
config: JamauthConfig;
|
|
118
|
+
children: ReactNode;
|
|
119
|
+
}): react.JSX.Element;
|
|
120
|
+
/** Read the configured jamauth client identity (throws outside a provider). */
|
|
121
|
+
declare function useJamauth(): JamauthConfig;
|
|
122
|
+
interface SessionState {
|
|
123
|
+
isAuthenticated: boolean;
|
|
124
|
+
token: string | null;
|
|
125
|
+
}
|
|
126
|
+
/** Reactive session state sourced from the stored access token. */
|
|
127
|
+
declare function useSession(): SessionState;
|
|
128
|
+
/** High-level auth surface: session state plus sign-out. */
|
|
129
|
+
declare function useAuth(): SessionState & {
|
|
130
|
+
signOut: () => void;
|
|
131
|
+
};
|
|
132
|
+
/** Low-level OIDC bridge bound to the configured authority/client identity. */
|
|
133
|
+
declare function useOidc(): {
|
|
134
|
+
authorityOrigin: () => string;
|
|
135
|
+
buildAuthorizeUrl: () => Promise<URL>;
|
|
136
|
+
buildEmbedUrl: (prompt?: string) => Promise<URL>;
|
|
137
|
+
exchangeCodeForToken: (code: string) => Promise<TokenResponse>;
|
|
138
|
+
};
|
|
139
|
+
/** Renders `children` only while authenticated (access token present). */
|
|
140
|
+
declare function SignedIn({ children }: {
|
|
141
|
+
children: ReactNode;
|
|
142
|
+
}): react.JSX.Element | null;
|
|
143
|
+
/** Renders `children` only while signed out (no access token present). */
|
|
144
|
+
declare function SignedOut({ children }: {
|
|
145
|
+
children: ReactNode;
|
|
146
|
+
}): react.JSX.Element | null;
|
|
147
|
+
|
|
148
|
+
interface SignInProps {
|
|
149
|
+
/** Override the handshake timeout (ms) for this surface. */
|
|
150
|
+
handshakeTimeoutMs?: number;
|
|
151
|
+
className?: string;
|
|
152
|
+
style?: CSSProperties;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Embedded sign-in surface — an iframe wrapper around the jamauth
|
|
156
|
+
* `/embed/authorize` flow. This component renders **no credential inputs**:
|
|
157
|
+
* the email+password form (and MFA / forgot / reset / verify) lives on the
|
|
158
|
+
* jamauth authority inside the frame, and the completed authorization code is
|
|
159
|
+
* relayed back to the parent via `postMessage`.
|
|
160
|
+
*/
|
|
161
|
+
declare function SignIn({ className, style }: SignInProps): react.JSX.Element;
|
|
162
|
+
|
|
163
|
+
interface SignUpProps {
|
|
164
|
+
/** Override the handshake timeout (ms) for this surface. */
|
|
165
|
+
handshakeTimeoutMs?: number;
|
|
166
|
+
className?: string;
|
|
167
|
+
style?: CSSProperties;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Embedded sign-up surface — an iframe wrapper around the jamauth
|
|
171
|
+
* `/embed/authorize` flow with `prompt=register`. Like `SignIn`, this renders
|
|
172
|
+
* **no credential inputs**; the sign-up form lives on the jamauth authority
|
|
173
|
+
* inside the frame and the completed authorization code is relayed back via
|
|
174
|
+
* `postMessage`.
|
|
175
|
+
*/
|
|
176
|
+
declare function SignUp({ className, style }: SignUpProps): react.JSX.Element;
|
|
177
|
+
|
|
178
|
+
interface UserButtonProps {
|
|
179
|
+
/** Label shown when signed out (default "Sign in"). */
|
|
180
|
+
signInLabel?: ReactNode;
|
|
181
|
+
/** Label shown when signed in (default "Sign out"). */
|
|
182
|
+
signOutLabel?: ReactNode;
|
|
183
|
+
/** Called instead of the default sign-out when the user is signed in. */
|
|
184
|
+
onSignOut?: () => void;
|
|
185
|
+
className?: string;
|
|
186
|
+
style?: CSSProperties;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* A minimal, framework-agnostic account button. It reflects the stored session
|
|
190
|
+
* state and, when signed in, signs the user out (or delegates to `onSignOut`).
|
|
191
|
+
* It renders no credential inputs.
|
|
192
|
+
*/
|
|
193
|
+
declare function UserButton({ signInLabel, signOutLabel, onSignOut, className, style, }: UserButtonProps): react.JSX.Element;
|
|
194
|
+
|
|
195
|
+
type EmbeddedStatus = 'loading' | 'ready' | 'authenticated' | 'fallback';
|
|
196
|
+
interface EmbeddedAuthState {
|
|
197
|
+
iframeRef: React.RefObject<HTMLIFrameElement | null>;
|
|
198
|
+
src: string;
|
|
199
|
+
status: EmbeddedStatus;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Mount the embedded `/embed/authorize` iframe and drive the confirmation
|
|
203
|
+
* handshake + timeout fallback:
|
|
204
|
+
*
|
|
205
|
+
* - `iframe.onload` is NOT authoritative (a `frame-ancestors`-blocked frame
|
|
206
|
+
* still fires `onload`). Instead the parent validates
|
|
207
|
+
* `event.origin === authorityOrigin` (derived from the configured authority,
|
|
208
|
+
* never hardcoded) **and** `event.source === iframe.contentWindow`.
|
|
209
|
+
* - A `handshakeTimeoutMs` timer (default ~5s) falls back to a top-level
|
|
210
|
+
* `window.location.assign(freshPkceAuthorizeUrl)` when no `jamauth:ready`
|
|
211
|
+
* arrives — idempotent and correct, so a false positive degrades to the
|
|
212
|
+
* top-level flow rather than a broken UX.
|
|
213
|
+
* - On `jamauth:authorize`, the code is exchanged via public PKCE and the
|
|
214
|
+
* tokens are stored.
|
|
215
|
+
*/
|
|
216
|
+
declare function useEmbeddedAuth(prompt?: string): EmbeddedAuthState;
|
|
217
|
+
|
|
218
|
+
export { type AuthorizeMessage, type EmbeddedAuthState, type EmbeddedStatus, type JamauthConfig, JamauthProvider, type OidcClientParams, type ReadyMessage, SESSION_CHANGED_EVENT, STORAGE_KEYS, type SessionState, SignIn, type SignInProps, SignUp, type SignUpProps, SignedIn, SignedOut, type TokenResponse, UserButton, type UserButtonProps, authorityOrigin, buildAuthorizeUrl, buildEmbedUrl, clearStoredTokens, exchangeCodeForToken, fallbackToTopLevelRedirect, isReadyMessage, isTrustedBridgeMessage, parseAuthorizeMessage, storeTokenResponse, useAuth, useEmbeddedAuth, useJamauth, useOidc, useSession };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode, CSSProperties } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Framework-agnostic OIDC authorization-code (PKCE) + embedded-iframe
|
|
6
|
+
* `postMessage` bridge for `@jamroast/jamauth-react`.
|
|
7
|
+
*
|
|
8
|
+
* Generalizes the PKCE S256 + `localStorage` token pattern from jamauth's own
|
|
9
|
+
* SPA (`web/src/lib/oidc-capture.ts`) so any client app (Next/Vite/Remix/etc.)
|
|
10
|
+
* can render a branded `SignIn`/`SignUp` on its own domain while every
|
|
11
|
+
* credential form (email+password, MFA, forgot/reset/verify) stays on the
|
|
12
|
+
* jamauth authority inside an embedded `<iframe>` that completes the OIDC
|
|
13
|
+
* authorization-code flow and relays `{ code, state }` to the parent via
|
|
14
|
+
* `postMessage`.
|
|
15
|
+
*
|
|
16
|
+
* Pure React + `window`/`postMessage`/`localStorage` with `typeof window`
|
|
17
|
+
* guards so it is SSR-safe. No credential inputs live here — credentials are
|
|
18
|
+
* typed only inside the jamauth frame (server-rendered interaction HTML).
|
|
19
|
+
*/
|
|
20
|
+
declare const STORAGE_KEYS: {
|
|
21
|
+
readonly userToken: "jamauth.userToken";
|
|
22
|
+
readonly refreshToken: "jamauth.refreshToken";
|
|
23
|
+
readonly tokenExpiresIn: "jamauth.tokenExpiresIn";
|
|
24
|
+
readonly pkceVerifier: "jamauth.pkceVerifier";
|
|
25
|
+
};
|
|
26
|
+
/** Custom event fired whenever the stored session changes (sign-in/sign-out). */
|
|
27
|
+
declare const SESSION_CHANGED_EVENT = "jamauth:session-changed";
|
|
28
|
+
/** Caller-supplied OIDC client identity (never a hardcoded first-party default). */
|
|
29
|
+
interface OidcClientParams {
|
|
30
|
+
/** The jamauth issuer/authority origin, e.g. `https://jamauth.net`. */
|
|
31
|
+
authority: string;
|
|
32
|
+
clientId: string;
|
|
33
|
+
redirectUri: string;
|
|
34
|
+
/** RFC 8707 resource indicator; only needed for RS256 human-token minting. */
|
|
35
|
+
resource?: string;
|
|
36
|
+
/** OIDC `login_hint` — the invitee email, prefilled on sign-in. */
|
|
37
|
+
loginHint?: string;
|
|
38
|
+
/** OIDC scope; defaults to `openid profile email offline_access`. */
|
|
39
|
+
scope?: string;
|
|
40
|
+
/** Token endpoint override; defaults to `${authority}/token`. */
|
|
41
|
+
tokenEndpoint?: string;
|
|
42
|
+
/** OIDC `prompt` value (e.g. `'register'` for the sign-up surface). */
|
|
43
|
+
prompt?: string;
|
|
44
|
+
}
|
|
45
|
+
interface TokenResponse {
|
|
46
|
+
access_token: string;
|
|
47
|
+
refresh_token?: string;
|
|
48
|
+
expires_in?: number;
|
|
49
|
+
}
|
|
50
|
+
type AuthorizeMessage = {
|
|
51
|
+
type: 'jamauth:authorize';
|
|
52
|
+
code: string;
|
|
53
|
+
state: string;
|
|
54
|
+
};
|
|
55
|
+
type ReadyMessage = {
|
|
56
|
+
type: 'jamauth:ready';
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Derive the configured authority origin. The handshake validates incoming
|
|
60
|
+
* `postMessage` events against this origin — never a hardcoded `jamauth.net`
|
|
61
|
+
* literal.
|
|
62
|
+
*/
|
|
63
|
+
declare function authorityOrigin(authority: string): string;
|
|
64
|
+
/** Build the top-level `/auth` authorization URL (PKCE S256, `response_type=code`). */
|
|
65
|
+
declare function buildAuthorizeUrl(params: OidcClientParams): Promise<URL>;
|
|
66
|
+
/** Build the embedded `/embed/authorize` iframe URL (same PKCE S256 params). */
|
|
67
|
+
declare function buildEmbedUrl(params: OidcClientParams): Promise<URL>;
|
|
68
|
+
/**
|
|
69
|
+
* Validate an incoming `postMessage` event against the configured authority
|
|
70
|
+
* origin (never hardcoded) AND the iframe's `contentWindow` (so a same-origin
|
|
71
|
+
* event from an unexpected frame is ignored).
|
|
72
|
+
*/
|
|
73
|
+
declare function isTrustedBridgeMessage(event: MessageEvent, authority: string, iframe: HTMLIFrameElement): boolean;
|
|
74
|
+
/** Parse a `jamauth:authorize` relay payload; returns `null` for other types. */
|
|
75
|
+
declare function parseAuthorizeMessage(data: unknown): {
|
|
76
|
+
code: string;
|
|
77
|
+
state: string;
|
|
78
|
+
} | null;
|
|
79
|
+
/** Parse a `jamauth:ready` handshake payload; returns `true` for the handshake. */
|
|
80
|
+
declare function isReadyMessage(data: unknown): data is ReadyMessage;
|
|
81
|
+
/** Store a minted token response (mirrors `oidc-capture.ts`). */
|
|
82
|
+
declare function storeTokenResponse(response: TokenResponse): void;
|
|
83
|
+
/** Clear the stored session tokens (sign-out). */
|
|
84
|
+
declare function clearStoredTokens(): void;
|
|
85
|
+
/**
|
|
86
|
+
* Exchange an authorization `code` for tokens via a PUBLIC PKCE request
|
|
87
|
+
* (`grant_type=authorization_code`, no client_secret, no Authorization header).
|
|
88
|
+
* The token endpoint defaults to `${authority}/token` (CORS-allowed for the
|
|
89
|
+
* registered client origin via `clientBasedCORS`).
|
|
90
|
+
*/
|
|
91
|
+
declare function exchangeCodeForToken(params: OidcClientParams, code: string): Promise<TokenResponse>;
|
|
92
|
+
/**
|
|
93
|
+
* Fallback to a top-level redirect with a fresh PKCE `authorizeUrl`. Used when
|
|
94
|
+
* the embedded iframe is blocked (or fails to handshake) — idempotent and
|
|
95
|
+
* correct, so a false positive degrades to the top-level flow rather than a
|
|
96
|
+
* broken UX.
|
|
97
|
+
*/
|
|
98
|
+
declare function fallbackToTopLevelRedirect(authorizeUrl: URL): void;
|
|
99
|
+
|
|
100
|
+
/** Configuration carried by `JamauthProvider`. */
|
|
101
|
+
interface JamauthConfig {
|
|
102
|
+
/** The jamauth issuer/authority origin, e.g. `https://jamauth.net`. */
|
|
103
|
+
authority: string;
|
|
104
|
+
clientId: string;
|
|
105
|
+
redirectUri: string;
|
|
106
|
+
resource?: string;
|
|
107
|
+
scope?: string;
|
|
108
|
+
tokenEndpoint?: string;
|
|
109
|
+
loginHint?: string;
|
|
110
|
+
/** Blocked-iframe handshake timeout in ms (default 5000). */
|
|
111
|
+
handshakeTimeoutMs?: number;
|
|
112
|
+
/** Called once the authorization code is exchanged for tokens. */
|
|
113
|
+
onToken?: (response: TokenResponse) => void;
|
|
114
|
+
}
|
|
115
|
+
/** Provide the jamauth authority + client identity to the embedded auth surface. */
|
|
116
|
+
declare function JamauthProvider({ config, children, }: {
|
|
117
|
+
config: JamauthConfig;
|
|
118
|
+
children: ReactNode;
|
|
119
|
+
}): react.JSX.Element;
|
|
120
|
+
/** Read the configured jamauth client identity (throws outside a provider). */
|
|
121
|
+
declare function useJamauth(): JamauthConfig;
|
|
122
|
+
interface SessionState {
|
|
123
|
+
isAuthenticated: boolean;
|
|
124
|
+
token: string | null;
|
|
125
|
+
}
|
|
126
|
+
/** Reactive session state sourced from the stored access token. */
|
|
127
|
+
declare function useSession(): SessionState;
|
|
128
|
+
/** High-level auth surface: session state plus sign-out. */
|
|
129
|
+
declare function useAuth(): SessionState & {
|
|
130
|
+
signOut: () => void;
|
|
131
|
+
};
|
|
132
|
+
/** Low-level OIDC bridge bound to the configured authority/client identity. */
|
|
133
|
+
declare function useOidc(): {
|
|
134
|
+
authorityOrigin: () => string;
|
|
135
|
+
buildAuthorizeUrl: () => Promise<URL>;
|
|
136
|
+
buildEmbedUrl: (prompt?: string) => Promise<URL>;
|
|
137
|
+
exchangeCodeForToken: (code: string) => Promise<TokenResponse>;
|
|
138
|
+
};
|
|
139
|
+
/** Renders `children` only while authenticated (access token present). */
|
|
140
|
+
declare function SignedIn({ children }: {
|
|
141
|
+
children: ReactNode;
|
|
142
|
+
}): react.JSX.Element | null;
|
|
143
|
+
/** Renders `children` only while signed out (no access token present). */
|
|
144
|
+
declare function SignedOut({ children }: {
|
|
145
|
+
children: ReactNode;
|
|
146
|
+
}): react.JSX.Element | null;
|
|
147
|
+
|
|
148
|
+
interface SignInProps {
|
|
149
|
+
/** Override the handshake timeout (ms) for this surface. */
|
|
150
|
+
handshakeTimeoutMs?: number;
|
|
151
|
+
className?: string;
|
|
152
|
+
style?: CSSProperties;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Embedded sign-in surface — an iframe wrapper around the jamauth
|
|
156
|
+
* `/embed/authorize` flow. This component renders **no credential inputs**:
|
|
157
|
+
* the email+password form (and MFA / forgot / reset / verify) lives on the
|
|
158
|
+
* jamauth authority inside the frame, and the completed authorization code is
|
|
159
|
+
* relayed back to the parent via `postMessage`.
|
|
160
|
+
*/
|
|
161
|
+
declare function SignIn({ className, style }: SignInProps): react.JSX.Element;
|
|
162
|
+
|
|
163
|
+
interface SignUpProps {
|
|
164
|
+
/** Override the handshake timeout (ms) for this surface. */
|
|
165
|
+
handshakeTimeoutMs?: number;
|
|
166
|
+
className?: string;
|
|
167
|
+
style?: CSSProperties;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Embedded sign-up surface — an iframe wrapper around the jamauth
|
|
171
|
+
* `/embed/authorize` flow with `prompt=register`. Like `SignIn`, this renders
|
|
172
|
+
* **no credential inputs**; the sign-up form lives on the jamauth authority
|
|
173
|
+
* inside the frame and the completed authorization code is relayed back via
|
|
174
|
+
* `postMessage`.
|
|
175
|
+
*/
|
|
176
|
+
declare function SignUp({ className, style }: SignUpProps): react.JSX.Element;
|
|
177
|
+
|
|
178
|
+
interface UserButtonProps {
|
|
179
|
+
/** Label shown when signed out (default "Sign in"). */
|
|
180
|
+
signInLabel?: ReactNode;
|
|
181
|
+
/** Label shown when signed in (default "Sign out"). */
|
|
182
|
+
signOutLabel?: ReactNode;
|
|
183
|
+
/** Called instead of the default sign-out when the user is signed in. */
|
|
184
|
+
onSignOut?: () => void;
|
|
185
|
+
className?: string;
|
|
186
|
+
style?: CSSProperties;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* A minimal, framework-agnostic account button. It reflects the stored session
|
|
190
|
+
* state and, when signed in, signs the user out (or delegates to `onSignOut`).
|
|
191
|
+
* It renders no credential inputs.
|
|
192
|
+
*/
|
|
193
|
+
declare function UserButton({ signInLabel, signOutLabel, onSignOut, className, style, }: UserButtonProps): react.JSX.Element;
|
|
194
|
+
|
|
195
|
+
type EmbeddedStatus = 'loading' | 'ready' | 'authenticated' | 'fallback';
|
|
196
|
+
interface EmbeddedAuthState {
|
|
197
|
+
iframeRef: React.RefObject<HTMLIFrameElement | null>;
|
|
198
|
+
src: string;
|
|
199
|
+
status: EmbeddedStatus;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Mount the embedded `/embed/authorize` iframe and drive the confirmation
|
|
203
|
+
* handshake + timeout fallback:
|
|
204
|
+
*
|
|
205
|
+
* - `iframe.onload` is NOT authoritative (a `frame-ancestors`-blocked frame
|
|
206
|
+
* still fires `onload`). Instead the parent validates
|
|
207
|
+
* `event.origin === authorityOrigin` (derived from the configured authority,
|
|
208
|
+
* never hardcoded) **and** `event.source === iframe.contentWindow`.
|
|
209
|
+
* - A `handshakeTimeoutMs` timer (default ~5s) falls back to a top-level
|
|
210
|
+
* `window.location.assign(freshPkceAuthorizeUrl)` when no `jamauth:ready`
|
|
211
|
+
* arrives — idempotent and correct, so a false positive degrades to the
|
|
212
|
+
* top-level flow rather than a broken UX.
|
|
213
|
+
* - On `jamauth:authorize`, the code is exchanged via public PKCE and the
|
|
214
|
+
* tokens are stored.
|
|
215
|
+
*/
|
|
216
|
+
declare function useEmbeddedAuth(prompt?: string): EmbeddedAuthState;
|
|
217
|
+
|
|
218
|
+
export { type AuthorizeMessage, type EmbeddedAuthState, type EmbeddedStatus, type JamauthConfig, JamauthProvider, type OidcClientParams, type ReadyMessage, SESSION_CHANGED_EVENT, STORAGE_KEYS, type SessionState, SignIn, type SignInProps, SignUp, type SignUpProps, SignedIn, SignedOut, type TokenResponse, UserButton, type UserButtonProps, authorityOrigin, buildAuthorizeUrl, buildEmbedUrl, clearStoredTokens, exchangeCodeForToken, fallbackToTopLevelRedirect, isReadyMessage, isTrustedBridgeMessage, parseAuthorizeMessage, storeTokenResponse, useAuth, useEmbeddedAuth, useJamauth, useOidc, useSession };
|