Merge branch 'main' into versions/5.0.0

# Conflicts:
#	RELEASE_NOTES.md
#	config/app/variables/cli/cli.json
#	config/app/variables/default.json
#	package-lock.json
#	package.json
This commit is contained in:
Joachim Van Herwegen 2022-08-04 17:18:34 +02:00
commit 740ba3398b
21 changed files with 5521 additions and 10956 deletions

View File

@ -158,9 +158,14 @@ jobs:
if: startsWith(github.ref, 'refs/tags/v') || (github.ref == 'refs/heads/main') if: startsWith(github.ref, 'refs/tags/v') || (github.ref == 'refs/heads/main')
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout -
name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v3
- name: Docker meta -
name: Set up QEMU
uses: docker/setup-qemu-action@v2
-
name: Docker meta
id: meta id: meta
uses: docker/metadata-action@v4 uses: docker/metadata-action@v4
with: with:
@ -173,31 +178,40 @@ jobs:
type=semver,pattern={{major}}.{{minor}} type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}} type=semver,pattern={{major}}
github-token: ${{ secrets.github_token }} github-token: ${{ secrets.github_token }}
- name: Set up Docker Buildx -
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2 uses: docker/setup-buildx-action@v2
- name: Login to DockerHub -
name: Login to DockerHub
uses: docker/login-action@v2 uses: docker/login-action@v2
with: with:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and export to docker -
name: Build and export to docker
uses: docker/build-push-action@v3 uses: docker/build-push-action@v3
with: with:
context: . context: .
load: true load: true
tags: ${{ steps.meta.outputs.tags }} tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }} labels: ${{ steps.meta.outputs.labels }}
- name: "Test docker image 'latest'" -
name: "Test docker image 'edge'"
if: github.ref == 'refs/heads/main'
run: | run: |
docker run --rm solidproject/community-server:latest --version docker run --rm --pull never solidproject/community-server:edge --version
- name: "Test docker image 'edge'" -
name: "Test docker image 'latest'"
if: startsWith(github.ref, 'refs/tags/v')
run: | run: |
docker run --rm solidproject/community-server:edge --version docker run --rm --pull never solidproject/community-server:latest --version
- name: Build and push -
name: Build and push
uses: docker/build-push-action@v3 uses: docker/build-push-action@v3
with: with:
context: . context: .
push: true push: true
platforms: linux/amd64,linux/arm/v7
tags: ${{ steps.meta.outputs.tags }} tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }} labels: ${{ steps.meta.outputs.labels }}
@ -212,11 +226,16 @@ jobs:
if: startsWith(github.ref, 'refs/heads/versions/') if: startsWith(github.ref, 'refs/heads/versions/')
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout -
name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v3
with: with:
ref: ${{ github.ref }} ref: ${{ github.ref }}
- name: Docker meta -
name: Set up QEMU
uses: docker/setup-qemu-action@v2
-
name: Docker meta
id: meta id: meta
uses: docker/metadata-action@v4 uses: docker/metadata-action@v4
with: with:
@ -226,28 +245,34 @@ jobs:
tags: | tags: |
type=raw,value=next type=raw,value=next
github-token: ${{ secrets.github_token }} github-token: ${{ secrets.github_token }}
- name: Set up Docker Buildx -
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2 uses: docker/setup-buildx-action@v2
- name: Login to DockerHub -
name: Login to DockerHub
uses: docker/login-action@v2 uses: docker/login-action@v2
with: with:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and export to docker -
name: Build and export to docker
uses: docker/build-push-action@v3 uses: docker/build-push-action@v3
with: with:
context: . context: .
load: true load: true
tags: ${{ steps.meta.outputs.tags }} tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }} labels: ${{ steps.meta.outputs.labels }}
- name: "Test docker image 'next'" -
name: "Test docker image 'next'"
run: | run: |
docker run --rm solidproject/community-server:next --version docker run --rm --pull never solidproject/community-server:next --version
- name: Build and push -
name: Build and push
uses: docker/build-push-action@v3 uses: docker/build-push-action@v3
with: with:
context: . context: .
push: true push: true
platforms: linux/amd64,linux/arm/v7
tags: ${{ steps.meta.outputs.tags }} tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }} labels: ${{ steps.meta.outputs.labels }}
@ -276,7 +301,7 @@ jobs:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- id: get_version - id: get_version
uses: battila7/get-version-action@v2 uses: battila7/get-version-action@v2
- uses: actions/setup-python@v2 - uses: actions/setup-python@v4
with: with:
python-version: 3.x python-version: 3.x
- run: pip install mkdocs-material - run: pip install mkdocs-material

