@dloizides/auth-web 1.10.0 → 1.11.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
@@ -1,4 +1,4 @@
1
- import { StyleSheet, View, Text, TextInput, TouchableOpacity, ActivityIndicator, Pressable } from 'react-native';
1
+ import { StyleSheet, Platform, View, Text, TextInput, TouchableOpacity, ActivityIndicator, Pressable } from 'react-native';
2
2
  import { createContext, useContext, useMemo, useState, useRef, useEffect, useCallback } from 'react';
3
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
4
  import { useMutation } from '@tanstack/react-query';
@@ -261,6 +261,14 @@ var DEFAULT_PREFERRED_METHOD_HINT_LABELS = {
261
261
  pin: "You usually sign in with your quick PIN on this account.",
262
262
  passkey: "You usually sign in with a passkey."
263
263
  };
264
+ var DEFAULT_DEMO_CREDENTIALS_HINT_LABELS = {
265
+ title: "Demo access",
266
+ description: "Explore the full product with our shared demo account.",
267
+ usernameLabel: "Username",
268
+ passwordLabel: "Password",
269
+ useCredentials: "Use these credentials",
270
+ useCredentialsHint: "Fill the sign-in form with the demo username and password"
271
+ };
264
272
  var DEFAULT_RESET_PASSWORD_LABELS = {
265
273
  title: "Reset password",
266
274
  description: "Choose a new password for your account.",
@@ -349,7 +357,12 @@ var AuthTestIds = {
349
357
  preferredMethodSettingsOption: "auth-preferred-method-settings-option",
350
358
  preferredMethodSettingsError: "auth-preferred-method-settings-error",
351
359
  // Preferred-method login-screen hint
352
- preferredMethodHint: "auth-preferred-method-hint"
360
+ preferredMethodHint: "auth-preferred-method-hint",
361
+ // Public-demo credentials panel
362
+ demoCredentialsHint: "auth-demo-credentials-hint",
363
+ demoCredentialsUsername: "auth-demo-credentials-username",
364
+ demoCredentialsPassword: "auth-demo-credentials-password",
365
+ demoCredentialsUseButton: "auth-demo-credentials-use"
353
366
  };
354
367
  function withTestIdPrefix(baseId, prefix) {
355
368
  return prefix === void 0 || prefix === "" ? baseId : `${prefix}-${baseId}`;
@@ -480,6 +493,21 @@ function useAuthStyles(theme) {
480
493
  });
481
494
  }, [theme]);
482
495
  }
