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