This commit is contained in:
PhilReact 2025-01-20 19:29:54 +02:00
parent 1f2c38e8df
commit d1f070555f
6 changed files with 306 additions and 221 deletions

View File

@ -174,15 +174,52 @@ export function openIndexedDB() {
} }
export const listOfAllQortalRequests = [
const UIQortalRequests = [
'GET_USER_ACCOUNT', 'DECRYPT_DATA', 'SEND_COIN', 'GET_LIST_ITEMS', 'GET_USER_ACCOUNT', 'DECRYPT_DATA', 'SEND_COIN', 'GET_LIST_ITEMS',
'ADD_LIST_ITEMS', 'DELETE_LIST_ITEM', 'VOTE_ON_POLL', 'CREATE_POLL', 'ADD_LIST_ITEMS', 'DELETE_LIST_ITEM', 'VOTE_ON_POLL', 'CREATE_POLL',
'SEND_CHAT_MESSAGE', 'JOIN_GROUP', 'DEPLOY_AT', 'GET_USER_WALLET', 'SEND_CHAT_MESSAGE', 'JOIN_GROUP', 'DEPLOY_AT', 'GET_USER_WALLET',
'GET_WALLET_BALANCE', 'GET_USER_WALLET_INFO', 'GET_CROSSCHAIN_SERVER_INFO', 'GET_WALLET_BALANCE', 'GET_USER_WALLET_INFO', 'GET_CROSSCHAIN_SERVER_INFO',
'GET_TX_ACTIVITY_SUMMARY', 'GET_FOREIGN_FEE', 'UPDATE_FOREIGN_FEE', 'GET_TX_ACTIVITY_SUMMARY', 'GET_FOREIGN_FEE', 'UPDATE_FOREIGN_FEE',
'GET_SERVER_CONNECTION_HISTORY', 'SET_CURRENT_FOREIGN_SERVER', 'GET_SERVER_CONNECTION_HISTORY', 'SET_CURRENT_FOREIGN_SERVER',
'ADD_FOREIGN_SERVER', 'REMOVE_FOREIGN_SERVER', 'GET_DAY_SUMMARY', 'CREATE_TRADE_BUY_ORDER', 'CREATE_TRADE_SELL_ORDER', 'CANCEL_TRADE_SELL_ORDER', 'IS_USING_GATEWAY', 'ADMIN_ACTION', 'SIGN_TRANSACTION', 'OPEN_NEW_TAB', 'CREATE_AND_COPY_EMBED_LINK', 'DECRYPT_QORTAL_GROUP_DATA', 'DECRYPT_DATA_WITH_SHARING_KEY', 'DELETE_HOSTED_DATA', 'GET_HOSTED_DATA' 'ADD_FOREIGN_SERVER', 'REMOVE_FOREIGN_SERVER', 'GET_DAY_SUMMARY', 'CREATE_TRADE_BUY_ORDER', 'CREATE_TRADE_SELL_ORDER', 'CANCEL_TRADE_SELL_ORDER', 'IS_USING_GATEWAY', 'ADMIN_ACTION', 'SIGN_TRANSACTION', 'OPEN_NEW_TAB', 'CREATE_AND_COPY_EMBED_LINK', 'DECRYPT_QORTAL_GROUP_DATA', 'DECRYPT_DATA_WITH_SHARING_KEY', 'DELETE_HOSTED_DATA', 'GET_HOSTED_DATA', 'PUBLISH_MULTIPLE_QDN_RESOURCES',
'PUBLISH_QDN_RESOURCE',
'ENCRYPT_DATA',
'ENCRYPT_DATA_WITH_SHARING_KEY',
'ENCRYPT_QORTAL_GROUP_DATA',
'SAVE_FILE',
'GET_ACCOUNT_DATA',
'GET_ACCOUNT_NAMES',
'SEARCH_NAMES',
'GET_NAME_DATA',
'GET_QDN_RESOURCE_URL',
'LINK_TO_QDN_RESOURCE',
'LIST_QDN_RESOURCES',
'SEARCH_QDN_RESOURCES',
'FETCH_QDN_RESOURCE',
'GET_QDN_RESOURCE_STATUS',
'GET_QDN_RESOURCE_PROPERTIES',
'GET_QDN_RESOURCE_METADATA',
'SEARCH_CHAT_MESSAGES',
'LIST_GROUPS',
'GET_BALANCE',
'GET_AT',
'GET_AT_DATA',
'LIST_ATS',
'FETCH_BLOCK',
'FETCH_BLOCK_RANGE',
'SEARCH_TRANSACTIONS',
'GET_PRICE',
'SHOW_ACTIONS'
]
export const UIQortalRequests = [
'GET_USER_ACCOUNT', 'DECRYPT_DATA', 'SEND_COIN', 'GET_LIST_ITEMS',
'ADD_LIST_ITEMS', 'DELETE_LIST_ITEM', 'VOTE_ON_POLL', 'CREATE_POLL',
'SEND_CHAT_MESSAGE', 'JOIN_GROUP', 'DEPLOY_AT', 'GET_USER_WALLET',
'GET_WALLET_BALANCE', 'GET_USER_WALLET_INFO', 'GET_CROSSCHAIN_SERVER_INFO',
'GET_TX_ACTIVITY_SUMMARY', 'GET_FOREIGN_FEE', 'UPDATE_FOREIGN_FEE',
'GET_SERVER_CONNECTION_HISTORY', 'SET_CURRENT_FOREIGN_SERVER',
'ADD_FOREIGN_SERVER', 'REMOVE_FOREIGN_SERVER', 'GET_DAY_SUMMARY', 'CREATE_TRADE_BUY_ORDER', 'CREATE_TRADE_SELL_ORDER', 'CANCEL_TRADE_SELL_ORDER', 'IS_USING_GATEWAY', 'ADMIN_ACTION', 'SIGN_TRANSACTION', 'OPEN_NEW_TAB', 'CREATE_AND_COPY_EMBED_LINK', 'DECRYPT_QORTAL_GROUP_DATA', 'DECRYPT_DATA_WITH_SHARING_KEY', 'DELETE_HOSTED_DATA', 'GET_HOSTED_DATA', 'SHOW_ACTIONS'
]; ];

