Changeset View
Changeset View
Standalone View
Standalone View
web/invite-links/invite-link-handler.react.js
// @flow | // @flow | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { | import { | ||||
useVerifyInviteLink, | useVerifyInviteLink, | ||||
verifyInviteLinkActionTypes, | verifyInviteLinkActionTypes, | ||||
} from 'lib/actions/link-actions.js'; | } from 'lib/actions/link-actions.js'; | ||||
import { useModalContext } from 'lib/components/modal-provider.react.js'; | import { useModalContext } from 'lib/components/modal-provider.react.js'; | ||||
import { isLoggedIn } from 'lib/selectors/user-selectors.js'; | import { isLoggedIn } from 'lib/selectors/user-selectors.js'; | ||||
import { getKeyserverOverrideForAnInviteLink } from 'lib/shared/invite-links.js'; | |||||
import type { KeyserverOverride } from 'lib/shared/invite-links.js'; | |||||
import { useDispatchActionPromise } from 'lib/utils/redux-promise-utils.js'; | import { useDispatchActionPromise } from 'lib/utils/redux-promise-utils.js'; | ||||
import { useDispatch } from 'lib/utils/redux-utils.js'; | import { useDispatch } from 'lib/utils/redux-utils.js'; | ||||
import AcceptInviteModal from './accept-invite-modal.react.js'; | import AcceptInviteModal from './accept-invite-modal.react.js'; | ||||
import { updateNavInfoActionType } from '../redux/action-types.js'; | import { updateNavInfoActionType } from '../redux/action-types.js'; | ||||
import { useSelector } from '../redux/redux-utils.js'; | import { useSelector } from '../redux/redux-utils.js'; | ||||
function InviteLinkHandler(): null { | function InviteLinkHandler(): null { | ||||
const inviteSecret = useSelector(state => state.navInfo.inviteSecret); | const inviteSecret = useSelector(state => state.navInfo.inviteSecret); | ||||
const inviteLinkSecret = React.useRef<?string>(null); | |||||
const [keyserverOverride, setKeyserverOverride] = | |||||
React.useState<?KeyserverOverride>(undefined); | |||||
const loggedIn = useSelector(isLoggedIn); | const loggedIn = useSelector(isLoggedIn); | ||||
const dispatchActionPromise = useDispatchActionPromise(); | const dispatchActionPromise = useDispatchActionPromise(); | ||||
const dispatch = useDispatch(); | const dispatch = useDispatch(); | ||||
const validateLink = useVerifyInviteLink(); | |||||
const { pushModal } = useModalContext(); | const { pushModal } = useModalContext(); | ||||
React.useEffect(() => { | React.useEffect(() => { | ||||
void (async () => { | |||||
if (!inviteSecret || !loggedIn) { | if (!inviteSecret || !loggedIn) { | ||||
return; | return; | ||||
} | } | ||||
dispatch({ | dispatch({ | ||||
type: updateNavInfoActionType, | type: updateNavInfoActionType, | ||||
payload: { inviteSecret: null }, | payload: { inviteSecret: null }, | ||||
}); | }); | ||||
const validateLinkPromise = validateLink({ secret: inviteSecret }); | setKeyserverOverride(undefined); | ||||
inviteLinkSecret.current = inviteSecret; | |||||
try { | |||||
const newKeyserverOverride = | |||||
await getKeyserverOverrideForAnInviteLink(inviteSecret); | |||||
setKeyserverOverride(newKeyserverOverride); | |||||
} catch (e) { | |||||
console.error('Error while downloading an invite link blob', e); | |||||
pushModal( | |||||
<AcceptInviteModal | |||||
verificationResponse={{ | |||||
status: 'invalid', | |||||
}} | |||||
inviteSecret={inviteSecret} | |||||
/>, | |||||
); | |||||
} | |||||
})(); | |||||
}, [dispatch, inviteSecret, loggedIn, pushModal]); | |||||
const validateLink = useVerifyInviteLink(keyserverOverride); | |||||
React.useEffect(() => { | |||||
const secret = inviteLinkSecret.current; | |||||
if (keyserverOverride === undefined || !secret) { | |||||
return; | |||||
} | |||||
setKeyserverOverride(undefined); | |||||
void (async () => { | |||||
let result; | |||||
try { | |||||
const validateLinkPromise = validateLink({ secret }); | |||||
void dispatchActionPromise( | void dispatchActionPromise( | ||||
verifyInviteLinkActionTypes, | verifyInviteLinkActionTypes, | ||||
validateLinkPromise, | validateLinkPromise, | ||||
); | ); | ||||
void (async () => { | |||||
const result = await validateLinkPromise; | result = await validateLinkPromise; | ||||
if (result.status === 'already_joined') { | if (result.status === 'already_joined') { | ||||
return; | return; | ||||
} | } | ||||
} catch (e) { | |||||
console.error('Error while verifying an invite link', e); | |||||
result = { | |||||
status: 'invalid', | |||||
}; | |||||
} | |||||
pushModal( | pushModal( | ||||
<AcceptInviteModal | <AcceptInviteModal | ||||
verificationResponse={result} | verificationResponse={result} | ||||
inviteSecret={inviteSecret} | inviteSecret={secret} | ||||
/>, | />, | ||||
); | ); | ||||
})(); | })(); | ||||
}, [ | }, [dispatchActionPromise, keyserverOverride, pushModal, validateLink]); | ||||
dispatch, | |||||
dispatchActionPromise, | |||||
inviteSecret, | |||||
loggedIn, | |||||
pushModal, | |||||
validateLink, | |||||
]); | |||||
return null; | return null; | ||||
} | } | ||||
export default InviteLinkHandler; | export default InviteLinkHandler; |