import React from 'react'; import { Container, Card, NgIf, Input, Button, Textarea, Loader, Notification, encrypt, decrypt } from '../utilities'; import { Session, invalidate, password } from '../data'; import { Uploader } from '../utilities'; export class ConnectPage extends React.Component { constructor(props){ super(props); this.state = { type: 'webdav', loading: false, error: null, advanced_ftp: false, // state of checkbox in the UI advanced_sftp: false, // state of checkbox in the UI advanced_webdav: false, advanced_s3: false, advanced_git: false, credentials: {}, password: password.get() || null, marginTop: this._marginTop() } // adapt from: https://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript function getParam(name) { const regex = new RegExp("[?&#]" + name.replace(/[\[\]]/g, "\\$&") + "(=([^&#]*)|&|#|$)"); const results = regex.exec(window.location.href); if (!results) return null; if (!results[2]) return ''; return decodeURIComponent(results[2].replace(/\+/g, " ")); } // dropbox login if(getParam('state') === 'dropbox'){ this.state.loading = true; this.authenticate({bearer: getParam('access_token'), type: 'dropbox'}) } // google drive login if(getParam('code')){ this.state.loading = true; this.authenticate({code: getParam('code'), type: 'gdrive'}) } } _marginTop(){ let size = Math.round(Math.abs((document.body.offsetHeight - 300) / 2)); return size > 150? 150 : size; } componentWillMount(){ window.onresize = () => { this.setState({marginTop: this._marginTop()}) } let raw = window.localStorage.getItem('store'); if(!this.state.loading && raw){ if(this.state.password === null){ let key = prompt("Your password: "); if(key){ password.set(key); let credentials = decrypt(raw, key); this.setState({password: password, credentials: credentials}, setAdvanced.bind(this)); } }else{ let credentials = decrypt(raw, this.state.password); this.setState({credentials: credentials}, setAdvanced.bind(this)); } function setAdvanced(){ if(this.state.credentials['ftp'] && (this.state.credentials['ftp']['path'] || this.state.credentials['ftp']['port']) ){ this.setState({advanced_ftp: true}) } if(this.state.credentials['sftp'] && (this.state.credentials['sftp']['path'] || this.state.credentials['sftp']['port'] || this.state.credentials['sftp']['private_key'])){ this.setState({advanced_sftp: true}) } if(this.state.credentials['webdav'] && this.state.credentials['webdav']['path']){ this.setState({advanced_webdav: true}) } if(this.state.credentials['s3'] && this.state.credentials['s3']['path']){ this.setState({advanced_s3: true}) } if(this.state.credentials['git'] && (this.state.credentials['git']['username'] || this.state.credentials['git']['commit'] || this.state.credentials['git']['branch'] || this.state.credentials['git']['passphrase'] || this.state.credentials['git']['author_name'] || this.state.credentials['git']['author_email'] || this.state.credentials['git']['committer_name'] || this.state.credentials['git']['committer_email'])){ this.setState({advanced_git: true}) } } } } getDefault(type, key){ if(this.state.credentials[type]){ return this.state.credentials[type][key] }else{ return null; } } onRememberMe(e){ let value = e.target.checked; if(value === true){ let key = prompt("password that will serve to encrypt your credentials:"); password.set(key); this.setState({password: key}); }else if(value === false){ window.localStorage.clear(); password.set(); this.setState({credentials: {}, password: null}); } } onChange(type){ this.setState({type: type}); } login_dropbox(e){ e.preventDefault(); this.setState({loading: true}); Session.url('dropbox').then((url) => { window.location.href = url; }).catch((err) => { if(err && err.code === 'CANCELLED'){ return } this.setState({loading: false, error: err}); window.setTimeout(() => { this.setState({error: null}) }, 1000); }); } login_google(e){ e.preventDefault(); this.setState({loading: true}); Session.url('gdrive').then((url) => { window.location.href = url; }).catch((err) => { if(err && err.code === 'CANCELLED'){ return } this.setState({loading: false, error: err}); window.setTimeout(() => { this.setState({error: null}) }, 1000); }) } authenticate(params){ if(password.get()){ this.state.credentials[params['type']] = params; window.localStorage.setItem('store', encrypt(this.state.credentials, password.get())); } Session.authenticate(params) .then((ok) => { this.setState({loading: false}); invalidate(); const path = params.path && /^\//.test(params.path)? /\/$/.test(params.path) ? params.path : params.path+'/' : '/'; this.props.history.push('/files'+path); }) .catch(err => { if(err && err.code === 'CANCELLED'){ return } this.setState({loading: false, error: err}); window.setTimeout(() => { this.setState({error: null}) }, 1000); }); } onSubmit(e){ e.preventDefault(); this.setState({loading: true}); // yes it's dirty but at least it's supported nearly everywhere and build won't push Megabytes or polyfill // to support the entries method of formData which would have made things much cleaner const serialize = function($form){ if(!$form) return {}; var obj = {}; var elements = $form.querySelectorAll( "input, select, textarea" ); for( var i = 0; i < elements.length; ++i ) { var element = elements[i]; var name = element.name; var value = element.value; if(name){ obj[name] = value; } } return obj; } const data = serialize(document.querySelector('form')); this.authenticate(data); } render() { let labelStyle = {color: 'rgba(0,0,0,0.4)', fontStyle: 'italic', fontSize: '0.9em'} let style = { top: {minWidth: '80px', borderTopLeftRadius: 0, borderTopRightRadius: 0, padding: '8px 5px'} } return (