Compare commits

..

3 Commits

6 changed files with 45 additions and 36 deletions

View File

@@ -5,6 +5,7 @@ import { useState, useEffect } from "react";
interface TextChainProps { interface TextChainProps {
text: string; text: string;
mt?: MantineSize; mt?: MantineSize;
withoutPaper?: boolean;
} }
export function TextChain(props : TextChainProps) { export function TextChain(props : TextChainProps) {
@@ -26,31 +27,41 @@ export function TextChain(props : TextChainProps) {
}); });
}, [text]); }, [text]);
const grid = (
<SimpleGrid cols={3} spacing="xs">
{text.split(" ").map((v, i) => {
return (
<Box
key={i}
className={classes.wordBox}
style={{
opacity: mounted[i] ? 1 : 0,
transform: mounted[i] ? 'scale(1)' : 'scale(0.9)',
transition: 'opacity 300ms ease, transform 300ms ease',
}}
>
<Text size="xs" c="dimmed" mr={4}>{i + 1}.</Text>
<Text size="sm" fw={500}>{v}</Text>
</Box>
);
})}
</SimpleGrid>
);
return ( return (
!props.withoutPaper ? (
<Box mt={props.mt}> <Box mt={props.mt}>
<Box className={classes.displayArea}> <Box className={classes.displayArea}>
<Text size="sm" mb="md" c="dimmed"> <Text size="sm" mb="md" c="dimmed">
Your seed phrase: Your seed phrase:
</Text> </Text>
<SimpleGrid cols={3} spacing="xs"> {grid}
{text.split(" ").map((v, i) => {
return (
<Box
key={i}
className={classes.wordBox}
style={{
opacity: mounted[i] ? 1 : 0,
transform: mounted[i] ? 'scale(1)' : 'scale(0.9)',
transition: 'opacity 300ms ease, transform 300ms ease',
}}
>
<Text size="xs" c="dimmed" mr={4}>{i + 1}.</Text>
<Text size="sm" fw={500}>{v}</Text>
</Box>
);
})}
</SimpleGrid>
</Box> </Box>
</Box> </Box>
) : (
<Box mt={props.mt}>
{grid}
</Box>
)
) )
} }

View File

