mirror of
https://github.com/Qortal/Qortal-Hub.git
synced 2025-06-14 20:11:22 +00:00
Merge branch 'develop' into feature/i18n-minor-refactoring
This commit is contained in:
commit
29ae25a27b
@ -440,7 +440,7 @@ const handleNotificationDirect = async (directs) => {
|
|||||||
let isFocused;
|
let isFocused;
|
||||||
const wallet = await getSaveWallet();
|
const wallet = await getSaveWallet();
|
||||||
const address = wallet.address0;
|
const address = wallet.address0;
|
||||||
let isDisableNotifications =
|
const isDisableNotifications =
|
||||||
(await getUserSettings({ key: 'disable-push-notifications' })) || false;
|
(await getUserSettings({ key: 'disable-push-notifications' })) || false;
|
||||||
const dataDirects = directs.filter((direct) => direct?.sender !== address);
|
const dataDirects = directs.filter((direct) => direct?.sender !== address);
|
||||||
try {
|
try {
|
||||||
@ -1281,7 +1281,6 @@ export async function addUserSettings({ keyValue }) {
|
|||||||
getData<any>(`${address}-userSettings`)
|
getData<any>(`${address}-userSettings`)
|
||||||
.then((storedData) => {
|
.then((storedData) => {
|
||||||
storedData = storedData || {}; // Initialize if no data found
|
storedData = storedData || {}; // Initialize if no data found
|
||||||
|
|
||||||
storedData[key] = value; // Update the key-value pair within stored data
|
storedData[key] = value; // Update the key-value pair within stored data
|
||||||
|
|
||||||
// Save updated structure back to localStorage
|
// Save updated structure back to localStorage
|
||||||
@ -1734,7 +1733,7 @@ export async function decryptSingleFunc({
|
|||||||
secretKeyObject,
|
secretKeyObject,
|
||||||
skipDecodeBase64,
|
skipDecodeBase64,
|
||||||
}) {
|
}) {
|
||||||
let holdMessages = [];
|
const holdMessages = [];
|
||||||
|
|
||||||
for (const message of messages) {
|
for (const message of messages) {
|
||||||
try {
|
try {
|
||||||
@ -1744,9 +1743,11 @@ export async function decryptSingleFunc({
|
|||||||
skipDecodeBase64,
|
skipDecodeBase64,
|
||||||
});
|
});
|
||||||
|
|
||||||
const decryptToUnit8Array = base64ToUint8Array(res);
|
if (res) {
|
||||||
const responseData = uint8ArrayToObject(decryptToUnit8Array);
|
const decryptToUnit8Array = base64ToUint8Array(res);
|
||||||
holdMessages.push({ ...message, decryptedData: responseData });
|
const responseData = uint8ArrayToObject(decryptToUnit8Array);
|
||||||
|
holdMessages.push({ ...message, decryptedData: responseData });
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
@ -1758,7 +1759,7 @@ export async function decryptSingleForPublishes({
|
|||||||
secretKeyObject,
|
secretKeyObject,
|
||||||
skipDecodeBase64,
|
skipDecodeBase64,
|
||||||
}) {
|
}) {
|
||||||
let holdMessages = [];
|
const holdMessages = [];
|
||||||
|
|
||||||
for (const message of messages) {
|
for (const message of messages) {
|
||||||
try {
|
try {
|
||||||
@ -2888,6 +2889,7 @@ export async function getTimestampEnterChat() {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getTimestampMention() {
|
export async function getTimestampMention() {
|
||||||
const wallet = await getSaveWallet();
|
const wallet = await getSaveWallet();
|
||||||
const address = wallet.address0;
|
const address = wallet.address0;
|
||||||
@ -2900,6 +2902,7 @@ export async function getTimestampMention() {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getTimestampGroupAnnouncement() {
|
export async function getTimestampGroupAnnouncement() {
|
||||||
const wallet = await getSaveWallet();
|
const wallet = await getSaveWallet();
|
||||||
const address = wallet.address0;
|
const address = wallet.address0;
|
||||||
@ -2996,6 +2999,7 @@ async function getGroupData() {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getGroupDataSingle(groupId) {
|
export async function getGroupDataSingle(groupId) {
|
||||||
const wallet = await getSaveWallet();
|
const wallet = await getSaveWallet();
|
||||||
const address = wallet.address0;
|
const address = wallet.address0;
|
||||||
@ -3266,6 +3270,7 @@ function setupMessageListener() {
|
|||||||
break;
|
break;
|
||||||
case 'updateThreadActivity':
|
case 'updateThreadActivity':
|
||||||
updateThreadActivityCase(request, event);
|
updateThreadActivityCase(request, event);
|
||||||
|
break;
|
||||||
case 'decryptGroupEncryption':
|
case 'decryptGroupEncryption':
|
||||||
decryptGroupEncryptionCase(request, event);
|
decryptGroupEncryptionCase(request, event);
|
||||||
break;
|
break;
|
||||||
@ -3387,7 +3392,7 @@ const checkGroupList = async () => {
|
|||||||
.filter(
|
.filter(
|
||||||
(item) =>
|
(item) =>
|
||||||
item?.name !== 'extension-proxy' &&
|
item?.name !== 'extension-proxy' &&
|
||||||
item?.address !== 'QSMMGSgysEuqDCuLw3S4cHrQkBrh3vP3VH'
|
item?.address !== 'QSMMGSgysEuqDCuLw3S4cHrQkBrh3vP3VH' // TODO put address in a specific file
|
||||||
)
|
)
|
||||||
.sort((a, b) => (b.timestamp || 0) - (a.timestamp || 0));
|
.sort((a, b) => (b.timestamp || 0) - (a.timestamp || 0));
|
||||||
|
|
||||||
@ -3411,7 +3416,7 @@ export const checkNewMessages = async () => {
|
|||||||
myName = userData.name;
|
myName = userData.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
let newAnnouncements = [];
|
const newAnnouncements = [];
|
||||||
const activeData = (await getStoredData('active-groups-directs')) || {
|
const activeData = (await getStoredData('active-groups-directs')) || {
|
||||||
groups: [],
|
groups: [],
|
||||||
directs: [],
|
directs: [],
|
||||||
@ -3441,6 +3446,7 @@ export const checkNewMessages = async () => {
|
|||||||
const latestMessage = responseData.filter(
|
const latestMessage = responseData.filter(
|
||||||
(pub) => pub?.name !== myName
|
(pub) => pub?.name !== myName
|
||||||
)[0];
|
)[0];
|
||||||
|
|
||||||
if (!latestMessage) {
|
if (!latestMessage) {
|
||||||
return; // continue to the next group
|
return; // continue to the next group
|
||||||
}
|
}
|
||||||
@ -3463,7 +3469,8 @@ export const checkNewMessages = async () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
let isDisableNotifications =
|
|
||||||
|
const isDisableNotifications =
|
||||||
(await getUserSettings({ key: 'disable-push-notifications' })) || false;
|
(await getUserSettings({ key: 'disable-push-notifications' })) || false;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@ -3611,8 +3618,8 @@ export const checkThreads = async (bringBack) => {
|
|||||||
if (userData?.name) {
|
if (userData?.name) {
|
||||||
myName = userData.name;
|
myName = userData.name;
|
||||||
}
|
}
|
||||||
let newAnnouncements = [];
|
const newAnnouncements = [];
|
||||||
let dataToBringBack = [];
|
const dataToBringBack = [];
|
||||||
const threadActivity = await getThreadActivity();
|
const threadActivity = await getThreadActivity();
|
||||||
if (!threadActivity) return null;
|
if (!threadActivity) return null;
|
||||||
|
|
||||||
@ -3627,7 +3634,6 @@ export const checkThreads = async (bringBack) => {
|
|||||||
for (const thread of selectedThreads) {
|
for (const thread of selectedThreads) {
|
||||||
try {
|
try {
|
||||||
const identifier = `thmsg-${thread?.threadId}`;
|
const identifier = `thmsg-${thread?.threadId}`;
|
||||||
const name = thread?.qortalName;
|
|
||||||
const endpoint = await getArbitraryEndpoint();
|
const endpoint = await getArbitraryEndpoint();
|
||||||
const url = await createEndpoint(
|
const url = await createEndpoint(
|
||||||
`${endpoint}?mode=ALL&service=DOCUMENT&identifier=${identifier}&limit=1&includemetadata=false&offset=${0}&reverse=true&prefix=true`
|
`${endpoint}?mode=ALL&service=DOCUMENT&identifier=${identifier}&limit=1&includemetadata=false&offset=${0}&reverse=true&prefix=true`
|
||||||
@ -3643,7 +3649,6 @@ export const checkThreads = async (bringBack) => {
|
|||||||
const latestMessage = responseData.filter(
|
const latestMessage = responseData.filter(
|
||||||
(pub) => pub?.name !== myName
|
(pub) => pub?.name !== myName
|
||||||
)[0];
|
)[0];
|
||||||
// const latestMessage = responseData[0]
|
|
||||||
|
|
||||||
if (!latestMessage) {
|
if (!latestMessage) {
|
||||||
continue;
|
continue;
|
||||||
@ -3717,7 +3722,7 @@ export const checkThreads = async (bringBack) => {
|
|||||||
'_type=thread-post' +
|
'_type=thread-post' +
|
||||||
`_data=${JSON.stringify(newAnnouncements[0])}`
|
`_data=${JSON.stringify(newAnnouncements[0])}`
|
||||||
);
|
);
|
||||||
let isDisableNotifications =
|
const isDisableNotifications =
|
||||||
(await getUserSettings({ key: 'disable-push-notifications' })) || false;
|
(await getUserSettings({ key: 'disable-push-notifications' })) || false;
|
||||||
if (!isDisableNotifications) {
|
if (!isDisableNotifications) {
|
||||||
// Check user settings to see if notifications are disabled
|
// Check user settings to see if notifications are disabled
|
||||||
|
@ -7,6 +7,15 @@ import { ChatOptions } from './ChatOptions';
|
|||||||
import ErrorBoundary from '../../common/ErrorBoundary';
|
import ErrorBoundary from '../../common/ErrorBoundary';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
type ReactionItem = {
|
||||||
|
sender: string;
|
||||||
|
senderName?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ReactionsMap = {
|
||||||
|
[reactionType: string]: ReactionItem[];
|
||||||
|
};
|
||||||
|
|
||||||
export const ChatList = ({
|
export const ChatList = ({
|
||||||
initialMessages,
|
initialMessages,
|
||||||
myAddress,
|
myAddress,
|
||||||
@ -236,7 +245,7 @@ export const ChatList = ({
|
|||||||
let message = messages[index] || null; // Safeguard against undefined
|
let message = messages[index] || null; // Safeguard against undefined
|
||||||
let replyIndex = -1;
|
let replyIndex = -1;
|
||||||
let reply = null;
|
let reply = null;
|
||||||
let reactions = null;
|
let reactions: ReactionsMap | null = null;
|
||||||
let isUpdating = false;
|
let isUpdating = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -444,13 +453,13 @@ export const ChatList = ({
|
|||||||
|
|
||||||
{enableMentions && (hasSecretKey || isPrivate === false) && (
|
{enableMentions && (hasSecretKey || isPrivate === false) && (
|
||||||
<ChatOptions
|
<ChatOptions
|
||||||
openQManager={openQManager}
|
|
||||||
messages={messages}
|
|
||||||
goToMessage={goToMessage}
|
goToMessage={goToMessage}
|
||||||
members={members}
|
|
||||||
myName={myName}
|
|
||||||
selectedGroup={selectedGroup}
|
|
||||||
isPrivate={isPrivate}
|
isPrivate={isPrivate}
|
||||||
|
members={members}
|
||||||
|
messages={messages}
|
||||||
|
myName={myName}
|
||||||
|
openQManager={openQManager}
|
||||||
|
selectedGroup={selectedGroup}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
|
@ -25,7 +25,6 @@ import {
|
|||||||
AppsSearchRight,
|
AppsSearchRight,
|
||||||
} from '../Apps/Apps-styles';
|
} from '../Apps/Apps-styles';
|
||||||
import IconClearInput from '../../assets/svgs/ClearInput.svg';
|
import IconClearInput from '../../assets/svgs/ClearInput.svg';
|
||||||
import { CellMeasurerCache } from 'react-virtualized';
|
|
||||||
import { getBaseApiReact } from '../../App';
|
import { getBaseApiReact } from '../../App';
|
||||||
import { MessageDisplay } from './MessageDisplay';
|
import { MessageDisplay } from './MessageDisplay';
|
||||||
import { useVirtualizer } from '@tanstack/react-virtual';
|
import { useVirtualizer } from '@tanstack/react-virtual';
|
||||||
@ -36,6 +35,7 @@ import { generateHTML } from '@tiptap/react';
|
|||||||
import ErrorBoundary from '../../common/ErrorBoundary';
|
import ErrorBoundary from '../../common/ErrorBoundary';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { isHtmlString } from '../../utils/chat';
|
import { isHtmlString } from '../../utils/chat';
|
||||||
|
import TextStyle from '@tiptap/extension-text-style';
|
||||||
|
|
||||||
const extractTextFromHTML = (htmlString = '') => {
|
const extractTextFromHTML = (htmlString = '') => {
|
||||||
return convert(htmlString, {
|
return convert(htmlString, {
|
||||||
@ -43,11 +43,6 @@ const extractTextFromHTML = (htmlString = '') => {
|
|||||||
})?.toLowerCase();
|
})?.toLowerCase();
|
||||||
};
|
};
|
||||||
|
|
||||||
const cache = new CellMeasurerCache({
|
|
||||||
fixedWidth: true,
|
|
||||||
defaultHeight: 50,
|
|
||||||
});
|
|
||||||
|
|
||||||
export const ChatOptions = ({
|
export const ChatOptions = ({
|
||||||
messages: untransformedMessages,
|
messages: untransformedMessages,
|
||||||
goToMessage,
|
goToMessage,
|
||||||
@ -86,6 +81,7 @@ export const ChatOptions = ({
|
|||||||
Underline,
|
Underline,
|
||||||
Highlight,
|
Highlight,
|
||||||
Mention,
|
Mention,
|
||||||
|
TextStyle,
|
||||||
]);
|
]);
|
||||||
return {
|
return {
|
||||||
...item,
|
...item,
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
|||||||
import { memo, useCallback, useEffect, useMemo, useRef } from 'react';
|
import { memo, useCallback, useEffect, useMemo, useRef } from 'react';
|
||||||
import { EditorProvider, useCurrentEditor } from '@tiptap/react';
|
import { Editor, EditorProvider, useCurrentEditor } from '@tiptap/react';
|
||||||
import StarterKit from '@tiptap/starter-kit';
|
import StarterKit from '@tiptap/starter-kit';
|
||||||
import { Color } from '@tiptap/extension-color';
|
import { Color } from '@tiptap/extension-color';
|
||||||
import ListItem from '@tiptap/extension-list-item';
|
import ListItem from '@tiptap/extension-list-item';
|
||||||
@ -34,16 +34,6 @@ import { fileToBase64 } from '../../utils/fileReading/index.js';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import i18n from 'i18next';
|
import i18n from 'i18next';
|
||||||
|
|
||||||
function textMatcher(doc, from) {
|
|
||||||
const textBeforeCursor = doc.textBetween(0, from, ' ', ' ');
|
|
||||||
const match = textBeforeCursor.match(/@[\w]*$/); // Match '@' followed by valid characters
|
|
||||||
if (!match) return null;
|
|
||||||
|
|
||||||
const start = from - match[0].length;
|
|
||||||
const query = match[0];
|
|
||||||
return { start, query };
|
|
||||||
}
|
|
||||||
|
|
||||||
const MenuBar = memo(
|
const MenuBar = memo(
|
||||||
({
|
({
|
||||||
setEditorRef,
|
setEditorRef,
|
||||||
@ -361,8 +351,8 @@ const MenuBar = memo(
|
|||||||
);
|
);
|
||||||
|
|
||||||
const extensions = [
|
const extensions = [
|
||||||
|
TextStyle,
|
||||||
Color.configure({ types: [TextStyle.name, ListItem.name] }),
|
Color.configure({ types: [TextStyle.name, ListItem.name] }),
|
||||||
TextStyle.configure({ types: [ListItem.name] }),
|
|
||||||
StarterKit.configure({
|
StarterKit.configure({
|
||||||
bulletList: {
|
bulletList: {
|
||||||
keepMarks: true,
|
keepMarks: true,
|
||||||
@ -383,11 +373,26 @@ const extensions = [
|
|||||||
|
|
||||||
const content = ``;
|
const content = ``;
|
||||||
|
|
||||||
export default ({
|
type TiptapProps = {
|
||||||
|
setEditorRef: (editorInstance: Editor | null) => void;
|
||||||
|
onEnter: () => void | Promise<void>;
|
||||||
|
disableEnter?: boolean;
|
||||||
|
isChat?: boolean;
|
||||||
|
maxHeightOffset?: number;
|
||||||
|
overrideMobile?: boolean;
|
||||||
|
customEditorHeight?: number | null;
|
||||||
|
setIsFocusedParent: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
|
isFocusedParent: boolean;
|
||||||
|
membersWithNames: unknown[];
|
||||||
|
enableMentions?: boolean;
|
||||||
|
insertImage: (image: any) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const Tiptap = ({
|
||||||
setEditorRef,
|
setEditorRef,
|
||||||
onEnter,
|
onEnter,
|
||||||
disableEnter,
|
disableEnter = false,
|
||||||
isChat,
|
isChat = false,
|
||||||
maxHeightOffset,
|
maxHeightOffset,
|
||||||
setIsFocusedParent,
|
setIsFocusedParent,
|
||||||
isFocusedParent,
|
isFocusedParent,
|
||||||
@ -396,7 +401,7 @@ export default ({
|
|||||||
membersWithNames,
|
membersWithNames,
|
||||||
enableMentions,
|
enableMentions,
|
||||||
insertImage,
|
insertImage,
|
||||||
}) => {
|
}: TiptapProps) => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const [isDisabledEditorEnter, setIsDisabledEditorEnter] = useAtom(
|
const [isDisabledEditorEnter, setIsDisabledEditorEnter] = useAtom(
|
||||||
isDisabledEditorEnterAtom
|
isDisabledEditorEnterAtom
|
||||||
@ -623,3 +628,5 @@ export default ({
|
|||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default Tiptap;
|
||||||
|
@ -59,7 +59,7 @@ export const Embed = ({ embedLink }) => {
|
|||||||
const [openSnack, setOpenSnack] = useState(false);
|
const [openSnack, setOpenSnack] = useState(false);
|
||||||
const [infoSnack, setInfoSnack] = useState(null);
|
const [infoSnack, setInfoSnack] = useState(null);
|
||||||
const [external, setExternal] = useState(null);
|
const [external, setExternal] = useState(null);
|
||||||
const [imageUrl, setImageUrl] = useState('');
|
const [imageUrl, setImageUrl] = useState(null);
|
||||||
const [parsedData, setParsedData] = useState(null);
|
const [parsedData, setParsedData] = useState(null);
|
||||||
const setBlobs = useSetAtom(blobControllerAtom);
|
const setBlobs = useSetAtom(blobControllerAtom);
|
||||||
const [selectedGroupId] = useAtom(selectedGroupIdAtom);
|
const [selectedGroupId] = useAtom(selectedGroupIdAtom);
|
||||||
|
@ -208,9 +208,8 @@ export const ImageCard = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export function ImageViewer({ src, alt = '' }) {
|
export function ImageViewer({ src = null, alt = '' }) {
|
||||||
const [isFullscreen, setIsFullscreen] = useState(false);
|
const [isFullscreen, setIsFullscreen] = useState(false);
|
||||||
|
|
||||||
const handleOpenFullscreen = () => setIsFullscreen(true);
|
const handleOpenFullscreen = () => setIsFullscreen(true);
|
||||||
const handleCloseFullscreen = () => setIsFullscreen(false);
|
const handleCloseFullscreen = () => setIsFullscreen(false);
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
@ -276,15 +276,13 @@ export async function getNameInfo(address: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const getGroupAdmins = async (groupNumber: number) => {
|
export const getGroupAdmins = async (groupNumber: number) => {
|
||||||
// const validApi = await findUsableApi();
|
|
||||||
|
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`${getBaseApiReact()}/groups/members/${groupNumber}?limit=0&onlyAdmins=true`
|
`${getBaseApiReact()}/groups/members/${groupNumber}?limit=0&onlyAdmins=true`
|
||||||
);
|
);
|
||||||
const groupData = await response.json();
|
const groupData = await response.json();
|
||||||
let members: any = [];
|
const members: any = [];
|
||||||
let membersAddresses = [];
|
const membersAddresses = [];
|
||||||
let both = [];
|
const both = [];
|
||||||
|
|
||||||
const getMemNames = groupData?.members?.map(async (member) => {
|
const getMemNames = groupData?.members?.map(async (member) => {
|
||||||
if (member?.member) {
|
if (member?.member) {
|
||||||
@ -600,10 +598,11 @@ export const Group = ({
|
|||||||
}, [myAddress]);
|
}, [myAddress]);
|
||||||
|
|
||||||
const getGroupOwner = async (groupId) => {
|
const getGroupOwner = async (groupId) => {
|
||||||
|
if (groupId == '0') return; // general group has id=0
|
||||||
try {
|
try {
|
||||||
const url = `${getBaseApiReact()}/groups/${groupId}`;
|
const url = `${getBaseApiReact()}/groups/${groupId}`;
|
||||||
const response = await fetch(url);
|
const response = await fetch(url);
|
||||||
let data = await response.json();
|
const data = await response.json();
|
||||||
|
|
||||||
const name = await getNameInfo(data?.owner);
|
const name = await getNameInfo(data?.owner);
|
||||||
if (name) {
|
if (name) {
|
||||||
@ -742,7 +741,7 @@ export const Group = ({
|
|||||||
data = await res.text();
|
data = await res.text();
|
||||||
}
|
}
|
||||||
|
|
||||||
const decryptedKey: any = await decryptResource(data);
|
const decryptedKey: any = await decryptResource(data, null);
|
||||||
const dataint8Array = base64ToUint8Array(decryptedKey.data);
|
const dataint8Array = base64ToUint8Array(decryptedKey.data);
|
||||||
const decryptedKeyToObject = uint8ArrayToObject(dataint8Array);
|
const decryptedKeyToObject = uint8ArrayToObject(dataint8Array);
|
||||||
|
|
||||||
@ -877,6 +876,7 @@ export const Group = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const getOwnerNameForGroup = async (owner: string, groupId: string) => {
|
const getOwnerNameForGroup = async (owner: string, groupId: string) => {
|
||||||
|
if (groupId == '0') return; // general group has id=0
|
||||||
try {
|
try {
|
||||||
if (!owner) return;
|
if (!owner) return;
|
||||||
if (groupsOwnerNamesRef.current[groupId]) return;
|
if (groupsOwnerNamesRef.current[groupId]) return;
|
||||||
@ -899,7 +899,7 @@ export const Group = ({
|
|||||||
const url = `${getBaseApiReact()}/groups/member/${address}`;
|
const url = `${getBaseApiReact()}/groups/member/${address}`;
|
||||||
const response = await fetch(url);
|
const response = await fetch(url);
|
||||||
if (!response.ok) throw new Error('Cannot get group properties');
|
if (!response.ok) throw new Error('Cannot get group properties');
|
||||||
let data = await response.json();
|
const data = await response.json();
|
||||||
const transformToObject = data.reduce((result, item) => {
|
const transformToObject = data.reduce((result, item) => {
|
||||||
result[item.groupId] = item;
|
result[item.groupId] = item;
|
||||||
return result;
|
return result;
|
||||||
|
@ -124,7 +124,7 @@ export const ListOfJoinRequests = ({
|
|||||||
setIsLoadingAccept(false);
|
setIsLoadingAccept(false);
|
||||||
setInfoSnack({
|
setInfoSnack({
|
||||||
type: 'success',
|
type: 'success',
|
||||||
message: t('group:message.success,group_join', {
|
message: t('group:message.success.group_join', {
|
||||||
postProcess: 'capitalizeFirstChar',
|
postProcess: 'capitalizeFirstChar',
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
@ -244,6 +244,7 @@ export const Wallets = ({ setExtState, setRawWallet, rawWallet }) => {
|
|||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{wallets?.length > 0 && (
|
{wallets?.length > 0 && (
|
||||||
<List
|
<List
|
||||||
sx={{
|
sx={{
|
||||||
@ -442,20 +443,22 @@ export const Wallets = ({ setExtState, setRawWallet, rawWallet }) => {
|
|||||||
postProcess: 'capitalizeFirstChar',
|
postProcess: 'capitalizeFirstChar',
|
||||||
})}
|
})}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<LoadingButton
|
<LoadingButton
|
||||||
loading={isLoadingEncryptSeed}
|
autoFocus
|
||||||
disabled={!seedValue || !seedName || !password}
|
disabled={!seedValue || !seedName || !password}
|
||||||
variant="contained"
|
loading={isLoadingEncryptSeed}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (!seedValue || !seedName || !password) return;
|
if (!seedValue || !seedName || !password) return;
|
||||||
onOk({ seedValue, seedName, password });
|
onOk({ seedValue, seedName, password });
|
||||||
}}
|
}}
|
||||||
autoFocus
|
variant="contained"
|
||||||
>
|
>
|
||||||
{t('core:action.add', {
|
{t('core:action.add', {
|
||||||
postProcess: 'capitalizeFirstChar',
|
postProcess: 'capitalizeFirstChar',
|
||||||
})}
|
})}
|
||||||
</LoadingButton>
|
</LoadingButton>
|
||||||
|
|
||||||
<Typography
|
<Typography
|
||||||
sx={{
|
sx={{
|
||||||
fontSize: '14px',
|
fontSize: '14px',
|
||||||
|
@ -77,7 +77,7 @@ export const encryptDataGroup = ({
|
|||||||
userPublicKey,
|
userPublicKey,
|
||||||
customSymmetricKey,
|
customSymmetricKey,
|
||||||
}: any) => {
|
}: any) => {
|
||||||
let combinedPublicKeys = [...publicKeys, userPublicKey];
|
const combinedPublicKeys = [...publicKeys, userPublicKey];
|
||||||
const decodedPrivateKey = Base58.decode(privateKey);
|
const decodedPrivateKey = Base58.decode(privateKey);
|
||||||
const publicKeysDuplicateFree = [...new Set(combinedPublicKeys)];
|
const publicKeysDuplicateFree = [...new Set(combinedPublicKeys)];
|
||||||
const Uint8ArrayData = base64ToUint8Array(data64);
|
const Uint8ArrayData = base64ToUint8Array(data64);
|
||||||
@ -114,7 +114,7 @@ export const encryptDataGroup = ({
|
|||||||
const keyNonce = new Uint8Array(24);
|
const keyNonce = new Uint8Array(24);
|
||||||
crypto.getRandomValues(keyNonce);
|
crypto.getRandomValues(keyNonce);
|
||||||
// Encrypt the symmetric key for each recipient.
|
// Encrypt the symmetric key for each recipient.
|
||||||
let encryptedKeys = [];
|
const encryptedKeys = [];
|
||||||
publicKeysDuplicateFree.forEach((recipientPublicKey) => {
|
publicKeysDuplicateFree.forEach((recipientPublicKey) => {
|
||||||
const publicKeyUnit8Array = Base58.decode(recipientPublicKey);
|
const publicKeyUnit8Array = Base58.decode(recipientPublicKey);
|
||||||
const convertedPrivateKey = ed2curve.convertSecretKey(decodedPrivateKey);
|
const convertedPrivateKey = ed2curve.convertSecretKey(decodedPrivateKey);
|
||||||
@ -153,7 +153,7 @@ export const encryptDataGroup = ({
|
|||||||
encryptedKeysSize += key.length;
|
encryptedKeysSize += key.length;
|
||||||
});
|
});
|
||||||
combinedDataSize += encryptedKeysSize;
|
combinedDataSize += encryptedKeysSize;
|
||||||
let combinedData = new Uint8Array(combinedDataSize);
|
const combinedData = new Uint8Array(combinedDataSize);
|
||||||
combinedData.set(strUint8Array);
|
combinedData.set(strUint8Array);
|
||||||
combinedData.set(nonce, strUint8Array.length);
|
combinedData.set(nonce, strUint8Array.length);
|
||||||
combinedData.set(keyNonce, strUint8Array.length + nonce.length);
|
combinedData.set(keyNonce, strUint8Array.length + nonce.length);
|
||||||
@ -244,9 +244,6 @@ export const encryptSingle = async ({
|
|||||||
encryptedData = nacl.secretbox(Uint8ArrayData, nonce, messageKey);
|
encryptedData = nacl.secretbox(Uint8ArrayData, nonce, messageKey);
|
||||||
encryptedDataBase64 = uint8ArrayToBase64(encryptedData);
|
encryptedDataBase64 = uint8ArrayToBase64(encryptedData);
|
||||||
|
|
||||||
// Convert the nonce to base64
|
|
||||||
const nonceBase64 = uint8ArrayToBase64(nonce);
|
|
||||||
|
|
||||||
// Concatenate the highest key, type number, nonce, and encrypted data (new format)
|
// Concatenate the highest key, type number, nonce, and encrypted data (new format)
|
||||||
const highestKeyStr = highestKey.toString().padStart(10, '0'); // Fixed length of 10 digits
|
const highestKeyStr = highestKey.toString().padStart(10, '0'); // Fixed length of 10 digits
|
||||||
|
|
||||||
@ -281,7 +278,7 @@ export const encryptSingle = async ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const decodeBase64ForUIChatMessages = (messages) => {
|
export const decodeBase64ForUIChatMessages = (messages) => {
|
||||||
let msgs = [];
|
const msgs = [];
|
||||||
for (const msg of messages) {
|
for (const msg of messages) {
|
||||||
try {
|
try {
|
||||||
const decoded = atob(msg?.data);
|
const decoded = atob(msg?.data);
|
||||||
@ -306,107 +303,114 @@ export const decryptSingle = async ({
|
|||||||
// First, decode the base64-encoded input (if skipDecodeBase64 is not set)
|
// First, decode the base64-encoded input (if skipDecodeBase64 is not set)
|
||||||
const decodedData = skipDecodeBase64 ? data64 : atob(data64);
|
const decodedData = skipDecodeBase64 ? data64 : atob(data64);
|
||||||
|
|
||||||
// Then, decode it again for the specific format (if double encoding is used)
|
if (secretKeyObject) {
|
||||||
const decodeForNumber = atob(decodedData);
|
// Then, decode it again for the specific format (if double encoding is used)
|
||||||
|
const decodeForNumber = atob(decodedData);
|
||||||
|
|
||||||
// Extract the key (assuming it's always the first 10 characters)
|
// Extract the key (assuming it's always the first 10 characters)
|
||||||
const keyStr = decodeForNumber.slice(0, 10);
|
const keyStr = decodeForNumber.slice(0, 10);
|
||||||
|
|
||||||
// Convert the key string back to a number
|
// Convert the key string back to a number
|
||||||
const highestKey = parseInt(keyStr, 10);
|
const highestKey = parseInt(keyStr, 10);
|
||||||
|
|
||||||
// Check if we have a valid secret key for the extracted highestKey
|
// Check if we have a valid secret key for the extracted highestKey
|
||||||
if (!secretKeyObject[highestKey]) {
|
if (!secretKeyObject[highestKey]) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
i18n.t('auth:message.error.find_secret_key', {
|
i18n.t('auth:message.error.find_secret_key', {
|
||||||
postProcess: 'capitalizeFirstChar',
|
postProcess: 'capitalizeFirstChar',
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
const secretKeyEntry = secretKeyObject[highestKey];
|
|
||||||
|
|
||||||
let typeNumberStr, nonceBase64, encryptedDataBase64;
|
|
||||||
|
|
||||||
// Determine if typeNumber exists by checking if the next 3 characters after keyStr are digits
|
|
||||||
const possibleTypeNumberStr = decodeForNumber.slice(10, 13);
|
|
||||||
const hasTypeNumber = /^\d{3}$/.test(possibleTypeNumberStr); // Check if next 3 characters are digits
|
|
||||||
|
|
||||||
if (secretKeyEntry.nonce) {
|
|
||||||
// Old format: nonce is present in the secretKeyObject, so no type number exists
|
|
||||||
nonceBase64 = secretKeyEntry.nonce;
|
|
||||||
encryptedDataBase64 = decodeForNumber.slice(10); // The remaining part is the encrypted data
|
|
||||||
} else {
|
|
||||||
if (hasTypeNumber) {
|
|
||||||
// const typeNumberStr = new TextDecoder().decode(typeNumberBytes);
|
|
||||||
if (decodeForNumber.slice(10, 13) !== '001') {
|
|
||||||
const decodedBinary = base64ToUint8Array(decodedData);
|
|
||||||
const highestKeyBytes = decodedBinary.slice(0, 10); // if ASCII digits only
|
|
||||||
const highestKeyStr = new TextDecoder().decode(highestKeyBytes);
|
|
||||||
|
|
||||||
const nonce = decodedBinary.slice(13, 13 + 24);
|
|
||||||
const encryptedData = decodedBinary.slice(13 + 24);
|
|
||||||
const highestKey = parseInt(highestKeyStr, 10);
|
|
||||||
|
|
||||||
const messageKey = base64ToUint8Array(
|
|
||||||
secretKeyObject[+highestKey].messageKey
|
|
||||||
);
|
|
||||||
const decryptedBytes = nacl.secretbox.open(
|
|
||||||
encryptedData,
|
|
||||||
nonce,
|
|
||||||
messageKey
|
|
||||||
);
|
|
||||||
|
|
||||||
// Check if decryption was successful
|
|
||||||
if (!decryptedBytes) {
|
|
||||||
throw new Error(
|
|
||||||
i18n.t('question:message.error.decryption_failed', {
|
|
||||||
postProcess: 'capitalizeFirstChar',
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert the decrypted Uint8Array back to a Base64 string
|
|
||||||
return uint8ArrayToBase64(decryptedBytes);
|
|
||||||
}
|
|
||||||
// New format: Extract type number and nonce
|
|
||||||
typeNumberStr = possibleTypeNumberStr; // Extract type number
|
|
||||||
nonceBase64 = decodeForNumber.slice(13, 45); // Extract nonce (next 32 characters after type number)
|
|
||||||
encryptedDataBase64 = decodeForNumber.slice(45); // The remaining part is the encrypted data
|
|
||||||
} else {
|
|
||||||
// Old format without type number (nonce is embedded in the message, first 32 characters after keyStr)
|
|
||||||
nonceBase64 = decodeForNumber.slice(10, 42); // First 32 characters for the nonce
|
|
||||||
encryptedDataBase64 = decodeForNumber.slice(42); // The remaining part is the encrypted data
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Convert Base64 strings to Uint8Array
|
const secretKeyEntry = secretKeyObject[highestKey];
|
||||||
const Uint8ArrayData = base64ToUint8Array(encryptedDataBase64);
|
|
||||||
const nonce = base64ToUint8Array(nonceBase64);
|
|
||||||
const messageKey = base64ToUint8Array(secretKeyEntry.messageKey);
|
|
||||||
|
|
||||||
if (!(Uint8ArrayData instanceof Uint8Array)) {
|
let nonceBase64, encryptedDataBase64;
|
||||||
throw new Error(
|
|
||||||
i18n.t('auth:message.error.invalid_uint8', {
|
// Determine if typeNumber exists by checking if the next 3 characters after keyStr are digits
|
||||||
postProcess: 'capitalizeFirstChar',
|
const possibleTypeNumberStr = decodeForNumber.slice(10, 13);
|
||||||
})
|
const hasTypeNumber = /^\d{3}$/.test(possibleTypeNumberStr); // Check if next 3 characters are digits
|
||||||
|
|
||||||
|
if (secretKeyEntry.nonce) {
|
||||||
|
// Old format: nonce is present in the secretKeyObject, so no type number exists
|
||||||
|
nonceBase64 = secretKeyEntry.nonce;
|
||||||
|
encryptedDataBase64 = decodeForNumber.slice(10); // The remaining part is the encrypted data
|
||||||
|
} else {
|
||||||
|
if (hasTypeNumber) {
|
||||||
|
// const typeNumberStr = new TextDecoder().decode(typeNumberBytes);
|
||||||
|
if (decodeForNumber.slice(10, 13) !== '001') {
|
||||||
|
const decodedBinary = base64ToUint8Array(decodedData);
|
||||||
|
const highestKeyBytes = decodedBinary.slice(0, 10); // if ASCII digits only
|
||||||
|
const highestKeyStr = new TextDecoder().decode(highestKeyBytes);
|
||||||
|
|
||||||
|
const nonce = decodedBinary.slice(13, 13 + 24);
|
||||||
|
const encryptedData = decodedBinary.slice(13 + 24);
|
||||||
|
const highestKey = parseInt(highestKeyStr, 10);
|
||||||
|
|
||||||
|
const messageKey = base64ToUint8Array(
|
||||||
|
secretKeyObject[+highestKey].messageKey
|
||||||
|
);
|
||||||
|
const decryptedBytes = nacl.secretbox.open(
|
||||||
|
encryptedData,
|
||||||
|
nonce,
|
||||||
|
messageKey
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check if decryption was successful
|
||||||
|
if (!decryptedBytes) {
|
||||||
|
throw new Error(
|
||||||
|
i18n.t('question:message.error.decryption_failed', {
|
||||||
|
postProcess: 'capitalizeFirstChar',
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert the decrypted Uint8Array back to a Base64 string
|
||||||
|
return uint8ArrayToBase64(decryptedBytes);
|
||||||
|
}
|
||||||
|
// New format: Extract type number and nonce
|
||||||
|
nonceBase64 = decodeForNumber.slice(13, 45); // Extract nonce (next 32 characters after type number)
|
||||||
|
encryptedDataBase64 = decodeForNumber.slice(45); // The remaining part is the encrypted data
|
||||||
|
} else {
|
||||||
|
// Old format without type number (nonce is embedded in the message, first 32 characters after keyStr)
|
||||||
|
nonceBase64 = decodeForNumber.slice(10, 42); // First 32 characters for the nonce
|
||||||
|
encryptedDataBase64 = decodeForNumber.slice(42); // The remaining part is the encrypted data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert Base64 strings to Uint8Array
|
||||||
|
const Uint8ArrayData = base64ToUint8Array(encryptedDataBase64);
|
||||||
|
const nonce = base64ToUint8Array(nonceBase64);
|
||||||
|
const messageKey = base64ToUint8Array(secretKeyEntry.messageKey);
|
||||||
|
|
||||||
|
if (!(Uint8ArrayData instanceof Uint8Array)) {
|
||||||
|
throw new Error(
|
||||||
|
i18n.t('auth:message.error.invalid_uint8', {
|
||||||
|
postProcess: 'capitalizeFirstChar',
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decrypt the data using the nonce and messageKey
|
||||||
|
const decryptedData = nacl.secretbox.open(
|
||||||
|
Uint8ArrayData,
|
||||||
|
nonce,
|
||||||
|
messageKey
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Check if decryption was successful
|
||||||
|
if (!decryptedData) {
|
||||||
|
throw new Error(
|
||||||
|
i18n.t('question:message.error.decryption_failed', {
|
||||||
|
postProcess: 'capitalizeFirstChar',
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert the decrypted Uint8Array back to a Base64 string
|
||||||
|
return uint8ArrayToBase64(decryptedData);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decrypt the data using the nonce and messageKey
|
return;
|
||||||
const decryptedData = nacl.secretbox.open(Uint8ArrayData, nonce, messageKey);
|
|
||||||
|
|
||||||
// Check if decryption was successful
|
|
||||||
if (!decryptedData) {
|
|
||||||
throw new Error(
|
|
||||||
i18n.t('question:message.error.decryption_failed', {
|
|
||||||
postProcess: 'capitalizeFirstChar',
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert the decrypted Uint8Array back to a Base64 string
|
|
||||||
return uint8ArrayToBase64(decryptedData);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const decryptGroupEncryptionWithSharingKey = async ({
|
export const decryptGroupEncryptionWithSharingKey = async ({
|
||||||
@ -424,14 +428,9 @@ export const decryptGroupEncryptionWithSharingKey = async ({
|
|||||||
// Extract the shared keyNonce
|
// Extract the shared keyNonce
|
||||||
const keyNonceStartPosition = nonceEndPosition;
|
const keyNonceStartPosition = nonceEndPosition;
|
||||||
const keyNonceEndPosition = keyNonceStartPosition + 24; // Nonce is 24 bytes
|
const keyNonceEndPosition = keyNonceStartPosition + 24; // Nonce is 24 bytes
|
||||||
const keyNonce = allCombined.slice(
|
|
||||||
keyNonceStartPosition,
|
|
||||||
keyNonceEndPosition
|
|
||||||
);
|
|
||||||
// Extract the sender's public key
|
// Extract the sender's public key
|
||||||
const senderPublicKeyStartPosition = keyNonceEndPosition;
|
const senderPublicKeyStartPosition = keyNonceEndPosition;
|
||||||
const senderPublicKeyEndPosition = senderPublicKeyStartPosition + 32; // Public keys are 32 bytes
|
const senderPublicKeyEndPosition = senderPublicKeyStartPosition + 32; // Public keys are 32 bytes
|
||||||
|
|
||||||
// Calculate count first
|
// Calculate count first
|
||||||
const countStartPosition = allCombined.length - 4; // 4 bytes before the end, since count is stored in Uint32 (4 bytes)
|
const countStartPosition = allCombined.length - 4; // 4 bytes before the end, since count is stored in Uint32 (4 bytes)
|
||||||
const countArray = allCombined.slice(
|
const countArray = allCombined.slice(
|
||||||
@ -662,7 +661,6 @@ export function decryptDeprecatedSingle(uint8Array, publicKey, privateKey) {
|
|||||||
const str = 'qortalEncryptedData';
|
const str = 'qortalEncryptedData';
|
||||||
const strEncoder = new TextEncoder();
|
const strEncoder = new TextEncoder();
|
||||||
const strUint8Array = strEncoder.encode(str);
|
const strUint8Array = strEncoder.encode(str);
|
||||||
const strData = combinedData.slice(0, strUint8Array.length);
|
|
||||||
const nonce = combinedData.slice(
|
const nonce = combinedData.slice(
|
||||||
strUint8Array.length,
|
strUint8Array.length,
|
||||||
strUint8Array.length + 24
|
strUint8Array.length + 24
|
||||||
|
@ -552,7 +552,7 @@ export const getUserAccount = async ({
|
|||||||
|
|
||||||
export const encryptData = async (data, sender) => {
|
export const encryptData = async (data, sender) => {
|
||||||
let data64 = data.data64 || data.base64;
|
let data64 = data.data64 || data.base64;
|
||||||
let publicKeys = data.publicKeys || [];
|
const publicKeys = data.publicKeys || [];
|
||||||
if (data?.file || data?.blob) {
|
if (data?.file || data?.blob) {
|
||||||
data64 = await fileToBase64(data?.file || data?.blob);
|
data64 = await fileToBase64(data?.file || data?.blob);
|
||||||
}
|
}
|
||||||
@ -587,8 +587,8 @@ export const encryptData = async (data, sender) => {
|
|||||||
|
|
||||||
export const encryptQortalGroupData = async (data, sender) => {
|
export const encryptQortalGroupData = async (data, sender) => {
|
||||||
let data64 = data?.data64 || data?.base64;
|
let data64 = data?.data64 || data?.base64;
|
||||||
let groupId = data?.groupId;
|
const groupId = data?.groupId;
|
||||||
let isAdmins = data?.isAdmins;
|
const isAdmins = data?.isAdmins;
|
||||||
if (!groupId) {
|
if (!groupId) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
i18n.t('question:message.generic.provide_group_id', {
|
i18n.t('question:message.generic.provide_group_id', {
|
||||||
@ -613,7 +613,7 @@ export const encryptQortalGroupData = async (data, sender) => {
|
|||||||
groupSecretkeys[groupId] &&
|
groupSecretkeys[groupId] &&
|
||||||
groupSecretkeys[groupId].secretKeyObject &&
|
groupSecretkeys[groupId].secretKeyObject &&
|
||||||
groupSecretkeys[groupId]?.timestamp &&
|
groupSecretkeys[groupId]?.timestamp &&
|
||||||
Date.now() - groupSecretkeys[groupId]?.timestamp < 1200000
|
Date.now() - groupSecretkeys[groupId]?.timestamp < 1200000 // TODO magic number
|
||||||
) {
|
) {
|
||||||
secretKeyObject = groupSecretkeys[groupId].secretKeyObject;
|
secretKeyObject = groupSecretkeys[groupId].secretKeyObject;
|
||||||
}
|
}
|
||||||
@ -659,7 +659,7 @@ export const encryptQortalGroupData = async (data, sender) => {
|
|||||||
groupSecretkeys[`admins-${groupId}`] &&
|
groupSecretkeys[`admins-${groupId}`] &&
|
||||||
groupSecretkeys[`admins-${groupId}`].secretKeyObject &&
|
groupSecretkeys[`admins-${groupId}`].secretKeyObject &&
|
||||||
groupSecretkeys[`admins-${groupId}`]?.timestamp &&
|
groupSecretkeys[`admins-${groupId}`]?.timestamp &&
|
||||||
Date.now() - groupSecretkeys[`admins-${groupId}`]?.timestamp < 1200000
|
Date.now() - groupSecretkeys[`admins-${groupId}`]?.timestamp < 1200000 // TODO magic number
|
||||||
) {
|
) {
|
||||||
secretKeyObject = groupSecretkeys[`admins-${groupId}`].secretKeyObject;
|
secretKeyObject = groupSecretkeys[`admins-${groupId}`].secretKeyObject;
|
||||||
}
|
}
|
||||||
@ -717,9 +717,9 @@ export const encryptQortalGroupData = async (data, sender) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const decryptQortalGroupData = async (data, sender) => {
|
export const decryptQortalGroupData = async (data, sender) => {
|
||||||
let data64 = data?.data64 || data?.base64;
|
const data64 = data?.data64 || data?.base64;
|
||||||
let groupId = data?.groupId;
|
const groupId = data?.groupId;
|
||||||
let isAdmins = data?.isAdmins;
|
const isAdmins = data?.isAdmins;
|
||||||
if (!groupId) {
|
if (!groupId) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
i18n.t('question:message.generic.provide_group_id', {
|
i18n.t('question:message.generic.provide_group_id', {
|
||||||
@ -742,7 +742,7 @@ export const decryptQortalGroupData = async (data, sender) => {
|
|||||||
groupSecretkeys[groupId] &&
|
groupSecretkeys[groupId] &&
|
||||||
groupSecretkeys[groupId].secretKeyObject &&
|
groupSecretkeys[groupId].secretKeyObject &&
|
||||||
groupSecretkeys[groupId]?.timestamp &&
|
groupSecretkeys[groupId]?.timestamp &&
|
||||||
Date.now() - groupSecretkeys[groupId]?.timestamp < 1200000
|
Date.now() - groupSecretkeys[groupId]?.timestamp < 1200000 // TODO magic number
|
||||||
) {
|
) {
|
||||||
secretKeyObject = groupSecretkeys[groupId].secretKeyObject;
|
secretKeyObject = groupSecretkeys[groupId].secretKeyObject;
|
||||||
}
|
}
|
||||||
@ -785,7 +785,7 @@ export const decryptQortalGroupData = async (data, sender) => {
|
|||||||
groupSecretkeys[`admins-${groupId}`] &&
|
groupSecretkeys[`admins-${groupId}`] &&
|
||||||
groupSecretkeys[`admins-${groupId}`].secretKeyObject &&
|
groupSecretkeys[`admins-${groupId}`].secretKeyObject &&
|
||||||
groupSecretkeys[`admins-${groupId}`]?.timestamp &&
|
groupSecretkeys[`admins-${groupId}`]?.timestamp &&
|
||||||
Date.now() - groupSecretkeys[`admins-${groupId}`]?.timestamp < 1200000
|
Date.now() - groupSecretkeys[`admins-${groupId}`]?.timestamp < 1200000 // TODO magic nummber
|
||||||
) {
|
) {
|
||||||
secretKeyObject = groupSecretkeys[`admins-${groupId}`].secretKeyObject;
|
secretKeyObject = groupSecretkeys[`admins-${groupId}`].secretKeyObject;
|
||||||
}
|
}
|
||||||
@ -843,7 +843,7 @@ export const decryptQortalGroupData = async (data, sender) => {
|
|||||||
|
|
||||||
export const encryptDataWithSharingKey = async (data, sender) => {
|
export const encryptDataWithSharingKey = async (data, sender) => {
|
||||||
let data64 = data?.data64 || data?.base64;
|
let data64 = data?.data64 || data?.base64;
|
||||||
let publicKeys = data.publicKeys || [];
|
const publicKeys = data.publicKeys || [];
|
||||||
if (data?.file || data?.blob) {
|
if (data?.file || data?.blob) {
|
||||||
data64 = await fileToBase64(data?.file || data?.blob);
|
data64 = await fileToBase64(data?.file || data?.blob);
|
||||||
}
|
}
|
||||||
@ -899,6 +899,7 @@ export const decryptDataWithSharingKey = async (data, sender) => {
|
|||||||
data64EncryptedData: encryptedData,
|
data64EncryptedData: encryptedData,
|
||||||
key,
|
key,
|
||||||
});
|
});
|
||||||
|
|
||||||
const base64ToObject = JSON.parse(atob(decryptedData));
|
const base64ToObject = JSON.parse(atob(decryptedData));
|
||||||
|
|
||||||
if (!base64ToObject.data)
|
if (!base64ToObject.data)
|
||||||
|
@ -152,7 +152,7 @@ function setupMessageListenerQortalRequest() {
|
|||||||
appInfo,
|
appInfo,
|
||||||
skipAuth,
|
skipAuth,
|
||||||
});
|
});
|
||||||
event.source.postMessage(
|
event.source!.postMessage(
|
||||||
{
|
{
|
||||||
requestId: request.requestId,
|
requestId: request.requestId,
|
||||||
action: request.action,
|
action: request.action,
|
||||||
@ -162,7 +162,7 @@ function setupMessageListenerQortalRequest() {
|
|||||||
event.origin
|
event.origin
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
event.source.postMessage(
|
event.source!.postMessage(
|
||||||
{
|
{
|
||||||
requestId: request.requestId,
|
requestId: request.requestId,
|
||||||
action: request.action,
|
action: request.action,
|
||||||
@ -236,7 +236,7 @@ function setupMessageListenerQortalRequest() {
|
|||||||
request.payload,
|
request.payload,
|
||||||
event.source
|
event.source
|
||||||
);
|
);
|
||||||
event.source.postMessage(
|
event.source!.postMessage(
|
||||||
{
|
{
|
||||||
requestId: request.requestId,
|
requestId: request.requestId,
|
||||||
action: request.action,
|
action: request.action,
|
||||||
@ -246,7 +246,7 @@ function setupMessageListenerQortalRequest() {
|
|||||||
event.origin
|
event.origin
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
event.source.postMessage(
|
event.source!.postMessage(
|
||||||
{
|
{
|
||||||
requestId: request.requestId,
|
requestId: request.requestId,
|
||||||
action: request.action,
|
action: request.action,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user