# Aibibu GADS on ws

GADS Hub and Provider are subcommands of the same Go repository. This deployment
updates both to upstream **v6.1.0**, commit `d8abfc3`. The Hub runs on ws; the Mac
Provider owns the USB Android device. Phone WorkTool remains installed unchanged.

Open **https://staff.aibibu.com/** and click **设备中控 GADS**. The application
launch URL is **https://gads.aibibu.com/enterprise/login**; the public root also
offers that enterprise login. The original operations portal remains independent.

## Authentication

`enterprise-oidc.patch` adds confidential OIDC authorization code login with PKCE
S256, state bound to an HttpOnly browser cookie, nonce, RS256 issuer/audience
verification, and a one-use 60-second native login ticket. It does not collect
staff passwords. The stock GADS 6.1.0 UI is unchanged; an adapter submits the
ticket through its existing visible login form. Its form contract is version
dependent, so verify browser login when changing the UI release.

After login, an Aibibu outer page hosts the unchanged native UI in a same-origin
frame. It observes the bound native session without extending inactivity time,
and returns to the enterprise entry after native logout or expiry. Repeated
staff launches retain a valid native session; a missing or expired browser JWT
uses the one-use ticket. Only explicitly allowed UI document navigations are
adapted; JSON APIs, WebSocket upgrades and Provider requests keep their routes.

Initial admission is the existing owner's stable OIDC subject **and** membership
in the dedicated `aibibu-gads-admin` group. Email does not link accounts or grant
roles. Other staff are currently denied; add an explicit role/workspace mapping
before extending access. Removing IdP membership prevents new logins; existing
GADS sessions must also be revoked or allowed to expire. Sessions have an 8-hour
absolute limit and a 1-hour inactivity timeout; restarting the Hub ends them.
Native username/password login is disabled while staff OIDC is configured.

`provision_staff.py` reuses the existing staff identity provisioner's durable,
idempotent ownership checks and access-denial verification. Its API target is
the private commerce guest `10.90.0.20:19000`. Run it on ws with an approved
private configuration file and the existing root-only IdP administrator token.
It creates only the isolated GADS client, application, group and binding; it
does not reset existing user passwords or memberships. It rejects an unowned
object with a matching name. Client secrets and stable owner configuration stay
in root-only server files, never in this repository.

## Build from source

Clone https://github.com/shamanec/GADS and check out `v6.1.0`. Apply
`android-manual-usb.patch`, then `enterprise-oidc.patch`. Use the upstream
`ui-files.zip` and official resources for that release unchanged. Populate
`hub-ui/build` with the official UI; those separately licensed files and the APK
must not be committed here.

```sh
git apply /path/to/ops/gads/android-manual-usb.patch
git apply /path/to/ops/gads/enterprise-oidc.patch
go run github.com/swaggo/swag/cmd/swag@v1.16.4 init -g hub/hub.go -o docs
go test -timeout 90s ./provider/devices ./hub/router ./common/db
go test -race -timeout 90s ./hub/auth -run TestEnterprise
go test -timeout 90s ./hub/auth -run 'Test(Touch|Delete|Sweep|AuthMiddleware|GenerateJWT|ValidateJWT|Session)'
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -tags ui \
  -ldflags '-X main.AppVersion=v6.1.0-aibibu-staff' -o GADS .
go build -tags ui -ldflags '-X main.AppVersion=v6.1.0-aibibu-usb' -o GADS-mac .
```

The upstream full test suite includes MongoDB integration tests requiring a
separate test database on localhost:27017. The scoped checks above pass without
pointing those integration tests at production.

## Runtime topology

| Component | Location | Address |
| --- | --- | --- |
| Hub systemd service | ws `/opt/aibibu/gads-hub` | `127.0.0.1:18100` |
| MongoDB, pinned Mongo 6.0 image | ws Docker | `127.0.0.1:27119` |
| Mac Android Provider | macOS LaunchAgent | `127.0.0.1:18102` |
| Public browser entry | existing Caddy | HTTPS 443 |

`compose.yaml` uses a dedicated `10.250.80.0/28` Docker network. Do not prune
existing Docker networks to resolve address-pool allocation errors. MongoDB
data persists under `/opt/aibibu/gads-hub/mongo`.