@@ -46,10 +46,11 @@ export function TextParser(props: TextParserProps) {
{ {
pattern: [ pattern: [
/(https?:\/\/[^\s]+)/g, /(https?:\/\/[^\s]+)/g,
/\b(?:https?:\/\/)?(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}(?:\/[^\s]*)?/g /\b(?:https?:\/\/)?(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}(?:\/[\w\-\.\/\?&#=%]*)?/g
], ],
render: (match: string) => { render: (match: string) => {
let domainZone = match.split('.').pop() || ''; let domain = match.replace(/https?:\/\//, '').split('/')[0];
let domainZone = domain.split('.').pop() || '';
domainZone = domainZone.split('/')[0]; domainZone = domainZone.split('/')[0];
if(!ALLOWED_DOMAINS_ZONES.includes(domainZone)) { if(!ALLOWED_DOMAINS_ZONES.includes(domainZone)) {
return <>{match}</>; return <>{match}</>;

View File

@@ -150,6 +150,7 @@ export function useAttachment(attachment: Attachment, keyPlain: string) {
} }
setDownloadStatus(DownloadStatus.DECRYPTING); setDownloadStatus(DownloadStatus.DECRYPTING);
//console.info("Decrypted attachment ", Buffer.from(keyPlain, 'binary').toString('hex')); //console.info("Decrypted attachment ", Buffer.from(keyPlain, 'binary').toString('hex'));
console.info("KP", keyPlain);
const decrypted = await decodeWithPassword(keyPlain, downloadedBlob); const decrypted = await decodeWithPassword(keyPlain, downloadedBlob);
setDownloadTag(""); setDownloadTag("");
if(attachment.type == AttachmentType.FILE) { if(attachment.type == AttachmentType.FILE) {

View File

@@ -184,15 +184,13 @@ export function DialogProvider(props: DialogProviderProps) {
readUpdated = true; readUpdated = true;
} }
let decryptKey = ''; let decryptKey = '';
if(message.from_me){ if(message.from_me && message.chacha_key != "" && message.chacha_key.startsWith("sync:")){
/** /**
* Если сообщение от меня, то ключ расшифровки для вложений * Если это сообщение от нас, то проверяем, есть ли внутри chacha_key, если есть, значит это
* не нужен, передаем пустую строку, так как под капотом * сообщение пришло нам в результате синхронизации и его нужно расшифровать, если chacha_key нет,
* в MessageAttachment.tsx при расшифровке вложений используется * значит сообщение отправлено с нашего устройства, и зашифровано на стороне отправки (plain_message)
* локальный ключ, а не тот что в сообщении, так как файл и так находится
* у нас локально
*/ */
decryptKey = ''; decryptKey = Buffer.from(await decodeWithPassword(privatePlain, message.chacha_key.replace("sync:", "")), 'binary').toString('utf-8');
} }
if(hasGroup(props.dialog)){ if(hasGroup(props.dialog)){
/** /**

View File

@@ -96,15 +96,15 @@ export function useDialogFiber() {
const content = packet.getContent(); const content = packet.getContent();
const timestamp = packet.getTimestamp(); const timestamp = packet.getTimestamp();
const messageId = packet.getMessageId(); const messageId = packet.getMessageId();
if (fromPublicKey != publicKey) { if (fromPublicKey != publicKey) {
/** /**
* Игнорируем если это не сообщение от нас * Игнорируем если это не сообщение от нас
*/ */
return; return;
} }
const chachaDecryptedKey = Buffer.from(await decodeWithPassword(privatePlain, aesChachaKey), "binary");
const chachaKey = await decodeWithPassword(privatePlain, aesChachaKey);
const chachaDecryptedKey = Buffer.from(chachaKey, "binary");
const key = chachaDecryptedKey.slice(0, 32); const key = chachaDecryptedKey.slice(0, 32);
const nonce = chachaDecryptedKey.slice(32); const nonce = chachaDecryptedKey.slice(32);
const decryptedContent = await chacha20Decrypt(content, nonce.toString('hex'), key.toString('hex')); const decryptedContent = await chacha20Decrypt(content, nonce.toString('hex'), key.toString('hex'));
@@ -160,7 +160,7 @@ export function useDialogFiber() {
content, content,
timestamp, timestamp,
0, //по умолчанию не прочитаны 0, //по умолчанию не прочитаны
'', "sync:" + aesChachaKey,
1, //Свои же сообщения всегда от нас 1, //Свои же сообщения всегда от нас
await encodeWithPassword(privatePlain, decryptedContent), await encodeWithPassword(privatePlain, decryptedContent),
publicKey, publicKey,

View File

@@ -5,7 +5,7 @@ import { SettingsInput } from "@/app/components/SettingsInput/SettingsInput";
import { TextChain } from "@/app/components/TextChain/TextChain"; import { TextChain } from "@/app/components/TextChain/TextChain";
import { decodeWithPassword } from "@/app/crypto/crypto"; import { decodeWithPassword } from "@/app/crypto/crypto";
import { useAccount } from "@/app/providers/AccountProvider/useAccount"; import { useAccount } from "@/app/providers/AccountProvider/useAccount";
import { Paper, Text } from "@mantine/core"; import { Text } from "@mantine/core";
import { useState } from "react"; import { useState } from "react";
export function Backup() { export function Backup() {
@@ -39,10 +39,8 @@ export function Backup() {
</Text> </Text>
{show.trim() !== "" && ( {show.trim() !== "" && (
<> <>
<Paper mt={'sm'} p={'md'} withBorder> <TextChain withoutPaper mt={'sm'} text={show}></TextChain>
<TextChain rainbow={true} mt={'sm'} text={show}></TextChain> <Text fz={10} mt={'sm'} c={'gray'} pl={'xs'} pr={'xs'}>
</Paper>
<Text fz={10} mt={3} c={'gray'} pl={'xs'} pr={'xs'}>
Please don't share your seed phrase! The administration will never ask you for it. Please don't share your seed phrase! The administration will never ask you for it.
</Text> </Text>
</> </>