Merge branch 'main' into versions/next-major

This commit is contained in:
Joachim Van Herwegen
2024-01-12 10:40:21 +01:00
15 changed files with 237 additions and 208 deletions

View File

@@ -3,6 +3,35 @@
All notable changes to this project will be documented in this file.
## [7.0.3](https://github.com/CommunitySolidServer/CommunitySolidServer/compare/v7.0.2...v7.0.3) (2024-01-05)
### Features
* Support default mainModulePath when creating App ([c6ec45c](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/c6ec45c7c0fb91a1c1365e9a0139e4fdaf8838d6))
### Fixes
* Encode WebID ownership tokens ([277a0d0](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/277a0d0ab724074ed96940836ecc973a8533c538))
* Fix pod base URL in README template ([4e7929f](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/4e7929f6d2b72fbb0a03e8f6e64955239f41c837))
* Only require append when creating with PUT ([a0b7ee4](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/a0b7ee42f3a39cdd8fe2dbf1470e53f57ea62aba))
### Chores
* Remove Docker arm builds ([648ce1f](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/648ce1fba8737dc7a008ff987de161e5902f9d09))
* Update linting dependency ([3a9b0d6](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/3a9b0d69f01d6f0490983eda4ff8000798e10dcc))
### Documentation
* Explain how to use AppRunner to start a server instance ([716c3c3](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/716c3c308933a10382d6726a70b5b77a62cfb787))
* Explain that users need to log in for client credentials ([dca71bc](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/dca71bc5b82a9790d861babdcb1dd231c99dd042))
* Fix links ([1f88864](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/1f888645d6619e253082f4bf0ed20e7ae4e4c38b))
* Describe server feature set ([c64a1a2](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/c64a1a241ddd975f22eb223d545c938dfc8cb63c))
* Fix Typo `is -> if` ([355f7dd](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/355f7dd1c7b9be14c3e243acb5c4634f3a800442))
### Testing
* Run tests on Node 21 ([8f74fc8](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/8f74fc82ad8a611bf96c293748bc5c01c859cdeb))
## [7.0.2](https://github.com/CommunitySolidServer/CommunitySolidServer/compare/v7.0.1...v7.0.2) (2023-11-20)
### Features

View File

@@ -1,22 +1,24 @@
# Releasing a new major version
# Releasing a new version
This is only relevant if you are a developer with push access responsible for doing a new release.
Steps to follow:
* Merge `main` into `versions/next-major`.
* **Major** releases only:
* Merge `main` into `versions/next-major`.
* Verify if there are issues when upgrading an existing installation to the new version.
* Can the data still be accessed?
* Does authentication still work?
* 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.
* Verify that the `RELEASE_NOTES.md` are correct.
* `npm run release -- -r major`
* Automatically updates Components.js references to the new version.
* **Major** and **Minor** releases:
* Verify that the `RELEASE_NOTES.md` are correct.
* `npm run release -- -r major/minor/patch`
* Automatically updates Components.js references to the new version in case of a major release.
Committed with `chore(release): Update configs to vx.0.0`.
* Updates the `package.json`, and generates the new entries in `CHANGELOG.md`.
Commits with `chore(release): Release version vx.0.0 of the npm package`
* Optionally run `npx commit-and-tag-version -r major --dry-run` to preview the commands that will be run
Commits with `chore(release): Release version vx.y.z of the npm package`
* Optionally run `npx commit-and-tag-version -r major/minor/patch --dry-run` to preview the commands that will be run
and the changes to `CHANGELOG.md`.
* The `postrelease` script will now prompt you to manually edit the `CHANGELOG.md`.
* All entries are added in separate sections of the new release according to their commit prefixes.
@@ -24,11 +26,12 @@ Steps to follow:
Documentation can be removed.
* Press any key in your terminal when your changes are ready.
* The `postrelease` script will amend the release commit, create an annotated tag and push changes to origin.
* Merge `versions/next-major` into `main` and push.
* **Major** releases only:
* Merge `versions/next-major` into `main` and push.
* Do a GitHub release.
* `npm publish`
* `npm dist-tag add @solid/community-server@x.0.0 next`
* Rename the `versions/x.0.0` branch to the next version.
* If there is no **pre-release** of a higher version:
* `npm dist-tag add @solid/community-server@x.y.z next`
* Potentially upgrade dependent repositories:
* Recipes at <https://github.com/CommunitySolidServer/recipes/>
* Tutorials at <https://github.com/CommunitySolidServer/tutorials/>
@@ -40,9 +43,3 @@ Steps to follow:
* Version with `npm run release -- -r major --prerelease alpha`
* Do not merge `versions/next-major` into `main`.
* Publish with `npm publish --tag next`.
* Do not update the branch or anything related.
## Changes when doing a minor release
* Version with `npm run release -- -r minor`
* Do not merge `versions/next-major` into `main`.

