66 lines
5.9 KiB
Markdown
66 lines
5.9 KiB
Markdown
# Capsule
|
|
|
|
Desktop companion for [The Tempus Project](https://TheTempusProject.com). Point it at a TTP site, sign in with a username and password or paste an API token, and work against that install from the desktop.
|
|
|
|
This replaces the old `TempusToolkit` Electron stub. The keepers were the login ? stored-token ? home flow. Hardcoded LAN URLs, `nodeIntegration`, and the leftover WoW-folder picker did not come along.
|
|
|
|
## Run it
|
|
|
|
From this folder (Windows source checkout is fine ? Capsule is Node, not PHP):
|
|
|
|
```bash
|
|
npm install
|
|
npm run dev
|
|
```
|
|
|
|
`npm start` previews a production build. There is no local TTP site on the Windows checkout. Login needs a reachable install (typically the Ubuntu host) with `api/apiAccessPersonal` on for user-token calls.
|
|
|
|
## Package and update
|
|
|
|
Set `CAPSULE_DEFAULT_SITE=https://ttp.joeykimsey.com` in `.env` (copy `.env.example`) or in the shell before `npm run dev` or a build. This non-secret setting is embedded at build time and defaults to the demo URL above. It prefills both sign-in forms and supplies the logged-out logo; a saved or connected site takes precedence. It does not select the update feed or connect/sign in automatically. Rebuild installed packages after changing it.
|
|
|
|
For automatic-update testing without a signing certificate, use the separate `dist:test-bootstrap` and `dist:test` commands described in [Free automatic-update testing](docs/releases.md#free-automatic-update-testing). Original Local installations require one bootstrap installation; subsequent test updates use the in-app updater.
|
|
|
|
`npm run dist:win` builds a per-user Windows x64 installer at `dist/local/Capsule-0.1.2-x64-Setup.exe` (the filename follows the package version). This unsigned local build installs as **Capsule**. It retains the previous Capsule Local installation identity and session directory for upgrades; automatic updates remain disabled. Close the existing app and run the new installer under the same Windows account to apply the rename. `npm run pack:win` produces an unpacked app for inspection. `npm test` checks updater behavior and release validation.
|
|
|
|
Public builds use `npm run release:win`, require a permanent HTTPS update URL and Windows signing identity, and go to `dist/release/`. Update-enabled builds check automatically 15 seconds after launch and every four hours. An available update shows a blue **Download update** banner; downloading requires that click. After verification, the blue banner offers **Restart to update**, including before sign-in. Closing the app normally does not install an update. A closed app checks after its next launch.
|
|
|
|
Read [Packaging and releases](docs/releases.md) for signing variables, hosting requirements, the release automation entry point, and the installed-upgrade acceptance test. No public feed or signing credentials are configured in this checkout.
|
|
|
|
## How auth works
|
|
|
|
All HTTP runs in the **main process** (`net.fetch`, so the PHP session cookie sticks). The renderer never sees the token and never talks to the site directly, so TTP's same-origin CORS policy does not apply. POSTs send `X-CSRF-Token` (and POST `token`) after a GET harvests `csrf`.
|
|
|
|
| Action | Endpoint | Notes |
|
|
|--------|----------|-------|
|
|
| Password sign-in | `POST /api/login` | `username` + `password`, `application/x-www-form-urlencoded`. Same limiter as browser login. CSRF from `GET /api/login`. No Turnstile. MFA accounts return `{ mfa }` instead of a token. |
|
|
| MFA code / method | `POST /api/login/mfa/{loginCode}` | `auth_code` or `mfaMethodSelect`. `loginCode` stays in the main process. |
|
|
| MFA reset | `POST /api/login/mfa/{loginCode}/reset` | Clears the chosen method so the picker shows again. |
|
|
| Confirm identity | `GET /api/profile` | Bearer user token. Also used to hydrate username after login. `GET /api/users/find/{username}` remains available. |
|
|
| Workspace | `GET /api/notifications`, `GET /api/messages`, `GET /api/messages/recent` | First inbox page plus the header dropdown after connect. Plugin-off responses show as unavailable. |
|
|
| Search | `GET /api/search` | Header search. `q`, `resource`, `page`. |
|
|
| Profile save | `POST /api/profile/update` | Avatar and prefs. |
|
|
| Mail / notices | `POST /api/messages/?`, `POST /api/notifications/?` | View, reply, create, read, unread, delete. |
|
|
| Contact / bugs | `GET` / `POST /api/contact`, `GET` / `POST /api/bugreport` | Footer pages when those plugins are enabled, accepting, and allowed. Hashing in while they are off shows a not-accepting notice. |
|
|
| Existing token | Admin ? Tokens | Personal or app token. A user token hydrates the workspace; an app token can connect but cannot call the user API. |
|
|
|
|
The token is stored under Electron `userData` (`session.json`). `safeStorage` encrypts it when the OS keychain is available. MFA `loginCode` is not stored.
|
|
|
|
App-facing pairing notes live with the PHP app: `repos/ttp/docs/capsule.md`.
|
|
|
|
## Layout
|
|
|
|
| Path | Job |
|
|
|------|-----|
|
|
| `src/main/` | Window, session file, TTP HTTP, IPC |
|
|
| `src/preload/` | `window.capsule` bridge |
|
|
| `src/renderer/` | Login, MFA, TTP-styled chrome, and live API views |
|
|
|
|
The logged-in header follows the public TTP shell (`text-bg-dark`, FA 6.7.1, Bootstrap 5.3). Search stays visible and centered. Account is a top-right dropdown like the site. Notifications and messages are the same bell / envelope menus. Profile edit covers User CP preferences except email, password, and phone ? those open `{site}/usercp/?`. Lists load from the site API after sign-in. The footer matches TTP copyright and social icons. Above that: Contact Us on the left (Contact and Report a Bug only when the site is accepting them), dark-mode in the middle, More Info (Privacy Policy, Terms of Service) on the right. No subscribe box. Privacy and terms open the connected site; contact and bug reports stay in-app.
|
|
|
|
## Remote
|
|
|
|
This checkout starts with no git remote. When the repo exists on the project host:
|
|
|
|
`ssh://git@git.thetempusproject.com:2222/the-tempus-project/capsule.git`
|