View File

@ -195,7 +195,7 @@ export const getGroupMembers = async (groupNumber: number) => {
}; };
export const decryptResource = async (data: string) => { export const decryptResource = async (data: string, fromQortalRequest) => {
try { try {
return new Promise((res, rej) => { return new Promise((res, rej) => {
window.sendMessage("decryptGroupEncryption", { window.sendMessage("decryptGroupEncryption", {
@ -206,10 +206,19 @@ export const decryptResource = async (data: string) => {
res(response); res(response);
return; return;
} }
rej(response.error); if(fromQortalRequest){
rej({error: response.error, message: response?.error});
} else {
rej(response.error);
}
}) })
.catch((error) => { .catch((error) => {
rej(error.message || "An error occurred"); if(fromQortalRequest){
rej({message: error.message || "An error occurred", error: error.message || "An error occurred"});
} else {
rej(error.message || "An error occurred",);
}
}); });
}); });

View File

@ -24,12 +24,7 @@ import {
TextField, TextField,
Typography, Typography,
} from "@mui/material"; } from "@mui/material";
import {
AutoSizer,
CellMeasurer,
CellMeasurerCache,
List,
} from "react-virtualized";
import { getNameInfo } from "./Group"; import { getNameInfo } from "./Group";
import { getBaseApi, getFee } from "../../background"; import { getBaseApi, getFee } from "../../background";
import { LoadingButton } from "@mui/lab"; import { LoadingButton } from "@mui/lab";
@ -51,6 +46,8 @@ import ShortUniqueId from "short-unique-id";
import { CustomizedSnackbars } from "../Snackbar/Snackbar"; import { CustomizedSnackbars } from "../Snackbar/Snackbar";
import { getGroupNames } from "./UserListOfInvites"; import { getGroupNames } from "./UserListOfInvites";
import { WrapperUserAction } from "../WrapperUserAction"; import { WrapperUserAction } from "../WrapperUserAction";
import { useVirtualizer } from "@tanstack/react-virtual";
import ErrorBoundary from "../../common/ErrorBoundary";
export const requestQueuePromos = new RequestQueueWithPromise(20); export const requestQueuePromos = new RequestQueueWithPromise(20);
@ -68,10 +65,7 @@ export function utf8ToBase64(inputString: string): string {
const uid = new ShortUniqueId({ length: 8 }); const uid = new ShortUniqueId({ length: 8 });
const cache = new CellMeasurerCache({
fixedWidth: true,
defaultHeight: 50,
});
export function getGroupId(str) { export function getGroupId(str) {
const match = str.match(/group-(\d+)-/); const match = str.match(/group-(\d+)-/);
@ -102,6 +96,16 @@ export const ListOfGroupPromotions = () => {
const { show, setTxList } = useContext(MyContext); const { show, setTxList } = useContext(MyContext);
const listRef = useRef(); const listRef = useRef();
const rowVirtualizer = useVirtualizer({
count: promotions.length,
getItemKey: React.useCallback(
(index) => promotions[index]?.identifier,
[promotions]
),
getScrollElement: () => listRef.current,
estimateSize: () => 80, // Provide an estimated height of items, adjust this as needed
overscan: 10, // Number of items to render outside the visible area to improve smoothness
});
useEffect(() => { useEffect(() => {
try { try {
@ -190,7 +194,7 @@ export const ListOfGroupPromotions = () => {
}, initialDelay); }, initialDelay);
return () => clearTimeout(initialTimeout); return () => clearTimeout(initialTimeout);
}, [getPromotions]); }, [getPromotions, promotionTimeInterval]);
const handlePopoverOpen = (event, index) => { const handlePopoverOpen = (event, index) => {
setPopoverAnchor(event.currentTarget); setPopoverAnchor(event.currentTarget);
@ -324,69 +328,165 @@ export const ListOfGroupPromotions = () => {
} }
}; };
// const handleCancelInvitation = async (address)=> {
// try {
// const fee = await getFee('CANCEL_GROUP_INVITE')
// await show({
// message: "Would you like to perform a CANCEL_GROUP_INVITE transaction?" ,
// publishFee: fee.fee + ' QORT'
// })
// setIsLoadingCancelInvite(true)
// await new Promise((res, rej)=> {
// window.sendMessage("cancelInvitationToGroup", {
// groupId,
// qortalAddress: address,
// })
// .then((response) => {
// if (!response?.error) {
// setInfoSnack({
// type: "success",
// message: "Successfully canceled invitation. It may take a couple of minutes for the changes to propagate",
// });
// setOpenSnack(true);
// handlePopoverClose();
// setIsLoadingCancelInvite(true);
// res(response);
// return;
// }
// setInfoSnack({
// type: "error",
// message: response?.error,
// });
// setOpenSnack(true);
// rej(response.error);
// })
// .catch((error) => {
// setInfoSnack({
// type: "error",
// message: error.message || "An error occurred",
// });
// setOpenSnack(true);
// rej(error);
// });
// })
// } catch (error) {
// } finally { return (
// setIsLoadingCancelInvite(false) <Box
// } sx={{
// } width: "100%",
display: "flex",
const rowRenderer = ({ index, key, parent, style }) => { flexDirection: "column",
const promotion = promotions[index]; alignItems: "center",
marginTop: "25px",
return ( }}
<CellMeasurer >
key={key} <Box
cache={cache} sx={{
parent={parent} width: isMobile ? "320px" : "750px",
columnIndex={0} maxWidth: "90%",
rowIndex={index} display: "flex",
flexDirection: "column",
padding: "0px 20px",
}}
> >
{({ measure }) => ( <Box
<div style={style} onLoad={measure}> sx={{
<Box width: "100%",
display: "flex",
justifyContent: "space-between",
alignItems: "center",
}}
>
<Typography
sx={{
fontSize: "13px",
fontWeight: 600,
}}
>
Group Promotions
</Typography>
<Button
variant="contained"
onClick={() => setIsShowModal(true)}
sx={{
fontSize: "12px",
}}
>
Add Promotion
</Button>
</Box>
<Spacer height="10px" />
</Box>
<Box
sx={{
width: isMobile ? "320px" : "750px",
maxWidth: "90%",
maxHeight: "700px",
display: "flex",
flexDirection: "column",
bgcolor: "background.paper",
padding: "20px 0px",
borderRadius: "19px",
}}
>
{loading && promotions.length === 0 && (
<Box
sx={{
width: "100%",
display: "flex",
justifyContent: "center",
}}
>
<CustomLoader />
</Box>
)}
{!loading && promotions.length === 0 && (
<Box
sx={{
width: "100%",
display: "flex",
justifyContent: "center",
alignItems: "center",
height: "100%",
}}
>
<Typography
sx={{
fontSize: "11px",
fontWeight: 400,
color: "rgba(255, 255, 255, 0.2)",
}}
>
Nothing to display
</Typography>
</Box>
)}
<div
style={{
height: "600px",
position: "relative",
display: "flex",
flexDirection: "column",
width: "100%",
}}
>
<div
ref={listRef}
className="scrollable-container"
style={{
flexGrow: 1,
overflow: "auto",
position: "relative",
display: "flex",
height: "0px",
}}
>
<div
style={{
height: rowVirtualizer.getTotalSize(),
width: "100%",
}}
>
<div
style={{
position: "absolute",
top: 0,
left: 0,
width: "100%",
}}
>
{rowVirtualizer.getVirtualItems().map((virtualRow) => {
const index = virtualRow.index;
const promotion = promotions[index];
return (
<div
data-index={virtualRow.index} //needed for dynamic row height measurement
ref={rowVirtualizer.measureElement} //measure dynamic row height
key={promotion?.identifier}
style={{
position: "absolute",
top: 0,
left: "50%", // Move to the center horizontally
transform: `translateY(${virtualRow.start}px) translateX(-50%)`, // Adjust for centering
width: "100%", // Control width (90% of the parent)
padding: "10px 0",
display: "flex",
alignItems: "center",
overscrollBehavior: "none",
flexDirection: "column",
gap: "5px",
}}
>
<ErrorBoundary
fallback={
<Typography>
Error loading content: Invalid Data
</Typography>
}
>
<Box
sx={{ sx={{
display: "flex", display: "flex",
flexDirection: "column", flexDirection: "column",
@ -598,125 +698,16 @@ export const ListOfGroupPromotions = () => {
</Box> </Box>
</Box> </Box>
<Spacer height="50px" /> <Spacer height="50px" />
</div> </ErrorBoundary>
)} </div>
</CellMeasurer>
); );
}; })}
</div>
</div>
</div>
</div>
return (
<Box
sx={{
width: "100%",
display: "flex",
flexDirection: "column",
alignItems: "center",
marginTop: "25px",
}}
>
<Box
sx={{
width: isMobile ? "320px" : "750px",
maxWidth: "90%",
display: "flex",
flexDirection: "column",
padding: "0px 20px",
}}
>
<Box
sx={{
width: "100%",
display: "flex",
justifyContent: "space-between",
alignItems: "center",
}}
>
<Typography
sx={{
fontSize: "13px",
fontWeight: 600,
}}
>
Group Promotions
</Typography>
<Button
variant="contained"
onClick={() => setIsShowModal(true)}
sx={{
fontSize: "12px",
}}
>
Add Promotion
</Button>
</Box>
<Spacer height="10px" />
</Box>
<Box
sx={{
width: isMobile ? "320px" : "750px",
maxWidth: "90%",
maxHeight: "700px",
display: "flex",
flexDirection: "column",
bgcolor: "background.paper",
padding: "20px 0px",
borderRadius: "19px",
}}
>
{loading && promotions.length === 0 && (
<Box
sx={{
width: "100%",
display: "flex",
justifyContent: "center",
}}
>
<CustomLoader />
</Box>
)}
{!loading && promotions.length === 0 && (
<Box
sx={{
width: "100%",
display: "flex",
justifyContent: "center",
alignItems: "center",
height: "100%",
}}
>
<Typography
sx={{
fontSize: "11px",
fontWeight: 400,
color: "rgba(255, 255, 255, 0.2)",
}}
>
Nothing to display
</Typography>
</Box>
)}
<div
style={{
height: "600px",
}}
>
<AutoSizer>
{({ height, width }) => (
<List
ref={listRef}
width={width}
height={height}
rowCount={promotions.length}
rowHeight={cache.rowHeight}
rowRenderer={rowRenderer}
deferredMeasurementCache={cache}
className="scrollable-container"
/>
)}
</AutoSizer>
</div>
</Box> </Box>
<Spacer height="20px" /> <Spacer height="20px" />

View File

@ -17,9 +17,9 @@ import { InviteMember } from "./InviteMember";
import { ListOfInvites } from "./ListOfInvites"; import { ListOfInvites } from "./ListOfInvites";
import { ListOfBans } from "./ListOfBans"; import { ListOfBans } from "./ListOfBans";
import { ListOfJoinRequests } from "./ListOfJoinRequests"; import { ListOfJoinRequests } from "./ListOfJoinRequests";
import { Box, Tab, Tabs } from "@mui/material"; import { Box, Card, Tab, Tabs } from "@mui/material";
import { CustomizedSnackbars } from "../Snackbar/Snackbar"; import { CustomizedSnackbars } from "../Snackbar/Snackbar";
import { MyContext, isMobile } from "../../App"; import { MyContext, getBaseApiReact, isMobile } from "../../App";
import { getGroupMembers, getNames } from "./Group"; import { getGroupMembers, getNames } from "./Group";
import { LoadingSnackbar } from "../Snackbar/LoadingSnackbar"; import { LoadingSnackbar } from "../Snackbar/LoadingSnackbar";
import { getFee } from "../../background"; import { getFee } from "../../background";
@ -59,6 +59,7 @@ export const ManageMembers = ({
const [infoSnack, setInfoSnack] = React.useState(null); const [infoSnack, setInfoSnack] = React.useState(null);
const [isLoadingMembers, setIsLoadingMembers] = React.useState(false) const [isLoadingMembers, setIsLoadingMembers] = React.useState(false)
const [isLoadingLeave, setIsLoadingLeave] = React.useState(false) const [isLoadingLeave, setIsLoadingLeave] = React.useState(false)
const [groupInfo, setGroupInfo] = React.useState(null)
const handleChange = (event: React.SyntheticEvent, newValue: number) => { const handleChange = (event: React.SyntheticEvent, newValue: number) => {
setValue(newValue); setValue(newValue);
}; };
@ -68,6 +69,7 @@ export const ManageMembers = ({
setOpen(false); setOpen(false);
}; };
const handleLeaveGroup = async () => { const handleLeaveGroup = async () => {
try { try {
setIsLoadingLeave(true) setIsLoadingLeave(true)
@ -130,10 +132,20 @@ export const ManageMembers = ({
setMembersWithNames(res?.members || []); setMembersWithNames(res?.members || []);
} catch (error) {} } catch (error) {}
}; };
const getGroupInfo = async (groupId) => {
try {
const response = await fetch(
`${getBaseApiReact()}/groups/${groupId}`
);
const groupData = await response.json();
setGroupInfo(groupData)
} catch (error) {}
};
React.useEffect(()=> { React.useEffect(()=> {
if(selectedGroup?.groupId){ if(selectedGroup?.groupId){
getMembers(selectedGroup?.groupId) getMembers(selectedGroup?.groupId)
getGroupInfo(selectedGroup?.groupId)
} }
}, [selectedGroup?.groupId]) }, [selectedGroup?.groupId])
@ -248,14 +260,23 @@ export const ManageMembers = ({
/> />
</Tabs> </Tabs>
</Box> </Box>
<Card sx={{
padding: '10px',
cursor: 'default',
}}>
<Box>
<Typography>GroupId: {groupInfo?.groupId}</Typography>
<Typography>GroupName: {groupInfo?.groupName}</Typography>
<Typography>Number of members: {groupInfo?.memberCount}</Typography>
</Box>
<Spacer height="20px" />
{selectedGroup?.groupId && !isOwner && ( {selectedGroup?.groupId && !isOwner && (
<LoadingButton loading={isLoadingLeave} loadingPosition="start" <LoadingButton size="small" loading={isLoadingLeave} loadingPosition="start"
variant="contained" onClick={handleLeaveGroup}> variant="contained" onClick={handleLeaveGroup}>
Leave Group Leave Group
</LoadingButton> </LoadingButton>
)} )}
</Card>
{value === 0 && ( {value === 0 && (
<Box <Box
sx={{ sx={{

View File

@ -1,4 +1,5 @@
import { gateways, getApiKeyFromStorage } from "./background"; import { gateways, getApiKeyFromStorage } from "./background";
import { listOfAllQortalRequests } from "./components/Apps/useQortalMessageListener";
import { addForeignServer, addListItems, adminAction, cancelSellOrder, createAndCopyEmbedLink, createBuyOrder, createPoll, createSellOrder, decryptData, decryptDataWithSharingKey, decryptQortalGroupData, deleteHostedData, deleteListItems, deployAt, encryptData, encryptDataWithSharingKey, encryptQortalGroupData, getCrossChainServerInfo, getDaySummary, getForeignFee, getHostedData, getListItems, getServerConnectionHistory, getTxActivitySummary, getUserAccount, getUserWallet, getUserWalletInfo, getWalletBalance, joinGroup, openNewTab, publishMultipleQDNResources, publishQDNResource, removeForeignServer, saveFile, sendChatMessage, sendCoin, setCurrentForeignServer, signTransaction, updateForeignFee, voteOnPoll } from "./qortalRequests/get"; import { addForeignServer, addListItems, adminAction, cancelSellOrder, createAndCopyEmbedLink, createBuyOrder, createPoll, createSellOrder, decryptData, decryptDataWithSharingKey, decryptQortalGroupData, deleteHostedData, deleteListItems, deployAt, encryptData, encryptDataWithSharingKey, encryptQortalGroupData, getCrossChainServerInfo, getDaySummary, getForeignFee, getHostedData, getListItems, getServerConnectionHistory, getTxActivitySummary, getUserAccount, getUserWallet, getUserWalletInfo, getWalletBalance, joinGroup, openNewTab, publishMultipleQDNResources, publishQDNResource, removeForeignServer, saveFile, sendChatMessage, sendCoin, setCurrentForeignServer, signTransaction, updateForeignFee, voteOnPoll } from "./qortalRequests/get";
import { getData, storeData } from "./utils/chromeStorage"; import { getData, storeData } from "./utils/chromeStorage";
@ -866,7 +867,25 @@ export const isRunningGateway = async ()=> {
} }
break; break;
} }
case "SHOW_ACTIONS" : {
try {
event.source.postMessage({
requestId: request.requestId,
action: request.action,
payload: listOfAllQortalRequests,
type: "backgroundMessageResponse",
}, event.origin);
} catch (error) {
event.source.postMessage({
requestId: request.requestId,
action: request.action,
error: error?.message,
type: "backgroundMessageResponse",
}, event.origin);
}
break;
}
default: default:
break; break;
} }

View File

@ -427,7 +427,7 @@ export const encryptData = async (data, sender) => {
}; };
export const encryptQortalGroupData = async (data, sender) => { export const encryptQortalGroupData = async (data, sender) => {
let data64 = data.data64; let data64 = data?.data64 || data?.base64;
let groupId = data?.groupId let groupId = data?.groupId
let isAdmins = data?.isAdmins let isAdmins = data?.isAdmins
if(!groupId){ if(!groupId){
@ -462,7 +462,8 @@ export const encryptQortalGroupData = async (data, sender) => {
url url
); );
const resData = await res.text(); const resData = await res.text();
const decryptedKey: any = await decryptResource(resData);
const decryptedKey: any = await decryptResource(resData, true);
const dataint8Array = base64ToUint8Array(decryptedKey.data); const dataint8Array = base64ToUint8Array(decryptedKey.data);
const decryptedKeyToObject = uint8ArrayToObject(dataint8Array); const decryptedKeyToObject = uint8ArrayToObject(dataint8Array);
@ -496,8 +497,7 @@ url
url url
); );
const resData = await res.text(); const resData = await res.text();
const decryptedKey: any = await decryptResource(resData); const decryptedKey: any = await decryptResource(resData, true);
const dataint8Array = base64ToUint8Array(decryptedKey.data); const dataint8Array = base64ToUint8Array(decryptedKey.data);
const decryptedKeyToObject = uint8ArrayToObject(dataint8Array); const decryptedKeyToObject = uint8ArrayToObject(dataint8Array);
@ -526,7 +526,7 @@ url
}; };
export const decryptQortalGroupData = async (data, sender) => { export const decryptQortalGroupData = async (data, sender) => {
let data64 = data.data64; let data64 = data?.data64 || data?.base64;
let groupId = data?.groupId let groupId = data?.groupId
let isAdmins = data?.isAdmins let isAdmins = data?.isAdmins
if(!groupId){ if(!groupId){
@ -557,7 +557,7 @@ export const decryptQortalGroupData = async (data, sender) => {
url url
); );
const resData = await res.text(); const resData = await res.text();
const decryptedKey: any = await decryptResource(resData); const decryptedKey: any = await decryptResource(resData, true);
const dataint8Array = base64ToUint8Array(decryptedKey.data); const dataint8Array = base64ToUint8Array(decryptedKey.data);
const decryptedKeyToObject = uint8ArrayToObject(dataint8Array); const decryptedKeyToObject = uint8ArrayToObject(dataint8Array);
@ -588,7 +588,7 @@ url
url url
); );
const resData = await res.text(); const resData = await res.text();
const decryptedKey: any = await decryptResource(resData); const decryptedKey: any = await decryptResource(resData, true);
const dataint8Array = base64ToUint8Array(decryptedKey.data); const dataint8Array = base64ToUint8Array(decryptedKey.data);
const decryptedKeyToObject = uint8ArrayToObject(dataint8Array); const decryptedKeyToObject = uint8ArrayToObject(dataint8Array);
@ -615,7 +615,7 @@ url
}; };
export const encryptDataWithSharingKey = async (data, sender) => { export const encryptDataWithSharingKey = async (data, sender) => {
let data64 = data.data64; let data64 = data?.data64 || data?.base64;
let publicKeys = data.publicKeys || []; let 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);
@ -663,7 +663,10 @@ export const decryptDataWithSharingKey = async (data, sender) => {
}; };
export const getHostedData = async (data, isFromExtension) => { export const getHostedData = async (data, isFromExtension) => {
const isGateway = await isRunningGateway();
if (isGateway) {
throw new Error("This action cannot be done through a gateway");
}
const resPermission = await getUserPermission( const resPermission = await getUserPermission(
{ {
text1: "Do you give this application permission to", text1: "Do you give this application permission to",
@ -675,18 +678,19 @@ export const getHostedData = async (data, isFromExtension) => {
if(accepted){ if(accepted){
const limit = data?.limit ? data?.limit : 20; const limit = data?.limit ? data?.limit : 20;
const query = data?.query ? data?.query : undefined const query = data?.query ? data?.query : ""
const offset = data?.offset ? data?.offset : 0 const offset = data?.offset ? data?.offset : 0
try { let urlPath = `/arbitrary/hosted/resources/?limit=${limit}&offset=${offset}`
if(query){
const url = await createEndpoint(`/arbitrary/hosted/resources/?limit=${limit}&query=${query}&offset=${offset}`); urlPath = urlPath + `&query=${query}`
const response = await fetch(url);
const data = await response.json();
return data
} catch (error) {
throw error
} }
const url = await createEndpoint(urlPath);
const response = await fetch(url);
const dataResponse = await response.json();
return dataResponse
} else { } else {
throw new Error("User declined to get list of hosted resources"); throw new Error("User declined to get list of hosted resources");
@ -695,6 +699,10 @@ export const getHostedData = async (data, isFromExtension) => {
}; };
export const deleteHostedData = async (data, isFromExtension) => { export const deleteHostedData = async (data, isFromExtension) => {
const isGateway = await isRunningGateway();
if (isGateway) {
throw new Error("This action cannot be done through a gateway");
}
const requiredFields = ["hostedData"]; const requiredFields = ["hostedData"];
const missingFields: string[] = []; const missingFields: string[] = [];
requiredFields.forEach((field) => { requiredFields.forEach((field) => {
@ -716,7 +724,7 @@ export const deleteHostedData = async (data, isFromExtension) => {
for (const hostedDataItem of hostedData){ for (const hostedDataItem of hostedData){
try { try {
const url = await createEndpoint(`/arbitrary/resource/${hostedDataItem.service}/${hostedDataItem.name}/${hostedDataItem.identifer}`); const url = await createEndpoint(`/arbitrary/resource/${hostedDataItem.service}/${hostedDataItem.name}/${hostedDataItem.identifier}`);
await fetch(url, { await fetch(url, {
method: "DELETE", method: "DELETE",
headers: { headers: {
@ -971,7 +979,7 @@ export const publishQDNResource = async (
if (!data.file && !data.data64 && !data.base64) { if (!data.file && !data.data64 && !data.base64) {
throw new Error("No data or file was submitted"); throw new Error("No data or file was submitted");
} }
// Use "default" if user hasn't specified an identifer // Use "default" if user hasn't specified an identifier
const service = data.service; const service = data.service;
const appFee = data?.appFee ? +data.appFee : undefined const appFee = data?.appFee ? +data.appFee : undefined
const appFeeRecipient = data?.appFeeRecipient const appFeeRecipient = data?.appFeeRecipient