Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
07d02d1
[maven-release-plugin] prepare for next development iteration
namedgraph Sep 12, 2025
b2c5c11
Post-release version bump
namedgraph Sep 12, 2025
248edab
The admin app moved to the `admin.` subdomain instead of the `admin/`…
namedgraph Oct 7, 2025
a06bb5d
Simplified `button.btn-load-endpoint-schema` handler
namedgraph Oct 9, 2025
9add255
Fix entrypoint to load datasets for all configured apps
namedgraph Oct 10, 2025
b631682
`$ldt:base` replaced with `ldt:base()` in client-side stylesheet
namedgraph Oct 13, 2025
d8b914c
Auth isolated by dataspace (#246)
namedgraph Oct 25, 2025
a797da1
Sticky left-nav/right-nav
namedgraph Oct 27, 2025
1be2cb3
Graph layout fixes
namedgraph Nov 6, 2025
97b9f9f
Removed unused namespace
namedgraph Nov 8, 2025
ddc3744
`CORSFilter` response filter
namedgraph Nov 9, 2025
4eaec20
SPARQL update proxying fix
namedgraph Nov 14, 2025
3878906
`application/x-www-form-urlencoded` proxying fix and test
namedgraph Nov 14, 2025
434fe0d
Improved SHACL support in UI
namedgraph Nov 14, 2025
3f88a9b
`ldh:Shape` mode fix
namedgraph Nov 16, 2025
0be53e8
Billion laughs exploit test and fix
namedgraph Nov 16, 2025
b9da02e
Restored "Public access" authorization
namedgraph Nov 16, 2025
eb69ec3
Fix LNK-009 (#251)
namedgraph Nov 17, 2025
f99836c
Fixed LNK-004 exploit
namedgraph Nov 17, 2025
33bd13d
LNK-002 exploit fix
namedgraph Nov 20, 2025
7773cc7
Fixed LNK-011 exploit (#255)
namedgraph Nov 24, 2025
aefdc22
Fix ClientUriRewriteFilter to use configured host instead of hardcode…
namedgraph Nov 24, 2025
eeaac18
SNAPSHOT bump
namedgraph Nov 24, 2025
8f3278b
Refactor `fragment` as `uri` (#256)
namedgraph Nov 28, 2025
b372b9b
Removed XOM dependency
namedgraph Nov 28, 2025
3021268
Changed nginx config to exempt internal requests from rate limiting
namedgraph Nov 30, 2025
041ced9
Optimize caching of authenticated requests
namedgraph Dec 1, 2025
0b856ea
Varnish optimization fixes
namedgraph Dec 1, 2025
cf35c12
Debug test
namedgraph Dec 1, 2025
1462f7c
Varnish container config fixes
namedgraph Dec 1, 2025
23c8684
Varnish entrypoint/command fixes
namedgraph Dec 2, 2025
cc47cda
Docker volume for Varnish cache file
namedgraph Dec 2, 2025
2ec950e
Removed rate limiting tests
namedgraph Dec 2, 2025
2a4232c
Paremeterized nginx and varnish configs
namedgraph Dec 2, 2025
3f417f2
Fixed `$ORIGIN` not to include default ports
namedgraph Dec 2, 2025
1a272b0
Removed debug output
namedgraph Dec 3, 2025
8ea7cb6
Fixed OpenLayer map dragging
namedgraph Dec 4, 2025
f53fb56
OAuth login refactoring (#257)
namedgraph Dec 7, 2025
0f4168e
Fixed access request URL building
namedgraph Dec 8, 2025
67004fc
WYMEditor cross-origin fix
namedgraph Dec 8, 2025
f77f2be
Replaced `ldh:new` with `ixsl:new`
namedgraph Dec 8, 2025
434b2d0
`varnish-frontend` invalidation logic
namedgraph Dec 9, 2025
59e1157
Cleanup
namedgraph Dec 9, 2025
158db54
Casting fix
namedgraph Dec 9, 2025
2ca42d8
`ldh:parent-origin` function
namedgraph Dec 10, 2025
19d06a3
Merge branch 'master' into develop
namedgraph Dec 11, 2025
94fda7f
ORCID OpenID Connect login (#258)
namedgraph Dec 11, 2025
bd15d11
Use system's base URI
namedgraph Dec 11, 2025
917d36f
Cleanup
namedgraph Dec 11, 2025
ef1864e
Changed Fuseki folder
namedgraph Dec 12, 2025
6ed78f4
Updated CHANGELOG
namedgraph Dec 12, 2025
45e6116
Removed unused code
namedgraph Dec 12, 2025
2d859a7
Updated release script
namedgraph Dec 12, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
.DS_Store
/target
/.env
/data
/uploads
/nb-configuration.xml
/node
Expand All @@ -12,4 +11,5 @@
/ssl
/http-tests/ssl
/http-tests/datasets
/http-tests/uploads
/http-tests/uploads
/fuseki
64 changes: 64 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,67 @@
## [5.1.0] - 2025-12-12
### Added
- ORCID OpenID Connect login support with JWT token verification
- `CORSFilter` response filter for cross-origin resource sharing on static assets
- Cache invalidation (BAN requests) for agent and user account lookup queries
- New `Application::normalizeOrigin` method for origin normalization
- `ldh:parent-origin` XPath function for parent origin retrieval
- HTTP tests for CORS functionality, internal IP blocking, and form proxying
- `ForbiddenExceptionMapper` for handling forbidden exceptions
- `Content-Security-Policy` header for uploaded files to prevent XSS attacks
- Sticky left and right navigation panels
- Support for recursive content blocks
- Docker volume for Varnish cache file persistence

### Changed
- **BREAKING**: Admin application moved from `/admin/` path to `admin.` subdomain
- **BREAKING**: Replaced `ldt:base` with `ldh:origin` in configuration (now uses absolute URIs with full domain names)
- Refactored OAuth2 authentication with extracted base classes `AuthorizeBase`, `LoginBase`, and `JWTVerifier`
- Provider-specific implementations for Google and ORCID OAuth flows in separate packages
- Authorization queries now isolated by dataspace using `FILTER(strstarts(str(?g), str($base)))`
- Optimized Varnish caching for authenticated requests with proper cache bypass for user-specific content
- Root domain extraction logic replaced with configured `BASE_URI` from `Application.getBaseURI()`
- Eliminated unnecessary wrapper methods (`getRootContextURI()`) in favor of direct `getSystem().getBaseURI()` calls
- Client-side XSLT now uses `ldt:base()` function instead of `$ldt:base` parameter
- OAuth and access request endpoints moved to end-user dataspace (no longer extend `GraphStoreImpl` or `SPARQLEndpointImpl`)
- ID tokens now returned via URL fragment instead of query parameters
- CLI scripts refactored: `--fragment` parameter renamed to `--uri`
- Nginx configuration now exempts internal requests from rate limiting
- Parameterized nginx and Varnish configurations for better flexibility
- Improved `ClientUriRewriteFilter` to use configured host instead of hardcoded localhost
- Agent metadata and authorizations now managed per-app in entrypoint.sh
- Separated templates for owner and secretary authorizations
- Fuseki data directory changed in Docker configuration
- `$ORIGIN` environment variable now excludes default ports (80/443)
- WYMEditor cross-origin compatibility fixes
- Replaced `ldh:new` with `ixsl:new` in client-side code

### Fixed
- Fixed security vulnerability [LNK-002 (cache poisoning)](https://github.com/AtomGraph/LinkedDataHub/issues/253)
- Fixed security vulnerability [LNK-004 (path traversal)](https://github.com/AtomGraph/LinkedDataHub/issues/252)
- Fixed security vulnerability [LNK-009 (SSRF - internal IP address proxying)](https://github.com/AtomGraph/LinkedDataHub/issues/250)
- Fixed security vulnerability [LNK-011 (XSS via uploaded files)](https://github.com/AtomGraph/LinkedDataHub/issues/254)
- Fixed Billion Laughs [XML entity expansion exploit](https://github.com/AtomGraph/LinkedDataHub/issues/249) by excluding Xerces dependency
- Fixed OpenLayers map dragging functionality
- Fixed graph layout rendering issues
- Fixed SPARQL update and `application/x-www-form-urlencoded` proxying
- Fixed access request URL building and modal form display
- Fixed `ldh:Shape` mode in XSLT
- Fixed HTML reloading after OAuth login
- Improved SHACL support in UI with better form controls
- Fixed performance regression in `ClientUriRewriteFilter` for production deployments
- Fixed agent and user account duplicate creation via proper cache invalidation
- Fixed same-site URI resolution for XSLT document loading across subdomains
- Fixed entrypoint to load datasets for all configured apps
- Fixed authorization filter to handle non-existent dataspaces (throws `NotFoundException`)

### Removed
- Removed `RequestAccess` resource from admin package (moved to end-user)
- Removed `admin/oauth2` package (OAuth moved to end-user dataspace)
- Removed XOM dependency
- Removed rate limiting tests from HTTP test suite
- Removed debug output from entrypoint and test scripts
- Removed unused namespace declarations

## [5.0.23] - 2025-09-11
### Added
- Drag handles for content blocks - blocks can now only be dragged by their dedicated drag handles
Expand Down
18 changes: 13 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ RUN mvn -Pstandalone clean install

# ==============================

FROM atomgraph/letsencrypt-tomcat:10.1.34
FROM atomgraph/letsencrypt-tomcat:10.1.46

LABEL maintainer="martynas@atomgraph.com"

Expand Down Expand Up @@ -72,14 +72,12 @@ ENV OWNER_CERT_ALIAS=root-owner
ENV OWNER_KEYSTORE=/var/linkeddatahub/ssl/owner/keystore.p12
ENV OWNER_CERT=/var/linkeddatahub/ssl/owner/cert.pem
ENV OWNER_PUBLIC_KEY=/var/linkeddatahub/ssl/owner/public.pem
ENV OWNER_PRIVATE_KEY=/var/linkeddatahub/ssl/owner/private.key

ENV SECRETARY_COMMON_NAME=LinkedDataHub
ENV SECRETARY_CERT_ALIAS=root-secretary
ENV SECRETARY_KEYSTORE=/var/linkeddatahub/ssl/secretary/keystore.p12
ENV SECRETARY_CERT=/var/linkeddatahub/ssl/secretary/cert.pem
ENV SECRETARY_PUBLIC_KEY=/var/linkeddatahub/ssl/secretary/public.pem
ENV SECRETARY_PRIVATE_KEY=/var/linkeddatahub/ssl/secretary/private.key

ENV CLIENT_KEYSTORE_MOUNT=/var/linkeddatahub/ssl/secretary/keystore.p12
ENV CLIENT_KEYSTORE="$CATALINA_HOME/webapps/ROOT/WEB-INF/keystore.p12"
Expand Down Expand Up @@ -147,12 +145,22 @@ COPY platform/import-letsencrypt-stg-roots.sh import-letsencrypt-stg-roots.sh

COPY platform/select-root-services.rq select-root-services.rq

# copy the metadata of the built-in secretary agent
COPY platform/select-agent-metadata.rq select-agent-metadata.rq

# copy the metadata of built-in agents

COPY platform/root-secretary.trig.template root-secretary.trig.template

COPY platform/root-owner.trig.template root-owner.trig.template

COPY platform/root-secretary-authorization.trig.template root-secretary-authorization.trig.template

COPY platform/root-owner-authorization.trig.template root-owner-authorization.trig.template

# copy the metadata of the namespace ontology

COPY platform/namespace-ontology.trig.template namespace-ontology.trig.template

# copy default datasets

COPY platform/datasets/admin.trig /var/linkeddatahub/datasets/admin.trig
Expand Down Expand Up @@ -197,7 +205,7 @@ RUN useradd --no-log-init -U ldh && \
RUN ./import-letsencrypt-stg-roots.sh

HEALTHCHECK --start-period=80s --retries=5 \
CMD curl -f -I "http://localhost:${HTTP_PORT}/ns" -H "Accept: application/n-triples" || exit 1 # relies on public access to the namespace document
CMD curl -f -I "http://localhost:7070/ns" -H "Accept: application/n-triples" || exit 1 # relies on public access to the namespace document

USER ldh

Expand Down
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,17 @@ It takes a few clicks and filling out a form to install the product into your ow
### Prerequisites

* `bash` shell 4.x. It should be included by default on Linux. On Windows you can install the [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/install-win10).
* [`openssl`](https://www.openssl.org/) available on `$PATH`
* [Docker](https://docs.docker.com/install/) installed. At least 8GB of memory dedicated to Docker is recommended.
* [Docker Compose](https://docs.docker.com/compose/install/) installed

#### CLI scripts

The following tools are required for CLI scripts in the `bin/` directory:

* [`curl`](https://curl.se/)
* [`openssl`](https://www.openssl.org/)
* `python` 3.x

### Steps

1. [Fork](https://guides.github.com/activities/forking/) this repository and clone the fork into a folder
Expand Down Expand Up @@ -270,11 +277,11 @@ LinkedDataHub includes an HTTP [test suite](https://github.com/AtomGraph/LinkedD
* [SPARQLBuilder](https://github.com/AtomGraph/sparql-builder)
* [OpenLayers](https://openlayers.org)
* [Google Charts](https://developers.google.com/chart)
* [xml-c14n-sync](https://github.com/AtomGraph/xml-c14n-sync)

### Java

* [Jersey](https://eclipse-ee4j.github.io/jersey/)
* [XOM](http://www.xom.nu)
* [JavaMail](https://javaee.github.io/javamail/)
* [Guava](https://github.com/google/guava)
* [java-jwt](https://github.com/auth0/java-jwt)
Expand Down
29 changes: 21 additions & 8 deletions bin/add-generic-service.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env bash
set -eo pipefail

print_usage()
{
Expand All @@ -16,6 +17,7 @@ print_usage()
printf " --description DESCRIPTION Description of the service (optional)\n"
printf " --slug SLUG String that will be used as URI path segment (optional)\n"
printf "\n"
printf " --uri URI URI of the service (optional)\n"
printf " --endpoint ENDPOINT_URI Endpoint URI\n"
printf " --graph-store GRAPH_STORE_URI Graph Store URI (optional)\n"
printf " --auth-user AUTH_USER Authorization username (optional)\n"
Expand Down Expand Up @@ -43,6 +45,11 @@ do
shift # past argument
shift # past value
;;
--proxy)
proxy="$2"
shift # past argument
shift # past value
;;
--title)
title="$2"
shift # past argument
Expand All @@ -53,8 +60,8 @@ do
shift # past argument
shift # past value
;;
--fragment)
fragment="$2"
--uri)
uri="$2"
shift # past argument
shift # past value
;;
Expand All @@ -69,7 +76,8 @@ do
shift # past value
;;
--auth-user)
auth_user=true
auth_user="$2"
shift # past argument
shift # past value
;;
--auth-pwd)
Expand All @@ -85,6 +93,8 @@ do
done
set -- "${args[@]}" # restore args

target="$1"

if [ -z "$cert_pem_file" ] ; then
print_usage
exit 1
Expand Down Expand Up @@ -112,10 +122,13 @@ args+=("-p")
args+=("$cert_password")
args+=("-t")
args+=("text/turtle") # content type
if [ -n "$proxy" ]; then
args+=("--proxy")
args+=("$proxy")
fi

if [ -n "$fragment" ] ; then
# relative URI that will be resolved against the request URI
subject="<#${fragment}>"
if [ -n "$uri" ] ; then
subject="<${uri}>"
else
subject="_:subject"
fi
Expand All @@ -142,8 +155,8 @@ if [ -n "$auth_pwd" ] ; then
turtle+="${subject} a:authPwd \"${auth_pwd}\" .\n"
fi
if [ -n "$description" ] ; then
turtle+="_:query dct:description \"${description}\" .\n"
turtle+="${subject} dct:description \"${description}\" .\n"
fi

# submit Turtle doc to the server
echo -e "$turtle" | post.sh "${args[@]}"
echo -e "$turtle" | turtle --base="$target" | post.sh "${args[@]}"
25 changes: 18 additions & 7 deletions bin/add-result-set-chart.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env bash
set -eo pipefail

print_usage()
{
Expand All @@ -14,7 +15,7 @@ print_usage()
printf "\n"
printf " --title TITLE Title of the chart\n"
printf " --description DESCRIPTION Description of the chart (optional)\n"
printf " --fragment STRING String that will be used as URI fragment identifier (optional)\n"
printf " --uri URI URI of the chart (optional)\n"
printf "\n"
printf " --query QUERY_URI URI of the SELECT query\n"
printf " --chart-type TYPE_URI URI of the chart type\n"
Expand Down Expand Up @@ -43,6 +44,11 @@ do
shift # past argument
shift # past value
;;
--proxy)
proxy="$2"
shift # past argument
shift # past value
;;
--title)
title="$2"
shift # past argument
Expand All @@ -53,8 +59,8 @@ do
shift # past argument
shift # past value
;;
--fragment)
fragment="$2"
--uri)
uri="$2"
shift # past argument
shift # past value
;;
Expand Down Expand Up @@ -86,6 +92,8 @@ do
done
set -- "${args[@]}" # restore args

target="$1"

if [ -z "$cert_pem_file" ] ; then
print_usage
exit 1
Expand Down Expand Up @@ -125,10 +133,13 @@ args+=("-p")
args+=("$cert_password")
args+=("-t")
args+=("text/turtle") # content type
if [ -n "$proxy" ]; then
args+=("--proxy")
args+=("$proxy")
fi

if [ -n "$fragment" ] ; then
# relative URI that will be resolved against the request URI
subject="<#${fragment}>"
if [ -n "$uri" ] ; then
subject="<${uri}>"
else
subject="_:subject"
fi
Expand All @@ -148,4 +159,4 @@ if [ -n "$description" ] ; then
fi

# submit Turtle doc to the server
echo -e "$turtle" | post.sh "${args[@]}"
echo -e "$turtle" | turtle --base="$target" | post.sh "${args[@]}"
Loading