496
+ function useLoginPrefill({
497
+ initialUsername,
498
+ initialPassword,
499
+ prefillNonce
500
+ }) {
501
+ const [username, setUsername] = useState(initialUsername ?? "");
502
+ const [password, setPassword] = useState(initialPassword ?? "");
503
+ const [appliedNonce, setAppliedNonce] = useState(prefillNonce);
504
+ if (prefillNonce !== appliedNonce) {
505
+ setAppliedNonce(prefillNonce);
506
+ setUsername(initialUsername ?? "");
507
+ setPassword(initialPassword ?? "");
508
+ }
509
+ return { username, password, setUsername, setPassword };
510
+ }
483
511
  var BffAuthStatus = /* @__PURE__ */ ((BffAuthStatus2) => {
484
512
  BffAuthStatus2["Loading"] = "loading";
485
513
  BffAuthStatus2["Authenticated"] = "authenticated";
@@ -591,7 +619,10 @@ function LoginForm({
591
619
  onForgotPassword,
592
620
  onSignUp,
593
621
  testIdPrefix,
594
- chromeless = false
622
+ chromeless = false,
623
+ initialUsername,
624
+ initialPassword,
625
+ prefillNonce
595
626
  }) {
596
627
  const theme = useAuthTheme(themeProp);
597
628
  const styles3 = useAuthStyles(theme);
@@ -600,8 +631,11 @@ function LoginForm({
600
631
  [labelsProp]
601
632
  );
602
633
  const { login, isSubmitting } = useBffAuth({ client, probeOnMount: false });
603
- const [username, setUsername] = useState("");
604
- const [password, setPassword] = useState("");
634
+ const { username, password, setUsername, setPassword } = useLoginPrefill({
635
+ initialUsername,
636
+ initialPassword,
637
+ prefillNonce
638
+ });
605
639
  const [errorText, setErrorText] = useState(null);
606
640
  const runLogin = useCallback(async () => {
607
641
  setErrorText(null);
@@ -3131,6 +3165,156 @@ function PreferredMethodHint({
3131
3165
  }
3132
3166
  return /* @__PURE__ */ jsx(View, { testID: withTestIdPrefix(AuthTestIds.preferredMethodHint, testIdPrefix), children: /* @__PURE__ */ jsx(Text, { style: styles3.helperText, children: text }) });
3133
3167
  }
3168
+ var PANEL_BORDER_WIDTH = 1;
3169
+ var ACCENT_RAIL_WIDTH = 3;
3170
+ var TITLE_LETTER_SPACING = 0.8;
3171
+ var DESCRIPTION_LINE_HEIGHT_RATIO = 1.45;
3172
+ var HALF = 2;
3173
+ var MONOSPACE_FONT = Platform.select({
3174
+ ios: "Menlo",
3175
+ android: "monospace",
3176
+ default: "monospace"
3177
+ });
3178
+ function useDemoCredentialsStyles(theme) {
3179
+ return useMemo(() => {
3180
+ const { colors, radii, spacing, typography } = theme;
3181
+ return StyleSheet.create({
3182
+ panel: {
3183
+ borderWidth: PANEL_BORDER_WIDTH,
3184
+ borderLeftWidth: ACCENT_RAIL_WIDTH,
3185
+ borderRadius: radii.card,
3186
+ borderColor: colors.border,
3187
+ borderLeftColor: colors.primary,
3188
+ padding: spacing.md,
3189
+ marginBottom: spacing.md,
3190
+ backgroundColor: colors.background
3191
+ },
3192
+ title: {
3193
+ fontSize: typography.caption,
3194
+ fontWeight: "700",
3195
+ letterSpacing: TITLE_LETTER_SPACING,
3196
+ textTransform: "uppercase",
3197
+ color: colors.primary
3198
+ },
3199
+ description: {
3200
+ fontSize: typography.caption,
3201
+ lineHeight: typography.caption * DESCRIPTION_LINE_HEIGHT_RATIO,
3202
+ marginTop: spacing.xs / HALF,
3203
+ marginBottom: spacing.sm,
3204
+ color: colors.textSecondary
3205
+ },
3206
+ row: {
3207
+ flexDirection: "row",
3208
+ alignItems: "center",
3209
+ justifyContent: "space-between",
3210
+ marginTop: spacing.xs / HALF
3211
+ },
3212
+ rowLabel: {
3213
+ fontSize: typography.caption,
3214
+ color: colors.textSecondary
3215
+ },
3216
+ rowValue: {
3217
+ fontFamily: MONOSPACE_FONT,
3218
+ fontSize: typography.caption,
3219
+ fontWeight: "600",
3220
+ borderWidth: PANEL_BORDER_WIDTH,
3221
+ borderRadius: radii.input,
3222
+ borderColor: colors.border,
3223
+ paddingVertical: spacing.xs / HALF,
3224
+ paddingHorizontal: spacing.xs,
3225
+ // Never let a long password squeeze the label off the row.
3226
+ flexShrink: 1,
3227
+ backgroundColor: colors.surface,
3228
+ color: colors.text
3229
+ }
3230
+ });
3231
+ }, [theme]);
3232
+ }
3233
+
3234
+ // src/demo/resolveDemoCredentials.ts
3235
+ function resolveDemoCredentials(credentials) {
3236
+ if (credentials === void 0 || credentials === null) {
3237
+ return null;
3238
+ }
3239
+ const username = typeof credentials.username === "string" ? credentials.username.trim() : "";
3240
+ const password = typeof credentials.password === "string" ? credentials.password : "";
3241
+ const isUnusable = username.length === 0 || password.length === 0;
3242
+ if (isUnusable) {
3243
+ return null;
3244
+ }
3245
+ return { username, password };
3246
+ }
3247
+ function DemoCredentialsHint({
3248
+ credentials,
3249
+ theme: themeProp,
3250
+ labels: labelsProp,
3251
+ testIdPrefix,
3252
+ onUse
3253
+ }) {
3254
+ const theme = useAuthTheme(themeProp);
3255
+ const authStyles = useAuthStyles(theme);
3256
+ const styles3 = useDemoCredentialsStyles(theme);
3257
+ const labels = useMemo(
3258
+ () => ({ ...DEFAULT_DEMO_CREDENTIALS_HINT_LABELS, ...labelsProp }),
3259
+ [labelsProp]
3260
+ );
3261
+ const resolved = useMemo(() => resolveDemoCredentials(credentials), [credentials]);
3262
+ const handleUse = useCallback(() => {
3263
+ if (resolved !== null && onUse !== void 0) {
3264
+ onUse(resolved);
3265
+ }
3266
+ }, [resolved, onUse]);
3267
+ if (resolved === null) {
3268
+ return null;
3269
+ }
3270
+ return /* @__PURE__ */ jsxs(
3271
+ View,
3272
+ {
3273
+ style: styles3.panel,
3274
+ testID: withTestIdPrefix(AuthTestIds.demoCredentialsHint, testIdPrefix),
3275
+ children: [
3276
+ /* @__PURE__ */ jsx(Text, { style: styles3.title, children: labels.title }),
3277
+ /* @__PURE__ */ jsx(Text, { style: styles3.description, children: labels.description }),
3278
+ /* @__PURE__ */ jsxs(View, { style: styles3.row, children: [
3279
+ /* @__PURE__ */ jsx(Text, { style: styles3.rowLabel, children: labels.usernameLabel }),
3280
+ /* @__PURE__ */ jsx(
3281
+ Text,
3282
+ {
3283
+ selectable: true,
3284
+ style: styles3.rowValue,
3285
+ testID: withTestIdPrefix(AuthTestIds.demoCredentialsUsername, testIdPrefix),
3286
+ children: resolved.username
3287
+ }
3288
+ )
3289
+ ] }),
3290
+ /* @__PURE__ */ jsxs(View, { style: styles3.row, children: [
3291
+ /* @__PURE__ */ jsx(Text, { style: styles3.rowLabel, children: labels.passwordLabel }),
3292
+ /* @__PURE__ */ jsx(
3293
+ Text,
3294
+ {
3295
+ selectable: true,
3296
+ style: styles3.rowValue,
3297
+ testID: withTestIdPrefix(AuthTestIds.demoCredentialsPassword, testIdPrefix),
3298
+ children: resolved.password
3299
+ }
3300
+ )
3301
+ ] }),
3302
+ onUse !== void 0 ? /* @__PURE__ */ jsx(
3303
+ TouchableOpacity,
3304
+ {
3305
+ accessibilityHint: labels.useCredentialsHint,
3306
+ accessibilityLabel: labels.useCredentials,
3307
+ accessibilityRole: "button",
3308
+ style: authStyles.secondaryButton,
3309
+ testID: withTestIdPrefix(AuthTestIds.demoCredentialsUseButton, testIdPrefix),
3310
+ onPress: handleUse,
3311
+ children: /* @__PURE__ */ jsx(Text, { style: authStyles.secondaryButtonText, children: labels.useCredentials })
3312
+ }
3313
+ ) : null
3314
+ ]
3315
+ }
3316
+ );
3317
+ }
3134
3318
  var EMPTY_CONFIG = {
3135
3319
  methods: [],
3136
3320
  registrationEnabled: false,
@@ -3236,6 +3420,34 @@ async function syncPreferredMethodFromServer(client) {
3236
3420
  return null;
3237
3421
  }
3238
3422
  }
3423
+ function useDemoCredentials({
3424
+ credentials,
3425
+ prefillOnMount = false
3426
+ } = {}) {
3427
+ const resolved = useMemo(() => resolveDemoCredentials(credentials), [credentials]);
3428
+ const [filled, setFilled] = useState(
3429
+ prefillOnMount ? resolved : null
3430
+ );
3431
+ const [prefillNonce, setPrefillNonce] = useState(0);
3432
+ const handleUse = useCallback((next) => {
3433
+ setFilled(next);
3434
+ setPrefillNonce((current) => current + 1);
3435
+ }, []);
3436
+ return useMemo(
3437
+ () => ({
3438
+ loginFormProps: {
3439
+ initialUsername: filled?.username,
3440
+ initialPassword: filled?.password,
3441
+ prefillNonce
3442
+ },
3443
+ // `credentials` is passed through unresolved on purpose: the hint applies
3444
+ // `resolveDemoCredentials` itself, so it fails closed even when it is used
3445
+ // standalone, without this hook.
3446
+ hintProps: { credentials, onUse: handleUse }
3447
+ }),
3448
+ [filled, prefillNonce, credentials, handleUse]
3449
+ );
3450
+ }
3239
3451
  async function lazyFetchHttpClient(request) {
3240
3452
  const fetchImpl = typeof fetch === "function" ? fetch.bind(globalThis) : void 0;
3241
3453
  if (fetchImpl === void 0) {
@@ -3322,6 +3534,6 @@ async function performBffLogout(options) {
3322
3534
  runGuarded(onRedirect, onError);
3323
3535
  }
3324
3536
 
3325
- export { AuthScreen, AuthTestIds, AuthThemeProvider, BffAuthStatus, DEFAULT_AUTH_CARD_MAX_WIDTH, 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, 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, ResetPasswordError, ResetPasswordForm, cachePreferredMethod, clearCachedPreferredMethod, collectUserRoles, createBffAuthClient, createPreferencesClient, defaultAuthTheme, isAllowedPinDigits, isPasswordValid, isValidForgotPasswordEmail, performBffLogout, readCachedPreferredMethod, readPasskeyError, readPasskeyRegistered, resolveAccessibleRoutes, resolvePostLoginRoute, startPasskeyLogin, startPasskeyRegistration, syncPreferredMethodFromServer, useAuthTheme, useBffAuth, useBffForgotPassword, useBffLoginConfig, useBffResetPassword, useDevicePinDisable, useDevicePinEnroll, useDevicePinUnlock, useForgotPasswordSubmit, useOtpLogin, usePasskeyCeremony, usePinLogin, usePreferredMethodSetting, useResetPasswordForm, validatePasswordPolicy, withTestIdPrefix };
3537
+ 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, 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 };
3326
3538
  //# sourceMappingURL=index.mjs.map
3327
3539
  //# sourceMappingURL=index.mjs.map