Added validation for Genres by Whitlisting Genre titles

Changed sort order on those endpoints to order genres alphabetically
fixed auth bug
Update api docs
This commit is contained in:
CyferShepard
2025-03-31 09:41:40 +02:00
parent 25b8627088
commit ccc8469716
4 changed files with 231 additions and 1 deletions

View File

@@ -50,9 +50,65 @@ const jf_library_items_mapping = (item) => ({
? item.ImageBlurHashes.Primary[item.ImageTags["Primary"]]
: null,
archived: false,
Genres: item.Genres && Array.isArray(item.Genres) ? JSON.stringify(item.Genres) : [],
Genres: item.Genres && Array.isArray(item.Genres) ? JSON.stringify(filterInvalidGenres(item.Genres.map(titleCase))) : [],
});
// Utility function to title-case a string
function titleCase(str) {
return str
.toLowerCase()
.split(" ")
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
.join(" ");
}
function filterInvalidGenres(genres) {
const validGenres = [
"Action",
"Adventure",
"Animated",
"Biography",
"Comedy",
"Crime",
"Dance",
"Disaster",
"Documentary",
"Drama",
"Erotic",
"Family",
"Fantasy",
"Found Footage",
"Historical",
"Horror",
"Independent",
"Legal",
"Live Action",
"Martial Arts",
"Musical",
"Mystery",
"Noir",
"Performance",
"Political",
"Romance",
"Satire",
"Science Fiction",
"Short",
"Silent",
"Slasher",
"Sports",
"Spy",
"Superhero",
"Supernatural",
"Suspense",
"Teen",
"Thriller",
"War",
"Western",
];
return genres.filter((genre) => validGenres.map((g) => g.toLowerCase()).includes(genre.toLowerCase()));
}
module.exports = {
jf_library_items_columns,
jf_library_items_mapping,

View File

@@ -20,6 +20,11 @@ router.post("/login", async (req, res) => {
try {
const { username, password } = req.body;
if (!username || !password || password === CryptoJS.SHA3("").toString()) {
res.sendStatus(401);
return;
}
const query = 'SELECT * FROM app_config WHERE ("APP_USER" = $1 AND "APP_PASSWORD" = $2) OR "REQUIRE_LOGIN" = false';
const values = [username, password];
const { rows: login } = await db.query(query, values);

View File

@@ -559,6 +559,7 @@ router.get("/getGenreUserStats", async (req, res) => {
where: [[{ column: "a.UserId", operator: "=", value: `$${values.length + 1}` }]],
group_by: [`COALESCE(g.genre, 'No Genre')`],
order_by: "genre",
sort_order: "asc",
pageNumber: page,
pageSize: size,
};
@@ -622,6 +623,7 @@ router.get("/getGenreLibraryStats", async (req, res) => {
where: [[{ column: "a.ParentId", operator: "=", value: `$${values.length + 1}` }]],
group_by: [`COALESCE(g.genre, 'No Genre')`],
order_by: "genre",
sort_order: "asc",
pageNumber: page,
pageSize: size,
};

View File

@@ -2474,6 +2474,53 @@
}
}
},
"/api/stopTask": {
"get": {
"tags": [
"API"
],
"description": "",
"parameters": [
{
"name": "authorization",
"in": "header",
"type": "string"
},
{
"name": "x-api-token",
"in": "header",
"type": "string"
},
{
"name": "req",
"in": "query",
"type": "string"
},
{
"name": "task",
"in": "query",
"type": "string"
}
],
"responses": {
"200": {
"description": "OK"
},
"400": {
"description": "Bad Request"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Not Found"
}
}
}
},
"/stats/getLibraryOverview": {
"get": {
"tags": [
@@ -3618,6 +3665,126 @@
}
}
},
"/stats/getGenreUserStats": {
"get": {
"tags": [
"Stats"
],
"description": "",
"parameters": [
{
"name": "authorization",
"in": "header",
"type": "string"
},
{
"name": "x-api-token",
"in": "header",
"type": "string"
},
{
"name": "req",
"in": "query",
"type": "string"
},
{
"name": "size",
"in": "query",
"type": "string"
},
{
"name": "page",
"in": "query",
"type": "string"
},
{
"name": "userid",
"in": "query",
"type": "string"
}
],
"responses": {
"200": {
"description": "OK"
},
"400": {
"description": "Bad Request"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Not Found"
},
"503": {
"description": "Service Unavailable"
}
}
}
},
"/stats/getGenreLibraryStats": {
"get": {
"tags": [
"Stats"
],
"description": "",
"parameters": [
{
"name": "authorization",
"in": "header",
"type": "string"
},
{
"name": "x-api-token",
"in": "header",
"type": "string"
},
{
"name": "req",
"in": "query",
"type": "string"
},
{
"name": "size",
"in": "query",
"type": "string"
},
{
"name": "page",
"in": "query",
"type": "string"
},
{
"name": "libraryid",
"in": "query",
"type": "string"
}
],
"responses": {
"200": {
"description": "OK"
},
"400": {
"description": "Bad Request"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Not Found"
},
"503": {
"description": "Service Unavailable"
}
}
}
},
"/backup/beginBackup": {
"get": {
"tags": [