# Technical documentation — members.mypass.zone

Evidence date: 2026-10-09. Source: `master` at `7268c97` (2022-06-24).

Secret values are named by location only. They are not copied into this document.

## Summary

A Zend Framework 1.11.10 PHP application. Apache rewrites requests into `public/index.php`. One module, `default`, serves the SA Rugby supplier portal. MySQL database name `teamwizz_SARU`, host `localhost`. Deployment is described for AWS CodeDeploy onto the path used by `supplier.sarugby.online`.

The git repository has one commit. There is no README, Composer file, Docker file, or PHP version pin.

## Application structure

```text
members.mypass.zone/
  .htaccess                      rewrite into public/ unless URI starts with /public/
  index.html                     Plesk domain-default page (not the portal)
  application/
    Bootstrap.php                empty _initDbAdapter
    configs/application.ini
    layouts/default.phtml        authenticated chrome (the layout ini selects)
    layouts/layout.phtml         unused Limitless demo
    models/                      Zend_Db_Table classes
    modules/default/
      controllers/Bootstrap.php  HTTPS redirect
      controllers/               portal controllers
      views/scripts/             phtml per controller
  library/Zend/                  Zend Framework 1.11.10
  library/PG/                    local helpers (layout picker, FPDF, image upload, match report)
  public/
    index.php                    front controller
    .htaccess                    rewrite missing files to index.php
    assets/, global_assets/      Limitless / Bootstrap CSS and JS
    dompdf/                      PDF library
    archives/                    gitignored runtime uploads (companies, accreditation)
  scripts/                       CodeDeploy hooks
  appspec.yml
  bitbucket-pipelines.yml
  codedeploy_deploy.py
  default/, default.zip          theme dump, not routed
  test/                          Plesk fcgi, php, and ssi samples
```

`public/index.php` defines:

- `APPLICATION_PATH` → `application/`
- `APPLICATION_ENV` from the environment, default `production`
- `UPDATE_PATH` → `public/archives/`
- time zone `Africa/Johannesburg`
- `display_errors` on, `error_reporting` `E_ALL|E_STRICT`

`application.ini` then sets `display_errors` off for production, staging, testing, and development. Layout is `default`. Front-controller plugin `PG_Controller_Plugin_LayoutPicker` is registered. Additional layout names are configured (`admin`, `union`, `referee`, `gir`, `accreditations`) and those layout files are not in `application/layouts/`. Locale default `af_ZA`. Session cookie lifetime 864000 seconds. DB adapter `pdo_mysql`.

Autoload namespace `PG_`.

## Request path

1. Root `.htaccess`: if the URI does not start with `/public/`, rewrite to `public/{path}`.
2. `public/.htaccess`: if the request is not an existing file, symlink, or directory, rewrite to `index.php`.
3. `index.php` bootstraps `Zend_Application` and runs it.
4. `Default_Bootstrap::_initForceSSL` redirects to HTTPS when `SERVER_PORT` is not 443.
5. The default module router maps `/controller/action`.

Authenticated controllers (`Index`, `Company`, `Users`, `Permits`) redirect to `/login/` in `init` when `Zend_Auth` has no identity. `Login` and `Register` disable the layout and do not require an identity.

## Controllers and routes

| URL prefix | Class loaded by the file name | Auth in init |
|---|---|---|
| `/` and `/index/...` | `IndexController` | Required |
| `/login/...` | `LoginController` | Not required |
| `/register/...` | `RegisterController` | Not required |
| `/company/...` | `CompanyController` | Required |
| `/users/...` | `UsersController` | Required |
| `/permits/...` | `PermitsController` | Required |
| `/error/...` | `ErrorController` | Not required |
| `/organisation/...` | `OrganisationController` | Not required. Actions empty. |
| `/authon/...` | `AuthonController` | Not required. Actions empty. |
| `/events/...` | File declares `Companies_EventsController`, not `EventsController` | Router mismatch |
| `/org/...` | File declares `Company_OrgController`, not `OrgController` | Router mismatch |

## Data

Zend_Db_Table names declared in `application/models`. No SQL schema, migration, or view definition is in the repository.

Used by the portal controllers:

| Model | Table or view name in code | Used for |
|---|---|---|
| `Model_UserProfile` | `Company_Members` | People, login flags, reset and validate keys |
| `Model_CompanyProfile` | `Companies_Profile` | Company. `adminLogin` reads `CompaniesLogin`. |
| `Model_AccreditationMemberProfile` | `AccreditationMemberProfile` | Name and contact copy of a person |
| `Model_CompanyEvents` | `Company_Events` | Company linked to an event |
| `Model_AccreditationList` | `Accreditation_List` | Event / accreditation row, load-in and load-out dates |
| `Model_AccreditationPermits` | `Accreditation_Permits` | Permit rows |
| `Model_AccreditationLoadingZones` | `Accreditation_Loading_Zones` | Zones |
| `Model_AccreditationLoadingServices` | `Accreditation_Load_Services_Types` | Service types on the permit form |
| `Model_AccreditationGates` | `EventGates` | Constructed on the permit screens |
| `Model_AccreVehicleTypes` | `vehicletypes` | Vehicle types |
| `Model_AccreCompanyTypes` | `Accre_Company_Types` | Company types (registration and profile) |
| `Model_BBEELevel` | `BBEE_Level` | B-BBEE levels |
| `Model_Country` | `countries` | Country list |

`CompaniesLogin` is the authentication table. It is not a Zend_Db_Table `$_name`. Whether it is a table or a view is **Unknown / Requires Confirmation**.

