# swb login

Signs in where a console signs in, and writes the credentials every other
command reads.

## Synopsis

```
usage: swb login <console-url>
```

## Arguments and flags

| Argument | Takes | Default |
|---|---|---|
| `<console-url>` | The console's URL. Any URL on the console's origin will do — `https://console.example` and `https://console.example/#/apps` name the same origin. Required. | — |
| `--help`, `-h` | Prints the command's help and exits. | off |

## What it does

1. Reads `<console-url>/config.json`, the document the console itself reads
   at start-up, for the control endpoint and the Application that console
   signs in with — its App ID and its own host.
2. Asks that Application's own host for a device code (RFC 8628) and prints
   the code beside the console's activation address,
   `<console-url>/#/activate?user_code=<code>`. The browser is opened there
   when this machine has one; the address is printed either way, so a machine
   with no browser signs in by the person approving the code somewhere else.
3. Waits while the person approves, then writes
   `~/.config/swb/credentials.json` (mode 0600): the console's origin, the
   control endpoint, the Frontegg coordinates and the tokens.

Nothing listens on a port and no redirect is registered on the Application:
the approval happens wherever the person already has a console session, so
`swb login` works the same over SSH, in a container and in an agent's
sandbox as it does on a laptop.

The token names the tenant the approving console session held. To work in
another tenant, switch tenant in the console and approve a new code — one
credential is one tenant, as a console session is.

## What it prints

```
Your code is WDLN-ABCD. Approve it at:
https://console.switchboard.example/#/activate?user_code=WDLN-ABCD
Opening the browser there; if it does not open, visit the address above.
Signed in to https://console.switchboard.example; credentials written to /Users/you/.config/swb/credentials.json
```

If Frontegg issues no refresh token, it adds `No refresh token was issued;
sign in again when the access token expires.`

`login` takes no `--json`: it prints what it did, not a record.

## The operation and the permission

None. `swb login` calls no control-plane operation — it reads the console's
own `config.json` and talks to Frontegg. Any person with a Frontegg account
in that environment can run it; what their token may then do is decided per
operation.

## The same act in the console

Opening the console and signing in. `swb login` signs in on the same
Application, for the same person, and the token it receives is the console's
token.

## Refusals and exit status

Exit status is 0 on success and 1 on every refusal below.

| Refusal | When |
|---|---|
| `swb login takes the console's URL` | No URL was given. |
| `"<url>" is not a URL` / `"<url>" is not an http or https URL` | The argument is not an address `swb` can fetch. |
| `<url>/config.json is not being served (404) — is this the console's address?` | The origin serves no console document. |
| `<url>/config.json did not parse as JSON` / `is missing "control", the control plane's endpoint` | The console's document is not the one `swb` expects. |
| `the configuration names no "frontegg.appId"` / `no "frontegg.appHost"` | The console's document names no Application, or no host for it. Nothing falls back to the environment's client id. |
| `<host> advertises no device_authorization_endpoint` | The Application's own host does not offer the device grant. |
| `the code expired before it was approved` | Nobody approved the code inside its lifetime. |
| `the token request was refused … access_denied` | The person denied the code on the activation page. |
| `SWB_PERSONAL_TOKEN is set, so this run already acts as the person who created that token` | A run holding a personal token needs no sign-in, and does not get one. |

## Example

```console
$ swb login https://console.switchboard.example
Your code is WDLN-ABCD. Approve it at:
https://console.switchboard.example/#/activate?user_code=WDLN-ABCD
Opening the browser there; if it does not open, visit the address above.
Signed in to https://console.switchboard.example; credentials written to /Users/you/.config/swb/credentials.json
```
