fix: the public page's own sign-in box knew nothing about the provider
Some checks failed
Tests / backend (push) Failing after 4s
Tests / frontend (push) Failing after 28s
Tests / e2e (push) Failing after 30s

/login was right; the landing page has a second, separate sign-in modal
and it still offered Email, Password and "Forgot password?" on a site
where none of the three can work. It now leads with "Sign in with
PedsHub SSO", drops the email form and the register half entirely under
sso_only, and says in one line where sign-in happens.

Both halves come from /auth/signup-policy and /auth/sso/config, the two
the page was already entitled to ask.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TqXevQJhxFrM7jJg82cgZN
This commit is contained in:
Daniel 2026-09-13 13:06:24 +02:00
parent 282b6a25f7
commit 8d7485eaad
2 changed files with 38 additions and 2 deletions

View file

@ -880,3 +880,10 @@
}
.lp-studio-cta { margin-top: 34px; text-align: center; }
/* The line between the provider's button and the email form, and the line
that stands in for the form when there is no email sign-in at all. */
.lp-modal-or {
margin: 12px 0 0; text-align: center;
font-size: .82rem; color: var(--text-muted);
}

View file

@ -254,6 +254,13 @@ function AuthModal({ mode, onClose, onSwitch }) {
const [inviteRequired, setInviteRequired] = useState(false)
const [inviteCode, setInviteCode] = useState('')
const [signupOpen, setSignupOpen] = useState(true)
//: The public page's own sign-in box. It is a different component from
//: /login and knew nothing about the provider, so on a site where the only
//: way in is single sign-on it offered an email and a password and a
//: "Forgot password?" three things that cannot work.
const [ssoOnly, setSsoOnly] = useState(false)
const [ssoEnabled, setSsoEnabled] = useState(false)
const [providerName, setProviderName] = useState('single sign-on')
useEffect(() => {
let live = true
@ -266,8 +273,13 @@ function AuthModal({ mode, onClose, onSwitch }) {
// offer, and a Register tab that leads to a refusal is worse than no
// tab at all.
setSignupOpen(res.data?.registration_open !== false)
setSsoOnly(res.data?.sso_only === true)
setProviderName(res.data?.provider_name || 'single sign-on')
})
.catch(() => {})
api.get('/auth/sso/config')
.then(res => { if (live) setSsoEnabled(res.data?.sso_enabled === true) })
.catch(() => {})
return () => { live = false }
}, [])
@ -355,8 +367,19 @@ function AuthModal({ mode, onClose, onSwitch }) {
</div>
)}
{/* The provider, first, and on an SSO-only site the only thing here. */}
{isLogin && !registered && ssoEnabled && (
<>
<a href="/api/auth/sso/login" className="btn btn-primary btn-block"
style={{ display: 'block', textAlign: 'center', textDecoration: 'none' }}>
Sign in with {providerName}
</a>
{!ssoOnly && <p className="lp-modal-or">or sign in with email</p>}
</>
)}
{/* Login form */}
{isLogin && !registered && (
{isLogin && !registered && !ssoOnly && (
<>
{unverified && !resendSent && (
<div className="lp-unverified">
@ -387,8 +410,14 @@ function AuthModal({ mode, onClose, onSwitch }) {
</>
)}
{isLogin && !registered && ssoOnly && (
<p className="lp-modal-or">
This site signs in through {providerName}.
</p>
)}
{/* Register form */}
{!isLogin && !registered && (
{!isLogin && !registered && !ssoOnly && (
<>
{error && <div className="alert alert-error">{error}</div>}
<form onSubmit={handleRegister}>