import {
html, useState, useEffect, useRef, useCallback,
} from './vendor/htm-preact.js';
import { t } from './i18n.js';
import {
hubFetch, navigate, session, HUB, loadAuth, _storeRecoveryKey,
} from './hub-client.js';
import * as platform from './platform.js';
import { Icon } from './icon.js';
import { loadPending } from './invite-link.js';
const PASSWORD_MIN_BITS = 60;
const PASSWORD_MIN_LEN = 12;
// The hub's USERNAME_MIN_LEN (api/users.py), checked here so the refusal comes
// before a passphrase derivation rather than after it.
const USERNAME_MIN_LEN = 8;
// ── Passphrase field ─────────────────────────────────────────────────────────
//
// A passphrase this long is mistyped often enough that checking it is worth a
// control, and the alternative people reach for otherwise is typing it into
// the username box to read it back. The button is out of the tab order
// (`tabindex="-1"`): everyone who is not reaching for it would pay a keystroke
// between the passphrase and the submit button, and it does nothing a keyboard
// user cannot do by other means. `type="button"` matters — a bare button in a
// form submits it, which here would try to sign in on the first click.
function PasswordInput({
value, onInput, placeholder, autocomplete,
minlength = null, autofocus = false,
}) {
const [shown, setShown] = useState(false);
const label = t(shown ? 'login.hide_password' : 'login.show_password');
return html`
`;
}
// What MeshBay is, beside the sign-in form. Browser only: inside the desktop
// application the reader has already downloaded it, and the links point at the
// project's own site rather than at whichever hub the application is set to.
//
// Written for somebody who is not in IT: what it does for them first, how it
// works in three steps, and privacy said once, plainly. Every sentence is held
// to MESHBAY_DESIGN.md §2.3 — "your content never passes through meshbay.org"
// is a claim the design makes; "meshbay.org cannot read anything" is one it
// forbids (T3). "Encrypted all the way" means device to node, as §2.3 defines.
const WELCOME_APPS = [
['chat', 'welcome.app_chat'], ['image', 'welcome.app_photos'],
['video', 'welcome.app_media'], ['play', 'welcome.app_video'],
['music', 'welcome.app_music'],
];
const WELCOME_STEPS = [
['home', 'welcome.step_home'], ['globe', 'welcome.step_anywhere'],
['user', 'welcome.step_share'],
];
const WELCOME_USES = [
['chat', 'welcome.use_chat'], ['image', 'welcome.use_photos'],
['cast', 'welcome.use_media'], ['pencil', 'welcome.use_apps'],
];
const WELCOME_BADGES = ['welcome.badge_free', 'welcome.badge_open',
'welcome.badge_no_ads', 'welcome.badge_no_tracking'];
const REPO = 'https://git.meshbay.org/meshbay.git/about/';
const WELCOME_DOCS = [
['folder', 'welcome.docs_source', [['welcome.docs_repo', REPO]]],
['user', 'welcome.docs_user', [
['welcome.docs_quickstart', `${REPO}docs/QUICKSTART.md`],
['welcome.docs_userguide', `${REPO}docs/USERGUIDE.md`]]],
['gear', 'welcome.docs_devel', [
['welcome.docs_design', `${REPO}docs/MESHBAY_DESIGN.md`],
['welcome.docs_protocol', `${REPO}docs/MESHBAY_NODE_PROTOCOL.md`]]],
];
// Under the sign-in form rather than at the foot of the text: on a desktop the
// text column runs far below the form, and these were the last thing on it.
function WelcomeLinks() {
return html`