hop2 0.11.15 → 0.11.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -0
- package/hay/apps/web/src/utils/voiceHold.ts +11 -0
- package/hay-web/assets/digest-archive.json +671 -695
- package/hay-web/assets/{index-Bcl-2CbE.js → index-B_Y3BI1G.js} +3 -3
- package/hay-web/assets/{index-Bcl-2CbE.js.map → index-B_Y3BI1G.js.map} +1 -1
- package/hay-web/index.html +1 -1
- package/hop +838 -1
- package/lib/mailer.js +199 -0
- package/lib/registration.js +337 -0
- package/package.json +1 -1
- package/tests/mailer.unit.test.cjs +160 -0
- package/tests/registration.integration.test.cjs +325 -0
- package/tests/registration.unit.test.cjs +170 -0
package/README.md
CHANGED
|
@@ -320,6 +320,44 @@ hop client ./credentials.json
|
|
|
320
320
|
|
|
321
321
|
First run prompts for password setup and TOTP enrollment, then the user logs in at their assigned URL such as `https://alice.hop.yourdomain.com`.
|
|
322
322
|
|
|
323
|
+
### Self-service signup (optional)
|
|
324
|
+
|
|
325
|
+
Instead of adding every user by hand, the landing host can serve a public
|
|
326
|
+
signup page. Visitors ask for a subdomain, confirm an email address on a
|
|
327
|
+
domain you nominate, and wait for you to approve — approval runs the same
|
|
328
|
+
`hop user add` + `hop user export` provisioning as the manual flow, then
|
|
329
|
+
emails them a one-time link to collect their credentials.
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
hop mail setup # SMTP (a Gmail App Password works)
|
|
333
|
+
hop registration admin jianzhou # reserve your own subdomain
|
|
334
|
+
hop registration domain uchicago.edu
|
|
335
|
+
hop registration enable
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
Then review requests as they arrive:
|
|
339
|
+
|
|
340
|
+
```bash
|
|
341
|
+
hop user pending
|
|
342
|
+
hop user approve alice
|
|
343
|
+
hop user reject bob "please use your own name"
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
Notes:
|
|
347
|
+
|
|
348
|
+
- Off by default. Enabling it makes the bare hostname public; your own
|
|
349
|
+
browser keeps working while its session cookie is valid, and
|
|
350
|
+
`https://<landing-host>/signin` always reaches the login page.
|
|
351
|
+
- Nothing runs on your machine for them. A registrant gets a Cloudflare
|
|
352
|
+
tunnel and a DNS record; hop itself runs on *their* computer, with their
|
|
353
|
+
own password and TOTP.
|
|
354
|
+
- The tunnel lives in **your** Cloudflare account and the subdomain is under
|
|
355
|
+
**your** domain, so an approved user can serve anything they like at
|
|
356
|
+
`their-name.your-domain`. Approve people you would vouch for, and use
|
|
357
|
+
`hop user remove <name>` to revoke (delete the DNS record by hand).
|
|
358
|
+
- Registrations live in `~/.hop2/.registrations.json` (0600). Verification
|
|
359
|
+
and claim links are stored only as hashes.
|
|
360
|
+
|
|
323
361
|
### Security
|
|
324
362
|
|
|
325
363
|
- Password + TOTP is supported; password is required for custom domains
|
|
@@ -116,6 +116,17 @@ export const createVoiceHold = (opts: VoiceHoldOptions) => {
|
|
|
116
116
|
* undefined — not a voice-relevant event; continue with other branches.
|
|
117
117
|
*/
|
|
118
118
|
const handleKey = (ev: { type: string; code: string; key: string; repeat?: boolean; metaKey?: boolean; ctrlKey?: boolean; altKey?: boolean; shiftKey?: boolean }): boolean | undefined => {
|
|
119
|
+
// Return, mid-dictation, ENDS it and keeps the words (Jian). Without
|
|
120
|
+
// this the Enter fell through to the terminal while the recogniser was
|
|
121
|
+
// still running: a bare newline hit the composer, and the transcript
|
|
122
|
+
// landed after it — the one key you would reach for to finish a thought
|
|
123
|
+
// was the one that split it in half. Swallowed rather than passed on, so
|
|
124
|
+
// this inserts and does not also submit; a second Return sends it.
|
|
125
|
+
if (active && ev.type === "keydown" && (ev.key === "Enter" || ev.code === "Enter"
|
|
126
|
+
|| ev.code === "NumpadEnter")) {
|
|
127
|
+
stop();
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
119
130
|
if (ev.code === "Space" && !ev.metaKey && !ev.ctrlKey && !ev.altKey && !ev.shiftKey
|
|
120
131
|
&& !!speechRecognitionCtor() && (active || opts.eligible())) {
|
|
121
132
|
if (ev.type === "keydown") {
|