@dloizides/auth-web 1.14.0 → 1.17.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 +58 -0
- package/dist/index.d.mts +302 -5
- package/dist/index.d.ts +302 -5
- package/dist/index.js +477 -20
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +470 -22
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -308,6 +308,29 @@ var DEFAULT_RESET_PASSWORD_LABELS = {
|
|
|
308
308
|
errorNetwork: "Something went wrong. Please try again."
|
|
309
309
|
};
|
|
310
310
|
|
|
311
|
+
// src/components/labels/accountSettingsLabels.ts
|
|
312
|
+
var DEFAULT_ACCOUNT_SETTINGS_LABELS = {
|
|
313
|
+
heading: "Account settings",
|
|
314
|
+
changePasswordTitle: "Change password",
|
|
315
|
+
changePasswordDescription: "Update the password you use to sign in.",
|
|
316
|
+
currentPasswordLabel: "Current password",
|
|
317
|
+
currentPasswordPlaceholder: "Enter your current password",
|
|
318
|
+
newPasswordLabel: "New password",
|
|
319
|
+
newPasswordPlaceholder: "Enter a new password",
|
|
320
|
+
confirmPasswordLabel: "Confirm new password",
|
|
321
|
+
confirmPasswordPlaceholder: "Re-enter your new password",
|
|
322
|
+
submit: "Change password",
|
|
323
|
+
submitting: "Changing password...",
|
|
324
|
+
submitHint: "Submit the form to change your password",
|
|
325
|
+
success: "Your password has been changed.",
|
|
326
|
+
errorWeakNewPassword: "Your new password must be at least 8 characters and include an uppercase letter, a lowercase letter and a number.",
|
|
327
|
+
errorMismatch: "The new password and its confirmation do not match.",
|
|
328
|
+
errorCurrentRequired: "Enter your current password.",
|
|
329
|
+
errorInvalidCurrent: "Your current password is incorrect, or the new password does not meet the policy.",
|
|
330
|
+
errorUnauthorized: "Your session has expired. Sign in again to change your password.",
|
|
331
|
+
errorFailed: "Could not change your password. Try again later."
|
|
332
|
+
};
|
|
333
|
+
|
|
311
334
|
// src/components/testIds.ts
|
|
312
335
|
var AuthTestIds = {
|
|
313
336
|
loginForm: "auth-login-form",
|
|
@@ -381,8 +404,19 @@ var AuthTestIds = {
|
|
|
381
404
|
preferredMethodSettingsError: "auth-preferred-method-settings-error",
|
|
382
405
|
// Preferred-method login-screen hint
|
|
383
406
|
preferredMethodHint: "auth-preferred-method-hint",
|
|
407
|
+
// Account-settings screen shell + in-app change-password form
|
|
408
|
+
accountSettings: "auth-account-settings",
|
|
409
|
+
accountSettingsChangePassword: "auth-account-settings-change-password",
|
|
410
|
+
changePasswordCurrentInput: "auth-change-password-current",
|
|
411
|
+
changePasswordNewInput: "auth-change-password-new",
|
|
412
|
+
changePasswordConfirmInput: "auth-change-password-confirm",
|
|
413
|
+
changePasswordSubmit: "auth-change-password-submit",
|
|
414
|
+
changePasswordError: "auth-change-password-error",
|
|
415
|
+
changePasswordSuccess: "auth-change-password-success",
|
|
384
416
|
// Public-demo credentials panel
|
|
385
417
|
demoCredentialsHint: "auth-demo-credentials-hint",
|
|
418
|
+
// Per-account heading, present only when >1 account is published (multi-account).
|
|
419
|
+
demoCredentialsAccountLabel: "auth-demo-credentials-account-label",
|
|
386
420
|
demoCredentialsUsername: "auth-demo-credentials-username",
|
|
387
421
|
demoCredentialsPassword: "auth-demo-credentials-password",
|
|
388
422
|
demoCredentialsUseButton: "auth-demo-credentials-use",
|
|
@@ -3202,6 +3236,307 @@ function PreferredMethodSettingsCard({
|
|
|
3202
3236
|
}
|
|
3203
3237
|
);
|
|
3204
3238
|
}
|
|
3239
|
+
|
|
3240
|
+
// src/password/ChangePasswordErrorKey.ts
|
|
3241
|
+
var ChangePasswordErrorKey = /* @__PURE__ */ ((ChangePasswordErrorKey2) => {
|
|
3242
|
+
ChangePasswordErrorKey2["WeakNewPassword"] = "weak_new_password";
|
|
3243
|
+
ChangePasswordErrorKey2["Mismatch"] = "mismatch";
|
|
3244
|
+
ChangePasswordErrorKey2["CurrentRequired"] = "current_required";
|
|
3245
|
+
ChangePasswordErrorKey2["InvalidCurrent"] = "invalid_current";
|
|
3246
|
+
ChangePasswordErrorKey2["Unauthorized"] = "unauthorized";
|
|
3247
|
+
ChangePasswordErrorKey2["Failed"] = "failed";
|
|
3248
|
+
return ChangePasswordErrorKey2;
|
|
3249
|
+
})(ChangePasswordErrorKey || {});
|
|
3250
|
+
function errorKeyForStatus(status) {
|
|
3251
|
+
if (status === "invalidCurrent") {
|
|
3252
|
+
return "invalid_current" /* InvalidCurrent */;
|
|
3253
|
+
}
|
|
3254
|
+
if (status === "unauthorized") {
|
|
3255
|
+
return "unauthorized" /* Unauthorized */;
|
|
3256
|
+
}
|
|
3257
|
+
return "failed" /* Failed */;
|
|
3258
|
+
}
|
|
3259
|
+
function useChangePassword({
|
|
3260
|
+
client,
|
|
3261
|
+
onChanged
|
|
3262
|
+
}) {
|
|
3263
|
+
const [currentPassword, setCurrentValue] = react.useState("");
|
|
3264
|
+
const [newPassword, setNewValue] = react.useState("");
|
|
3265
|
+
const [confirmPassword, setConfirmValue] = react.useState("");
|
|
3266
|
+
const [submitting, setSubmitting] = react.useState(false);
|
|
3267
|
+
const [succeeded, setSucceeded] = react.useState(false);
|
|
3268
|
+
const [errorKey, setErrorKey] = react.useState(null);
|
|
3269
|
+
const clearStatus = react.useCallback(() => {
|
|
3270
|
+
setErrorKey(null);
|
|
3271
|
+
setSucceeded(false);
|
|
3272
|
+
}, []);
|
|
3273
|
+
const setCurrentPassword = react.useCallback((value) => {
|
|
3274
|
+
setCurrentValue(value);
|
|
3275
|
+
clearStatus();
|
|
3276
|
+
}, [clearStatus]);
|
|
3277
|
+
const setNewPassword = react.useCallback((value) => {
|
|
3278
|
+
setNewValue(value);
|
|
3279
|
+
clearStatus();
|
|
3280
|
+
}, [clearStatus]);
|
|
3281
|
+
const setConfirmPassword = react.useCallback((value) => {
|
|
3282
|
+
setConfirmValue(value);
|
|
3283
|
+
clearStatus();
|
|
3284
|
+
}, [clearStatus]);
|
|
3285
|
+
const reset = react.useCallback(() => {
|
|
3286
|
+
setCurrentValue("");
|
|
3287
|
+
setNewValue("");
|
|
3288
|
+
setConfirmValue("");
|
|
3289
|
+
setSubmitting(false);
|
|
3290
|
+
setSucceeded(false);
|
|
3291
|
+
setErrorKey(null);
|
|
3292
|
+
}, []);
|
|
3293
|
+
const submit = react.useCallback(() => {
|
|
3294
|
+
if (currentPassword === "") {
|
|
3295
|
+
setErrorKey("current_required" /* CurrentRequired */);
|
|
3296
|
+
return;
|
|
3297
|
+
}
|
|
3298
|
+
if (newPassword !== confirmPassword) {
|
|
3299
|
+
setErrorKey("mismatch" /* Mismatch */);
|
|
3300
|
+
return;
|
|
3301
|
+
}
|
|
3302
|
+
if (!isPasswordValid(newPassword)) {
|
|
3303
|
+
setErrorKey("weak_new_password" /* WeakNewPassword */);
|
|
3304
|
+
return;
|
|
3305
|
+
}
|
|
3306
|
+
setErrorKey(null);
|
|
3307
|
+
setSucceeded(false);
|
|
3308
|
+
setSubmitting(true);
|
|
3309
|
+
client.changePassword({ currentPassword, newPassword }).then((result) => {
|
|
3310
|
+
if (result.status === "success") {
|
|
3311
|
+
setCurrentValue("");
|
|
3312
|
+
setNewValue("");
|
|
3313
|
+
setConfirmValue("");
|
|
3314
|
+
setSucceeded(true);
|
|
3315
|
+
onChanged?.();
|
|
3316
|
+
return;
|
|
3317
|
+
}
|
|
3318
|
+
setErrorKey(errorKeyForStatus(result.status));
|
|
3319
|
+
}).catch(() => {
|
|
3320
|
+
setErrorKey("failed" /* Failed */);
|
|
3321
|
+
}).finally(() => {
|
|
3322
|
+
setSubmitting(false);
|
|
3323
|
+
});
|
|
3324
|
+
}, [client, currentPassword, newPassword, confirmPassword, onChanged]);
|
|
3325
|
+
return {
|
|
3326
|
+
currentPassword,
|
|
3327
|
+
newPassword,
|
|
3328
|
+
confirmPassword,
|
|
3329
|
+
setCurrentPassword,
|
|
3330
|
+
setNewPassword,
|
|
3331
|
+
setConfirmPassword,
|
|
3332
|
+
submitting,
|
|
3333
|
+
succeeded,
|
|
3334
|
+
errorKey,
|
|
3335
|
+
submit,
|
|
3336
|
+
reset
|
|
3337
|
+
};
|
|
3338
|
+
}
|
|
3339
|
+
function errorMessage2(errorKey, labels) {
|
|
3340
|
+
switch (errorKey) {
|
|
3341
|
+
case "weak_new_password" /* WeakNewPassword */:
|
|
3342
|
+
return labels.errorWeakNewPassword;
|
|
3343
|
+
case "mismatch" /* Mismatch */:
|
|
3344
|
+
return labels.errorMismatch;
|
|
3345
|
+
case "current_required" /* CurrentRequired */:
|
|
3346
|
+
return labels.errorCurrentRequired;
|
|
3347
|
+
case "invalid_current" /* InvalidCurrent */:
|
|
3348
|
+
return labels.errorInvalidCurrent;
|
|
3349
|
+
case "unauthorized" /* Unauthorized */:
|
|
3350
|
+
return labels.errorUnauthorized;
|
|
3351
|
+
case "failed" /* Failed */:
|
|
3352
|
+
return labels.errorFailed;
|
|
3353
|
+
default:
|
|
3354
|
+
return null;
|
|
3355
|
+
}
|
|
3356
|
+
}
|
|
3357
|
+
function ChangePasswordCard({
|
|
3358
|
+
client,
|
|
3359
|
+
theme: themeProp,
|
|
3360
|
+
labels: labelsProp,
|
|
3361
|
+
testIdPrefix,
|
|
3362
|
+
onChanged
|
|
3363
|
+
}) {
|
|
3364
|
+
const theme = useAuthTheme(themeProp);
|
|
3365
|
+
const styles3 = useAuthStyles(theme);
|
|
3366
|
+
const labels = react.useMemo(
|
|
3367
|
+
() => ({ ...DEFAULT_ACCOUNT_SETTINGS_LABELS, ...labelsProp }),
|
|
3368
|
+
[labelsProp]
|
|
3369
|
+
);
|
|
3370
|
+
const form = useChangePassword({ client, onChanged });
|
|
3371
|
+
const message = errorMessage2(form.errorKey, labels);
|
|
3372
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3373
|
+
reactNative.View,
|
|
3374
|
+
{
|
|
3375
|
+
style: styles3.card,
|
|
3376
|
+
testID: withTestIdPrefix(AuthTestIds.accountSettingsChangePassword, testIdPrefix),
|
|
3377
|
+
children: [
|
|
3378
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.title, children: labels.changePasswordTitle }),
|
|
3379
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.subtitle, children: labels.changePasswordDescription }),
|
|
3380
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles3.fieldGroup, children: [
|
|
3381
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.label, children: labels.currentPasswordLabel }),
|
|
3382
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3383
|
+
reactNative.TextInput,
|
|
3384
|
+
{
|
|
3385
|
+
accessibilityLabel: labels.currentPasswordLabel,
|
|
3386
|
+
autoComplete: "current-password",
|
|
3387
|
+
placeholder: labels.currentPasswordPlaceholder,
|
|
3388
|
+
placeholderTextColor: theme.colors.textSecondary,
|
|
3389
|
+
secureTextEntry: true,
|
|
3390
|
+
style: styles3.input,
|
|
3391
|
+
testID: withTestIdPrefix(AuthTestIds.changePasswordCurrentInput, testIdPrefix),
|
|
3392
|
+
value: form.currentPassword,
|
|
3393
|
+
onChangeText: form.setCurrentPassword
|
|
3394
|
+
}
|
|
3395
|
+
)
|
|
3396
|
+
] }),
|
|
3397
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles3.fieldGroup, children: [
|
|
3398
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.label, children: labels.newPasswordLabel }),
|
|
3399
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3400
|
+
reactNative.TextInput,
|
|
3401
|
+
{
|
|
3402
|
+
accessibilityLabel: labels.newPasswordLabel,
|
|
3403
|
+
autoComplete: "new-password",
|
|
3404
|
+
placeholder: labels.newPasswordPlaceholder,
|
|
3405
|
+
placeholderTextColor: theme.colors.textSecondary,
|
|
3406
|
+
secureTextEntry: true,
|
|
3407
|
+
style: styles3.input,
|
|
3408
|
+
testID: withTestIdPrefix(AuthTestIds.changePasswordNewInput, testIdPrefix),
|
|
3409
|
+
value: form.newPassword,
|
|
3410
|
+
onChangeText: form.setNewPassword
|
|
3411
|
+
}
|
|
3412
|
+
)
|
|
3413
|
+
] }),
|
|
3414
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles3.fieldGroup, children: [
|
|
3415
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.label, children: labels.confirmPasswordLabel }),
|
|
3416
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3417
|
+
reactNative.TextInput,
|
|
3418
|
+
{
|
|
3419
|
+
accessibilityLabel: labels.confirmPasswordLabel,
|
|
3420
|
+
autoComplete: "new-password",
|
|
3421
|
+
placeholder: labels.confirmPasswordPlaceholder,
|
|
3422
|
+
placeholderTextColor: theme.colors.textSecondary,
|
|
3423
|
+
secureTextEntry: true,
|
|
3424
|
+
style: styles3.input,
|
|
3425
|
+
testID: withTestIdPrefix(AuthTestIds.changePasswordConfirmInput, testIdPrefix),
|
|
3426
|
+
value: form.confirmPassword,
|
|
3427
|
+
onChangeText: form.setConfirmPassword
|
|
3428
|
+
}
|
|
3429
|
+
)
|
|
3430
|
+
] }),
|
|
3431
|
+
message !== null ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3432
|
+
reactNative.Text,
|
|
3433
|
+
{
|
|
3434
|
+
style: styles3.errorText,
|
|
3435
|
+
testID: withTestIdPrefix(AuthTestIds.changePasswordError, testIdPrefix),
|
|
3436
|
+
children: message
|
|
3437
|
+
}
|
|
3438
|
+
) : null,
|
|
3439
|
+
form.succeeded ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3440
|
+
reactNative.Text,
|
|
3441
|
+
{
|
|
3442
|
+
style: styles3.successText,
|
|
3443
|
+
testID: withTestIdPrefix(AuthTestIds.changePasswordSuccess, testIdPrefix),
|
|
3444
|
+
children: labels.success
|
|
3445
|
+
}
|
|
3446
|
+
) : null,
|
|
3447
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3448
|
+
reactNative.TouchableOpacity,
|
|
3449
|
+
{
|
|
3450
|
+
accessibilityHint: labels.submitHint,
|
|
3451
|
+
accessibilityLabel: form.submitting ? labels.submitting : labels.submit,
|
|
3452
|
+
accessibilityRole: "button",
|
|
3453
|
+
disabled: form.submitting,
|
|
3454
|
+
style: form.submitting ? [styles3.primaryButton, styles3.primaryButtonDisabled] : styles3.primaryButton,
|
|
3455
|
+
testID: withTestIdPrefix(AuthTestIds.changePasswordSubmit, testIdPrefix),
|
|
3456
|
+
onPress: form.submit,
|
|
3457
|
+
children: form.submitting ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.ActivityIndicator, { color: theme.colors.onPrimary, size: "small" }) : /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.primaryButtonText, children: labels.submit })
|
|
3458
|
+
}
|
|
3459
|
+
)
|
|
3460
|
+
]
|
|
3461
|
+
}
|
|
3462
|
+
);
|
|
3463
|
+
}
|
|
3464
|
+
var GAP = 16;
|
|
3465
|
+
var layout = reactNative.StyleSheet.create({
|
|
3466
|
+
content: {
|
|
3467
|
+
width: "100%",
|
|
3468
|
+
alignItems: "center",
|
|
3469
|
+
rowGap: GAP
|
|
3470
|
+
}
|
|
3471
|
+
});
|
|
3472
|
+
function AccountSettingsScreen({
|
|
3473
|
+
changePassword,
|
|
3474
|
+
devicePin,
|
|
3475
|
+
passkeys,
|
|
3476
|
+
preferredMethod,
|
|
3477
|
+
theme: themeProp,
|
|
3478
|
+
labels: labelsProp,
|
|
3479
|
+
testIdPrefix
|
|
3480
|
+
}) {
|
|
3481
|
+
const theme = useAuthTheme(themeProp);
|
|
3482
|
+
const styles3 = useAuthStyles(theme);
|
|
3483
|
+
const labels = react.useMemo(
|
|
3484
|
+
() => ({ ...DEFAULT_ACCOUNT_SETTINGS_LABELS, ...labelsProp }),
|
|
3485
|
+
[labelsProp]
|
|
3486
|
+
);
|
|
3487
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3488
|
+
reactNative.ScrollView,
|
|
3489
|
+
{
|
|
3490
|
+
contentContainerStyle: styles3.screen,
|
|
3491
|
+
testID: withTestIdPrefix(AuthTestIds.accountSettings, testIdPrefix),
|
|
3492
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: layout.content, children: [
|
|
3493
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.title, children: labels.heading }),
|
|
3494
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3495
|
+
ChangePasswordCard,
|
|
3496
|
+
{
|
|
3497
|
+
client: changePassword.client,
|
|
3498
|
+
labels: labelsProp,
|
|
3499
|
+
testIdPrefix,
|
|
3500
|
+
theme,
|
|
3501
|
+
onChanged: changePassword.onChanged
|
|
3502
|
+
}
|
|
3503
|
+
),
|
|
3504
|
+
devicePin !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3505
|
+
DevicePinSettingsCard,
|
|
3506
|
+
{
|
|
3507
|
+
client: devicePin.client,
|
|
3508
|
+
enrollLabels: devicePin.enrollLabels,
|
|
3509
|
+
initialHasPin: devicePin.initialHasPin,
|
|
3510
|
+
labels: devicePin.labels,
|
|
3511
|
+
testIdPrefix,
|
|
3512
|
+
theme,
|
|
3513
|
+
onChanged: devicePin.onChanged
|
|
3514
|
+
}
|
|
3515
|
+
) : null,
|
|
3516
|
+
passkeys !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3517
|
+
PasskeySettingsCard,
|
|
3518
|
+
{
|
|
3519
|
+
labels: passkeys.labels,
|
|
3520
|
+
returnUrl: passkeys.returnUrl,
|
|
3521
|
+
testIdPrefix,
|
|
3522
|
+
theme
|
|
3523
|
+
}
|
|
3524
|
+
) : null,
|
|
3525
|
+
preferredMethod !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3526
|
+
PreferredMethodSettingsCard,
|
|
3527
|
+
{
|
|
3528
|
+
availableMethods: preferredMethod.availableMethods,
|
|
3529
|
+
client: preferredMethod.client,
|
|
3530
|
+
labels: preferredMethod.labels,
|
|
3531
|
+
testIdPrefix,
|
|
3532
|
+
theme,
|
|
3533
|
+
onChanged: preferredMethod.onChanged
|
|
3534
|
+
}
|
|
3535
|
+
) : null
|
|
3536
|
+
] })
|
|
3537
|
+
}
|
|
3538
|
+
);
|
|
3539
|
+
}
|
|
3205
3540
|
function hintFor(method, labels) {
|
|
3206
3541
|
if (method === "password") {
|
|
3207
3542
|
return labels.password;
|
|
@@ -3238,9 +3573,21 @@ function DemoCredentialsBody({
|
|
|
3238
3573
|
styles: styles3,
|
|
3239
3574
|
authStyles,
|
|
3240
3575
|
testIdPrefix,
|
|
3576
|
+
accountLabel,
|
|
3577
|
+
testIdIndex,
|
|
3241
3578
|
onUse
|
|
3242
3579
|
}) {
|
|
3580
|
+
const testId = (base) => withTestIdPrefix(testIdIndex === void 0 ? base : `${base}-${testIdIndex}`, testIdPrefix);
|
|
3581
|
+
const hasLabel = typeof accountLabel === "string" && accountLabel.length > 0;
|
|
3243
3582
|
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { children: [
|
|
3583
|
+
hasLabel ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3584
|
+
reactNative.Text,
|
|
3585
|
+
{
|
|
3586
|
+
style: styles3.accountLabel,
|
|
3587
|
+
testID: testId(AuthTestIds.demoCredentialsAccountLabel),
|
|
3588
|
+
children: accountLabel
|
|
3589
|
+
}
|
|
3590
|
+
) : null,
|
|
3244
3591
|
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles3.row, children: [
|
|
3245
3592
|
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.rowLabel, children: labels.usernameLabel }),
|
|
3246
3593
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -3248,7 +3595,7 @@ function DemoCredentialsBody({
|
|
|
3248
3595
|
{
|
|
3249
3596
|
selectable: true,
|
|
3250
3597
|
style: styles3.rowValue,
|
|
3251
|
-
testID:
|
|
3598
|
+
testID: testId(AuthTestIds.demoCredentialsUsername),
|
|
3252
3599
|
children: credentials.username
|
|
3253
3600
|
}
|
|
3254
3601
|
)
|
|
@@ -3260,7 +3607,7 @@ function DemoCredentialsBody({
|
|
|
3260
3607
|
{
|
|
3261
3608
|
selectable: true,
|
|
3262
3609
|
style: styles3.rowValue,
|
|
3263
|
-
testID:
|
|
3610
|
+
testID: testId(AuthTestIds.demoCredentialsPassword),
|
|
3264
3611
|
children: credentials.password
|
|
3265
3612
|
}
|
|
3266
3613
|
)
|
|
@@ -3272,7 +3619,7 @@ function DemoCredentialsBody({
|
|
|
3272
3619
|
accessibilityLabel: labels.useCredentials,
|
|
3273
3620
|
accessibilityRole: "button",
|
|
3274
3621
|
style: [authStyles.secondaryButton, styles3.useButton],
|
|
3275
|
-
testID:
|
|
3622
|
+
testID: testId(AuthTestIds.demoCredentialsUseButton),
|
|
3276
3623
|
onPress: onUse,
|
|
3277
3624
|
children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: authStyles.secondaryButtonText, children: labels.useCredentials })
|
|
3278
3625
|
}
|
|
@@ -3325,6 +3672,15 @@ function useDemoCredentialsStyles(theme) {
|
|
|
3325
3672
|
marginBottom: spacing.sm,
|
|
3326
3673
|
color: colors.textSecondary
|
|
3327
3674
|
},
|
|
3675
|
+
accountLabel: {
|
|
3676
|
+
fontSize: typography.caption,
|
|
3677
|
+
fontWeight: "700",
|
|
3678
|
+
color: colors.text,
|
|
3679
|
+
// Separates one account block from the previous one; the first block sits
|
|
3680
|
+
// under the panel description / disclosure divider, which already spaces it.
|
|
3681
|
+
marginTop: spacing.sm,
|
|
3682
|
+
marginBottom: spacing.xs / HALF
|
|
3683
|
+
},
|
|
3328
3684
|
row: {
|
|
3329
3685
|
flexDirection: "row",
|
|
3330
3686
|
alignItems: "center",
|
|
@@ -3400,8 +3756,39 @@ function resolveDemoCredentials(credentials) {
|
|
|
3400
3756
|
}
|
|
3401
3757
|
return { username, password };
|
|
3402
3758
|
}
|
|
3759
|
+
|
|
3760
|
+
// src/demo/resolveDemoAccounts.ts
|
|
3761
|
+
function resolveAccount(account) {
|
|
3762
|
+
if (account === void 0 || account === null) {
|
|
3763
|
+
return null;
|
|
3764
|
+
}
|
|
3765
|
+
const pair = resolveDemoCredentials(account);
|
|
3766
|
+
if (pair === null) {
|
|
3767
|
+
return null;
|
|
3768
|
+
}
|
|
3769
|
+
const label = typeof account.label === "string" ? account.label : "";
|
|
3770
|
+
return { label, username: pair.username, password: pair.password };
|
|
3771
|
+
}
|
|
3772
|
+
function resolveAccountList(accounts) {
|
|
3773
|
+
if (!Array.isArray(accounts)) {
|
|
3774
|
+
return [];
|
|
3775
|
+
}
|
|
3776
|
+
return accounts.map(resolveAccount).filter((account) => account !== null);
|
|
3777
|
+
}
|
|
3778
|
+
function resolveDemoAccounts(credentials) {
|
|
3779
|
+
if (credentials === void 0 || credentials === null) {
|
|
3780
|
+
return [];
|
|
3781
|
+
}
|
|
3782
|
+
const fromList = resolveAccountList(credentials.publishedAccounts);
|
|
3783
|
+
if (fromList.length > 0) {
|
|
3784
|
+
return fromList;
|
|
3785
|
+
}
|
|
3786
|
+
const single = resolveDemoCredentials(credentials);
|
|
3787
|
+
return single === null ? [] : [{ label: "", username: single.username, password: single.password }];
|
|
3788
|
+
}
|
|
3403
3789
|
function DemoCredentialsHint({
|
|
3404
3790
|
credentials,
|
|
3791
|
+
accounts,
|
|
3405
3792
|
variant = "disclosure" /* Disclosure */,
|
|
3406
3793
|
theme: themeProp,
|
|
3407
3794
|
labels: labelsProp,
|
|
@@ -3416,29 +3803,35 @@ function DemoCredentialsHint({
|
|
|
3416
3803
|
() => ({ ...DEFAULT_DEMO_CREDENTIALS_HINT_LABELS, ...labelsProp }),
|
|
3417
3804
|
[labelsProp]
|
|
3418
3805
|
);
|
|
3419
|
-
const
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3806
|
+
const resolvedAccounts = react.useMemo(
|
|
3807
|
+
() => accounts !== void 0 && accounts.length > 0 ? resolveAccountList(accounts) : resolveDemoAccounts(credentials),
|
|
3808
|
+
[accounts, credentials]
|
|
3809
|
+
);
|
|
3810
|
+
const makeUse = react.useCallback(
|
|
3811
|
+
(account) => onUse === void 0 ? void 0 : () => onUse({ username: account.username, password: account.password }),
|
|
3812
|
+
[onUse]
|
|
3813
|
+
);
|
|
3425
3814
|
const handleToggle = react.useCallback(() => {
|
|
3426
3815
|
setExpanded((current) => !current);
|
|
3427
3816
|
}, []);
|
|
3428
|
-
if (
|
|
3817
|
+
if (resolvedAccounts.length === 0) {
|
|
3429
3818
|
return null;
|
|
3430
3819
|
}
|
|
3431
|
-
const
|
|
3820
|
+
const isSingle = resolvedAccounts.length === 1;
|
|
3821
|
+
const body = resolvedAccounts.map((account, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
3432
3822
|
DemoCredentialsBody,
|
|
3433
3823
|
{
|
|
3824
|
+
accountLabel: isSingle ? void 0 : account.label,
|
|
3434
3825
|
authStyles,
|
|
3435
|
-
credentials:
|
|
3826
|
+
credentials: { username: account.username, password: account.password },
|
|
3436
3827
|
labels,
|
|
3437
3828
|
styles: styles3,
|
|
3829
|
+
testIdIndex: isSingle ? void 0 : index,
|
|
3438
3830
|
testIdPrefix,
|
|
3439
|
-
onUse:
|
|
3440
|
-
}
|
|
3441
|
-
|
|
3831
|
+
onUse: makeUse(account)
|
|
3832
|
+
},
|
|
3833
|
+
`${account.username}-${String(index)}`
|
|
3834
|
+
));
|
|
3442
3835
|
if (variant === "panel" /* Panel */) {
|
|
3443
3836
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3444
3837
|
reactNative.View,
|
|
@@ -3594,7 +3987,11 @@ function useDemoCredentials({
|
|
|
3594
3987
|
credentials,
|
|
3595
3988
|
prefillOnMount = false
|
|
3596
3989
|
} = {}) {
|
|
3597
|
-
const
|
|
3990
|
+
const accounts = react.useMemo(() => resolveDemoAccounts(credentials), [credentials]);
|
|
3991
|
+
const resolved = react.useMemo(() => {
|
|
3992
|
+
const first = accounts[0];
|
|
3993
|
+
return first === void 0 ? null : { username: first.username, password: first.password };
|
|
3994
|
+
}, [accounts]);
|
|
3598
3995
|
const [filled, setFilled] = react.useState(
|
|
3599
3996
|
prefillOnMount ? resolved : null
|
|
3600
3997
|
);
|
|
@@ -3626,11 +4023,12 @@ function useDemoCredentials({
|
|
|
3626
4023
|
prefillIntent
|
|
3627
4024
|
},
|
|
3628
4025
|
// `credentials` is passed through unresolved on purpose: the hint applies
|
|
3629
|
-
// `
|
|
3630
|
-
// standalone, without this hook.
|
|
3631
|
-
|
|
4026
|
+
// `resolveDemoAccounts` itself, so it fails closed even when it is used
|
|
4027
|
+
// standalone, without this hook. `accounts` is the already-resolved list the
|
|
4028
|
+
// hint prefers — one labelled row per entry.
|
|
4029
|
+
hintProps: { credentials, accounts, onUse: handleUse }
|
|
3632
4030
|
}),
|
|
3633
|
-
[filled, prefillNonce, prefillIntent, credentials, handleUse]
|
|
4031
|
+
[filled, prefillNonce, prefillIntent, credentials, accounts, handleUse]
|
|
3634
4032
|
);
|
|
3635
4033
|
}
|
|
3636
4034
|
async function lazyFetchHttpClient(request) {
|
|
@@ -3718,6 +4116,56 @@ async function performBffLogout(options) {
|
|
|
3718
4116
|
}
|
|
3719
4117
|
runGuarded(onRedirect, onError);
|
|
3720
4118
|
}
|
|
4119
|
+
var CHANGE_PASSWORD_ENDPOINT = "/bff/account/change-password";
|
|
4120
|
+
var CSRF_HEADER2 = "X-BFF-Csrf";
|
|
4121
|
+
var CSRF_HEADER_VALUE2 = "1";
|
|
4122
|
+
var JSON_CONTENT_TYPE2 = "application/json";
|
|
4123
|
+
var HTTP_NO_CONTENT = 204;
|
|
4124
|
+
var HTTP_OK = 200;
|
|
4125
|
+
var HTTP_BAD_REQUEST2 = 400;
|
|
4126
|
+
var HTTP_UNAUTHORIZED = 401;
|
|
4127
|
+
async function lazyFetchHttpClient2(request) {
|
|
4128
|
+
const fetchImpl = typeof fetch === "function" ? fetch.bind(globalThis) : void 0;
|
|
4129
|
+
if (fetchImpl === void 0) {
|
|
4130
|
+
throw new Error("createBffChangePasswordClient: fetch is not available in this environment");
|
|
4131
|
+
}
|
|
4132
|
+
return authClient.createFetchHttpClient(fetchImpl)(request);
|
|
4133
|
+
}
|
|
4134
|
+
function resultFromStatus(status) {
|
|
4135
|
+
if (status === HTTP_NO_CONTENT || status === HTTP_OK) {
|
|
4136
|
+
return { status: "success" };
|
|
4137
|
+
}
|
|
4138
|
+
if (status === HTTP_BAD_REQUEST2) {
|
|
4139
|
+
return { status: "invalidCurrent" };
|
|
4140
|
+
}
|
|
4141
|
+
if (status === HTTP_UNAUTHORIZED) {
|
|
4142
|
+
return { status: "unauthorized" };
|
|
4143
|
+
}
|
|
4144
|
+
return { status: "error" };
|
|
4145
|
+
}
|
|
4146
|
+
function createBffChangePasswordClient(options = {}) {
|
|
4147
|
+
const http = options.http ?? lazyFetchHttpClient2;
|
|
4148
|
+
const baseUrl = options.baseUrl ?? "";
|
|
4149
|
+
const url = `${baseUrl}${CHANGE_PASSWORD_ENDPOINT}`;
|
|
4150
|
+
return {
|
|
4151
|
+
changePassword: async (request) => {
|
|
4152
|
+
try {
|
|
4153
|
+
const response = await http({
|
|
4154
|
+
url,
|
|
4155
|
+
method: "POST",
|
|
4156
|
+
headers: { "Content-Type": JSON_CONTENT_TYPE2, [CSRF_HEADER2]: CSRF_HEADER_VALUE2 },
|
|
4157
|
+
body: JSON.stringify({
|
|
4158
|
+
currentPassword: request.currentPassword,
|
|
4159
|
+
newPassword: request.newPassword
|
|
4160
|
+
})
|
|
4161
|
+
});
|
|
4162
|
+
return resultFromStatus(response.status);
|
|
4163
|
+
} catch {
|
|
4164
|
+
return { status: "error" };
|
|
4165
|
+
}
|
|
4166
|
+
}
|
|
4167
|
+
};
|
|
4168
|
+
}
|
|
3721
4169
|
|
|
3722
4170
|
Object.defineProperty(exports, "BffAuthClient", {
|
|
3723
4171
|
enumerable: true,
|
|
@@ -3727,10 +4175,15 @@ Object.defineProperty(exports, "createFetchHttpClient", {
|
|
|
3727
4175
|
enumerable: true,
|
|
3728
4176
|
get: function () { return authClient.createFetchHttpClient; }
|
|
3729
4177
|
});
|
|
4178
|
+
exports.AccountSettingsScreen = AccountSettingsScreen;
|
|
3730
4179
|
exports.AuthScreen = AuthScreen;
|
|
3731
4180
|
exports.AuthTestIds = AuthTestIds;
|
|
3732
4181
|
exports.AuthThemeProvider = AuthThemeProvider;
|
|
3733
4182
|
exports.BffAuthStatus = BffAuthStatus;
|
|
4183
|
+
exports.CHANGE_PASSWORD_ENDPOINT = CHANGE_PASSWORD_ENDPOINT;
|
|
4184
|
+
exports.ChangePasswordCard = ChangePasswordCard;
|
|
4185
|
+
exports.ChangePasswordErrorKey = ChangePasswordErrorKey;
|
|
4186
|
+
exports.DEFAULT_ACCOUNT_SETTINGS_LABELS = DEFAULT_ACCOUNT_SETTINGS_LABELS;
|
|
3734
4187
|
exports.DEFAULT_AUTH_CARD_MAX_WIDTH = DEFAULT_AUTH_CARD_MAX_WIDTH;
|
|
3735
4188
|
exports.DEFAULT_DEMO_CREDENTIALS_HINT_LABELS = DEFAULT_DEMO_CREDENTIALS_HINT_LABELS;
|
|
3736
4189
|
exports.DEFAULT_DEVICE_PIN_ENROLL_LABELS = DEFAULT_DEVICE_PIN_ENROLL_LABELS;
|
|
@@ -3780,6 +4233,7 @@ exports.cachePreferredMethod = cachePreferredMethod;
|
|
|
3780
4233
|
exports.clearCachedPreferredMethod = clearCachedPreferredMethod;
|
|
3781
4234
|
exports.collectUserRoles = collectUserRoles;
|
|
3782
4235
|
exports.createBffAuthClient = createBffAuthClient;
|
|
4236
|
+
exports.createBffChangePasswordClient = createBffChangePasswordClient;
|
|
3783
4237
|
exports.createPreferencesClient = createPreferencesClient;
|
|
3784
4238
|
exports.defaultAuthTheme = defaultAuthTheme;
|
|
3785
4239
|
exports.isAllowedPinDigits = isAllowedPinDigits;
|
|
@@ -3790,6 +4244,8 @@ exports.readCachedPreferredMethod = readCachedPreferredMethod;
|
|
|
3790
4244
|
exports.readPasskeyError = readPasskeyError;
|
|
3791
4245
|
exports.readPasskeyRegistered = readPasskeyRegistered;
|
|
3792
4246
|
exports.resolveAccessibleRoutes = resolveAccessibleRoutes;
|
|
4247
|
+
exports.resolveAccountList = resolveAccountList;
|
|
4248
|
+
exports.resolveDemoAccounts = resolveDemoAccounts;
|
|
3793
4249
|
exports.resolveDemoCredentials = resolveDemoCredentials;
|
|
3794
4250
|
exports.resolvePostLoginRoute = resolvePostLoginRoute;
|
|
3795
4251
|
exports.startPasskeyLogin = startPasskeyLogin;
|
|
@@ -3800,6 +4256,7 @@ exports.useBffAuth = useBffAuth;
|
|
|
3800
4256
|
exports.useBffForgotPassword = useBffForgotPassword;
|
|
3801
4257
|
exports.useBffLoginConfig = useBffLoginConfig;
|
|
3802
4258
|
exports.useBffResetPassword = useBffResetPassword;
|
|
4259
|
+
exports.useChangePassword = useChangePassword;
|
|
3803
4260
|
exports.useDemoCredentials = useDemoCredentials;
|
|
3804
4261
|
exports.useDevicePinDisable = useDevicePinDisable;
|
|
3805
4262
|
exports.useDevicePinEnroll = useDevicePinEnroll;
|