Skip to main content
Jahia Store
EN

Jahia Store

community
Download 5.1.2

Information

Module ID
jahia-store
Group ID
org.jahia.community
Status
community
Category
Admin Features
Author
JSG
Developer website
http://www.jahia.com
Requires Jahia
8.2.2.1
Updated
2026-09-23
Source
scm:git:git@github.com:Jahia/privateappstore.git

The Private App Store ("Forge") backend — a Jahia 8.2 Java/OSGi module providing the JCR content model, the GraphQL admin API, the Jahia Actions for authoring (module upload, reviews, …), background jobs, a Maven proxy, and the moduleList.json feed.

Its website and in-site administration UI are provided by the sibling jahia-store-template JavaScript module.

Screenshots

Versions

Upgrade notes

  • Security. This release fixes two privilege issues on the store-developer role:
    • SEC-366 / GHSA-f882-3xwv-3439: the role could rewrite the site's live ACL. On startup, the module removes jcr:modifyAccessControl_live from store-developer and logs SEC-366: removed ... from role store-developer. If it logs SEC-366: could not remove ... instead, the installation is still exposed: remove that permission from /roles/store-developer by hand.
    • SEC-381: an upload now grants owner only on the nodes it creates. See CHANGELOG.md.
  • Deploy with jahia-store-template 5.0.6. It shows the new upload-based "Released" date and hides sign-in for public-edge (CDN-fronted) visitors.