Models present and not constructed by a controller in this repository include Fixture, FixtureScores, Squad, Tournament, TournamentFoodSession, FoodSessionItems, Nutritions, Allergens, MenuVenues, MatchReport, NewsArticles, Unions, Positions, Profile, GirProfile, Ethnicity, Logs, ComentryAndCiting, and BBEETypes. Provenance: **Inferred** leftover from a larger SARU / Teamwizz application that shares `teamwizz_SARU`.

Uploads (gitignored: `public/archives/`, `public/files/pics/`):

- Company logo: `public/archives/companies/{CID}_image.jpg`
- Staff photo: `public/archives/accreditation/{MID}_image.jpg`

## Authentication

- `Zend_Auth` with `Zend_Auth_Adapter_DbTable`.
- Passwords stored as MD5. `mcrypt_create_iv` generates reset keys, validation keys, and staff passwords. `mcrypt` was removed in PHP 7.2. The PHP version on the deploy host is **Unknown / Requires Confirmation**. The code will not run on a modern PHP that lacks the mcrypt extension.
- Session namespace `EVENT` holds `EID`.
- No CSRF token, no password-complexity check, and no rate limit were found on login, registration, or reset.

## Mail

Each of `LoginController`, `RegisterController`, `IndexController`, and `PermitsController` has its own `sendMail` copy.

| Setting | Value in code |
|---|---|
| Transport | `Zend_Mail_Transport_Smtp` |
| Host | `smtp.office365.com` |
| Port | 587 |
| SSL | `tls` |
| Username | `accreditations@sarugbyevents.co.za` |
| From name | Accreditation - BIL 2021 |
| Subject | BIL 2021 Notification |
| Commented previous host | `mail.sarugby.co.za` |
| Commented previous From | `accreditation@sarugby.co.za` |

The password is in each of those methods. It is not repeated here.

`PermitsController::postEmailToFp` can POST to `https://footprintapp.net/email/send`. The create-permit action does not call it.

## PDF

`IndexController::getpermitpdfAction` loads Dompdf from `dompdf/dompdf_config.inc.php` (relative to the working directory, not an absolute path). It HTTP-GETs `https://www.footprintapp.net/pdf/getpermit/id/{id}`, converts UTF-8 to Windows-1250, renders A4 landscape, writes under `AC_PATH/loadin/pdf/`, and streams the file. `AC_PATH` is not defined in this repository.

## Deployment

`bitbucket-pipelines.yml` uses image `python:3.5.1` and runs only on branches `qa` and `prod`. Each step exports AWS keys, application name, deployment group, and S3 bucket from Bitbucket variables (`QA_*` or `PROD_*`), installs `zip` and `boto3==1.3.0`, zips the tree to `/tmp/artifact.zip`, and runs `codedeploy_deploy.py`.

`codedeploy_deploy.py` is the Amazon Bitbucket Builds sample (header dated 2016). It uploads the zip to S3 and calls `create_deployment`. It reads `DEPLOYMENT_CONFIG` from the environment. The pipeline file does not export `DEPLOYMENT_CONFIG`. Provenance: **Implemented** in the script, **absent** from the pipeline. Whether the variable is set on the Bitbucket repository is **Unknown / Requires Confirmation**.

`appspec.yml`:

- OS linux
- Destination `/mnt/data/www/html/sarugby.online/supplier.sarugby.online/`
- Owner and group `apache`
- BeforeInstall: `scripts/install_dependencies` (`yum install -y httpd`) as root
- ApplicationStop: `scripts/remove_archives.sh` (deletes CodeDeploy deployment-root directories other than the last successful install) as root
- ApplicationStart: `scripts/start_server` (`service httpd start`) as root

`scripts/stop_server` exists and is not referenced by `appspec.yml`. Its shell test is written `isExistApp = `pgrep httpd`` with spaces around `=`, which is not a valid bash assignment.

`master` is not a pipeline branch. A push to `master` does not deploy.

## Security notes (evidence, not a remediation plan)

These are implemented properties of the tree. They need human review. This document does not repeat secret values and does not describe how to use them.

- Database username, password, host, and database name are in `application/configs/application.ini`.
- SMTP passwords are in the four `sendMail` methods. An older password remains in comments.
- A login override string is compared in `LoginController::indexAction`.
- Many queries concatenate request values into SQL (`RegistrationNumber`, reset key, member id, and others).
- `public/index.php` enables `display_errors` in every environment.
- `emailtestAction` sends mail to a hardcoded personal address.
- `uploadremotecompanyAction` writes a file for a caller-supplied company id without an auth check.
- Permit cancel and duplicate update or copy a row by id without checking `CID`.

## Background work, queues, monitoring

No queue, cron, worker, or application log configuration was found. `ErrorController` uses Zend's error handler plugin. `Model_Logs` maps to `TournamentLogs` and is unused by the portal controllers.

CodeDeploy and Bitbucket Pipelines are the only automation. There is no test suite for the portal. `sonar-project.properties` and `sonarqube_scan.bat` are not in this commit.

## Dependencies (vendored, no lockfile)

| Piece | Evidence |
|---|---|
| PHP with the `mcrypt` extension | `mcrypt_create_iv` in Login, Register, Index, Users |
| Zend Framework 1.11.10 | `library/Zend/Version.php` constant `VERSION` |
| Dompdf | `public/dompdf` |
| jQuery 3.1.1 and Bootstrap / Limitless | `public/assets` |
| boto3 1.3.0 and Python 3.5.1 | pipeline only |
| Apache httpd on Amazon Linux (`yum`, `service`) | CodeDeploy scripts |

## Local library `PG`

Under `library/PG/Controller/Plugin/`: `LayoutPicker.php` (registered), plus Ajax, email layout, encode, FPDF, image uploaders, LOC, match report, notifications, password generator, and file upload. The portal controllers inspected do not construct the match-report or FPDF plugins. `LayoutPicker` is the one named in `application.ini`.
