Home › Publishing Workflow › Contacts
Contacts
Post-login "my account" screens on the contacts.php entry file's Contact_Manager dispatcher (class/contacts.class.php, view/contacts.view.php, view/index.contacts.view.php) — profile view/edit, saved manuscript records, saved searches, favorite subjects, 2FA enrollment, and email-unsubscribe — reached once a reader is already signed in.
| Page | Status | Workflow | E2E | Enhanced | Legacy Ref | Route | Roles |
|---|---|---|---|---|---|---|---|
| My Profile | Full | — | Yes | tabbed | contacts.php | /contacts | Any authenticated contact (self); Journal Admin (Editor-in-Chief / System Admin / Editorial Office) viewing another contact via _tc |
| Edit Profile | Full | — | Yes | validation | contacts.php?_action=edit | /contacts?_action=edit&_tc=... | Self (own contact) or Journal Admin (Editor-in-Chief / System Admin / Editorial Office) |
| Change Password | Full | — | Yes | validation | contacts.php?_action=chpass | /contacts?_action=chpass | Any authenticated contact (self); Journal Admin can also reach it for their own admin password via the adm POST param (see changePasswordAction's $cnCode branch) |
| Saved Records | Pending | — | — | — | contacts.php?_action=records | /contacts?_action=records | Any authenticated contact (self) |
| Saved Searches | Dropped | — | — | — | contacts.php?_action=search | /contacts?_action=search | Any authenticated contact (self) |
| Favorite Subjects | Dropped | — | — | — | contacts.php?_action=favsubs | /contacts?_action=favsubs | Any authenticated contact (self) |
| Enable Two-Factor Authentication | Pending | — | — | — | contacts.php?_action=enable2fa | /contacts?_action=enable2fa | Any authenticated contact (self) |
| Unsubscribe from Alert Emails | Pending | — | — | — | contacts.php?unsubscribe=... | /contacts?unsubscribe=<encrypted email token> | Public (via the one-time emailed unsubscribe link; no session required) |
Features
| Feature | Status | E2E | Description |
|---|---|---|---|
| Signed-in reader can view their own profile details (name, contact info, avatar, join date) | Full | Yes | Legacy read-only showContactInfo table becomes the hero header plus prefilled General tab of the tabbed profile editor. |
| Reader can edit their own profile (personal, academic and preference fields, honoring journal-configured required/disabled/custom fields) | Full | Yes | Save is dirty-tracked with a sticky footer; validation errors surface live per field and as per-tab error dots with auto-jump to the first errored tab. |
| Reader can upload, replace or delete their profile avatar | Full | — | Avatar changes preview immediately in the hero header and persist on save. |
| Reader can pick favorite/specialty subjects as part of profile editing | Full | Yes | The subjects data model survives inside the profile editor even though the standalone legacy Favorite Subjects page is dead. |
| Journal admin (Editor-in-Chief / System Admin / Editorial Office) can view and edit another contact's profile | Full | Yes | The legacy admin-views-other-contact mode is promoted to a dedicated Journal Admin Users detail screen instead of reusing the reader profile route. |
| Reader can change their password with current-password verification and strength rules (min 8 chars, letters+digits, not equal to old, confirm match) | Full | Yes | Legacy re-rendered the form with a single server-side error string; the port validates current/new/confirm live before submit. |
| Journal admin can change their separate admin-account password via the same change-password form (legacy 'adm' POST branch) | Pending | — | Legacy changePasswordAction targets $_SESSION['juAdmUser__'] instead of the contact when POST adm is set (apps/legacy/js/class/contacts.class.php:1937); the new stack has no distinct admin-credential counterpart on this form. |
| A password change is recorded in the contact's action history | Pending | — | Legacy logs cn_action_type=4 via saveCnActionHistory after every successful password change (apps/legacy/js/class/contacts.class.php:1986-1992); no equivalent audit write found on the ported change-password flow. |
| Reader can view their saved manuscript records (article title, save date, link to the article) | Pending | — | Legacy myRecords lists ju_contact_article rows ordered by title with an explicit 'no records found' state (apps/legacy/js/class/contacts.class.php:2013); no apps/web counterpart. |
| Reader can bulk-delete saved records via checkboxes | Pending | — | The legacy myRecords table has per-row checkboxes and a Delete button calling deleteRecords() (apps/legacy/js/view/contacts.view.php:1243,1271); sub-feature of Saved Records with no port. |
| Reader can enroll in TOTP two-factor authentication (QR code + verification code) and disable it again | Pending | — | Legacy enableTwoFactor shows enable/disable buttons based on cn_op_values plus a QR image and code-verify input (apps/legacy/js/class/contacts.class.php:2567, view :1444); apps/web has unwired two-factor-management/setup/panel components but no page mounts them, so the capability is not reachable. |
| Email recipient can unsubscribe from alert emails via a one-time emailed link, without logging in, with a yes/no confirmation step | Pending | — | Legacy unsubscibeAlertEmails decrypts the token, shows a confirm form, and appends the email to the journal-level unsubscibe_em setting (apps/legacy/js/class/contacts.class.php:2184); no apps/web counterpart. |
| Reader can view saved searches | Dropped | — | A titled, reachable route that was never implemented in legacy and is deliberately not carried forward. |
| Reader can manage favorite subjects on a standalone page | Dropped | — | Only the dead standalone page is dropped; the favorite/specialty subjects capability itself is ported inside Edit Profile. |
| Admin sees a manager to-do list on their own profile landing page | Pending | — | Legacy showContactInfo appends __managerToDo() output when the logged-in viewer is an admin viewing their own profile (apps/legacy/js/class/contacts.class.php:167-176); the new profile page has no to-do block (may belong to an admin dashboard instead). |
| Super admin can view and edit their own profile (General + Security only) without a tenant context | New | — | No legacy predecessor: the legacy admin credential had no self-service profile page; needed because the new platform has a tenant-less super-admin session. |
| Profile tabs are URL-synced so a specific tab (e.g. ?tab=security) is deep-linkable | New | Yes | Supports shareable/bookmarkable tab state, which the single-page legacy forms had no notion of. |
Open flag (unresolved in Phase B): this module overlaps conceptually with Journal Admin › Users and with journal-configuration screens that have no clear home yet. Kept under Publishing Workflow because the legacy role-portal router lives here. See also: Journal Admin › Users.
Sign-in/registration/password-reset/2FA-verification rows on this same
contacts.php dispatcher live in a different module.contacts.php (default, unauthenticated), ?_action=signup, ?_action=login&frg=1 (forgot password), ?_action=twofactor, and ?_action=rp (reset password via email link) are inventoried under Journal › Contact & Auth, since they are pre-account / credential flows reachable only while a reader is not yet signed in. ?_action=chpass (Change Password) is catalogued on this page instead: despite the similarly-named neighbors, changePasswordForm's guard (class/contacts.class.php:804) redirects home unless $_SESSION['juAdmUser__'] or $_SESSION[SESSION_NAME_ID] is already set — the identical post-login guard used by Enable Two-Factor Authentication below — so it cannot be reached pre-login at all. This module covers exactly the "Reader My Account" gap flagged as open in that page's notes.Saved Searches and Favorite Subjects render no content.
Both set a page title/breadcrumb (
CN_SAVED_SEARCHS / CN_SUBJECTS) but their case blocks in contacts.php's content switch are empty — there is no matching $FUNCTION branch in view/contacts.view.php, so the rendered page is header/footer chrome around a blank body. Kept as rows (matching the "Reader My Account" gap the sibling Journal page's notes call out) rather than dropped, since they are still distinct, reachable, titled routes — just an unfinished/dead feature. Note: the Favorite Subjects data model itself is not dead — ju_contact_subject rows with fav_spc = 2 are the same rows read and written by the Specialty/subjects picker on the Edit Profile screen, via Contact_Manager::saveCnSubject (class/contacts.class.php:1796), called from changeContactInfo (class/contacts.class.php:1740, the Edit Profile submit handler, dispatched from manageContactAction on POST['Edit']) and saveNewContact (class/contacts.class.php:1230, registration, dispatched on POST['Insert']). Only the standalone contacts.php?_action=favsubs page (empty case block, contacts.php:313-315) was never wired to a view — Saved Searches has no such backing feature anywhere else in the codebase (its case block at contacts.php:309-311 is likewise empty, with no other saved-search mechanism found) and is fully dead.Excluded as non-rows.
Logout (
_action=logout) calls Contact_Manager::logoutAction() and exits with no render. The im=... query param (Contact_Manager::impsConfAdmin, used by Journal Admin's impersonate-user action) decrypts a token, sets the session, and redirects with no render of its own. Both are pure session/redirect handlers, not pages.view/contact.role.view.php and class/contact.role.class.php are a false friend for this module.Despite the "contact" naming and being listed as a likely anchor, neither file is ever required by
contacts.php — both are used only by manager.php and mng_assist.php (the sibling Manager and Management Assistant modules). Excluded here accordingly.