{{define "setup-page"}} Privatae bastion — set this machine up

Set this machine up

Pairing, a second factor, folders, the anchor and the owner name. Back to what this machine is doing.

{{template "setup" .}}
{{end}} {{define "setup"}} {{if .Flash}}
{{.Flash}}
{{end}} {{if .ReadError}}
This machine's pairing records cannot be read: {{.ReadError}}. The panels below cannot be trusted until that is fixed.
{{end}} {{/* The state first, because every panel below reads differently depending on it — an anchor on a local box means nothing, and a folder needs a host. */}}
Mode
{{.Mode}}
Anchor
{{if .AnchorHost}}
{{.AnchorHost}}{{if .AnchorOwner}} (owner “{{.AnchorOwner}}”){{end}}
{{else}}
none{{if .AnchorRequired}} required{{end}}
{{end}}
Owner
{{if .Owner}}{{.Owner}}{{else}}not claimed{{end}}
{{if .Hosts}}
{{range .Hosts}}
{{.Name}}
{{.State}} {{if .IsAnchor}}anchor{{end}} {{if .Active}} {{if .Serving}}serving {{else}}not answering{{end}} {{end}} {{if .Stepup}}second factor {{else}}no second factor{{end}}
{{end}}
{{end}}
{{/* ── 1. pair ───────────────────────────────────────────────────────────── */}}

Pair a host

The token comes from your host's “Set up a bastion”. It is used once.

Pairing adds a host; it never replaces one. On an anchored machine a new host is written pending and starts nothing until the anchor host approves it. Nothing here needs the bastion restarted.
{{/* ── 2. second factor ──────────────────────────────────────────────────── */}}

A second factor on this machine

Once a factor is enrolled, your host can only reach a folder or move files here after you approve the request on this machine. Your host never sees the code.

{{if .Enrol}}
{{/* The handle addresses the enrolment on the server. The secret is never in this page: it is in the pixels. */}} QR code for the second factor being enrolled on this machine

Point your authenticator app at the square. It will appear as Privatae NAC, for {{.Enrol.Host}}.

Nothing is written to this machine until that code matches.

{{else if .Servable}} {{/* .Servable, not .Hosts: a pending pairing gets no state on this machine at all, not even a directory (run.go:311), and a factor for it would gate ops it has no lanes to run. */}}
Replacing a factor stops the authenticator enrolled now from working.
{{else if .Hosts}}

No host here has its lanes open, and a second factor gates ops a pairing without lanes cannot run. Nothing is created for a pending host on this machine until the anchor host approves it.

{{else}}

Pair a host first — a factor is enrolled per host.

{{end}}
{{/* ── 3. folders ────────────────────────────────────────────────────────── */}}

Add a folder to your network

{{if .Servable}}

Your files stay on this machine. Your host keeps only the index, and the draft does nothing until you approve it there.

{{/* A browser cannot open a native folder picker without the user choosing a folder in it, and what it hands back is a file list, not a path this machine can name. So: a typed path, checked against the real filesystem as it is typed. */}}
{{if .Check}}{{template "folder-check" .}}{{end}}
{{if gt (len .Servable) 1}} {{else}} {{range .Servable}}

Proposed to {{.Name}}.

{{end}} {{end}}
{{else}}

No host on this machine has its lanes open, so there is nothing to propose a folder to yet.

{{end}}
{{/* ── 4. the anchor ─────────────────────────────────────────────────────── */}}

Which host holds the anchor

The anchor host is the one that approves every other host paired here. It is a choice among the hosts this machine already serves.

{{if .Hosts}}
{{range .Hosts}} {{end}}
{{else}}

Pair a host first — the anchor is one of them.

{{end}}
{{if .Cmd}}{{template "anchor-cmd" .}}{{end}}
This page will not do it. Claiming the anchor needs machine authority — root on this box is what stands behind it — and it decides who approves every pairing made here from now on. A page you are signed into for twelve hours is not the right thing to hang that on, so the choice is here and the act stays at a terminal.
{{/* ── 5. the owner name ─────────────────────────────────────────────────── */}}

Who owns this machine

A plain name, shown on this machine's card on every host it serves. It is optional and it grants nothing.

{{if .Cmd}}{{template "owner-cmd" .}}{{end}}
Root-gated for the same reason as the anchor: there is no authority above this box to ask, so the ability to run root here is what the name stands on.
{{end}} {{/* ── fragments swapped on their own, so typing does not lose focus ─────── */}} {{define "folder-check"}} {{with .Check}}

{{.Line}} {{if .Resolved}}
{{.Resolved}}{{end}} {{if .Note}}
{{.Note}}{{end}}

{{end}} {{end}} {{define "stepup-key"}} {{if and .Enrol .Enrol.Key}}

Enter this key by hand, then type a code from the app:

{{.Enrol.Key}}

It is a secret. It is on screen because you asked for it, and it is gone from this page as soon as you reload.

{{else}}

That enrolment has expired — start it again.

{{end}} {{end}} {{define "anchor-cmd"}} {{with .Cmd}}
{{if .Command}}

{{.Command}}

{{end}} {{if .How}}

{{.How}}

{{end}} {{if .Why}}

{{.Why}}

{{end}}
{{end}} {{end}} {{define "owner-cmd"}} {{with .Cmd}}
{{if .Command}}

{{.Command}}

{{end}} {{if .How}}

{{.How}}

{{end}} {{if .Why}}

{{.Why}}

{{end}}
{{end}} {{end}}