Skip to content

Commit

Permalink
feat: use AsyncGeneratorCall to impl decryptFrom
Browse files Browse the repository at this point in the history
  • Loading branch information
Jack-Works committed Sep 5, 2019
1 parent a913bd1 commit c386583
Show file tree
Hide file tree
Showing 9 changed files with 200 additions and 155 deletions.
6 changes: 6 additions & 0 deletions src/background-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@ import elliptic from 'elliptic'
import * as CryptoService from './extension/background-script/CryptoService'
import * as WelcomeService from './extension/background-script/WelcomeService'
import * as PeopleService from './extension/background-script/PeopleService'
import { decryptFromMessageWithProgress } from './extension/background-script/CryptoServices/decryptFrom'
Object.assign(window, { CryptoService, WelcomeService, PeopleService })
Object.assign(window, {
ServicesWithProgress: {
decryptFrom: decryptFromMessageWithProgress,
},
})
require('./extension/service')
require('./provider.worker')

Expand Down
94 changes: 44 additions & 50 deletions src/components/InjectedComponents/DecryptedPost.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import React, { useCallback, useState, useEffect } from 'react'
import React, { useCallback, useState, useEffect, useRef } from 'react'
import AsyncComponent from '../../utils/components/AsyncComponent'
import { AdditionalContent } from './AdditionalPostContent'
import { useShareMenu } from './SelectPeopleDialog'
import { sleep } from '../../utils/utils'
import Services from '../../extension/service'
import { ServicesWithProgress } from '../../extension/service'
import { geti18nString } from '../../utils/i18n'
import { makeStyles } from '@material-ui/styles'
import { Box, Link, useMediaQuery, useTheme, Button, SnackbarContent } from '@material-ui/core'
import { Person } from '../../database'
import { Identifier, PersonIdentifier, PostIVIdentifier } from '../../database/type'
import { Identifier, PersonIdentifier } from '../../database/type'
import { NotSetupYetPrompt } from '../shared/NotSetupYetPrompt'
import { MessageCenter, TypedMessages } from '../../utils/messages'
import { Payload } from '../../utils/type-transform/Payload'
import { SuccessDecryption } from '../../extension/background-script/CryptoServices/decryptFrom'
import {
SuccessDecryption,
FailureDecryption,
DecryptionProgress,
} from '../../extension/background-script/CryptoServices/decryptFrom'

interface DecryptPostSuccessProps {
data: { signatureVerifyResult: boolean; content: string }
Expand Down Expand Up @@ -66,13 +69,13 @@ function DecryptPostSuccess({ data, people, ...props }: DecryptPostSuccessProps)
)
}

