anything-llm/server/utils/middleware/communityHubDownloadsEnabled.js
Sean Hatfield 05c530221b
Community hub integration ()
* wip hub connection page fe + backend

* lint

* implement backend for local hub items + placeholder endpoints to fetch hub app data

* fix hebrew translations

* revamp community integration flow

* change sidebar

* Auto import if id in URL param
remove preview in card screen and instead go to import flow

* get user's items + team items from hub + ui improvements to hub settings

* lint

* fix merge conflict

* refresh hook for community items

* add fallback for user items

* Disable bundle items by default on all instances

* remove translations (will complete later)

* loading skeleton

* Make community hub endpoints admin only
show visibility on items
combine import/apply for items to they are event logged for review

* improve middleware and import flow

* community hub ui updates

* Adjust importing process

* community hub to dev

* Add webscraper preload into imported plugins

* add runtime property to plugins

* Fix button status on imported skill change
show alert on skill change
Update markdown type and theme on import of agent skill

* update documentaion paths

* remove unused import

* linting

* review loading state

---------

Co-authored-by: Timothy Carambat <rambat1010@gmail.com>
2024-11-26 09:59:43 -08:00

77 lines
3.2 KiB
JavaScript

const { CommunityHub } = require("../../models/communityHub");
const { reqBody } = require("../http");
/**
* ### Must be called after `communityHubItem`
* Checks if community hub bundle downloads are enabled. The reason this functionality is disabled
* by default is that since AgentSkills, Workspaces, and DataConnectors are all imported from the
* community hub via unzipping a bundle - it would be possible for a malicious user to craft and
* download a malicious bundle and import it into their own hosted instance. To avoid this, this
* functionality is disabled by default and must be enabled manually by the system administrator.
*
* On hosted systems, this would not be an issue since the user cannot modify this setting, but those
* who self-host can still unlock this feature manually by setting the environment variable
* which would require someone who likely has the capacity to understand the risks and the
* implications of importing unverified items that can run code on their system, container, or instance.
* @see {@link https://docs.anythingllm.com/docs/community-hub/import}
* @param {import("express").Request} request
* @param {import("express").Response} response
* @param {import("express").NextFunction} next
* @returns {void}
*/
function communityHubDownloadsEnabled(request, response, next) {
if (!("COMMUNITY_HUB_BUNDLE_DOWNLOADS_ENABLED" in process.env)) {
return response.status(422).json({
error:
"Community Hub bundle downloads are not enabled. The system administrator must enable this feature manually to allow this instance to download these types of items. See https://docs.anythingllm.com/configuration#anythingllm-hub-agent-skills",
});
}
// If the admin specifically did not set the system to `allow_all` then downloads are limited to verified items or private items only.
// This is to prevent users from downloading unverified items and importing them into their own instance without understanding the risks.
const item = response.locals.bundleItem;
if (
!item.verified &&
item.visibility !== "private" &&
process.env.COMMUNITY_HUB_BUNDLE_DOWNLOADS_ENABLED !== "allow_all"
) {
return response.status(422).json({
error:
"Community hub bundle downloads are limited to verified public items or private team items only. Please contact the system administrator to review or modify this setting. See https://docs.anythingllm.com/configuration#anythingllm-hub-agent-skills",
});
}
next();
}
/**
* Fetch the bundle item from the community hub.
* Sets `response.locals.bundleItem` and `response.locals.bundleUrl`.
*/
async function communityHubItem(request, response, next) {
const { importId } = reqBody(request);
if (!importId)
return response.status(500).json({
success: false,
error: "Import ID is required",
});
const {
url,
item,
error: fetchError,
} = await CommunityHub.getBundleItem(importId);
if (fetchError)
return response.status(500).json({
success: false,
error: fetchError,
});
response.locals.bundleItem = item;
response.locals.bundleUrl = url;
next();
}
module.exports = {
communityHubItem,
communityHubDownloadsEnabled,
};