Fix magic OTP on dev, fix portal login flash of login form

- loginOTP.cfm/sendOTP.cfm: Use magic OTP code (123456) on dev instead of random
- portal/login.html: Hide login card until auth check completes to prevent flash of login form when redirecting to business selection

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
John Mizerek 2026-01-31 14:19:36 -08:00
parent c5a332b04e
commit 498ebb6c0e
3 changed files with 29 additions and 7 deletions

View file

@ -76,8 +76,12 @@ try {
}, { datasource: "payfrit" }); }, { datasource: "payfrit" });
} }
// Generate and save OTP // Generate OTP (use magic code on dev for easy testing)
otp = generateOTP(); otp = generateOTP();
if (structKeyExists(application, "MAGIC_OTP_ENABLED") && application.MAGIC_OTP_ENABLED
&& structKeyExists(application, "MAGIC_OTP_CODE") && len(application.MAGIC_OTP_CODE)) {
otp = application.MAGIC_OTP_CODE;
}
queryExecute(" queryExecute("
UPDATE Users UPDATE Users
SET MobileVerifyCode = :otp SET MobileVerifyCode = :otp

View file

@ -81,6 +81,10 @@ try {
", { phone: { value: phone, cfsqltype: "cf_sql_varchar" } }, { datasource: "payfrit" }); ", { phone: { value: phone, cfsqltype: "cf_sql_varchar" } }, { datasource: "payfrit" });
otp = generateOTP(); otp = generateOTP();
if (structKeyExists(application, "MAGIC_OTP_ENABLED") && application.MAGIC_OTP_ENABLED
&& structKeyExists(application, "MAGIC_OTP_CODE") && len(application.MAGIC_OTP_CODE)) {
otp = application.MAGIC_OTP_CODE;
}
userUUID = ""; userUUID = "";
if (qIncomplete.recordCount > 0) { if (qIncomplete.recordCount > 0) {

View file

@ -167,6 +167,14 @@
border-color: var(--primary); border-color: var(--primary);
} }
.login-card {
visibility: hidden;
}
.login-card.ready {
visibility: visible;
}
.step { .step {
display: none; display: none;
} }
@ -186,7 +194,7 @@
</div> </div>
<!-- Step 1: Login --> <!-- Step 1: Login -->
<div class="step active" id="step-login"> <div class="step" id="step-login">
<form class="login-form" id="loginForm"> <form class="login-form" id="loginForm">
<div class="login-error" id="loginError"></div> <div class="login-error" id="loginError"></div>
@ -239,27 +247,31 @@
businesses: [], businesses: [],
init() { init() {
// Check if already logged in const card = document.querySelector('.login-card');
const savedToken = localStorage.getItem('payfrit_portal_token'); const savedToken = localStorage.getItem('payfrit_portal_token');
const savedBusiness = localStorage.getItem('payfrit_portal_business'); const savedBusiness = localStorage.getItem('payfrit_portal_business');
const savedUserId = localStorage.getItem('payfrit_portal_userid'); const savedUserId = localStorage.getItem('payfrit_portal_userid');
if (savedToken && savedBusiness) { if (savedToken && savedBusiness) {
// Already logged in with a business - redirect to portal // Already logged in with a business - redirect to portal (stay hidden)
this.verifyAndRedirect(savedToken, savedBusiness); this.verifyAndRedirect(savedToken, savedBusiness);
return; return;
} }
if (savedToken && savedUserId) { if (savedToken && savedUserId) {
// Has token but no business selected (switching businesses) // Has token but no business selected - skip login, show business selection
// Skip login form, go directly to business selection
this.userToken = savedToken; this.userToken = savedToken;
this.userId = parseInt(savedUserId); this.userId = parseInt(savedUserId);
this.showStep('business');
card.classList.add('ready');
this.loadBusinessesAndShow(); this.loadBusinessesAndShow();
return; return;
} }
// Setup form handlers // No saved session - show login form
this.showStep('login');
card.classList.add('ready');
document.getElementById('loginForm').addEventListener('submit', (e) => { document.getElementById('loginForm').addEventListener('submit', (e) => {
e.preventDefault(); e.preventDefault();
this.login(); this.login();
@ -331,6 +343,7 @@
// Load user's businesses // Load user's businesses
await this.loadBusinesses(); await this.loadBusinesses();
const card = document.querySelector('.login-card');
if (this.businesses.length === 0) { if (this.businesses.length === 0) {
// No businesses - go directly to wizard // No businesses - go directly to wizard
this.startNewRestaurant(); this.startNewRestaurant();
@ -340,6 +353,7 @@
} else { } else {
// Multiple businesses - show selection // Multiple businesses - show selection
this.showStep('business'); this.showStep('business');
card.classList.add('ready');
} }
} else { } else {
const friendlyErrors = { const friendlyErrors = {