View File

@ -1,6 +1,31 @@
# Changelog # Changelog
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
## [4.1.0](https://github.com/CommunitySolidServer/CommunitySolidServer/compare/v4.0.1...v4.1.0) (2022-08-04)
### Features
* add test phase for docker images ([0159557](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/01595577a8b9aabf618ece4c261f95fc2082023f))
* args as env vars ([a461586](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/a46158692178d30975f3a91a9ce2bbdbc4f5882f))
* build versioned documentation site from CI pipeline ([027c803](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/027c803b33ff2309d09c1cc908b971c8ae785a43))
### Fixes
* Accept client WebIDs with a context array ([d290848](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/d2908480960b9708460ad71c010ea11e86497968))
* Enable ACL in default quota config ([26b42f0](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/26b42f0b175293e266bd404a1dbe206d21154690))
* Improve HTTP stream error messages ([93a141d](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/93a141dd6160c0f55839dfec1312b9f085569bcd))
* prevent JsonResourceStorage from generating too long filenames ([13dbcb6](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/13dbcb662b84ce926fcae832a16da47305e370f4))
* rdf convertors should not read or write plain JSON ([9ecb769](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/9ecb769e092cfb4cb08b514477f320956a4b302c))
* Rewrite request with a root path to OIDC Provider ([0a84230](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/0a84230307d72e1afa30386ff9dda160a9ca98d4))
* Use encrypted field to check for TLS. ([82f9070](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/82f90709a656b0d996118d2e869b6b4a2c8a2e5d))
### Chores
* Update dependencies ([15e756e](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/15e756efc1fa6c732b9872ea75249606ae9144a6))
### Documentation
* update docs links to new documentation site ([d0f9d1e](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/d0f9d1e24da7d89240efdbc11df7a5096841a398))
## [5.0.0-alpha.0](https://github.com/CommunitySolidServer/CommunitySolidServer/compare/v4.0.0...v5.0.0-alpha.0) (2022-05-05) ## [5.0.0-alpha.0](https://github.com/CommunitySolidServer/CommunitySolidServer/compare/v4.0.0...v5.0.0-alpha.0) (2022-05-05)

View File

@ -1,13 +1,13 @@
# Build stage # Build stage
FROM node:lts-alpine AS build FROM node:lts-alpine AS build
## Set current working directory # Set current working directory
WORKDIR /community-server WORKDIR /community-server
## Copy the dockerfile's context's community server files # Copy the dockerfile's context's community server files
COPY . . COPY . .
## Install and build the Solid community server (prepare script cannot run in wd) # Install and build the Solid community server (prepare script cannot run in wd)
RUN npm ci --unsafe-perm && npm run build RUN npm ci --unsafe-perm && npm run build
@ -15,17 +15,17 @@ RUN npm ci --unsafe-perm && npm run build
# Runtime stage # Runtime stage
FROM node:lts-alpine FROM node:lts-alpine
## Add contact informations for questions about the container # Add contact informations for questions about the container
LABEL maintainer="Solid Community Server Docker Image Maintainer <thomas.dupont@ugent.be>" LABEL maintainer="Solid Community Server Docker Image Maintainer <thomas.dupont@ugent.be>"
## Container config & data dir for volume sharing # Container config & data dir for volume sharing
## Defaults to filestorage with /data directory (passed through CMD below) # Defaults to filestorage with /data directory (passed through CMD below)
RUN mkdir /config /data RUN mkdir /config /data
## Set current directory # Set current directory
WORKDIR /community-server WORKDIR /community-server
## Copy runtime files from build stage # Copy runtime files from build stage
COPY --from=build /community-server/package.json . COPY --from=build /community-server/package.json .
COPY --from=build /community-server/bin ./bin COPY --from=build /community-server/bin ./bin
COPY --from=build /community-server/config ./config COPY --from=build /community-server/config ./config
@ -33,11 +33,12 @@ COPY --from=build /community-server/dist ./dist
COPY --from=build /community-server/node_modules ./node_modules COPY --from=build /community-server/node_modules ./node_modules
COPY --from=build /community-server/templates ./templates COPY --from=build /community-server/templates ./templates
## Informs Docker that the container listens on the specified network port at runtime # Informs Docker that the container listens on the specified network port at runtime
EXPOSE 3000 EXPOSE 3000
## Set command run by the container # Set command run by the container
ENTRYPOINT [ "node", "bin/server.js" ] ENTRYPOINT [ "node", "bin/server.js" ]
## By default run in filemode (overriden if passing alternative arguments) # By default run in filemode (overriden if passing alternative arguments or env vars)
CMD [ "-c", "config/file.json", "-f", "/data" ] ENV CSS_CONFIG=config/file.json
ENV CSS_ROOT_FILE_PATH=/data

