HomeJournal › Contact & Auth

Contact & Auth

Public support inquiry form plus the journal's reader account system — sign-in, registration, and password recovery/change. Legacy entry: journal/contact.us.php (support form, using class/config.class.php's JU_Config directly — no Contact_Manager involvement) and contacts.php (dispatched into class/contacts.class.php's Contact_Manager) — neither has an auth gate to enter.

Page Status E2E Enhanced Legacy Ref Route Roles
Contact Us Full Yes validation journal/contact.us.php /journal/contact.us Public
Login Full inline-2fa contacts.php /contacts Public
Register (Sign Up) Full Yes validation contacts.php?_action=signup /contacts?_action=signup Public (registration can be disabled by journal setting disable_reg)
Forgot Password Full recaptcha contacts.php?_action=login&frg=1 /contacts?_action=login&frg=1 Public
Two-Factor Verification Full inline contacts.php?_action=twofactor /contacts?_action=twofactor Public (mid-login only — requires a pending login attempt with a temporary session)
Reset Password (Email Link) Full validation contacts.php?_action=rp /contacts?t=<encrypted: _action=rp&e={email}&c={confirm_code}> Public (via the one-time emailed link only; blocked for non-browser user agents)
Unsubscribe (Email Alerts) Pending contacts.php?unsubscribe=<encrypted token> /contacts?unsubscribe=<encrypted: em={email}> Public — reachable only via the one-time encrypted link mailed to the recipient; no session check at all
Change Password Full Yes validation contacts.php?_action=chpass /contacts?_action=chpass Public — requires an active reader (or logged-in admin) session

Features

FeatureStatusE2EDescription
Visitor can send a support inquiry (name, email, phone, subject, query type, message) that is emailed to the journal Full Yes The legacy eight-value query-type select is preserved; success shows a toast instead of a reloaded confirmation page.
Journal admin can turn the public contact form off (no_contact_form) while still showing the configured contact note text Full When disabled, only the journal-configured note is shown; the form is suppressed.
Contact form submissions are bot-protected Full reCAPTCHA v3 only; the legacy image-CAPTCHA fallback path is not reproduced (see Dropped feature).
Fallback image CAPTCHA (math/word challenge) when reCAPTCHA is unavailable, and CAPTCHA escalation after 3 failed login/reset attempts Dropped Legacy escalated to a visible challenge after 3 failed attempts or when Google was unreachable; the port relies on reCAPTCHA v3 scoring on every submit.
Reader can sign in with username or email and password Full Public header e2e (TC-JR-HP-008) still asserts the legacy login href, so no spec exercises the native page yet.
Reader with 2FA enrolled must enter a TOTP code to complete sign-in Full Verification is inline in the login flow with auto-focus OTP input and a Back option; success updates the session and routes to /profile.
Successful login updates the reader's last-login timestamp and IP Full Server-side side effect of login, verified by API integration spec rather than e2e.
Login attempts (success and failure) are recorded in contact action history and the audit log Pending Legacy saveCnActionHistory + saveAuditLog fire on both wrong-login and success (contacts.class.php:740-745, 790-793); no equivalent action-history/audit write was found cited for the new login path — flagged for verification.
Visitor can register a reader account (contact_code=0) and receives a registration email Full Yes Duplicate username/email rejection and the registration email are server-side parts of the same capability.
Journal setting disable_reg can switch public registration off Basic Legacy hides/blocks signup when disable_reg is set; the ported register page needs a parity check for this gate.
Admin dashboard 'Register a New Author' shortcut (eic_custom_opt contains reg_au) reuses the public signup Pending Per apps/legacy/spec/auth/contact-registration.md it is the identical /contacts?_action=signup route, not a separate form; no apps/web admin-dashboard shortcut to the native /register page was cited.
Reader can request a password-reset link by email Full Legacy returned wrongEmail for unknown addresses; the new form shows explicit submit/success states.
Reader completes password reset from the emailed one-time link by setting a new password of their choice Full Includes an invalid/expired-token state that routes back to /forgot-password for a fresh link.
System emails the reader a newly generated password after a reset-link visit Dropped Superseded rather than lost: the reset link now leads to a set-your-own-password form.
Reset link is blocked for non-browser user agents (crawler protection so mail scanners don't burn the one-time link) Pending Legacy resetPasswordForm bails out via crawler.detect.php isCrawler (contacts.class.php:926-929); no equivalent user-agent gate was found cited for the new-password route.
Logged-in reader (or admin) can change their password after confirming the current one Full Yes Same page also serves the super-admin context by branching on pathname.
Email recipient can unsubscribe from alert emails via a token-encrypted link (no login required) Pending Legacy Contact_Manager::unsubscibeAlertEmails decrypts em={email} from the link, shows a confirm form with CSRF token, and appends the address to the journal's unsubscibe_em setting; grep of apps/web found no unsubscribe route — the footer newsletter SUBSCRIBE form is a different capability.
Newsletter subscribe form in the public journal footer New Opt-in counterpart designed from scratch for the new public footer; does not replace the missing token-gated unsubscribe.
Contact Us has an older, simpler fallback in the mainm/mainn theme dirs.
Those two front-end directories don't call journal/contact.us.php at all — their .htaccess rewrites the same pretty URL (contact.us) to an inline branch inside their own index.php (?contact) that only echoes the contact_us journal-setting note text, with no form, no CSRF, and no CAPTCHA. The row above documents the current, spec-matching implementation (journal/contact.us.php, per apps/legacy/spec/journal/contact-us.md); the mainm/mainn variant is flagged here rather than split into a second row since it's a strictly reduced legacy fallback of the same conceptual page, not a materially distinct screen. Worth a second look in Phase C if any live journal still runs on the mainm/mainn docroot.
Reader "My Account" actions on the same contacts.php dispatcher are intentionally excluded here.
Once a reader is signed in, contacts.php also serves profile view/edit (_action=edit / profile, shared with the admin-side edit-profile form), saved manuscripts (_action=records), and 2FA enrollment (_action=enable2fa) — each gated behind an active $_SESSION[SESSION_NAME_ID] (Contact_Manager::showContactInfo / ::myRecords / ::enableTwoFactor all redirect to login or bail out without one). These are post-login account-management screens, not "sign-in/sign-up/registration/password flows," and none of the Journal segment's other modules (Home, Journal Info, Issues & Articles, Browse, Search, Static Pages) obviously claims a reader-account area either — flagging this as an open gap for Phase C/D triage (possibly a future "Reader Account" module) rather than force-fitting them into Contact & Auth. Email-preference unsubscribe (unsubscribe) is not part of this excluded group despite riding the same dispatcher: Contact_Manager::unsubscibeAlertEmails() carries no session check at all, so it gets its own public/token-gated row above instead (peer to Reset Password (Email Link), not to this post-login set). Two more _action values on the same dispatcher, search and favsubs, are also absent from both this excluded list and the table above, but for a third reason: both are empty no-op cases in the content-dispatch switch (case 'search': break; / case 'favsubs': break;) — no Contact_Manager method is called, no view is rendered, and inc/js/contacts.js has no client-side handling for either — i.e. dead/stub code, not an implemented reader-account screen, as of the current codebase.
"Register a New Author" is the same route as Register, not a separate row.
Per apps/legacy/spec/auth/contact-registration.md, the admin dashboard's "Register a New Author" shortcut (shown when journal setting eic_custom_opt contains reg_au) links to the identical public contacts?_action=signup URL and handler — there is no separate admin-only form or code path.