diff --git a/packages/common/actions/entities/item.js b/packages/common/actions/entities/item.js index 8d70db60f..af64b268b 100644 --- a/packages/common/actions/entities/item.js +++ b/packages/common/actions/entities/item.js @@ -311,11 +311,11 @@ export const createAnonymousLinkRequest = () => ({ type: CREATE_ANONYMOUS_LINK_REQUEST, }); -export const createAnonymousLinkSuccess = (itemId, share) => ({ +export const createAnonymousLinkSuccess = (itemId, shared) => ({ type: CREATE_ANONYMOUS_LINK_SUCCESS, payload: { itemId, - share, + shared, }, }); diff --git a/packages/common/actions/entities/member.js b/packages/common/actions/entities/member.js index 1584fa5c5..cff30b26a 100644 --- a/packages/common/actions/entities/member.js +++ b/packages/common/actions/entities/member.js @@ -58,11 +58,12 @@ export const fetchTeamMembersFailure = () => ({ type: FETCH_TEAM_MEMBERS_FAILURE, }); -export const createMemberRequest = (email, role) => ({ +// @Deprecated +export const createMemberRequest = (email, teamRole) => ({ type: CREATE_MEMBER_REQUEST, payload: { email, - role, + teamRole, }, }); @@ -77,11 +78,11 @@ export const createMemberFailure = () => ({ type: CREATE_MEMBER_FAILURE, }); -export const createMemberBatchRequest = (email, role) => ({ +export const createMemberBatchRequest = (email, teamRole) => ({ type: CREATE_MEMBER_BATCH_REQUEST, payload: { email, - role, + teamRole, }, }); diff --git a/packages/common/actions/entities/user.js b/packages/common/actions/entities/user.js index d1ab883b5..e94c3b99f 100644 --- a/packages/common/actions/entities/user.js +++ b/packages/common/actions/entities/user.js @@ -2,6 +2,10 @@ export const FETCH_USERS_REQUEST = '@user/FETCH_USERS_REQUEST'; export const FETCH_USERS_SUCCESS = '@user/FETCH_USERS_SUCCESS'; export const FETCH_USERS_FAILURE = '@user/FETCH_USERS_FAILURE'; +export const CREATE_USER_REQUEST = '@user/CREATE_USER_REQUEST'; +export const CREATE_USER_SUCCESS = '@user/CREATE_USER_SUCCESS'; +export const CREATE_USER_FAILURE = '@user/CREATE_USER_FAILURE'; + export const RESET_USER_STATE = '@user/RESET_USER_STATE'; export const fetchUsersRequest = () => ({ @@ -19,6 +23,22 @@ export const fetchUsersFailure = () => ({ type: FETCH_USERS_FAILURE, }); +export const createUserRequest = payload => ({ + type: CREATE_USER_REQUEST, + payload, +}); + +export const createUserSuccess = user => ({ + type: CREATE_USER_SUCCESS, + payload: { + user, + }, +}); + +export const createUserFailure = () => ({ + type: CREATE_USER_FAILURE, +}); + export const resetUserState = () => ({ type: RESET_USER_STATE, }); diff --git a/packages/common/actions/workflow.js b/packages/common/actions/workflow.js index 1d5487da4..b13ad23bd 100644 --- a/packages/common/actions/workflow.js +++ b/packages/common/actions/workflow.js @@ -6,6 +6,7 @@ export const INIT_TEAM_SETTINGS = '@workflow/INIT_TEAM_SETTINGS'; export const INIT_IMPORT_SETTINGS = '@workflow/INIT_IMPORT_SETTINGS'; export const INIT_CREATE_PAGE = '@workflow/INIT_CREATE_PAGE'; export const INIT_DASHBOARD = '@workflow/INIT_DASHBOARD'; +export const INIT_SHARE = '@workflow/INIT_SHARE'; export const FINISH_PROCESSING_KEYPAIRS = '@workflow/FINISH_PROCESSING_KEYPAIRS'; @@ -69,6 +70,10 @@ export const initDashboard = () => ({ type: INIT_DASHBOARD, }); +export const initShare = () => ({ + type: INIT_SHARE, +}); + export const finishProcessingKeyPairs = () => ({ type: FINISH_PROCESSING_KEYPAIRS, }); diff --git a/packages/common/api.js b/packages/common/api.js index 58806c8ec..78bf49412 100755 --- a/packages/common/api.js +++ b/packages/common/api.js @@ -146,9 +146,9 @@ export const deleteTeam = teamId => callApi.delete(`/teams/${teamId}`); export const getTeamMembers = teamId => callApi.get(`/teams/${teamId}/members`); export const getDefaultTeamMembers = () => callApi.get('/teams/default/members'); -export const postAddTeamMember = ({ teamId, userId, role, secret }) => +export const postAddTeamMember = ({ teamId, userId, teamRole, secret }) => callApi.post(`/teams/${teamId}/members/${userId}`, { - teamRole: role, + teamRole, secret, }); export const updateTeamMember = ({ teamId, userId, teamRole }) => @@ -209,7 +209,6 @@ export const getLastUpdatedUserItems = ( export const postItemShare = ({ itemId, users }) => callApi.post(`/items/${itemId}/share`, { users }); -export const getCheckShare = id => callApi.get(`/anonymous/share/${id}/check`); // item batch export const postCreateItemsBatch = data => callApi.post('/items/batch', data); diff --git a/packages/common/reducers/entities/item.js b/packages/common/reducers/entities/item.js index 6f14e3cd7..e6a21786e 100644 --- a/packages/common/reducers/entities/item.js +++ b/packages/common/reducers/entities/item.js @@ -240,7 +240,7 @@ export default createReducer(initialState, { ...state.byId, [payload.itemId]: { ...state.byId[payload.itemId], - shared: payload.share, + shared: payload.shared, }, }, }; diff --git a/packages/common/reducers/entities/user.js b/packages/common/reducers/entities/user.js index fbace84e8..b9387b51d 100644 --- a/packages/common/reducers/entities/user.js +++ b/packages/common/reducers/entities/user.js @@ -3,6 +3,9 @@ import { FETCH_USERS_REQUEST, FETCH_USERS_SUCCESS, FETCH_USERS_FAILURE, + CREATE_USER_REQUEST, + CREATE_USER_SUCCESS, + CREATE_USER_FAILURE, RESET_USER_STATE, } from '@caesar/common/actions/entities/user'; @@ -27,6 +30,21 @@ export default createReducer(initialState, { [FETCH_USERS_FAILURE](state) { return { ...state, isLoading: false, isError: true }; }, + [CREATE_USER_REQUEST](state) { + return state; + }, + [CREATE_USER_SUCCESS](state, { payload }) { + return { + ...state, + byId: { + ...state.byId, + [payload.user.id]: payload.user, + }, + }; + }, + [CREATE_USER_FAILURE](state) { + return state; + }, [RESET_USER_STATE]() { return initialState; }, diff --git a/packages/common/sagas/common/anonymous.js b/packages/common/sagas/common/anonymous.js index e65fdb91f..c81e33be5 100644 --- a/packages/common/sagas/common/anonymous.js +++ b/packages/common/sagas/common/anonymous.js @@ -1,10 +1,7 @@ import { put, call, takeLatest, select } from 'redux-saga/effects'; import { workInProgressItemSelector } from '@caesar/common/selectors/workflow'; -import { - encryptItem, - generateAnonymousEmail, -} from '@caesar/common/utils/cipherUtils'; -import { createMemberSaga } from '@caesar/common/sagas/entities/member'; +import { generateAnonymousEmail } from '@caesar/common/utils/item'; +import { createUserSaga } from '@caesar/common/sagas/entities/user'; import { DOMAIN_ROLES } from '@caesar/common/constants'; import { generateSharingUrl } from '@caesar/common/utils/sharing'; import { objectToBase64 } from '@caesar/common/utils/base64'; @@ -19,62 +16,44 @@ import { import { updateWorkInProgressItem } from '@caesar/common/actions/workflow'; import { updateGlobalNotification } from '@caesar/common/actions/application'; import { getServerErrorMessage } from '@caesar/common/utils/error'; +import { shareItemBatchSaga } from './share'; export function* createAnonymousLinkSaga() { try { const workInProgressItem = yield select(workInProgressItemSelector); - const email = generateAnonymousEmail(); + const email = generateAnonymousEmail(workInProgressItem.id); - const { - id: userId, - name, - password, - masterPassword, - publicKey, - } = yield call(createMemberSaga, { + const createdUser = yield call(createUserSaga, { payload: { email, - role: DOMAIN_ROLES.ROLE_ANONYMOUS_USER, + domainRole: DOMAIN_ROLES.ROLE_ANONYMOUS_USER, }, }); - // TODO: Add new flow of sharing with keipair.share - // eslint-disable-next-line no-console - console.warn('Not yet implemented'); - const encryptedSecret = yield call( - encryptItem, - workInProgressItem.data, - publicKey, - ); + const { plainPassword: password, masterPassword } = createdUser; - const item = { - id: 'itemId', - secret: encryptedSecret, - }; + yield call(shareItemBatchSaga, { + payload: { + data: { itemIds: [workInProgressItem.id], members: [createdUser] }, + }, + }); // TODO: Make shorted link const link = generateSharingUrl( - item.id, objectToBase64({ e: email, p: password, - mp: masterPassword, + m: masterPassword, }), ); - const share = { - id: item.id, - userId, - email, - name, - link, - publicKey, - isAccepted: false, - domainRoles: [DOMAIN_ROLES.ROLE_ANONYMOUS_USER], - }; + // TODO: Rename here and on backend to 'anonymLink' or move to secret + // TODO: Encrypt with user key => maybe in secret + const shared = link; - yield put(createAnonymousLinkSuccess(workInProgressItem.id, share)); + // TODO: Add request to update 'shared' item + yield put(createAnonymousLinkSuccess(workInProgressItem.id, shared)); yield put(updateWorkInProgressItem()); } catch (error) { // eslint-disable-next-line no-console diff --git a/packages/common/sagas/common/invite.js b/packages/common/sagas/common/invite.js index 8cea33642..909b68666 100644 --- a/packages/common/sagas/common/invite.js +++ b/packages/common/sagas/common/invite.js @@ -11,7 +11,7 @@ export function* inviteNewMemberBatchSaga({ payload: { members } }) { objectToBase64({ e: email, p: password, - mp: masterPassword, + m: masterPassword, }), ), })); diff --git a/packages/common/sagas/entities/item.js b/packages/common/sagas/entities/item.js index 1ef5e290f..51d6af46d 100644 --- a/packages/common/sagas/entities/item.js +++ b/packages/common/sagas/entities/item.js @@ -744,7 +744,7 @@ export function* updateItemSaga({ payload: { item } }) { export function* editItemSaga({ payload: { item }, - meta: { setSubmitting, notification }, + meta: { setSubmitting = Function.prototype, notification } = {}, }) { try { const { @@ -780,9 +780,12 @@ export function* editItemSaga({ } yield put(updateWorkInProgressItem(item.id)); - yield call(notification.show, { - text: `The '${item.data.name}' has been updated`, - }); + + if (notification) { + yield call(notification.show, { + text: `The '${item.data.name}' has been updated`, + }); + } } catch (error) { // eslint-disable-next-line no-console console.error(error); diff --git a/packages/common/sagas/entities/member.js b/packages/common/sagas/entities/member.js index 3b54109c3..30a44954e 100644 --- a/packages/common/sagas/entities/member.js +++ b/packages/common/sagas/entities/member.js @@ -60,6 +60,7 @@ const setNewFlag = (members, isNew) => const renameUserId = members => members.map(({ userId, ...member }) => ({ id: userId, ...member })); +// TODO: replace with create user export function* createMemberSaga({ payload: { email, role } }) { try { const { password, masterPassword, publicKey, privateKey } = yield call( @@ -102,6 +103,7 @@ export function* createMemberSaga({ payload: { email, role } }) { } } +// TODO: replace with create user batch export function* createMemberBatchSaga({ payload: { emailRolePairs } }) { try { if (!emailRolePairs.length) { @@ -176,6 +178,7 @@ export function* createMemberBatchSaga({ payload: { emailRolePairs } }) { } } +// TODO: For what stuff do we need it? export function* getOrCreateMemberBatchSaga({ payload: { emailRolePairs } }) { try { const emailRoleObject = emailRolePairs.reduce( @@ -239,7 +242,7 @@ export function* getOrCreateMemberBatchSaga({ payload: { emailRolePairs } }) { } } -export function* addMemberToTeamListsBatchSaga({ payload: { teamId, users } }) { +export function* addTeamMembersBatchSaga({ payload: { teamId, users } }) { try { const keypair = yield select(teamKeyPairSelector, { teamId }); const userIds = users.map(user => user.id); @@ -330,10 +333,7 @@ export default function* memberSagas() { yield takeLatest(CREATE_MEMBER_REQUEST, createMemberSaga); yield takeLatest(CREATE_MEMBER_BATCH_REQUEST, createMemberBatchSaga); yield takeLatest(FETCH_TEAM_MEMBERS_REQUEST, fetchTeamMembersSaga); - yield takeLatest( - ADD_TEAM_MEMBERS_BATCH_REQUEST, - addMemberToTeamListsBatchSaga, - ); + yield takeLatest(ADD_TEAM_MEMBERS_BATCH_REQUEST, addTeamMembersBatchSaga); yield takeLatest(UPDATE_TEAM_MEMBER_ROLE_REQUEST, updateTeamMemberRoleSaga); yield takeLatest(REMOVE_TEAM_MEMBER_REQUEST, removeTeamMemberSaga); } diff --git a/packages/common/sagas/entities/team.js b/packages/common/sagas/entities/team.js index c5ef15506..d543fc527 100644 --- a/packages/common/sagas/entities/team.js +++ b/packages/common/sagas/entities/team.js @@ -44,7 +44,7 @@ import { pinTeam, } from '@caesar/common/api'; import { fetchUsersSaga } from '@caesar/common/sagas/entities/user'; -import { addMemberToTeamListsBatchSaga } from '@caesar/common/sagas/entities/member'; +import { addTeamMembersBatchSaga } from '@caesar/common/sagas/entities/member'; import { getServerErrorMessage, getServerErrors, @@ -296,7 +296,7 @@ export function* createTeamSaga({ ); if (adminsToInvite.length > 0 && serverTeam?.id) { - yield call(addMemberToTeamListsBatchSaga, { + yield call(addTeamMembersBatchSaga, { payload: { teamId: serverTeam?.id, users: adminsToInvite, diff --git a/packages/common/sagas/entities/user.js b/packages/common/sagas/entities/user.js index c6ef1e794..afbb4ba6b 100644 --- a/packages/common/sagas/entities/user.js +++ b/packages/common/sagas/entities/user.js @@ -3,9 +3,18 @@ import { FETCH_USERS_REQUEST, fetchUsersSuccess, fetchUsersFailure, + CREATE_USER_REQUEST, + createUserSuccess, + createUserFailure, } from '@caesar/common/actions/entities/user'; -import { getUsers } from '@caesar/common/api'; +import { getUsers, postNewUser } from '@caesar/common/api'; import { convertUsersToEntity } from '@caesar/common/normalizers/normalizers'; +import { + generateSeedAndVerifier, + generateUser, + generateUsersBatch, +} from '@caesar/common/utils/cipherUtils'; +import { ENTITY_TYPE, DOMAIN_ROLES } from '@caesar/common/constants'; export function* fetchUsersSaga() { try { @@ -19,6 +28,43 @@ export function* fetchUsersSaga() { } } +export function* createUserSaga({ payload: { email, domainRole } }) { + try { + const { password, masterPassword, publicKey, privateKey } = yield call( + generateUser, + email, + ); + + const { seed, verifier } = generateSeedAndVerifier(email, password); + + const data = { + email, + plainPassword: password, + publicKey, + encryptedPrivateKey: privateKey, + seed, + verifier, + domainRoles: [domainRole], + }; + + const { data: user } = yield call(postNewUser, data); + + if (domainRole === DOMAIN_ROLES.ROLE_ANONYMOUS_USER) { + return { ...data, ...user, masterPassword }; + } + + const convertedUser = convertUsersToEntity([{ ...data, ...user }]); + yield put(createUserSuccess(convertedUser)); + + return convertedUser[user.id]; + } catch (error) { + yield put(createUserFailure()); + + return null; + } +} + export default function* userSagas() { yield takeLatest(FETCH_USERS_REQUEST, fetchUsersSaga); + yield takeLatest(CREATE_USER_REQUEST, createUserSaga); } diff --git a/packages/common/sagas/workflow.js b/packages/common/sagas/workflow.js index a38af38d6..06daf2dd1 100644 --- a/packages/common/sagas/workflow.js +++ b/packages/common/sagas/workflow.js @@ -14,6 +14,7 @@ import { INIT_TEAMS_SETTINGS, INIT_TEAM_SETTINGS, INIT_IMPORT_SETTINGS, + INIT_SHARE, UPDATE_WORK_IN_PROGRESS_ITEM, SET_WORK_IN_PROGRESS_ITEM, finishIsLoading, @@ -655,7 +656,9 @@ function* getItemKeyPair({ function* decryptItemRaws({ payload: { item } }) { try { // If item is null or aready had decypted attachments then do not dectrypt again! - if (!item || (item?.data?.raws && Object.values(item?.data?.raws) > 0)) return; + if (!item || (item?.data?.raws && Object.values(item?.data?.raws) > 0)) { + return; + } const { raws } = JSON.parse(item.secret); @@ -762,6 +765,15 @@ function* initImportSettingsSaga() { } } +function* initShareSaga() { + try { + console.log('Implement init share flow'); + } catch (error) { + // eslint-disable-next-line no-console + console.error('error: ', error); + } +} + function* vaultsReadySaga() { yield call(initTeamsSaga); yield put(vaultsReady()); @@ -790,6 +802,7 @@ export default function* workflowSagas() { yield takeLatest(INIT_TEAMS_SETTINGS, initTeamsSettingsSaga); yield takeLatest(INIT_TEAM_SETTINGS, initTeamSettingsSaga); yield takeLatest(INIT_IMPORT_SETTINGS, initImportSettingsSaga); + yield takeLatest(INIT_SHARE, initShareSaga); yield takeLatest(SET_WORK_IN_PROGRESS_ITEM, setWorkInProgressItemSaga); yield takeLatest(UPDATE_WORK_IN_PROGRESS_ITEM, updateWorkInProgressItemSaga); diff --git a/packages/common/selectors/workflow.js b/packages/common/selectors/workflow.js index 0a4d16def..ab1da79f7 100644 --- a/packages/common/selectors/workflow.js +++ b/packages/common/selectors/workflow.js @@ -92,7 +92,11 @@ export const workInProgressItemSharedMembersSelector = createSelector( workInProgressItemSelector, usersByIdSelector, (workInProgressItem, usersById) => - workInProgressItem?.invited?.map(userId => usersById[userId]) || [], + workInProgressItem?.invited?.reduce((acc, userId) => { + const user = usersById[userId]; + + return user ? [...acc, user] : acc; + }, []) || [], ); export const isDecryptionProgressSelector = createSelector( diff --git a/packages/common/utils/cipherUtils.js b/packages/common/utils/cipherUtils.js index 6029e28f5..340f5031d 100644 --- a/packages/common/utils/cipherUtils.js +++ b/packages/common/utils/cipherUtils.js @@ -1,7 +1,5 @@ import * as openpgp from 'openpgp'; import { generateKeys } from './key'; -import { getHostName } from './getDomainName'; -import { randomId } from './uuid4'; import { objectToBase64, base64ToObject } from './base64'; import { createSrp } from './srp'; import { passwordGenerator } from './passwordGenerator'; @@ -112,9 +110,6 @@ export const generateUsersBatch = async emails => { })); }; -export const generateAnonymousEmail = () => - `anonymous_${randomId()}@${getHostName()}`; - export const generateSeedAndVerifier = (email, password) => { const seed = srp.getRandomSeed(); const verifier = srp.generateV(srp.generateX(seed, email, password)); diff --git a/packages/common/utils/item.js b/packages/common/utils/item.js index 75c69cd89..12ab914f5 100644 --- a/packages/common/utils/item.js +++ b/packages/common/utils/item.js @@ -1,7 +1,8 @@ import { getHostName } from '@caesar/common/utils/getDomainName'; +import { ITEM_TYPE, DOMAIN_HOSTNAME } from '../constants'; import { processUploadedFiles } from './attachment'; import { decryptItem } from './cipherUtils'; -import { ITEM_TYPE, DOMAIN_HOSTNAME } from '../constants'; +import { randomId } from './uuid4'; export const extractItemType = item => item?.type || ITEM_TYPE.SYSTEM; @@ -56,6 +57,9 @@ export const generateSystemItemEmail = entityName => { return `systems+${entityName}@${DOMAIN_HOSTNAME || getHostName()}`; }; +export const generateAnonymousEmail = itemId => + `anonymous+${itemId}-${randomId()}@${DOMAIN_HOSTNAME || getHostName()}`; + export const extractKeysFromSystemItem = item => { const itemRaws = item.data?.raws || { publicKey: null, diff --git a/packages/common/utils/sharing.js b/packages/common/utils/sharing.js index 1fe12f8f5..57292ef4b 100644 --- a/packages/common/utils/sharing.js +++ b/packages/common/utils/sharing.js @@ -1,7 +1,7 @@ import { APP_URI } from '@caesar/common/constants'; -export const generateSharingUrl = (shareId, encryption) => - `${APP_URI}/share/${shareId}/${encryption}`; +export const generateSharingUrl = encryption => + `${APP_URI}/share/${encryption}`; export const generateInviteUrl = encryption => `${APP_URI}/invite/${encryption}`; diff --git a/packages/components/InviteModal/InviteModal.js b/packages/components/InviteModal/InviteModal.js index 5dec1ada5..54778814b 100755 --- a/packages/components/InviteModal/InviteModal.js +++ b/packages/components/InviteModal/InviteModal.js @@ -50,11 +50,11 @@ class InviteModal extends Component { })); }; - handleChangeRole = changedRoleMember => (_, role) => { + handleChangeRole = updatedMember => (_, teamRole) => { this.setState(prevState => ({ ...prevState, users: prevState.users.map(member => - member.id === changedRoleMember.id ? { ...member, role } : member, + member.id === updatedMember.id ? { ...member, role: teamRole } : member, ), })); }; diff --git a/packages/components/Item/components/OwnerAndShares.js b/packages/components/Item/components/OwnerAndShares.js index b33622221..2c4a9a3f6 100755 --- a/packages/components/Item/components/OwnerAndShares.js +++ b/packages/components/Item/components/OwnerAndShares.js @@ -55,6 +55,7 @@ const NoMembers = styled.div` `; const ShareButton = styled.button` + flex: 0 0 40px; width: 40px; height: 40px; padding: 0; diff --git a/packages/components/ShareModal/ShareModal.js b/packages/components/ShareModal/ShareModal.js index d09fec683..0d4677cd2 100644 --- a/packages/components/ShareModal/ShareModal.js +++ b/packages/components/ShareModal/ShareModal.js @@ -86,7 +86,6 @@ export const ShareModal = ({ onRevokeAccess = Function.prototype, onRemove = Function.prototype, }) => { - const disableAnonymLink = true; const [members, setMembers] = useState([]); const [teamIds, setTeamIds] = useState([]); const [isOpenedInvited, setOpenedInvited] = useState(false); @@ -210,7 +209,7 @@ export const ShareModal = ({ )} - {!disableAnonymLink && !isMultiMode && ( + {!isMultiMode && ( (shared && shared.link) || null; +export const getAnonymousLink = shared => shared || null; export const hideLink = link => `${APP_URI}/${link diff --git a/packages/containers/Bootstrap/Bootstrap.js b/packages/containers/Bootstrap/Bootstrap.js index c1db7f0cb..f1d12bfad 100644 --- a/packages/containers/Bootstrap/Bootstrap.js +++ b/packages/containers/Bootstrap/Bootstrap.js @@ -62,7 +62,7 @@ class Bootstrap extends Component { currentUser?.domainRoles?.includes(DOMAIN_ROLES.ROLE_ANONYMOUS_USER) || currentUser?.domainRoles?.includes(DOMAIN_ROLES.ROLE_READ_ONLY_USER); - if (!currentUser || (isAnonymousOrReadOnlyUser && !shared?.mp)) { + if (!currentUser || (isAnonymousOrReadOnlyUser && !shared?.m)) { logout(); } @@ -216,7 +216,7 @@ class Bootstrap extends Component { initialStep={currentStep} navigationSteps={this.navigationPanelSteps} currentUser={this.currentUser} - sharedMasterPassword={shared.mp} + sharedMasterPassword={shared.m} masterPassword={IS_PROD ? null : this.props.masterPassword} onFinish={this.handleFinishMasterPassword} /> @@ -225,7 +225,7 @@ class Bootstrap extends Component { // if user is using sharing url and master password is included inside share // url we don't turn on LockScreen via SessionChecker(onFinishTimeout) - if (currentStep === BOOTSTRAP_FINISH && shared.mp) { + if (currentStep === BOOTSTRAP_FINISH && shared.m) { return ( { - const inbox = list.find(({ type }) => type === LIST_TYPE.INBOX); +const SharingComponent = () => { + const item = null; + const dispatch = useDispatch(); - if (!inbox || !inbox.children) { + useEffectOnce(() => { + dispatch(initShare()); + }); + + if (!item) { return null; } - return inbox.children[0]; + return ( + + + + ); }; -class SharingComponent extends Component { - state = this.prepareInitialState(); - - async componentDidMount() { - const { privateKey, password } = this.props; - - const { data: list } = await getLists(); - - const item = getInboxItem(list); - - const privateKeyObj = await unsealPrivateKeyObj(privateKey, password); - const decryptedSecret = await decryptItem(item.secret, privateKeyObj); - - this.setState({ - item: { ...item, data: decryptedSecret }, - }); - } - - prepareInitialState() { - return { - item: null, - }; - } - - render() { - const { item } = this.state; - - if (!item) { - return null; - } - - const itemSubject = { - __typename: PERMISSION_ENTITY.ITEM, - }; - - return ( - - - - ); - } -} - -const Sharing = memo(SharingComponent); - -export default Sharing; +export const Sharing = memo(SharingComponent); diff --git a/packages/containers/Sharing/index.js b/packages/containers/Sharing/index.js index ee5798316..b1498b4e0 100644 --- a/packages/containers/Sharing/index.js +++ b/packages/containers/Sharing/index.js @@ -1 +1 @@ -export { default as Sharing } from './Sharing'; +export { Sharing } from './Sharing'; diff --git a/packages/containers/Team/Team.js b/packages/containers/Team/Team.js index b3150d7aa..95b16e371 100644 --- a/packages/containers/Team/Team.js +++ b/packages/containers/Team/Team.js @@ -67,7 +67,7 @@ export const TeamContainer = ({ currentUser, team, members }) => { const measuredRef = useCallback(node => { if (node !== null) { setTableWidth(node.getBoundingClientRect().width); - // To calculate where roleDropdown must be opened + // To calculate where teamRoleDropdown must be opened setTableRowGroupNode(node.children[0]?.children[1].children[0]); } }, []); diff --git a/packages/containers/Team/createColumns.js b/packages/containers/Team/createColumns.js index ceabd30fe..4a4747fb6 100644 --- a/packages/containers/Team/createColumns.js +++ b/packages/containers/Team/createColumns.js @@ -106,7 +106,7 @@ export const createColumns = ({ Cell: ({ value }) => {value}, }; - const roleColumn = { + const teamRoleColumn = { accessor: 'teamRole', width: ROLE_COLUMN_WIDTH, Filter: getColumnFilter('Role'), @@ -132,7 +132,7 @@ export const createColumns = ({ { + handleChangeMemberRole = (member, teamRole) => { // TODO: Need to implement UI. Use member.id instead of userId - this.props.updateTeamMemberRoleRequest(member.id, role); + this.props.updateTeamMemberRoleRequest(member.id, teamRole); }; handlePinTeam = (teamId, isPinned) => event => { diff --git a/packages/web-app/pages/invite.js b/packages/web-app/pages/invite.js index 304c79e29..c93474423 100644 --- a/packages/web-app/pages/invite.js +++ b/packages/web-app/pages/invite.js @@ -4,7 +4,7 @@ import { Bootstrap, Invite } from '@caesar/containers'; import { base64ToObject } from '@caesar/common/utils/base64'; import { login } from '@caesar/common/utils/authUtils'; -const validFields = ['e', 'p', 'mp']; +const validFields = ['e', 'p', 'm']; const validateFields = (data, fields) => data && fields.every(field => !!data[field]); diff --git a/packages/web-app/pages/share.js b/packages/web-app/pages/share.js index ec0d63c47..9a3ddf4b2 100644 --- a/packages/web-app/pages/share.js +++ b/packages/web-app/pages/share.js @@ -3,7 +3,6 @@ import { Error, Head } from '@caesar/components'; import { Bootstrap, Sharing } from '@caesar/containers'; import { base64ToObject } from '@caesar/common/utils/base64'; import { login } from '@caesar/common/utils/authUtils'; -import { getCheckShare } from '@caesar/common/api'; const validFields = ['e', 'p']; @@ -21,10 +20,7 @@ const SharePage = ({ statusCode, shared }) => ( ); -SharePage.getInitialProps = async ({ - res, - query: { encryption = '', shareId = '' }, -}) => { +SharePage.getInitialProps = async ({ res, query: { encryption = '' } }) => { const shared = base64ToObject(encryption); const isFieldsValidated = validateFields(shared, validFields); @@ -46,8 +42,6 @@ SharePage.getInitialProps = async ({ } try { - await getCheckShare(shareId); - const jwt = await login(shared.e, shared.p); res.cookie('token', jwt, { path: '/' }); diff --git a/packages/web-app/server.js b/packages/web-app/server.js index 904fe8a81..2d92a8ee9 100755 --- a/packages/web-app/server.js +++ b/packages/web-app/server.js @@ -77,9 +77,8 @@ app.prepare().then(() => { }); }); - server.get('/share/:shareId/:encryption', (req, res) => { + server.get('/share/:encryption', (req, res) => { app.render(req, res, '/share', { - shareId: req.params.shareId, encryption: req.params.encryption, }); });