123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- import { Component, createRef } from "inferno";
- import * as matrixcs from "matrix-js-sdk";
- import * as localforage from "localforage";
- import Header from "./ui/Header";
- import TextInput from "./ui/TextInput";
- import SoftKey from "./ui/SoftKey";
- import TextListItem from "./ui/TextListItem";
- import ListView from "./ListView";
- import requestFunc from "./requestFunc";
- import colors from "KaiUI/src/theme/colors.scss";
- class Login extends Component {
- updateHomeServer = (evt) => {
- this.setState({ homeserver: evt.target.value });
- };
- updateUsername = (evt) => {
- this.setState({ username: evt.target.value });
- };
- updateLoginData = (evt) => {
- this.setState({ loginData: evt.target.value });
- };
- updateCursor = (cursor) => {
- this.setState({
- cursor: cursor,
- });
- };
- handleKeyDown = (evt) => {
- if (evt.key === "Backspace") {
- if (this.state.selectedLoginMethod) {
- this.setState({ selectedLoginMethod: "" });
- evt.preventDefault();
- } else if (this.state.loginFlows.length) {
- this.setState({ loginFlows: [] });
- evt.preventDefault();
- }
- }
- };
- doLogin = () => {
- if (this.state.loginData) {
- this.doLoginFinal();
- } else if (this.state.loginFlows.length === 0) {
- this.doLoginFlows();
- } else {
- this.doLoginData();
- }
- };
- doLoginFlows = () => {
- let homeserver, username;
- homeserver = this.state.homeserver;
- username = this.state.username;
- if (!homeserver || !username) {
- return;
- }
- if (!homeserver.startsWith("https://")) {
- homeserver = "https://" + homeserver;
- }
- window.mClient = matrixcs.createClient({
- baseUrl: homeserver,
- request: requestFunc,
- });
- window.mClient.loginFlows().then((result) => {
- this.setState({ loginFlows: result.flows });
- });
- };
- doLoginData = () => {
- const loginMethod = this.state.loginFlows[this.state.cursor];
- console.log(`[doLogindata] User wanna login with ${loginMethod.type}`);
- switch (loginMethod.type) {
- case "m.login.password":
- console.log("[doLoiginData] Logging in with password");
- this.setState({ selectedLoginMethod: "m.login.password" });
- break;
- default:
- alert("This login method is currently not supported :(");
- break;
- }
- };
- doLoginFinal = () => {
- switch (
- this.state.selectedLoginMethod // eslint-disable-line default-case
- ) {
- case "m.login.password":
- window.mClient
- .loginWithPassword(
- `@${this.state.username}:${this.state.homeserver}`,
- this.state.loginData
- )
- .then((result) => {
- localforage.setItem("login", result).then(() => {
- alert(`Logged in as ${this.state.username}`);
- window.location = window.location; // eslint-disable-line no-self-assign
- });
- })
- .catch((err) => {
- console.log("[doLoginFinal] Login Error", err.toString());
- switch (err.errcode) {
- case "M_FORBIDDEN":
- alert("Incorrect login credentials");
- break;
- case "M_USER_DEACTIVATED":
- alert("This user has been deactivated");
- this.setState({ loginData: null, loginFlows: [] });
- break;
- case "M_LIMIT_EXCEEDED":
- const retry = err.retry_after_ms / 1000;
- alert(`Too many requests! Please retry after ${retry} seconds`);
- break;
- default:
- alert("Login failed");
- break;
- }
- });
- }
- };
- constructor(props) {
- super(props);
- this.headerRef = createRef();
- this.listViewRef = createRef();
- this.state = {
- homeserver: "",
- username: "",
- loginFlows: [],
- selectedLoginMethod: "",
- loginData: null,
- cursor: 0,
- };
- this.listView = (
- <ListView
- cursor={0}
- cursorChangeCb={this.updateCursor}
- ref={this.listViewRef}
- $HasNonKeyedChildren
- >
- <TextInput
- label="Homeserver"
- placeholder="https://matrix.org"
- onChange={this.updateHomeServer}
- defaultValue={this.state.homeserver}
- />
- <TextInput
- label="Username"
- placeholder="somebody"
- onChange={this.updateUsername}
- defaultValue={this.state.username}
- />
- </ListView>
- );
- this.header = (
- <Header
- text={""}
- backgroundColor={colors.headerBlue}
- ref={this.headerRef}
- />
- );
- }
- componentWillUpdate(nextProps, nextState, context) {
- if (nextState.selectedLoginMethod) {
- switch (nextState.selectedLoginMethod) {
- case "m.login.password":
- this.headerRef.current.setState({ text: "Login with password" });
- this.listViewRef.current.resetChildrenCursor([
- <TextInput
- label="Password"
- fieldType="password"
- placeholder="HG#$@B#@#G%N&*"
- onChange={this.updateLoginData}
- />,
- ]);
- break;
- default:
- break;
- }
- } else if (nextState.loginFlows.length) {
- if (this.headerRef.current.state.text === "Login method") return;
- this.headerRef.current.setState({ text: "Login method" });
- this.listViewRef.current.resetChildrenCursor(
- nextState.loginFlows.map((item) => <TextListItem primary={item.type} />)
- );
- }
- }
- render() {
- if (this.state.loginFlows.length === 0) {
- this.headerRef.current &&
- this.headerRef.current.setState({ text: "Login" });
- }
- return (
- <div>
- {this.header}
- {this.listView}
- <footer $HasVNodeChildren>
- <SoftKey
- leftText="Quit"
- leftCb={() => window.close()}
- centerCb={this.doLogin}
- centerText="Login"
- />
- </footer>
- </div>
- );
- }
- }
- export default Login;
|