2022-06-21 21:42:29 +00:00
|
|
|
import { None, Some } from "@sniptt/monads";
|
2021-02-22 02:39:04 +00:00
|
|
|
import { Component, linkEvent } from "inferno";
|
|
|
|
import { Helmet } from "inferno-helmet";
|
2022-06-21 21:42:29 +00:00
|
|
|
import {
|
|
|
|
LoginResponse,
|
|
|
|
Register,
|
|
|
|
toUndefined,
|
|
|
|
UserOperation,
|
|
|
|
wsJsonToRes,
|
|
|
|
wsUserOp,
|
|
|
|
} from "lemmy-js-client";
|
2021-02-22 02:39:04 +00:00
|
|
|
import { Subscription } from "rxjs";
|
2021-07-17 20:42:55 +00:00
|
|
|
import { delay, retryWhen, take } from "rxjs/operators";
|
|
|
|
import { i18n } from "../../i18next";
|
|
|
|
import { UserService, WebSocketService } from "../../services";
|
2022-06-21 21:42:29 +00:00
|
|
|
import { toast, wsClient } from "../../utils";
|
2021-07-17 20:42:55 +00:00
|
|
|
import { Spinner } from "../common/icon";
|
2021-02-22 02:39:04 +00:00
|
|
|
import { SiteForm } from "./site-form";
|
2020-09-06 16:15:25 +00:00
|
|
|
|
|
|
|
interface State {
|
2020-12-24 01:58:27 +00:00
|
|
|
userForm: Register;
|
2020-09-06 16:15:25 +00:00
|
|
|
doneRegisteringUser: boolean;
|
|
|
|
userLoading: boolean;
|
|
|
|
}
|
|
|
|
|
|
|
|
export class Setup extends Component<any, State> {
|
|
|
|
private subscription: Subscription;
|
|
|
|
|
|
|
|
private emptyState: State = {
|
2022-06-21 21:42:29 +00:00
|
|
|
userForm: new Register({
|
2020-09-06 16:15:25 +00:00
|
|
|
username: undefined,
|
|
|
|
password: undefined,
|
|
|
|
password_verify: undefined,
|
|
|
|
show_nsfw: true,
|
|
|
|
// The first admin signup doesn't need a captcha
|
2022-06-21 21:42:29 +00:00
|
|
|
captcha_uuid: None,
|
|
|
|
captcha_answer: None,
|
|
|
|
email: None,
|
|
|
|
honeypot: None,
|
|
|
|
answer: None,
|
|
|
|
}),
|
2022-06-27 20:50:47 +00:00
|
|
|
doneRegisteringUser: UserService.Instance.myUserInfo.isSome(),
|
2020-09-06 16:15:25 +00:00
|
|
|
userLoading: false,
|
|
|
|
};
|
|
|
|
|
|
|
|
constructor(props: any, context: any) {
|
|
|
|
super(props, context);
|
|
|
|
|
|
|
|
this.state = this.emptyState;
|
|
|
|
|
|
|
|
this.subscription = WebSocketService.Instance.subject
|
|
|
|
.pipe(retryWhen(errors => errors.pipe(delay(3000), take(10))))
|
|
|
|
.subscribe(
|
|
|
|
msg => this.parseMessage(msg),
|
|
|
|
err => console.error(err),
|
2021-02-22 02:39:04 +00:00
|
|
|
() => console.log("complete")
|
2020-09-06 16:15:25 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
componentWillUnmount() {
|
|
|
|
this.subscription.unsubscribe();
|
|
|
|
}
|
|
|
|
|
|
|
|
get documentTitle(): string {
|
2021-02-22 02:39:04 +00:00
|
|
|
return `${i18n.t("setup")} - Lemmy`;
|
2020-09-06 16:15:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
|
|
|
return (
|
|
|
|
<div class="container">
|
|
|
|
<Helmet title={this.documentTitle} />
|
|
|
|
<div class="row">
|
|
|
|
<div class="col-12 offset-lg-3 col-lg-6">
|
2021-02-22 02:39:04 +00:00
|
|
|
<h3>{i18n.t("lemmy_instance_setup")}</h3>
|
2020-09-06 16:15:25 +00:00
|
|
|
{!this.state.doneRegisteringUser ? (
|
|
|
|
this.registerUser()
|
|
|
|
) : (
|
2022-06-21 21:42:29 +00:00
|
|
|
<SiteForm site={None} showLocal />
|
2020-09-06 16:15:25 +00:00
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
registerUser() {
|
|
|
|
return (
|
|
|
|
<form onSubmit={linkEvent(this, this.handleRegisterSubmit)}>
|
2021-02-22 02:39:04 +00:00
|
|
|
<h5>{i18n.t("setup_admin")}</h5>
|
2020-09-06 16:15:25 +00:00
|
|
|
<div class="form-group row">
|
|
|
|
<label class="col-sm-2 col-form-label" htmlFor="username">
|
2021-02-22 02:39:04 +00:00
|
|
|
{i18n.t("username")}
|
2020-09-06 16:15:25 +00:00
|
|
|
</label>
|
|
|
|
<div class="col-sm-10">
|
|
|
|
<input
|
|
|
|
type="text"
|
|
|
|
class="form-control"
|
|
|
|
id="username"
|
|
|
|
value={this.state.userForm.username}
|
|
|
|
onInput={linkEvent(this, this.handleRegisterUsernameChange)}
|
|
|
|
required
|
|
|
|
minLength={3}
|
|
|
|
pattern="[a-zA-Z0-9_]+"
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="form-group row">
|
|
|
|
<label class="col-sm-2 col-form-label" htmlFor="email">
|
2021-02-22 02:39:04 +00:00
|
|
|
{i18n.t("email")}
|
2020-09-06 16:15:25 +00:00
|
|
|
</label>
|
|
|
|
|
|
|
|
<div class="col-sm-10">
|
|
|
|
<input
|
|
|
|
type="email"
|
|
|
|
id="email"
|
|
|
|
class="form-control"
|
2021-02-22 02:39:04 +00:00
|
|
|
placeholder={i18n.t("optional")}
|
2022-06-21 21:42:29 +00:00
|
|
|
value={toUndefined(this.state.userForm.email)}
|
2020-09-06 16:15:25 +00:00
|
|
|
onInput={linkEvent(this, this.handleRegisterEmailChange)}
|
|
|
|
minLength={3}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="form-group row">
|
|
|
|
<label class="col-sm-2 col-form-label" htmlFor="password">
|
2021-02-22 02:39:04 +00:00
|
|
|
{i18n.t("password")}
|
2020-09-06 16:15:25 +00:00
|
|
|
</label>
|
|
|
|
<div class="col-sm-10">
|
|
|
|
<input
|
|
|
|
type="password"
|
|
|
|
id="password"
|
|
|
|
value={this.state.userForm.password}
|
|
|
|
onInput={linkEvent(this, this.handleRegisterPasswordChange)}
|
|
|
|
class="form-control"
|
|
|
|
required
|
2021-11-16 14:46:22 +00:00
|
|
|
autoComplete="new-password"
|
|
|
|
minLength={10}
|
2021-03-01 17:38:03 +00:00
|
|
|
maxLength={60}
|
2020-09-06 16:15:25 +00:00
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="form-group row">
|
|
|
|
<label class="col-sm-2 col-form-label" htmlFor="verify-password">
|
2021-02-22 02:39:04 +00:00
|
|
|
{i18n.t("verify_password")}
|
2020-09-06 16:15:25 +00:00
|
|
|
</label>
|
|
|
|
<div class="col-sm-10">
|
|
|
|
<input
|
|
|
|
type="password"
|
|
|
|
id="verify-password"
|
|
|
|
value={this.state.userForm.password_verify}
|
|
|
|
onInput={linkEvent(this, this.handleRegisterPasswordVerifyChange)}
|
|
|
|
class="form-control"
|
|
|
|
required
|
2021-11-16 14:46:22 +00:00
|
|
|
autoComplete="new-password"
|
|
|
|
minLength={10}
|
2021-03-01 17:38:03 +00:00
|
|
|
maxLength={60}
|
2020-09-06 16:15:25 +00:00
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="form-group row">
|
|
|
|
<div class="col-sm-10">
|
|
|
|
<button type="submit" class="btn btn-secondary">
|
2021-02-22 02:39:04 +00:00
|
|
|
{this.state.userLoading ? <Spinner /> : i18n.t("sign_up")}
|
2020-09-06 16:15:25 +00:00
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</form>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
handleRegisterSubmit(i: Setup, event: any) {
|
|
|
|
event.preventDefault();
|
|
|
|
i.state.userLoading = true;
|
|
|
|
i.setState(i.state);
|
|
|
|
event.preventDefault();
|
2020-12-24 22:05:57 +00:00
|
|
|
WebSocketService.Instance.send(wsClient.register(i.state.userForm));
|
2020-09-06 16:15:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
handleRegisterUsernameChange(i: Setup, event: any) {
|
|
|
|
i.state.userForm.username = event.target.value;
|
|
|
|
i.setState(i.state);
|
|
|
|
}
|
|
|
|
|
|
|
|
handleRegisterEmailChange(i: Setup, event: any) {
|
2022-06-21 21:42:29 +00:00
|
|
|
i.state.userForm.email = Some(event.target.value);
|
2020-09-06 16:15:25 +00:00
|
|
|
i.setState(i.state);
|
|
|
|
}
|
|
|
|
|
|
|
|
handleRegisterPasswordChange(i: Setup, event: any) {
|
|
|
|
i.state.userForm.password = event.target.value;
|
|
|
|
i.setState(i.state);
|
|
|
|
}
|
|
|
|
|
|
|
|
handleRegisterPasswordVerifyChange(i: Setup, event: any) {
|
|
|
|
i.state.userForm.password_verify = event.target.value;
|
|
|
|
i.setState(i.state);
|
|
|
|
}
|
|
|
|
|
2020-12-24 01:58:27 +00:00
|
|
|
parseMessage(msg: any) {
|
|
|
|
let op = wsUserOp(msg);
|
2020-09-06 16:15:25 +00:00
|
|
|
if (msg.error) {
|
2021-02-22 02:39:04 +00:00
|
|
|
toast(i18n.t(msg.error), "danger");
|
2020-09-06 16:15:25 +00:00
|
|
|
this.state.userLoading = false;
|
|
|
|
this.setState(this.state);
|
|
|
|
return;
|
2020-12-24 01:58:27 +00:00
|
|
|
} else if (op == UserOperation.Register) {
|
2022-06-21 21:42:29 +00:00
|
|
|
let data = wsJsonToRes<LoginResponse>(msg, LoginResponse);
|
2020-09-06 16:15:25 +00:00
|
|
|
this.state.userLoading = false;
|
|
|
|
UserService.Instance.login(data);
|
|
|
|
this.setState(this.state);
|
2020-12-24 01:58:27 +00:00
|
|
|
} else if (op == UserOperation.CreateSite) {
|
2021-02-22 02:39:04 +00:00
|
|
|
window.location.href = "/";
|
2020-09-06 16:15:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|