Add the sign-up page and the first-run checklist
Second half of #7. The API could create accounts from invite links since the last change; this is the part somebody can actually use. /signup is the one route that works without a session. It asks the server what it may offer before showing anything: an invite link that is good names the team it leads to, a link that is not says so before somebody picks a password rather than after, and an invite-only server with no link says that instead of presenting a form it will refuse. The login card only offers "create one" when sign-up is open, so the door nobody can walk through is not advertised. Signing up signs you in and lands on the queue, because the alternative is a form saying "now go and log in" about the credential just chosen. The checklist is the other half. Four things have to be true before an alert reaches a phone -- a notification topic, somebody on the rota, an alert source, and an alert that has actually arrived -- and on a fresh install none of them are. It sits above the queue until they are. It is computed from the data rather than from stored progress: a topic is set or it is not, an integration exists or it does not. That means it cannot claim a step is done when it is not, and it comes back by itself if somebody deletes their integration a month later. The only stored state is the dismissal, which is per user and not per browser -- finishing on a laptop should not leave the phone nagging. The topic step is the only one the checklist can finish itself, and the only proof that counts is a phone buzzing, so there is a test push. POST /api/me/notify/test publishes directly rather than through the outbox, which requires an incident this deliberately does not have. Its failure is the useful part: a wrong topic, a rejected token and an ntfy that is down all look identical from the phone, which is silence, so the error comes back to the browser instead. Verified against a live server with a real ntfy stand-in, the whole path: an owner mints an invite, the sign-up page reports it valid and names the team, the invitee signs up and is signed in as a member of that team, the checklist's four questions answer correctly on a fresh install, a test push is refused with no topic and delivered with one -- "PAGED terdut-owner | terdut test" -- and the dismissal survives a reload. Claude-Session: https://claude.ai/code/session_01RHPj4ggeFdEjKKfm4SHbD7
This commit is contained in:
@@ -37,6 +37,37 @@
|
||||
<button class="btn btn-primary btn-block" type="submit">Sign in</button>
|
||||
<p class="login-hint">No password yet? Ask an admin to set one, or run
|
||||
<code>PUT /api/users/{id}/password</code> with your API key.</p>
|
||||
<p class="login-hint" id="signup-link" hidden>
|
||||
No account? <a href="/signup">Create one</a>.</p>
|
||||
</form>
|
||||
|
||||
<!-- Sign-up. Shown instead of the login card at /signup, and only offers
|
||||
what the server allows: an invite link, or open sign-up. -->
|
||||
<form id="signup-form" class="login-card" autocomplete="on" hidden>
|
||||
<div class="login-brand">
|
||||
<img src="/icon.svg" alt="" width="40" height="40">
|
||||
<h1>terdut</h1>
|
||||
</div>
|
||||
<p class="signup-intro" id="signup-intro"></p>
|
||||
<label>
|
||||
<span>Username</span>
|
||||
<input name="username" autocomplete="username" autocapitalize="none" spellcheck="false" required>
|
||||
</label>
|
||||
<label>
|
||||
<span>Email</span>
|
||||
<input name="email" type="email" autocomplete="email" required>
|
||||
</label>
|
||||
<label>
|
||||
<span>Password</span>
|
||||
<input name="password" type="password" autocomplete="new-password" minlength="10" required>
|
||||
</label>
|
||||
<label id="signup-team-label" hidden>
|
||||
<span>Team name</span>
|
||||
<input name="team_name" autocomplete="off">
|
||||
</label>
|
||||
<p class="form-error" role="alert" hidden></p>
|
||||
<button class="btn btn-primary btn-block" type="submit">Create account</button>
|
||||
<p class="login-hint">Already have one? <a href="/">Sign in</a>.</p>
|
||||
</form>
|
||||
</main>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user