mirror of
https://github.com/Qortal/Qortal-Hub.git
synced 2025-05-13 05:07:52 +00:00
tighten up csp
This commit is contained in:
parent
1b8137fe35
commit
37de676069
@ -23,7 +23,7 @@ const capacitorFileConfig: CapacitorElectronConfig = getCapacitorElectronConfig(
|
|||||||
|
|
||||||
// Initialize our app. You can pass menu templates into the app here.
|
// Initialize our app. You can pass menu templates into the app here.
|
||||||
// const myCapacitorApp = new ElectronCapacitorApp(capacitorFileConfig);
|
// const myCapacitorApp = new ElectronCapacitorApp(capacitorFileConfig);
|
||||||
const myCapacitorApp = new ElectronCapacitorApp(capacitorFileConfig, trayMenuTemplate, appMenuBarMenuTemplate);
|
export const myCapacitorApp = new ElectronCapacitorApp(capacitorFileConfig, trayMenuTemplate, appMenuBarMenuTemplate);
|
||||||
|
|
||||||
// If deeplinking is enabled then we will set it up here.
|
// If deeplinking is enabled then we will set it up here.
|
||||||
if (capacitorFileConfig.electron?.deepLinkingEnabled) {
|
if (capacitorFileConfig.electron?.deepLinkingEnabled) {
|
||||||
|
@ -5,7 +5,10 @@ console.log('User Preload!');
|
|||||||
const { contextBridge, shell, ipcRenderer } = require('electron');
|
const { contextBridge, shell, ipcRenderer } = require('electron');
|
||||||
|
|
||||||
contextBridge.exposeInMainWorld('electronAPI', {
|
contextBridge.exposeInMainWorld('electronAPI', {
|
||||||
openExternal: (url) => shell.openExternal(url)
|
openExternal: (url) => shell.openExternal(url),
|
||||||
|
setAllowedDomains: (domains) => {
|
||||||
|
ipcRenderer.send('set-allowed-domains', domains);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
contextBridge.exposeInMainWorld('electron', {
|
contextBridge.exposeInMainWorld('electron', {
|
||||||
@ -13,3 +16,5 @@ contextBridge.exposeInMainWorld('electron', {
|
|||||||
onUpdateDownloaded: (callback) => ipcRenderer.on('update_downloaded', callback),
|
onUpdateDownloaded: (callback) => ipcRenderer.on('update_downloaded', callback),
|
||||||
restartApp: () => ipcRenderer.send('restart_app')
|
restartApp: () => ipcRenderer.send('restart_app')
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ipcRenderer.send('test-ipc');
|
@ -6,13 +6,34 @@ import {
|
|||||||
} from '@capacitor-community/electron';
|
} from '@capacitor-community/electron';
|
||||||
import chokidar from 'chokidar';
|
import chokidar from 'chokidar';
|
||||||
import type { MenuItemConstructorOptions } from 'electron';
|
import type { MenuItemConstructorOptions } from 'electron';
|
||||||
import { app, BrowserWindow, Menu, MenuItem, nativeImage, Tray, session } from 'electron';
|
import { app, BrowserWindow, Menu, MenuItem, nativeImage, Tray, session, ipcMain } from 'electron';
|
||||||
import electronIsDev from 'electron-is-dev';
|
import electronIsDev from 'electron-is-dev';
|
||||||
import electronServe from 'electron-serve';
|
import electronServe from 'electron-serve';
|
||||||
import windowStateKeeper from 'electron-window-state';
|
import windowStateKeeper from 'electron-window-state';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
import { myCapacitorApp } from '.';
|
||||||
|
|
||||||
|
|
||||||
|
const defaultDomains = [
|
||||||
|
'http://127.0.0.1:12391',
|
||||||
|
'ws://127.0.0.1:12391',
|
||||||
|
'https://ext-node.qortal.link',
|
||||||
|
'wss://ext-node.qortal.link',
|
||||||
|
'https://appnode.qortal.org',
|
||||||
|
"https://api.qortal.org",
|
||||||
|
"https://api2.qortal.org",
|
||||||
|
"https://appnode.qortal.org",
|
||||||
|
"https://apinode.qortalnodes.live",
|
||||||
|
"https://apinode1.qortalnodes.live",
|
||||||
|
"https://apinode2.qortalnodes.live",
|
||||||
|
"https://apinode3.qortalnodes.live",
|
||||||
|
"https://apinode4.qortalnodes.live"
|
||||||
|
|
||||||
|
];
|
||||||
|
// let allowedDomains: string[] = [...defaultDomains]
|
||||||
|
const domainHolder = {
|
||||||
|
allowedDomains: [...defaultDomains],
|
||||||
|
};
|
||||||
// Define components for a watcher to detect when the webapp is changed so we can reload in Dev mode.
|
// Define components for a watcher to detect when the webapp is changed so we can reload in Dev mode.
|
||||||
const reloadWatcher = {
|
const reloadWatcher = {
|
||||||
debouncer: null,
|
debouncer: null,
|
||||||
@ -220,15 +241,79 @@ export class ElectronCapacitorApp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set a CSP up for our application based on the custom scheme
|
// Set a CSP up for our application based on the custom scheme
|
||||||
|
// export function setupContentSecurityPolicy(customScheme: string): void {
|
||||||
|
// session.defaultSession.webRequest.onHeadersReceived((details, callback) => {
|
||||||
|
// callback({
|
||||||
|
// responseHeaders: {
|
||||||
|
// ...details.responseHeaders,
|
||||||
|
// 'Content-Security-Policy': [
|
||||||
|
// "script-src 'self' 'wasm-unsafe-eval' 'unsafe-inline' 'unsafe-eval'; object-src 'self'; connect-src 'self' https://*:* http://*:* wss://*:* ws://*:*",
|
||||||
|
// ],
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
export function setupContentSecurityPolicy(customScheme: string): void {
|
export function setupContentSecurityPolicy(customScheme: string): void {
|
||||||
session.defaultSession.webRequest.onHeadersReceived((details, callback) => {
|
session.defaultSession.webRequest.onHeadersReceived((details, callback) => {
|
||||||
callback({
|
const allowedSources = ["'self'", ...domainHolder.allowedDomains].join(' ');
|
||||||
responseHeaders: {
|
const csp = `
|
||||||
...details.responseHeaders,
|
script-src 'self' 'wasm-unsafe-eval' 'unsafe-inline' 'unsafe-eval' ${allowedSources};
|
||||||
'Content-Security-Policy': [
|
object-src 'self';
|
||||||
"script-src 'self' 'wasm-unsafe-eval' 'unsafe-inline' 'unsafe-eval'; object-src 'self'; connect-src 'self' https://*:* http://*:* wss://*:* ws://*:*",
|
connect-src ${allowedSources};
|
||||||
],
|
`.replace(/\s+/g, ' ').trim();
|
||||||
},
|
|
||||||
|
callback({
|
||||||
|
responseHeaders: {
|
||||||
|
...details.responseHeaders,
|
||||||
|
'Content-Security-Policy': [csp],
|
||||||
|
},
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// IPC listener for updating allowed domains
|
||||||
|
ipcMain.on('set-allowed-domains', (event, domains: string[]) => {
|
||||||
|
|
||||||
|
// Validate and transform user-provided domains
|
||||||
|
const validatedUserDomains = domains
|
||||||
|
.flatMap((domain) => {
|
||||||
|
try {
|
||||||
|
const url = new URL(domain);
|
||||||
|
const protocol = url.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||||
|
const socketUrl = `${protocol}//${url.hostname}${url.port ? ':' + url.port : ''}`;
|
||||||
|
return [url.origin, socketUrl];
|
||||||
|
} catch {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.filter(Boolean) as string[];
|
||||||
|
|
||||||
|
// Combine default and validated user domains
|
||||||
|
const newAllowedDomains = [...new Set([...defaultDomains, ...validatedUserDomains])];
|
||||||
|
|
||||||
|
// Sort both current allowed domains and new domains for comparison
|
||||||
|
const sortedCurrentDomains = [...domainHolder.allowedDomains].sort();
|
||||||
|
const sortedNewDomains = [...newAllowedDomains].sort();
|
||||||
|
|
||||||
|
// Check if the lists are different
|
||||||
|
const hasChanged =
|
||||||
|
sortedCurrentDomains.length !== sortedNewDomains.length ||
|
||||||
|
sortedCurrentDomains.some((domain, index) => domain !== sortedNewDomains[index]);
|
||||||
|
|
||||||
|
// If there's a change, update allowedDomains and reload the window
|
||||||
|
if (hasChanged) {
|
||||||
|
domainHolder.allowedDomains = newAllowedDomains;
|
||||||
|
|
||||||
|
const mainWindow = myCapacitorApp.getMainWindow();
|
||||||
|
if (mainWindow && !mainWindow.isDestroyed()) {
|
||||||
|
mainWindow.webContents.reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,15 +23,14 @@ import { set } from "lodash";
|
|||||||
import { cleanUrl, isUsingLocal } from "../background";
|
import { cleanUrl, isUsingLocal } from "../background";
|
||||||
|
|
||||||
const manifestData = {
|
const manifestData = {
|
||||||
version: '0.2.0'
|
version: "0.2.0",
|
||||||
}
|
};
|
||||||
|
|
||||||
export const NotAuthenticated = ({
|
export const NotAuthenticated = ({
|
||||||
getRootProps,
|
getRootProps,
|
||||||
getInputProps,
|
getInputProps,
|
||||||
setExtstate,
|
setExtstate,
|
||||||
|
|
||||||
|
|
||||||
apiKey,
|
apiKey,
|
||||||
setApiKey,
|
setApiKey,
|
||||||
globalApiKey,
|
globalApiKey,
|
||||||
@ -54,9 +53,9 @@ export const NotAuthenticated = ({
|
|||||||
const [customApikey, setCustomApiKey] = React.useState("");
|
const [customApikey, setCustomApiKey] = React.useState("");
|
||||||
const [customNodeToSaveIndex, setCustomNodeToSaveIndex] =
|
const [customNodeToSaveIndex, setCustomNodeToSaveIndex] =
|
||||||
React.useState(null);
|
React.useState(null);
|
||||||
const importedApiKeyRef = useRef(null)
|
const importedApiKeyRef = useRef(null);
|
||||||
const currentNodeRef = useRef(null)
|
const currentNodeRef = useRef(null);
|
||||||
const hasLocalNodeRef = useRef(null)
|
const hasLocalNodeRef = useRef(null);
|
||||||
const isLocal = cleanUrl(currentNode?.url) === "127.0.0.1:12391";
|
const isLocal = cleanUrl(currentNode?.url) === "127.0.0.1:12391";
|
||||||
const handleFileChangeApiKey = (event) => {
|
const handleFileChangeApiKey = (event) => {
|
||||||
const file = event.target.files[0]; // Get the selected file
|
const file = event.target.files[0]; // Get the selected file
|
||||||
@ -71,7 +70,6 @@ export const NotAuthenticated = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const checkIfUserHasLocalNode = useCallback(async () => {
|
const checkIfUserHasLocalNode = useCallback(async () => {
|
||||||
try {
|
try {
|
||||||
const url = `http://127.0.0.1:12391/admin/status`;
|
const url = `http://127.0.0.1:12391/admin/status`;
|
||||||
@ -93,43 +91,48 @@ export const NotAuthenticated = ({
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
window.sendMessage("getCustomNodesFromStorage")
|
window
|
||||||
.then((response) => {
|
.sendMessage("getCustomNodesFromStorage")
|
||||||
if (response) {
|
.then((response) => {
|
||||||
setCustomNodes(response || []);
|
if (response) {
|
||||||
}
|
setCustomNodes(response || []);
|
||||||
})
|
window.electronAPI.setAllowedDomains(response?.map((node)=> node.url))
|
||||||
.catch((error) => {
|
|
||||||
console.error("Failed to get custom nodes from storage:", error.message || "An error occurred");
|
|
||||||
});
|
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error(
|
||||||
|
"Failed to get custom nodes from storage:",
|
||||||
|
error.message || "An error occurred"
|
||||||
|
);
|
||||||
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(()=> {
|
useEffect(() => {
|
||||||
importedApiKeyRef.current = importedApiKey
|
importedApiKeyRef.current = importedApiKey;
|
||||||
}, [importedApiKey])
|
}, [importedApiKey]);
|
||||||
useEffect(()=> {
|
useEffect(() => {
|
||||||
currentNodeRef.current = currentNode
|
currentNodeRef.current = currentNode;
|
||||||
}, [currentNode])
|
}, [currentNode]);
|
||||||
|
|
||||||
useEffect(()=> {
|
useEffect(() => {
|
||||||
hasLocalNodeRef.current = hasLocalNode
|
hasLocalNodeRef.current = hasLocalNode;
|
||||||
}, [hasLocalNode])
|
}, [hasLocalNode]);
|
||||||
|
|
||||||
const validateApiKey = useCallback(async (key, fromStartUp) => {
|
const validateApiKey = useCallback(async (key, fromStartUp) => {
|
||||||
try {
|
try {
|
||||||
if(!currentNodeRef.current) return
|
if (!currentNodeRef.current) return;
|
||||||
const isLocalKey = cleanUrl(key?.url) === "127.0.0.1:12391";
|
const isLocalKey = cleanUrl(key?.url) === "127.0.0.1:12391";
|
||||||
if(isLocalKey && !hasLocalNodeRef.current && !fromStartUp){
|
if (isLocalKey && !hasLocalNodeRef.current && !fromStartUp) {
|
||||||
throw new Error('Please turn on your local node')
|
throw new Error("Please turn on your local node");
|
||||||
|
}
|
||||||
}
|
const isCurrentNodeLocal =
|
||||||
const isCurrentNodeLocal = cleanUrl(currentNodeRef.current?.url) === "127.0.0.1:12391";
|
cleanUrl(currentNodeRef.current?.url) === "127.0.0.1:12391";
|
||||||
if(isLocalKey && !isCurrentNodeLocal) {
|
if (isLocalKey && !isCurrentNodeLocal) {
|
||||||
setIsValidApiKey(false);
|
setIsValidApiKey(false);
|
||||||
setUseLocalNode(false);
|
setUseLocalNode(false);
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
let payload = {};
|
let payload = {};
|
||||||
|
|
||||||
if (currentNodeRef.current?.url === "http://127.0.0.1:12391") {
|
if (currentNodeRef.current?.url === "http://127.0.0.1:12391") {
|
||||||
@ -137,7 +140,7 @@ export const NotAuthenticated = ({
|
|||||||
apikey: importedApiKeyRef.current || key?.apikey,
|
apikey: importedApiKeyRef.current || key?.apikey,
|
||||||
url: currentNodeRef.current?.url,
|
url: currentNodeRef.current?.url,
|
||||||
};
|
};
|
||||||
} else if(currentNodeRef.current) {
|
} else if (currentNodeRef.current) {
|
||||||
payload = currentNodeRef.current;
|
payload = currentNodeRef.current;
|
||||||
}
|
}
|
||||||
const url = `${payload?.url}/admin/apikey/test`;
|
const url = `${payload?.url}/admin/apikey/test`;
|
||||||
@ -152,21 +155,24 @@ export const NotAuthenticated = ({
|
|||||||
// Assuming the response is in plain text and will be 'true' or 'false'
|
// Assuming the response is in plain text and will be 'true' or 'false'
|
||||||
const data = await response.text();
|
const data = await response.text();
|
||||||
if (data === "true") {
|
if (data === "true") {
|
||||||
window.sendMessage("setApiKey", payload)
|
window
|
||||||
.then((response) => {
|
.sendMessage("setApiKey", payload)
|
||||||
if (response) {
|
.then((response) => {
|
||||||
handleSetGlobalApikey(payload);
|
if (response) {
|
||||||
setIsValidApiKey(true);
|
handleSetGlobalApikey(payload);
|
||||||
setUseLocalNode(true);
|
setIsValidApiKey(true);
|
||||||
if (!fromStartUp) {
|
setUseLocalNode(true);
|
||||||
setApiKey(payload);
|
if (!fromStartUp) {
|
||||||
|
setApiKey(payload);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
})
|
.catch((error) => {
|
||||||
.catch((error) => {
|
console.error(
|
||||||
console.error("Failed to set API key:", error.message || "An error occurred");
|
"Failed to set API key:",
|
||||||
});
|
error.message || "An error occurred"
|
||||||
|
);
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
setIsValidApiKey(false);
|
setIsValidApiKey(false);
|
||||||
setUseLocalNode(false);
|
setUseLocalNode(false);
|
||||||
@ -213,24 +219,28 @@ export const NotAuthenticated = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
setCustomNodes(nodes);
|
setCustomNodes(nodes);
|
||||||
|
window.electronAPI.setAllowedDomains(nodes?.map((node)=> node.url))
|
||||||
|
|
||||||
setCustomNodeToSaveIndex(null);
|
setCustomNodeToSaveIndex(null);
|
||||||
if (!nodes) return;
|
if (!nodes) return;
|
||||||
window.sendMessage("setCustomNodes", nodes)
|
window
|
||||||
.then((response) => {
|
.sendMessage("setCustomNodes", nodes)
|
||||||
if (response) {
|
.then((response) => {
|
||||||
setMode("list");
|
if (response) {
|
||||||
setUrl("http://");
|
setMode("list");
|
||||||
setCustomApiKey("");
|
setUrl("http://");
|
||||||
// add alert if needed
|
setCustomApiKey("");
|
||||||
}
|
// add alert if needed
|
||||||
})
|
}
|
||||||
.catch((error) => {
|
})
|
||||||
console.error("Failed to set custom nodes:", error.message || "An error occurred");
|
.catch((error) => {
|
||||||
});
|
console.error(
|
||||||
|
"Failed to set custom nodes:",
|
||||||
|
error.message || "An error occurred"
|
||||||
|
);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Spacer height="35px" />
|
<Spacer height="35px" />
|
||||||
@ -296,16 +306,16 @@ export const NotAuthenticated = ({
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
<Spacer height="15px" />
|
<Spacer height="15px" />
|
||||||
|
|
||||||
<Typography
|
<Typography
|
||||||
sx={{
|
sx={{
|
||||||
fontSize: "12px",
|
fontSize: "12px",
|
||||||
visibility: !useLocalNode && 'hidden'
|
visibility: !useLocalNode && "hidden",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{"Using node: "} {currentNode?.url}
|
{"Using node: "} {currentNode?.url}
|
||||||
</Typography>
|
</Typography>
|
||||||
<>
|
<>
|
||||||
<Spacer height="15px" />
|
<Spacer height="15px" />
|
||||||
<Box
|
<Box
|
||||||
@ -344,28 +354,30 @@ export const NotAuthenticated = ({
|
|||||||
validateApiKey(currentNode);
|
validateApiKey(currentNode);
|
||||||
} else {
|
} else {
|
||||||
setCurrentNode({
|
setCurrentNode({
|
||||||
url: "http://127.0.0.1:12391",
|
url: "http://127.0.0.1:12391",
|
||||||
|
});
|
||||||
|
setUseLocalNode(false);
|
||||||
|
window
|
||||||
|
.sendMessage("setApiKey", null)
|
||||||
|
.then((response) => {
|
||||||
|
if (response) {
|
||||||
|
setApiKey(null);
|
||||||
|
handleSetGlobalApikey(null);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
setUseLocalNode(false)
|
.catch((error) => {
|
||||||
window.sendMessage("setApiKey", null)
|
console.error(
|
||||||
.then((response) => {
|
"Failed to set API key:",
|
||||||
if (response) {
|
error.message || "An error occurred"
|
||||||
setApiKey(null);
|
);
|
||||||
handleSetGlobalApikey(null);
|
});
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.error("Failed to set API key:", error.message || "An error occurred");
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}}
|
}}
|
||||||
disabled={false}
|
disabled={false}
|
||||||
defaultChecked
|
defaultChecked
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
label={`Use ${isLocal ? 'Local' : 'Custom'} Node`}
|
label={`Use ${isLocal ? "Local" : "Custom"} Node`}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
{currentNode?.url === "http://127.0.0.1:12391" && (
|
{currentNode?.url === "http://127.0.0.1:12391" && (
|
||||||
@ -379,31 +391,33 @@ export const NotAuthenticated = ({
|
|||||||
onChange={handleFileChangeApiKey} // File input handler
|
onChange={handleFileChangeApiKey} // File input handler
|
||||||
/>
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
<Typography sx={{
|
<Typography
|
||||||
fontSize: '12px',
|
sx={{
|
||||||
visibility: importedApiKey ? 'visible' : 'hidden'
|
fontSize: "12px",
|
||||||
}}>{`api key : ${importedApiKey}`}</Typography>
|
visibility: importedApiKey ? "visible" : "hidden",
|
||||||
|
}}
|
||||||
|
>{`api key : ${importedApiKey}`}</Typography>
|
||||||
|
|
||||||
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<Button
|
<Button
|
||||||
size="small"
|
size="small"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setShow(true);
|
setShow(true);
|
||||||
}}
|
}}
|
||||||
variant="contained"
|
variant="contained"
|
||||||
component="label"
|
component="label"
|
||||||
>
|
>
|
||||||
Choose custom node
|
Choose custom node
|
||||||
</Button>
|
</Button>
|
||||||
</>
|
</>
|
||||||
<Typography sx={{
|
<Typography
|
||||||
color: "white",
|
sx={{
|
||||||
fontSize: '12px'
|
color: "white",
|
||||||
}}>Build version: {manifestData?.version}</Typography>
|
fontSize: "12px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Build version: {manifestData?.version}
|
||||||
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
</>
|
</>
|
||||||
<CustomizedSnackbars
|
<CustomizedSnackbars
|
||||||
@ -430,7 +444,6 @@ export const NotAuthenticated = ({
|
|||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
||||||
{mode === "list" && (
|
{mode === "list" && (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
@ -472,17 +485,20 @@ export const NotAuthenticated = ({
|
|||||||
setMode("list");
|
setMode("list");
|
||||||
setShow(false);
|
setShow(false);
|
||||||
setUseLocalNode(false);
|
setUseLocalNode(false);
|
||||||
window.sendMessage("setApiKey", null)
|
window
|
||||||
.then((response) => {
|
.sendMessage("setApiKey", null)
|
||||||
if (response) {
|
.then((response) => {
|
||||||
setApiKey(null);
|
if (response) {
|
||||||
handleSetGlobalApikey(null);
|
setApiKey(null);
|
||||||
}
|
handleSetGlobalApikey(null);
|
||||||
})
|
}
|
||||||
.catch((error) => {
|
})
|
||||||
console.error("Failed to set API key:", error.message || "An error occurred");
|
.catch((error) => {
|
||||||
});
|
console.error(
|
||||||
|
"Failed to set API key:",
|
||||||
|
error.message || "An error occurred"
|
||||||
|
);
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
variant="contained"
|
variant="contained"
|
||||||
>
|
>
|
||||||
@ -527,18 +543,21 @@ export const NotAuthenticated = ({
|
|||||||
setMode("list");
|
setMode("list");
|
||||||
setShow(false);
|
setShow(false);
|
||||||
setIsValidApiKey(false);
|
setIsValidApiKey(false);
|
||||||
setUseLocalNode(false);
|
setUseLocalNode(false);
|
||||||
window.sendMessage("setApiKey", null)
|
window
|
||||||
.then((response) => {
|
.sendMessage("setApiKey", null)
|
||||||
if (response) {
|
.then((response) => {
|
||||||
setApiKey(null);
|
if (response) {
|
||||||
handleSetGlobalApikey(null);
|
setApiKey(null);
|
||||||
}
|
handleSetGlobalApikey(null);
|
||||||
})
|
}
|
||||||
.catch((error) => {
|
})
|
||||||
console.error("Failed to set API key:", error.message || "An error occurred");
|
.catch((error) => {
|
||||||
});
|
console.error(
|
||||||
|
"Failed to set API key:",
|
||||||
|
error.message || "An error occurred"
|
||||||
|
);
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
variant="contained"
|
variant="contained"
|
||||||
>
|
>
|
||||||
@ -563,7 +582,6 @@ export const NotAuthenticated = ({
|
|||||||
...(customNodes || []),
|
...(customNodes || []),
|
||||||
].filter((item) => item?.url !== node?.url);
|
].filter((item) => item?.url !== node?.url);
|
||||||
|
|
||||||
|
|
||||||
saveCustomNodes(nodesToSave);
|
saveCustomNodes(nodesToSave);
|
||||||
}}
|
}}
|
||||||
variant="contained"
|
variant="contained"
|
||||||
@ -601,9 +619,7 @@ export const NotAuthenticated = ({
|
|||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
{mode === "list" && (
|
{mode === "list" && (
|
||||||
|
Loading…
x
Reference in New Issue
Block a user