The Mac LaunchAgent `cn.aibibu.gads.ws-tunnel` establishes the trusted `ws` SSH
connection with strict host-key checking and forwards:

* Mac `18100` and legacy `10000` to ws Hub `18100`;
* Mac `27019` to ws MongoDB `27119`;
* ws `18102` back to Mac Provider `18102`.

The Provider `cn.aibibu.gads.local-android` uses nickname `local-android`, MongoDB
`127.0.0.1:27019`, Hub `http://127.0.0.1:18100` and the flags:

```text
--android-manual-apk-install --android-usb-only --android-preserve-ime
```

These preserve the manually installed helper APK, USB-only ADB, and the existing
keyboard. The jobs are installed in `~/Library/LaunchAgents` and start on Mac
sign-in. Keep the Mac awake and the phone connected for availability. The prior
Mac Hub is stopped. Its existing local MongoDB on 27018 is unused by the new
deployment and retained as the original data, not a newly generated backup.

## Server configuration

Install `aibibu-gads-hub.service` and create mode-0600 `staff.env` on ws:

```text
GADS_STAFF_ORIGIN=https://gads.aibibu.com
GADS_STAFF_ISSUER=https://staff.aibibu.com/application/o/gads/
GADS_STAFF_CLIENT_ID=aibibu-gads
GADS_STAFF_OWNER_SUBJECT=<existing approved owner UUID>
GADS_STAFF_GROUP=aibibu-gads-admin
GADS_STAFF_SECRET_FILE=/opt/aibibu/gads-hub/staff-client-secret.private
```

The secret file is mode 0400, owned by `aibibu-gads`. The service runs as that
non-login user with `ProtectSystem=strict`, `ProtectHome=true`, and writes only
its UI extraction directory. MongoDB and the reverse Provider tunnel bind to
loopback. `gads.caddy` publishes only the Hub and explicitly denies public
`/provider-update` requests. Import it into the existing Caddyfile, validate the
candidate config, then reload; do not replace other site blocks. Hub request
logging omits URLs to avoid retaining OIDC codes and websocket JWTs.

## Phone limitation

The tested phone identifies as **Redmi 8, Android 10**. Live video was verified,
but input failed with `INJECT_EVENTS` permission denial. Xiaomi's separate
“USB debugging (Security settings)” requirement remains a phone-side action.
GADS does not require a SIM for USB control over a Wi-Fi-connected phone. A SIM
recognition fault should be diagnosed by cross-testing cards and the slot;
rooting is not a remedy for a physical slot fault.

This deployment does not claim acceptance of the WorkTool PDF/download/upload
business flow. That remains a separate phone test once input is enabled.

## Acceptance, 2026-10-06

Hub and Mac Provider are updated to upstream v6.1.0. The deployed Hub includes
the enterprise changes through GADS source commit `43c8f46`; its SHA256 is
`953083b2fab0c395728b40209b5cb84c077fd8ca49d498c7b31774022329d888`.

Verified in the real browser: valid HTTPS, the staff dashboard launch, enterprise
SSO without a separate GADS password, repeated launch, recovery after Hub
restart, native Apps navigation, and native logout returning to the enterprise
entry. Earlier in the same acceptance run the USB phone appeared available and
displayed live video. The phone subsequently disconnected from USB; the final
remote input test awaits reconnection and the Xiaomi security-debugging switch.

Scoped authentication race tests and router/database tests pass. Applying both
published patches to v6.1.0 reproduces all 14 changed source files byte for byte.
Caddy configuration validates; the Hub service is active and enabled, MongoDB
is healthy, and Hub/Provider/Mongo ports listen only on loopback. Valid-TLS
origin requests return 404 for public `/provider-update`, 401 for anonymous
device access, and 200 for the source offer. The source directory contains only
the public index, README and patches; `/source/staff.env` returns 404.

## Licensing and source

The public `/source/` page offers the source instructions and complete patches
without requiring access to the private Aibibu GitHub repository.

Upstream GADS Go code and these modifications are **AGPL-3.0**; see the upstream
LICENSE and the complete source at tag v6.1.0 plus these two patches. GADS UI and
helper assets have separate upstream terms. They are obtained from the official
release and used unchanged; this repository contains only our source patches
and deployment configuration, not those proprietary artifacts or credentials.
