Fix admin auth gap from basePath stripping, add password reveal toggle
Middleware compared request.nextUrl.pathname (basePath already stripped by Next.js) against paths still prefixed with /shop, so /shop/admin pages loaded without server-side auth protection. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
ec2ebca836
commit
517e00aeb1
@ -10,6 +10,7 @@ export default function AdminLoginPage() {
|
||||
const [password, setPassword] = useState('')
|
||||
const [error, setError] = useState('')
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [showPassword, setShowPassword] = useState(false)
|
||||
|
||||
async function handleSubmit(e: React.FormEvent) {
|
||||
e.preventDefault()
|
||||
@ -34,16 +35,30 @@ export default function AdminLoginPage() {
|
||||
<h1 className="title is-4" style={{ marginBottom: '1.5rem' }}>Admin Login</h1>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<div className="field">
|
||||
<div className="control">
|
||||
<div className="control has-icons-right">
|
||||
<input
|
||||
className="input"
|
||||
type="password"
|
||||
type={showPassword ? 'text' : 'password'}
|
||||
placeholder="Password"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
autoFocus
|
||||
required
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
className="icon is-right"
|
||||
style={{ pointerEvents: 'auto', cursor: 'pointer', background: 'none', border: 'none' }}
|
||||
onClick={() => setShowPassword((v) => !v)}
|
||||
aria-label={showPassword ? 'Hide password' : 'Show password'}
|
||||
tabIndex={-1}
|
||||
>
|
||||
{showPassword ? (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M17.94 17.94A10.94 10.94 0 0 1 12 20c-7 0-11-8-11-8a18.5 18.5 0 0 1 5.06-5.94M9.9 4.24A10.94 10.94 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"/><line x1="1" y1="1" x2="23" y2="23"/></svg>
|
||||
) : (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8Z"/><circle cx="12" cy="12" r="3"/></svg>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{error && <p className="help is-danger">{error}</p>}
|
||||
|
||||
@ -28,11 +28,11 @@ async function deriveSessionToken(password: string): Promise<string> {
|
||||
export async function middleware(request: NextRequest) {
|
||||
const { pathname } = request.nextUrl
|
||||
|
||||
if (pathname === '/shop/admin/login' || pathname === '/api/admin/login') {
|
||||
if (pathname === '/admin/login' || pathname === '/api/admin/login') {
|
||||
return NextResponse.next()
|
||||
}
|
||||
|
||||
if (pathname.startsWith('/shop/admin') || pathname.startsWith('/api/admin')) {
|
||||
if (pathname.startsWith('/admin') || pathname.startsWith('/api/admin')) {
|
||||
const token = request.cookies.get(COOKIE)?.value
|
||||
const password = process.env.ADMIN_PASSWORD
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user