# Technical documentation — pestelite_html (Pest Elite)

Evidence date: 2026-10-06.

Source: `main` at `c5476a0e05bc75140ef06446686bc2f066ad8bea` (2024-02-19). Remote: `https://bitbucket.org/overdrive/pestelite_html.git`. Only branch: `main`.

## What this repository is

A Cordova project whose `www/` tree is a set of static HTML pages. The pages talk to one Form.io project. There is no application server, database, or test suite in git.

`config.xml` and `package.json` still carry the Apache Cordova sample description and author. The screens are Pest Elite registers.

## Repository layout

```text
pestelite_html/
  config.xml
  package.json
  package-lock.json
  .gitignore
  www/
    index.html            login
    sites.html            site / service reports
    clients.html
    pesticides.html
    users.html
    sites/index.html      unlinked pesticide form
    css/index.css         Cordova sample, not linked
    img/logo.png
    js/index.js           deviceready stub
    js/formio.js          empty
    js/lib/constants.js   unused Form.io base URL
```

Tracked file count at `c5476a0`: 15 paths. `www/js/formio.js` is an empty blob.

`.gitignore` ignores `.DS_Store`, `node_modules/`, `/plugins/`, and `/platforms/`. A fresh clone has no `node_modules`, `plugins`, or `platforms`.

## Frameworks and languages

| Piece | Version in the repo | Role |
|---|---|---|
| Apache Cordova widget | config widget `1.0.0` | Packaged app metadata |
| cordova-android | `12.0.1` exact in the lockfile, `^12.0.1` in package.json | devDependency |
| cordova-ios | `7.0.1` exact in the lockfile, `^7.0.1` in package.json | devDependency |
| HTML, CSS, browser JavaScript | — | All UI |
| Bootstrap CSS | `4.6.1` from jsDelivr | Layout |
| Bootstrap JS | `4.6.2` from jsDelivr | Modals and navbar |
| jQuery | `3.5.1` slim | Used as `$("#...").modal("toggle")` |
| Popper | `1.16.1` | Bootstrap dropdown/modal dependency |
| Form.io client | `formio.full.min.js` and `formio.full.min.css` from `cdn.form.io`, unpinned | Renders forms inside modals |

The Cordova CLI is not listed in `dependencies` or `devDependencies`. `npm start` runs `cordova emulate`. `npm run android` runs `cordova emulate android`. Both need a global or otherwise available `cordova` binary, plus generated platforms. Neither was run for this document.

`npm test` is `echo "Error: no test specified" && exit 1`.

License field in `package.json` is `Apache-2.0`. The sample file headers are the Apache license. The Pest Elite screens added in `c5476a0` keep those headers.

## Application structure

Each list page repeats the same pattern:

1. Navbar.
2. A container with a heading, an Add button, and a list element.
3. Three Bootstrap modals: new, view, and update. The update modal is never opened.
4. `js/index.js`, then an inline script.

Login (`www/index.html`) is the exception. It has no navbar and no Form.io renderer on the active path. It posts with `fetch`.

`www/js/lib/constants.js` is an ES module (`export const`) and is not referenced with a script tag. The pages would not load it as a classic script. The constant duplicates the host that is hard-coded in the HTML.

`www/js/index.js` registers `deviceready`. The HTML files do not include `cordova.js` and do not have `#deviceready`. In a normal browser the event does not fire, so the stub does nothing. Inside a Cordova WebView, without the script tag, Cordova's usual bridge script is also absent unless the container injects it. That injection is **Unknown**.

## Form.io integration

Host: `https://rzkiqpzlxxtfqjl.form.io`.

Project id on the fetched forms: `65778584972fd0f18a111f4e`.

| Path | Form.io type | Form `_id` | `modified` (as returned) | Caller |
|---|---|---|---|---|
| `pestelitelogin` | form | `65c0b0a897f8e889b54d54be` | 2024-02-12 | POST `.../pestelitelogin/submission` from login |
| `digimonkv1` | form | `65b20db1a5c076dcf1999761` | 2024-02-23 | GET collection and Formio.createForm from `sites.html` |
| `clientregister` | form | `65800d9303bfccb44900cb63` | 2024-07-12 | `clients.html`, and the site form's client select |
| `pesticidesregister` | form | `65b23c965f44cbd732a1438c` | 2024-04-15 | `pesticides.html`, `sites/index.html`, pesticide grid |
| `pesteliteusers` | resource | `65c0a2695e73db6988139702` | 2024-04-08 | `users.html`, role lookup, technician select |

Login request:

```http
POST /pestelitelogin/submission
Content-Type: application/json
x-jwt-token: <empty>

{"data":{"email":"...","password":"..."}}
```

On success the code reads header `x-jwt-token` and body fields `data` and `_id`.

List request:

