Passwords are now encrypted with Web Crypto AES-GCM (256-bit) before being stored in browser.storage.local. The random key is persisted so it survives browser/service-worker restarts (otherwise old ciphertext could never be decrypted). Encryption/decryption happen in the background via encrypt-password/decrypt-password messages; autoLogin decrypts on the fly and falls back to a legacy plaintext password for pre-encryption profiles. The popup never reveals a stored password and preserves it when editing with a blank field. Removes the plaintext-password-at-rest smell flagged in the design review. Note: this is at-rest obfuscation-level security (the key ships with the extension); the extension only talks to the school portal.
152 lines
6.4 KiB
Markdown
152 lines
6.4 KiB
Markdown
# ISMIS Helper
|
||
|
||
A lightweight **[Firefox](https://addons.mozilla.org/)** / **[Chrome](https://chromewebstore.google.com/)**
|
||
extension for the USC ISMIS student portal that:
|
||
|
||
- Auto-fills and auto-submits your login.
|
||
- Auto-accepts the privacy-policy modal.
|
||
- Exports a **Study Load PDF** that matches the official layout — bundled **Segoe UI**
|
||
fonts, the USC logo, the course table, and the units total.
|
||
|
||
One codebase builds for **both browsers** (see [Build](#build)).
|
||
|
||
## Install
|
||
|
||
> Temporary/development install. For distribution, publish the built zips to
|
||
> Firefox AMO and the Chrome Web Store — they are store-ready.
|
||
|
||
### Firefox (load temporary add-on)
|
||
|
||
1. Build the Firefox variant (or download `ismis-helper-firefox.zip` from CI):
|
||
```bash
|
||
node scripts/build.js firefox
|
||
```
|
||
The output is at `dist/ismis-helper-firefox.zip` (unzip it, or use `dist/firefox/`
|
||
directly).
|
||
2. Open `about:debugging` in Firefox.
|
||
3. Click **This Firefox** → **Load Temporary Add-on…**.
|
||
4. Select `dist/firefox/manifest.json`.
|
||
5. Open `https://ismis.usc.edu.ph` and use the extension.
|
||
|
||
### Chrome (load unpacked)
|
||
|
||
1. Build the Chrome variant (or download `ismis-helper-chrome.zip` from CI):
|
||
```bash
|
||
node scripts/build.js chrome
|
||
```
|
||
2. Unzip `dist/ismis-helper-chrome.zip` (or use `dist/chrome/` directly).
|
||
3. Open `chrome://extensions` in Chrome.
|
||
4. Enable **Developer mode** (toggle, top-right).
|
||
5. Click **Load unpacked** and select the unzipped `dist/chrome` folder.
|
||
6. Open `https://ismis.usc.edu.ph` and use the extension.
|
||
|
||
> For a persistent install, package and publish via Firefox AMO / Chrome Web Store
|
||
> with the same built zips.
|
||
|
||
### Distribute to real users
|
||
|
||
#### Firefox (self-hosted, temporary)
|
||
|
||
> **Note:** Firefox blocks unsigned extensions for normal installs. The proper
|
||
> fix is to sign the add-on via **addons.mozilla.org (AMO)** and publish it there
|
||
> (or self-host a signed `.xpi`). AMO is currently **under maintenance**, so until
|
||
> it returns, the only way to install the unsigned build is to lower Firefox's
|
||
> signing check on each user's machine. This is a per-user browser setting and is
|
||
> **not** suitable for a broad audience — use it for personal / small-group use.
|
||
|
||
1. Build the Firefox variant (or download `ismis-helper-firefox.zip` from a release):
|
||
```bash
|
||
node scripts/build.js firefox
|
||
```
|
||
2. In Firefox, open `about:config` and accept the warning.
|
||
3. Search for `xpinstall.signatures.required` and set it to **`false`**.
|
||
4. **Restart Firefox** for the change to take effect.
|
||
5. Install the add-on from the release zip: drag `ismis-helper-firefox.zip` into
|
||
Firefox (or File → Open File… and select it).
|
||
|
||
> When AMO is back online, prefer the signed route: publish the same zip to AMO
|
||
> (or sign it with `web-ext sign`) so users install it normally without touching
|
||
> `about:config`.
|
||
|
||
#### Chrome (self-hosted)
|
||
|
||
Chrome does **not** require signing for normal installs. Users can install the
|
||
built `ismis-helper-chrome.zip` directly:
|
||
|
||
1. Download `ismis-helper-chrome.zip` from a release and unzip it.
|
||
2. Open `chrome://extensions`, enable **Developer mode**, and click **Load unpacked**.
|
||
3. Select the unzipped folder.
|
||
|
||
> For a store experience, publish the same zip to the Chrome Web Store (one-time
|
||
> $5 developer registration).
|
||
|
||
## Features
|
||
|
||
- **Saved login profiles** (stored in `browser.storage.local`) — only one enabled at
|
||
a time, with a master on/off toggle.
|
||
- **One-click Download PDF** button on the Study Load page, plus **CSV / Excel /
|
||
JSON / Next Up** export buttons.
|
||
- PDF settings in the popup:
|
||
- Truncate long course descriptions to match the official PDF (default on).
|
||
- Show/hide `Year Level`, and set a custom Year Level value.
|
||
- Year Level mode: `Auto` (recommended), `Use custom value`, or `Profile value
|
||
only`.
|
||
- **Smart Year Level**: for the semester being printed, `Auto` derives the
|
||
standing from remaining units (Student Prospectus total − Lacking Subjects,
|
||
reflecting units actually passed) or, failing that, from the View Grades
|
||
history. Custom value overrides; the profile-scraped value is the fallback.
|
||
- **Live progress indicator**: during any export a status bar below the buttons
|
||
shows the current step (reading table, fetching course descriptions `i/N`,
|
||
profile, year level, building file) with a progress percentage.
|
||
- **Next Up import**: the Next Up export writes CSV in the exact column contract
|
||
the Raycast [Next Up](https://github.com/) extension accepts
|
||
(`title, courseCode, days, startTime, endTime, room, units, professorName`),
|
||
so schedules drop straight into the app.
|
||
- **Bundled Segoe UI fonts** for a 1:1 look with the official document.
|
||
- Builds and packages automatically via Gitea Actions (zips + versioned releases
|
||
with a signed `.xpi`).
|
||
|
||
## Build
|
||
|
||
Requires **Node.js** (the `build.js` script itself is dependency-free; `npm install`
|
||
is only needed to run the tests).
|
||
|
||
```bash
|
||
npm install # dev deps for tests
|
||
npm test # run the test suite
|
||
npm run build # build both -> dist/*.zip
|
||
node scripts/build.js all # build both explicitly
|
||
node scripts/build.js chrome # just chrome
|
||
node scripts/build.js all --version 1.3.0 # versioned zips
|
||
```
|
||
|
||
**CI (Gitea Actions):** on every push, both zips are built, tests run, and the
|
||
zips are uploaded as artifacts. When you push a `v*` tag (e.g. `v1.3.0`), it
|
||
additionally creates a **Gitea Release** with both versioned zips attached.
|
||
|
||
## Settings
|
||
|
||
Open the extension popup to:
|
||
- Manage login profiles (add / edit / enable).
|
||
- Toggle the master on/off switch.
|
||
- Set PDF options: truncate descriptions, show/hide `Year Level`, Year Level
|
||
mode, and a custom Year Level value.
|
||
|
||
The Study Load page gets a button row — **Download PDF**, **CSV**, **Excel**,
|
||
**JSON**, and **Next Up** — next to the total-units line.
|
||
|
||
## Data & privacy
|
||
|
||
- Profile **passwords are encrypted at rest** with Web Crypto AES-GCM (256-bit).
|
||
The key lives in `browser.storage.local` so it survives restarts. This removes
|
||
the plaintext-password smell from storage; it is NOT strong protection against
|
||
an attacker who can read both the storage and the extension source — this
|
||
extension only talks to the school portal, never any third-party server.
|
||
- This is a personal-use helper for the university portal; use it only with your
|
||
own account.
|
||
|
||
## Development
|
||
|
||
See [`AGENTS.md`](AGENTS.md) for the repository layout, build model, and coding
|
||
conventions for this project.
|