120 lines
6.6 KiB
Markdown
120 lines
6.6 KiB
Markdown
# Connect Desk
|
|
|
|
One window. Every Amazon Connect login signed in at the same time.
|
|
|
|
```sh
|
|
npm start
|
|
```
|
|
|
|
## The problem it solves
|
|
|
|
All your accounts live on the **same** Connect domain and differ only by login. A browser profile
|
|
holds exactly one session per domain, so signing in as account B silently evicts account A — which is
|
|
why you ended up with a separate Chrome profile per brand.
|
|
|
|
Connect Desk gives every account its **own session partition** (its own cookie jar). Ten accounts stay
|
|
signed in simultaneously, side by side, in one window. Sessions persist across restarts: sign in once
|
|
per account and stay in.
|
|
|
|
## Why it isn't a web page
|
|
|
|
Connect sends `Content-Security-Policy: frame-ancestors 'self'`, which forbids any external site from
|
|
embedding the CCP in an iframe. Only the AWS account that *owns* the instance can allowlist an origin,
|
|
and these instances are owned by Amazon, not by you — so a browser-based dashboard is permanently
|
|
blocked.
|
|
|
|
`frame-ancestors` restricts documents embedded **in a frame**. Here each account is a **top-level
|
|
view**, not a frame, so the rule doesn't apply. Verified: the CCP loads in each partition with zero CSP
|
|
errors, and no AWS permission of any kind is required.
|
|
|
|
## The two instances
|
|
|
|
Accounts live on one of two Amazon Connect instances (separate directories, separate logins):
|
|
|
|
| Marketplaces | Instance |
|
|
|---|---|
|
|
| US, CA | `amazon-product-support-a67d8h.my.connect.aws/agent-app-v2` |
|
|
| UK, DE, FR, IT, ES, NL, BE, SE | `amazon-product-support-q42kxm.my.connect.aws/agent-app-v2` |
|
|
|
|
Each account is assigned to an instance when you add it, shown as a **US** / **EU** chip on its row,
|
|
and changeable from the right-click menu. The URLs are stored in `accounts.json` under `instances`
|
|
if they ever need editing.
|
|
|
|
## Using it
|
|
|
|
- **Sidebar** lists your accounts. Click one to switch; the others keep running in the background and
|
|
keep receiving chats (background throttling is disabled for exactly this reason).
|
|
- **Incoming chat** is impossible to miss: a full-sidebar popup, a native OS notification (Mac and
|
|
Windows), a beep, taskbar/Dock flash, and the app switches to the ringing account. Click the popup
|
|
or the OS notification to jump there. This still works if you were looking at a different account.
|
|
- **+ Add account** first asks which instance (US/CA or UK/EU) the account belongs to, creates a new
|
|
isolated session, and drops you straight into naming it. Names also fill in automatically from the
|
|
signed-in agent; a manual rename always wins.
|
|
- **Right-click an account** for Rename, Set Available, Set Offline, instance selection, Reload, and
|
|
Remove (native OS menu).
|
|
- **Right-click in a chat** for spelling suggestions plus Cut / Copy / Paste. Spellcheck is on for
|
|
Connect composers (US + UK English).
|
|
- **All Available / All Offline** flip every signed-in account's status at once; a toast summarizes
|
|
which accounts changed and which need sign-in.
|
|
- **Sign in all / Sign out all** manage sessions in bulk. Sign-out ends each session server-side,
|
|
wipes the account's cookies, and **pauses auto-login for that account** (otherwise saved sign-ins
|
|
would immediately log it back in) — the dot goes grey with a "signed out" chip. Sign in all (or
|
|
per-account right-click → Sign in) resumes auto-login. This state survives app restarts.
|
|
|
|
## Credentials
|
|
|
|
By default none are stored — each account view shows Connect's own login page and the session cookie
|
|
stays inside that account's partition.
|
|
|
|
**Saved sign-ins (optional, off until you use it):** the "Saved sign-ins…" panel stores a username +
|
|
password per account so accounts log themselves in — at startup and again whenever a session expires.
|
|
|
|
Each row has **Save** (store this account's credentials) and **Sign in** (save, then log this one
|
|
account in immediately); the footer has **Save all**, **Sign in all**, and **Close**. Saving never
|
|
signs anything in on its own — the two are separate deliberate actions. "Sign in all" works through
|
|
the accounts **one at a time** with a gap between each, so a dozen simultaneous logins don't hit
|
|
Amazon's auth endpoint at once.
|
|
|
|
How it's protected:
|
|
|
|
- Passwords are encrypted with the OS keychain-backed key (`safeStorage`: macOS Keychain / Windows
|
|
DPAPI) and stored as ciphertext in `credentials.json`. Never plaintext; `accounts.json` never
|
|
contains secrets; the file cannot be decrypted on another computer or by another OS user.
|
|
- Credentials are released to an account's view **only** when that view is on the account's real
|
|
Amazon login host (`<alias>.my.connect.aws` / `<alias>.awsapps.com`) — enforced in the main
|
|
process, so no other page can request them.
|
|
- At most 2 automatic attempts per account per 5 minutes, so a wrong password can't be hammered into
|
|
an account lockout.
|
|
- "forget" in the panel deletes an account's saved sign-in; removing an account does too.
|
|
- If the form can't be filled, **nothing is submitted** and a toast says why — an empty submit would
|
|
burn an auth attempt and push the account toward a lockout.
|
|
|
|
The sign-in page is a GWT app whose username box is `<input type="username" id="wdc_username">` —
|
|
`username` is not a valid HTML input type, so the field is matched by name/id, never by type. The
|
|
page also carries a hidden `#wdc_organization` decoy and a hidden `#wdc_mfa` second password field;
|
|
both are deliberately skipped. If Amazon ever enables MFA on an account, auto sign-in cannot complete
|
|
it and you'll need to sign in manually.
|
|
|
|
The honest trade-off: anyone using your unlocked computer session can start the app and be signed in
|
|
— same as any password manager without a master password. Lock your machine.
|
|
|
|
## Known limits
|
|
|
|
- **One login per account, once.** AWS confirms there is no cross-account SSO without SAML federation,
|
|
which only the instance owner can configure. This app removes the *browser juggling*, not the logins.
|
|
- **Chat detection is best-effort.** It hooks Amazon Connect Streams (`window.connect`) in the CCP
|
|
iframe inside Agent Workspace, and falls back to scanning the page text if Streams never appears.
|
|
The fallback can break if Amazon restyles the CCP. Switching accounts and the sessions themselves
|
|
are unaffected either way.
|
|
- Ten-plus live CCPs is genuinely heavy. If it drags, remove accounts you aren't covering that day.
|
|
|
|
## Layout
|
|
|
|
| File | Role |
|
|
|---|---|
|
|
| `main.js` | Window, one partitioned `WebContentsView` per account, alerts, notifications |
|
|
| `probe.js` | Main-world Streams probe (injected into the CCP page and its iframes) |
|
|
| `preload.js` | Injected per account — relays contacts, status commands, login autofill |
|
|
| `ui-preload.js` | IPC bridge for the sidebar |
|
|
| `ui/` | Sidebar: account list, alerts, controls |
|