@dloizides/auth-web 1.9.1 → 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/CHANGELOG.md +109 -0
- package/README.md +78 -0
- package/dist/index.d.mts +263 -2
- package/dist/index.d.ts +263 -2
- package/dist/index.js +258 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +255 -6
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
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
|
|
604
|
-
|
|
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) {
|
|
@@ -3285,6 +3497,43 @@ function resolveAccessibleRoutes(user, table) {
|
|
|
3285
3497
|
return table.routes.filter((entry) => userRoles.has(entry.role));
|
|
3286
3498
|
}
|
|
3287
3499
|
|
|
3288
|
-
|
|
3500
|
+
// src/session/performBffLogout.ts
|
|
3501
|
+
function toError4(caught) {
|
|
3502
|
+
return caught instanceof Error ? caught : new Error(String(caught));
|
|
3503
|
+
}
|
|
3504
|
+
function runGuarded(callback, onError) {
|
|
3505
|
+
if (callback === void 0) {
|
|
3506
|
+
return;
|
|
3507
|
+
}
|
|
3508
|
+
try {
|
|
3509
|
+
callback();
|
|
3510
|
+
} catch (caught) {
|
|
3511
|
+
onError?.(toError4(caught));
|
|
3512
|
+
}
|
|
3513
|
+
}
|
|
3514
|
+
function assignLocation(url) {
|
|
3515
|
+
if (typeof window === "undefined") {
|
|
3516
|
+
return;
|
|
3517
|
+
}
|
|
3518
|
+
window.location.assign(url);
|
|
3519
|
+
}
|
|
3520
|
+
async function performBffLogout(options) {
|
|
3521
|
+
const { client, onClearSession, onRedirect, onError, navigateToIdp = assignLocation } = options;
|
|
3522
|
+
runGuarded(onClearSession, onError);
|
|
3523
|
+
let idpLogoutUrl = null;
|
|
3524
|
+
try {
|
|
3525
|
+
idpLogoutUrl = await client.logout({ redirect: false });
|
|
3526
|
+
} catch (caught) {
|
|
3527
|
+
onError?.(toError4(caught));
|
|
3528
|
+
}
|
|
3529
|
+
if (idpLogoutUrl !== null) {
|
|
3530
|
+
const url = idpLogoutUrl;
|
|
3531
|
+
runGuarded(() => navigateToIdp(url), onError);
|
|
3532
|
+
return;
|
|
3533
|
+
}
|
|
3534
|
+
runGuarded(onRedirect, onError);
|
|
3535
|
+
}
|
|
3536
|
+
|
|
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 };
|
|
3289
3538
|
//# sourceMappingURL=index.mjs.map
|
|
3290
3539
|
//# sourceMappingURL=index.mjs.map
|