Handle Ombi API object-format requestedUser field
Build and Push Docker Image / build (push) Successful in 47s
Licence Check / Licence compatibility and copyright header verification (push) Failing after 1m24s
CI / Security audit (push) Successful in 1m47s
CI / Swagger Validation & Coverage (push) Successful in 2m11s
CI / Tests & coverage (push) Successful in 2m27s

The Ombi API returns requestedUser as an OmbiUser object instead of a string.
Add extractRequestedUser helper to extract username from various fields
(alias, userAlias, userName, normalizedUserName) with fallback to legacy string format.
Update client and server routes to use the helper for consistent username extraction.
This commit is contained in:
2026-05-21 21:56:36 +01:00
parent 26d9e429a9
commit 9862c0555c
6 changed files with 191 additions and 22 deletions
+3 -2
View File
@@ -13,6 +13,7 @@ const { buildUserDownloads } = require('../services/DownloadBuilder');
const { onHistoryUpdate, offHistoryUpdate } = require('../utils/historyFetcher');
const arrRetrieverRegistry = require('../utils/arrRetrievers');
const { getOmbiInstances } = require('../utils/config');
const { extractRequestedUser } = require('../utils/ombiHelpers');
// Track active SSE clients for disconnect cleanup
@@ -502,11 +503,11 @@ router.get('/stream', requireAuth, async (req, res) => {
if (!showAllOmbi && username) {
const usernameLower = username.toLowerCase();
filteredOmbiMovieRequests = filteredOmbiMovieRequests.filter(req => {
const requestedUser = req.requestedUser || req.userAlias || '';
const requestedUser = extractRequestedUser(req);
return requestedUser.toLowerCase() === usernameLower;
});
filteredOmbiTvRequests = filteredOmbiTvRequests.filter(req => {
const requestedUser = req.requestedUser || req.userAlias || '';
const requestedUser = extractRequestedUser(req);
return requestedUser.toLowerCase() === usernameLower;
});
}
+3 -2
View File
@@ -4,6 +4,7 @@ const { logToFile } = require('../utils/logger');
const cache = require('../utils/cache');
const { getOmbiInstances } = require('../utils/config');
const requireAuth = require('../middleware/requireAuth');
const { extractRequestedUser } = require('../utils/ombiHelpers');
const router = express.Router();
@@ -77,12 +78,12 @@ router.get('/requests', requireAuth, async (req, res) => {
const usernameLower = username.toLowerCase();
filteredMovieRequests = filteredMovieRequests.filter(req => {
const requestedUser = req.requestedUser || req.userAlias || '';
const requestedUser = extractRequestedUser(req);
return requestedUser.toLowerCase() === usernameLower;
});
filteredTvRequests = filteredTvRequests.filter(req => {
const requestedUser = req.requestedUser || req.userAlias || '';
const requestedUser = extractRequestedUser(req);
return requestedUser.toLowerCase() === usernameLower;
});
}
+5 -1
View File
@@ -6,6 +6,7 @@ const { getWebhookSecret, getSonarrInstances, getRadarrInstances, getOmbiInstanc
const cache = require('../utils/cache');
const arrRetrieverRegistry = require('../utils/arrRetrievers');
const { pollAllServices, POLL_INTERVAL, POLLING_ENABLED } = require('../utils/poller');
const { extractRequestedUser } = require('../utils/ombiHelpers');
const router = express.Router();
@@ -661,6 +662,9 @@ router.post('/ombi', webhookLimiter, (req, res) => {
// Ombi uses notificationType instead of eventType
const { notificationType, requestId, requestedUser, applicationUrl } = req.body;
const eventType = notificationType || req.body.eventType;
// Extract username from requestedUser (handles both object and string formats)
const username = extractRequestedUser(req.body);
if (!eventType || !OMBI_EVENTS.has(eventType)) {
logToFile(`[Webhook] Ombi payload rejected: invalid or missing notificationType`);
@@ -678,7 +682,7 @@ router.post('/ombi', webhookLimiter, (req, res) => {
}
try {
logToFile(`[Webhook] Ombi event received - Type: ${eventType}, RequestId: ${requestId}, User: ${requestedUser}`);
logToFile(`[Webhook] Ombi event received - Type: ${eventType}, RequestId: ${requestId}, User: ${username}`);
logToFile(`[Webhook] Ombi payload: ${JSON.stringify(req.body)}`);
// Update webhook metrics for polling optimization
+31
View File
@@ -0,0 +1,31 @@
/**
* Helper functions for extracting user information from Ombi API responses.
* The Ombi API returns requestedUser as an OmbiStore.Entities.OmbiUser object,
* not a string, so we need to extract the username from the object.
*/
/**
* Extracts the username from an Ombi request object.
* Handles both the OmbiUser object format and legacy string format.
*
* @param {Object} request - The Ombi request object
* @returns {string} The extracted username, or empty string if not found
*/
function extractRequestedUser(request) {
if (!request) return '';
// Handle object format: OmbiStore.Entities.OmbiUser
if (request.requestedUser && typeof request.requestedUser === 'object') {
// Priority: alias > userAlias > userName > normalizedUserName
return request.requestedUser.alias ||
request.requestedUser.userAlias ||
request.requestedUser.userName ||
request.requestedUser.normalizedUserName || '';
}
// Handle string format (fallback for compatibility)
return request.requestedUser || request.requestedByAlias || '';
}
module.exports = {
extractRequestedUser
};