mirror of
				https://github.com/mickael-kerjean/filestash.git
				synced 2025-10-31 10:07:15 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			230 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			230 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| import React from "react";
 | |
| import { FormBuilder, Icon, Input, Alert } from "../../components/";
 | |
| import { Backend, Config } from "../../model/";
 | |
| import { FormObjToJSON, notify, format, createFormBackend } from "../../helpers/";
 | |
| import { t } from "../../locales/";
 | |
| 
 | |
| import "./backend.scss";
 | |
| 
 | |
| export class BackendPage extends React.Component {
 | |
|     constructor(props){
 | |
|         super(props);
 | |
|         this.state = {
 | |
|             backend_enabled: [],
 | |
|             backend_available: [],
 | |
|             auth_available: ["LDAP", "SAML", "OpenID", "External"],
 | |
|             auth_enabled: null,
 | |
|             config: null
 | |
|         };
 | |
|     }
 | |
| 
 | |
|     componentDidMount(){
 | |
|         Promise.all([
 | |
|             Backend.all(),
 | |
|             Config.all()
 | |
|         ]).then((data) => {
 | |
|             let [backend, config] = data;
 | |
|             this.setState({
 | |
|                 backend_available: backend,
 | |
|                 backend_enabled: window.CONFIG["connections"].filter((b) => b).map((conn) => {
 | |
|                     return createFormBackend(backend, conn);
 | |
|                 }),
 | |
|                 config: config
 | |
|             });
 | |
|         });
 | |
|     }
 | |
| 
 | |
|     onChange(e){
 | |
|         this.setState({refresh: Math.random()}); // refresh the screen to refresh the mutation
 | |
|                                                  // that have happenned down the stack
 | |
| 
 | |
|         let json = FormObjToJSON(this.state.config);
 | |
|         json.connections = this.state.backend_enabled.map((backend) => {
 | |
|             let data = FormObjToJSON(backend, (obj, key) => {
 | |
|                 if(obj[key].enabled === true){
 | |
|                     obj[key] = obj[key].value || obj[key].default;
 | |
|                 } else {
 | |
|                     delete obj[key];
 | |
|                 }
 | |
|             });
 | |
|             const key = Object.keys(data)[0];
 | |
|             return data[key];
 | |
|         });
 | |
| 
 | |
|         // persist config object in the backend
 | |
|         this.props.isSaving(true);
 | |
|         return Config.save(json, true, () => {
 | |
|             this.props.isSaving(false);
 | |
|         }, (err) => {
 | |
|             notify.send(err && err.message || t("Oops"), "error");
 | |
|             this.props.isSaving(false);
 | |
|         });
 | |
|     }
 | |
| 
 | |
|     addBackend(backend_id){
 | |
|         this.setState({
 | |
|             backend_enabled: this.state.backend_enabled.concat(
 | |
|                 createFormBackend(this.state.backend_available, {
 | |
|                     type: backend_id,
 | |
|                     label: backend_id.toUpperCase()
 | |
|                 })
 | |
|             )
 | |
|         }, this.onChange.bind(this));
 | |
|     }
 | |
| 
 | |
|     removeBackend(n){
 | |
|         this.setState({
 | |
|             backend_enabled: this.state.backend_enabled.filter((_, i) => i !== n)
 | |
|         }, this.onChange.bind(this));
 | |
|     }
 | |
| 
 | |
|     onClickAuthAvailable(auth){
 | |
|         this.setState({
 | |
|             auth_enabled: this.state.auth_enabled === auth ? null : auth
 | |
|         });
 | |
|     }
 | |
| 
 | |
|     render(){
 | |
|         const update = (value, struct) => {
 | |
|             struct.enabled = value;
 | |
|             this.setState({refresh: Math.random()});
 | |
|             if(value === false){
 | |
|                 struct.value = null;
 | |
|             }
 | |
|             return;
 | |
|         };
 | |
| 
 | |
|         const enable = (struct) => {
 | |
|             if(typeof struct.value === "string"){
 | |
|                 struct.enabled = true;
 | |
|                 return true;
 | |
|             }
 | |
|             return !!struct.enabled;
 | |
|         };
 | |
| 
 | |
|         const isActiveBackend = (backend_key) => {
 | |
|             return this.state.backend_enabled
 | |
|                 .map((b) => Object.keys(b)[0])
 | |
|                 .indexOf(backend_key) !== -1;
 | |
|         };
 | |
| 
 | |
|         const isActiveAuth = (auth_key) => {
 | |
|             return auth_key === this.state.auth_enabled;
 | |
|         };
 | |
| 
 | |
|         return (
 | |
|             <div className="component_dashboard">
 | |
|               <h2>Enabled Backends</h2>
 | |
|               <div className="box-container">
 | |
|                 {
 | |
|                     Object.keys(this.state.backend_available)
 | |
|                         .sort((a, b) => a > b)
 | |
|                         .map((backend_available, index) => (
 | |
|                             <div key={index} onClick={this.addBackend.bind(this, backend_available)}
 | |
|                                  className={"box-item pointer no-select" + (isActiveBackend(backend_available) ? " active": "")}>
 | |
|                               <div>
 | |
|                                 { backend_available }
 | |
|                                 <span className="no-select">
 | |
|                                   <span className="icon">+</span>
 | |
|                                 </span>
 | |
|                               </div>
 | |
|                             </div>
 | |
|                         ))
 | |
|                 }
 | |
|               </div>
 | |
| 
 | |
|               <h2>Authentication Middleware</h2>
 | |
| 
 | |
|               <Alert>
 | |
|                 Integrate Filestash with your identity management system
 | |
|               </Alert>
 | |
| 
 | |
|               <div className="box-container">
 | |
|                 {
 | |
|                     this.state.auth_available.map((auth) => (
 | |
|                         <div onClick={this.onClickAuthAvailable.bind(this, auth)} key={auth}
 | |
|                              className={"box-item pointer no-select" + (isActiveAuth(auth) ? " active": "")}>
 | |
|                           <div>
 | |
|                             { auth }
 | |
|                             <span className="no-select">
 | |
|                               <span className="icon">
 | |
|                                 { isActiveAuth(auth) === false ? "+" : <Icon name="delete" /> }
 | |
|                               </span>
 | |
|                             </span>
 | |
|                           </div>
 | |
|                         </div>
 | |
|                     ))
 | |
|                 }
 | |
|               </div>
 | |
| 
 | |
|               {
 | |
|                   this.state.auth_enabled !== null && (
 | |
|                       <React.Fragment>
 | |
|                         <Alert className="success">
 | |
|                           <i><strong>Register your interest: <a href={`mailto:mickael@kerjean.me?Subject=Filestash - Authentication Middleware - ${this.state.auth_enabled}`}>mickael@kerjean.me</a></strong></i>
 | |
|                         </Alert>
 | |
|                       </React.Fragment>
 | |
|                   )
 | |
|               }
 | |
| 
 | |
|               <h2>Backend Configuration</h2>
 | |
| 
 | |
|               {
 | |
|                   this.state.backend_enabled.length !== 0 ? <div>
 | |
|                     <form>
 | |
|                       {
 | |
|                           this.state.backend_enabled.map((backend_enable, index) => {
 | |
|                               return (
 | |
|                                   <div key={index}>
 | |
|                                     <div className="icons no-select" onClick={this.removeBackend.bind(this, index)}>
 | |
|                                       <Icon name="delete" />
 | |
|                                     </div>
 | |
|                                     <FormBuilder onChange={this.onChange.bind(this)}
 | |
|                                                  idx={index}
 | |
|                                                  key={index}
 | |
|                                                  form={{"": backend_enable}}
 | |
|                                                  autoComplete="new-password"
 | |
|                                                  render={ ($input, props, struct, onChange) => {
 | |
|                                                      let $checkbox = (
 | |
|                                                          <Input type="checkbox" style={{width: "inherit", marginRight: "6px", top: "6px"}}
 | |
|                                                                 checked={enable(struct)} onChange={(e) => onChange(update.bind(this, e.target.checked))}/>
 | |
|                                                      );
 | |
|                                                      if(struct.label === "label"){
 | |
|                                                          $checkbox = null;
 | |
|                                                      } else if(struct.readonly === true) {
 | |
|                                                          $checkbox = null;
 | |
|                                                      }
 | |
|                                                      return (
 | |
|                                                          <label className={"no-select input_type_" + props.params["type"]}>
 | |
|                                                            <div>
 | |
|                                                              <span>
 | |
|                                                                { $checkbox }
 | |
|                                                                { format(struct.label) }:
 | |
|                                                              </span>
 | |
|                                                              <div style={{width: "100%"}}>
 | |
|                                                                { $input }
 | |
|                                                              </div>
 | |
|                                                            </div>
 | |
|                                                            <div>
 | |
|                                                              <span className="nothing"></span>
 | |
|                                                              <div style={{width: "100%"}}>
 | |
|                                                                {
 | |
|                                                                    struct.description ? (<div className="description">{struct.description}</div>) : null
 | |
|                                                                }
 | |
|                                                              </div>
 | |
|                                                            </div>
 | |
|                                                          </label>
 | |
|                                                      );
 | |
|                                                  }} />
 | |
|                                   </div>
 | |
|                               );
 | |
|                           })
 | |
|                       }
 | |
|                     </form>
 | |
|                   </div> : <Alert>You need to enable a backend first.</Alert>
 | |
|               }
 | |
|             </div>
 | |
|         );
 | |
|     }
 | |
| }
 | 