What's Changed

  • test: lock moduleList.json field contract (#55 regression guard) by @fbourasse in #64
  • chore: add cypress test for unpublished module visibility by @goonerish in #66
  • fix: store-developer could rewrite the site's live ACL (GHSA-f882-3xwv-3439 / SEC-366) by @fbourasse in #80
  • test: cover cross-user fragment cache identity (SEC-375 / GHSA-g6wp-ghxm-mx76) by @fbourasse in #82
  • test(e2e): cover the module dependency lists by @goonerish in #86
  • feat(forge): date releases by upload time, not last edit (uploadDate) by @goonerish in #87
  • SUPPORT-687: serve anonymous, read-only use to the public edge by @fbourasse in #89
  • fix: record the upload's owner grant only for the nodes it created by @delallioui in #83
  • test: align the STORE_TEMPLATE_VERSION default in .env.example with 5.0.6-SNAPSHOT by @fbourasse in #90

New Contributors

Full Changelog: 5_1_1...5_1_2

Requires Jahia 8.2.2.1Updated 2026-09-23

Hotfix for a 5.1.0 regression that broke module-list consumers.

5.1.0 (via SECURITY-571 #55) dropped the path (top-level + per-entry) and
per-entry jcrprimarytype fields from the anonymous moduleList.json feed. Jahia
core's ForgeService — the app-store client that refreshes available modules —
requires those fields, so consuming instances failed with:

[ForgeService] unable to parse JSON return string for  https://store.jahia.com/en/sites/store/contents/modules-repository.moduleList.json

 

Fix: the feed's field set is restored to the 5.0.0 contract (path +
jcrprimarytype are back and documented in-code as required). All other 5.1.0
security hardening (#54, #56, #57, #58, #28, #61) is unchanged.

📥 Install

Download jahia-store-5.1.1.jar below and deploy it to store.jahia.com
(Administration → Modules, or the karaf/deploy / provisioning path), replacing
5.1.0. Consuming instances will then refresh their module list normally.

Full changelog: 5_1_0...5_1_1

Requires Jahia 8.2.2.1Updated 2026-09-23

Security-hardening release rolling up the full SECURITY-571 internal blind-audit
remediation (the intermediate 5.0.1 was never published). No functional/API
changes to the storefront or authoring UI — existing content and integrations are
unaffected. Pairs with jahia-store-template 5.0.1.

🔒 Security

Remediation of the 2026-07 blind audit and its fix-verification follow-up:

  • Draft package pages no longer exposed to anonymous visitors (#54) — the live
    publish gate now applies to the shared jmix:forgeElement mixin, so unpublished
    jnt:forgePackage detail pages are gated exactly like modules. Backed by a
    defense-in-depth check in the storefront detail view (store-template).
  • Server-side re-validation of uploaded media, scoped by node structure
    (#28, hardened by #61) — ForgeMediaMimeListener sniffs the real magic bytes of
    any jnt:resource written under a forge element and removes a script-capable
    file (a declared SVG/HTML/XML mime, or bytes that sniff as markup) anywhere in
    the module subtree — not just icon/screenshots. Media folders additionally
    require a genuine raster. Legitimate binaries (the module artifact) are untouched.
  • Log-injection hardening (#56, #58) — attacker-controllable manifest fields
    (CreateEntryFromJar) and request parameters (MavenProxy) are sanitized before
    logging, preventing forged log lines (CWE-117).
  • Reduced information disclosure in the anonymous feed (#55) — the public
    moduleList.json no longer emits absolute JCR paths or node primary types; a
    stable opaque id is kept for consumers.
  • Documented MavenProxy deployment invariant (#57) — operator guidance against
    a confused-deputy exposure on misconfigured public stores.
Requires Jahia 8.2.2.1Updated 2026-07-02

5.0.0 is a major release of the Private App Store backend. The module was renamed
from the old Forge / privateappstore artifact to jahia-store, its JSP-based
storefront was removed in favour of the new jahia-store-template JavaScript
module, and its server side was modernized: a single namespaced GraphQL surface,
per-site settings stored as file-backed OSGi configuration, and a hardened, well-tested
upload/proxy/permission stack. Relicensed to Apache 2.0.

Pairs with: jahia-store-template 5.0.0 (the storefront/editor UI). Backed by a
Sonatype Nexus (or any hosted Maven release repo) for module artifacts.


Highlights

  • Renamed to jahia-store (artifact id and OSGi bundle).
  • Storefront extracted to the jahia-store-template JS module — the legacy JSP
    storefront and its dead Java were removed; this module is now backend-only
    (GraphQL, Actions, feeds, Maven proxy, settings).
  • One namespaced GraphQL surface — all store operations live under a single
    forge field instead of polluting the root Query/Mutation.
  • Settings survive restart — per-site configuration is now a file-backed OSGi
    factory configuration served by a ManagedServiceFactory, replacing the old JCR
    mixin and the programmatic ConfigurationAdmin instances that were lost on restart.
  • Security & permissions hardened across upload, Maven proxy, role management and
    feeds, with ~98 JUnit tests, a green SonarQube gate, and CodeQL remediation.

GraphQL

  • All store operations are grouped under a single hierarchical namespace: Query.forge
    returns a ForgeQuery container and Mutation.forge returns a ForgeMutation
    container, with operations as nested fields — e.g.
    forge { settings, categorySettings, manageRolesSettings, searchPrincipals } and
    forge { updateSettings, setRootCategory, addCategory, updateCategoryTitles, deleteCategory, grantRole, revokeRole }.
  • This removes the flat root-level fields that previously collided with other modules
    (the cross-bundle "Duplicate field" schema failure) and were undiscoverable.
  • The /modules/graphql endpoint stays permission-gated; write features with a Java
    side run as Jahia Actions (CSRF-guarded over XMLHttpRequest), not GraphQL.

Settings & configuration

  • Per-site settings — Nexus connection (url/id/user/password base64 +
    rootCategoryUuid) and storefront branding — are stored as a per-site OSGi factory
    configuration
     <karaf.etc>/org.jahia.modules.forge.forgeSettings-<siteKey>.cfg.
  • ForgeSettingsServiceImpl is a ManagedServiceFactory keyed by siteKey: Felix
    FileInstall delivers each .cfg to it; save()/delete() write/remove the file
    atomically. File-backed, so settings survive restarts and redeploys and can be
    hand-edited in karaf/etc.
  • A shipped, marker-protected default template (…forgeSettings-default.cfg) documents
    the keys and can be copied per site.
  • Branding is exposed to the (anonymous) storefront via an in-process OSGi-service
    bridge; the password is never returned to clients.

Module upload, publish & download

  • Upload (CreateEntryFromJar Action) deploys the module artifact to the configured
    Maven release repository and creates the catalog node, running in the posting
    workspace; accepts JAR/TGZ (WAR upload removed).
  • Publish gate with owner publish toggle and auto-publish of the latest version;
    add / remove version supported.
  • Maven proxy serves downloads from the backing repository at
    /modules/mavenproxy/...; download URLs are generated from coordinates (not stored).
    Anonymous download is allowed where the repository read gate permits.

Roles & administration

  • Site-scoped role management (store-administrator, store-developer, reader) with
    grant/revoke restricted to an allowlist; store administration lives in jContent.

Feeds

  • moduleList.json / RSS feeds retained (the contract consumed by
    jahia-store-template), with output escaping and a coordinate guard that suppresses
    download URLs for unsafe (.. / /) coordinates.

Security & quality

  • Hardening: upload version-coordinate validation, Maven-proxy URL allowlist /
    path-traversal guards, siteKey validation on role and category operations, RSS/feed
    escaping, atomic writes.
  • ~98 JUnit tests (validators, role allowlist, settings factory dispatch, proxy URL
    grammar, upload coordinates), SonarQube quality gate green, CodeQL alerts
    remediated.

Upgrade notes / breaking changes

  • Renamed to jahia-store (artifact id + bundle). Uninstall the previous
    Forge/privateappstore module before deploying 5.0.0
     — running both registers the
    same global GraphQL field / servlet alias and breaks the whole GraphQL schema.
  • Storefront moved to the separate jahia-store-template 5.0.0 module — deploy it
    alongside this one (it also needs the richtext-ckeditor5 module for authoring).
  • Settings moved out of JCR. Per-site settings created by pre-5.0.0 builds (JCR
    jmix:forgeSettings, or the interim programmatic ConfigurationAdmin instances) are
    not auto-migrated — re-save them once in the store administration UI (or drop the
    values into the karaf/etc .cfg).
  • WAR module upload removed — publish modules as JAR or TGZ.
  • Review/rating feature removed (content types left dormant).
  • License changed to Apache 2.0.
  • Bump the module version when shipping changed initial JCR import content (imported
    once per version).

Requirements

  • Jahia 8.2.x (graphql-dxm-provider).
  • jahia-store-template 5.0.0 (storefront) + richtext-ckeditor5 (authoring).
  • A hosted Maven release repository (e.g. Sonatype Nexus) for module artifacts.
Requires Jahia 8.2.2.1Updated 2026-06-25