Merge branch 'main' into versions/5.0.0

This commit is contained in:
Joachim Van Herwegen
2022-05-24 10:40:27 +02:00
21 changed files with 2600 additions and 680 deletions

View File

@@ -4,7 +4,7 @@ module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
tsconfigRootDir: __dirname,
project: [ './tsconfig.json', './test/tsconfig.json' ],
project: [ './tsconfig.json', './test/tsconfig.json', './scripts/tsconfig.json' ],
},
// Ignoring js files (such as this one) since they seem to conflict with rules that require typing info
ignorePatterns: [ '*.js' ],

View File

@@ -38,10 +38,8 @@ jobs:
until $(curl --output /dev/null --silent --head --fail -k http://localhost:3000/); do
sleep 1
done
- name: Build test script
run: npx tsc -p test/deploy/tsconfig.json
- name: Create users
run: node test/tmp/cth/createAccountCredentials.js http://localhost:3000/ >> test/deploy/conformance.env
run: npx ts-node test/deploy/createAccountCredentials.ts http://localhost:3000/ >> test/deploy/conformance.env
- name: Run the test harness
run: >
docker run -i --rm

15
.versionrc.json Normal file
View File

@@ -0,0 +1,15 @@
{
"types": [
{"type": "feat", "section": "Features"},
{"type": "fix", "section": "Fixes"},
{"type": "chore", "section": "Chores"},
{"type": "chore(deps)", "section": "Dependency updates"},
{"type": "docs", "section": "Documentation"},
{"type": "style", "section": "Styling"},
{"type": "refactor", "section": "Refactors"},
{"type": "perf", "section": "Performance"},
{"type": "test", "section": "Testing"}
],
"header": "# Changelog\n\nAll notable changes to this project will be documented in this file.",
"releaseCommitMessageFormat": "chore(release): Release version {{currentTag}} of the npm package"
}

View File

@@ -120,7 +120,7 @@ All notable changes to this project will be documented in this file.
* fix: Make UnionCredentialsExtractor tolerate failures. ([c13456c](https://github.com/solid/community-server/commit/c13456c2259538e502a59ce73a226bab2c99c395))
* fix: Accept lowercase Authorization tokens. ([9c52011](https://github.com/solid/community-server/commit/9c52011addde6cbdfd22efeb9485841c640363be))
* feat: Return correct status codes for invalid requests ([1afed65](https://github.com/solid/community-server/commit/1afed65368f98f4fda7bdd8f9fc5071f51d4dc5b))
* fix: Split AccountStorage and ForgotPasswordStorage ([d067165](expiring now) (<https://github.com/solid/community-server/commit/d067165b68a824143ff65f289d8a1e5e53d15103>))
* fix: Split AccountStorage and ForgotPasswordStorage (expiring now) ([d067165](https://github.com/solid/community-server/commit/d067165b68a824143ff65f289d8a1e5e53d15103))
* fix: Add content-negotiation when fetching dataset from url ([ce754c1](https://github.com/solid/community-server/commit/ce754c119fb87dc8a4f79c639e316bd04d40109b))
* fix: Prevent login page from showing error before redirect ([1ed45c8](https://github.com/solid/community-server/commit/1ed45c8903e8750b818885cb6e48183e4c36f22a))
* fix: Make IDP routes independent of handlers ([1769b79](https://github.com/solid/community-server/commit/1769b799df090a036f2d2925c06ba8d9f7130e6b))
@@ -195,7 +195,7 @@ All notable changes to this project will be documented in this file.
* fix: Allow clients to be remembered in the SessionHttpHandler ([47b3a2d](https://github.com/solid/community-server/commit/47b3a2d77f4a5b3fa5bab364ac19dc32d79a89c1))
* fix: Convert data to SparqlDataAccessor in regex config ([f34e124](https://github.com/solid/community-server/commit/f34e124e1b88c59b4e456b3f69d9373e61550bd1))
* fix([7928f43](deps): update dependency @solid/access-token-verifier to ^0.12.0 (<https://github.com/solid/community-server/commit/7928f43f443f914c7850a968912f19a78212d266>))
* fix(deps): update dependency @solid/access-token-verifier to ^0.12.0 ([7928f43](https://github.com/solid/community-server/commit/7928f43f443f914c7850a968912f19a78212d266))
## [1.0.0](https://github.com/solid/community-server/compare/v1.0.0-beta.2...v1.0.0) (2021-08-04)
@@ -271,7 +271,7 @@ All notable changes to this project will be documented in this file.
* feat: Create ErrorHandler to convert errors to Representations ([e1f9587](https://github.com/solid/community-server/commit/e1f95877dac6a8f77d2c7a687bf478440ee5cb17))
* feat: Add showStackTrace CLI variable ([b604dd8](https://github.com/solid/community-server/commit/b604dd8331e1c7682dd6080c696981855e277df6))
* feat: Create WWW-Authenticate metadata writer ([e3c5b39](https://github.com/solid/community-server/commit/e3c5b3975266e5eee3939f9d1e8f5e0537417782))
* [Expose constant Allow header]([a6371b0](https://github.com/solid/community-server/commit/a6371b073597ae922c3374d952dfdf2f920017ac))
* Expose constant Allow header ([a6371b0]([a6371b0](https://github.com/solid/community-server/commit/a6371b073597ae922c3374d952dfdf2f920017ac))
* feat: Add ErrorToHtmlConverter using templates ([9c0fa77](https://github.com/solid/community-server/commit/9c0fa775276b8ba3383d25a155a2507309e0a1de))
* fix: Support BGPs with variables in SPARQL UPDATE queries ([f299b36](https://github.com/solid/community-server/commit/f299b36e2429245bf82be85ca0cccf733d658619))
@@ -290,7 +290,7 @@ All notable changes to this project will be documented in this file.
### Added
* feat: Add identity provider ([1d65143](#455) (<https://github.com/solid/community-server/commit/1d65143e89d4d64663805467a1587850690eeb59>))
* feat: Add identity provider (#455) ([1d65143](https://github.com/solid/community-server/commit/1d65143e89d4d64663805467a1587850690eeb59))
* feat: Add redis based locking mechanism ([99d0173](https://github.com/solid/community-server/commit/99d0173213be4b05bc78b80ac108cbb5f0906ad6))
* feat: enable more compact config props using type-scoped contexts ([2861b90](https://github.com/solid/community-server/commit/2861b902c476c456b9e5c208ab5048fc6e318421))
* feat: Update ChainedConverter to create dynamic paths ([44d82ea](https://github.com/solid/community-server/commit/44d82eac045fc3a5e8ae4b5407fc1989889f9e27))
@@ -341,7 +341,7 @@ All notable changes to this project will be documented in this file.
### Fixed
* fix: Do not re-encode static assets. ([c899e6c](#566) (<https://github.com/solid/community-server/commit/c899e6c4b1ab714347f49006b96615ad54fdb387>))
* fix: Do not re-encode static assets. (#566) ([c899e6c](https://github.com/solid/community-server/commit/c899e6c4b1ab714347f49006b96615ad54fdb387))
* fix: Preserve query string in transformations. ([6e50443](https://github.com/solid/community-server/commit/6e50443a3930adb14a483899b87589ccf42e7596))
* fix: Test error classes correctly ([c29928c](https://github.com/solid/community-server/commit/c29928c32c0d2ce5c97889edb3bd73904ab6077e))
* fix: Close unpiped streams ([386d782](https://github.com/solid/community-server/commit/386d78277dc7dda340c284bfff1ef8c40605e7ed))
@@ -356,7 +356,7 @@ All notable changes to this project will be documented in this file.
* fix: do not output filesystem container size ([1486f01](https://github.com/solid/community-server/commit/1486f01aaf714aba945df5f31f17cb5e96002d1a))
* Fix #621: acl:AuthenticatedAgent instead of foaf:AuthenticatedAgent ([91791a0](https://github.com/solid/community-server/commit/91791a0a140a9b1c80c2d7d9dde910c90b2062d8))
* fix: Allow non-variable BGP boedies in SPARQL updates ([894d458](https://github.com/solid/community-server/commit/894d4589d96533e9432c63911adc355c0785f0e0))
* [Correctly handle slugs in POST requests]([28c0eb7](https://github.com/solid/community-server/commit/28c0eb7e887f907fc4ca3a5045d9eb71cf0b0491))
* Correctly handle slugs in POST requests ([28c0eb7](https://github.com/solid/community-server/commit/28c0eb7e887f907fc4ca3a5045d9eb71cf0b0491))
* fix: Update faulty token verifier ([5c6822d](https://github.com/solid/community-server/commit/5c6822d4686585a03631b371427c7e2151ab65c7))
* fix: SPARQL PATCH Content Type ([2a34a43](https://github.com/solid/community-server/commit/2a34a430fa7435df01743e7f8ac7de014d259405))
* fix: SPARQL body parser test content type metadata ([23473f5](https://github.com/solid/community-server/commit/23473f59e69c1e028c7796996d98cf571277ad14))
@@ -391,7 +391,7 @@ All notable changes to this project will be documented in this file.
* feat: Export UnsecureConstantCredentialsExtractor. ([5429014](https://github.com/solid/community-server/commit/542901488fb043d47575206f87d0106f656e0974))
* feat: Add IfNeededConverter and PassthroughConverter. ([6763500](https://github.com/solid/community-server/commit/676350046631b75b136ad01ccca0ce6a64104526))
* feat: Support composite PATCH updates ([36761e8](https://github.com/solid/community-server/commit/36761e81249c9d7e787083de08135f1f22b5c23d))
* [Add optional path and url suffixes to FixedContentTypeMapper]([4ac0167](https://github.com/solid/community-server/commit/4ac0167c8d2b25a5bc5169617f04f2f9f3eece88))
* Add optional path and url suffixes to FixedContentTypeMapper ([4ac0167]([4ac0167](https://github.com/solid/community-server/commit/4ac0167c8d2b25a5bc5169617f04f2f9f3eece88))
* feat: Implement UnsupportedAsyncHandler. ([dd9d873](https://github.com/solid/community-server/commit/dd9d8731226d22e24643ee8565f4369480bae260))
* feat: Add ConstantConverter. ([5416d66](https://github.com/solid/community-server/commit/5416d66a31f4388c99352a3def81a4d06b085e78))
* feat: Set Vary header. ([693d48b](https://github.com/solid/community-server/commit/693d48b9eb965c4a479e137eea157eb1943b40a9))
@@ -564,8 +564,8 @@ All notable changes to this project will be documented in this file.
### Added
* feat: Expose types ([1dd1469](https://github.com/solid/community-server/commit/1dd14692feed21410557548d877c99ac08c2090f))
* feat: Implement resource mapper for the file resource store ([383da24](#142) (<https://github.com/solid/community-server/commit/383da24601118d13e32c41b044ed7e69b31cc113>))
* feat: More integration tests and test configs ([b1991cb](#154) (<https://github.com/solid/community-server/commit/b1991cb08ae722aae497104067a7a455456952c7>))
* feat: Implement resource mapper for the file resource store (#142) ([383da24](https://github.com/solid/community-server/commit/383da24601118d13e32c41b044ed7e69b31cc113))
* feat: More integration tests and test configs (#154) ([b1991cb](https://github.com/solid/community-server/commit/b1991cb08ae722aae497104067a7a455456952c7))
* feat: Update RepresentationMetadata to store triples ([76319ba](https://github.com/solid/community-server/commit/76319ba360f563122f1d35854b0e846417da2490))
* feat: Add logging ([99464d9](https://github.com/solid/community-server/commit/99464d9a954569cc1f259b01d28e223550571d7a))
* feat: Implement HEAD request support ([0644f8d](https://github.com/solid/community-server/commit/0644f8d24517b88018f85941d5b74b94c3a443f3))
@@ -607,8 +607,8 @@ All notable changes to this project will be documented in this file.
* refactor: Rename instances of data resource to document ([626b311](https://github.com/solid/community-server/commit/626b3114f413af2eb87c00c880ed86dc7569bb08))
* refactor: Remove file and in memory stores ([03c64e5](https://github.com/solid/community-server/commit/03c64e561707a4880822338817dc030b97a0f53f))
* refactor: Make ExtensionBasedMapper only expose what is needed ([4df2645](https://github.com/solid/community-server/commit/4df26454d44a71e676342fc4c5b37fa9e2ee118c))
* refactor: Implement empty canHandle on base class. ([1a45b65](#289) (<https://github.com/solid/community-server/commit/1a45b65df702815a65cc6fb539a6687eea5d3194>))
* chore: Organize tests ([73a56d8](#292) (<https://github.com/solid/community-server/commit/73a56d8682711fedd8f54216275e521c44a51670>))
* refactor: Implement empty canHandle on base class. (#289) ([1a45b65](https://github.com/solid/community-server/commit/1a45b65df702815a65cc6fb539a6687eea5d3194))
* chore: Organize tests (#292) ([73a56d8](https://github.com/solid/community-server/commit/73a56d8682711fedd8f54216275e521c44a51670))
* chore: Use Jest recommended linting. ([4b4f737](https://github.com/solid/community-server/commit/4b4f7370137dbbacf2ef2c887e952ad6d7e55622))
* refactor: Change constructor so it is supported by Components.js ([dee4eef](https://github.com/solid/community-server/commit/dee4eef131f1852dd62428ff122d73630070d710))
* refactor: Change routing constructors to work with Components.js ([50dfea1](https://github.com/solid/community-server/commit/50dfea1a27b461ea8ca87526165d33f0d991c44a))
@@ -621,7 +621,7 @@ All notable changes to this project will be documented in this file.
* fix: metadata file error in FileResourceStore ([c808dfe](https://github.com/solid/community-server/commit/c808dfeff09e26a4b31199cc0eec9db8667add28))
* fix: Retain status codes when combining errors ([10723bb](https://github.com/solid/community-server/commit/10723bb6b866316c2f20da0fe47349bd5f52edf5))
* fix: Have AsyncHandlers only check what is necessary ([4d34cdd](https://github.com/solid/community-server/commit/4d34cdd12f6dfcc5d5df64bd5c90b13148f69cfb))
* [Fix typo.]([79defc3](https://github.com/solid/community-server/commit/79defc3abb77d1454038c8a8e25b79494a9f4a6b))
* Fix typo. ([79defc3](https://github.com/solid/community-server/commit/79defc3abb77d1454038c8a8e25b79494a9f4a6b))
* fix: Make sure all URI characters are correctly encoded ([e85ca62](https://github.com/solid/community-server/commit/e85ca622da0c8e3ef8344332e162cfe327f74551))
* fix: Fix test issues ([2296219](https://github.com/solid/community-server/commit/22962192ffff5eac028ef3604e1cd989331cbff0))
* fix: Remove metadata file if no new metadata is stored ([63f891c](https://github.com/solid/community-server/commit/63f891c0f17ee915af21805ca114d2a9a90fb62e))
@@ -650,7 +650,7 @@ All notable changes to this project will be documented in this file.
* feat: add support for parsing more RDF formats using rdf-parse ([e88e680](https://github.com/solid/community-server/commit/e88e680ed7bd2799cdfd6f627dfc85f064dee94c))
* feat: Support link and slug headers in SimpleBodyParser ([86d5f36](https://github.com/solid/community-server/commit/86d5f367d52b769b563a8ad6ea1a02274f9ec5ab))
* feat: Move runtime config into dedicated component, Closes #67 ([5126356](https://github.com/solid/community-server/commit/5126356c940bb12d9765bbd3571b6f1f6fa65cd0))
* feat: Add file based ResourceStore ([381dae4](#52) (<https://github.com/solid/community-server/commit/381dae42f689a11937ca4daf0227d0bd16064ce3>))
* feat: Add file based ResourceStore (#52) ([381dae4](https://github.com/solid/community-server/commit/381dae42f689a11937ca4daf0227d0bd16064ce3))
* feat: Add more extensive permission parsing support ([e06d0bc](https://github.com/solid/community-server/commit/e06d0bc8c5fed72a47bf8e82f0affba27e1f77bb))
* feat: Integrate acl with rest of server ([769b492](https://github.com/solid/community-server/commit/769b49293cffa77cd7381331bc59e488d7e8f4c9))
* feat: Add acl support ([0545ca1](https://github.com/solid/community-server/commit/0545ca121eedec5541900aa1411dbeea8af015e2))
@@ -683,4 +683,4 @@ All notable changes to this project will be documented in this file.
* feat: add FirstCompositeHandler to support multiple handlers ([4229932](https://github.com/solid/community-server/commit/4229932a3ac75c2532da4e495e96b779fc5b6c92))
* feat: add custom errors ([57405f3](https://github.com/solid/community-server/commit/57405f3e2695f3a82628e02052695314d656af95))
* feat: add additional supported interfaces ([a4f2b39](https://github.com/solid/community-server/commit/a4f2b3995c3e8cfeacf5fe3dbbc0eeb8020f9c9e))
* [Initial configuration]([b949b6c](https://github.com/solid/community-server/commit/b949b6cf5eade549b91731edcd1c4d931537a42e))
* Initial configuration ([b949b6c](https://github.com/solid/community-server/commit/b949b6cf5eade549b91731edcd1c4d931537a42e))

View File

@@ -3,35 +3,35 @@
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/x.0.0`.
* 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 the recipes at https://github.com/CommunitySolidServer/recipes
* 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.
* Update all Components.js references to the new version.
* All contexts in all configs to
`https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^x.0.0/components/context.jsonld`.
* Update all `lsd` entries in `package.json` to the new version.
* Commit this with `chore: Update configs to vx.0.0`.
* `npm version major -m "chore: Release version %s of the npm package"`
* This will update the `package.json`, generate a tag, and generate the new entries in `CHANGELOG.md`.
* Manually edit the `CHANGELOG.md`.
* First reverse the list of new entries so they go from old to new.
* Put all entries in matching categories, look at the previous release for reference.
* Most `chore` and `docs` entries can probably be removed.
* Make sure there are 2 newlines between this and the previous section.
* `git push --follow-tags`
* Merge `versions/x.0.0` into `main` and push.
* Do a GitHub release.
* `npm publish`
* 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.
* Potentially upgrade the recipes at https://github.com/CommunitySolidServer/recipes
* Merge `main` into `versions/x.0.0`.
* 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 the recipes at <https://github.com/CommunitySolidServer/recipes>
* 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` or `npx standard-version -r major`
* Automatically updates Components.js references to the new version. Committed with `chore(release): Update configs to vx.0.0`.
* Updates the `package.json`, generate a tag, and generate the new entries in `CHANGELOG.md`. Commited with `chore(release): Release version vx0.0 of the npm package`
* You can always add `--dry-run` to the above command to preview the commands that will be run and the changes to `CHANGELOG.md`.
* Manually edit the `CHANGELOG.md`.
* All entries are added in separate sections of the new release according to their commit prefixes.
* Re-organize the entries accordingly, referencing previous releases.
* Most of the entries in Chores and Documentation can be removed.
* Make sure there are 2 newlines between this and the previous section.
* `git add CHANGELOG.md && git commit --amend --no-edit --no-verify` to add manual changes to the release commit.
* `git push --follow-tags`
* Merge `versions/x.0.0` into `main` and push.
* Do a GitHub release.
* `npm publish`
* 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.
* Potentially upgrade the recipes at <https://github.com/CommunitySolidServer/recipes>
Changes when doing a pre-release of a major version:
* Version with `npm version premajor --preid alpha -m "chore: Release version %s of the npm package"`.
* Do not merge `versions/x.0.0` into `main`.
* Publish with `npm publish --tag next`.
* Do not update the branch or anything related.
* Version with `npm release -- -r major --pre-release alpha`
* Do not merge `versions/x.0.0` into `main`.
* Publish with `npm publish --tag next`.
* Do not update the branch or anything related.

2905
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -51,6 +51,7 @@
"jest": "jest --coverageReporters text-summary --",
"lint": "eslint . --cache --ignore-path .gitignore --max-warnings 0",
"prepare": "npm run build",
"release": "standard-version",
"start": "node ./bin/server.js",
"start:file": "node ./bin/server.js -c config/file.json -f ./data",
"test": "npm run test:ts && npm run jest",
@@ -60,7 +61,6 @@
"test:unit": "jest --config=./jest.coverage.config.js test/unit",
"test:watch": "jest --coverageReporters none --watch test/unit",
"validate": "componentsjs-compile-config urn:solid-server:default:Initializer -c config/default.json -f > /dev/null",
"version": "manual-git-changelog onversion",
"watch": "nodemon --watch \"dist/**/*.js\" --exec npm start"
},
"husky": {
@@ -69,6 +69,12 @@
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
},
"standard-version": {
"scripts": {
"postbump": "ts-node ./scripts/upgradeConfig.ts",
"postchangelog": "ts-node ./scripts/formatChangelog.ts"
}
},
"files": [
"bin",
"dist",
@@ -164,12 +170,14 @@
"husky": "^4.3.8",
"jest": "^27.4.7",
"jest-rdf": "^1.7.0",
"manual-git-changelog": "^1.0.1",
"node-mocks-http": "^1.11.0",
"nodemon": "^2.0.15",
"set-cookie-parser": "^2.4.8",
"simple-git": "^3.7.1",
"standard-version": "^9.3.2",
"supertest": "^6.2.2",
"ts-jest": "^27.1.3",
"ts-node": "^10.7.0",
"typedoc": "^0.22.11",
"typescript": "^4.5.5"
}

View File

@@ -0,0 +1,33 @@
#!/usr/bin/env ts-node
/* eslint-disable no-console */
import { readFile, writeFile } from 'fs-extra';
/**
* Script called after the changelog changes of standard-version
* This script can be extended to add further custom formatting
* to the changelog.
* Current automatic changes:
* - Change all version titles to H2 ("### [vX.Y.Z]" to "## [vX.Y.Z]")
*/
/**
* @param from - Regular expression to search for
* @param to - String to replace to
* @param filePath - File to search/replace
* @returns Promise
*/
async function replaceInFile(from: RegExp, to: string, filePath: string): Promise<void> {
const data = await readFile(filePath, 'utf8');
const result = data.replace(from, to);
return writeFile(filePath, result, 'utf8');
}
/**
* Ends the process and writes out an error in case something goes wrong.
*/
function endProcess(error: Error): never {
console.error(error);
process.exit(1);
}
replaceInFile(/### \[/gu, '## [', 'CHANGELOG.md').catch(endProcess);

6
scripts/tsconfig.json Normal file
View File

@@ -0,0 +1,6 @@
{
"extends": "../tsconfig.json",
"include": [
"."
]
}

91
scripts/upgradeConfig.ts Normal file
View File

@@ -0,0 +1,91 @@
#!/usr/bin/env ts-node
/* eslint-disable no-console */
import escapeStringRegexp from 'escape-string-regexp';
import { readdir, readFile, writeFile } from 'fs-extra';
import simpleGit from 'simple-git';
import { joinFilePath, readPackageJson } from '../src/util/PathUtil';
/**
* Script: upgradeConfigs.ts
* Run with: ts-node scripts/upgradeConfig.ts
* ------------------------------------------
* Upgrades the lsd:module references to CSS in package.json
* and all JSON-LD config files.
* This script is run alongside standard-version after the
* version bump is done in package.json but before the
* release has been committed.
*/
/**
* Search and replace the version of a component with given name
* @param filePath - File to search/replace
* @param regex - RegExp matching the component reference
* @param version - Semantic version to change to
*/
async function replaceComponentVersion(filePath: string, regex: RegExp, version: string): Promise<void> {
console.log(`Replacing version in ${filePath}`);
const data = await readFile(filePath, 'utf8');
const result = data.replace(regex, `$1^${version}`);
return writeFile(filePath, result, 'utf8');
}
/**
* Recursive search for files that match a given Regex
* @param path - Path of folder to start search in
* @param regex - A regular expression to which file names will be matched
* @returns Promise with all file pathss
*/
async function getFilePaths(path: string, regex: RegExp): Promise<string[]> {
const entries = await readdir(path, { withFileTypes: true });
const files = entries
.filter((file): boolean => !file.isDirectory())
.filter((file): boolean => regex.test(file.name))
.map((file): string => joinFilePath(path, file.name));
const folders = entries.filter((folder): boolean => folder.isDirectory());
for (const folder of folders) {
files.push(...await getFilePaths(joinFilePath(path, folder.name), regex));
}
return files;
}
/**
* Changes version of Component references in package.json and
* JSON-LD config files (config/) to the current major version of
* the NPM package.
* Commits changes to config files (not package.json, changes to
* that file are included in the release commit).
*/
async function upgradeConfig(): Promise<void> {
const pkg = await readPackageJson();
const major = pkg.version.split('.')[0];
console.log(`Changing ${pkg['lsd:module']} references to ${major}.0.0\n`);
const configs = await getFilePaths('config/', /.+\.json/u);
configs.push(...await getFilePaths('test/integration/config/', /.+\.json/u));
configs.push(...await getFilePaths('templates/config/', /.+\.json/u));
const escapedName = escapeStringRegexp(pkg['lsd:module']);
const regex = new RegExp(`(${escapedName}/)${/\^\d+\.\d+\.\d+/u.source}`, 'gmu');
for (const config of configs) {
await replaceComponentVersion(config, regex, `${major}.0.0`);
}
await replaceComponentVersion('package.json', regex, `${major}.0.0`);
await simpleGit().commit(`chore(release): Update configs to v${major}.0.0`, configs, { '--no-verify': null });
}
/**
* Ends the process and writes out an error in case something goes wrong.
*/
function endProcess(error: Error): never {
console.error(error);
process.exit(1);
}
upgradeConfig().catch(endProcess);

View File

@@ -18,6 +18,13 @@ export class OidcHttpHandler extends HttpHandler {
public async handle({ request, response }: HttpHandlerInput): Promise<void> {
const provider = await this.providerFactory.getProvider();
// Rewrite requests to allow hosting on root paths
const path = new URL(provider.issuer).pathname;
if (path.length > 1 && request.url!.startsWith(`${path}.well-known/openid-configuration`)) {
request.url = request.url!.replace(path, '/');
}
this.logger.debug(`Sending request to oidc-provider: ${request.url}`);
// Even though the typings do not indicate this, this is a Promise that needs to be awaited.
// Otherwise, the `BaseHttpServerFactory` will write a 404 before the OIDC library could handle the response.

View File

@@ -51,9 +51,10 @@ export class WebIdAdapter extends PassthroughAdapter {
let json: any | undefined;
try {
json = JSON.parse(data);
const contexts = Array.isArray(json['@context']) ? json['@context'] : [ json['@context'] ];
// We can only parse as simple JSON if the @context is correct
if (json['@context'] !== 'https://www.w3.org/ns/solid/oidc-context.jsonld') {
throw new Error('Invalid context');
if (!contexts.includes('https://www.w3.org/ns/solid/oidc-context.jsonld')) {
throw new Error('Missing context https://www.w3.org/ns/solid/oidc-context.jsonld');
}
} catch (error: unknown) {
json = undefined;

View File

@@ -1,13 +1,19 @@
import { createHash } from 'crypto';
import { parse } from 'path';
import { BasicRepresentation } from '../../http/representation/BasicRepresentation';
import type { Representation } from '../../http/representation/Representation';
import type { ResourceIdentifier } from '../../http/representation/ResourceIdentifier';
import { NotFoundHttpError } from '../../util/errors/NotFoundHttpError';
import { ensureLeadingSlash, ensureTrailingSlash, isContainerIdentifier, joinUrl } from '../../util/PathUtil';
import { ensureLeadingSlash, ensureTrailingSlash, isContainerIdentifier, joinUrl,
joinFilePath } from '../../util/PathUtil';
import { readableToString } from '../../util/StreamUtil';
import { LDP } from '../../util/Vocabularies';
import type { ResourceStore } from '../ResourceStore';
import type { KeyValueStorage } from './KeyValueStorage';
// Maximum allowed length for the keys, longer keys will be hashed.
const KEY_LENGTH_LIMIT = 255;
/**
* A {@link KeyValueStorage} for JSON-like objects using a {@link ResourceStore} as backend.
*
@@ -114,6 +120,15 @@ export class JsonResourceStorage<T> implements KeyValueStorage<string, T> {
* Converts a key into an identifier for internal storage.
*/
private keyToIdentifier(key: string): ResourceIdentifier {
// Parse the key as a file path
const parsedPath = parse(key);
// Hash long filenames to prevent issues with the underlying storage.
// E.g. a UNIX a file name cannot exceed 255 bytes.
// This is a temporary fix for https://github.com/CommunitySolidServer/CommunitySolidServer/issues/1013,
// until we have a solution for data migration.
if (parsedPath.base.length > KEY_LENGTH_LIMIT) {
key = joinFilePath(parsedPath.dir, this.applyHash(parsedPath.base));
}
return { path: joinUrl(this.container, key) };
}
@@ -127,4 +142,8 @@ export class JsonResourceStorage<T> implements KeyValueStorage<string, T> {
// on the `entries` results matching a key that was sent before.
return ensureLeadingSlash(identifier.path.slice(this.container.length));
}
private applyHash(key: string): string {
return createHash('sha256').update(key).digest('hex');
}
}

View File

@@ -8,6 +8,7 @@ import { getLoggerFor } from '../logging/LogUtil';
import type { RepresentationConverter } from '../storage/conversion/RepresentationConverter';
import { INTERNAL_QUADS } from './ContentTypes';
import { BadRequestHttpError } from './errors/BadRequestHttpError';
import { createErrorMessage } from './errors/ErrorUtil';
const logger = getLoggerFor('FetchUtil');
@@ -23,8 +24,8 @@ export async function fetchDataset(url: string): Promise<Representation> {
const quadStream = (await rdfDereferencer.dereference(url)).data;
const quadArray = await arrayifyStream<Quad>(quadStream);
return new BasicRepresentation(quadArray, { path: url }, INTERNAL_QUADS, false);
} catch {
throw new BadRequestHttpError(`Could not parse resource at URL (${url})!`);
} catch (error: unknown) {
throw new BadRequestHttpError(`Could not parse resource at URL (${url})! ${createErrorMessage(error)}`);
}
})();
}

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://solid.github.io/mashlib/dist/browse.html?uri={{podBaseUrl}}).
you can open your pod in [Databrowser](https://solidos.github.io/mashlib/dist/browse.html?uri={{podBaseUrl}}).
## Learn more
The [Solid website](https://solidproject.org/)

View File

@@ -8,7 +8,7 @@
</head>
<body>
<header>
<a href="/"><img src="/.well-known/css/images/solid.svg" alt="[Solid logo]" /></a>
<a href="./"><img src="/.well-known/css/images/solid.svg" alt="[Solid logo]" /></a>
<h1>Community Solid Server</h1>
</header>
<main>
@@ -22,7 +22,7 @@
<h2 id="users">Getting started as a <em>user</em></h2>
<p>
<a href="/idp/register/">Sign up for an account</a>
<a href="./idp/register/">Sign up for an account</a>
to get started with your own Pod and WebID.
</p>
<p>

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env node
#!/usr/bin/env ts-node
/* eslint-disable no-console */
import fetch from 'cross-fetch';
import urljoin from 'url-join';

View File

@@ -1,15 +0,0 @@
{
"extends": "@tsconfig/node14/tsconfig.json",
"compilerOptions": {
"declaration": true,
"inlineSources": true,
"newLine": "lf",
"outDir": "../tmp/cth",
"preserveConstEnums": true,
"sourceMap": true,
"stripInternal": true
},
"include": [
"createAccountCredentials.ts"
]
}

View File

@@ -5,7 +5,9 @@ import type { HttpRequest } from '../../../src/server/HttpRequest';
import type { HttpResponse } from '../../../src/server/HttpResponse';
describe('An OidcHttpHandler', (): void => {
const request: HttpRequest = {} as any;
const request: HttpRequest = {
url: '/.well-known/openid-configuration',
} as any;
const response: HttpResponse = {} as any;
let provider: jest.Mocked<Provider>;
let providerFactory: jest.Mocked<ProviderFactory>;
@@ -14,11 +16,12 @@ describe('An OidcHttpHandler', (): void => {
beforeEach(async(): Promise<void> => {
provider = {
callback: jest.fn().mockReturnValue(jest.fn()),
issuer: 'http://localhost:3000/',
} as any;
providerFactory = {
getProvider: jest.fn().mockResolvedValue(provider),
};
} as any;
handler = new OidcHttpHandler(providerFactory);
});
@@ -29,4 +32,24 @@ describe('An OidcHttpHandler', (): void => {
expect(provider.callback.mock.results[0].value).toHaveBeenCalledTimes(1);
expect(provider.callback.mock.results[0].value).toHaveBeenLastCalledWith(request, response);
});
it('rewrites the request when using base URL with root path.', async(): Promise<void> => {
Object.assign(provider, { issuer: 'http://localhost:3000/path/' });
request.url = '/path/.well-known/openid-configuration';
await expect(handler.handle({ request, response })).resolves.toBeUndefined();
expect(request.url).toBe('/.well-known/openid-configuration');
expect(provider.callback).toHaveBeenCalledTimes(1);
expect(provider.callback.mock.results[0].value).toHaveBeenCalledTimes(1);
expect(provider.callback.mock.results[0].value).toHaveBeenLastCalledWith(request, response);
});
it('respects query parameters when rewriting requests.', async(): Promise<void> => {
Object.assign(provider, { issuer: 'http://localhost:3000/path/' });
request.url = '/path/.well-known/openid-configuration?param1=value1';
await expect(handler.handle({ request, response })).resolves.toBeUndefined();
expect(request.url).toBe('/.well-known/openid-configuration?param1=value1');
expect(provider.callback).toHaveBeenCalledTimes(1);
expect(provider.callback.mock.results[0].value).toHaveBeenCalledTimes(1);
expect(provider.callback.mock.results[0].value).toHaveBeenLastCalledWith(request, response);
});
});

View File

@@ -85,6 +85,15 @@ describe('A WebIdAdapterFactory', (): void => {
});
});
it('can handle a context array.', async(): Promise<void> => {
json['@context'] = [ json['@context'] ];
fetchMock.mockResolvedValueOnce({ url: id, status: 200, text: (): string => JSON.stringify(json) });
await expect(adapter.find(id)).resolves.toEqual({
...json,
token_endpoint_auth_method: 'none',
});
});
it('errors if there is a client_id mismatch.', async(): Promise<void> => {
json.client_id = 'someone else';
fetchMock.mockResolvedValueOnce({ url: id, status: 200, text: (): string => JSON.stringify(json) });

View File

@@ -1,3 +1,4 @@
import { createHash } from 'crypto';
import { BasicRepresentation } from '../../../../src/http/representation/BasicRepresentation';
import type { Representation } from '../../../../src/http/representation/Representation';
import { RepresentationMetadata } from '../../../../src/http/representation/RepresentationMetadata';
@@ -5,7 +6,7 @@ import type { ResourceIdentifier } from '../../../../src/http/representation/Res
import { JsonResourceStorage } from '../../../../src/storage/keyvalue/JsonResourceStorage';
import type { ResourceStore } from '../../../../src/storage/ResourceStore';
import { NotFoundHttpError } from '../../../../src/util/errors/NotFoundHttpError';
import { isContainerIdentifier } from '../../../../src/util/PathUtil';
import { isContainerIdentifier, joinUrl } from '../../../../src/util/PathUtil';
import { readableToString } from '../../../../src/util/StreamUtil';
import { LDP } from '../../../../src/util/Vocabularies';
@@ -123,7 +124,23 @@ describe('A JsonResourceStorage', (): void => {
]);
});
it('can handle resources being deleted while iterating in the entries call.', async(): Promise<void> => {
//
});
it('converts keys that would result in too large filenames into an identifier that uses a hash.',
async(): Promise<void> => {
const longFileName = `${'sometext'.repeat(32)}.json`;
const b64LongFileName = Buffer.from(longFileName).toString('base64');
const longKey = `/container/${b64LongFileName}`;
const longKeyId = joinUrl(subContainerIdentifier, createHash('sha256').update(b64LongFileName).digest('hex'));
await storage.set(longKey, 'data');
// Check if a hash of the key has been used for the filename part of the key.
expect(data.has(longKeyId)).toBeTruthy();
data.clear();
// Check that normal keys stay unaffected
const normalKey = '/container/test';
const normalKeyId = joinUrl(containerIdentifier, normalKey);
await storage.set(normalKey, 'data');
expect(data.has(normalKeyId)).toBeTruthy();
});
});