repos
/ orchard main

orchard

mirror

Every site I host, in one repo, along with the Cloudflare Tunnel and Caddy that front them. It's all Go, Vite, and SQLite, and it runs on a desktop at home with nothing listening on an inbound port.

blogbuncaddycloudflare-tunneldockergogolanghomelabhtml-templatemonorepoself-hostedseosqlitestatic-sitetypstuptime-monitoringviteweb-analytics

1.5 KB · 40 lines · HTML Raw History
 1{{ define "main" }}
 2<div class="container-fluid px-4 py-4">
 3  <div class="page-head">
 4    <div>
 5      <div class="auth-eyebrow">sessions</div>
 6      <h1 class="page-title">Signed in on {{ len .Sessions }}</h1>
 7    </div>
 8    <form method="POST" action="/sessions/revoke-others">
 9      <button type="submit" class="btn btn-outline-light btn-sm">Sign out everywhere else</button>
10    </form>
11  </div>
12
13  {{ template "alerts" . }}
14
15  <div class="panel">
16    {{ range .Sessions }}
17    <div class="session">
18      <span class="session-dot {{ if .Current }}is-current{{ end }}" aria-hidden="true"></span>
19      <div class="session-main">
20        <div class="session-where">
21          {{ if .City }}{{ .City }}, {{ end }}{{ if .Country }}{{ .Country }}{{ else }}Unknown location{{ end }}
22          {{ if .Current }}<span class="tag">this device</span>{{ end }}
23        </div>
24        <div class="session-meta">{{ browser .UA }} · {{ .IP }} · started {{ when .Created }} · seen {{ ago .LastSeen }}</div>
25      </div>
26      <form method="POST" action="/sessions/revoke">
27        <input type="hidden" name="id" value="{{ .ID }}">
28        <button type="submit" class="btn btn-sm btn-outline-light">Revoke</button>
29      </form>
30    </div>
31    {{ else }}
32    <p class="auth-hint mt-0 mb-0">No live sessions.</p>
33    {{ end }}
34  </div>
35
36  <p class="auth-hint">Every site checks this list on each request, so revoking one takes effect
37    everywhere at once rather than when a signed cookie happens to expire.</p>
38</div>
39{{ end }}