@edgespark/web 0.0.2 → 0.0.4
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/auth/styles/styles.css +10 -0
- package/dist/auth/local-dev.d.ts +31 -0
- package/dist/auth-ui/ManagedAuthUI.d.ts +15 -4
- package/dist/auth-ui/config.d.ts +17 -1
- package/dist/auth-ui/google-one-tap.d.ts +47 -0
- package/dist/auth-ui/index.d.ts +1 -1
- package/dist/auth-ui/mount.d.ts +20 -2
- package/dist/auth-ui/prompt-google-one-tap.d.ts +43 -0
- package/dist/auth-ui/types.d.ts +19 -1
- package/dist/index.cjs +14 -13
- package/dist/index.d.ts +1 -1
- package/dist/index.es.js +844 -549
- package/package.json +1 -1
package/auth/styles/styles.css
CHANGED
|
@@ -258,6 +258,16 @@
|
|
|
258
258
|
background: var(--edgespark-auth-bg-muted);
|
|
259
259
|
}
|
|
260
260
|
|
|
261
|
+
.edgespark-auth__dev-banner {
|
|
262
|
+
background: #fef3c7;
|
|
263
|
+
color: #92400e;
|
|
264
|
+
padding: 0.5rem 1rem;
|
|
265
|
+
border-radius: 6px;
|
|
266
|
+
font-size: 0.8rem;
|
|
267
|
+
text-align: center;
|
|
268
|
+
margin-bottom: 0.75rem;
|
|
269
|
+
}
|
|
270
|
+
|
|
261
271
|
@media (max-width: 480px) {
|
|
262
272
|
.edgespark-auth__card {
|
|
263
273
|
padding: 18px;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Is the web app running in local-dev mode?
|
|
3
|
+
*
|
|
4
|
+
* Reads a `<meta name="edgespark-local-dev" content="true">` tag that
|
|
5
|
+
* the `edgespark dev` reverse proxy splices into every HTML response.
|
|
6
|
+
* The dev proxy only runs under `edgespark dev`; the meta tag is absent
|
|
7
|
+
* on deployed apps (served through the CF dispatcher, which doesn't
|
|
8
|
+
* inject).
|
|
9
|
+
*
|
|
10
|
+
* Uses a <meta> tag rather than an inline <script> so the signal works
|
|
11
|
+
* under strict CSP — `script-src 'self'` without `'unsafe-inline'`
|
|
12
|
+
* would silently drop a script-based marker. Meta tags carry no
|
|
13
|
+
* script-src constraint.
|
|
14
|
+
*
|
|
15
|
+
* No server round-trip, no build-time macro, no hostname heuristic, no
|
|
16
|
+
* framework assumptions. Survives SDK pre-bundling — the SDK reads the
|
|
17
|
+
* DOM at call time, not a value captured at build time.
|
|
18
|
+
*/
|
|
19
|
+
export declare function isLocalDev(): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Auto-verify email in local dev. The server reads the pending verification
|
|
22
|
+
* token from D1, drives Better Auth's verify-email handler, and returns with
|
|
23
|
+
* the session cookie already set. Single round-trip — no token round-trip on
|
|
24
|
+
* the client.
|
|
25
|
+
*/
|
|
26
|
+
export declare function autoVerifyLocalDev(email: string): Promise<boolean>;
|
|
27
|
+
/**
|
|
28
|
+
* Fetch the pending OTP for password reset in local dev.
|
|
29
|
+
* Returns the OTP string or null if not available.
|
|
30
|
+
*/
|
|
31
|
+
export declare function fetchOtpLocalDev(email: string): Promise<string | null>;
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import { BetterAuthClientInstance } from '../auth/types';
|
|
2
2
|
import { NormalizedAuthUIConfig } from './config';
|
|
3
|
+
import { AuthUIModuleRuntimeOptions } from './mount';
|
|
3
4
|
import { MountAuthUIOptions, MountedAuthUI } from './types';
|
|
4
|
-
export interface ManagedAuthUIRuntimeOptions {
|
|
5
|
-
syncPublicSession?: () => Promise<void> | void;
|
|
6
|
-
}
|
|
7
5
|
/**
|
|
8
6
|
* Internal managed auth UI implementation.
|
|
9
7
|
*
|
|
10
8
|
* The public API only exposes `authUI.mount(...)`; this class owns the DOM,
|
|
11
9
|
* form flows, and lifecycle.
|
|
10
|
+
*
|
|
11
|
+
* DOM ownership: the instance owns a single root element it appends to the
|
|
12
|
+
* mount container. It never writes to `container.innerHTML`. This keeps
|
|
13
|
+
* tear-down safe when the container is a DOM node a reconciling framework
|
|
14
|
+
* (React/Vue/Solid) reuses across conditional branches — wiping the
|
|
15
|
+
* container would erase sibling content the framework just rendered.
|
|
12
16
|
*/
|
|
13
17
|
export declare class ManagedAuthUI implements MountedAuthUI {
|
|
14
18
|
private readonly container;
|
|
@@ -27,7 +31,7 @@ export declare class ManagedAuthUI implements MountedAuthUI {
|
|
|
27
31
|
private pendingFocusSnapshot;
|
|
28
32
|
private focusRestoreTimer;
|
|
29
33
|
private verificationCompletionAction;
|
|
30
|
-
constructor(container: HTMLElement, auth: BetterAuthClientInstance, options: MountAuthUIOptions, loadConfig: () => Promise<NormalizedAuthUIConfig>, runtimeOptions?:
|
|
34
|
+
constructor(container: HTMLElement, auth: BetterAuthClientInstance, options: MountAuthUIOptions, loadConfig: () => Promise<NormalizedAuthUIConfig>, runtimeOptions?: AuthUIModuleRuntimeOptions | undefined);
|
|
31
35
|
destroy(): void;
|
|
32
36
|
private initialize;
|
|
33
37
|
private redirectAfterManagedReturnLookupFailure;
|
|
@@ -35,6 +39,7 @@ export declare class ManagedAuthUI implements MountedAuthUI {
|
|
|
35
39
|
private readMountSession;
|
|
36
40
|
private render;
|
|
37
41
|
private renderLoading;
|
|
42
|
+
private renderDevModeBanner;
|
|
38
43
|
private renderStatus;
|
|
39
44
|
private renderCurrentView;
|
|
40
45
|
private renderSignInView;
|
|
@@ -53,6 +58,12 @@ export declare class ManagedAuthUI implements MountedAuthUI {
|
|
|
53
58
|
private resendResetCode;
|
|
54
59
|
private handleResetPassword;
|
|
55
60
|
private resendVerificationEmail;
|
|
61
|
+
/**
|
|
62
|
+
* Drive the local-dev auto-verify endpoint and, on success, complete the
|
|
63
|
+
* auth flow. Returns whether auto-verify completed — callers decide what
|
|
64
|
+
* to do on `false` (sign-up falls through to a retry UI; resend throws).
|
|
65
|
+
*/
|
|
66
|
+
private tryDevAutoVerify;
|
|
56
67
|
private sendVerificationEmail;
|
|
57
68
|
private completeAuth;
|
|
58
69
|
private retryAuthCompletionDataIfNeeded;
|
package/dist/auth-ui/config.d.ts
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
export type OAuthProviderId = "google" | "apple" | "microsoft" | "github" | "gitlab" | "discord";
|
|
2
|
+
interface OAuthProviderConfig {
|
|
3
|
+
/**
|
|
4
|
+
* OAuth Client ID resolved server-side. Present only when both the Client
|
|
5
|
+
* ID var and the corresponding secret resolve, so a non-empty value is
|
|
6
|
+
* the "this provider is fully wired browser-side" signal.
|
|
7
|
+
*/
|
|
8
|
+
clientId?: string;
|
|
9
|
+
}
|
|
2
10
|
interface OAuthProviderBlock {
|
|
3
11
|
enabled?: boolean;
|
|
12
|
+
config?: OAuthProviderConfig;
|
|
4
13
|
}
|
|
5
14
|
interface ProviderEmailPassword {
|
|
6
15
|
enabled?: boolean;
|
|
@@ -27,7 +36,14 @@ export interface NormalizedAuthUIConfig {
|
|
|
27
36
|
requireEmailVerification: boolean;
|
|
28
37
|
passwordResetEmailOtpEnabled: boolean;
|
|
29
38
|
oauthProviders: OAuthProviderId[];
|
|
39
|
+
/**
|
|
40
|
+
* Resolved Google OAuth Client ID when Google is enabled and both
|
|
41
|
+
* credentials resolved server-side; `null` otherwise. Signals that
|
|
42
|
+
* Google client-side wiring is ready.
|
|
43
|
+
*/
|
|
44
|
+
googleClientId: string | null;
|
|
45
|
+
isLocalDev: boolean;
|
|
30
46
|
}
|
|
31
47
|
export declare function loadNormalizedAuthUIConfig(): Promise<NormalizedAuthUIConfig>;
|
|
32
|
-
export declare function normalizeAuthUIConfig(config: AuthConfigResponse): NormalizedAuthUIConfig;
|
|
48
|
+
export declare function normalizeAuthUIConfig(config: AuthConfigResponse, isLocalDev?: boolean): NormalizedAuthUIConfig;
|
|
33
49
|
export {};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal helpers for driving Google Identity Services (One Tap) from the
|
|
3
|
+
* managed auth UI. Loads the GIS client script on demand and exposes a tiny
|
|
4
|
+
* typed surface around the global `google.accounts.id` namespace.
|
|
5
|
+
*
|
|
6
|
+
* GIS is treated as a UX enhancement: any load failure falls back silently
|
|
7
|
+
* to the regular "Continue with Google" OAuth button.
|
|
8
|
+
*/
|
|
9
|
+
interface GsiCredentialResponse {
|
|
10
|
+
credential: string;
|
|
11
|
+
select_by?: string;
|
|
12
|
+
}
|
|
13
|
+
interface GsiInitializeOptions {
|
|
14
|
+
client_id: string;
|
|
15
|
+
callback: (response: GsiCredentialResponse) => void;
|
|
16
|
+
auto_select?: boolean;
|
|
17
|
+
cancel_on_tap_outside?: boolean;
|
|
18
|
+
use_fedcm_for_prompt?: boolean;
|
|
19
|
+
context?: "signin" | "signup" | "use";
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Subset of Google's `PromptMomentNotification`. Methods are optional because
|
|
23
|
+
* GIS's FedCM-era roadmap retires some of them, and EdgeSpark does not depend
|
|
24
|
+
* on `@types/google.accounts` for the full type surface.
|
|
25
|
+
*/
|
|
26
|
+
interface GsiPromptNotification {
|
|
27
|
+
isNotDisplayed?: () => boolean;
|
|
28
|
+
isSkippedMoment?: () => boolean;
|
|
29
|
+
isDismissedMoment?: () => boolean;
|
|
30
|
+
getDismissedReason?: () => string | undefined;
|
|
31
|
+
}
|
|
32
|
+
interface GsiIdAccounts {
|
|
33
|
+
initialize(options: GsiInitializeOptions): void;
|
|
34
|
+
prompt(notificationCallback?: (notification: GsiPromptNotification) => void): void;
|
|
35
|
+
cancel(): void;
|
|
36
|
+
disableAutoSelect(): void;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Loads `accounts.google.com/gsi/client` once per page and resolves with
|
|
40
|
+
* the `google.accounts.id` namespace. Subsequent calls return the same
|
|
41
|
+
* promise; load failures reject and reset so a caller can retry next mount.
|
|
42
|
+
*/
|
|
43
|
+
export declare function loadGoogleIdentityServices(): Promise<GsiIdAccounts>;
|
|
44
|
+
export type GoogleIdentityServices = GsiIdAccounts;
|
|
45
|
+
export type GoogleCredentialResponse = GsiCredentialResponse;
|
|
46
|
+
export type GooglePromptNotification = GsiPromptNotification;
|
|
47
|
+
export {};
|
package/dist/auth-ui/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { createAuthUIModule } from './mount';
|
|
2
2
|
export { AUTH_UI_APPEARANCE_VARIABLE, AUTH_UI_APPEARANCE_VARIABLE_NAMES, AUTH_UI_THEME, AUTH_UI_DEFAULT_THEME, AUTH_UI_THEME_DARK, AUTH_UI_THEME_LIGHT, AUTH_UI_THEMES, } from './appearance';
|
|
3
3
|
export type { AuthUIAppearance, AuthUIAppearanceVariableName, AuthUIAppearanceVariables, AuthUITheme, } from './appearance';
|
|
4
|
-
export type { AuthSuccessEvent, AuthUILabelOverrides, AuthUILabels, ControlledAuthUIOptions, EdgeSparkAuthUI, MountAuthUIOptions, MountedAuthUI, RedirectAuthUIOptions, } from './types';
|
|
4
|
+
export type { AuthenticatedAuthSuccessEvent, AuthSuccessEvent, AuthUILabelOverrides, AuthUILabels, ControlledAuthUIOptions, EdgeSparkAuthUI, MountAuthUIOptions, MountedAuthUI, OneTapPromptHandle, PromptGoogleOneTapOptions, RedirectAuthUIOptions, } from './types';
|
package/dist/auth-ui/mount.d.ts
CHANGED
|
@@ -1,4 +1,22 @@
|
|
|
1
1
|
import { BetterAuthClientInstance } from '../auth/types';
|
|
2
|
-
import { ManagedAuthUIRuntimeOptions } from './ManagedAuthUI';
|
|
3
2
|
import { EdgeSparkAuthUI } from './types';
|
|
4
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Internal runtime config for the auth-UI module factory. Threads cross-cutting
|
|
5
|
+
* auth wiring into `ManagedAuthUI` (modal/redirect flows) and
|
|
6
|
+
* `promptGoogleOneTap` (page-load One Tap prompt).
|
|
7
|
+
*/
|
|
8
|
+
export interface AuthUIModuleRuntimeOptions {
|
|
9
|
+
/**
|
|
10
|
+
* Best-effort hook to nudge the public auth session after the managed UI
|
|
11
|
+
* completes a sign-in. Used by `ManagedAuthUI`'s email and OAuth flows.
|
|
12
|
+
*/
|
|
13
|
+
syncPublicSession?: () => Promise<void> | void;
|
|
14
|
+
/**
|
|
15
|
+
* The public auth client used by `promptGoogleOneTap` for credential
|
|
16
|
+
* exchange. Routing One Tap through the same client as `signIn`/`signUp`
|
|
17
|
+
* keeps session updates and `onSessionChange` consistent across all
|
|
18
|
+
* sign-in methods.
|
|
19
|
+
*/
|
|
20
|
+
publicAuthClient: BetterAuthClientInstance;
|
|
21
|
+
}
|
|
22
|
+
export declare function createAuthUIModule(auth: BetterAuthClientInstance, runtimeOptions: AuthUIModuleRuntimeOptions): EdgeSparkAuthUI;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { BetterAuthClientInstance } from '../auth/types';
|
|
2
|
+
import { EdgeSparkAuthError } from '../errors';
|
|
3
|
+
import { NormalizedAuthUIConfig } from './config';
|
|
4
|
+
import { AuthenticatedAuthSuccessEvent } from './types';
|
|
5
|
+
export interface PromptGoogleOneTapOptions {
|
|
6
|
+
/**
|
|
7
|
+
* Fires when Google One Tap sign-in completes.
|
|
8
|
+
*
|
|
9
|
+
* **Most apps should prefer `client.auth.onSessionChange`** as the single
|
|
10
|
+
* source of truth — it fires for One Tap, modal sign-in, sign-out, and
|
|
11
|
+
* cross-tab session changes. Use `onSuccess` only for flow-local concerns
|
|
12
|
+
* scoped to this specific prompt (e.g., per-flow analytics).
|
|
13
|
+
*/
|
|
14
|
+
onSuccess?: (event: AuthenticatedAuthSuccessEvent) => void;
|
|
15
|
+
/**
|
|
16
|
+
* Fires on credential-exchange or post-sign-in errors.
|
|
17
|
+
*/
|
|
18
|
+
onError?: (error: EdgeSparkAuthError) => void;
|
|
19
|
+
/**
|
|
20
|
+
* Fires when Google declines to display the prompt — e.g., FedCM cooldown,
|
|
21
|
+
* no eligible accounts, or browser permission denied. Use this to render a
|
|
22
|
+
* fallback "Sign in with Google" button.
|
|
23
|
+
*/
|
|
24
|
+
onUnavailable?: () => void;
|
|
25
|
+
}
|
|
26
|
+
export interface OneTapPromptHandle {
|
|
27
|
+
/**
|
|
28
|
+
* Dismiss the prompt and suppress any pending callbacks. Idempotent and
|
|
29
|
+
* safe to call after the prompt has already closed.
|
|
30
|
+
*/
|
|
31
|
+
cancel(): void;
|
|
32
|
+
}
|
|
33
|
+
interface PromptRuntime {
|
|
34
|
+
/**
|
|
35
|
+
* The wrapped public auth client. Calls flow through its path-proxy so
|
|
36
|
+
* `oneTap.callback` triggers the same session-atom refresh and
|
|
37
|
+
* `onSessionChange` emit as `signIn`/`signUp`.
|
|
38
|
+
*/
|
|
39
|
+
authClient: BetterAuthClientInstance;
|
|
40
|
+
loadConfig: () => Promise<NormalizedAuthUIConfig>;
|
|
41
|
+
}
|
|
42
|
+
export declare function createPromptGoogleOneTap(runtime: PromptRuntime): (options?: PromptGoogleOneTapOptions) => OneTapPromptHandle;
|
|
43
|
+
export {};
|
package/dist/auth-ui/types.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ import { EdgeSparkAuthError } from '../errors';
|
|
|
3
3
|
import { RedirectTarget } from '../redirect';
|
|
4
4
|
import { DeepPartial } from '../shared/types';
|
|
5
5
|
import { AuthUIAppearance } from './appearance';
|
|
6
|
+
import { OneTapPromptHandle, PromptGoogleOneTapOptions } from './prompt-google-one-tap';
|
|
7
|
+
export type { OneTapPromptHandle, PromptGoogleOneTapOptions } from './prompt-google-one-tap';
|
|
6
8
|
/** Sign-in or sign-up completed with an authenticated session. */
|
|
7
9
|
export type AuthenticatedAuthSuccessEvent = {
|
|
8
10
|
action: "sign-in";
|
|
@@ -152,5 +154,21 @@ export interface EdgeSparkAuthUI {
|
|
|
152
154
|
* surrounding app wants to control routing/state after auth completes.
|
|
153
155
|
*/
|
|
154
156
|
mount(container: HTMLElement, options: MountAuthUIOptions): MountedAuthUI;
|
|
157
|
+
/**
|
|
158
|
+
* Triggers a Google One Tap prompt. Calling the function is the opt-in —
|
|
159
|
+
* there is no separate server config or option flag.
|
|
160
|
+
*
|
|
161
|
+
* The prompt shows only when Google is fully wired server-side (the
|
|
162
|
+
* project's `auth-config.yaml` enables Google with resolvable credentials).
|
|
163
|
+
* Otherwise the call logs a clear error to the console and returns an
|
|
164
|
+
* inert handle.
|
|
165
|
+
*
|
|
166
|
+
* @example
|
|
167
|
+
* useEffect(() => {
|
|
168
|
+
* if (session) return;
|
|
169
|
+
* const prompt = client.authUI.promptGoogleOneTap();
|
|
170
|
+
* return () => prompt.cancel();
|
|
171
|
+
* }, [session]);
|
|
172
|
+
*/
|
|
173
|
+
promptGoogleOneTap(options?: PromptGoogleOneTapOptions): OneTapPromptHandle;
|
|
155
174
|
}
|
|
156
|
-
export {};
|