feat: improve authentication and user management

- Fix token missing issue after email code registration/login
- Add last login time update for code-based login
- Support email login in addition to username login
- Fix password login for code-registered users (allow setting password)
- Fix referral code parameter passing from URL hash
- Add email column to user management table
- Improve profile page layout (align card heights, reorganize layout)
- Add i18n support for Register Bonus, Referral Bonus, Code Lock Minutes, Code Max Attempts
- Fix billing service add_credits to support reference_id parameter
- Update password handling documentation
This commit is contained in:
TIANHE
2026-01-14 20:42:10 +08:00
parent fa721c034c
commit 445e7ac290
33 changed files with 7715 additions and 234 deletions
+211 -1
View File
@@ -215,6 +215,100 @@ const locale = {
'user.login.privacy.view': 'View Privacy Policy',
'user.login.privacy.collapse': 'Hide Privacy Policy',
'user.login.privacy.content': 'We value your privacy and data protection. (1) Scope of collection: We only collect information necessary to provide the service (e.g., email, mobile number, country code, Web3 wallet address) and limited logs/device data. (2) Purpose of use: Account login and security verification, feature provisioning, troubleshooting, and compliance requirements. (3) Storage & security: Data is encrypted and access-controlled to prevent unauthorized access, disclosure, or loss. (4) Sharing & third parties: We do not share personal data with third parties except as required by law or to deliver the service; where third-party services are involved (e.g., wallets, SMS providers), processing is limited to the minimum scope required. (5) Cookies/local storage: Used for session and login state (e.g., tokens, PHPSESSID). You may clear or restrict them in your browser. (6) Your rights: You may exercise rights of access, correction, deletion, and consent withdrawal as permitted by law. (7) Changes & notices: We will provide prominent notice for updates. Continued use indicates that you have read and agreed to the updated terms. If you do not agree, please stop using the service and contact us.',
// Login page additions
'user.login.username': 'Username',
'user.login.usernameRequired': 'Please enter username',
'user.login.passwordRequired': 'Please enter password',
'user.login.tab': 'Login',
'user.login.submit': 'Login',
'user.login.register': 'Create Account',
'user.login.forgotPassword': 'Forgot Password?',
'user.login.orLoginWith': 'Or login with',
'user.login.methodPassword': 'Password',
'user.login.methodCode': 'Email Code',
'user.login.email': 'Email',
'user.login.emailRequired': 'Please enter email',
'user.login.emailInvalid': 'Invalid email format',
'user.login.verificationCode': 'Verification Code',
'user.login.codeRequired': 'Please enter verification code',
'user.login.sendCode': 'Send',
'user.login.codeSent': 'Verification code sent',
'user.login.codeLoginHint': 'New users will be auto-registered',
'user.login.welcomeNew': 'Welcome!',
'user.login.accountCreated': 'Your account has been created',
// OAuth
'user.oauth.processing': 'Processing login...',
'user.oauth.error.missing_params': 'Missing required parameters',
'user.oauth.error.invalid_state': 'Invalid state parameter',
'user.oauth.error.user_creation_failed': 'Failed to create user',
'user.oauth.error.server_error': 'Server error',
// Register page
'user.register.tab': 'Register',
'user.register.title': 'Create Account',
'user.register.email': 'Email',
'user.register.emailRequired': 'Please enter email',
'user.register.emailInvalid': 'Invalid email format',
'user.register.verificationCode': 'Verification Code',
'user.register.codeRequired': 'Please enter verification code',
'user.register.sendCode': 'Send Code',
'user.register.codeSent': 'Verification code sent',
'user.register.username': 'Username',
'user.register.usernameRequired': 'Please enter username',
'user.register.usernameLength': 'Username must be 3-30 characters',
'user.register.usernamePattern': 'Start with letter, letters/numbers/underscore only',
'user.register.password': 'Password',
'user.register.passwordRequired': 'Please enter password',
'user.register.confirmPassword': 'Confirm Password',
'user.register.confirmPasswordRequired': 'Please confirm password',
'user.register.passwordMismatch': 'Passwords do not match',
'user.register.submit': 'Create Account',
'user.register.haveAccount': 'Already have an account?',
'user.register.login': 'Login',
'user.register.success': 'Registration successful',
'user.register.pleaseLogin': 'Please login with your new account',
'user.register.pwdMinLength': 'At least 8 characters',
'user.register.pwdUppercase': 'At least one uppercase letter',
'user.register.pwdLowercase': 'At least one lowercase letter',
'user.register.pwdNumber': 'At least one number',
// Reset password page
'user.resetPassword.title': 'Reset Password',
'user.resetPassword.email': 'Email',
'user.resetPassword.emailRequired': 'Please enter email',
'user.resetPassword.emailInvalid': 'Invalid email format',
'user.resetPassword.verificationCode': 'Verification Code',
'user.resetPassword.codeRequired': 'Please enter verification code',
'user.resetPassword.sendCode': 'Send Code',
'user.resetPassword.codeSent': 'Verification code sent',
'user.resetPassword.next': 'Next',
'user.resetPassword.backToLogin': 'Back to Login',
'user.resetPassword.resettingFor': 'Resetting password for',
'user.resetPassword.newPassword': 'New Password',
'user.resetPassword.passwordRequired': 'Please enter new password',
'user.resetPassword.confirmPassword': 'Confirm New Password',
'user.resetPassword.confirmPasswordRequired': 'Please confirm password',
'user.resetPassword.submit': 'Reset Password',
'user.resetPassword.back': 'Back',
'user.resetPassword.successTitle': 'Password Reset Successful',
'user.resetPassword.successSubtitle': 'You can now login with your new password',
'user.resetPassword.goToLogin': 'Go to Login',
// Security
'user.security.retry': 'Retry',
// Profile - change password
'profile.passwordHintNew': 'For security, email verification is required to change password. Password must be at least 8 characters with uppercase, lowercase, and number.',
'profile.verificationCode': 'Verification Code',
'profile.codeRequired': 'Please enter verification code',
'profile.codePlaceholder': 'Enter verification code',
'profile.sendCode': 'Send Code',
'profile.codeSent': 'Verification code sent',
'profile.codeWillSendTo': 'Code will be sent to',
'profile.noEmailWarning': 'Please set your email first in Basic Info tab',
'account.basicInfo': 'Basic Information',
'account.id': 'User ID',
'account.username': 'Username',
@@ -2019,6 +2113,9 @@ const locale = {
'settings.link.supportedExchanges': 'Supported Exchanges',
'settings.link.applyApi': 'Apply API',
'settings.link.createSearchEngine': 'Create Search Engine',
'settings.link.getTurnstileKey': 'Get Turnstile Key',
'settings.link.getGoogleCredentials': 'Get Google Credentials',
'settings.link.getGithubCredentials': 'Get GitHub Credentials',
'settings.restartRequired': 'Settings saved. Some changes require Python service restart to take effect.',
'settings.copyRestartCmd': 'Copy restart command',
'settings.copySuccess': 'Copied',
@@ -2037,11 +2134,35 @@ const locale = {
'settings.group.agent': 'AI Agent',
'settings.group.network': 'Network & Proxy',
'settings.group.search': 'Web Search',
'settings.group.security': 'Registration & Security',
'settings.group.app': 'Application',
// Settings fields - Auth
'settings.field.SECRET_KEY': 'Secret Key',
'settings.field.ADMIN_USER': 'Admin Username',
'settings.field.ADMIN_PASSWORD': 'Admin Password',
'settings.field.ADMIN_EMAIL': 'Admin Email',
// Settings fields - Security
'settings.field.ENABLE_REGISTRATION': 'Enable Registration',
'settings.field.TURNSTILE_SITE_KEY': 'Turnstile Site Key',
'settings.field.TURNSTILE_SECRET_KEY': 'Turnstile Secret Key',
'settings.field.FRONTEND_URL': 'Frontend URL',
'settings.field.GOOGLE_CLIENT_ID': 'Google Client ID',
'settings.field.GOOGLE_CLIENT_SECRET': 'Google Client Secret',
'settings.field.GOOGLE_REDIRECT_URI': 'Google Redirect URI',
'settings.field.GITHUB_CLIENT_ID': 'GitHub Client ID',
'settings.field.GITHUB_CLIENT_SECRET': 'GitHub Client Secret',
'settings.field.GITHUB_REDIRECT_URI': 'GitHub Redirect URI',
'settings.field.SECURITY_IP_MAX_ATTEMPTS': 'IP Max Failed Attempts',
'settings.field.SECURITY_IP_WINDOW_MINUTES': 'IP Window (minutes)',
'settings.field.SECURITY_IP_BLOCK_MINUTES': 'IP Block Duration (minutes)',
'settings.field.SECURITY_ACCOUNT_MAX_ATTEMPTS': 'Account Max Failed Attempts',
'settings.field.SECURITY_ACCOUNT_WINDOW_MINUTES': 'Account Window (minutes)',
'settings.field.SECURITY_ACCOUNT_BLOCK_MINUTES': 'Account Block Duration (minutes)',
'settings.field.VERIFICATION_CODE_EXPIRE_MINUTES': 'Verification Code Expiry (minutes)',
'settings.field.VERIFICATION_CODE_RATE_LIMIT': 'Code Rate Limit (seconds)',
'settings.field.VERIFICATION_CODE_IP_HOURLY_LIMIT': 'Code Hourly Limit per IP',
'settings.field.VERIFICATION_CODE_MAX_ATTEMPTS': 'Code Max Attempts',
'settings.field.VERIFICATION_CODE_LOCK_MINUTES': 'Code Lock Minutes',
// Settings fields - Server
'settings.field.PYTHON_API_HOST': 'Listen Address',
'settings.field.PYTHON_API_PORT': 'Port',
@@ -2179,6 +2300,10 @@ const locale = {
'portfolio.monitors.channels': 'Channels',
'portfolio.monitors.runNow': 'Run Now',
'portfolio.monitors.analysisResult': 'AI Analysis Result',
'portfolio.monitors.runningTitle': 'AI Analysis Started',
'portfolio.monitors.runningDesc': 'Analysis is running in background. Results will be pushed via notification. Analyzing multiple positions may take a few minutes.',
'portfolio.monitors.timeoutTitle': 'Request Timeout',
'portfolio.monitors.timeoutDesc': 'Analysis may still be running in background. Please check notifications for results later. If no notification is received, please try again.',
'portfolio.modal.addPosition': 'Add Position',
'portfolio.modal.editPosition': 'Edit Position',
'portfolio.modal.addMonitor': 'Add Monitor',
@@ -2238,6 +2363,7 @@ const locale = {
'portfolio.message.monitorDisabled': 'Monitor paused',
'portfolio.message.monitorRunSuccess': 'Analysis completed',
'portfolio.message.monitorRunFailed': 'Analysis failed',
'portfolio.message.monitorRunning': 'AI analysis started, please wait for notification',
// Portfolio - Groups
'portfolio.groups.all': 'All Positions',
'portfolio.groups.ungrouped': 'Ungrouped',
@@ -2280,6 +2406,7 @@ const locale = {
'common.refresh': 'Refresh',
'userManage.title': 'User Management',
'userManage.searchPlaceholder': 'Search by username/email/nickname',
'userManage.description': 'Manage system users, roles and permissions',
'userManage.createUser': 'Create User',
'userManage.editUser': 'Edit User',
@@ -2325,6 +2452,7 @@ const locale = {
'profile.nicknamePlaceholder': 'Enter your nickname',
'profile.emailPlaceholder': 'Enter your email',
'profile.emailInvalid': 'Invalid email format',
'profile.emailCannotChange': 'Email cannot be changed after registration',
'profile.passwordHint': 'Password must be at least 6 characters',
'profile.oldPassword': 'Current Password',
'profile.newPassword': 'New Password',
@@ -2336,7 +2464,89 @@ const locale = {
'profile.confirmPasswordRequired': 'Please confirm password',
'profile.confirmPasswordPlaceholder': 'Confirm new password',
'profile.passwordMin': 'Password must be at least 6 characters',
'profile.passwordMismatch': 'Passwords do not match'
'profile.passwordMismatch': 'Passwords do not match',
// Profile - Credits
'profile.credits.title': 'My Credits',
'profile.credits.unit': 'Credits',
'profile.credits.recharge': 'Top Up',
'profile.credits.vipExpires': 'VIP expires on',
'profile.credits.vipExpired': 'VIP expired',
'profile.credits.noVip': 'Not a VIP',
'profile.credits.hint': 'AI analysis and other features consume credits. VIP users get free access.',
// Profile - Credits Log
'profile.creditsLog': 'Credits History',
'profile.creditsLog.time': 'Time',
'profile.creditsLog.action': 'Type',
'profile.creditsLog.amount': 'Change',
'profile.creditsLog.balance': 'Balance',
'profile.creditsLog.remark': 'Remark',
'profile.creditsLog.actionConsume': 'Consume',
'profile.creditsLog.actionRecharge': 'Recharge',
'profile.creditsLog.actionAdjust': 'Adjust',
'profile.creditsLog.actionRefund': 'Refund',
'profile.creditsLog.actionVipGrant': 'VIP Grant',
'profile.creditsLog.actionVipRevoke': 'VIP Revoke',
'profile.creditsLog.actionRegisterBonus': 'Register Bonus',
'profile.creditsLog.actionReferralBonus': 'Referral Bonus',
// Profile - Referral
'profile.referral.title': 'Invite Friends',
'profile.referral.listTab': 'Referrals',
'profile.referral.totalInvited': 'Invited',
'profile.referral.bonusPerInvite': 'Per Invite',
'profile.referral.yourLink': 'Your Referral Link',
'profile.referral.copyLink': 'Copy Link',
'profile.referral.linkCopied': 'Referral link copied',
'profile.referral.newUserBonus': 'New users get',
'profile.referral.user': 'User',
'profile.referral.registerTime': 'Registered',
'profile.referral.noReferrals': 'No referrals yet',
'profile.referral.shareNow': 'Share Now',
// User Manage - Credits & VIP
'userManage.credits': 'Credits',
'userManage.adjustCredits': 'Adjust Credits',
'userManage.setVip': 'Set VIP',
'userManage.currentCredits': 'Current Credits',
'userManage.newCredits': 'New Credits',
'userManage.enterCredits': 'Enter new credits amount',
'userManage.creditsNonNegative': 'Credits cannot be negative',
'userManage.currentVip': 'Current VIP Status',
'userManage.vipActive': 'Active',
'userManage.vipExpired': 'Expired',
'userManage.vipDays': 'VIP Days',
'userManage.vipExpiresAt': 'VIP Expires At',
'userManage.cancelVip': 'Cancel VIP',
'userManage.days': 'days',
'userManage.customDate': 'Custom Date',
'userManage.selectDate': 'Please select a date',
'userManage.remark': 'Remark',
'userManage.remarkPlaceholder': 'Optional remark',
// Settings - Billing
'settings.group.billing': 'Billing & Credits',
'settings.field.BILLING_ENABLED': 'Enable Billing',
'settings.field.BILLING_VIP_BYPASS': 'VIP Free Access',
'settings.field.BILLING_COST_AI_ANALYSIS': 'AI Analysis Cost',
'settings.field.BILLING_COST_STRATEGY_RUN': 'Strategy Run Cost',
'settings.field.BILLING_COST_BACKTEST': 'Backtest Cost',
'settings.field.BILLING_COST_PORTFOLIO_MONITOR': 'Portfolio Monitor Cost',
'settings.field.CREDITS_REGISTER_BONUS': 'Register Bonus',
'settings.field.CREDITS_REFERRAL_BONUS': 'Referral Bonus',
'settings.field.RECHARGE_TELEGRAM_URL': 'Recharge Telegram URL',
'settings.desc.BILLING_ENABLED': 'Enable billing system. Users need credits to use certain features when enabled',
'settings.desc.BILLING_VIP_BYPASS': 'VIP users can use all paid features for free during VIP period',
'settings.desc.BILLING_COST_AI_ANALYSIS': 'Credits consumed per AI analysis request',
'settings.desc.BILLING_COST_STRATEGY_RUN': 'Credits consumed when starting a strategy',
'settings.desc.BILLING_COST_BACKTEST': 'Credits consumed per backtest run',
'settings.desc.BILLING_COST_PORTFOLIO_MONITOR': 'Credits consumed per portfolio AI monitoring run',
'settings.desc.CREDITS_REGISTER_BONUS': 'Credits awarded to new users on registration',
'settings.desc.CREDITS_REFERRAL_BONUS': 'Credits awarded to referrer when someone signs up with their referral code',
'settings.desc.VERIFICATION_CODE_MAX_ATTEMPTS': 'Maximum attempts to verify a code before lockout',
'settings.desc.VERIFICATION_CODE_LOCK_MINUTES': 'Lockout duration after exceeding max attempts',
'settings.desc.RECHARGE_TELEGRAM_URL': 'Telegram customer service URL for recharge inquiries'
}
export default {