Fix business tenant binding and update password on cross-site signup.
Resolve the active business from the host domain so multi-business staff no longer load another tenant’s CMS data, and replace the Meshkee password when linking an existing account to a new site. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor
parent
193c63bfd2
commit
89269dff04
@@ -336,12 +336,16 @@ const en = {
|
||||
'signup.error.length': 'Password must be at least 8 characters.',
|
||||
'signup.error.create': 'Unable to create account.',
|
||||
'signup.error.cellExists':
|
||||
'This mobile number already has an account in Meshkee Unified Management System (__MESHKEE_APP__) on {sites}. Your password and data will stay the same. Continue to verify by SMS and join this website too.',
|
||||
'This mobile number already has an account in Meshkee Unified Management System (__MESHKEE_APP__) on {sites}. Your profile stays the same; the password you enter here will replace your Meshkee password. Continue to verify by SMS and join this website too.',
|
||||
'signup.error.cellExistsGeneric':
|
||||
'This mobile number already has an account in Meshkee Unified Management System (__MESHKEE_APP__) on another website. Your password and data will stay the same. Continue to verify by SMS and join this website too.',
|
||||
'This mobile number already has an account in Meshkee Unified Management System (__MESHKEE_APP__) on another website. Your profile stays the same; the password you enter here will replace your Meshkee password. Continue to verify by SMS and join this website too.',
|
||||
'signup.info.verify': 'Account created. Enter the SMS code to verify your number and sign in.',
|
||||
'signup.info.verifyExisting':
|
||||
'Enter the SMS code to join this website. Your Meshkee password and profile stay the same.',
|
||||
'signup.info.verifyExistingPasswordUpdated':
|
||||
'Enter the SMS code to finish joining. Your Meshkee password was updated to the one you just entered.',
|
||||
'signup.toast.passwordUpdated':
|
||||
'Your Meshkee password was updated to the one you entered on this website.',
|
||||
'signup.cellExists.title': 'Existing Meshkee account',
|
||||
'signup.cellExists.admit': 'I understand, continue',
|
||||
|
||||
@@ -729,12 +733,16 @@ const fa: Record<MessageKey, string> = {
|
||||
'signup.error.length': 'رمز عبور باید حداقل ۸ کاراکتر باشد.',
|
||||
'signup.error.create': 'ایجاد حساب ممکن نشد.',
|
||||
'signup.error.cellExists':
|
||||
'این شماره موبایل قبلاً در سیستم مدیریت یکپارچه ی مشکی (__MESHKEE_APP__) حساب دارد ({sites}). رمز عبور و اطلاعات شما همان خواهد بود. با ادامه، تأیید پیامکی را انجام دهید تا وارد این وبسایت هم شوید.',
|
||||
'این شماره موبایل قبلاً در سیستم مدیریت یکپارچه ی مشکی (__MESHKEE_APP__) حساب دارد ({sites}). اطلاعات شما همان میماند؛ رمزی که اینجا وارد کردید جایگزین رمز مشکی میشود. با ادامه، تأیید پیامکی را انجام دهید تا وارد این وبسایت هم شوید.',
|
||||
'signup.error.cellExistsGeneric':
|
||||
'این شماره موبایل قبلاً در سیستم مدیریت یکپارچه ی مشکی (__MESHKEE_APP__) (وبسایت دیگری) حساب دارد. رمز عبور و اطلاعات شما همان خواهد بود. با ادامه، تأیید پیامکی را انجام دهید تا وارد این وبسایت هم شوید.',
|
||||
'این شماره موبایل قبلاً در سیستم مدیریت یکپارچه ی مشکی (__MESHKEE_APP__) (وبسایت دیگری) حساب دارد. اطلاعات شما همان میماند؛ رمزی که اینجا وارد کردید جایگزین رمز مشکی میشود. با ادامه، تأیید پیامکی را انجام دهید تا وارد این وبسایت هم شوید.',
|
||||
'signup.info.verify': 'حساب ایجاد شد. کد پیامکی را وارد کنید تا شماره تأیید شود و وارد شوید.',
|
||||
'signup.info.verifyExisting':
|
||||
'کد پیامکی را وارد کنید تا به این وبسایت بپیوندید. رمز عبور و اطلاعات مشکی شما همان میماند.',
|
||||
'signup.info.verifyExistingPasswordUpdated':
|
||||
'کد پیامکی را وارد کنید تا عضویت تمام شود. رمز مشکی شما به رمزی که همین الان وارد کردید بهروز شد.',
|
||||
'signup.toast.passwordUpdated':
|
||||
'رمز مشکی شما به رمزی که در این وبسایت وارد کردید بهروز شد.',
|
||||
'signup.cellExists.title': 'حساب موجود در مشکی',
|
||||
'signup.cellExists.admit': 'متوجه شدم، ادامه',
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
resetPassword,
|
||||
sendOtp,
|
||||
} from '../services/authService'
|
||||
import { LanguageSelect, PasswordStrengthMeter, isPasswordStrong, useLocale } from '@meshkee/dashboard-ui'
|
||||
import { LanguageSelect, PasswordStrengthMeter, isPasswordStrong, useLocale, useToast } from '@meshkee/dashboard-ui'
|
||||
import { useT } from '../i18n/useT'
|
||||
import { safeRedirectPath } from '../lib/redirect'
|
||||
import { BackgroundOrbs } from '../components/BackgroundOrbs'
|
||||
@@ -66,6 +66,7 @@ export function LoginPage() {
|
||||
const { businessName, businessNameEn, logoUrl } = useTenantBranding()
|
||||
const tenantDomain = getTenantDomain()
|
||||
const t = useT()
|
||||
const { showToast } = useToast()
|
||||
const { locale, dir } = useLocale()
|
||||
|
||||
const [view, setView] = useState<AuthView>('login')
|
||||
@@ -207,7 +208,7 @@ export function LoginPage() {
|
||||
}
|
||||
}
|
||||
|
||||
async function runSignup() {
|
||||
async function runSignup(acknowledgeExistingAccount = false) {
|
||||
const cellNumber = resolveCellNumber()
|
||||
if (!cellNumber) return
|
||||
|
||||
@@ -220,10 +221,15 @@ export function LoginPage() {
|
||||
firstName: firstName.trim(),
|
||||
lastName: lastName.trim(),
|
||||
domain: tenantDomain,
|
||||
...(acknowledgeExistingAccount ? { acknowledgeExistingAccount: true } : {}),
|
||||
})
|
||||
|
||||
setCellExistsSites(null)
|
||||
|
||||
if (data.passwordUpdated) {
|
||||
showToast(t('signup.toast.passwordUpdated'), 'info')
|
||||
}
|
||||
|
||||
if (data.user.customerBusinesses.length === 0) {
|
||||
logoutRequest()
|
||||
setError(CUSTOMER_ACCESS_MESSAGE)
|
||||
@@ -232,14 +238,19 @@ export function LoginPage() {
|
||||
|
||||
if (!data.user.cellVerifiedAt) {
|
||||
logoutRequest()
|
||||
await continueToSmsVerify(cellNumber)
|
||||
await continueToSmsVerify(
|
||||
cellNumber,
|
||||
data.passwordUpdated
|
||||
? t('signup.info.verifyExistingPasswordUpdated')
|
||||
: t('signup.info.verify'),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
await login(cellNumber, password)
|
||||
navigate(redirectTo)
|
||||
} catch (err) {
|
||||
if (err instanceof ApiError) {
|
||||
if (!acknowledgeExistingAccount && err instanceof ApiError) {
|
||||
const sites = parseCellExistsSites(err.message)
|
||||
if (sites !== null) {
|
||||
setCellExistsSites(sites)
|
||||
@@ -253,13 +264,13 @@ export function LoginPage() {
|
||||
}
|
||||
}
|
||||
|
||||
async function continueToSmsVerify(cellNumber: string) {
|
||||
async function continueToSmsVerify(cellNumber: string, infoMessage?: string) {
|
||||
setView('otp')
|
||||
setSmsStep('phone')
|
||||
setPassword('')
|
||||
setConfirmPassword('')
|
||||
setSmsCode('')
|
||||
setInfo(t('signup.info.verify'))
|
||||
setInfo(infoMessage ?? t('signup.info.verify'))
|
||||
try {
|
||||
const otpResult = await sendOtp(cellNumber, tenantDomain)
|
||||
if (!otpResult.enabled) {
|
||||
@@ -292,9 +303,8 @@ export function LoginPage() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Existing Meshkee account on another site: user admits the notice, then proves
|
||||
* phone ownership via SMS. login-otp links them to this website (password/data unchanged),
|
||||
* so they appear in the business Customers list after verification.
|
||||
* Existing Meshkee account on another site: user admits the notice, then we link
|
||||
* them with the new password and prove phone ownership via SMS.
|
||||
*/
|
||||
async function handleAdmitCellExists() {
|
||||
clearMessages()
|
||||
@@ -304,27 +314,7 @@ export function LoginPage() {
|
||||
return
|
||||
}
|
||||
|
||||
setIsSubmitting(true)
|
||||
setCellExistsSites(null)
|
||||
try {
|
||||
setInfo(t('signup.info.verifyExisting'))
|
||||
setView('otp')
|
||||
setSmsStep('phone')
|
||||
setPassword('')
|
||||
setConfirmPassword('')
|
||||
setSmsCode('')
|
||||
const otpResult = await sendOtp(cellNumber, tenantDomain)
|
||||
if (!otpResult.enabled) {
|
||||
setInfo(otpResult.message)
|
||||
}
|
||||
setCodeSent(true)
|
||||
setSmsStep('code')
|
||||
startCountdown()
|
||||
} catch (otpErr) {
|
||||
handleApiError(otpErr, t('login.error.sendCode'))
|
||||
} finally {
|
||||
setIsSubmitting(false)
|
||||
}
|
||||
await runSignup(true)
|
||||
}
|
||||
|
||||
async function handleResetPassword(e: React.FormEvent) {
|
||||
|
||||
Reference in New Issue
Block a user