A guest login is a full account with a clock on it
Mitchell, on the read-only version built earlier today: scratch it. He hands these to people he trusts and revokes them otherwise, so a console with half its tabs missing solved a problem he doesn't have. So the allow-list, the middleware check and every "not for a guest" branch in the UI are gone. What is left is the part that was the point: a throwaway account that expires by itself, is checked on every request, swept once a minute, and can be ended in one tap. A guest now gets the whole console on every machine, terminal included. Said once, since it is his call and he has made it: that means a guest has a root-capable shell on every host, and can make an account or a token of its own that outlives the guest login. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
8a7167bf03
commit
179f342a2c
+7
-7
@@ -20,9 +20,9 @@ export default function Users({ me }: { me: Me }) {
|
||||
|
||||
const GUEST_MINUTES = [15, 30, 60, 120, 480] as const
|
||||
|
||||
// A login to hand somebody so they can look at the console: it expires on its own, it can be
|
||||
// ended here at any moment, and it can only read. Making one is the only way to see its
|
||||
// password, so it is shown until dismissed rather than in a toast.
|
||||
// A login to hand somebody you are showing the console to: an ordinary account with a clock
|
||||
// on it, which expires on its own and can be ended here at any moment. Making one is the only
|
||||
// time its password is readable, so it is shown until dismissed rather than in a toast.
|
||||
function Guests() {
|
||||
const [list, setList] = useState<Guest[] | null>(null)
|
||||
const [minutes, setMinutes] = useState<number>(30)
|
||||
@@ -39,16 +39,16 @@ function Guests() {
|
||||
finally { setBusy(false) }
|
||||
}
|
||||
const revoke = async (g: Guest) => {
|
||||
if (!await askYes(`End the guest login ${g.name}? Whoever has it is signed out at once.`, 'Revoke')) return
|
||||
if (!await askYes(`End the guest login ${g.name}? Whoever has it is signed out at once, everywhere.`, 'Revoke')) return
|
||||
try { await api.revokeGuest(g.name); toast(`${g.name} revoked`); if (fresh?.name === g.name) setFresh(null); load() }
|
||||
catch (e) { toast(e instanceof Error ? e.message : 'failed', 'err') }
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<div className="dash-bar"><h2 className="section">Guest logins</h2><span className="spacer" /><span className="muted small">temporary, and can only look</span></div>
|
||||
<div className="dash-bar"><h2 className="section">Guest logins</h2><span className="spacer" /><span className="muted small">temporary, and can be revoked</span></div>
|
||||
<section className="card">
|
||||
{list === null && <Loading label="Loading…" />}
|
||||
{list?.length === 0 && <div className="empty">None. One lets somebody look around without an account.</div>}
|
||||
{list?.length === 0 && <div className="empty">None. One lets somebody in for a while without giving them an account.</div>}
|
||||
{list?.map((g) => {
|
||||
const left = new Date(g.expires).getTime() - Date.now()
|
||||
return (
|
||||
@@ -67,7 +67,7 @@ function Guests() {
|
||||
{GUEST_MINUTES.map((m) => <option key={m} value={m}>{m < 60 ? `${m} minutes` : `${m / 60} hour${m === 60 ? '' : 's'}`}</option>)}
|
||||
</select>
|
||||
</label>
|
||||
<div className="svc-actions"><Btn className="btn on" busy={busy} onClick={create}>Create guest login</Btn><span className="muted small">A guest sees the dashboard, containers, disks and hardware, read-only. No terminal, no files, no settings, nothing it can change. It stops working when the time is up, or when you revoke it.</span></div>
|
||||
<div className="svc-actions"><Btn className="btn on" busy={busy} onClick={create}>Create guest login</Btn><span className="muted small">A guest can do everything you can, on every machine — including the terminal — until the time is up or you revoke it. Give one out accordingly.</span></div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user