aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/src/meshbay_hub/static
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/static')
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/auth-page.js9
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/keyderive.js6
2 files changed, 13 insertions, 2 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/auth-page.js b/packages/meshbay-hub/src/meshbay_hub/static/auth-page.js
index df08bc4..4c00137 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/auth-page.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/auth-page.js
@@ -237,8 +237,11 @@ export function RegisterPage() {
const rk = window.MeshBayKeys.generateRecoveryKey();
// `name` (trimmed), not the raw field: the hub stores the trimmed
// username and every key derivation must fold in the same string.
+ // `captcha.token` rides along — the submit button is already disabled
+ // until it is set when a captcha is configured (see the form below).
await window.MeshBayKeys.registerUser(
- name, email, password, emailRecovery ? rk.mnemonic : null);
+ name, email, password, emailRecovery ? rk.mnemonic : null,
+ captcha.token);
setRecoveryMnemonic(rk.mnemonic);
session.recoveryKey =
await window.MeshBayKeys.deriveRecoveryKey(rk.mnemonic, name);
@@ -257,6 +260,10 @@ export function RegisterPage() {
}
} catch (err) {
setError(err.message);
+ // A reCAPTCHA token is single-use: after a failed attempt (name taken,
+ // e-mail in use…) it is spent, so clear it and make the user solve a
+ // fresh one before the next try. No-op when no captcha is configured.
+ captcha.reset();
} finally {
setLoading(false);
}
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/keyderive.js b/packages/meshbay-hub/src/meshbay_hub/static/keyderive.js
index 0aaa6a5..a540a94 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/keyderive.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/keyderive.js
@@ -276,7 +276,7 @@ async function decryptBundle(bundleB64, password, username) {
*
* Returns the raw private keys for immediate use after registration.
*/
-async function registerUser(username, email, password, recoveryMnemonic) {
+async function registerUser(username, email, password, recoveryMnemonic, captchaToken) {
// No keypair here any more. Identity keys are per node: one is generated the
// first time this account joins a given node, encrypted under the passphrase,
// and left with that node. So an operator who cracks what sits on their own
@@ -291,6 +291,10 @@ async function registerUser(username, email, password, recoveryMnemonic) {
// appends it to the verification e-mail and stores it nowhere
// (docs/auth-confirm.md §4.4). Omitted when they chose to save it themselves.
if (recoveryMnemonic) payload.recovery_key = recoveryMnemonic;
+ // reCAPTCHA response, when the hub has a captcha configured. The widget lives
+ // in RegisterPage (auth-page.js); this function just forwards its token. A
+ // hub with no captcha configured sends nothing and the server does not check.
+ if (captchaToken) payload.captcha_token = captchaToken;
const resp = await hubCall('/v1/users/register', {
method: 'POST',