```http
GET /{formPath}/submission
Content-Type: application/json
x-jwt-token: <localStorage x-jwt-token>
```

Create form URL: `https://rzkiqpzlxxtfqjl.form.io/{formPath}`.

View form URL: `https://rzkiqpzlxxtfqjl.form.io/{formPath}/submission/{id}`.

User lookup on the sites page: `GET /pesteliteusers/submission/{id}` where `{id}` is `localStorage["pest-elite-user-id"].split('"')[1]`. The id was stored with `JSON.stringify`, which adds quotes.

`GET /pestelitelogin/action` returned 401 on the evidence date. Form actions (for example a Login action that would issue the JWT) are not visible in this repo and were not readable anonymously. **Unknown / Requires Confirmation.**

Client address components set `provider` to `nominatim`. Nominatim is OpenStreetMap's search service. The HTML does not call it.

The site form includes file components (`uploadTheImageOfTheSiteMap`, `uploadImage`). The storage provider is whatever Form.io has configured for that project. It is not set in git. **Unknown.**

## Local storage

| Key | Written by | Contents |
|---|---|---|
| `x-jwt-token` | login success | header value, or the string from a missing header |
| `pest-elite-user` | login success | `JSON.stringify(json.data)` |
| `pest-elite-user-id` | login success | `JSON.stringify(json['_id'])` |

Commented code would have used `sessionStorage` key `pestEliteUser`. That path is not active.

No cookie, no indexedDB, no Cordova storage plugin.

## Authentication and access

The app treats "list response is OK" as "signed in" and anything else as "go to login". It does not inspect the JWT.

The published form documents include `access` and `submissionAccess` arrays. They name the anonymous role `000000000000000000000000` and three other role ids. Those ids are not mapped to Admin / Client / Technician anywhere in git. See `business-rules.md`.

Password fields exist on the login form (`protected: true`) and on the user resource (`protected: true`). The login page stores the entire `data` object from the login response. Whether that object includes the password was not checked, because checking it would mean sending credentials.

## Cordova and build

`config.xml`:

- Widget id `com.elite.pest`, version `1.0.0`.
- Name `PestElite`.
- Icon `./www/img/logo.png`, declared 57 by 57. The file is a PNG. Its pixel size was not measured.
- Description and author are still the Cordova sample.
- Content src `index.html`.
- `allow-intent` for `http://*/*` and `https://*/*`.
- No `access` origin, no preferences, no plugins, no platform blocks.

`package.json` `cordova.platforms` lists `ios` and `android`. Because `/platforms` and `/plugins` are gitignored and absent, this commit does not contain an Android or iOS project. Building requires installing npm devDependencies, installing the Cordova CLI, and adding platforms. That sequence is **Inferred** from Cordova's normal layout, not from a README. There is no README.

## Security observations present in the source

Documented so a later reader does not miss them. They are not a pentest.

- CSP meta tags are commented out on every page. Inline scripts run.
- List and card rendering concatenates submission fields into HTML.
- The JWT is in `localStorage`.
- Login sends the password in a JSON body to Form.io.
- `allow-intent` is unrestricted http and https.
- The admin-only class toggle does not use a CSS class that Bootstrap 4 defines. The other pages have no role check.
- Form schemas, including field names and access lists, were readable without a token on the evidence date.

## Infrastructure, deployment, operations

Not in the repository:

- CI configuration (no `bitbucket-pipelines.yml`, no GitHub workflow, no Dockerfile).
- Hosting, app-store, or signing configuration.
- Environment variables or a `.env` file. The Form.io host is hard-coded.
- Monitoring, logging beyond `console.log`, queues, or workers.
- A database. Persistence is Form.io.

`sonar-project.properties` and `sonarqube_scan.bat` were named in the onboarding issue as files on the scan host. They are not in `main`. **Unknown** whether they exist only as untracked files on that machine.

## Development process visible in git

Two commits, both by Jason Wandrag `<jasonwandrag@hotmail.com>`:

| Commit | Date | Message |
|---|---|---|
| `158f88b` | 2024-02-09 17:10 +0200 | First commit |
| `c5476a0` | 2024-02-19 15:30 +0200 | Functional Updates |

No tags, no other branches, no merge commits.

## Related web property

The live site form embeds:

`https://pestelite.co.za/wp-content/uploads/2022/07/PE_Logo-removebg-preview-e1659271343336.png`

That URL is a WordPress uploads path. This repository does not contain the WordPress site. The relationship is **Unknown / Requires Confirmation**.

## How the documents in this folder fit together

- `project-plan.md` — what the product appears to be, scope, and status.
- `prd.md` — screen and form behaviour as requirements.
- `features.md` — current, unused, and external features.
- `business-rules.md` — validation, roles, and display rules.
- This file — structure, dependencies, and integration mechanics.
