diff --git a/client/package.json b/client/package.json index 3a8a09a..edd24c3 100644 --- a/client/package.json +++ b/client/package.json @@ -21,7 +21,6 @@ "moment": "^2.24.0", "node-sass": "^4.12.0", "popper.js": "^1.15.0", - "query-string": "^6.5.0", "randomcolor": "^0.5.4", "react": "^16.8.6", "react-dom": "^16.8.6", diff --git a/client/src/actions/app.js b/client/src/actions/app.js index 42e37f5..198dd8f 100644 --- a/client/src/actions/app.js +++ b/client/src/actions/app.js @@ -18,3 +18,11 @@ export const toggleSoundEnabled = payload => async (dispatch) => { export const toggleSocketConnected = payload => async (dispatch) => { dispatch({ type: 'TOGGLE_SOCKET_CONNECTED', payload }) } + +export const createUser = payload => async (dispatch) => { + dispatch({ type: 'CREATE_USER', payload }) +} + +export const clearActivities = () => async (dispatch) => { + dispatch({ type: 'CLEAR_ACTIVITIES' }) +} diff --git a/client/src/actions/encrypted_messages.js b/client/src/actions/encrypted_messages.js new file mode 100644 index 0000000..3fdccea --- /dev/null +++ b/client/src/actions/encrypted_messages.js @@ -0,0 +1,19 @@ +import { getSocket } from 'utils/socket' +import { + prepare as prepareMessage, + process as processMessage, +} from 'utils/message' + +export const sendEncryptedMessage = payload => async (dispatch, getState) => { + const state = getState() + const msg = await prepareMessage(payload, state) + dispatch({ type: `SEND_ENCRYPTED_MESSAGE_${msg.original.type}`, payload: msg.original.payload }) + getSocket().emit('ENCRYPTED_MESSAGE', msg.toSend) +} + +export const receiveEncryptedMessage = payload => async (dispatch, getState) => { + const state = getState() + const message = await processMessage(payload, state) + // Pass current state to all RECEIVE_ENCRYPTED_MESSAGE reducers for convenience, since each may have different needs + dispatch({ type: `RECEIVE_ENCRYPTED_MESSAGE_${message.type}`, payload: { payload: message.payload, state } }) +} \ No newline at end of file diff --git a/client/src/actions/fetch.js b/client/src/actions/fetch.js deleted file mode 100644 index cfa95c8..0000000 --- a/client/src/actions/fetch.js +++ /dev/null @@ -1,12 +0,0 @@ -const methodMap = { - GET: '', - POST: 'CREATE_', - PUT: 'UPDATE_', - DELETE: 'DELETE_', -} - -export const fetchStart = (name, method, resourceId, meta) => ({ type: `FETCH_${methodMap[method]}${name.toUpperCase()}_START`, payload: { resourceId, meta } }) - -export const fetchSuccess = (name, method, response) => ({ type: `FETCH_${methodMap[method]}${name.toUpperCase()}_SUCCESS`, payload: response }) - -export const fetchFailure = (name, method, response) => ({ type: `FETCH_${methodMap[method]}${name.toUpperCase()}_FAILURE`, payload: response }) diff --git a/client/src/actions/index.js b/client/src/actions/index.js index 1297389..3504084 100644 --- a/client/src/actions/index.js +++ b/client/src/actions/index.js @@ -1,4 +1,4 @@ -export * from './fetch' -export * from './room' export * from './app' +export * from './unencrypted_messages' +export * from './encrypted_messages' diff --git a/client/src/actions/room.js b/client/src/actions/room.js deleted file mode 100644 index 83b0d96..0000000 --- a/client/src/actions/room.js +++ /dev/null @@ -1,104 +0,0 @@ -import fetch from 'api' -import isEqual from 'lodash/isEqual' -import { - process as processMessage, - prepare as prepareMessage, -} from 'utils/message' -import { getSocket } from 'utils/socket' - -export const receiveSocketMessage = payload => async (dispatch, getState) => { - const state = getState() - const message = await processMessage(payload, state) - // Pass current state to all HANDLE_SOCKET_MESSAGE reducers for convenience, since each may have different needs - dispatch({ type: `HANDLE_SOCKET_MESSAGE_${message.type}`, payload: { payload: message.payload, state } }) -} - -export const createUser = payload => async (dispatch) => { - dispatch({ type: 'CREATE_USER', payload }) -} - -export const sendUserEnter = payload => async () => { - getSocket().emit('USER_ENTER', { - publicKey: payload.publicKey, - }) -} - -export const receiveUserExit = payload => async (dispatch, getState) => { - const state = getState() - const exitingUser = state.room.members.find(m => !payload.map(p => JSON.stringify(p.publicKey)).includes(JSON.stringify(m.publicKey))) - - if (!exitingUser) { - return; - } - - const exitingUserId = exitingUser.id - const exitingUsername = exitingUser.username - - dispatch({ - type: 'USER_EXIT', - payload: { - members: payload, - id: exitingUserId, - username: exitingUsername, - }, - }) -} - -export const receiveUserEnter = payload => async (dispatch) => { - dispatch({ type: 'USER_ENTER', payload }) -} - -export const onFileTransfer = payload => async (dispatch) => { - dispatch({ type: 'PREFLIGHT_FILE_TRANSFER', payload }) -} - -export const sendSocketMessage = payload => async (dispatch, getState) => { - const state = getState() - const msg = await prepareMessage(payload, state) - dispatch({ type: `SEND_SOCKET_MESSAGE_${msg.original.type}`, payload: msg.original.payload }) - getSocket().emit('PAYLOAD', msg.toSend) -} - -export const toggleLockRoom = () => async (dispatch, getState) => { - const state = getState() - getSocket().emit('TOGGLE_LOCK_ROOM', null, (res) => { - dispatch({ - type: 'TOGGLE_LOCK_ROOM', - payload: { - locked: res.isLocked, - username: state.user.username, - sender: state.user.id, - }, - }) - }) -} - -export const receiveToggleLockRoom = payload => async (dispatch, getState) => { - const state = getState() - - const lockedByUser = state.room.members.find(m => isEqual(m.publicKey, payload.publicKey)) - const lockedByUsername = lockedByUser.username - const lockedByUserId = lockedByUser.id - - dispatch({ - type: 'RECEIVE_TOGGLE_LOCK_ROOM', - payload: { - username: lockedByUsername, - locked: payload.locked, - id: lockedByUserId, - }, - }) -} - -export const clearActivities = () => async (dispatch) => { - dispatch({ type: 'CLEAR_ACTIVITIES' }) -} - -export const onConnected = payload => async (dispatch) => { - dispatch({ type: 'CONNECTED', payload }) -} - -export const sendUserDisconnect = () => async () => { - getSocket().emit('USER_DISCONNECT') -} - diff --git a/client/src/actions/unencrypted_messages.js b/client/src/actions/unencrypted_messages.js new file mode 100644 index 0000000..af251df --- /dev/null +++ b/client/src/actions/unencrypted_messages.js @@ -0,0 +1,80 @@ +import { getSocket } from 'utils/socket' + +const receiveUserEnter = (payload, dispatch) => { + dispatch({ type: 'USER_ENTER', payload }) +} + +const receiveToggleLockRoom = (payload, dispatch, getState) => { + const state = getState() + + const lockedByUser = state.room.members.find(m => m.publicKey.n === payload.publicKey.n) + const lockedByUsername = lockedByUser.username + const lockedByUserId = lockedByUser.id + + dispatch({ + type: 'RECEIVE_TOGGLE_LOCK_ROOM', + payload: { + username: lockedByUsername, + locked: payload.locked, + id: lockedByUserId, + }, + }) +} + +const receiveUserExit = (payload, dispatch, getState) => { + const state = getState() + const payloadPublicKeys = payload.map(member => member.publicKey.n); + const exitingUser = state.room.members.find(m => !payloadPublicKeys.includes(m.publicKey.n)) + + if (!exitingUser) { + return; + } + + const exitingUserId = exitingUser.id + const exitingUsername = exitingUser.username + + dispatch({ + type: 'USER_EXIT', + payload: { + members: payload, + id: exitingUserId, + username: exitingUsername, + }, + }) +} + +export const receiveUnencryptedMessage = (type, payload) => async (dispatch, getState) => { + switch(type) { + case 'USER_ENTER': + return receiveUserEnter(payload, dispatch); + case 'USER_EXIT': + return receiveUserExit(payload, dispatch, getState); + case 'TOGGLE_LOCK_ROOM': + return receiveToggleLockRoom(payload, dispatch, getState); + default: + return; + } +} + +const sendToggleLockRoom = (dispatch, getState) => { + const state = getState() + getSocket().emit('TOGGLE_LOCK_ROOM', null, (res) => { + dispatch({ + type: 'TOGGLE_LOCK_ROOM', + payload: { + locked: res.isLocked, + username: state.user.username, + sender: state.user.id, + }, + }) + }) +} + +export const sendUnencryptedMessage = (type, payload) => async (dispatch, getState) => { + switch(type) { + case 'TOGGLE_LOCK_ROOM': + return sendToggleLockRoom(dispatch, getState); + default: + return; + } +} \ No newline at end of file diff --git a/client/src/api/index.js b/client/src/api/index.js deleted file mode 100644 index b4f627e..0000000 --- a/client/src/api/index.js +++ /dev/null @@ -1,59 +0,0 @@ -import { - fetchStart, - fetchSuccess, - fetchFailure, -} from 'actions' -import queryString from 'querystring' -import generateUrl from './generator' - -export default (opts, dispatch, name, metaOpts = {}) => { - const method = opts.method || 'GET' - const resourceId = opts.resourceId - let url = generateUrl(opts.resourceName, resourceId) - - const config = { - method, - headers: {}, - type: 'cors', - } - - if (opts.body) { - config.body = JSON.stringify(opts.body) - config.headers['Content-Type'] = 'application/json' - } - - if (opts.query) { - url = `${url}?${queryString.stringify(opts.query)}` - } - - return new Promise((resolve, reject) => { - const meta = { ...metaOpts, timestamp: Date.now() } - dispatch(fetchStart(name, method, resourceId, meta)) - return window.fetch(url, config) - .then(async (response) => { - let json = {} - - try { - json = await response.json() - } catch (e) { - throw new Error(e) - } - - const dispatchOps = { - response, - json, - resourceId, - meta, - } - - if (response.ok) { - dispatch(fetchSuccess(name, method, dispatchOps)) - return resolve(dispatchOps) - } - - dispatch(fetchFailure(name, method, dispatchOps)) - - return reject(dispatchOps) - }) - }) -} diff --git a/client/src/components/About/index.js b/client/src/components/About/index.js index 71885c6..ee45c05 100644 --- a/client/src/components/About/index.js +++ b/client/src/components/About/index.js @@ -71,7 +71,7 @@ class About extends Component {