Skip to content

Commit

Permalink
feat: add debug mode for PostInspector
Browse files Browse the repository at this point in the history
  • Loading branch information
Jack-Works committed Sep 23, 2019
1 parent 310f00b commit 243f208
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 67 deletions.
119 changes: 75 additions & 44 deletions src/components/InjectedComponents/DecryptedPost.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import {
FailureDecryption,
SuccessDecryption,
} from '../../extension/background-script/CryptoServices/decryptFrom'
import { useValueRef } from '../../utils/hooks/useValueRef'
import { debugModeSetting } from '../shared-settings/debugMode'

interface DecryptPostSuccessProps {
data: { signatureVerifyResult: boolean; content: string }
Expand Down Expand Up @@ -115,21 +117,40 @@ function DecryptPost(props: DecryptPostProps) {
)
const [__, forceReDecrypt] = useState<number>()

const [debugHash, setDebugHash] = useState<string>('Unknown')
const isDebugging = useValueRef(debugModeSetting)

const rAD = useCallback(
async (people: Person[]) => {
await requestAppendRecipients(people)
await sleep(1500)
},
[requestAppendRecipients],
)
const debugHashJSX = (
<ul>
{postBy.equals(whoAmI) ? null : (
<li>
Hash of this post: {debugHash}
<br />
It should be same on your friend's Maskbook, if it isn't the same, that means your friend does not
receive your crypto key correctly or you didn't set your Maskbook correctly.
</li>
)}
<li>Decrypted reason: {decryptedResult ? decryptedResult.through.join(',') : 'Unknown'}</li>
</ul>
)
if (decryptedResult) {
return (
<DecryptPostSuccess
data={decryptedResult}
alreadySelectedPreviously={alreadySelectedPreviously}
requestAppendRecipients={postBy.equals(whoAmI) ? rAD : undefined}
people={people}
/>
<>
<DecryptPostSuccess
data={decryptedResult}
alreadySelectedPreviously={alreadySelectedPreviously}
requestAppendRecipients={postBy.equals(whoAmI) ? rAD : undefined}
people={people}
/>
{isDebugging ? debugHashJSX : null}
</>
)
}
const awaitingComponent =
Expand All @@ -139,47 +160,57 @@ function DecryptPost(props: DecryptPostProps) {
<DecryptPostAwaiting type={decryptingStatus} />
)
return (
<AsyncComponent
promise={async () => {
const iter = ServicesWithProgress.decryptFrom(encryptedText, postBy, whoAmI)
let last = await iter.next()
while (!last.done) {
setDecryptingStatus(last.value)
last = await iter.next()
}
return last.value
}}
dependencies={[
__,
encryptedText,
postBy.toText(),
whoAmI.toText(),
Identifier.IdentifiersToString(people.map(x => x.identifier)),
Identifier.IdentifiersToString(alreadySelectedPreviously.map(x => x.identifier)),
]}
awaitingComponent={awaitingComponent}
completeComponent={result => {
if ('error' in result.data) {
<>
<AsyncComponent
promise={async () => {
const iter = ServicesWithProgress.decryptFrom(encryptedText, postBy, whoAmI)
let last = await iter.next()
while (!last.done) {
if ('debug' in last.value) {
switch (last.value.debug) {
case 'debug_finding_hash':
setDebugHash(last.value.hash.join('-'))
}
} else {
setDecryptingStatus(last.value)
}
last = await iter.next()
}
return last.value
}}
dependencies={[
__,
encryptedText,
postBy.toText(),
whoAmI.toText(),
Identifier.IdentifiersToString(people.map(x => x.identifier)),
Identifier.IdentifiersToString(alreadySelectedPreviously.map(x => x.identifier)),
]}
awaitingComponent={awaitingComponent}
completeComponent={result => {
if ('error' in result.data) {
return (
<DecryptPostFailed
retry={() => forceReDecrypt(Math.random())}
error={new Error(result.data.error)}
/>
)
}
setDecryptedResult(result.data)
props.onDecrypted(result.data.content)
return (
<DecryptPostFailed
retry={() => forceReDecrypt(Math.random())}
error={new Error(result.data.error)}
<DecryptPostSuccess
data={result.data}
alreadySelectedPreviously={alreadySelectedPreviously}
requestAppendRecipients={postBy.equals(whoAmI) ? rAD : undefined}
people={people}
/>
)
}
setDecryptedResult(result.data)
props.onDecrypted(result.data.content)
return (
<DecryptPostSuccess
data={result.data}
alreadySelectedPreviously={alreadySelectedPreviously}
requestAppendRecipients={postBy.equals(whoAmI) ? rAD : undefined}
people={people}
/>
)
}}
failedComponent={DecryptPostFailed}
/>
}}
failedComponent={DecryptPostFailed}
/>
{isDebugging ? debugHashJSX : null}
</>
)
}

