Hide downloads module sensitive data

Working thowards #259
This commit is contained in:
ajnart
2022-07-22 17:18:33 +02:00
parent a4defd330c
commit 81a7789f9c
5 changed files with 93 additions and 46 deletions

View File

@@ -15,6 +15,7 @@ import { useEffect, useState } from 'react';
import axios from 'axios'; import axios from 'axios';
import { NormalizedTorrent } from '@ctrl/shared-torrent'; import { NormalizedTorrent } from '@ctrl/shared-torrent';
import { useViewportSize } from '@mantine/hooks'; import { useViewportSize } from '@mantine/hooks';
import { showNotification } from '@mantine/notifications';
import { IModule } from '../modules'; import { IModule } from '../modules';
import { useConfig } from '../../../tools/state'; import { useConfig } from '../../../tools/state';
import { AddItemShelfButton } from '../../AppShelf/AddAppShelfItem'; import { AddItemShelfButton } from '../../AppShelf/AddAppShelfItem';
@@ -52,11 +53,27 @@ export default function DownloadComponent() {
useEffect(() => { useEffect(() => {
setIsLoading(true); setIsLoading(true);
if (downloadServices.length === 0) return; if (downloadServices.length === 0) return;
setSafeInterval(() => { const interval = setSafeInterval(() => {
// Send one request with each download service inside // Send one request with each download service inside
axios.post('/api/modules/downloads', { config }).then((response) => { axios
.post('/api/modules/downloads')
.then((response) => {
setTorrents(response.data); setTorrents(response.data);
setIsLoading(false); setIsLoading(false);
})
.catch((error) => {
setTorrents([]);
// eslint-disable-next-line no-console
console.error('Error while fetching torrents', error.response.data);
setIsLoading(false);
clearInterval(interval);
showNotification({
title: 'Error fetching torrents',
autoClose: false,
color: 'red',
message:
'Please check your config for any potential errors, check the console for more info',
});
}); });
}, 5000); }, 5000);
}, []); }, []);

View File

@@ -6,6 +6,7 @@ import { NormalizedTorrent } from '@ctrl/shared-torrent';
import { linearGradientDef } from '@nivo/core'; import { linearGradientDef } from '@nivo/core';
import { Datum, ResponsiveLine } from '@nivo/line'; import { Datum, ResponsiveLine } from '@nivo/line';
import { useListState } from '@mantine/hooks'; import { useListState } from '@mantine/hooks';
import { showNotification } from '@mantine/notifications';
import { AddItemShelfButton } from '../../AppShelf/AddAppShelfItem'; import { AddItemShelfButton } from '../../AppShelf/AddAppShelfItem';
import { useConfig } from '../../../tools/state'; import { useConfig } from '../../../tools/state';
import { humanFileSize } from '../../../tools/humanFileSize'; import { humanFileSize } from '../../../tools/humanFileSize';
@@ -43,9 +44,24 @@ export default function TotalDownloadsComponent() {
const totalUploadSpeed = torrents.reduce((acc, torrent) => acc + torrent.uploadSpeed, 0); const totalUploadSpeed = torrents.reduce((acc, torrent) => acc + torrent.uploadSpeed, 0);
useEffect(() => { useEffect(() => {
if (downloadServices.length === 0) return; if (downloadServices.length === 0) return;
setSafeInterval(() => { const interval = setSafeInterval(() => {
axios.post('/api/modules/downloads', { config }).then((response) => { axios
.post('/api/modules/downloads')
.then((response) => {
setTorrents(response.data); setTorrents(response.data);
})
.catch((error) => {
setTorrents([]);
// eslint-disable-next-line no-console
console.error('Error while fetching torrents', error.response.data);
clearInterval(interval);
showNotification({
title: 'Error fetching torrents',
autoClose: false,
color: 'red',
message:
'Please check your config for any potential errors, check the console for more info',
});
}); });
}, 1000); }, 1000);
}, [config.services]); }, [config.services]);

View File

@@ -1,11 +1,14 @@
// This interface is to be used in all the modules of the project // This interface is to be used in all the modules of the project
// Each module should have its own interface and call the following function: // Each module should have its own interface and call the following function:
// TODO: Add a function to register a module // TODO: Add a function to register a module
import { TablerIcon } from '@tabler/icons';
// Note: Maybe use context to keep track of the modules // Note: Maybe use context to keep track of the modules
export interface IModule { export interface IModule {
title: string; title: string;
description: string; description: string;
icon: React.ReactNode; icon: TablerIcon;
component: React.ComponentType; component: React.ComponentType;
options?: Option; options?: Option;
} }

View File

@@ -2,12 +2,15 @@ import { Deluge } from '@ctrl/deluge';
import { QBittorrent } from '@ctrl/qbittorrent'; import { QBittorrent } from '@ctrl/qbittorrent';
import { NormalizedTorrent } from '@ctrl/shared-torrent'; import { NormalizedTorrent } from '@ctrl/shared-torrent';
import { Transmission } from '@ctrl/transmission'; import { Transmission } from '@ctrl/transmission';
import { getCookie } from 'cookies-next';
import { NextApiRequest, NextApiResponse } from 'next'; import { NextApiRequest, NextApiResponse } from 'next';
import { getConfig } from '../../../tools/getConfig';
import { Config } from '../../../tools/types'; import { Config } from '../../../tools/types';
async function Post(req: NextApiRequest, res: NextApiResponse) { async function Post(req: NextApiRequest, res: NextApiResponse) {
// Get the type of service from the request url // Get the type of service from the request url
const { config }: { config: Config } = req.body; const configName = getCookie('config-name', { req });
const { config }: { config: Config } = getConfig(configName?.toString() ?? 'default').props;
const qBittorrentServices = config.services.filter((service) => service.type === 'qBittorrent'); const qBittorrentServices = config.services.filter((service) => service.type === 'qBittorrent');
const delugeServices = config.services.filter((service) => service.type === 'Deluge'); const delugeServices = config.services.filter((service) => service.type === 'Deluge');
const transmissionServices = config.services.filter((service) => service.type === 'Transmission'); const transmissionServices = config.services.filter((service) => service.type === 'Transmission');
@@ -20,6 +23,7 @@ async function Post(req: NextApiRequest, res: NextApiResponse) {
message: 'Missing services', message: 'Missing services',
}); });
} }
try {
await Promise.all( await Promise.all(
qBittorrentServices.map((service) => qBittorrentServices.map((service) =>
new QBittorrent({ new QBittorrent({
@@ -53,7 +57,10 @@ async function Post(req: NextApiRequest, res: NextApiResponse) {
.then((e) => torrents.push(...e.torrents)) .then((e) => torrents.push(...e.torrents))
) )
); );
res.status(200).json(torrents); } catch (e: any) {
return res.status(401).json(e);
}
return res.status(200).json(torrents);
} }
export default async (req: NextApiRequest, res: NextApiResponse) => { export default async (req: NextApiRequest, res: NextApiResponse) => {

View File

@@ -14,7 +14,11 @@ export function getConfig(name: string) {
settings: { settings: {
searchUrl: 'https://www.google.com/search?q=', searchUrl: 'https://www.google.com/search?q=',
}, },
modules: {}, modules: {
'Search Bar': {
enabled: true,
},
},
}, },
}, },
}; };