Skip to content
This repository was archived by the owner on Jan 7, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions web_hosting_manager/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
1 change: 1 addition & 0 deletions web_hosting_manager/app/actions/actionTypes.js
Original file line number Diff line number Diff line change
@@ -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',
Expand Down
50 changes: 28 additions & 22 deletions web_hosting_manager/app/actions/app.js
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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());
}
})
})
});
};
};

Expand All @@ -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()
};
};

Expand All @@ -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);
})
Expand All @@ -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);
});
Expand All @@ -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())
};
};

Expand All @@ -121,22 +120,22 @@ 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())
};
};

export const getContainer = (containerPath: string) => {
return {
type: ACTION_TYPES.FETCH_CONTAINER,
payload: api.getContainer(containerPath)
payload: api.getServiceContainer(containerPath)
};
};

Expand All @@ -157,15 +156,15 @@ 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
});
};
};

export const cancelUpload = () => {
api.cancelUpload();
api.cancelFileUpload();
const err = new Error(I18n.t('messages.uploadCancelled'));
return {
type: ACTION_TYPES.UPLOAD_FAILED,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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);
})
};
};
Expand All @@ -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
};
};
14 changes: 6 additions & 8 deletions web_hosting_manager/app/components/Auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}
Expand Down
11 changes: 9 additions & 2 deletions web_hosting_manager/app/components/CreateService.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -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)}`);
}
}

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -192,4 +199,4 @@ CreateService.propTypes = {
createContainerAndService: PropTypes.func.isRequired,
createService: PropTypes.func.isRequired,
getPublicContainers: PropTypes.func.isRequired,
}
};
17 changes: 11 additions & 6 deletions web_hosting_manager/app/components/Home.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand All @@ -14,7 +15,8 @@ export default class Auth extends Component {
this.state = {
newPublicId: '',
publicIdVisible: false,
showRemapModal: false
showRemapModal: false,
publicNameErr: ''
};
this.remap = {
containerName: '',
Expand All @@ -31,9 +33,6 @@ export default class Auth extends Component {
}

componentWillUpdate(nextProps) {
if (nextProps.isRevoked) {
nextProps.router.replace('/');
}
if (nextProps.fetchingPublicContainers) {
this.reloadingContainer = true;
}
Expand All @@ -54,15 +53,20 @@ 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;
}
this.props.createPublicId(this.state.newPublicId);
}

cancelpublicId() {
this.setState({ publicNameErr: null });
this.refs.publicId.refs.input.value = '';
this.resetPublicIdModal();
this.props.clearNotification();
}

resetPublicIdModal() {
Expand Down Expand Up @@ -102,7 +106,7 @@ export default class Auth extends Component {
placeholder={I18n.t('label.enterPublicId')}
onPressEnter={this.createPublicId.bind(this)}
/>
<div className="error-msg">{this.props.creatingPublicId ? '' : this.props.publicIdError}</div>
<div className="error-msg withMar">{this.props.creatingPublicId ? '' : this.props.publicIdError || this.state.publicNameErr}</div>
</div>
</Modal>
</div>
Expand Down Expand Up @@ -174,6 +178,7 @@ export default class Auth extends Component {
this.setState({
showRemapModal: false
});
this.props.clearNotification();
}

showRemapModal(service, publicId) {
Expand All @@ -200,7 +205,7 @@ export default class Auth extends Component {
defaultValue={this.state.newPublicId} placeholder={I18n.t('messages.publicIdPlaceholder')}
onPressEnter={this.createPublicId.bind(this)}
/>
<div className="error-msg">{this.props.creatingPublicId ? '' : this.props.publicIdError}</div>
<div className="error-msg">{this.props.creatingPublicId ? '' : this.props.publicIdError || this.state.publicNameErr}</div>
<Button
type="primary" onClick={this.createPublicId.bind(this)}
loading={this.props.creatingPublicId}
Expand Down
9 changes: 8 additions & 1 deletion web_hosting_manager/app/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { initTempFolder } from './lib/temp';
import routes from './routes';
import configureStore from './store/configureStore';
import loadLocale from './locales/loader';
import { connect, onAuthSuccess, onAuthFailure } from './actions/app';
import { connect, onAuthSuccess, onAuthFailure, clearAccessData } from './actions/app';
import './app.global.css';

const store = configureStore();
Expand Down Expand Up @@ -42,6 +42,13 @@ const listenForAuthReponse = (event, response) => {

ipc.on('auth-response', listenForAuthReponse);

ipc.on('clear-access-data', (event, res) => {
if (res) {
store.dispatch(clearAccessData());
}
});


render(
<Provider store={store}>
<Router history={history} routes={routes} />
Expand Down
14 changes: 7 additions & 7 deletions web_hosting_manager/app/lib/Downloader.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import fs from 'fs';
import path from 'path';
import { getPath } from './temp';
import { shell } from 'electron';
import { safe, TAG_TYPE_WWW, accessContainers } from './api';
import safeApi from './api';
import CONSTANTS from './constants';

export default class Downloader {
constructor(networkPath, callback) {
Expand All @@ -12,22 +13,21 @@ export default class Downloader {
}

start() {

const containerPath = {
dir: this.path.split('/').slice(0, 3).join('/'),
file: this.path.split('/').slice(3).join('/')
};
const tokens = this.path.split('/');
const filePath = path.join(getPath(), tokens.pop());

return safe.auth.getContainer(accessContainers.public)
.then((mdata) => mdata.encryptKey(containerPath.dir).then((encKey) => mdata.get(encKey)).then((value) => mdata.decrypt(value.buf)))
.then((val) => safe.mutableData.newPublic(val, TAG_TYPE_WWW))
return safeApi.getPublicContainer()
.then((md) => safeApi.getMDataValueForKey(md, containerPath.dir))
.then((val) => app.mutableData.newPublic(val, CONSTANTS.TAG_TYPE.WWW))
.then((mdata) => {
const nfs = mdata.emulateAs('NFS');
return nfs.fetch(containerPath.file)
.then((file) => {
return safe.immutableData.fetch(file.dataMapName);
})
.then((file) => app.immutableData.fetch(file.dataMapName))
.then((i) => i.read());
})
.then((data) => {
Expand Down
Loading