View File

@@ -100,11 +100,10 @@ Once you have an Access token, you can use it for authenticated requests until i
```ts
import { buildAuthenticatedFetch } from '@inrupt/solid-client-authn-core';
import fetch from 'node-fetch';
// The DPoP key needs to be the same key as the one used in the previous step.
// The Access token is the one generated in the previous step.
const authFetch = await buildAuthenticatedFetch(fetch, accessToken, { dpopKey });
const authFetch = await buildAuthenticatedFetch(accessToken, { dpopKey });
// authFetch can now be used as a standard fetch function that will authenticate as your WebID.
// This request will do a simple GET for example.
const response = await authFetch('http://localhost:3000/private');

View File

@@ -1,6 +1,62 @@
# Configuring the CSS as a development server in another project
It can be useful to use the CSS as local server to develop Solid applications against.
There are several ways to configure and run a server in your project.
Note that starting up the server takes some time so set your timeout high enough if you are using this in your tests.
## Starting the server through code
You can create a server instance in your code, or tests, by calling the `create` function of a new `AppRunner` instance.
The resulting object has `start` and `stop` functions.
The `create` function takes as input an object with 5 optional parameters
which can all be used to define the server configuration.
None of these are mandatory, if you don't think you need one you can probably ignore it.
These are discussed below.
### loaderProperties
These values are specifically to configure how Components.js handles starting the server.
Most of these are generally not going to be relevant,
but here are some of those you might want to change:
* **mainModulePath**: Determines where Components.js will look for components.
Defaults to the folder where the server dependency is installed.
In case you are making a custom component,
this value needs to point to the directory of your project instead.
* **logLevel**: The logging level of Components.js when building. Defaults to `warn`.
### config
The file path of the Components.js configuration that needs to be used.
This can also be an array of configuration paths.
The `@css:` prefix can be used for file paths to generate a path
relative to the folder where the server dependency is installed.
Defaults to `@css:config/default.json`.
### variableBindings
Allows you to assign values to the variables that are used in a Components.js configuration.
For example, `{ 'urn:solid-server:default:variable:port': 3000 }` tells the server to use port 3000.
### shorthand
Allows you to assign values to parameters similarly as if you would call the server from the CLI.
For example, `{ port: 3000 }` tells the server to use port 3000.
This is very similar to the `variableBindings` field mentioned above,
as CLI parameters all get translated into Components.js variables,
although some get transformed before being put into a variable.
If you are not sure which one to use, `shorthand` is the safer choice to use.
### argv
If used, this parameter expects a string array.
Here you can provide the raw dump of CLI values,
so you don't have to parse them yourself,
should this be useful for your application.
## Configuring the server in `package.json`
As an alternative to using CLI arguments, or environment variables, the CSS can be configured in the `package.json` as follows:
```json
@@ -24,7 +80,7 @@ As an alternative to using CLI arguments, or environment variables, the CSS can
```
These parameters will then be used when the `community-solid-server`
command is executed as an npm script (as shown in the example above).
command is executed as an `npm` script (as shown in the example above).
Or whenever the `community-solid-server` command is executed in the same
folder as the `package.json`.

215
package-lock.json generated
View File

@@ -1,19 +1,19 @@
{
"name": "@solid/community-server",
"version": "7.0.2",
"version": "7.0.3",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@solid/community-server",
"version": "7.0.2",
"version": "7.0.3",
"license": "MIT",
"dependencies": {
"@comunica/context-entries": "^2.8.2",
"@comunica/query-sparql": "^2.9.0",
"@rdfjs/types": "^1.1.0",
"@solid/access-control-policy": "^0.1.3",
"@solid/access-token-verifier": "^2.0.5",
"@solid/access-token-verifier": "^2.1.0",
"@types/async-lock": "^1.4.0",
"@types/bcryptjs": "^2.4.4",
"@types/cookie": "^0.5.2",
@@ -85,8 +85,8 @@
"@antfu/eslint-config": "2.3.4",
"@commitlint/cli": "^18.2.0",
"@commitlint/config-conventional": "^18.0.0",
"@inrupt/solid-client-authn-core": "^1.17.3",
"@inrupt/solid-client-authn-node": "^1.17.3",
"@inrupt/solid-client-authn-core": "^2.0.0",
"@inrupt/solid-client-authn-node": "^2.0.0",
"@tsconfig/node18": "^18.2.2",
"@types/jest": "^29.5.5",
"@types/set-cookie-parser": "^2.4.4",
@@ -4275,15 +4275,6 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
"node_modules/@fastify/busboy": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.0.0.tgz",
"integrity": "sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ==",
"dev": true,
"engines": {
"node": ">=14"
}
},
"node_modules/@humanwhocodes/config-array": {
"version": "0.11.13",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz",
@@ -4330,62 +4321,32 @@
}
},
"node_modules/@inrupt/solid-client-authn-core": {
"version": "1.17.3",
"resolved": "https://registry.npmjs.org/@inrupt/solid-client-authn-core/-/solid-client-authn-core-1.17.3.tgz",
"integrity": "sha512-UuHLFChd+0155EwYgdQJN6mP7fpnT4UFnWZT0+gDAbudUkUI0dKp6HKisWkJAK+KY1wDZ5HCQmCKBpjtiPXuyA==",
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@inrupt/solid-client-authn-core/-/solid-client-authn-core-2.0.0.tgz",
"integrity": "sha512-qM+E9I5u2DFlsfyoXossx8w0vKv8p+rXH98K9RUauJImpygQ3I3Ra6hSB2bwA1PdPQd5ttNg236oKe1sTT6Hqw==",
"dev": true,
"dependencies": {
"@inrupt/universal-fetch": "^1.0.1",
"events": "^3.3.0",
"jose": "^4.14.6",
"jose": "^5.1.3",
"uuid": "^9.0.1"
},
"engines": {
"node": "^16.0.0 || ^18.0.0 || ^20.0.0"
}
},
"node_modules/@inrupt/solid-client-authn-core/node_modules/jose": {
"version": "4.15.4",
"resolved": "https://registry.npmjs.org/jose/-/jose-4.15.4.tgz",
"integrity": "sha512-W+oqK4H+r5sITxfxpSU+MMdr/YSWGvgZMQDIsNoBDGGy4i7GBPTtvFKibQzW06n3U3TqHjhvBJsirShsEJ6eeQ==",
"dev": true,
"funding": {
"url": "https://github.com/sponsors/panva"
"node": "^18.0.0 || ^20.0.0"
}
},
"node_modules/@inrupt/solid-client-authn-node": {
"version": "1.17.3",
"resolved": "https://registry.npmjs.org/@inrupt/solid-client-authn-node/-/solid-client-authn-node-1.17.3.tgz",
"integrity": "sha512-3lmSh7VNBUVFlBQZBQAtqyVz2B0bRTP8Zm4mkIxG519b2oJwLQtttP/cqQU1WutqADjLLB7Xx4zQTnf2E7yZkw==",
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@inrupt/solid-client-authn-node/-/solid-client-authn-node-2.0.0.tgz",
"integrity": "sha512-S1vGRodX0MSAKR3B6tm4qUvMhGv0sMcFjYyhVil7isoRI/7ei5QTpm+081RTWe6/cv4WI6UiHER3YIG15uwhhg==",
"dev": true,
"dependencies": {
"@inrupt/solid-client-authn-core": "^1.17.3",
"@inrupt/universal-fetch": "^1.0.1",
"jose": "^4.14.6",
"openid-client": "~5.5.0",
"@inrupt/solid-client-authn-core": "^2.0.0",
"jose": "^5.1.3",
"openid-client": "~5.6.1",
"uuid": "^9.0.1"
},
"engines": {
"node": "^16.0.0 || ^18.0.0 || ^20.0.0"
}
},
"node_modules/@inrupt/solid-client-authn-node/node_modules/jose": {
"version": "4.15.4",
"resolved": "https://registry.npmjs.org/jose/-/jose-4.15.4.tgz",
"integrity": "sha512-W+oqK4H+r5sITxfxpSU+MMdr/YSWGvgZMQDIsNoBDGGy4i7GBPTtvFKibQzW06n3U3TqHjhvBJsirShsEJ6eeQ==",
"dev": true,
"funding": {
"url": "https://github.com/sponsors/panva"
}
},
"node_modules/@inrupt/universal-fetch": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@inrupt/universal-fetch/-/universal-fetch-1.0.1.tgz",
"integrity": "sha512-oqbG7jS1fa6hVkjSir+u5Ab3eSbyxFyOjsgjDICL27mAd5z8oImTSETnY2hYbkRaJQYKMBOXhtm7L5/+EbeVJg==",
"dev": true,
"dependencies": {
"node-fetch": "^2.6.7",
"undici": "^5.19.1"
"node": "^18.0.0 || ^20.0.0"
}
},
"node_modules/@ioredis/commands": {
@@ -4970,25 +4931,17 @@
"integrity": "sha512-LTxfN8N5hNBNYfuwJr0nyfxlp2P0+GeK+biCa1FQgIqska3wXpTgYaxjVgsw27mKx4N1FOlaGwG+nXdLnl9ykg=="
},
"node_modules/@solid/access-token-verifier": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/@solid/access-token-verifier/-/access-token-verifier-2.0.5.tgz",
"integrity": "sha512-YsoMmEk7pN6tlCHcDm5iLa9ZYvTYvuk3SX5cz18XW1qYmM46znEGnXz94vm7DIa7DcTLGi9suMw7M5pRs2xOLw==",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@solid/access-token-verifier/-/access-token-verifier-2.1.0.tgz",
"integrity": "sha512-79u92GD1SBTxjYghg2ta6cfoBNZ5ljz/9zE6RmXUypTXW7oI18DTWiSrEjWwI4njW+OMh+4ih+sAR6AkI1IFxg==",
"dependencies": {
"jose": "^4.10.3",
"jose": "^5.1.3",
"lru-cache": "^6.0.0",
"n3": "^1.16.2",
"node-fetch": "^2.6.7",
"n3": "^1.17.1",
"node-fetch": "^2.7.0",
"ts-guards": "^0.5.1"
}
},
"node_modules/@solid/access-token-verifier/node_modules/jose": {
"version": "4.15.4",
"resolved": "https://registry.npmjs.org/jose/-/jose-4.15.4.tgz",
"integrity": "sha512-W+oqK4H+r5sITxfxpSU+MMdr/YSWGvgZMQDIsNoBDGGy4i7GBPTtvFKibQzW06n3U3TqHjhvBJsirShsEJ6eeQ==",
"funding": {
"url": "https://github.com/sponsors/panva"
}
},
"node_modules/@stylistic/eslint-plugin": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-1.5.0.tgz",
@@ -12997,9 +12950,9 @@
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="
},
"node_modules/node-fetch": {
"version": "2.6.12",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz",
"integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==",
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
"dependencies": {
"whatwg-url": "^5.0.0"
},
@@ -13356,12 +13309,12 @@
}
},
"node_modules/openid-client": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.5.0.tgz",
"integrity": "sha512-Y7Xl8BgsrkzWLHkVDYuroM67hi96xITyEDSkmWaGUiNX6CkcXC3XyQGdv5aWZ6dukVKBFVQCADi9gCavOmU14w==",
"version": "5.6.4",
"resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.6.4.tgz",
"integrity": "sha512-T1h3B10BRPKfcObdBklX639tVz+xh34O7GjofqrqiAQdm7eHsQ00ih18x6wuJ/E6FxdtS2u3FmUGPDeEcMwzNA==",
"dev": true,
"dependencies": {
"jose": "^4.14.4",
"jose": "^4.15.4",
"lru-cache": "^6.0.0",
"object-hash": "^2.2.0",
"oidc-token-hash": "^5.0.3"
@@ -15531,18 +15484,6 @@
"integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
"dev": true
},
"node_modules/undici": {
"version": "5.26.3",
"resolved": "https://registry.npmjs.org/undici/-/undici-5.26.3.tgz",
"integrity": "sha512-H7n2zmKEWgOllKkIUkLvFmsJQj062lSm3uA4EYApG8gLuiOM0/go9bIoC3HVaSnfg4xunowDE2i9p8drkXuvDw==",
"dev": true,
"dependencies": {
"@fastify/busboy": "^2.0.0"
},
"engines": {
"node": ">=14.0"
}
},
"node_modules/unist-util-stringify-position": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz",
@@ -19709,12 +19650,6 @@
"dev": true,
"peer": true
},
"@fastify/busboy": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.0.0.tgz",
"integrity": "sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ==",
"dev": true
},
"@humanwhocodes/config-array": {
"version": "0.11.13",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz",
@@ -19748,54 +19683,26 @@
"dev": true
},
"@inrupt/solid-client-authn-core": {
"version": "1.17.3",
"resolved": "https://registry.npmjs.org/@inrupt/solid-client-authn-core/-/solid-client-authn-core-1.17.3.tgz",
"integrity": "sha512-UuHLFChd+0155EwYgdQJN6mP7fpnT4UFnWZT0+gDAbudUkUI0dKp6HKisWkJAK+KY1wDZ5HCQmCKBpjtiPXuyA==",
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@inrupt/solid-client-authn-core/-/solid-client-authn-core-2.0.0.tgz",
"integrity": "sha512-qM+E9I5u2DFlsfyoXossx8w0vKv8p+rXH98K9RUauJImpygQ3I3Ra6hSB2bwA1PdPQd5ttNg236oKe1sTT6Hqw==",
"dev": true,
"requires": {
"@inrupt/universal-fetch": "^1.0.1",
"events": "^3.3.0",
"jose": "^4.14.6",
"jose": "^5.1.3",
"uuid": "^9.0.1"
},
"dependencies": {
"jose": {
"version": "4.15.4",
"resolved": "https://registry.npmjs.org/jose/-/jose-4.15.4.tgz",
"integrity": "sha512-W+oqK4H+r5sITxfxpSU+MMdr/YSWGvgZMQDIsNoBDGGy4i7GBPTtvFKibQzW06n3U3TqHjhvBJsirShsEJ6eeQ==",
"dev": true
}
}
},
"@inrupt/solid-client-authn-node": {
"version": "1.17.3",
"resolved": "https://registry.npmjs.org/@inrupt/solid-client-authn-node/-/solid-client-authn-node-1.17.3.tgz",
"integrity": "sha512-3lmSh7VNBUVFlBQZBQAtqyVz2B0bRTP8Zm4mkIxG519b2oJwLQtttP/cqQU1WutqADjLLB7Xx4zQTnf2E7yZkw==",
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@inrupt/solid-client-authn-node/-/solid-client-authn-node-2.0.0.tgz",
"integrity": "sha512-S1vGRodX0MSAKR3B6tm4qUvMhGv0sMcFjYyhVil7isoRI/7ei5QTpm+081RTWe6/cv4WI6UiHER3YIG15uwhhg==",
"dev": true,
"requires": {
"@inrupt/solid-client-authn-core": "^1.17.3",
"@inrupt/universal-fetch": "^1.0.1",
"jose": "^4.14.6",
"openid-client": "~5.5.0",
"@inrupt/solid-client-authn-core": "^2.0.0",
"jose": "^5.1.3",
"openid-client": "~5.6.1",
"uuid": "^9.0.1"
},
"dependencies": {
"jose": {
"version": "4.15.4",
"resolved": "https://registry.npmjs.org/jose/-/jose-4.15.4.tgz",
"integrity": "sha512-W+oqK4H+r5sITxfxpSU+MMdr/YSWGvgZMQDIsNoBDGGy4i7GBPTtvFKibQzW06n3U3TqHjhvBJsirShsEJ6eeQ==",
"dev": true
}
}
},
"@inrupt/universal-fetch": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@inrupt/universal-fetch/-/universal-fetch-1.0.1.tgz",
"integrity": "sha512-oqbG7jS1fa6hVkjSir+u5Ab3eSbyxFyOjsgjDICL27mAd5z8oImTSETnY2hYbkRaJQYKMBOXhtm7L5/+EbeVJg==",
"dev": true,
"requires": {
"node-fetch": "^2.6.7",
"undici": "^5.19.1"
}
},
"@ioredis/commands": {
@@ -20272,22 +20179,15 @@
"integrity": "sha512-LTxfN8N5hNBNYfuwJr0nyfxlp2P0+GeK+biCa1FQgIqska3wXpTgYaxjVgsw27mKx4N1FOlaGwG+nXdLnl9ykg=="
},
"@solid/access-token-verifier": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/@solid/access-token-verifier/-/access-token-verifier-2.0.5.tgz",
"integrity": "sha512-YsoMmEk7pN6tlCHcDm5iLa9ZYvTYvuk3SX5cz18XW1qYmM46znEGnXz94vm7DIa7DcTLGi9suMw7M5pRs2xOLw==",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@solid/access-token-verifier/-/access-token-verifier-2.1.0.tgz",
"integrity": "sha512-79u92GD1SBTxjYghg2ta6cfoBNZ5ljz/9zE6RmXUypTXW7oI18DTWiSrEjWwI4njW+OMh+4ih+sAR6AkI1IFxg==",
"requires": {
"jose": "^4.10.3",
"jose": "^5.1.3",
"lru-cache": "^6.0.0",
"n3": "^1.16.2",
"node-fetch": "^2.6.7",
"n3": "^1.17.1",
"node-fetch": "^2.7.0",
"ts-guards": "^0.5.1"
},
"dependencies": {
"jose": {
"version": "4.15.4",
"resolved": "https://registry.npmjs.org/jose/-/jose-4.15.4.tgz",
"integrity": "sha512-W+oqK4H+r5sITxfxpSU+MMdr/YSWGvgZMQDIsNoBDGGy4i7GBPTtvFKibQzW06n3U3TqHjhvBJsirShsEJ6eeQ=="
}
}
},
"@stylistic/eslint-plugin": {
@@ -26253,9 +26153,9 @@
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="
},
"node-fetch": {
"version": "2.6.12",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz",
"integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==",
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
"requires": {
"whatwg-url": "^5.0.0"
},
@@ -26521,12 +26421,12 @@
"dev": true
},
"openid-client": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.5.0.tgz",
"integrity": "sha512-Y7Xl8BgsrkzWLHkVDYuroM67hi96xITyEDSkmWaGUiNX6CkcXC3XyQGdv5aWZ6dukVKBFVQCADi9gCavOmU14w==",
"version": "5.6.4",
"resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.6.4.tgz",
"integrity": "sha512-T1h3B10BRPKfcObdBklX639tVz+xh34O7GjofqrqiAQdm7eHsQ00ih18x6wuJ/E6FxdtS2u3FmUGPDeEcMwzNA==",
"dev": true,
"requires": {
"jose": "^4.14.4",
"jose": "^4.15.4",
"lru-cache": "^6.0.0",
"object-hash": "^2.2.0",
"oidc-token-hash": "^5.0.3"
@@ -28199,15 +28099,6 @@
"integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
"dev": true
},
"undici": {
"version": "5.26.3",
"resolved": "https://registry.npmjs.org/undici/-/undici-5.26.3.tgz",
"integrity": "sha512-H7n2zmKEWgOllKkIUkLvFmsJQj062lSm3uA4EYApG8gLuiOM0/go9bIoC3HVaSnfg4xunowDE2i9p8drkXuvDw==",
"dev": true,
"requires": {
"@fastify/busboy": "^2.0.0"
}
},
"unist-util-stringify-position": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz",

View File

@@ -1,6 +1,6 @@
{
"name": "@solid/community-server",
"version": "7.0.2",
"version": "7.0.3",
"description": "Community Solid Server: an open and modular implementation of the Solid specifications",
"license": "MIT",
"homepage": "https://github.com/CommunitySolidServer/CommunitySolidServer#readme",
@@ -77,7 +77,7 @@
"@comunica/query-sparql": "^2.9.0",
"@rdfjs/types": "^1.1.0",
"@solid/access-control-policy": "^0.1.3",
"@solid/access-token-verifier": "^2.0.5",
"@solid/access-token-verifier": "^2.1.0",
"@types/async-lock": "^1.4.0",
"@types/bcryptjs": "^2.4.4",
"@types/cookie": "^0.5.2",
@@ -146,8 +146,8 @@
"@antfu/eslint-config": "2.3.4",
"@commitlint/cli": "^18.2.0",
"@commitlint/config-conventional": "^18.0.0",
"@inrupt/solid-client-authn-core": "^1.17.3",
"@inrupt/solid-client-authn-node": "^1.17.3",
"@inrupt/solid-client-authn-core": "^2.0.0",
"@inrupt/solid-client-authn-node": "^2.0.0",
"@tsconfig/node18": "^18.2.2",
"@types/jest": "^29.5.5",
"@types/set-cookie-parser": "^2.4.4",

View File

@@ -39,11 +39,13 @@ export class MethodModesExtractor extends ModesExtractor {
if (READ_METHODS.has(method)) {
requiredModes.add(target, AccessMode.read);
}
// Setting a resource's representation requires Write permissions
if (method === 'PUT') {
requiredModes.add(target, AccessMode.write);
// …and, if the resource does not exist yet, Create permissions are required as well
if (!await this.resourceSet.hasResource(target)) {
if (await this.resourceSet.hasResource(target)) {
// Replacing a resource's representation with PUT requires Write permissions
requiredModes.add(target, AccessMode.write);
} else {
// ... while creating a new resource with PUT requires Append and Create permissions.
requiredModes.add(target, AccessMode.append);
requiredModes.add(target, AccessMode.create);
}
}

View File

@@ -51,7 +51,7 @@ export class TokenOwnershipValidator extends OwnershipValidator {
* Creates a key to use with the token storage.
*/
private getTokenKey(webId: string): string {
return `ownershipToken${webId}`;
return encodeURIComponent(webId);
}
/**

View File

@@ -36,13 +36,17 @@ const ENV_VAR_PREFIX = 'CSS';
export interface AppRunnerInput {
/**
* Properties that will be used when building the Components.js manager.
* Sets `typeChecking` to false by default as the server components will result in errors otherwise.
* Default values:
* - `typeChecking`: `false`, as the server components would otherwise error.
* - `mainModulePath`: `@css:`, which resolves to the directory of the CSS package.
* This is useful for packages that depend on the CSS
* but do not create any new modules themselves.
*/
loaderProperties: IComponentsManagerBuilderOptions<App>;
loaderProperties?: Partial<IComponentsManagerBuilderOptions<App>>;
/**
* Path to the server config file(s).
* Path to the server config file(s). Defaults to `@css:config/default.json`.
*/
config: string | string[];
config?: string | string[];
/**
* Values to apply to the Components.js variables.
* These are the variables CLI values will be converted to.
@@ -87,14 +91,19 @@ export class AppRunner {
*
* @param input - All values necessary to configure the server.
*/
public async create(input: AppRunnerInput): Promise<App> {
public async create(input: AppRunnerInput = {}): Promise<App> {
const loaderProperties = {
typeChecking: false,
mainModulePath: '@css:',
dumpErrorState: false,
...input.loaderProperties,
};
// Expand mainModulePath as needed
loaderProperties.mainModulePath = resolveAssetPath(loaderProperties.mainModulePath);
// Potentially expand file paths as needed
const configs = (Array.isArray(input.config) ? input.config : [ input.config ]).map(resolveAssetPath);
// Potentially expand config paths as needed
let configs = input.config ?? [ '@css:config/default.json' ];
configs = (Array.isArray(configs) ? configs : [ configs ]).map(resolveAssetPath);
let componentsManager: ComponentsManager<any>;
try {
@@ -178,8 +187,8 @@ export class AppRunner {
const params = await yargv.parse();
const loaderProperties: IComponentsManagerBuilderOptions<App> = {
mainModulePath: resolveAssetPath(params.mainModulePath),
const loaderProperties: AppRunnerInput['loaderProperties'] = {
mainModulePath: params.mainModulePath,
logLevel: params.loggingLevel,
};

View File

@@ -14,7 +14,7 @@ The easiest way to interact with pods
is through Solid apps.
<br>
For example,
you can open your pod in [Databrowser](https://solidos.github.io/mashlib/dist/browse.html?uri={{podBaseUrl}}).
you can open your pod in [Databrowser](https://solidos.github.io/mashlib/dist/browse.html?uri={{base.path}}).
## Accessing your account
To keep track of your pods, webIDs and any other resources,

View File

@@ -6,15 +6,27 @@ import type { ResourceStore } from '../../src/storage/ResourceStore';
import { APPLICATION_X_WWW_FORM_URLENCODED } from '../../src/util/ContentTypes';
import { joinUrl } from '../../src/util/PathUtil';
import { getPort } from '../util/Util';
import { getDefaultVariables, getTestConfigPath, instantiateFromConfig } from './Config';
import { getDefaultVariables, getTestConfigPath, getTestFolder, instantiateFromConfig, removeFolder } from './Config';
const port = getPort('Accounts');
const baseUrl = `http://localhost:${port}/`;
const rootFilePath = getTestFolder('Accounts');
const stores: [string, any][] = [
[ 'in-memory storage', {
config: 'memory-pod.json',
teardown: jest.fn(),
}],
[ 'on-disk storage', {
config: 'file-pod.json',
teardown: async(): Promise<void> => removeFolder(rootFilePath),
}],
];
// Don't send actual e-mails
jest.mock('nodemailer');
describe('A server with account management', (): void => {
describe.each(stores)('A server with account management using %s', (name, { config, teardown }): void => {
let app: App;
let store: ResourceStore;
let sendMail: jest.Mock;
@@ -42,8 +54,11 @@ describe('A server with account management', (): void => {
const instances = await instantiateFromConfig(
'urn:solid-server:test:Instances',
getTestConfigPath('memory-pod.json'),
getDefaultVariables(port, baseUrl),
getTestConfigPath(config),
{
...getDefaultVariables(port, baseUrl),
'urn:solid-server:default:variable:rootFilePath': rootFilePath,
},
) as Record<string, any>;
({ app, store } = instances);
await app.start();
@@ -68,6 +83,7 @@ describe('A server with account management', (): void => {
});
afterAll(async(): Promise<void> => {
await teardown();
await app.stop();
});

View File

@@ -392,7 +392,7 @@ describe.each(stores)('A Solid server with IDP using %s', (name, { config, teard
});
it('can use the generated access token to do an authenticated call.', async(): Promise<void> => {
const authFetch = await buildAuthenticatedFetch(fetch, accessToken!, { dpopKey });
const authFetch = await buildAuthenticatedFetch(accessToken!, { dpopKey });
let res = await fetch(container);
expect(res.status).toBe(401);
res = await authFetch(container);

View File

@@ -83,7 +83,7 @@ const table: [string, string, AM[], AM[] | undefined, string, string, number, nu
[ 'PUT', 'C/R', [], [ AM.append ], '', TXT, 401, 401 ],
[ 'PUT', 'C/R', [], [ AM.write ], '', TXT, 205, 401 ],
[ 'PUT', 'C/R', [ AM.read ], undefined, '', TXT, 401, 401 ],
[ 'PUT', 'C/R', [ AM.append ], undefined, '', TXT, 401, 401 ],
[ 'PUT', 'C/R', [ AM.append ], undefined, '', TXT, 401, 201 ],
[ 'PUT', 'C/R', [ AM.write ], undefined, '', TXT, 205, 201 ],
[ 'PUT', 'C/R', [ AM.append ], [ AM.write ], '', TXT, 205, 201 ],

View File

@@ -58,11 +58,11 @@ describe('A MethodModesExtractor', (): void => {
compareMaps(await extractor.handle({ ...operation, method: 'PUT' }), getMap([ AccessMode.write ]));
});
it('requires create for PUT operations if the target does not exist.', async(): Promise<void> => {
it('requires append/create for PUT operations if the target does not exist.', async(): Promise<void> => {
resourceSet.hasResource.mockResolvedValueOnce(false);
compareMaps(
await extractor.handle({ ...operation, method: 'PUT' }),
getMap([ AccessMode.write, AccessMode.create ]),
getMap([ AccessMode.append, AccessMode.create ]),
);
});

View File

@@ -206,6 +206,30 @@ describe('AppRunner', (): void => {
expect(app.clusterManager.isSingleThreaded()).toBeFalsy();
});
it('has several defaults.', async(): Promise<void> => {
const createdApp = await new AppRunner().create();
expect(createdApp).toBe(app);
expect(ComponentsManager.build).toHaveBeenCalledTimes(1);
expect(ComponentsManager.build).toHaveBeenCalledWith({
mainModulePath: joinFilePath(__dirname, '../../../'),
typeChecking: false,
dumpErrorState: false,
});
expect(manager.configRegistry.register).toHaveBeenCalledTimes(1);
expect(manager.configRegistry.register)
.toHaveBeenCalledWith(joinFilePath(__dirname, '/../../../config/default.json'));
expect(manager.instantiate).toHaveBeenCalledTimes(2);
expect(manager.instantiate).toHaveBeenNthCalledWith(1, 'urn:solid-server-app-setup:default:CliResolver', {});
expect(manager.instantiate)
.toHaveBeenNthCalledWith(2, 'urn:solid-server:default:App', { variables: {}});
expect(shorthandResolver.handleSafe).toHaveBeenCalledTimes(1);
expect(shorthandResolver.handleSafe).toHaveBeenLastCalledWith({});
expect(cliExtractor.handleSafe).toHaveBeenCalledTimes(0);
expect(app.start).toHaveBeenCalledTimes(0);
expect(app.clusterManager.isSingleThreaded()).toBeFalsy();
});
it('throws an error if threading issues are detected with 1 class.', async(): Promise<void> => {
listSingleThreadedComponentsMock.mockImplementationOnce((): string[] => [ 'ViolatingClass' ]);
const variables = {
@@ -344,6 +368,7 @@ describe('AppRunner', (): void => {
logLevel: 'info',
mainModulePath: joinFilePath(__dirname, '../../../'),
typeChecking: false,
dumpErrorState: false,
});
expect(manager.configRegistry.register).toHaveBeenCalledTimes(1);
expect(manager.configRegistry.register)
@@ -375,6 +400,7 @@ describe('AppRunner', (): void => {
logLevel: 'info',
mainModulePath: joinFilePath(__dirname, '../../../'),
typeChecking: false,
dumpErrorState: false,
});
expect(manager.configRegistry.register).toHaveBeenCalledTimes(2);
expect(manager.configRegistry.register).toHaveBeenNthCalledWith(1, '/var/cwd/config1.json');
@@ -419,6 +445,7 @@ describe('AppRunner', (): void => {
logLevel: 'debug',
mainModulePath: '/var/cwd/module/path',
typeChecking: false,
dumpErrorState: false,
});
expect(manager.configRegistry.register).toHaveBeenCalledTimes(1);
expect(manager.configRegistry.register).toHaveBeenCalledWith('/var/cwd/myconfig.json');
@@ -569,6 +596,7 @@ describe('AppRunner', (): void => {
logLevel: 'info',
mainModulePath: joinFilePath(__dirname, '../../../'),
typeChecking: false,
dumpErrorState: false,
});
expect(manager.configRegistry.register).toHaveBeenCalledTimes(1);
expect(manager.configRegistry.register)
@@ -600,6 +628,7 @@ describe('AppRunner', (): void => {
logLevel: 'debug',
mainModulePath: joinFilePath(__dirname, '../../../'),
typeChecking: false,
dumpErrorState: false,
});
expect(manager.configRegistry.register).toHaveBeenCalledTimes(1);
expect(manager.configRegistry.register)
@@ -760,6 +789,7 @@ describe('AppRunner', (): void => {
logLevel: 'info',
mainModulePath: joinFilePath(__dirname, '../../../'),
typeChecking: false,
dumpErrorState: false,
});
expect(manager.configRegistry.register).toHaveBeenCalledTimes(1);
expect(manager.configRegistry.register)