All checks were successful
farmcontrol/farmcontrol-api/pipeline/head This commit looks good
This commit introduces the `syncWebhooks` function to streamline the process of synchronizing webhook configurations for marketplaces. It enhances the existing `ensureWebhookSubscriptions` function to utilize `syncWebhooks`, ensuring that webhook URLs and verification tokens are correctly set and updated. Additionally, a new module for managing webhook configurations is added, which includes utility functions for building webhook URLs and generating verification tokens. Tests are also included to validate the new functionality and its integration with existing systems, improving the overall reliability of webhook management.
294 lines
7.3 KiB
JavaScript
294 lines
7.3 KiB
JavaScript
import express from 'express';
|
|
import { isAuthenticated } from '../../keycloak.js';
|
|
import { checkPermissions, hasPermission } from '../../database/permissions.js';
|
|
import { getFilter, convertPropertiesString, getSort } from '../../utils.js';
|
|
|
|
const router = express.Router();
|
|
|
|
const listAllowedFilters = [
|
|
'name',
|
|
'provider',
|
|
'active',
|
|
'connected',
|
|
'state.type',
|
|
'createdAt',
|
|
'updatedAt',
|
|
'state',
|
|
'_reference',
|
|
];
|
|
const listAllowedSorters = [
|
|
'name',
|
|
'provider',
|
|
'active',
|
|
'connected',
|
|
'state',
|
|
'createdAt',
|
|
'updatedAt',
|
|
'_id',
|
|
];
|
|
const propertiesAllowedFilters = [
|
|
'name',
|
|
'provider',
|
|
'active',
|
|
'connected',
|
|
'state.type',
|
|
'createdAt',
|
|
'updatedAt',
|
|
];
|
|
import {
|
|
listMarketplacesRouteHandler,
|
|
getMarketplaceRouteHandler,
|
|
editMarketplaceRouteHandler,
|
|
newMarketplaceRouteHandler,
|
|
deleteMarketplaceRouteHandler,
|
|
listMarketplacesByPropertiesRouteHandler,
|
|
getMarketplaceStatsRouteHandler,
|
|
getMarketplaceHistoryRouteHandler,
|
|
getMarketplaceAuthUrlRouteHandler,
|
|
exchangeMarketplaceAuthCodeRouteHandler,
|
|
refreshMarketplaceAuthRouteHandler,
|
|
syncMarketplaceRouteHandler,
|
|
syncMarketplaceItemsRouteHandler,
|
|
syncMarketplaceOrdersRouteHandler,
|
|
syncMarketplaceFulfillmentPoliciesRouteHandler,
|
|
syncMarketplacePaymentPoliciesRouteHandler,
|
|
syncMarketplaceReturnPoliciesRouteHandler,
|
|
syncMarketplaceTaxRatesRouteHandler,
|
|
syncMarketplaceWebhooksRouteHandler,
|
|
marketplaceWebhookRouteHandler,
|
|
marketplaceWebhookChallengeRouteHandler,
|
|
subscribeMarketplaceWebhooksRouteHandler,
|
|
debugEbayRouteHandler,
|
|
searchMarketplacesRouteHandler,
|
|
getMarketplacePropertyValuesRouteHandler,
|
|
getMarketplaceNeighborsRouteHandler,
|
|
} from '../../services/sales/marketplaces.js';
|
|
|
|
router.get('/', isAuthenticated, checkPermissions('marketplace', 'list'), async (req, res) => {
|
|
const { page, limit, property, search, sortProperty, sortOrder } = req.query;
|
|
const filter = await getFilter(req.query, listAllowedFilters);
|
|
listMarketplacesRouteHandler(
|
|
req,
|
|
res,
|
|
page,
|
|
limit,
|
|
property,
|
|
filter,
|
|
search,
|
|
getSort(sortProperty, listAllowedSorters),
|
|
sortOrder
|
|
);
|
|
});
|
|
|
|
router.get(
|
|
'/properties',
|
|
checkPermissions('marketplace', 'list'),
|
|
isAuthenticated,
|
|
async (req, res) => {
|
|
let properties = convertPropertiesString(req.query.properties);
|
|
const filter = await getFilter(req.query, propertiesAllowedFilters, false);
|
|
var masterFilter = {};
|
|
if (req.query.masterFilter) {
|
|
masterFilter = JSON.parse(req.query.masterFilter);
|
|
}
|
|
listMarketplacesByPropertiesRouteHandler(req, res, properties, filter, masterFilter);
|
|
}
|
|
);
|
|
|
|
router.get(
|
|
'/values',
|
|
checkPermissions('marketplace', 'list'),
|
|
isAuthenticated,
|
|
async (req, res) => {
|
|
const { property } = req.query;
|
|
getMarketplacePropertyValuesRouteHandler(req, res, property);
|
|
}
|
|
);
|
|
router.get(
|
|
'/search',
|
|
checkPermissions('marketplace', 'list'),
|
|
isAuthenticated,
|
|
async (req, res) => {
|
|
const { search } = req.query;
|
|
searchMarketplacesRouteHandler(req, res, search);
|
|
}
|
|
);
|
|
|
|
router.post('/', isAuthenticated, checkPermissions('marketplace', 'new'), async (req, res) => {
|
|
newMarketplaceRouteHandler(req, res);
|
|
});
|
|
|
|
router.get('/stats', isAuthenticated, async (req, res) => {
|
|
getMarketplaceStatsRouteHandler(req, res);
|
|
});
|
|
|
|
router.get('/history', isAuthenticated, async (req, res) => {
|
|
getMarketplaceHistoryRouteHandler(req, res);
|
|
});
|
|
|
|
router.get('/:id/auth/url', isAuthenticated, async (req, res) => {
|
|
getMarketplaceAuthUrlRouteHandler(req, res);
|
|
});
|
|
|
|
router.post(
|
|
'/:id/auth/exchange',
|
|
isAuthenticated,
|
|
async (req, res, next) => {
|
|
try {
|
|
const allowed =
|
|
(await hasPermission(req.user, 'marketplace', 'connect')) ||
|
|
(await hasPermission(req.user, 'marketplace', 'reconnect'));
|
|
if (!allowed) {
|
|
return res.status(403).json({ error: 'Forbidden', code: 'FORBIDDEN' });
|
|
}
|
|
return next();
|
|
} catch (err) {
|
|
return next(err);
|
|
}
|
|
},
|
|
async (req, res) => {
|
|
exchangeMarketplaceAuthCodeRouteHandler(req, res);
|
|
}
|
|
);
|
|
|
|
router.post(
|
|
'/:id/auth/refresh',
|
|
isAuthenticated,
|
|
checkPermissions('marketplace', 'refreshToken'),
|
|
async (req, res) => {
|
|
refreshMarketplaceAuthRouteHandler(req, res);
|
|
}
|
|
);
|
|
|
|
router.post(
|
|
'/:id/sync',
|
|
isAuthenticated,
|
|
checkPermissions('marketplace', 'sync'),
|
|
async (req, res) => {
|
|
syncMarketplaceRouteHandler(req, res);
|
|
}
|
|
);
|
|
|
|
router.post(
|
|
'/:id/sync/fulfillmentPolicies',
|
|
isAuthenticated,
|
|
checkPermissions('marketplace', 'sync'),
|
|
async (req, res) => {
|
|
syncMarketplaceFulfillmentPoliciesRouteHandler(req, res);
|
|
}
|
|
);
|
|
|
|
router.post(
|
|
'/:id/sync/paymentPolicies',
|
|
isAuthenticated,
|
|
checkPermissions('marketplace', 'sync'),
|
|
async (req, res) => {
|
|
syncMarketplacePaymentPoliciesRouteHandler(req, res);
|
|
}
|
|
);
|
|
|
|
router.post(
|
|
'/:id/sync/returnPolicies',
|
|
isAuthenticated,
|
|
checkPermissions('marketplace', 'sync'),
|
|
async (req, res) => {
|
|
syncMarketplaceReturnPoliciesRouteHandler(req, res);
|
|
}
|
|
);
|
|
|
|
router.post(
|
|
'/:id/sync/taxRates',
|
|
isAuthenticated,
|
|
checkPermissions('marketplace', 'sync'),
|
|
async (req, res) => {
|
|
syncMarketplaceTaxRatesRouteHandler(req, res);
|
|
}
|
|
);
|
|
|
|
router.post(
|
|
'/:id/sync/items',
|
|
isAuthenticated,
|
|
checkPermissions('marketplace', 'sync'),
|
|
async (req, res) => {
|
|
syncMarketplaceItemsRouteHandler(req, res);
|
|
}
|
|
);
|
|
|
|
router.post(
|
|
'/:id/sync/orders',
|
|
isAuthenticated,
|
|
checkPermissions('marketplace', 'sync'),
|
|
async (req, res) => {
|
|
syncMarketplaceOrdersRouteHandler(req, res);
|
|
}
|
|
);
|
|
|
|
router.post(
|
|
'/:id/sync/webhooks',
|
|
isAuthenticated,
|
|
checkPermissions('marketplace', 'sync'),
|
|
async (req, res) => {
|
|
syncMarketplaceWebhooksRouteHandler(req, res);
|
|
}
|
|
);
|
|
|
|
router.get('/:id/hook', async (req, res) => {
|
|
marketplaceWebhookChallengeRouteHandler(req, res);
|
|
});
|
|
router.get('/:id/ebay-challenge', async (req, res) => {
|
|
marketplaceWebhookChallengeRouteHandler(req, res);
|
|
});
|
|
|
|
// Webhook endpoint — no auth, provider verifies via signature
|
|
router.post('/:id/hook', async (req, res) => {
|
|
marketplaceWebhookRouteHandler(req, res);
|
|
});
|
|
router.post('/:id/ebay-webhook', async (req, res) => {
|
|
marketplaceWebhookRouteHandler(req, res);
|
|
});
|
|
|
|
router.post(
|
|
'/:id/webhooks/subscribe',
|
|
isAuthenticated,
|
|
checkPermissions('marketplace', 'connect'),
|
|
async (req, res) => {
|
|
subscribeMarketplaceWebhooksRouteHandler(req, res);
|
|
}
|
|
);
|
|
|
|
router.get('/:id/debug-ebay', isAuthenticated, async (req, res) => {
|
|
debugEbayRouteHandler(req, res);
|
|
});
|
|
router.get('/:id/debug/ebay', isAuthenticated, async (req, res) => {
|
|
debugEbayRouteHandler(req, res);
|
|
});
|
|
|
|
router.get('/neighbors', isAuthenticated, async (req, res) => {
|
|
const { property, search, sortProperty, sortOrder, id } = req.query;
|
|
const filter = await getFilter(req.query, listAllowedFilters);
|
|
getMarketplaceNeighborsRouteHandler(
|
|
req,
|
|
res,
|
|
property,
|
|
filter,
|
|
search,
|
|
getSort(sortProperty, listAllowedSorters),
|
|
sortOrder,
|
|
id
|
|
);
|
|
});
|
|
|
|
router.get('/:id', isAuthenticated, checkPermissions('marketplace', 'info'), async (req, res) => {
|
|
getMarketplaceRouteHandler(req, res);
|
|
});
|
|
|
|
router.put('/:id', isAuthenticated, checkPermissions('marketplace', 'edit'), async (req, res) => {
|
|
editMarketplaceRouteHandler(req, res);
|
|
});
|
|
|
|
router.delete('/:id', isAuthenticated, async (req, res) => {
|
|
deleteMarketplaceRouteHandler(req, res);
|
|
});
|
|
|
|
export default router;
|