1 import { END, eventChannel } from 'redux-saga';
2 import { put, select, take, takeEvery } from 'redux-saga/effects';
3 import { c } from 'ttag';
5 import { acceptInvite } from '@proton/pass/lib/invites/invite.requests';
6 import { requestItemsForShareId } from '@proton/pass/lib/items/item.requests';
7 import { parseShareResponse } from '@proton/pass/lib/shares/share.parser';
14 } from '@proton/pass/store/actions';
15 import { requestProgress } from '@proton/pass/store/request/actions';
16 import type { RequestProgress } from '@proton/pass/store/request/types';
17 import { selectInviteByToken } from '@proton/pass/store/selectors/invites';
18 import type { Invite, ItemRevision, Maybe, Share, ShareGetResponse, ShareType } from '@proton/pass/types';
19 import noop from '@proton/utils/noop';
21 type AcceptInviteChannel = RequestProgress<ItemRevision[], null>;
23 function* acceptInviteWorker({ payload, meta: { request } }: ReturnType<typeof inviteAcceptIntent>) {
24 const requestId = request.id;
25 const { inviteToken } = payload;
28 yield put(stopEventPolling());
30 const invite: Maybe<Invite> = yield select(selectInviteByToken(inviteToken));
31 if (!invite) throw new Error(c('Error').t`Unknown invite`);
33 const encryptedShare: ShareGetResponse = yield acceptInvite({ ...payload, inviteKeys: invite.keys });
34 const share: Maybe<Share<ShareType.Vault>> = yield parseShareResponse(encryptedShare);
35 if (!share) throw new Error(c('Error').t`Could not open invited vault`);
37 const progressChannel = eventChannel<AcceptInviteChannel>((emitter) => {
38 requestItemsForShareId(share.shareId, (progress) => emitter({ type: 'progress', progress, data: null }))
39 .then((result) => emitter({ type: 'done', result }))
40 .catch((error) => emitter({ type: 'error', error }))
41 .finally(() => emitter(END));
47 const action: AcceptInviteChannel = yield take(progressChannel);
48 if (action.type === 'progress') yield put(requestProgress(requestId, action.progress));
49 if (action.type === 'done') yield put(inviteAcceptSuccess(requestId, inviteToken, share, action.result));
50 if (action.type === 'error') throw action.error;
53 yield put(inviteAcceptFailure(requestId, err));
55 yield put(startEventPolling());
59 export default function* watcher() {
60 yield takeEvery(inviteAcceptIntent.match, acceptInviteWorker);