View File

@ -81,6 +81,8 @@ docker run --rm -v ~/Solid:/data -p 3000:3000 -it solidproject/community-server:
docker run --rm -p 3000:3000 -it solidproject/community-server -c config/default.json docker run --rm -p 3000:3000 -it solidproject/community-server -c config/default.json
# Or use your own configuration mapped to the right directory # Or use your own configuration mapped to the right directory
docker run --rm -v ~/solid-config:/config -p 3000:3000 -it solidproject/community-server -c /config/my-config.json docker run --rm -v ~/solid-config:/config -p 3000:3000 -it solidproject/community-server -c /config/my-config.json
# Or use environment variables to configure your css instance
docker run --rm -v ~/Solid:/data -p 3000:3000 -it -e CSS_CONFIG=config/file-no-setup.json -e CSS_LOGGING_LEVEL=debug solidproject/community-server
``` ```
### 🗃️ Helm Chart ### 🗃️ Helm Chart
@ -128,6 +130,15 @@ The Community Solid Server can be started in multithreaded mode with any config.
npm start -- -c config/file.json -w -1 npm start -- -c config/file.json -w -1
``` ```
### 🖥️ Environment variables
Parameters can also be passed through environment variables.
They are prefixed with `CSS_` and converted from `camelCase` to `CAMEL_CASE`
> eg. `--showStackTrace` => `CSS_SHOW_STACK_TRACE`
**Note: command-line arguments will always override environment variables!**
### 🧶 Custom configurations ### 🧶 Custom configurations
More substantial changes to server behavior can be achieved More substantial changes to server behavior can be achieved
by writing new configuration files in JSON-LD. by writing new configuration files in JSON-LD.
@ -144,12 +155,12 @@ Recipes for configuring the server can be found at [CommunitySolidServer/recipes
The server allows writing and plugging in custom modules The server allows writing and plugging in custom modules
without altering its base source code. without altering its base source code.
The [📗 API documentation](https://communitysolidserver.github.io/CommunitySolidServer/docs/) and The [📗 API documentation](https://communitysolidserver.github.io/CommunitySolidServer/latest/docs) and
the [📐 architectural diagram](https://rubenverborgh.github.io/solid-server-architecture/solid-architecture-v1-3-0.pdf) the [📐 architectural diagram](https://rubenverborgh.github.io/solid-server-architecture/solid-architecture-v1-3-0.pdf)
can help you find your way. can help you find your way.
If you want to help out with server development, If you want to help out with server development,
have a look at the [📓 user documentation](https://github.com/CommunitySolidServer/CommunitySolidServer/blob/main/documentation/) and have a look at the [📓 user documentation](https://communitysolidserver.github.io/CommunitySolidServer/) and
[🛠 good first issues](https://github.com/CommunitySolidServer/CommunitySolidServer/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22). [🛠 good first issues](https://github.com/CommunitySolidServer/CommunitySolidServer/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22).

View File

@ -93,6 +93,10 @@ These changes are relevant if you wrote custom modules for the server that depen
A new interface `SingleThreaded` has been added. This empty interface can be implemented to mark a component as not-threadsafe. When the CSS starts in multithreaded mode, it will error and halt if any SingleThreaded components are instantiated. A new interface `SingleThreaded` has been added. This empty interface can be implemented to mark a component as not-threadsafe. When the CSS starts in multithreaded mode, it will error and halt if any SingleThreaded components are instantiated.
## v4.1.0
### New features
- Environment variables can be used instead of CLI arguments if preferred.
## v4.0.1 ## v4.0.1
Freezes the `oidc-provider` dependency to prevent a potential issue with the solid authn client Freezes the `oidc-provider` dependency to prevent a potential issue with the solid authn client
as described in https://github.com/inrupt/solid-client-authn-js/issues/2103. as described in https://github.com/inrupt/solid-client-authn-js/issues/2103.
@ -100,9 +104,9 @@ as described in https://github.com/inrupt/solid-client-authn-js/issues/2103.
## v4.0.0 ## v4.0.0
### New features ### New features
- The server can be started with a new parameter to automatically generate accounts and pods, - The server can be started with a new parameter to automatically generate accounts and pods,
for more info see [here](documentation/seeding-pods.md). for more info see [here](https://communitysolidserver.github.io/CommunitySolidServer/4.0/seeding-pods/).
- It is now possible to automate authentication requests using Client Credentials, - It is now possible to automate authentication requests using Client Credentials,
for more info see [here](documentation/client-credentials.md). for more info see [here](https://communitysolidserver.github.io/CommunitySolidServer/4.0/client-credentials/).
- A new `RedirectingHttpHandler` class has been added which can be used to redirect certain URLs. - A new `RedirectingHttpHandler` class has been added which can be used to redirect certain URLs.
- A new default configuration `config/https-file-cli.json` - A new default configuration `config/https-file-cli.json`
that can set the HTTPS parameters through the CLI has been added. that can set the HTTPS parameters through the CLI has been added.

View File

@ -116,6 +116,8 @@
], ],
"options": { "options": {
"usage": "node ./bin/server.js [args]", "usage": "node ./bin/server.js [args]",
"envVarPrefix": "CSS",
"loadFromEnv": true,
"strictMode": true "strictMode": true
} }
} }

View File

@ -18,7 +18,7 @@ it is always possible we miss something,
so please report it if you find incorrect information or links that no longer work. so please report it if you find incorrect information or links that no longer work.
An introductory tutorial that gives a quick overview of the Solid and CSS basics can be found An introductory tutorial that gives a quick overview of the Solid and CSS basics can be found
[here](https://github.com/KNowledgeOnWebScale/solid-linked-data-workshops-hands-on-exercises/blob/main/css-tutorial.md). [here](https://github.com/CommunitySolidServer/tutorials/blob/main/getting-started.md).
This is a good way to get started with the server and its setup. This is a good way to get started with the server and its setup.
If you want to know what is new in the latest version, If you want to know what is new in the latest version,

View File

@ -2,7 +2,7 @@
One potential issue for scripts and other applications is that it requires user interaction to log in and authenticate. One potential issue for scripts and other applications is that it requires user interaction to log in and authenticate.
The CSS offers an alternative solution for such cases by making use of Client Credentials. The CSS offers an alternative solution for such cases by making use of Client Credentials.
Once you have created an account as described in the [Identity Provider section](dependency-injection.md), Once you have created an account as described in the [Identity Provider section](identity-provider.md),
users can request a token that apps can use to authenticate without user input. users can request a token that apps can use to authenticate without user input.
All requests to the client credentials API currently require you All requests to the client credentials API currently require you

View File

@ -62,8 +62,15 @@ curl -X DELETE http://localhost:3000/myfile.txt
### `PATCH`: Modifying resources ### `PATCH`: Modifying resources
Currently, only patches over RDF resources are supported using [SPARQL Update](https://www.w3.org/TR/sparql11-update/) Modify a resource using [N3 Patch](https://solidproject.org/TR/protocol#n3-patch):
queries without `WHERE` clause.
```shell
curl -X PATCH -H "Content-Type: text/n3" \
--data-raw "@prefix solid: <http://www.w3.org/ns/solid/terms#>. _:rename a solid:InsertDeletePatch; solid:inserts { <ex:s2> <ex:p2> <ex:o2>. }." \
http://localhost:3000/myfile.ttl
```
Modify a resource using [SPARQL Update](https://www.w3.org/TR/sparql11-update/):
```shell ```shell
curl -X PATCH -H "Content-Type: application/sparql-update" \ curl -X PATCH -H "Content-Type: application/sparql-update" \

View File

@ -8,7 +8,7 @@ Steps to follow:
* Verify if there are issues when upgrading an existing installation to the new version. * Verify if there are issues when upgrading an existing installation to the new version.
* Can the data still be accessed? * Can the data still be accessed?
* Does authentication still work? * Does authentication still work?
* Is there an issue upgrading the recipes at <https://github.com/CommunitySolidServer/recipes> * Is there an issue upgrading any of the dependent repositories (see below for links)?
* None of the above has to be blocking per se, but should be noted in the release notes if relevant. * None of the above has to be blocking per se, but should be noted in the release notes if relevant.
* Verify that the RELEASE_NOTES.md are correct. * Verify that the RELEASE_NOTES.md are correct.
* `npm run release -- -r major` or `npx standard-version -r major` * `npm run release -- -r major` or `npx standard-version -r major`
@ -25,9 +25,12 @@ Steps to follow:
* Merge `versions/x.0.0` into `main` and push. * Merge `versions/x.0.0` into `main` and push.
* Do a GitHub release. * Do a GitHub release.
* `npm publish` * `npm publish`
* Check if there is a `next` tag that needs to be replaced.
* Rename the `versions/x.0.0` branch to the next version. * Rename the `versions/x.0.0` branch to the next version.
* Update `.github/workflows/schedule.yml` and `.github/dependabot.yml` to point at the new branch. * Update `.github/workflows/schedule.yml` and `.github/dependabot.yml` to point at the new branch.
* Potentially upgrade the recipes at <https://github.com/CommunitySolidServer/recipes> * Potentially upgrade dependent repositories:
* Recipes at <https://github.com/CommunitySolidServer/recipes/>
* Tutorials at <https://github.com/CommunitySolidServer/tutorials/>
Changes when doing a pre-release of a major version: Changes when doing a pre-release of a major version:

View File

@ -27,7 +27,7 @@ For example, to set up a pod without registering the generated WebID with the Id
"podName": "example", "podName": "example",
"email": "hello@example.com", "email": "hello@example.com",
"password": "abc123", "password": "abc123",
"webId": "https://pod.inrupt.com/example/profile/card#me", "webId": "https://id.inrupt.com/example",
"register": false "register": false
} }
] ]

16185
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -89,46 +89,47 @@
"@comunica/query-sparql": "^2.2.1", "@comunica/query-sparql": "^2.2.1",
"@rdfjs/types": "^1.1.0", "@rdfjs/types": "^1.1.0",
"@solid/access-token-verifier": "^2.0.3", "@solid/access-token-verifier": "^2.0.3",
"@types/async-lock": "^1.1.3", "@types/async-lock": "^1.1.5",
"@types/bcrypt": "^5.0.0", "@types/bcryptjs": "^2.4.2",
"@types/cors": "^2.8.12", "@types/cors": "^2.8.12",
"@types/ejs": "^3.1.1",
"@types/end-of-stream": "^1.4.1", "@types/end-of-stream": "^1.4.1",
"@types/fs-extra": "^9.0.13", "@types/fs-extra": "^9.0.13",
"@types/lodash.orderby": "^4.6.6", "@types/lodash.orderby": "^4.6.7",
"@types/marked": "^4.0.2", "@types/marked": "^4.0.3",
"@types/mime-types": "^2.1.1", "@types/mime-types": "^2.1.1",
"@types/n3": "^1.10.4", "@types/n3": "^1.10.4",
"@types/node": "^14.18.0", "@types/node": "^14.18.23",
"@types/nodemailer": "^6.4.4", "@types/nodemailer": "^6.4.4",
"@types/oidc-provider": "^7.8.1", "@types/oidc-provider": "^7.11.1",
"@types/proper-lockfile": "^4.1.2", "@types/proper-lockfile": "^4.1.2",
"@types/pump": "^1.1.1", "@types/pump": "^1.1.1",
"@types/punycode": "^2.1.0", "@types/punycode": "^2.1.0",
"@types/sparqljs": "^3.1.3", "@types/sparqljs": "^3.1.3",
"@types/url-join": "^4.0.1", "@types/url-join": "^4.0.1",
"@types/uuid": "^8.3.4", "@types/uuid": "^8.3.4",
"@types/ws": "^8.2.2", "@types/ws": "^8.5.3",
"@types/yargs": "^17.0.8", "@types/yargs": "^17.0.10",
"arrayify-stream": "^2.0.0", "arrayify-stream": "^2.0.0",
"async-lock": "^1.3.0", "async-lock": "^1.3.2",
"bcrypt": "^5.0.1", "bcryptjs": "^2.4.3",
"componentsjs": "^5.2.0", "componentsjs": "^5.2.0",
"cors": "^2.8.5", "cors": "^2.8.5",
"cross-fetch": "^3.1.5", "cross-fetch": "^3.1.5",
"ejs": "^3.1.6", "ejs": "^3.1.8",
"end-of-stream": "^1.4.4", "end-of-stream": "^1.4.4",
"escape-string-regexp": "^4.0.0", "escape-string-regexp": "^4.0.0",
"fetch-sparql-endpoint": "^3.0.0", "fetch-sparql-endpoint": "^3.0.1",
"fs-extra": "^10.0.0", "fs-extra": "^10.1.0",
"handlebars": "^4.7.7", "handlebars": "^4.7.7",
"ioredis": "^5.0.4", "ioredis": "^5.2.2",
"jose": "^4.4.0", "jose": "^4.8.3",
"jsonld-context-parser": "^2.1.5", "jsonld-context-parser": "^2.1.5",
"lodash.orderby": "^4.6.0", "lodash.orderby": "^4.6.0",
"marked": "^4.0.12", "marked": "^4.0.18",
"mime-types": "^2.1.34", "mime-types": "^2.1.35",
"n3": "^1.16.0", "n3": "^1.16.2",
"nodemailer": "^6.7.2", "nodemailer": "^6.7.7",
"oidc-provider": "7.10.6", "oidc-provider": "7.10.6",
"proper-lockfile": "^4.1.2", "proper-lockfile": "^4.1.2",
"pump": "^3.0.0", "pump": "^3.0.0",
@ -136,33 +137,32 @@
"rdf-dereference": "^2.0.0", "rdf-dereference": "^2.0.0",
"rdf-parse": "^2.1.0", "rdf-parse": "^2.1.0",
"rdf-serialize": "^2.0.0", "rdf-serialize": "^2.0.0",
"rdf-terms": "^1.7.1", "rdf-terms": "^1.9.0",
"sparqlalgebrajs": "^4.0.2", "sparqlalgebrajs": "^4.0.3",
"sparqljs": "^3.5.1", "sparqljs": "^3.5.2",
"url-join": "^4.0.1", "url-join": "^4.0.1",
"uuid": "^8.3.2", "uuid": "^8.3.2",
"winston": "^3.5.1", "winston": "^3.8.1",
"winston-transport": "^4.4.2", "winston-transport": "^4.5.0",
"ws": "^8.4.2", "ws": "^8.8.1",
"yargs": "^17.3.1" "yargs": "^17.5.1"
}, },
"devDependencies": { "devDependencies": {
"@commitlint/cli": "^17.0.0", "@commitlint/cli": "^17.0.3",
"@commitlint/config-conventional": "^17.0.0", "@commitlint/config-conventional": "^17.0.3",
"@inrupt/solid-client-authn-core": "^1.11.5", "@inrupt/solid-client-authn-core": "^1.12.2",
"@inrupt/solid-client-authn-node": "^1.11.5", "@inrupt/solid-client-authn-node": "^1.12.2",
"@microsoft/tsdoc-config": "^0.15.2", "@microsoft/tsdoc-config": "^0.16.1",
"@tsconfig/node14": "^1.0.1", "@tsconfig/node14": "^1.0.1",
"@types/cheerio": "^0.22.30", "@types/cheerio": "^0.22.31",
"@types/ejs": "^3.1.0", "@types/jest": "^27.5.2",
"@types/jest": "^27.4.0",
"@types/set-cookie-parser": "^2.4.2", "@types/set-cookie-parser": "^2.4.2",
"@types/supertest": "^2.0.11", "@types/supertest": "^2.0.12",
"@typescript-eslint/eslint-plugin": "^5.3.0", "@typescript-eslint/eslint-plugin": "^5.3.0",
"@typescript-eslint/parser": "^5.3.0", "@typescript-eslint/parser": "^5.3.0",
"cheerio": "^1.0.0-rc.10", "cheerio": "^1.0.0-rc.12",
"componentsjs-generator": "^3.0.3", "componentsjs-generator": "^3.0.3",
"eslint": "^8.8.0", "eslint": "^8.21.0",
"eslint-config-es": "4.1.0", "eslint-config-es": "4.1.0",
"eslint-import-resolver-typescript": "^3.2.5", "eslint-import-resolver-typescript": "^3.2.5",
"eslint-plugin-eslint-comments": "^3.2.0", "eslint-plugin-eslint-comments": "^3.2.0",
@ -172,17 +172,17 @@
"eslint-plugin-unicorn": "^37.0.1", "eslint-plugin-unicorn": "^37.0.1",
"eslint-plugin-unused-imports": "^2.0.0", "eslint-plugin-unused-imports": "^2.0.0",
"husky": "^4.3.8", "husky": "^4.3.8",
"jest": "^27.4.7", "jest": "^27.5.1",
"jest-rdf": "^1.7.0", "jest-rdf": "^1.7.0",
"node-mocks-http": "^1.11.0", "node-mocks-http": "^1.11.0",
"nodemon": "^2.0.15", "nodemon": "^2.0.19",
"set-cookie-parser": "^2.4.8", "set-cookie-parser": "^2.5.1",
"simple-git": "^3.7.1", "simple-git": "^3.11.0",
"standard-version": "^9.3.2", "standard-version": "^9.5.0",
"supertest": "^6.2.2", "supertest": "^6.2.4",
"ts-jest": "^27.1.3", "ts-jest": "^27.1.5",
"ts-node": "^10.7.0", "ts-node": "^10.9.1",
"typedoc": "^0.22.11", "typedoc": "^0.23.10",
"typescript": "^4.5.5" "typescript": "^4.7.4"
} }
} }

