import React from 'react'; import { Input, Button, Container, Icon, NgIf, Loader } from '../../components/'; import { Config, Admin } from '../../model/'; import { notify, FormObjToJSON, alert, prompt } from '../../helpers'; import { bcrypt_password } from '../../helpers/bcrypt'; import ReactCSSTransitionGroup from 'react-addons-css-transition-group'; import "./setup.scss"; export class SetupPage extends React.Component { constructor(props){ super(props); this.state = { busy: false, }; } componentDidMount() { const start = (e) => { e.preventDefault(); this.props.history.push("/"); }; Config.all().then((config) => { if(config.log.telemetry.value === true) return; this.unlisten = this.props.history.listen((location, action) => { this.unlisten(); alert.now((

Help making this software better by sending crash reports and anonymous usage statistics

)); }); }); } onAdminPassword(p, done){ this.setState({busy: true}); Config.all().then((config) => { return bcrypt_password(p).then((hash) => { config = FormObjToJSON(config); config.connections = window.CONFIG.connections; config.auth.admin = hash; Config.save(config, false) .then(() => Admin.login(p)) .then(() => this.setState({busy: false}, done)) .catch((err) => { this.setState({busy: false}); notify.send(err && err.message, "error"); }); }).catch((err) => { this.setState({busy: false}); notify.send("Hash error: " + JSON.stringify(err), "error"); }); }).catch((err) => { notify.send(err && err.message, "error"); this.setState({busy: false}); }); } onExposeInstance(choice, done){ this.setState({busy: true}); return Config.all().then((config) => { config = FormObjToJSON(config); config.connections = window.CONFIG.connections; switch(choice){ case "tunnel": config.features.server.enable_tunnel = true; break; default: config.features.server.enable_tunnel = false; break; } Config.save(config, false) .then(() => this.setState({busy: false}, done)) .catch((err) => { notify.send(err && err.message, "error"); this.setState({busy: false}); }); }).catch((err) => { notify.send(err && err.message, "error"); this.setState({busy: false}); }); } enableLog(value){ Config.all().then((config) => { config = FormObjToJSON(config); config.connections = window.CONFIG.connections; config.log.telemetry = value; Config.save(config, false); }); }; summaryCall(){ this.setState({busy: true}); return Config.all().then((config) => { this.setState({busy: false}); return [ { "name_success": "SSL is configured properly", "name_failure": "SSL is not configured properly", "pass": window.location.protocol !== "http:", "severe": true, "message": "This can lead to data leaks. Please use a SSL certificate or expose your instance via a filestash domain" }, { "name_success": "Application is running as '" + objectGet(config, ["constant", "user", "value"]) + "'", "name_failure": "Application is running as root", "pass": objectGet(config, ["constant", "user", "value"]) !== "root", "severe": true, "message": "This is dangerous, you should use another user with less privileges" }, { "name_success": "Emacs is installed", "name_failure": "Emacs is not installed", "pass": objectGet(config, ["constant", "emacs", "value"]), "severe": false, "message": "If you want to use all the org-mode features of Filestash, you need to install emacs" }, { "name_success": "Pdftotext is installed", "name_failure": "Pdftotext is not installed", "pass": objectGet(config, ["constant", "pdftotext", "value"]), "severe": false, "message": "You won't be able to search through PDF documents without it" } ]; }).catch((err) => { notify.send(err && err.message, "error"); this.setState({busy: false}); }); } tunnelCall(){ this.setState({busy: true}); return Config.all().then((config) => { //this.setState({busy: false}); return objectGet(config, ["features", "server", "tunnel_url", "value"]); }); } render(){ return (
); } } class MultiStepForm extends React.Component { constructor(props){ super(props); this.state = { current: parseInt(window.location.hash.replace("#", "")) || 0, answer_password: "", has_answered_password: false, answer_expose: "", has_answered_expose: false, deps: [], redirect_uri: null, working_message: "Working" }; } componentDidMount(){ if(this.state.current == 2){ this.fetchDependencies(); } } onAdminPassword(e){ e.preventDefault(); this.props.onAdminPassword(this.state.answer_password, () => { this.setState({current: 1, has_answered_password: true}); }); } onExposeInstance(value, e){ e.preventDefault(); this.setState({answer_expose: value}); this.props.onExposeInstance(value, () => { if(value === "tunnel"){ const waitForDomain = (count = 0) => { return this.props.tunnelCall().then((url) => { if(url && /\.filestash\.app$/.test(url) === true){ return Promise.resolve(url); } if(count > 10){ this.setState({working_message: "Building your domain"}); }else if(count > 30){ this.setState({working_message: "Processing ."+".".repeat(count % 3)}); } if(count >= 60){ return Promise.reject({message: "Couldn't create a domain name"}); } return new Promise((done) => window.setTimeout(done, 1000)) .then(() => waitForDomain(count + 1)); }); }; waitForDomain().then((url) => { this.setState({redirect_uri: url}); }).catch((err) => { window.location.hash = "#2"; window.location.reload(); }); } else { this.setState({current: 2, has_answered_expose: true}, () => { this.onStepChange(2); }); } }); } onStepChange(n){ this.setState({current: n}); if(n === 2){ this.fetchDependencies(); } } fetchDependencies() { this.props.summaryCall().then((deps) => { this.setState({deps: deps}); }); } render() { const hideMenu =