@dloizides/auth-web 1.12.0 → 1.13.0

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/index.mjs CHANGED
@@ -113,7 +113,7 @@ function AuthScreen({
113
113
  ] });
114
114
  }
115
115
 
116
- // src/components/labels.ts
116
+ // src/components/labels/loginLabels.ts
117
117
  var DEFAULT_LOGIN_LABELS = {
118
118
  title: "Sign in",
119
119
  subtitle: "Welcome back",
@@ -128,6 +128,8 @@ var DEFAULT_LOGIN_LABELS = {
128
128
  invalidCredentials: "Incorrect username or password.",
129
129
  missingFields: "Enter both your username and password."
130
130
  };
131
+
132
+ // src/components/labels/forgotPasswordLabels.ts
131
133
  var DEFAULT_FORGOT_PASSWORD_LABELS = {
132
134
  title: "Forgot password",
133
135
  description: "Enter your email and we will send you a reset link.",
@@ -144,6 +146,8 @@ var DEFAULT_FORGOT_PASSWORD_FIELDS_LABELS = {
144
146
  cancel: "Cancel",
145
147
  close: "Close"
146
148
  };
149
+
150
+ // src/components/labels/otpLabels.ts
147
151
  var DEFAULT_OTP_LABELS = {
148
152
  requestTitle: "Sign in with a code",
149
153
  requestDescription: "Enter your email and we will send you a one-time code.",
@@ -164,6 +168,8 @@ var DEFAULT_OTP_LABELS = {
164
168
  resending: "Resending...",
165
169
  changeEmail: "Use a different email"
166
170
  };
171
+
172
+ // src/components/labels/pinLabels.ts
167
173
  var DEFAULT_PIN_LABELS = {
168
174
  title: "Enter your event PIN",
169
175
  description: "Enter the PIN for this event to sign in.",
@@ -174,6 +180,8 @@ var DEFAULT_PIN_LABELS = {
174
180
  missingPin: "Enter your event PIN.",
175
181
  invalidPin: "That PIN is incorrect, has expired, or is locked out."
176
182
  };
183
+
184
+ // src/components/labels/devicePinLabels.ts
177
185
  var DEFAULT_DEVICE_PIN_UNLOCK_LABELS = {
178
186
  title: "Welcome back, {name}",
179
187
  titleNoName: "Welcome back",
@@ -231,6 +239,8 @@ var DEFAULT_DEVICE_PIN_SETTINGS_LABELS = {
231
239
  disabling: "Disabling...",
232
240
  disableFailed: "Could not disable PIN sign-in. Try again later."
233
241
  };
242
+
243
+ // src/components/labels/passkeyLabels.ts
234
244
  var DEFAULT_PASSKEY_LOGIN_LABELS = {
235
245
  signInButton: "Sign in with a passkey",
236
246
  signInHint: "Use your fingerprint, face, or security key to sign in",
@@ -246,6 +256,8 @@ var DEFAULT_PASSKEY_SETTINGS_LABELS = {
246
256
  addHint: "Start setting up a passkey for this account",
247
257
  registeredSuccess: "Your passkey was added. You can now use it to sign in."
248
258
  };
259
+
260
+ // src/components/labels/preferredMethodLabels.ts
249
261
  var DEFAULT_PREFERRED_METHOD_SETTINGS_LABELS = {
250
262
  title: "Preferred sign-in method",
251
263
  description: "Pick how you usually sign in. We will show this method first on your devices.",
@@ -261,14 +273,20 @@ var DEFAULT_PREFERRED_METHOD_HINT_LABELS = {
261
273
  pin: "You usually sign in with your quick PIN on this account.",
262
274
  passkey: "You usually sign in with a passkey."
263
275
  };
276
+
277
+ // src/components/labels/demoLabels.ts
264
278
  var DEFAULT_DEMO_CREDENTIALS_HINT_LABELS = {
265
279
  title: "Demo access",
266
280
  description: "Explore the full product with our shared demo account.",
267
281
  usernameLabel: "Username",
268
282
  passwordLabel: "Password",
269
283
  useCredentials: "Use these credentials",
270
- useCredentialsHint: "Fill the sign-in form with the demo username and password"
284
+ useCredentialsHint: "Fill the sign-in form with the demo username and password",
285
+ toggle: "Try the demo",
286
+ toggleHint: "Show the demo account username and password"
271
287
  };
288
+
289
+ // src/components/labels/resetPasswordLabels.ts
272
290
  var DEFAULT_RESET_PASSWORD_LABELS = {
273
291
  title: "Reset password",
274
292
  description: "Choose a new password for your account.",
@@ -362,7 +380,9 @@ var AuthTestIds = {
362
380
  demoCredentialsHint: "auth-demo-credentials-hint",
363
381
  demoCredentialsUsername: "auth-demo-credentials-username",
364
382
  demoCredentialsPassword: "auth-demo-credentials-password",
365
- demoCredentialsUseButton: "auth-demo-credentials-use"
383
+ demoCredentialsUseButton: "auth-demo-credentials-use",
384
+ // The collapsed disclosure trigger (`disclosure` variant only).
385
+ demoCredentialsToggle: "auth-demo-credentials-toggle"
366
386
  };
367
387
  function withTestIdPrefix(baseId, prefix) {
368
388
  return prefix === void 0 || prefix === "" ? baseId : `${prefix}-${baseId}`;
@@ -522,6 +542,35 @@ function useLoginPrefill({
522
542
  }
523
543
  return { username, password, setUsername, setPassword };
524
544
  }
545
+ function useLoginSubmit({
546
+ username,
547
+ password,
548
+ login,
549
+ onSuccess,
550
+ missingFieldsLabel,
551
+ invalidCredentialsLabel
552
+ }) {
553
+ const [errorText, setErrorText] = useState(null);
554
+ const runLogin = useCallback(async () => {
555
+ setErrorText(null);
556
+ const trimmedUsername = username.trim();
557
+ const hasMissingField = trimmedUsername.length === 0 || password.length === 0;
558
+ if (hasMissingField) {
559
+ setErrorText(missingFieldsLabel);
560
+ return;
561
+ }
562
+ try {
563
+ const user = await login({ username: trimmedUsername, password });
564
+ onSuccess(user);
565
+ } catch {
566
+ setErrorText(invalidCredentialsLabel);
567
+ }
568
+ }, [username, password, login, onSuccess, missingFieldsLabel, invalidCredentialsLabel]);
569
+ const handleSubmit = useCallback(() => {
570
+ void runLogin();
571
+ }, [runLogin]);
572
+ return { errorText, handleSubmit };
573
+ }
525
574
  var BffAuthStatus = /* @__PURE__ */ ((BffAuthStatus2) => {
526
575
  BffAuthStatus2["Loading"] = "loading";
527
576
  BffAuthStatus2["Authenticated"] = "authenticated";
@@ -652,25 +701,14 @@ function LoginForm({
652
701
  prefillNonce,
653
702
  prefillIntent
654
703
  });
655
- const [errorText, setErrorText] = useState(null);
656
- const runLogin = useCallback(async () => {
657
- setErrorText(null);
658
- const trimmedUsername = username.trim();
659
- const hasMissingField = trimmedUsername.length === 0 || password.length === 0;
660
- if (hasMissingField) {
661
- setErrorText(labels.missingFields);
662
- return;
663
- }
664
- try {
665
- const user = await login({ username: trimmedUsername, password });
666
- onSuccess(user);
667
- } catch {
668
- setErrorText(labels.invalidCredentials);
669
- }
670
- }, [username, password, login, onSuccess, labels.missingFields, labels.invalidCredentials]);
671
- const handleSubmit = useCallback(() => {
672
- void runLogin();
673
- }, [runLogin]);
704
+ const { errorText, handleSubmit } = useLoginSubmit({
705
+ username,
706
+ password,
707
+ login,
708
+ onSuccess,
709
+ missingFieldsLabel: labels.missingFields,
710
+ invalidCredentialsLabel: labels.invalidCredentials
711
+ });
674
712
  const submitButtonStyle = isSubmitting ? [styles3.primaryButton, styles3.primaryButtonDisabled] : styles3.primaryButton;
675
713
  const content = /* @__PURE__ */ jsxs(Fragment, { children: [
676
714
  /* @__PURE__ */ jsx(Text, { style: styles3.title, children: labels.title }),
@@ -3181,7 +3219,62 @@ function PreferredMethodHint({
3181
3219
  }
3182
3220
  return /* @__PURE__ */ jsx(View, { testID: withTestIdPrefix(AuthTestIds.preferredMethodHint, testIdPrefix), children: /* @__PURE__ */ jsx(Text, { style: styles3.helperText, children: text }) });
3183
3221
  }
3222
+ function DemoCredentialsBody({
3223
+ credentials,
3224
+ labels,
3225
+ styles: styles3,
3226
+ authStyles,
3227
+ testIdPrefix,
3228
+ onUse
3229
+ }) {
3230
+ return /* @__PURE__ */ jsxs(View, { children: [
3231
+ /* @__PURE__ */ jsxs(View, { style: styles3.row, children: [
3232
+ /* @__PURE__ */ jsx(Text, { style: styles3.rowLabel, children: labels.usernameLabel }),
3233
+ /* @__PURE__ */ jsx(
3234
+ Text,
3235
+ {
3236
+ selectable: true,
3237
+ style: styles3.rowValue,
3238
+ testID: withTestIdPrefix(AuthTestIds.demoCredentialsUsername, testIdPrefix),
3239
+ children: credentials.username
3240
+ }
3241
+ )
3242
+ ] }),
3243
+ /* @__PURE__ */ jsxs(View, { style: styles3.row, children: [
3244
+ /* @__PURE__ */ jsx(Text, { style: styles3.rowLabel, children: labels.passwordLabel }),
3245
+ /* @__PURE__ */ jsx(
3246
+ Text,
3247
+ {
3248
+ selectable: true,
3249
+ style: styles3.rowValue,
3250
+ testID: withTestIdPrefix(AuthTestIds.demoCredentialsPassword, testIdPrefix),
3251
+ children: credentials.password
3252
+ }
3253
+ )
3254
+ ] }),
3255
+ onUse !== void 0 ? /* @__PURE__ */ jsx(
3256
+ TouchableOpacity,
3257
+ {
3258
+ accessibilityHint: labels.useCredentialsHint,
3259
+ accessibilityLabel: labels.useCredentials,
3260
+ accessibilityRole: "button",
3261
+ style: [authStyles.secondaryButton, styles3.useButton],
3262
+ testID: withTestIdPrefix(AuthTestIds.demoCredentialsUseButton, testIdPrefix),
3263
+ onPress: onUse,
3264
+ children: /* @__PURE__ */ jsx(Text, { style: authStyles.secondaryButtonText, children: labels.useCredentials })
3265
+ }
3266
+ ) : null
3267
+ ] });
3268
+ }
3269
+
3270
+ // src/components/DemoCredentialsHintVariant.ts
3271
+ var DemoCredentialsHintVariant = /* @__PURE__ */ ((DemoCredentialsHintVariant2) => {
3272
+ DemoCredentialsHintVariant2["Panel"] = "panel";
3273
+ DemoCredentialsHintVariant2["Disclosure"] = "disclosure";
3274
+ return DemoCredentialsHintVariant2;
3275
+ })(DemoCredentialsHintVariant || {});
3184
3276
  var PANEL_BORDER_WIDTH = 1;
3277
+ var TRIGGER_MIN_HEIGHT = 32;
3185
3278
  var ACCENT_RAIL_WIDTH = 3;
3186
3279
  var TITLE_LETTER_SPACING = 0.8;
3187
3280
  var DESCRIPTION_LINE_HEIGHT_RATIO = 1.45;
@@ -3242,6 +3335,40 @@ function useDemoCredentialsStyles(theme) {
3242
3335
  flexShrink: 1,
3243
3336
  backgroundColor: colors.surface,
3244
3337
  color: colors.text
3338
+ },
3339
+ // ── Disclosure variant ──────────────────────────────────────────────
3340
+ // No panel fill, no border, no brand rail: the collapsed state is one
3341
+ // line of text and nothing else, so on a page a real customer uses it
3342
+ // reads as a footnote rather than as a second call to action.
3343
+ disclosure: {
3344
+ marginTop: spacing.md,
3345
+ alignSelf: "stretch"
3346
+ },
3347
+ disclosureTrigger: {
3348
+ alignSelf: "center",
3349
+ justifyContent: "center",
3350
+ minHeight: TRIGGER_MIN_HEIGHT,
3351
+ paddingHorizontal: spacing.xs
3352
+ },
3353
+ disclosureTriggerText: {
3354
+ fontSize: typography.caption,
3355
+ textDecorationLine: "underline",
3356
+ // `textSecondary`, NOT a dimmed `text`. This is the same token the rest
3357
+ // of the helper copy uses, so it inherits whatever AA contrast the
3358
+ // consuming app already guarantees. Discretion here is carried by the
3359
+ // caption size, the centred placement below the form, and the absence
3360
+ // of any fill or border — never by fading the text toward the
3361
+ // background, which is how "discreet" quietly becomes a contrast bug.
3362
+ color: colors.textSecondary
3363
+ },
3364
+ disclosureBody: {
3365
+ marginTop: spacing.sm,
3366
+ paddingTop: spacing.sm,
3367
+ borderTopWidth: PANEL_BORDER_WIDTH,
3368
+ borderTopColor: colors.border
3369
+ },
3370
+ useButton: {
3371
+ alignSelf: "stretch"
3245
3372
  }
3246
3373
  });
3247
3374
  }, [theme]);
@@ -3262,6 +3389,7 @@ function resolveDemoCredentials(credentials) {
3262
3389
  }
3263
3390
  function DemoCredentialsHint({
3264
3391
  credentials,
3392
+ variant = "disclosure" /* Disclosure */,
3265
3393
  theme: themeProp,
3266
3394
  labels: labelsProp,
3267
3395
  testIdPrefix,
@@ -3270,6 +3398,7 @@ function DemoCredentialsHint({
3270
3398
  const theme = useAuthTheme(themeProp);
3271
3399
  const authStyles = useAuthStyles(theme);
3272
3400
  const styles3 = useDemoCredentialsStyles(theme);
3401
+ const [expanded, setExpanded] = useState(false);
3273
3402
  const labels = useMemo(
3274
3403
  () => ({ ...DEFAULT_DEMO_CREDENTIALS_HINT_LABELS, ...labelsProp }),
3275
3404
  [labelsProp]
@@ -3280,53 +3409,57 @@ function DemoCredentialsHint({
3280
3409
  onUse(resolved);
3281
3410
  }
3282
3411
  }, [resolved, onUse]);
3412
+ const handleToggle = useCallback(() => {
3413
+ setExpanded((current) => !current);
3414
+ }, []);
3283
3415
  if (resolved === null) {
3284
3416
  return null;
3285
3417
  }
3418
+ const body = /* @__PURE__ */ jsx(
3419
+ DemoCredentialsBody,
3420
+ {
3421
+ authStyles,
3422
+ credentials: resolved,
3423
+ labels,
3424
+ styles: styles3,
3425
+ testIdPrefix,
3426
+ onUse: onUse === void 0 ? void 0 : handleUse
3427
+ }
3428
+ );
3429
+ if (variant === "panel" /* Panel */) {
3430
+ return /* @__PURE__ */ jsxs(
3431
+ View,
3432
+ {
3433
+ style: styles3.panel,
3434
+ testID: withTestIdPrefix(AuthTestIds.demoCredentialsHint, testIdPrefix),
3435
+ children: [
3436
+ /* @__PURE__ */ jsx(Text, { style: styles3.title, children: labels.title }),
3437
+ /* @__PURE__ */ jsx(Text, { style: styles3.description, children: labels.description }),
3438
+ body
3439
+ ]
3440
+ }
3441
+ );
3442
+ }
3286
3443
  return /* @__PURE__ */ jsxs(
3287
3444
  View,
3288
3445
  {
3289
- style: styles3.panel,
3446
+ style: styles3.disclosure,
3290
3447
  testID: withTestIdPrefix(AuthTestIds.demoCredentialsHint, testIdPrefix),
3291
3448
  children: [
3292
- /* @__PURE__ */ jsx(Text, { style: styles3.title, children: labels.title }),
3293
- /* @__PURE__ */ jsx(Text, { style: styles3.description, children: labels.description }),
3294
- /* @__PURE__ */ jsxs(View, { style: styles3.row, children: [
3295
- /* @__PURE__ */ jsx(Text, { style: styles3.rowLabel, children: labels.usernameLabel }),
3296
- /* @__PURE__ */ jsx(
3297
- Text,
3298
- {
3299
- selectable: true,
3300
- style: styles3.rowValue,
3301
- testID: withTestIdPrefix(AuthTestIds.demoCredentialsUsername, testIdPrefix),
3302
- children: resolved.username
3303
- }
3304
- )
3305
- ] }),
3306
- /* @__PURE__ */ jsxs(View, { style: styles3.row, children: [
3307
- /* @__PURE__ */ jsx(Text, { style: styles3.rowLabel, children: labels.passwordLabel }),
3308
- /* @__PURE__ */ jsx(
3309
- Text,
3310
- {
3311
- selectable: true,
3312
- style: styles3.rowValue,
3313
- testID: withTestIdPrefix(AuthTestIds.demoCredentialsPassword, testIdPrefix),
3314
- children: resolved.password
3315
- }
3316
- )
3317
- ] }),
3318
- onUse !== void 0 ? /* @__PURE__ */ jsx(
3449
+ /* @__PURE__ */ jsx(
3319
3450
  TouchableOpacity,
3320
3451
  {
3321
- accessibilityHint: labels.useCredentialsHint,
3322
- accessibilityLabel: labels.useCredentials,
3452
+ accessibilityHint: labels.toggleHint,
3453
+ accessibilityLabel: labels.toggle,
3323
3454
  accessibilityRole: "button",
3324
- style: authStyles.secondaryButton,
3325
- testID: withTestIdPrefix(AuthTestIds.demoCredentialsUseButton, testIdPrefix),
3326
- onPress: handleUse,
3327
- children: /* @__PURE__ */ jsx(Text, { style: authStyles.secondaryButtonText, children: labels.useCredentials })
3455
+ accessibilityState: { expanded },
3456
+ style: styles3.disclosureTrigger,
3457
+ testID: withTestIdPrefix(AuthTestIds.demoCredentialsToggle, testIdPrefix),
3458
+ onPress: handleToggle,
3459
+ children: /* @__PURE__ */ jsx(Text, { style: styles3.disclosureTriggerText, children: labels.toggle })
3328
3460
  }
3329
- ) : null
3461
+ ),
3462
+ expanded ? /* @__PURE__ */ jsx(View, { style: styles3.disclosureBody, children: body }) : null
3330
3463
  ]
3331
3464
  }
3332
3465
  );
@@ -3572,6 +3705,6 @@ async function performBffLogout(options) {
3572
3705
  runGuarded(onRedirect, onError);
3573
3706
  }
3574
3707
 
3575
- export { AuthScreen, AuthTestIds, AuthThemeProvider, BffAuthStatus, DEFAULT_AUTH_CARD_MAX_WIDTH, DEFAULT_DEMO_CREDENTIALS_HINT_LABELS, DEFAULT_DEVICE_PIN_ENROLL_LABELS, DEFAULT_DEVICE_PIN_SETTINGS_LABELS, DEFAULT_DEVICE_PIN_UNLOCK_LABELS, DEFAULT_FORGOT_PASSWORD_FIELDS_LABELS, DEFAULT_FORGOT_PASSWORD_LABELS, DEFAULT_LOGIN_LABELS, DEFAULT_OTP_LABELS, DEFAULT_PASSKEY_LOGIN_LABELS, DEFAULT_PASSKEY_SETTINGS_LABELS, DEFAULT_PIN_LABELS, DEFAULT_PREFERRED_METHOD_HINT_LABELS, DEFAULT_PREFERRED_METHOD_SETTINGS_LABELS, DEFAULT_RESET_PASSWORD_LABELS, DEVICE_PIN_ALLOWED_DIGITS, DEVICE_PIN_DEFAULT_DIGITS, DemoCredentialsHint, DevicePinEnrollErrorKey, DevicePinEnrollForm, DevicePinErrorKey, DevicePinInput, DevicePinLengthPicker, DevicePinOffer, DevicePinSettingsCard, DevicePinUnlockScreen, ForgotPasswordFields, ForgotPasswordForm, LoginForm, OtpForm, OtpLoginStep, PASSWORD_MAX_LENGTH, PASSWORD_MIN_LENGTH, PasskeyCeremonyMode, PasskeyCeremonyStatus, PasskeyLoginButton, PasskeySettingsCard, PasswordPolicyError, PinForm, PreferredMethodHint, PreferredMethodSettingsCard, PrefillIntent, ResetPasswordError, ResetPasswordForm, cachePreferredMethod, clearCachedPreferredMethod, collectUserRoles, createBffAuthClient, createPreferencesClient, defaultAuthTheme, isAllowedPinDigits, isPasswordValid, isValidForgotPasswordEmail, performBffLogout, readCachedPreferredMethod, readPasskeyError, readPasskeyRegistered, resolveAccessibleRoutes, resolveDemoCredentials, resolvePostLoginRoute, startPasskeyLogin, startPasskeyRegistration, syncPreferredMethodFromServer, useAuthTheme, useBffAuth, useBffForgotPassword, useBffLoginConfig, useBffResetPassword, useDemoCredentials, useDevicePinDisable, useDevicePinEnroll, useDevicePinUnlock, useForgotPasswordSubmit, useOtpLogin, usePasskeyCeremony, usePinLogin, usePreferredMethodSetting, useResetPasswordForm, validatePasswordPolicy, withTestIdPrefix };
3708
+ export { AuthScreen, AuthTestIds, AuthThemeProvider, BffAuthStatus, DEFAULT_AUTH_CARD_MAX_WIDTH, DEFAULT_DEMO_CREDENTIALS_HINT_LABELS, DEFAULT_DEVICE_PIN_ENROLL_LABELS, DEFAULT_DEVICE_PIN_SETTINGS_LABELS, DEFAULT_DEVICE_PIN_UNLOCK_LABELS, DEFAULT_FORGOT_PASSWORD_FIELDS_LABELS, DEFAULT_FORGOT_PASSWORD_LABELS, DEFAULT_LOGIN_LABELS, DEFAULT_OTP_LABELS, DEFAULT_PASSKEY_LOGIN_LABELS, DEFAULT_PASSKEY_SETTINGS_LABELS, DEFAULT_PIN_LABELS, DEFAULT_PREFERRED_METHOD_HINT_LABELS, DEFAULT_PREFERRED_METHOD_SETTINGS_LABELS, DEFAULT_RESET_PASSWORD_LABELS, DEVICE_PIN_ALLOWED_DIGITS, DEVICE_PIN_DEFAULT_DIGITS, DemoCredentialsHint, DemoCredentialsHintVariant, DevicePinEnrollErrorKey, DevicePinEnrollForm, DevicePinErrorKey, DevicePinInput, DevicePinLengthPicker, DevicePinOffer, DevicePinSettingsCard, DevicePinUnlockScreen, ForgotPasswordFields, ForgotPasswordForm, LoginForm, OtpForm, OtpLoginStep, PASSWORD_MAX_LENGTH, PASSWORD_MIN_LENGTH, PasskeyCeremonyMode, PasskeyCeremonyStatus, PasskeyLoginButton, PasskeySettingsCard, PasswordPolicyError, PinForm, PreferredMethodHint, PreferredMethodSettingsCard, PrefillIntent, ResetPasswordError, ResetPasswordForm, cachePreferredMethod, clearCachedPreferredMethod, collectUserRoles, createBffAuthClient, createPreferencesClient, defaultAuthTheme, isAllowedPinDigits, isPasswordValid, isValidForgotPasswordEmail, performBffLogout, readCachedPreferredMethod, readPasskeyError, readPasskeyRegistered, resolveAccessibleRoutes, resolveDemoCredentials, resolvePostLoginRoute, startPasskeyLogin, startPasskeyRegistration, syncPreferredMethodFromServer, useAuthTheme, useBffAuth, useBffForgotPassword, useBffLoginConfig, useBffResetPassword, useDemoCredentials, useDevicePinDisable, useDevicePinEnroll, useDevicePinUnlock, useForgotPasswordSubmit, useOtpLogin, usePasskeyCeremony, usePinLogin, usePreferredMethodSetting, useResetPasswordForm, validatePasswordPolicy, withTestIdPrefix };
3576
3709
  //# sourceMappingURL=index.mjs.map
3577
3710
  //# sourceMappingURL=index.mjs.map