View File

@ -36,7 +36,8 @@ export class BasicResponseWriter extends ResponseWriter {
if (input.result.data) { if (input.result.data) {
const pipe = pipeSafely(input.result.data, input.response); const pipe = pipeSafely(input.result.data, input.response);
pipe.on('error', (error): void => { pipe.on('error', (error): void => {
this.logger.error(`Writing to HttpResponse failed with message ${error.message}`); this.logger.error(`Aborting streaming response because of server error; headers already sent.`);
this.logger.error(`Response error: ${error.message}`);
}); });
} else { } else {
// If there is input data the response will end once the input stream ends // If there is input data the response will end once the input stream ends

View File

@ -1,5 +1,5 @@
import assert from 'assert'; import assert from 'assert';
import { hash, compare } from 'bcrypt'; import { hash, compare } from 'bcryptjs';
import { v4 } from 'uuid'; import { v4 } from 'uuid';
import type { ExpiringStorage } from '../../../../storage/keyvalue/ExpiringStorage'; import type { ExpiringStorage } from '../../../../storage/keyvalue/ExpiringStorage';
import type { KeyValueStorage } from '../../../../storage/keyvalue/KeyValueStorage'; import type { KeyValueStorage } from '../../../../storage/keyvalue/KeyValueStorage';

View File

@ -26,6 +26,8 @@ const CORE_CLI_PARAMETERS = {
mainModulePath: { type: 'string', alias: 'm', requiresArg: true }, mainModulePath: { type: 'string', alias: 'm', requiresArg: true },
} as const; } as const;
const ENV_VAR_PREFIX = 'CSS';
/** /**
* A class that can be used to instantiate and start a server based on a Component.js configuration. * A class that can be used to instantiate and start a server based on a Component.js configuration.
*/ */
@ -137,7 +139,9 @@ export class AppRunner {
.usage('node ./bin/server.js [args]') .usage('node ./bin/server.js [args]')
.options(CORE_CLI_PARAMETERS) .options(CORE_CLI_PARAMETERS)
// We disable help here as it would only show the core parameters // We disable help here as it would only show the core parameters
.help(false); .help(false)
// We also read from environment variables
.env(ENV_VAR_PREFIX);
const params = await yargv.parse(); const params = await yargv.parse();

View File

@ -64,7 +64,11 @@ export class BaseHttpServerFactory implements HttpServerFactory {
async(request: IncomingMessage, response: ServerResponse): Promise<void> => { async(request: IncomingMessage, response: ServerResponse): Promise<void> => {
try { try {
this.logger.info(`Received ${request.method} request for ${request.url}`); this.logger.info(`Received ${request.method} request for ${request.url}`);
await this.handler.handleSafe({ request: guardStream(request), response }); const guardedRequest = guardStream(request);
guardedRequest.on('error', (error): void => {
this.logger.error(`Request error: ${error.message}`);
});
await this.handler.handleSafe({ request: guardedRequest, response });
} catch (error: unknown) { } catch (error: unknown) {
let errMsg: string; let errMsg: string;
if (!isError(error)) { if (!isError(error)) {

View File

@ -8,7 +8,8 @@ const guardedTimeout = Symbol('guardedTimeout');
// Private fields for guarded streams // Private fields for guarded streams
class Guard { class Guard {
private [guardedErrors]: Error[]; // Workaround for the fact that we don't initialize this variable as expected
declare private [guardedErrors]: Error[];
private [guardedTimeout]?: NodeJS.Timeout; private [guardedTimeout]?: NodeJS.Timeout;
} }
@ -20,7 +21,7 @@ class Guard {
export type Guarded<T extends NodeJS.EventEmitter = NodeJS.EventEmitter> = T & Guard; export type Guarded<T extends NodeJS.EventEmitter = NodeJS.EventEmitter> = T & Guard;
/** /**
* Determines whether the stream is guarded from emitting errors. * Determines whether the stream is guarded against emitting errors.
*/ */
export function isGuarded<T extends NodeJS.EventEmitter>(stream: T): stream is Guarded<T> { export function isGuarded<T extends NodeJS.EventEmitter>(stream: T): stream is Guarded<T> {
return typeof (stream as any)[guardedErrors] === 'object'; return typeof (stream as any)[guardedErrors] === 'object';

View File

@ -489,7 +489,7 @@ describe('AppRunner', (): void => {
// Check logLevel to be set to debug instead of default `info` // Check logLevel to be set to debug instead of default `info`
expect(ComponentsManager.build).toHaveBeenCalledWith({ expect(ComponentsManager.build).toHaveBeenCalledWith({
dumpErrorState: true, dumpErrorState: true,
logLevel: 'info', logLevel: 'debug',
mainModulePath: joinFilePath(__dirname, '../../../'), mainModulePath: joinFilePath(__dirname, '../../../'),
typeChecking: false, typeChecking: false,
}); });
@ -502,7 +502,6 @@ describe('AppRunner', (): void => {
expect(cliExtractor.handleSafe).toHaveBeenCalledWith([ 'node', 'script' ]); expect(cliExtractor.handleSafe).toHaveBeenCalledWith([ 'node', 'script' ]);
expect(shorthandResolver.handleSafe).toHaveBeenCalledTimes(1); expect(shorthandResolver.handleSafe).toHaveBeenCalledTimes(1);
expect(shorthandResolver.handleSafe).toHaveBeenCalledWith(defaultParameters); expect(shorthandResolver.handleSafe).toHaveBeenCalledWith(defaultParameters);
expect(manager.instantiate).toHaveBeenNthCalledWith(1, 'urn:solid-server-app-setup:default:CliResolver', {});
expect(manager.instantiate).toHaveBeenNthCalledWith(2, expect(manager.instantiate).toHaveBeenNthCalledWith(2,
'urn:solid-server:default:App', 'urn:solid-server:default:App',
{ variables: defaultVariables }); { variables: defaultVariables });

View File

@ -90,6 +90,15 @@ describe('A BaseHttpServerFactory', (): void => {
const res = await request(server).get('/').expect(500); const res = await request(server).get('/').expect(500);
expect(res.text).toContain('Unknown error: apple.'); expect(res.text).toContain('Unknown error: apple.');
}); });
it('can handle errors on the HttpResponse.', async(): Promise<void> => {
// This just makes sure the logging line is covered.
// Actually destroying the request to trigger an error causes issues for supertest
handler.handleSafe.mockImplementationOnce(async(input): Promise<void> => {
input.request.emit('error', new Error('bad request'));
});
await request(server).get('/').expect(404);
});
}); });
describe('with showStackTrace enabled', (): void => { describe('with showStackTrace enabled', (): void => {

View File

@ -33,7 +33,7 @@ describe('A LockingResourceStore', (): void => {
const readable = guardedStreamFrom([ 1, 2, 3 ]); const readable = guardedStreamFrom([ 1, 2, 3 ]);
const { destroy } = readable; const { destroy } = readable;
readable.destroy = jest.fn((error): void => destroy.call(readable, error)); readable.destroy = jest.fn((error): any => destroy.call(readable, error));
source = { source = {
getRepresentation: jest.fn((): any => addOrder('getRepresentation', { data: readable } as Representation)), getRepresentation: jest.fn((): any => addOrder('getRepresentation', { data: readable } as Representation)),
addResource: jest.fn((): any => addOrder('addResource')), addResource: jest.fn((): any => addOrder('addResource')),