# 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 (`.my.connect.aws` / `.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 `` — `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 |