Expand Down
32 changes: 24 additions & 8 deletions src/components/InjectedComponents/PostInspector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import { deconstructPayload } from '../../utils/type-transform/Payload'
import Services from '../../extension/service'
import { PersonIdentifier } from '../../database/type'
import { Person } from '../../database'
import { styled } from '@material-ui/core/styles'
import { useCurrentIdentity, useFriendsList } from '../DataSource/useActivatedUI'
import { getActivatedUI } from '../../social-network/ui'
import { useValueRef } from '../../utils/hooks/useValueRef'
import { debugModeSetting } from '../shared-settings/debugMode'

const Debug = styled('div')({ display: 'none' })
interface PostInspectorProps {
onDecrypted(post: string): void
post: string
Expand All @@ -24,6 +24,7 @@ export function PostInspector(props: PostInspectorProps) {
const people = useFriendsList()
const [alreadySelectedPreviously, setAlreadySelectedPreviously] = useState<Person[]>([])
const decodeResult = getActivatedUI().publicKeyDecoder(post)
const isDebugging = useValueRef(debugModeSetting)
const type = {
encryptedPost: deconstructPayload(post),
provePost: decodeResult ? [decodeResult] : null,
Expand All @@ -39,14 +40,23 @@ export function PostInspector(props: PostInspectorProps) {

if (postBy.isUnknown) return null

const debugInfo = isDebugging ? (
<ul>
<li>Post content: {props.post}</li>
<li>Post by: {props.postBy.userId}</li>
<li>
Who am I:{' '}
{whoAmI ? `Nickname ${whoAmI.nickname || 'unknown'}, UserID ${whoAmI.identifier.userId}` : 'Unknown'}
</li>
<li>Post ID: {props.postId || 'Unknown'}</li>
</ul>
) : null

if (type.encryptedPost) {
props.needZip()
if (!isDebugging) props.needZip()
const { iv, ownersAESKeyEncrypted, version } = type.encryptedPost
return (
<>
<Debug children={post} data-id="post" />
<Debug children={postBy.toText()} data-id="post by" />
<Debug children={postId} data-id="post id" />
<DecryptPostUI.UI
onDecrypted={props.onDecrypted}
requestAppendRecipients={async people => {
Expand All @@ -66,10 +76,16 @@ export function PostInspector(props: PostInspectorProps) {
whoAmI={whoAmI ? whoAmI.identifier : PersonIdentifier.unknown}
postBy={postBy}
/>
{debugInfo}
</>
)
} else if (type.provePost) {
return <AddToKeyStore postBy={postBy} provePost={post} />
return (
<>
<AddToKeyStore postBy={postBy} provePost={post} />
{debugInfo}
</>
)
}
return null
return debugInfo
}
47 changes: 34 additions & 13 deletions src/extension/background-script/CryptoServices/decryptFrom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,23 @@ import { MessageCenter } from '../../../utils/messages'
type Progress = {
progress: 'finding_person_public_key' | 'finding_post_key'
}
type DebugInfo = {
debug: 'debug_finding_hash'
hash: [string, string]
}
type Success = {
signatureVerifyResult: boolean
content: string
through: ('author_key_not_found' | 'my_key_not_found' | 'post_key_cached' | 'normal_decrypted')[]
}
type Failure = {
error: string
}
export type SuccessDecryption = Success
export type FailureDecryption = Failure
export type DecryptionProgress = Progress
type ReturnOfDecryptFromMessageWithProgress = AsyncIterator<Failure | Progress, Success | Failure, void> & {
[Symbol.asyncIterator](): AsyncIterator<Failure | Progress, Success | Failure, void>
type ReturnOfDecryptFromMessageWithProgress = AsyncIterator<Failure | Progress | DebugInfo, Success | Failure, void> & {
[Symbol.asyncIterator](): AsyncIterator<Failure | Progress | DebugInfo, Success | Failure, void>
}

/**
Expand Down Expand Up @@ -65,7 +70,12 @@ export async function* decryptFromMessageWithProgress(
byPerson = await addPerson(by).catch(() => null)

if (!byPerson || !byPerson.publicKey) {
if (cachedPostResult) return { signatureVerifyResult: false, content: cachedPostResult }
if (cachedPostResult)
return {
signatureVerifyResult: false,
content: cachedPostResult,
through: ['author_key_not_found', 'post_key_cached'],
} as Success
let rejectGun = () => {}
let rejectDatabase = () => {}
const awaitGun = new Promise((resolve, reject) => {
Expand Down Expand Up @@ -103,7 +113,12 @@ export async function* decryptFromMessageWithProgress(

const mine = await getMyPrivateKey(whoAmI)
if (!mine) {
if (cachedPostResult) return { signatureVerifyResult: false, content: cachedPostResult }
if (cachedPostResult)
return {
signatureVerifyResult: false,
content: cachedPostResult,
through: ['my_key_not_found', 'post_key_cached'],
} as Success
return { error: geti18nString('service_not_setup_yet') }
}

Expand All @@ -113,7 +128,8 @@ export async function* decryptFromMessageWithProgress(
return {
signatureVerifyResult: await cryptoProvider.verify(unverified, signature || '', mine.publicKey),
content: cachedPostResult,
}
through: ['post_key_cached'],
} as Success

const [contentArrayBuffer, postAESKey] = await cryptoProvider.decryptMessage1ToNByMyself({
version,
Expand All @@ -128,20 +144,24 @@ export async function* decryptFromMessageWithProgress(
try {
if (!signature) throw new Error()
const signatureVerifyResult = await cryptoProvider.verify(unverified, signature, mine.publicKey)
return { signatureVerifyResult, content }
return { signatureVerifyResult, content, through: ['normal_decrypted'] } as Success
} catch {
return { signatureVerifyResult: false, content }
return { signatureVerifyResult: false, content, through: ['normal_decrypted'] } as Success
}
} else {
if (cachedPostResult)
if (cachedPostResult) {
const { keyHash, postHash } = await Gun2.queryPostKeysOnGun2(iv, mine.publicKey)
yield { debug: 'debug_finding_hash', hash: [postHash, keyHash] }
return {
signatureVerifyResult: await cryptoProvider.verify(
unverified,
signature || '',
byPerson.publicKey,
),
content: cachedPostResult,
}
through: ['post_key_cached'],
} as Success
}
yield { progress: 'finding_post_key' }
const aesKeyEncrypted: Array<Alpha40.PublishedAESKey | Gun2.SharedAESKeyGun2> = []
if (version === -40) {
Expand All @@ -151,7 +171,8 @@ export async function* decryptFromMessageWithProgress(
if (result === undefined) return { error: geti18nString('service_not_share_target') }
aesKeyEncrypted.push(result)
} else if (version === -39) {
const keys = await Gun2.queryPostKeysOnGun2(iv, mine.publicKey)
const { keyHash, keys, postHash } = await Gun2.queryPostKeysOnGun2(iv, mine.publicKey)
yield { debug: 'debug_finding_hash', hash: [postHash, keyHash] }
aesKeyEncrypted.push(...keys)
}

Expand Down Expand Up @@ -192,7 +213,7 @@ export async function* decryptFromMessageWithProgress(
| Alpha39.PublishedAESKey
| Alpha40.PublishedAESKey
| Array<Alpha39.PublishedAESKey | Alpha40.PublishedAESKey>,
) {
): Promise<Success> {
const [contentArrayBuffer, postAESKey] = await cryptoProvider.decryptMessage1ToNByOther({
version,
AESKeyEncrypted: key,
Expand All @@ -212,9 +233,9 @@ export async function* decryptFromMessageWithProgress(
signature,
byPerson!.publicKey!,
)
return { signatureVerifyResult, content }
return { signatureVerifyResult, content, through: ['normal_decrypted'] }
} catch {
return { signatureVerifyResult: false, content }
return { signatureVerifyResult: false, content, through: ['normal_decrypted'] }
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/network/gun/version.2/post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ OnlyRunInContext('background', 'gun')
export async function queryPostKeysOnGun2(
postSalt: string,
partitionByCryptoKey: CryptoKey,
): Promise<SharedAESKeyGun2[]> {
): Promise<{ keys: SharedAESKeyGun2[]; postHash: string; keyHash: string }> {
const postHash = await hashPostSalt(postSalt)
const keyHash = await hashCryptoKey(partitionByCryptoKey)

Expand All @@ -31,7 +31,7 @@ export async function queryPostKeysOnGun2(
const resultPromise = internalKeys.map(key => gun2.get(key).once().then!())
const result = (await Promise.all(resultPromise)) as SharedAESKeyGun2[]
console.info(`await gun2[${postHash}][${keyHash}]\n`, result)
return result
return { keys: result, keyHash, postHash }
}

/**
Expand Down

0 comments on commit 243f208

Please sign in to comment.