@luminaryworks/auth-react 0.3.2 → 0.4.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 +38 -1
- package/dist/index.d.ts +99 -30
- package/dist/index.js +294 -156
- package/dist/index.js.map +1 -1
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -24,7 +24,7 @@ On first 401: try refresh → else open reauth UI (overlay + OIDC **popup**, not
|
|
|
24
24
|
|
|
25
25
|
## Headless login panel
|
|
26
26
|
|
|
27
|
-
Branded panel with **social buttons** (auto-loaded from IdP Experience `socialConnectors` — google / github / x / …) plus **unified account** password.
|
|
27
|
+
Branded panel with **social buttons** (auto-loaded from IdP Experience `socialConnectors` — google / github / x / …) plus **unified account** password. The default `LogtoExperienceAdapter` keeps Logto's `direct_sign_in=social:<target>` parameter inside provider-specific code. Buttons are hidden when the IdP has no social connectors (do not invent Google/GitHub — that dumped users on Logto `/sign-in`).
|
|
28
28
|
|
|
29
29
|
Styles ship as **CSS Modules (SCSS)**. The built bundle auto-injects panel CSS in the browser. Optional explicit import (SSR / style control):
|
|
30
30
|
|
|
@@ -56,9 +56,46 @@ Override layout via `className` / `style` on the root.
|
|
|
56
56
|
|------|---------|--------|
|
|
57
57
|
| `showSocialConnectors` | `true` | `false` skips fetch and hides divider + social buttons |
|
|
58
58
|
| `socialProviders` | `"auto"` | allowlist, or `[]` (same effect as `showSocialConnectors={false}`) |
|
|
59
|
+
| `experienceAdapter` | catalog default | optional custom `LoginExperienceAdapter`; otherwise `config.iamProvider` |
|
|
60
|
+
| `config.iamProvider` | `logto` | `logto` Headless; `oidc` / `zitadel` Hosted Redirect |
|
|
59
61
|
|
|
60
62
|
IdP hosted `/sign-in` social row layout: `node scripts/apply-branding.mjs` (customCss wrap). Enable connectors: `ensure-sign-in-experience.mjs` + `verify-social-direct-signin.mjs`.
|
|
61
63
|
|
|
64
|
+
### Login experience adapters
|
|
65
|
+
|
|
66
|
+
`HeadlessLoginPanel` delegates non-standard password and social-connector flows
|
|
67
|
+
to `LoginExperienceAdapter`; standard OIDC authorization code + PKCE remains in
|
|
68
|
+
the OIDC client. Adapter methods are optional and are used only when both the
|
|
69
|
+
matching capability and method are present. Without password support, the panel
|
|
70
|
+
renders `labels.submitSso` and starts a standard hosted OIDC flow. Built-in
|
|
71
|
+
factory ids: `logto` (default Headless), `hosted` / `oidc` / `zitadel` (Hosted
|
|
72
|
+
Redirect). ZITADEL is a reserved plugin — there is no empty Experience stub:
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
import {
|
|
76
|
+
createLoginExperienceAdapter,
|
|
77
|
+
HostedOidcExperienceAdapter,
|
|
78
|
+
LogtoExperienceAdapter,
|
|
79
|
+
resolveLoginExperienceAdapter,
|
|
80
|
+
type LoginExperienceAdapter,
|
|
81
|
+
type LoginExperienceCapability,
|
|
82
|
+
} from "@luminaryworks/auth-react";
|
|
83
|
+
|
|
84
|
+
const logto = new LogtoExperienceAdapter();
|
|
85
|
+
const sameDefault = createLoginExperienceAdapter("logto");
|
|
86
|
+
const resolved = resolveLoginExperienceAdapter(logto);
|
|
87
|
+
const zitadelLogin = createLoginExperienceAdapter("zitadel"); // HostedOidcExperienceAdapter
|
|
88
|
+
|
|
89
|
+
// Hosted-only enterprise IdP: no Experience API methods are required.
|
|
90
|
+
const hostedOnly = {
|
|
91
|
+
provider: "enterprise",
|
|
92
|
+
capabilities: [],
|
|
93
|
+
} satisfies LoginExperienceAdapter;
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Existing `experiencePasswordSignIn` and `fetchSocialConnectors` imports remain
|
|
97
|
+
available as compatibility functions backed by the default Logto adapter.
|
|
98
|
+
|
|
62
99
|
## Popup callback
|
|
63
100
|
|
|
64
101
|
Callback route must detect popup windows and call `handleSignInPopupCallback` (do not SSO-exchange inside the popup).
|
package/dist/index.d.ts
CHANGED
|
@@ -27,6 +27,11 @@ interface LuminaryIdpConfig {
|
|
|
27
27
|
* When set, Headless password sign-in is attempted before OIDC popup fallback.
|
|
28
28
|
*/
|
|
29
29
|
experienceApiBase?: string;
|
|
30
|
+
/**
|
|
31
|
+
* IAM catalog id: `logto` (default Headless), `oidc` / `zitadel` (Hosted Redirect).
|
|
32
|
+
* Ignored when `HeadlessLoginPanel` receives an explicit `experienceAdapter`.
|
|
33
|
+
*/
|
|
34
|
+
iamProvider?: string;
|
|
30
35
|
}
|
|
31
36
|
interface LuminaryAuthSession {
|
|
32
37
|
accessToken: string;
|
|
@@ -45,9 +50,12 @@ declare function createUserManager(config: LuminaryIdpConfig): UserManager;
|
|
|
45
50
|
declare function resetUserManager(): void;
|
|
46
51
|
interface SignInOptions {
|
|
47
52
|
returnUrl?: string;
|
|
53
|
+
/** Provider-specific authorize parameters supplied by an experience adapter. */
|
|
54
|
+
extraQueryParams?: Record<string, string>;
|
|
48
55
|
/**
|
|
49
56
|
* Logto direct sign-in, e.g. `social:google` / `social:github` / `sso:<connectorId>`.
|
|
50
57
|
* Skips the hosted password page and opens the provider immediately.
|
|
58
|
+
* @deprecated Prefer a LoginExperienceAdapter, which supplies extraQueryParams.
|
|
51
59
|
*/
|
|
52
60
|
directSignIn?: string;
|
|
53
61
|
}
|
|
@@ -83,10 +91,17 @@ declare function clearStoredSession(config: LuminaryIdpConfig): void;
|
|
|
83
91
|
declare function getCurrentUser(config: LuminaryIdpConfig): Promise<LuminaryAuthSession | null>;
|
|
84
92
|
|
|
85
93
|
/**
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
94
|
+
* Capabilities exposed by a headless login-experience provider.
|
|
95
|
+
*
|
|
96
|
+
* Consumers can use these flags to avoid assuming that every provider supports
|
|
97
|
+
* Logto's password, connector-discovery, or direct social-login flows.
|
|
89
98
|
*/
|
|
99
|
+
declare const LOGIN_EXPERIENCE_CAPABILITIES: {
|
|
100
|
+
readonly passwordSignIn: "password-sign-in";
|
|
101
|
+
readonly socialConnectors: "social-connectors";
|
|
102
|
+
readonly socialDirectSignIn: "social-direct-sign-in";
|
|
103
|
+
};
|
|
104
|
+
type LoginExperienceCapability = (typeof LOGIN_EXPERIENCE_CAPABILITIES)[keyof typeof LOGIN_EXPERIENCE_CAPABILITIES];
|
|
90
105
|
type ExperienceIdentifierType = "email" | "username" | "phone";
|
|
91
106
|
interface ExperiencePasswordSignInInput {
|
|
92
107
|
/** Experience API origin (no trailing slash). Prefer SPA origin when proxied. */
|
|
@@ -108,39 +123,91 @@ interface ExperiencePasswordSignInResult {
|
|
|
108
123
|
redirectTo?: string;
|
|
109
124
|
raw?: unknown;
|
|
110
125
|
}
|
|
111
|
-
/**
|
|
112
|
-
* Force authorize onto the Experience/SPA origin so Set-Cookie lands on the same
|
|
113
|
-
* host as subsequent `/api/experience` calls (dev proxy strips Domain).
|
|
114
|
-
*/
|
|
115
|
-
declare function sameOriginAuthorizeUrl(authorizeUrl: string, apiBase: string): string;
|
|
116
|
-
/**
|
|
117
|
-
* Headless password sign-in via Logto Experience API.
|
|
118
|
-
* Requires an OIDC interaction cookie (see {@link bootstrapOidcInteraction}) and
|
|
119
|
-
* same-site Experience calls (SPA proxy or Auth Gateway on the SPA origin).
|
|
120
|
-
*
|
|
121
|
-
* On success, follow {@link ExperiencePasswordSignInResult.redirectTo} in the same
|
|
122
|
-
* window — that URL completes the PKCE round-trip started by createSigninRequest.
|
|
123
|
-
* Do not start a second authorize (that shows Logto `/sign-in` again).
|
|
124
|
-
*
|
|
125
|
-
* Tries the guessed identifier type first, then the alternate email/username so
|
|
126
|
-
* users can sign in with either when both methods are enabled on the IdP.
|
|
127
|
-
*/
|
|
128
|
-
declare function experiencePasswordSignIn(input: ExperiencePasswordSignInInput): Promise<ExperiencePasswordSignInResult>;
|
|
129
126
|
interface ExperienceSocialConnector {
|
|
130
127
|
id: string;
|
|
131
128
|
target: string;
|
|
132
129
|
name: string;
|
|
133
130
|
logo?: string;
|
|
134
131
|
}
|
|
135
|
-
|
|
136
|
-
* Public Logto sign-in experience (no auth). Returns enabled social connectors
|
|
137
|
-
* in SIE order — use for Headless social buttons (google / github / x / …).
|
|
138
|
-
*/
|
|
139
|
-
declare function fetchSocialConnectors(input: {
|
|
132
|
+
interface FetchSocialConnectorsInput {
|
|
140
133
|
/** Same origin as Experience / IdP (e.g. SPA proxy or http://localhost:3001). */
|
|
141
134
|
apiBase: string;
|
|
142
135
|
appId?: string;
|
|
143
|
-
}
|
|
136
|
+
}
|
|
137
|
+
interface SocialSignInRequest {
|
|
138
|
+
/** Provider-specific authorize parameters, passed through by the OIDC client. */
|
|
139
|
+
extraQueryParams?: Record<string, string>;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Provider boundary for non-standard login-experience APIs.
|
|
143
|
+
*
|
|
144
|
+
* Standard OIDC redirect/popup and PKCE handling intentionally remain in the
|
|
145
|
+
* OIDC client. Only provider-specific Experience operations belong here.
|
|
146
|
+
*/
|
|
147
|
+
interface LoginExperienceAdapter {
|
|
148
|
+
readonly provider: string;
|
|
149
|
+
readonly capabilities: readonly LoginExperienceCapability[];
|
|
150
|
+
experiencePasswordSignIn?(input: ExperiencePasswordSignInInput): Promise<ExperiencePasswordSignInResult>;
|
|
151
|
+
fetchSocialConnectors?(input: FetchSocialConnectorsInput): Promise<ExperienceSocialConnector[]>;
|
|
152
|
+
createSocialSignInRequest?(target: string): SocialSignInRequest;
|
|
153
|
+
}
|
|
154
|
+
type LoginExperienceProvider = "logto" | "hosted" | "oidc" | "zitadel" | (string & {});
|
|
155
|
+
/**
|
|
156
|
+
* Factory for built-in login adapters.
|
|
157
|
+
*
|
|
158
|
+
* - `logto`: Experience API Headless (password + social connectors)
|
|
159
|
+
* - `hosted` / `oidc` / `zitadel`: standard OIDC Hosted Redirect (no empty vendor SDK)
|
|
160
|
+
*
|
|
161
|
+
* Products may still pass a custom `LoginExperienceAdapter`. Do not add stub
|
|
162
|
+
* adapters for unintegrated Headless APIs.
|
|
163
|
+
*/
|
|
164
|
+
declare function createLoginExperienceAdapter(provider?: LoginExperienceProvider): LoginExperienceAdapter;
|
|
165
|
+
/**
|
|
166
|
+
* Resolve an explicit product adapter, or the catalog adapter for `iamProvider`.
|
|
167
|
+
* Defaults to Logto for backward compatibility.
|
|
168
|
+
*/
|
|
169
|
+
declare function resolveLoginExperienceAdapter(adapter?: LoginExperienceAdapter | null, iamProvider?: string | null): LoginExperienceAdapter;
|
|
170
|
+
/** `VITE_IAM_PROVIDER` / `IAM_PROVIDER` / older `IDP_MODE`. */
|
|
171
|
+
declare function resolveLoginExperienceProviderFromEnv(env?: Record<string, string | undefined>): LoginExperienceProvider;
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Logto Experience API (Headless) adapter.
|
|
175
|
+
* Prefer same-origin Experience base (SPA proxies /api/experience) so cookies
|
|
176
|
+
* work on HTTP localhost.
|
|
177
|
+
*/
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Force authorize onto the Experience/SPA origin so Set-Cookie lands on the
|
|
181
|
+
* same host as subsequent `/api/experience` calls (dev proxy strips Domain).
|
|
182
|
+
*/
|
|
183
|
+
declare function sameOriginAuthorizeUrl(authorizeUrl: string, apiBase: string): string;
|
|
184
|
+
/** Build Logto's provider-specific direct sign-in authorize parameter. */
|
|
185
|
+
declare function createLogtoDirectSignInRequest(directSignIn: string): SocialSignInRequest;
|
|
186
|
+
/** Built-in adapter for Logto's non-standard Experience API. */
|
|
187
|
+
declare class LogtoExperienceAdapter implements LoginExperienceAdapter {
|
|
188
|
+
readonly provider = "logto";
|
|
189
|
+
readonly capabilities: readonly LoginExperienceCapability[];
|
|
190
|
+
experiencePasswordSignIn(input: ExperiencePasswordSignInInput): Promise<ExperiencePasswordSignInResult>;
|
|
191
|
+
fetchSocialConnectors(input: FetchSocialConnectorsInput): Promise<ExperienceSocialConnector[]>;
|
|
192
|
+
createSocialSignInRequest(target: string): SocialSignInRequest;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Standard OIDC Hosted Redirect adapter.
|
|
197
|
+
*
|
|
198
|
+
* Used for enterprise OIDC and reserved IAM plugins (ZITADEL) that have no
|
|
199
|
+
* shipped Headless Experience API. Password and social stay on the IdP hosted UI.
|
|
200
|
+
*/
|
|
201
|
+
declare class HostedOidcExperienceAdapter implements LoginExperienceAdapter {
|
|
202
|
+
readonly provider: string;
|
|
203
|
+
readonly capabilities: readonly LoginExperienceCapability[];
|
|
204
|
+
constructor(provider?: string);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/** @deprecated Use a LoginExperienceAdapter instance. */
|
|
208
|
+
declare function experiencePasswordSignIn(input: ExperiencePasswordSignInInput): Promise<ExperiencePasswordSignInResult>;
|
|
209
|
+
/** @deprecated Use a LoginExperienceAdapter instance. */
|
|
210
|
+
declare function fetchSocialConnectors(input: FetchSocialConnectorsInput): Promise<ExperienceSocialConnector[]>;
|
|
144
211
|
|
|
145
212
|
/**
|
|
146
213
|
* AuthGate — single-flight 401 recovery with optional token refresh + reauth UI.
|
|
@@ -235,7 +302,7 @@ interface HeadlessLoginLabels {
|
|
|
235
302
|
identifierPlaceholder?: string;
|
|
236
303
|
passwordPlaceholder?: string;
|
|
237
304
|
submitPassword?: string;
|
|
238
|
-
/**
|
|
305
|
+
/** Hosted OIDC button shown when the adapter has no password capability. */
|
|
239
306
|
submitSso?: string;
|
|
240
307
|
submitGoogle?: string;
|
|
241
308
|
submitGithub?: string;
|
|
@@ -248,6 +315,8 @@ interface HeadlessLoginLabels {
|
|
|
248
315
|
}
|
|
249
316
|
interface HeadlessLoginPanelProps {
|
|
250
317
|
config: Partial<LuminaryIdpConfig>;
|
|
318
|
+
/** Login-experience provider. Defaults to the catalog adapter for `config.iamProvider`. */
|
|
319
|
+
experienceAdapter?: LoginExperienceAdapter;
|
|
251
320
|
/** Product display name shown as brand signal */
|
|
252
321
|
productName: string;
|
|
253
322
|
logoSrc?: string;
|
|
@@ -290,7 +359,7 @@ interface HeadlessLoginPanelProps {
|
|
|
290
359
|
}
|
|
291
360
|
/** Shared default accent for product login panels. */
|
|
292
361
|
declare const DEFAULT_LOGIN_THEME_COLOR = "#3a84ff";
|
|
293
|
-
declare function HeadlessLoginPanel({ config, productName, logoSrc, labels: labelsProp, returnUrl, mode, showSocialConnectors, socialProviders, showCancel, onCancel, onOidcSession, onExperienceRedirect, footer, className, style, themeColor, }: HeadlessLoginPanelProps): react.JSX.Element;
|
|
362
|
+
declare function HeadlessLoginPanel({ config, experienceAdapter: experienceAdapterProp, productName, logoSrc, labels: labelsProp, returnUrl, mode, showSocialConnectors, socialProviders, showCancel, onCancel, onOidcSession, onExperienceRedirect, footer, className, style, themeColor, }: HeadlessLoginPanelProps): react.JSX.Element;
|
|
294
363
|
|
|
295
364
|
interface ReauthOverlayProps {
|
|
296
365
|
config: Partial<LuminaryIdpConfig>;
|
|
@@ -353,4 +422,4 @@ declare function createPostLoginPathHelpers(options: PostLoginPathOptions): {
|
|
|
353
422
|
isUnsafeReturnPath: (path: string) => boolean;
|
|
354
423
|
};
|
|
355
424
|
|
|
356
|
-
export { type AuthGateConfig, type AuthGatePhase, AuthGateProvider, type AuthGateProviderProps, type AuthGateSnapshot, DEFAULT_LOGIN_THEME_COLOR, type ExperienceIdentifierType, type ExperiencePasswordSignInInput, type ExperiencePasswordSignInResult, type ExperienceSocialConnector, type HeadlessLoginLabels, HeadlessLoginPanel, type HeadlessLoginPanelProps, LuminaryAuthProvider, type LuminaryAuthProviderProps, type LuminaryAuthSession, type LuminaryIdpConfig, type PostLoginPathOptions, ReauthOverlay, type ReauthOverlayProps, type SignInOptions, type SocialProviderTarget, type UnauthorizedDisposition, authGate, clearStoredSession, createPostLoginPathHelpers, createUserManager, experiencePasswordSignIn, fetchSocialConnectors, getCurrentUser, getStoredAccessToken, handleSignInCallback, handleSignInPopupCallback, isIdpConfigured, isOidcPopupWindow, prepareSignInRequestUrl, readIdpConfigFromEnv, resetUserManager, resolveExperienceApiBase, resolveIssuer, sameOriginAuthorizeUrl, signInPopup, signInRedirect, signOutRedirect, useAuthGate, useAuthGateOptional, useLuminaryAuth, withAuthGateRetry };
|
|
425
|
+
export { type AuthGateConfig, type AuthGatePhase, AuthGateProvider, type AuthGateProviderProps, type AuthGateSnapshot, DEFAULT_LOGIN_THEME_COLOR, type ExperienceIdentifierType, type ExperiencePasswordSignInInput, type ExperiencePasswordSignInResult, type ExperienceSocialConnector, type FetchSocialConnectorsInput, type HeadlessLoginLabels, HeadlessLoginPanel, type HeadlessLoginPanelProps, HostedOidcExperienceAdapter, LOGIN_EXPERIENCE_CAPABILITIES, type LoginExperienceAdapter, type LoginExperienceCapability, type LoginExperienceProvider, LogtoExperienceAdapter, LuminaryAuthProvider, type LuminaryAuthProviderProps, type LuminaryAuthSession, type LuminaryIdpConfig, type PostLoginPathOptions, ReauthOverlay, type ReauthOverlayProps, type SignInOptions, type SocialProviderTarget, type SocialSignInRequest, type UnauthorizedDisposition, authGate, clearStoredSession, createLoginExperienceAdapter, createLogtoDirectSignInRequest, createPostLoginPathHelpers, createUserManager, experiencePasswordSignIn, fetchSocialConnectors, getCurrentUser, getStoredAccessToken, handleSignInCallback, handleSignInPopupCallback, isIdpConfigured, isOidcPopupWindow, prepareSignInRequestUrl, readIdpConfigFromEnv, resetUserManager, resolveExperienceApiBase, resolveIssuer, resolveLoginExperienceAdapter, resolveLoginExperienceProviderFromEnv, sameOriginAuthorizeUrl, signInPopup, signInRedirect, signOutRedirect, useAuthGate, useAuthGateOptional, useLuminaryAuth, withAuthGateRetry };
|