@reblu/site-next 1.1.0 → 1.2.1

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/dist/auth.d.ts ADDED
@@ -0,0 +1,267 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ interface LoginFormCopy {
4
+ magicLinkTabLabel: string;
5
+ passwordTabLabel: string;
6
+ emailLabel: string;
7
+ emailPlaceholder: string;
8
+ passwordLabel: string;
9
+ passwordPlaceholder: string;
10
+ passwordSubmitCta: string;
11
+ forgotPasswordCta: string;
12
+ magicLinkSubmitCta: string;
13
+ magicLinkSuccessTitle: string;
14
+ magicLinkSuccessMessage: string;
15
+ mfaTitle: string;
16
+ mfaMessage: string;
17
+ mfaCodeLabel: string;
18
+ mfaCodePlaceholder: string;
19
+ mfaSubmitCta: string;
20
+ invalidEmailError: string;
21
+ networkError: string;
22
+ invalidCredentialsError: string;
23
+ mfaInvalidCodeError: string;
24
+ }
25
+ interface LoginFormProps {
26
+ passwordLoginUrl: string;
27
+ mfaVerifyUrl: string;
28
+ magicLinkRequestUrl: string;
29
+ resetPasswordUrl: string;
30
+ copy?: Partial<LoginFormCopy>;
31
+ className?: string;
32
+ defaultMethod?: 'magic-link' | 'password';
33
+ onPasswordSubmitted?: (email: string) => void;
34
+ onMagicLinkSubmitted?: (email: string) => void;
35
+ onMfaSubmitted?: () => void;
36
+ }
37
+ declare function LoginForm(props: LoginFormProps): react_jsx_runtime.JSX.Element;
38
+
39
+ interface AuthCallbackCopy {
40
+ loadingTitle: string;
41
+ loadingMessage: string;
42
+ successMessage: string;
43
+ expiredTitle: string;
44
+ expiredMessage: string;
45
+ expiredCta: string;
46
+ networkErrorTitle: string;
47
+ networkErrorMessage: string;
48
+ networkErrorRetryCta: string;
49
+ networkErrorBackCta: string;
50
+ malformedTitle: string;
51
+ malformedMessage: string;
52
+ malformedCta: string;
53
+ }
54
+ interface AuthCallbackProps {
55
+ exchangeUrl: string;
56
+ loginUrl: string;
57
+ copy?: Partial<AuthCallbackCopy>;
58
+ onSuccess?: (redirectTo: string) => void;
59
+ onError?: (state: 'expired' | 'network' | 'malformed', error?: Error) => void;
60
+ className?: string;
61
+ }
62
+ declare function AuthCallback({ exchangeUrl, loginUrl, copy, onSuccess, onError, className, }: AuthCallbackProps): react_jsx_runtime.JSX.Element;
63
+
64
+ /**
65
+ * Maps the raw `?error=` query param that Supabase appends when a magic link is
66
+ * already consumed or expired to a user-facing Spanish message.
67
+ *
68
+ * Supabase redirects to /login?error=... with a raw English message (e.g.
69
+ * "Email link is invalid or has expired"). Showing that verbatim is confusing,
70
+ * so we translate the common cases and signal whether the "Solicitar otro
71
+ * enlace" CTA should be offered.
72
+ *
73
+ * Matching is case-insensitive and whitespace-tolerant so it survives small
74
+ * variations in how the error text arrives.
75
+ *
76
+ * Relocated from apps/demo-site/src/lib/utils/login-errors.ts (REB-510 slice
77
+ * 2a) as a copy-injectable helper — Spanish defaults are unchanged, and a SITE
78
+ * MAY override individual messages via `Partial<LoginErrorCopy>`.
79
+ */
80
+ interface LoginErrorInfo {
81
+ /** Message shown in the error card. */
82
+ message: string;
83
+ /** Whether to show the "Solicitar otro enlace" CTA. */
84
+ showRequestLink: boolean;
85
+ }
86
+ interface LoginErrorCopy {
87
+ expiredMessage: string;
88
+ missingTokenMessage: string;
89
+ genericMessage: string;
90
+ }
91
+ declare function mapLoginError(error: string | null | undefined, copy?: Partial<LoginErrorCopy>): LoginErrorInfo | null;
92
+
93
+ interface AuthLogoCopy {
94
+ /**
95
+ * Overrides the rendered `<img>` alt text. Pass `''` explicitly to mark the
96
+ * logo as decorative (e.g. when an adjacent heading already announces
97
+ * `siteName`, so screen readers shouldn't read it twice) — `undefined`
98
+ * (the key simply omitted from `copy`) is what falls back to `siteName`.
99
+ */
100
+ altText?: string;
101
+ /** Shown when neither a logo URL nor `siteName` is available. */
102
+ fallbackLabel: string;
103
+ }
104
+ interface AuthLogoProps {
105
+ logoLightExpandedUrl: string | null;
106
+ logoDarkExpandedUrl: string | null;
107
+ logoLightSmallUrl: string | null;
108
+ logoDarkSmallUrl: string | null;
109
+ siteName: string;
110
+ /** @default 'expanded' */
111
+ variant?: 'expanded' | 'compact';
112
+ className?: string;
113
+ copy?: Partial<AuthLogoCopy>;
114
+ /**
115
+ * When `true`, renders `null` instead of the `siteName`/fallback-label text
116
+ * span whenever no logo URL resolves for the active variant+theme, rather
117
+ * than showing the text. Use this when the consumer already renders
118
+ * `siteName` as a heading elsewhere on the page — without it, a visitor
119
+ * with no logo configured (or only a light-mode logo, viewed in dark mode)
120
+ * would see/hear `siteName` twice: once from this fallback, once from the
121
+ * consumer's own heading.
122
+ * @default false
123
+ */
124
+ hideTextFallback?: boolean;
125
+ }
126
+ /**
127
+ * Dynamic tenant logo for auth pages (REB-510 R1). Resolves expanded/compact ×
128
+ * light/dark from the 4 `/api/site/config` logo URLs, switching light/dark
129
+ * CLIENT-SIDE via `next-themes`. Falls back to `siteName` text, then a generic
130
+ * `copy.fallbackLabel`, whenever the resolved URL for the active
131
+ * variant+theme combination is `null` — it never silently swaps in the OTHER
132
+ * theme's logo.
133
+ *
134
+ * Hydration-safe: `next-themes`' `resolvedTheme` is `undefined` until it
135
+ * mounts client-side, so pre-mount `isDark` is always `false` — the same
136
+ * light-first markup the server rendered, avoiding a hydration mismatch.
137
+ *
138
+ * Renders a plain `<img>`, not `next/image`: this is a distributable SDK
139
+ * consumed by external SITE repos, so it cannot assume the consuming app's
140
+ * `next.config` `images.remotePatterns` allowlists the tenant's logo CDN.
141
+ */
142
+ declare function AuthLogo(props: AuthLogoProps): react_jsx_runtime.JSX.Element | null;
143
+
144
+ interface ResetPasswordRequestCopy {
145
+ emailLabel: string;
146
+ emailPlaceholder: string;
147
+ submitCta: string;
148
+ submittingCta: string;
149
+ successTitle: string;
150
+ successMessage: string;
151
+ backToLoginCta: string;
152
+ invalidEmailError: string;
153
+ networkError: string;
154
+ }
155
+ interface ResetPasswordRequestProps {
156
+ requestUrl: string;
157
+ loginUrl: string;
158
+ copy?: Partial<ResetPasswordRequestCopy>;
159
+ className?: string;
160
+ onSubmitted?: (email: string) => void;
161
+ }
162
+ /**
163
+ * Step 1 of the password-reset flow — anti-enumeration: always shows the same
164
+ * generic success message on a 2xx response, regardless of whether the email
165
+ * exists (the backend never leaks that).
166
+ */
167
+ declare function ResetPasswordRequest(props: ResetPasswordRequestProps): react_jsx_runtime.JSX.Element;
168
+
169
+ interface ResetPasswordConfirmCopy {
170
+ passwordLabel: string;
171
+ passwordPlaceholder: string;
172
+ confirmPasswordLabel: string;
173
+ confirmPasswordPlaceholder: string;
174
+ mfaCodeLabel: string;
175
+ mfaCodePlaceholder: string;
176
+ mfaHelpMessage: string;
177
+ submitCta: string;
178
+ submittingCta: string;
179
+ passwordTooShortError: string;
180
+ passwordMismatchError: string;
181
+ mfaInvalidCodeError: string;
182
+ genericError: string;
183
+ missingTokensTitle: string;
184
+ missingTokensMessage: string;
185
+ requestNewLinkCta: string;
186
+ }
187
+ interface ResetPasswordConfirmProps {
188
+ confirmUrl: string;
189
+ loginUrl: string;
190
+ resetRequestUrl: string;
191
+ copy?: Partial<ResetPasswordConfirmCopy>;
192
+ className?: string;
193
+ onSuccess?: () => void;
194
+ }
195
+ /**
196
+ * Step 2 of the password-reset flow. Reads `access_token`/`refresh_token`
197
+ * straight off `useSearchParams` — no `window.location.search` + effect-timing
198
+ * workaround needed here because, unlike a page-level default export, this is
199
+ * a component the SITE mounts inside its own `<Suspense>` boundary.
200
+ *
201
+ * REB-378: when the account has a verified MFA factor, the recovery session
202
+ * (AAL1) cannot change the password on its own. The backend responds
203
+ * `{ data: { mfaRequired: true } }` and this reveals a 6-digit TOTP field so
204
+ * the user can resubmit with the code (the recovery tokens stay valid).
205
+ */
206
+ declare function ResetPasswordConfirm(props: ResetPasswordConfirmProps): react_jsx_runtime.JSX.Element;
207
+
208
+ interface SetPasswordCopy {
209
+ passwordLabel: string;
210
+ passwordPlaceholder: string;
211
+ confirmPasswordLabel: string;
212
+ confirmPasswordPlaceholder: string;
213
+ submitCta: string;
214
+ submittingCta: string;
215
+ passwordTooShortError: string;
216
+ passwordMismatchError: string;
217
+ genericError: string;
218
+ missingTokenTitle: string;
219
+ missingTokenMessage: string;
220
+ backToLoginCta: string;
221
+ }
222
+ interface SetPasswordProps {
223
+ submitUrl: string;
224
+ loginUrl: string;
225
+ copy?: Partial<SetPasswordCopy>;
226
+ className?: string;
227
+ onSuccess?: (sessionExchangeUrl: string) => void;
228
+ }
229
+ /**
230
+ * Invite flow — for a user setting their initial password. Reads
231
+ * `session_exchange_token` off `useSearchParams`; on success, redirects via
232
+ * `window.location.assign` (NOT the Next router) because the returned
233
+ * `sessionExchangeUrl` points at base-api's own domain to set cookies, not a
234
+ * same-origin SITE route.
235
+ */
236
+ declare function SetPassword(props: SetPasswordProps): react_jsx_runtime.JSX.Element;
237
+
238
+ interface AuthConfirmCopy {
239
+ loadingMessage: string;
240
+ successTitle: string;
241
+ successMessage: string;
242
+ successCta: string;
243
+ errorTitle: string;
244
+ errorMessage: string;
245
+ errorCta: string;
246
+ }
247
+ interface AuthConfirmProps {
248
+ confirmUrl: string;
249
+ loginUrl: string;
250
+ copy?: Partial<AuthConfirmCopy>;
251
+ className?: string;
252
+ }
253
+ /**
254
+ * Dual-mode email confirmation (signup / email-change):
255
+ *
256
+ * 1. `?success=true` — base-api already ran `verifyOtp` server-side and
257
+ * redirected here. Shows the confirmed message with no API call.
258
+ * 2. `?token_hash=&type=` — client-initiated verify: POSTs to `confirmUrl`
259
+ * and follows the returned `sessionExchangeUrl`, or shows success/error
260
+ * copy based on the response.
261
+ *
262
+ * Neither param present → shown as an error state with a link back to login,
263
+ * rather than a silent client-side redirect.
264
+ */
265
+ declare function AuthConfirm(props: AuthConfirmProps): react_jsx_runtime.JSX.Element;
266
+
267
+ export { AuthCallback, type AuthCallbackCopy, type AuthCallbackProps, AuthConfirm, type AuthConfirmCopy, type AuthConfirmProps, AuthLogo, type AuthLogoCopy, type AuthLogoProps, type LoginErrorCopy, type LoginErrorInfo, LoginForm, type LoginFormCopy, type LoginFormProps, ResetPasswordConfirm, type ResetPasswordConfirmCopy, type ResetPasswordConfirmProps, ResetPasswordRequest, type ResetPasswordRequestCopy, type ResetPasswordRequestProps, SetPassword, type SetPasswordCopy, type SetPasswordProps, mapLoginError };