diff --git a/web_hosting_manager/README.md b/web_hosting_manager/README.md
index 5041c9a..4345736 100644
--- a/web_hosting_manager/README.md
+++ b/web_hosting_manager/README.md
@@ -68,6 +68,11 @@ To run the application without packaging run
$ npm run build
$ npm start
```
+#### Clear Access Data
+#####macOs
+ Click `SAFE Hosting Manager -> Clear Access Data` from the menu.
+#####Windows and Linux
+ Click `File -> Clear Access Data` from the menu.
# License
diff --git a/web_hosting_manager/app/actions/actionTypes.js b/web_hosting_manager/app/actions/actionTypes.js
index 8cdcb3f..33bad11 100644
--- a/web_hosting_manager/app/actions/actionTypes.js
+++ b/web_hosting_manager/app/actions/actionTypes.js
@@ -1,4 +1,5 @@
const ACTION_TYPES = {
+ CLEAR_ACCESS_DATA: 'CLEAR_ACCESS_DATA',
RESET: 'RESET',
AUTH_REQUEST_SENT: 'AUTH_REQUEST_SENT',
AUTH_REQUEST_SEND_FAILED: 'AUTH_REQUEST_SEND_FAILED',
diff --git a/web_hosting_manager/app/actions/app.js b/web_hosting_manager/app/actions/app.js
index 8c0aa1c..a27d41b 100644
--- a/web_hosting_manager/app/actions/app.js
+++ b/web_hosting_manager/app/actions/app.js
@@ -1,8 +1,10 @@
// @flow
-import * as api from '../lib/api';
+import api from '../lib/api';
import { I18n } from 'react-redux-i18n';
import ACTION_TYPES from './actionTypes';
+import CONSTANTS from '../lib/constants';
+import * as utils from '../lib/utils';
const sendAuthRequest = () => {
const action = api.authorise() ? ACTION_TYPES.AUTH_REQUEST_SENT : ACTION_TYPES.AUTH_REQUEST_SEND_FAILED;
@@ -24,19 +26,14 @@ export const revoked = () => {
};
export const connect = (authRes: String) => {
- if (!authRes && !api.hasLocalAuthInfo()) {
+ if (!authRes && !utils.localAuthInfo.get()) {
return sendAuthRequest();
}
return (dispatch) => {
return dispatch({
type: ACTION_TYPES.CONNECT,
payload: api.connect(authRes)
- .then((resType) => {
- if (resType === api.AUTH_RES_TYPES.revoked) {
- return dispatch(revoked());
- }
- })
- })
+ });
};
};
@@ -56,7 +53,7 @@ export const onAuthFailure = (error: Object) => {
export const getAccessInfo = () => {
return {
type: ACTION_TYPES.FETCH_ACCESS_INFO,
- payload: api.fetchAccessInfo()
+ payload: api.canAccessContainers()
};
};
@@ -70,7 +67,7 @@ export const getPublicNames = () => {
export const createPublicId = (publicId: string) => {
return {
type: ACTION_TYPES.CREATE_PUBLIC_ID,
- payload: api.createPublicId(publicId)
+ payload: api.createPublicName(publicId)
.then(() => {
return api.fetchPublicNames(publicId);
})
@@ -82,10 +79,10 @@ export const createContainerAndService = (publicId: string, service: string,
const path = `${parentConatiner}/${publicId}/${conatinerName}`;
return {
type: ACTION_TYPES.CREATE_CONTAINER_AND_SERVICE,
- payload: api.checkServiceExist(publicId, service, path)
+ payload: api.updateServiceIfExist(publicId, service, path)
.then((exist) => {
if (!exist) {
- return api.createContainer(path)
+ return api.createServiceContainer(path)
.then((name) => {
return api.createService(publicId, service, name);
});
@@ -99,7 +96,9 @@ export const createContainerAndService = (publicId: string, service: string,
export const createService = (publicId: string, service: string, containerPath: string) => {
return {
type: ACTION_TYPES.CREATE_SERVICE,
- payload: api.createService(publicId, service, containerPath)
+ payload: api.getServiceContainerMeta(containerPath)
+ .then((meta) => api.createService(publicId, service, meta.name))
+ .then(() => api.fetchServices())
};
};
@@ -121,14 +120,14 @@ export const getServices = () => {
export const getPublicContainers = () => {
return {
type: ACTION_TYPES.FETCH_PUBLIC_CONTAINERS,
- payload: api.getPublicContainers()
+ payload: api.getPublicContainerKeys()
};
};
export const remapService = (service: string, publicId: string, containerPath: string) => {
return {
type: ACTION_TYPES.REMAP_SERVICE,
- payload: api.remapService(service, publicId, containerPath)
+ payload: api.remapService(publicId, service, containerPath)
.then(() => api.fetchServices())
};
};
@@ -136,7 +135,7 @@ export const remapService = (service: string, publicId: string, containerPath: s
export const getContainer = (containerPath: string) => {
return {
type: ACTION_TYPES.FETCH_CONTAINER,
- payload: api.getContainer(containerPath)
+ payload: api.getServiceContainer(containerPath)
};
};
@@ -157,7 +156,7 @@ export const upload = (localPath: string, networkPath: string) => {
payload: error
});
};
- api.upload(localPath, networkPath, progressCallback, errorCallback);
+ api.fileUpload(localPath, networkPath, progressCallback, errorCallback);
dispatch({
type: ACTION_TYPES.UPLOAD_STARTED
});
@@ -165,7 +164,7 @@ export const upload = (localPath: string, networkPath: string) => {
};
export const cancelUpload = () => {
- api.cancelUpload();
+ api.cancelFileUpload();
const err = new Error(I18n.t('messages.uploadCancelled'));
return {
type: ACTION_TYPES.UPLOAD_FAILED,
@@ -178,7 +177,7 @@ export const download = (networkPath: string) => {
dispatch({
type: ACTION_TYPES.DOWNLOAD_STARTED
});
- api.download(networkPath, (err, status) => {
+ api.fileDownload(networkPath, (err, status) => {
if (err) {
return dispatch({
type: ACTION_TYPES.DOWNLOAD_FAILED,
@@ -194,7 +193,7 @@ export const download = (networkPath: string) => {
};
export const cancelDownload = () => {
- api.cancelDownload();
+ api.cancelFileDownload();
const err = new Error(I18n.t('messages.downloadCancelled'));
return {
type: ACTION_TYPES.DOWNLOAD_FAILED,
@@ -205,9 +204,9 @@ export const cancelDownload = () => {
export const deleteItem = (containerPath, name) => {
return {
type: ACTION_TYPES.DELETE,
- payload: api.deleteItem(`${containerPath}/${name}`)
+ payload: api.deleteFileOrDir(`${containerPath}/${name}`)
.then(() => {
- return api.getContainer(containerPath);
+ return api.getServiceContainer(containerPath);
})
};
};
@@ -217,3 +216,10 @@ export const clearNotification = () => {
type: ACTION_TYPES.CLEAR_NOTIFICATION
}
};
+
+export const clearAccessData = () => {
+ utils.localAuthInfo.clear();
+ return {
+ type: ACTION_TYPES.CLEAR_ACCESS_DATA
+ };
+};
diff --git a/web_hosting_manager/app/components/Auth.js b/web_hosting_manager/app/components/Auth.js
index 2a153c1..ad15a82 100644
--- a/web_hosting_manager/app/components/Auth.js
+++ b/web_hosting_manager/app/components/Auth.js
@@ -5,28 +5,26 @@ import { I18n } from 'react-redux-i18n';
export default class Auth extends Component {
componentDidMount() {
- if (!this.props.isRevoked) {
- this.props.connect();
- }
+ this.props.connect();
}
componentWillUpdate(props) {
- if (!this.props.isRevoked && props.fetchedServices && !props.serviceError) {
+ if (props.fetchedServices && !props.serviceError) {
props.router.replace('/home');
}
}
componentDidUpdate() {
- if (this.props.isConnected && !this.props.fetchedAccessInfo && !this.props.accessInfoError) {
+ if (this.props.isConnected && !this.props.fetchingAccessInfo && !this.props.fetchedAccessInfo && !this.props.accessInfoError) {
return this.props.getAccessInfo();
}
- if (this.props.fetchedAccessInfo && !this.props.fetchedPublicNames && !this.props.publicNameError) {
+ if (this.props.fetchedAccessInfo && !this.props.fetchingPublicNames && !this.props.fetchedPublicNames && !this.props.publicNameError) {
return this.props.getPublicNames();
}
- if (this.props.fetchedPublicNames && !this.props.fetchedPublicContainers && !this.props.publicContainersError) {
+ if (this.props.fetchedPublicNames && !this.props.fetchingPublicContainers && !this.props.fetchedPublicContainers && !this.props.publicContainersError) {
return this.props.getPublicContainers();
}
- if (this.props.fetchedPublicContainers && !this.props.fetchedServices && !this.props.serviceError) {
+ if (this.props.fetchedPublicContainers && !this.props.fetchingServices && !this.props.fetchedServices && !this.props.serviceError) {
return this.props.getServices();
}
}
diff --git a/web_hosting_manager/app/components/CreateService.js b/web_hosting_manager/app/components/CreateService.js
index 8321459..019696e 100644
--- a/web_hosting_manager/app/components/CreateService.js
+++ b/web_hosting_manager/app/components/CreateService.js
@@ -2,6 +2,7 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Button, Card, Input, Select, Icon } from 'antd';
import { I18n } from 'react-redux-i18n';
+import { domainCheck } from '../utils/app_utils';
import Nav from './Nav';
@@ -35,7 +36,8 @@ export default class CreateService extends Component {
isCreatingContainerAndService: false
});
} else if (this.props.creatingService && !nextProps.creatingService) {
- this.props.router.goBack();
+ const servicePath = this.state.isCreatingContainerAndService ? `_public/${this.props.params.publicId}/${this.state.containerName}` : this.containerName;
+ this.props.router.replace(`files/${this.state.serviceName}/${this.props.params.publicId}/${encodeURIComponent(servicePath)}`);
}
}
@@ -63,6 +65,11 @@ export default class CreateService extends Component {
containerError: containerNameErrorMsg
});
valid = false;
+ } else if(!domainCheck(this.state.serviceName)) {
+ this.setState({
+ serviceError: I18n.t('messages.serviceNameInvalid')
+ });
+ valid = false;
}
return valid;
}
@@ -192,4 +199,4 @@ CreateService.propTypes = {
createContainerAndService: PropTypes.func.isRequired,
createService: PropTypes.func.isRequired,
getPublicContainers: PropTypes.func.isRequired,
-}
+};
diff --git a/web_hosting_manager/app/components/Home.js b/web_hosting_manager/app/components/Home.js
index 48e1c9e..8393ad5 100644
--- a/web_hosting_manager/app/components/Home.js
+++ b/web_hosting_manager/app/components/Home.js
@@ -5,6 +5,7 @@ import ReactDOM from 'react-dom';
import { I18n } from 'react-redux-i18n';
import { Link } from 'react-router';
import NetworkStatus from './NetworkStatus';
+import { domainCheck } from '../utils/app_utils';
import Nav from './Nav';
@@ -14,7 +15,8 @@ export default class Auth extends Component {
this.state = {
newPublicId: '',
publicIdVisible: false,
- showRemapModal: false
+ showRemapModal: false,
+ publicNameErr: ''
};
this.remap = {
containerName: '',
@@ -31,9 +33,6 @@ export default class Auth extends Component {
}
componentWillUpdate(nextProps) {
- if (nextProps.isRevoked) {
- nextProps.router.replace('/');
- }
if (nextProps.fetchingPublicContainers) {
this.reloadingContainer = true;
}
@@ -54,6 +53,9 @@ export default class Auth extends Component {
}
createPublicId() {
+ if (!domainCheck(this.state.newPublicId)) {
+ return this.setState({ publicNameErr: I18n.t('messages.publicNameInvalid') });
+ }
if (this.props.creatingPublicId) {
return;
}
@@ -61,8 +63,10 @@ export default class Auth extends Component {
}
cancelpublicId() {
+ this.setState({ publicNameErr: null });
this.refs.publicId.refs.input.value = '';
this.resetPublicIdModal();
+ this.props.clearNotification();
}
resetPublicIdModal() {
@@ -102,7 +106,7 @@ export default class Auth extends Component {
placeholder={I18n.t('label.enterPublicId')}
onPressEnter={this.createPublicId.bind(this)}
/>
-
{this.props.creatingPublicId ? '' : this.props.publicIdError}
+ {this.props.creatingPublicId ? '' : this.props.publicIdError || this.state.publicNameErr}
@@ -174,6 +178,7 @@ export default class Auth extends Component {
this.setState({
showRemapModal: false
});
+ this.props.clearNotification();
}
showRemapModal(service, publicId) {
@@ -200,7 +205,7 @@ export default class Auth extends Component {
defaultValue={this.state.newPublicId} placeholder={I18n.t('messages.publicIdPlaceholder')}
onPressEnter={this.createPublicId.bind(this)}
/>
- {this.props.creatingPublicId ? '' : this.props.publicIdError}
+ {this.props.creatingPublicId ? '' : this.props.publicIdError || this.state.publicNameErr}