mirror of
				https://github.com/karl0ss/homepage.git
				synced 2025-11-04 08:20:58 +00:00 
			
		
		
		
	Cache Pyload widget login sessionId, refactor
This commit is contained in:
		
							parent
							
								
									bbacf4e671
								
							
						
					
					
						commit
						8b2b8d7b35
					
				@ -7,15 +7,23 @@ import useWidgetAPI from "utils/proxy/use-widget-api";
 | 
				
			|||||||
export default function Component({ service }) {
 | 
					export default function Component({ service }) {
 | 
				
			||||||
  const { t } = useTranslation();
 | 
					  const { t } = useTranslation();
 | 
				
			||||||
  const { widget } = service;
 | 
					  const { widget } = service;
 | 
				
			||||||
  const { data: pyloadData, error: pyloadError } = useWidgetAPI(
 | 
					  const { data: pyloadData, error: pyloadError } = useWidgetAPI(widget, "status");
 | 
				
			||||||
    widget,
 | 
					 | 
				
			||||||
    "statusServer",
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (pyloadError || !pyloadData) {
 | 
					  if (pyloadError || pyloadData?.error) {
 | 
				
			||||||
    return <Container error={t("widget.api_error")} />;
 | 
					    return <Container error={t("widget.api_error")} />;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!pyloadData) {
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					      <Container service={service}>
 | 
				
			||||||
 | 
					        <Block label="pyload.speed" />
 | 
				
			||||||
 | 
					        <Block label="pyload.active" />
 | 
				
			||||||
 | 
					        <Block label="pyload.queue" />
 | 
				
			||||||
 | 
					        <Block label="pyload.total" />
 | 
				
			||||||
 | 
					      </Container>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <Container service={service}>
 | 
					    <Container service={service}>
 | 
				
			||||||
      <Block label="pyload.speed" value={t("common.bitrate", { value: pyloadData.speed })} />
 | 
					      <Block label="pyload.speed" value={t("common.bitrate", { value: pyloadData.speed })} />
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,36 @@
 | 
				
			|||||||
 | 
					import cache from "memory-cache";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import getServiceWidget from "utils/config/service-helpers";
 | 
					import getServiceWidget from "utils/config/service-helpers";
 | 
				
			||||||
import { formatApiCall } from "utils/proxy/api-helpers";
 | 
					import { formatApiCall } from "utils/proxy/api-helpers";
 | 
				
			||||||
import widgets from "widgets/widgets";
 | 
					import widgets from "widgets/widgets";
 | 
				
			||||||
 | 
					import createLogger from "utils/logger";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const proxyName = 'pyloadProxyHandler';
 | 
				
			||||||
 | 
					const logger = createLogger(proxyName);
 | 
				
			||||||
 | 
					const sessionCacheKey = `${proxyName}__sessionId`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async function fetchFromPyloadAPI(url, sessionId, params) {
 | 
				
			||||||
 | 
					  const options = {
 | 
				
			||||||
 | 
					    method: "POST",
 | 
				
			||||||
 | 
					    headers: {
 | 
				
			||||||
 | 
					      "Content-Type": "application/x-www-form-urlencoded",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (params) {
 | 
				
			||||||
 | 
					    options.body = Object.keys(params).map(k => `${k}=${params[k]}`).join('&');
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    options.body = `session=${sessionId}`
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  return fetch(url, options).then((response) => response.json());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async function login(loginUrl, username, password) {
 | 
				
			||||||
 | 
					  const sessionId = await fetchFromPyloadAPI(loginUrl, null, { username, password })
 | 
				
			||||||
 | 
					  cache.put(sessionCacheKey, sessionId);
 | 
				
			||||||
 | 
					  return sessionId;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default async function pyloadProxyHandler(req, res) {
 | 
					export default async function pyloadProxyHandler(req, res) {
 | 
				
			||||||
  const { group, service, endpoint } = req.query;
 | 
					  const { group, service, endpoint } = req.query;
 | 
				
			||||||
@ -12,23 +42,25 @@ export default async function pyloadProxyHandler(req, res) {
 | 
				
			|||||||
      const url = new URL(formatApiCall(widgets[widget.type].api, { endpoint, ...widget }));
 | 
					      const url = new URL(formatApiCall(widgets[widget.type].api, { endpoint, ...widget }));
 | 
				
			||||||
      const loginUrl = `${widget.url}/api/login`;
 | 
					      const loginUrl = `${widget.url}/api/login`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // Pyload api does not support argument passing as JSON.
 | 
					      let sessionId = cache.get(sessionCacheKey);
 | 
				
			||||||
      const sessionId = await fetch(loginUrl, {
 | 
					 | 
				
			||||||
        method: "POST",
 | 
					 | 
				
			||||||
        // Empty passwords are supported.
 | 
					 | 
				
			||||||
        body: `username=${widget.username}&password=${widget.password ?? ''}`,
 | 
					 | 
				
			||||||
        headers: {
 | 
					 | 
				
			||||||
          "Content-Type": "application/x-www-form-urlencoded",
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
      }).then((response) => response.json());
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      const apiResponse = await fetch(url, {
 | 
					      if (!sessionId) {
 | 
				
			||||||
        method: "POST",
 | 
					        sessionId = await login(loginUrl, widget.username, widget.password);
 | 
				
			||||||
        body: `session=${sessionId}`,
 | 
					      }
 | 
				
			||||||
        headers: {
 | 
					
 | 
				
			||||||
          "Content-Type": "application/x-www-form-urlencoded",
 | 
					      let apiResponse = await fetchFromPyloadAPI(url, sessionId);
 | 
				
			||||||
        },
 | 
					
 | 
				
			||||||
      }).then((response) => response.json());
 | 
					      if (apiResponse?.error === 'Forbidden') {
 | 
				
			||||||
 | 
					        logger.debug("Failed to retrieve data from Pyload API, login and re-try");
 | 
				
			||||||
 | 
					        cache.del(sessionCacheKey);
 | 
				
			||||||
 | 
					        sessionId = await login(loginUrl, widget.username, widget.password);
 | 
				
			||||||
 | 
					        apiResponse = await fetchFromPyloadAPI(url, sessionId);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      if (apiResponse?.error) {
 | 
				
			||||||
 | 
					        return res.status(500).send(apiResponse);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      cache.del(sessionCacheKey);
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      return res.send(apiResponse);
 | 
					      return res.send(apiResponse);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -3,6 +3,12 @@ import pyloadProxyHandler from "./proxy";
 | 
				
			|||||||
const widget = {
 | 
					const widget = {
 | 
				
			||||||
  api: "{url}/api/{endpoint}",
 | 
					  api: "{url}/api/{endpoint}",
 | 
				
			||||||
  proxyHandler: pyloadProxyHandler,
 | 
					  proxyHandler: pyloadProxyHandler,
 | 
				
			||||||
};
 | 
					
 | 
				
			||||||
 | 
					  mappings: {
 | 
				
			||||||
 | 
					    "status": {
 | 
				
			||||||
 | 
					      endpoint: "statusServer",
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default widget;
 | 
					export default widget;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user