diff --git a/src/constants.js b/src/constants.js index 532697f..f66ba3e 100644 --- a/src/constants.js +++ b/src/constants.js @@ -51,6 +51,14 @@ exports.DATA_LOCATIONS = { win32: '%LOCALAPPDATA%\\repertory\\ui' }; +exports.S3_PROVIDER_LIST = [ + 'Goobox S3', +]; + +exports.S3_PROVIDER_URL = { + 'Goobox S3': 'https://sias3.goobox.io', +}; + exports.PROVIDER_LIST = [ 'Sia', 'Skynet', diff --git a/src/containers/AddMount/AddMount.js b/src/containers/AddMount/AddMount.js index 6af67bf..68ae5b9 100644 --- a/src/containers/AddMount/AddMount.js +++ b/src/containers/AddMount/AddMount.js @@ -8,6 +8,8 @@ import Text from '../../components/UI/Text/Text'; import {notifyError} from '../../redux/actions/error_actions'; import {addRemoteMount, addS3Mount} from '../../redux/actions/mount_actions'; import {createModalConditionally} from '../../utils'; +import DropDown from '../../components/UI/DropDown/DropDown'; +import * as Constants from '../../constants'; const mapStateToProps = state => { return { @@ -19,7 +21,7 @@ const mapStateToProps = state => { const mapDispatchToProps = dispatch => { return { addRemoteMount: (hostNameOrIp, port, token) => dispatch(addRemoteMount(hostNameOrIp, port, token)), - addS3Mount: (name, accessKey, secretKey, region, bucketName) => dispatch(addS3Mount(name, accessKey, secretKey, region, bucketName)), + addS3Mount: (name, accessKey, secretKey, region, bucketName, url) => dispatch(addS3Mount(name, accessKey, secretKey, region, bucketName, url)), notifyError: (msg, critical, callback) => dispatch(notifyError(msg, critical, callback)), } }; @@ -32,6 +34,7 @@ const default_state = { HostNameOrIp: '', Name: '', Port: 20000, + Provider: '', Region: 'any', SecretKey: '', Token: '', @@ -51,7 +54,7 @@ export default connect(mapStateToProps, mapDispatchToProps)(class extends Compon this.props.notifyError('Remote host already exists'); } else { this.setState({ - Display: false + DisplayRemote: false }, () => { this.props.addRemoteMount(this.state.HostNameOrIp, this.state.Port, this.state.Token); this.setState({ @@ -63,7 +66,28 @@ export default connect(mapStateToProps, mapDispatchToProps)(class extends Compon }; addS3Mount = () => { - + if (this.state.Name.length === 0) { + this.props.notifyError('Name cannot be empty.'); + } else if (this.state.AccessKey.length === 0) { + this.props.notifyError('AccessKey cannot be empty.'); + } else if (this.state.SecretKey.length === 0) { + this.props.notifyError('SecretKey cannot be empty.') + } else { + const provider = 'S3' + this.state.Name; + if (this.props.S3Mounts.includes(provider)) { + this.props.notifyError('Remote host already exists'); + } else { + this.setState({ + DisplayS3: false + }, () => { + this.props.addS3Mount(this.state.Name, this.state.AccessKey, this.state.SecretKey, + this.state.Region, this.state.BucketName, Constants.S3_PROVIDER_URL[this.state.Provider]); + this.setState({ + ...default_state, + }); + }); + } + } }; handleAddS3Mount = () => { @@ -112,21 +136,13 @@ export default connect(mapStateToProps, mapDispatchToProps)(class extends Compon type={'text'} value={this.state.Token}/>
- - - - - - - -
- - - -
+
+ +
+ +
)); @@ -135,33 +151,49 @@ export default connect(mapStateToProps, mapDispatchToProps)(class extends Compon dxStyle={{width: 'auto', height: 'auto', padding: 'var(--default_spacing)'}}>

Add S3 Mount

- - this.setState({Name: e.target.value.trim()})} - className={'ConfigurationItemInput'} - style={{width: '100%'}} - type={'text'} - value={this.state.Name}/> +
+ +
+ +
+
+ this.setState({Name: e.target.value.trim()})} + className={'ConfigurationItemInput'} + style={{width: '100%'}} + type={'text'} + value={this.state.Name}/> +
+ this.setState({Provider: e.target.value})} + items={Constants.S3_PROVIDER_LIST} + selected={Constants.S3_PROVIDER_LIST[0]}/> +
- - this.setState({BucketName: e.target.value})} - className={'ConfigurationItemInput'} - style={{width: '100%'}} - type={'text'} - value={this.state.BucketName}/> +
+ +
+ +
+
+ this.setState({BucketName: e.target.value})} + className={'ConfigurationItemInput'} + style={{width: '100%'}} + type={'text'} + value={this.state.BucketName}/> +
+ this.setState({Region: e.target.value})} + className={'ConfigurationItemInput'} + type={'text'} + value={this.state.Region}/> +
- - this.setState({Region: e.target.value})} - className={'ConfigurationItemInput'} - type={'text'} - value={this.state.Region}/> -
-
- -
- - - - - - - -
- - - -
+
+
+
+ +
+ +
)); diff --git a/src/containers/MountItems/MountItem/MountItem.js b/src/containers/MountItems/MountItem/MountItem.js index 9af80ec..733dbb1 100644 --- a/src/containers/MountItems/MountItem/MountItem.js +++ b/src/containers/MountItems/MountItem/MountItem.js @@ -183,7 +183,7 @@ export default connect(mapStateToProps, mapDispatchToProps)(props => { {((props.provider === 'Skynet') && (props.MState.Mounted)) ? ( { stream.end(() => { if (downloaded === 0) { - completeCallback(Error('Received 0 bytes')); + completeCallback(new Error('Received 0 bytes')); } else if (downloaded !== total) { - completeCallback(Error('Received incorrect number of bytes')); + completeCallback(new Error('Received incorrect number of bytes')); } else { completeCallback(); } @@ -731,7 +731,7 @@ module.exports.getDataDirectory = _getDataDirectory; module.exports.getMissingDependencies = dependencies => { return new Promise((resolve, reject) => { if (!dependencies) { - reject(Error('Dependency list is invalid')); + reject(new Error('Dependency list is invalid')); } let missing = []; @@ -782,7 +782,7 @@ module.exports.getMissingDependencies = dependencies => { hive = Registry.HKU; break; default: - throw Error('Invalid registry hive: ' + hiveName); + throw new Error('Invalid registry hive: ' + hiveName); } const key = dep.registry[index].substr(hiveName.length); @@ -996,8 +996,12 @@ module.exports.setConfigValue = (name, value, provider, remote, s3, version) => reject(err); }); - process.on('exit', () => { - resolve(); + process.on('exit', code => { + if (code !== 0) { + reject(new Error('Failed to set configuration value: ' + code)); + } else { + resolve(); + } }); process.unref(); @@ -1059,7 +1063,7 @@ module.exports.testRepertoryBinary = version => { if (code === 0) { resolve(); } else { - reject(Error('Invalid exit code: ' + code)); + reject(new Error('Invalid exit code: ' + code)); } }) .catch(error => { @@ -1080,7 +1084,7 @@ module.exports.verifyHash = (file, hash) => { command = 'sha256sum'; args = ['-b', file, '-z']; } else { - reject(Error('Platform not supported: ' + os.platform())) + reject(new Error('Platform not supported: ' + os.platform())) } if (command) { execFile(command, args, (err, stdout) => { @@ -1091,7 +1095,7 @@ module.exports.verifyHash = (file, hash) => { if (hash2 === hash.toLowerCase()) { resolve(hash2); } else { - reject(Error('Checksum failed for file')); + reject(new Error('Checksum failed for file')); } } }); @@ -1129,13 +1133,13 @@ module.exports.verifySignature = (file, signatureFile, publicKeyFile) => { } }); } else { - reject(Error('Failed to locate \'openssl.exe\'')); + reject(new Error('Failed to locate \'openssl.exe\'')); } }); } else if (os.platform() === 'linux') { executeVerify('openssl'); } else { - reject(Error('Platform not supported: ' + os.platform())) + reject(new Error('Platform not supported: ' + os.platform())) } }); }; diff --git a/src/redux/actions/mount_actions.js b/src/redux/actions/mount_actions.js index ab8bac0..c747caf 100644 --- a/src/redux/actions/mount_actions.js +++ b/src/redux/actions/mount_actions.js @@ -11,14 +11,15 @@ export const addRemoteMount = (hostNameOrIp, port, token) => { const ipcRenderer = getIPCRenderer(); const provider = 'Remote' + hostNameOrIp + ':' + port; - dispatch(addRemoteMount2(provider)); dispatch(setBusy(true)); ipcRenderer.once(Constants.IPC_Set_Config_Values_Reply, (_, arg) => { if (arg.data.Success) { + dispatch(addRemoteMount2(provider)); ipcRenderer.send(Constants.IPC_Detect_Mount, { Provider: provider, RemoteMounts: getState().mounts.RemoteMounts, + S3Mounts: getState().mounts.S3Mounts, Version: getState().relver.InstalledVersion, }); } else { @@ -42,18 +43,19 @@ export const addRemoteMount = (hostNameOrIp, port, token) => { }; }; -export const addS3Mount = (name, accessKey, secretKey, region, bucketName) => { +export const addS3Mount = (name, accessKey, secretKey, region, bucketName, url) => { return (dispatch, getState) => { const ipcRenderer = getIPCRenderer(); const provider = 'S3' + name; - dispatch(addS3Mount2(provider)); dispatch(setBusy(true)); ipcRenderer.once(Constants.IPC_Set_Config_Values_Reply, (_, arg) => { if (arg.data.Success) { + dispatch(addS3Mount2(provider)); ipcRenderer.send(Constants.IPC_Detect_Mount, { Provider: provider, + RemoteMounts: getState().mounts.RemoteMounts, S3Mounts: getState().mounts.S3Mounts, Version: getState().relver.InstalledVersion, }); @@ -70,6 +72,7 @@ export const addS3Mount = (name, accessKey, secretKey, region, bucketName) => { {Name: 'S3Config.SecretKey', Value: secretKey}, {Name: 'S3Config.Region', Value: region}, {Name: 'S3Config.BucketName', Value: bucketName}, + {Name: 'S3Config.URL', Value: url}, ], Provider: provider, S3: true, diff --git a/src/renderer/ipc/ConfigIPC.js b/src/renderer/ipc/ConfigIPC.js index 8e4796a..81f0e7e 100644 --- a/src/renderer/ipc/ConfigIPC.js +++ b/src/renderer/ipc/ConfigIPC.js @@ -40,8 +40,8 @@ const addListeners = (ipcMain, {standardIPCReply}) => { .then(() => { setConfigValue(++i); }) - .catch(() => { - setConfigValue(++i); + .catch(error => { + standardIPCReply(event, Constants.IPC_Set_Config_Values_Reply, {}, error); }); } else { standardIPCReply(event, Constants.IPC_Set_Config_Values_Reply, {}); diff --git a/src/renderer/ipc/MountsIPC.js b/src/renderer/ipc/MountsIPC.js index a977557..fced82c 100644 --- a/src/renderer/ipc/MountsIPC.js +++ b/src/renderer/ipc/MountsIPC.js @@ -93,6 +93,7 @@ const addListeners = (ipcMain, {setTrayImage, standardIPCReply}) => { const providerList = [ ...Constants.PROVIDER_LIST, ...data.RemoteMounts, + ...data.S3Mounts, ]; for (const provider of providerList) { driveLetters[provider] = [];