function DecryptPostAwaiting(props: { type?: DecryptingStatus }) {
function DecryptPostAwaiting(props: { type?: DecryptionProgress }) {
const key = {
finding_post_key: 'decrypted_postbox_decrypting_finding_post_key',
finding_person_public_key: 'decrypted_postbox_decrypting_finding_person_key',
undefined: 'decrypted_postbox_decrypting',
} as const
return <AdditionalContent title={geti18nString(key[props.type || 'undefined'])} />
return <AdditionalContent title={geti18nString(key[(props.type && props.type.progress) || 'undefined'])} />
}

const useDecryptPostFailedStyles = makeStyles({
Expand All @@ -81,16 +84,16 @@ const useDecryptPostFailedStyles = makeStyles({
maxWidth: '50em',
},
})
export function DecryptPostFailed({ error, retry }: { error: Error; retry: () => void }) {
export function DecryptPostFailed({ error, retry }: { error: Error; retry?: () => void }) {
const styles = useDecryptPostFailedStyles()
if (error && error.message === geti18nString('service_not_setup_yet')) {
return <NotSetupYetPrompt />
}
const button = (
const button = retry ? (
<Button onClick={retry} color="primary" size="small">
{geti18nString('retry_decryption')}
</Button>
)
) : null
return <SnackbarContent classes={styles} elevation={0} message={error && error.message} action={button} />
}

Expand All @@ -102,18 +105,20 @@ interface DecryptPostProps {
encryptedText: string
people: Person[]
alreadySelectedPreviously: Person[]
payload: Payload | null

requestAppendRecipients(to: Person[]): Promise<void>
}
type DecryptingStatus = undefined | 'finding_person_public_key' | 'finding_post_key'
function DecryptPost(props: DecryptPostProps) {
const { postBy, whoAmI, encryptedText, people, alreadySelectedPreviously, requestAppendRecipients } = props
const { payload } = props

const [decryptedResult, setDecryptedResult] = useState<null | SuccessDecryption>(null)
const [decryptingStatus, setDecryptingStatus] = useState<DecryptingStatus>(undefined)
const [decryptingStatus, setDecryptingStatus] = useState<DecryptionProgress | FailureDecryption | undefined>(
undefined,
)
const [__, forceReDecrypt] = useState<number>()
const cancelTask = useRef<() => void>(() => {})
useEffect(() => {
cancelTask.current()
})

const rAD = useCallback(
async (people: Person[]) => {
Expand All @@ -122,33 +127,6 @@ function DecryptPost(props: DecryptPostProps) {
},
[requestAppendRecipients],
)
useEffect(() => {
let listener = (data: TypedMessages['decryptionStatusUpdated']) => {
if (!payload) return
const id = new PostIVIdentifier(postBy.network, payload.iv)
if (id.equals(data.post)) {
switch (data.status) {
case 'finding_person_public_key':
setDecryptingStatus('finding_person_public_key')
break
case 'finding_post_key':
setDecryptingStatus('finding_post_key')
break
case 'found_person_public_key':
setDecryptingStatus('finding_post_key')
forceReDecrypt(Math.random())
break
case 'new_post_key':
setDecryptingStatus('finding_post_key')
forceReDecrypt(Math.random())
break
default:
break
}
}
}
return MessageCenter.on('decryptionStatusUpdated', listener)
}, [postBy, payload])
if (decryptedResult) {
return (
<DecryptPostSuccess
Expand All @@ -159,9 +137,25 @@ function DecryptPost(props: DecryptPostProps) {
/>
)
}
const awaitingComponent =
decryptingStatus && 'error' in decryptingStatus ? (
<DecryptPostFailed error={new Error(decryptingStatus.error)} />
) : (
<DecryptPostAwaiting type={decryptingStatus} />
)
return (
<AsyncComponent
promise={() => Services.Crypto.decryptFrom(encryptedText, postBy, whoAmI)}
promise={async () => {
cancelTask.current()
const iter = ServicesWithProgress.decryptFrom(encryptedText, postBy, whoAmI)
cancelTask.current = () => iter.throw!(new Error('Client aborted'))
let last = await iter.next()
while (!last.done) {
setDecryptingStatus(last.value)
last = await iter.next()
}
return last.value
}}
dependencies={[
__,
encryptedText,
Expand All @@ -170,21 +164,21 @@ function DecryptPost(props: DecryptPostProps) {
Identifier.IdentifiersToString(people.map(x => x.identifier)),
Identifier.IdentifiersToString(alreadySelectedPreviously.map(x => x.identifier)),
]}
awaitingComponent={<DecryptPostAwaiting type={decryptingStatus} />}
completeComponent={_props => {
if ('error' in _props.data) {
awaitingComponent={awaitingComponent}
completeComponent={result => {
if ('error' in result.data) {
return (
<DecryptPostFailed
retry={() => forceReDecrypt(Math.random())}
error={new Error(_props.data.error)}
error={new Error(result.data.error)}
/>
)
}
setDecryptedResult(_props.data)
props.onDecrypted(_props.data.content)
setDecryptedResult(result.data)
props.onDecrypted(result.data.content)
return (
<DecryptPostSuccess
data={_props.data}
data={result.data}
alreadySelectedPreviously={alreadySelectedPreviously}
requestAppendRecipients={postBy.equals(whoAmI) ? rAD : undefined}
people={people}
Expand Down
2 changes: 0 additions & 2 deletions src/components/InjectedComponents/PostInspector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ interface PostInspectorProps {
onDecrypted(post: string): void
post: string
postBy: PersonIdentifier
payload: Payload | null
postId: string
needZip(): void
}
Expand Down Expand Up @@ -47,7 +46,6 @@ export function PostInspector(props: PostInspectorProps) {
<Debug children={postBy.toText()} data-id="post by" />
<Debug children={postId} data-id="post id" />
<DecryptPostUI.UI
payload={props.payload}
onDecrypted={props.onDecrypted}
requestAppendRecipients={async people => {
setAlreadySelectedPreviously(alreadySelectedPreviously.concat(people))
Expand Down
Loading

0 comments on commit c386583

Please sign in to comment.