Ports the panel/security partial: change-credentials form and 2FA
toggle. The 2FA modal is a new shared component since enabling 2FA,
disabling 2FA, and changing credentials all funnel through it with
slightly different copy.
- TwoFactorModal.vue: 'set' flow renders a QR code + manual key + a
6-digit verifier; 'confirm' flow renders just the verifier. The
parent passes a confirm(success) callback that fires only when the
entered code matches the live TOTP value (otpauth lib).
- SecurityTab.vue: holds the local user form (oldUsername/oldPassword/
new*), POSTs /panel/setting/updateUser, and on success force-redirects
to logout. When 2FA is on, the credentials change goes through the
confirm-modal first.
- toggleTwoFactor leaves the switch read-only (the v-bound :checked
matches AllSetting) and only flips after the modal succeeds, so
cancelling out leaves state unchanged.
- Adds otpauth ^9.5.1 dep (qrious was already present).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>