mirror of
https://github.com/BreizhHardware/Jellystat.git
synced 2026-01-18 16:27:20 +01:00
auth setup fixes
This commit is contained in:
@@ -412,9 +412,6 @@ class JellyfinAPI {
|
||||
}
|
||||
|
||||
async validateSettings(url, apikey) {
|
||||
if (!this.configReady) {
|
||||
return [];
|
||||
}
|
||||
try {
|
||||
const response = await axios.get(url, {
|
||||
headers: {
|
||||
|
||||
@@ -897,26 +897,4 @@ router.post("/deletePlaybackActivity", async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
//Jellyfin related functions
|
||||
|
||||
router.post("/validateSettings", async (req, res) => {
|
||||
const { url, apikey } = req.body;
|
||||
|
||||
if (url === undefined || apikey === undefined) {
|
||||
res.status(400);
|
||||
res.send("URL or API Key not provided");
|
||||
return;
|
||||
}
|
||||
|
||||
var _url = url;
|
||||
_url = _url.replace(/\/web\/index\.html#!\/home\.html$/, "");
|
||||
if (!/^https?:\/\//i.test(url)) {
|
||||
_url = "http://" + url;
|
||||
}
|
||||
_url = _url.replace(/\/$/, "") + "/system/configuration";
|
||||
|
||||
const validation = await Jellyfin.validateSettings(_url, apikey);
|
||||
res.send(validation);
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
||||
@@ -83,4 +83,33 @@ router.post("/createuser", async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
router.post("/configSetup", async (req, res) => {
|
||||
try {
|
||||
const { JF_HOST, JF_API_KEY } = req.body;
|
||||
const config = await new configClass().getConfig();
|
||||
|
||||
if (JF_HOST === undefined && JF_API_KEY === undefined) {
|
||||
res.status(400);
|
||||
res.send("JF_HOST and JF_API_KEY are required for configuration");
|
||||
return;
|
||||
}
|
||||
|
||||
const { rows: getConfig } = await db.query('SELECT * FROM app_config where "ID"=1');
|
||||
|
||||
if (config.state != null && config.state < 2) {
|
||||
let query = 'UPDATE app_config SET "JF_HOST"=$1, "JF_API_KEY"=$2 where "ID"=1';
|
||||
if (getConfig.length === 0) {
|
||||
query = 'INSERT INTO app_config ("ID","JF_HOST","JF_API_KEY","APP_USER","APP_PASSWORD") VALUES (1,$1,$2,null,null)';
|
||||
}
|
||||
|
||||
const { rows } = await db.query(query, [JF_HOST, JF_API_KEY]);
|
||||
res.send(rows);
|
||||
} else {
|
||||
res.sendStatus(500);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
|
||||
const db = require("../db");
|
||||
const moment = require('moment');
|
||||
const taskstate = require('../logging/taskstate');
|
||||
const moment = require("moment");
|
||||
const taskstate = require("../logging/taskstate");
|
||||
|
||||
|
||||
const {jf_logging_columns,jf_logging_mapping,} = require("../models/jf_logging");
|
||||
const { jf_logging_columns, jf_logging_mapping } = require("../models/jf_logging");
|
||||
const express = require("express");
|
||||
const router = express.Router();
|
||||
|
||||
|
||||
// #swagger.tags = ['Logs']
|
||||
router.get("/getLogs", async (req, res) => {
|
||||
try {
|
||||
const { rows } = await db.query(`SELECT * FROM jf_logging order by "TimeRun" desc LIMIT 50 `);
|
||||
@@ -18,72 +15,54 @@ router.get("/getLogs", async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
async function insertLog(uuid,triggertype,taskType)
|
||||
{
|
||||
async function insertLog(uuid, triggertype, taskType) {
|
||||
try {
|
||||
let startTime = moment();
|
||||
const log=
|
||||
{
|
||||
"Id":uuid,
|
||||
"Name":taskType,
|
||||
"Type":"Task",
|
||||
"ExecutionType":triggertype,
|
||||
"Duration":0,
|
||||
"TimeRun":startTime,
|
||||
"Log":JSON.stringify([{}]),
|
||||
"Result":taskstate.RUNNING
|
||||
|
||||
const log = {
|
||||
Id: uuid,
|
||||
Name: taskType,
|
||||
Type: "Task",
|
||||
ExecutionType: triggertype,
|
||||
Duration: 0,
|
||||
TimeRun: startTime,
|
||||
Log: JSON.stringify([{}]),
|
||||
Result: taskstate.RUNNING,
|
||||
};
|
||||
|
||||
await db.insertBulk("jf_logging",log,jf_logging_columns);
|
||||
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return [];
|
||||
}
|
||||
|
||||
await db.insertBulk("jf_logging", log, jf_logging_columns);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
async function updateLog(uuid,data,taskstate)
|
||||
{
|
||||
async function updateLog(uuid, data, taskstate) {
|
||||
try {
|
||||
|
||||
const { rows:task } = await db.query(
|
||||
`SELECT "TimeRun" FROM jf_logging WHERE "Id" = '${uuid}';`
|
||||
);
|
||||
const { rows: task } = await db.query(`SELECT "TimeRun" FROM jf_logging WHERE "Id" = '${uuid}';`);
|
||||
|
||||
if (task.length === 0) {
|
||||
console.log("Unable to find task to update");
|
||||
}else{
|
||||
|
||||
} else {
|
||||
let endtime = moment();
|
||||
let startTime = moment(task[0].TimeRun);
|
||||
let duration = endtime.diff(startTime, 'seconds');
|
||||
const log=
|
||||
{
|
||||
"Id":uuid,
|
||||
"Name":"NULL Placeholder",
|
||||
"Type":"Task",
|
||||
"ExecutionType":"NULL Placeholder",
|
||||
"Duration":duration,
|
||||
"TimeRun":startTime,
|
||||
"Log":JSON.stringify(data),
|
||||
"Result":taskstate
|
||||
|
||||
let duration = endtime.diff(startTime, "seconds");
|
||||
const log = {
|
||||
Id: uuid,
|
||||
Name: "NULL Placeholder",
|
||||
Type: "Task",
|
||||
ExecutionType: "NULL Placeholder",
|
||||
Duration: duration,
|
||||
TimeRun: startTime,
|
||||
Log: JSON.stringify(data),
|
||||
Result: taskstate,
|
||||
};
|
||||
|
||||
await db.insertBulk("jf_logging",log,jf_logging_columns);
|
||||
}
|
||||
|
||||
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return [];
|
||||
}
|
||||
|
||||
await db.insertBulk("jf_logging", log, jf_logging_columns);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module.exports =
|
||||
{router,insertLog,updateLog};
|
||||
module.exports = { router, insertLog, updateLog };
|
||||
|
||||
@@ -163,4 +163,48 @@ router.get("/getRecentlyAdded", async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
//Jellyfin related functions
|
||||
|
||||
router.post("/validateSettings", async (req, res) => {
|
||||
const { url, apikey } = req.body;
|
||||
|
||||
if (url === undefined || apikey === undefined) {
|
||||
res.status(400);
|
||||
res.send("URL or API Key not provided");
|
||||
return;
|
||||
}
|
||||
|
||||
const urlRegex = new RegExp(
|
||||
"^((http|https):\\/\\/)?" + // optional protocol
|
||||
"((([a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])\\.)+" + // subdomain
|
||||
"([a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])" + // domain name
|
||||
"|([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}))" + // OR ip (v4) address
|
||||
"(\\:[0-9]+)?$", // port
|
||||
"i" // case-insensitive
|
||||
);
|
||||
|
||||
const isValidUrl = (string) => urlRegex.test(string);
|
||||
console.log(url, isValidUrl(url));
|
||||
if (!isValidUrl(url)) {
|
||||
res.status(400);
|
||||
|
||||
res.send({
|
||||
isValid: false,
|
||||
errorMessage: "Invalid URL",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
var _url = url;
|
||||
_url = _url.replace(/\/web\/index\.html#!\/home\.html$/, "");
|
||||
if (!/^https?:\/\//i.test(url)) {
|
||||
_url = "http://" + url;
|
||||
}
|
||||
_url = _url.replace(/\/$/, "") + "/system/configuration";
|
||||
|
||||
const validation = await Jellyfin.validateSettings(_url, apikey);
|
||||
|
||||
res.send(validation);
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
||||
@@ -19,10 +19,10 @@ const knexConfig = require("./migrations");
|
||||
const authRouter = require("./routes/auth");
|
||||
const apiRouter = require("./routes/api");
|
||||
const proxyRouter = require("./routes/proxy");
|
||||
const syncRouter = require("./routes/sync");
|
||||
const { router: syncRouter } = require("./routes/sync");
|
||||
const statsRouter = require("./routes/stats");
|
||||
const backupRouter = require("./routes/backup");
|
||||
const logRouter = require("./routes/logging");
|
||||
const { router: backupRouter } = require("./routes/backup");
|
||||
const { router: logRouter } = require("./routes/logging");
|
||||
const utilsRouter = require("./routes/utils");
|
||||
|
||||
// tasks
|
||||
@@ -61,16 +61,16 @@ app.use("/proxy", proxyRouter, () => {
|
||||
app.use("/api", authenticate, apiRouter, () => {
|
||||
/* #swagger.tags = ['API']*/
|
||||
}); // mount the API router at /api, with JWT middleware
|
||||
app.use("/sync", authenticate, syncRouter.router, () => {
|
||||
app.use("/sync", authenticate, syncRouter, () => {
|
||||
/* #swagger.tags = ['Sync']*/
|
||||
}); // mount the API router at /sync, with JWT middleware
|
||||
app.use("/stats", authenticate, statsRouter, () => {
|
||||
/* #swagger.tags = ['Stats']*/
|
||||
}); // mount the API router at /stats, with JWT middleware
|
||||
app.use("/backup", authenticate, backupRouter.router, () => {
|
||||
app.use("/backup", authenticate, backupRouter, () => {
|
||||
/* #swagger.tags = ['Backup']*/
|
||||
}); // mount the API router at /backup, with JWT middleware
|
||||
app.use("/logs", authenticate, logRouter.router, () => {
|
||||
app.use("/logs", authenticate, logRouter, () => {
|
||||
/* #swagger.tags = ['Logs']*/
|
||||
}); // mount the API router at /logs, with JWT middleware
|
||||
app.use("/utils", authenticate, utilsRouter, () => {
|
||||
|
||||
@@ -1,55 +1,58 @@
|
||||
const swaggerAutogen = require('swagger-autogen')();
|
||||
const swaggerAutogen = require("swagger-autogen")();
|
||||
|
||||
const outputFile = './swagger.json';
|
||||
const endpointsFiles = ['./server.js'];
|
||||
const outputFile = "./swagger.json";
|
||||
const endpointsFiles = ["./server.js"];
|
||||
const config = {
|
||||
info: {
|
||||
title: 'Jellystat API Documentation',
|
||||
description: '',
|
||||
info: {
|
||||
title: "Jellystat API Documentation",
|
||||
description: "",
|
||||
},
|
||||
tags: [
|
||||
{
|
||||
name: "API",
|
||||
description: "Jellystat API Endpoints",
|
||||
},
|
||||
tags: [
|
||||
{
|
||||
name: 'API',
|
||||
description: 'Jellystat API Endpoints',
|
||||
},
|
||||
{
|
||||
name: 'Auth',
|
||||
description: 'Jellystat Auth Endpoints',
|
||||
},
|
||||
{
|
||||
name: 'Proxy',
|
||||
description: 'Jellyfin Proxied Endpoints',
|
||||
},
|
||||
{
|
||||
name: 'Stats',
|
||||
description: 'Jellystat Statisitc Endpoints',
|
||||
},
|
||||
{
|
||||
name: 'Backup',
|
||||
description: 'Jellystat Backup/Restore Endpoints',
|
||||
},
|
||||
{
|
||||
name: 'Logs',
|
||||
description: 'Jellystat Log Endpoints',
|
||||
},
|
||||
],
|
||||
host: '',
|
||||
schemes: ['http', 'https'],
|
||||
securityDefinitions: {
|
||||
apiKey: {
|
||||
type: 'apiKey',
|
||||
name: 'x-api-token',
|
||||
in: 'header',
|
||||
},
|
||||
{
|
||||
name: "Auth",
|
||||
description: "Jellystat Auth Endpoints",
|
||||
},
|
||||
security: [
|
||||
{
|
||||
apiKey: [],
|
||||
},
|
||||
],
|
||||
{
|
||||
name: "Proxy",
|
||||
description: "Jellyfin Proxied Endpoints",
|
||||
},
|
||||
{
|
||||
name: "Stats",
|
||||
description: "Jellystat Statisitc Endpoints",
|
||||
},
|
||||
{
|
||||
name: "Sync",
|
||||
description: "Jellystat Sync Endpoints",
|
||||
},
|
||||
{
|
||||
name: "Backup",
|
||||
description: "Jellystat Backup/Restore Endpoints",
|
||||
},
|
||||
{
|
||||
name: "Logs",
|
||||
description: "Jellystat Log Endpoints",
|
||||
},
|
||||
],
|
||||
host: "",
|
||||
schemes: ["http", "https"],
|
||||
securityDefinitions: {
|
||||
apiKey: {
|
||||
type: "apiKey",
|
||||
name: "x-api-token",
|
||||
in: "header",
|
||||
},
|
||||
},
|
||||
security: [
|
||||
{
|
||||
apiKey: [],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
module.exports = config;
|
||||
|
||||
|
||||
swaggerAutogen(outputFile, endpointsFiles, config);
|
||||
|
||||
@@ -24,6 +24,10 @@
|
||||
"name": "Stats",
|
||||
"description": "Jellystat Statisitc Endpoints"
|
||||
},
|
||||
{
|
||||
"name": "Sync",
|
||||
"description": "Jellystat Sync Endpoints"
|
||||
},
|
||||
{
|
||||
"name": "Backup",
|
||||
"description": "Jellystat Backup/Restore Endpoints"
|
||||
@@ -90,6 +94,9 @@
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -130,6 +137,42 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/auth/configSetup": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"Auth"
|
||||
],
|
||||
"description": "",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"JF_HOST": {
|
||||
"example": "any"
|
||||
},
|
||||
"JF_API_KEY": {
|
||||
"example": "any"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request"
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/proxy/web/assets/img/devices/": {
|
||||
"get": {
|
||||
"tags": [
|
||||
@@ -312,6 +355,39 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/proxy/validateSettings": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"Proxy"
|
||||
],
|
||||
"description": "",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"url": {
|
||||
"example": "any"
|
||||
},
|
||||
"apikey": {
|
||||
"example": "any"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/getconfig": {
|
||||
"get": {
|
||||
"tags": [
|
||||
@@ -1874,7 +1950,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/validateSettings": {
|
||||
"/api/deletePlaybackActivity": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"API"
|
||||
@@ -1902,10 +1978,7 @@
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"url": {
|
||||
"example": "any"
|
||||
},
|
||||
"apikey": {
|
||||
"ids": {
|
||||
"example": "any"
|
||||
}
|
||||
}
|
||||
@@ -1927,6 +2000,9 @@
|
||||
},
|
||||
"404": {
|
||||
"description": "Not Found"
|
||||
},
|
||||
"503": {
|
||||
"description": "Service Unavailable"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,21 +38,18 @@ function Setup() {
|
||||
}
|
||||
|
||||
async function validateSettings(_url, _apikey) {
|
||||
const result = await axios.post(
|
||||
"/api/validateSettings",
|
||||
{
|
||||
const result = await axios
|
||||
.post("/proxy/validateSettings", {
|
||||
url: _url,
|
||||
apikey: _apikey,
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
}
|
||||
);
|
||||
})
|
||||
.catch((error) => {
|
||||
return error.response;
|
||||
});
|
||||
|
||||
let data = result.data;
|
||||
console.log(result);
|
||||
console.log(data);
|
||||
return { isValid: data.isValid, errorMessage: data.errorMessage };
|
||||
}
|
||||
|
||||
@@ -70,12 +67,7 @@ function Setup() {
|
||||
|
||||
// Send a POST request to /api/setconfig/ with the updated configuration
|
||||
axios
|
||||
.post("/api/setconfig/", formValues, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${config.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
})
|
||||
.post("/auth/configSetup/", formValues)
|
||||
.then(async () => {
|
||||
setsubmitButtonText(i18next.t("SETTINGS_SAVED"));
|
||||
setProcessing(false);
|
||||
|
||||
Reference in New Issue
Block a user