solid-server 5.7.0 → 5.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -17,7 +17,7 @@ jobs:
17
17
 
18
18
  strategy:
19
19
  matrix:
20
- node-version: [12.x, 14.x]
20
+ node-version: [12.x, 14.x, 16.x]
21
21
  os: [ubuntu-latest]
22
22
 
23
23
  steps:
package/.nvmrc CHANGED
@@ -1 +1 @@
1
- 13.14.0
1
+ 16.14.0
package/README.md CHANGED
@@ -371,7 +371,8 @@ In order to really get a feel for the Solid platform, and to test out `solid`,
371
371
  you will need the following:
372
372
 
373
373
  1. A WebID profile and browser certificate from one of the Solid-compliant
374
- identity providers, such as [solidcommunity.net](https://solidcommunity.net).
374
+ identity providers, such as [solidcommunity.net](bourgeoa
375
+ community.net).
375
376
 
376
377
  2. A server-side SSL certificate for `solid` to use (see the section below
377
378
  on creating a self-signed certificate for testing).
@@ -453,7 +454,7 @@ You can receive or provide help too:
453
454
  - [NSS Gitter channel](https://gitter.im/solid/node-solid-server) for specific (installation) advice about this code base
454
455
  - [Create a new issue](https://github.com/solid/node-solid-server/issues/new) to report bugs
455
456
  - [Fix an issue](https://github.com/solid/node-solid-server/issues)
456
- - Reach out to Jackson at jacksonm@inrupt.com to become more involved in maintaining Node Solid Server
457
+ - Reach out to @bourgeoa at alain.bourgeois10@gmail.com to become more involved in maintaining Node Solid Server
457
458
 
458
459
  Have a look at [CONTRIBUTING.md](https://github.com/solid/node-solid-server/blob/master/CONTRIBUTING.md).
459
460
 
package/index.html CHANGED
@@ -38,7 +38,7 @@
38
38
  <dt>Name</dt>
39
39
  <dd>localhost</dd>
40
40
  <dt>Details</dt>
41
- <dd>Running on <a href="https://github.com/solid/node-solid-server/releases/tag/v5.6.6">Solid 5.6.6</a></dd>
41
+ <dd>Running on <a href="https://github.com/solid/node-solid-server/releases/tag/v5.7.3">Solid 5.7.3</a></dd>
42
42
  </dl>
43
43
  </section>
44
44
  </div>
package/lib/create-app.js CHANGED
@@ -32,7 +32,7 @@ const corsSettings = cors({
32
32
  methods: [
33
33
  'OPTIONS', 'HEAD', 'GET', 'PATCH', 'POST', 'PUT', 'DELETE'
34
34
  ],
35
- exposedHeaders: 'Authorization, User, Location, Link, Vary, Last-Modified, ETag, Accept-Patch, Accept-Post, Updates-Via, Allow, WAC-Allow, Content-Length, WWW-Authenticate, X-Powered-By',
35
+ exposedHeaders: 'Authorization, User, Location, Link, Vary, Last-Modified, ETag, Accept-Patch, Accept-Post, Updates-Via, Allow, WAC-Allow, Content-Length, WWW-Authenticate, MS-Author-Via, X-Powered-By',
36
36
  credentials: true,
37
37
  maxAge: 1728000,
38
38
  origin: true,
@@ -13,7 +13,7 @@ const validUrl = require('valid-url')
13
13
 
14
14
  const CORS_SETTINGS = {
15
15
  methods: 'GET',
16
- exposedHeaders: 'Authorization, User, Location, Link, Vary, Last-Modified, Content-Length, Content-Location, X-Powered-By',
16
+ exposedHeaders: 'Authorization, User, Location, Link, Vary, Last-Modified, Content-Length, Content-Location, MS-Author-Via, X-Powered-By',
17
17
  maxAge: 1728000,
18
18
  origin: true
19
19
  }
@@ -27,6 +27,8 @@ async function handler (req, res, next) {
27
27
  const requestedType = negotiator.mediaType()
28
28
  const possibleRDFType = negotiator.mediaType(RDFs)
29
29
 
30
+ res.header('MS-Author-Via', 'SPARQL')
31
+
30
32
  // Set live updates
31
33
  if (ldp.live) {
32
34
  res.header('Updates-Via', ldp.resourceMapper.resolveUrl(req.hostname).replace(/^http/, 'ws'))
@@ -18,11 +18,28 @@ const PATCH_PARSERS = {
18
18
  'text/n3': require('./patch/n3-patch-parser.js')
19
19
  }
20
20
 
21
+ // use media-type as contentType for new RDF resource
21
22
  const DEFAULT_FOR_NEW_CONTENT_TYPE = 'text/turtle'
22
23
 
24
+ function contentTypeForNew (req) {
25
+ let contentTypeForNew = DEFAULT_FOR_NEW_CONTENT_TYPE
26
+ if (req.path.endsWith('.jsonld')) contentTypeForNew = 'application/ld+json'
27
+ else if (req.path.endsWith('.n3')) contentTypeForNew = 'text/n3'
28
+ else if (req.path.endsWith('.rdf')) contentTypeForNew = 'application/rdf+xml'
29
+ return contentTypeForNew
30
+ }
31
+
32
+ function contentForNew (contentType) {
33
+ let contentForNew = ''
34
+ if (contentType.includes('ld+json')) contentForNew = JSON.stringify('{}')
35
+ else if (contentType.includes('rdf+xml')) contentForNew = '<rdf:RDF\n xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">\n\n</rdf:RDF>'
36
+ return contentForNew
37
+ }
38
+
23
39
  // Handles a PATCH request
24
40
  async function patchHandler (req, res, next) {
25
41
  debug(`PATCH -- ${req.originalUrl}`)
42
+ res.header('MS-Author-Via', 'SPARQL')
26
43
  try {
27
44
  // Obtain details of the target resource
28
45
  const ldp = req.app.locals.ldp
@@ -32,9 +49,9 @@ async function patchHandler (req, res, next) {
32
49
  // First check if the file already exists
33
50
  ({ path, contentType } = await ldp.resourceMapper.mapUrlToFile({ url: req }))
34
51
  } catch (err) {
35
- // If the file doesn't exist, request one to be created with the default content type
52
+ // If the file doesn't exist, request to create one with the file media type as contentType
36
53
  ({ path, contentType } = await ldp.resourceMapper.mapUrlToFile(
37
- { url: req, createIfNotExists: true, contentType: DEFAULT_FOR_NEW_CONTENT_TYPE }))
54
+ { url: req, createIfNotExists: true, contentType: contentTypeForNew(req) }))
38
55
  // check if a folder with same name exists
39
56
  await ldp.checkItemName(req)
40
57
  resourceExists = false
@@ -92,13 +109,14 @@ function readGraph (resource) {
92
109
  // If the file does not exist, assume empty contents
93
110
  // (it will be created after a successful patch)
94
111
  if (err.code === 'ENOENT') {
95
- fileContents = ''
112
+ fileContents = contentForNew(resource.contentType)
96
113
  // Fail on all other errors
97
114
  } else {
98
115
  return reject(error(500, `Original file read error: ${err}`))
99
116
  }
100
117
  }
101
118
  debug('PATCH -- Read target file (%d bytes)', fileContents.length)
119
+ fileContents = resource.contentType.includes('json') ? JSON.parse(fileContents) : fileContents
102
120
  resolve(fileContents)
103
121
  })
104
122
  )
@@ -176,23 +194,34 @@ function writeGraph (graph, resource, root, serverUri) {
176
194
  debug('PATCH -- Writing patched file')
177
195
  return new Promise((resolve, reject) => {
178
196
  const resourceSym = graph.sym(resource.url)
179
- const serialized = $rdf.serialize(resourceSym, graph, resource.url, resource.contentType)
180
-
181
- // First check if we are above quota
182
- overQuota(root, serverUri).then((isOverQuota) => {
183
- if (isOverQuota) {
184
- return reject(error(413,
185
- 'User has exceeded their storage quota'))
186
- }
187
197
 
188
- fs.writeFile(resource.path, serialized, { encoding: 'utf8' }, function (err) {
189
- if (err) {
190
- return reject(error(500, `Failed to write file after patch: ${err}`))
198
+ function doWrite (serialized) {
199
+ // First check if we are above quota
200
+ overQuota(root, serverUri).then((isOverQuota) => {
201
+ if (isOverQuota) {
202
+ return reject(error(413,
203
+ 'User has exceeded their storage quota'))
191
204
  }
192
- debug('PATCH -- applied successfully')
193
- resolve('Patch applied successfully.\n')
205
+
206
+ fs.writeFile(resource.path, serialized, { encoding: 'utf8' }, function (err) {
207
+ if (err) {
208
+ return reject(error(500, `Failed to write file after patch: ${err}`))
209
+ }
210
+ debug('PATCH -- applied successfully')
211
+ resolve('Patch applied successfully.\n')
212
+ })
213
+ }).catch(() => reject(error(500, 'Error finding user quota')))
214
+ }
215
+
216
+ if (resource.contentType === 'application/ld+json') {
217
+ $rdf.serialize(resourceSym, graph, resource.url, resource.contentType, function (err, result) {
218
+ if (err) return reject(error(500, `Failed to serialize after patch: ${err}`))
219
+ doWrite(result)
194
220
  })
195
- }).catch(() => reject(error(500, 'Error finding user quota')))
221
+ } else {
222
+ const serialized = $rdf.serialize(resourceSym, graph, resource.url, resource.contentType)
223
+ doWrite(serialized)
224
+ }
196
225
  })
197
226
  }
198
227
 
@@ -8,6 +8,7 @@ const { stringToStream } = require('../utils')
8
8
 
9
9
  async function handler (req, res, next) {
10
10
  debug(req.originalUrl)
11
+ res.header('MS-Author-Via', 'SPARQL')
11
12
 
12
13
  const contentType = req.get('content-type')
13
14
  if (isAuxiliary(req)) {
@@ -82,9 +82,7 @@ class ResourceMapper {
82
82
 
83
83
  // Determine the URL by chopping off everything after the dollar sign
84
84
  const pathname = this._removeDollarExtension(path)
85
- const url = `${this.resolveUrl(hostname)}${
86
- pathname.split('/').map((component) => encodeURIComponent(component)).join('/')
87
- }`
85
+ const url = `${this.resolveUrl(hostname)}${this._encodePath(pathname)}`
88
86
  return { url, contentType: this._getContentTypeFromExtension(path) }
89
87
  }
90
88
 
@@ -95,7 +93,7 @@ class ResourceMapper {
95
93
  contentType = contentType ? contentType.replace(/\s*;.*/, '') : ''
96
94
  // Parse the URL and find the base file path
97
95
  const { pathname, hostname } = this._parseUrl(url)
98
- const filePath = this.resolveFilePath(hostname, decodeURIComponent(pathname))
96
+ const filePath = this.resolveFilePath(hostname, this._decodePath(pathname))
99
97
  if (filePath.indexOf('/..') >= 0) {
100
98
  throw new Error('Disallowed /.. segment in URL')
101
99
  }
@@ -149,6 +147,31 @@ class ResourceMapper {
149
147
  return { path, contentType: contentType || this._defaultContentType }
150
148
  }
151
149
 
150
+ // encode/decode path except slash (/), %encodedSlash (%2F|%2f), or ntimes%encodedSlash (%2525...2F|%2525...2f)
151
+ // see https://github.com/solid/node-solid-server/issues/1666
152
+ _exceptSlash () { return /(\/|%(?:25)*(?:2f))/gi }
153
+
154
+ _encodePath (pathname) {
155
+ return pathname.split(this._exceptSlash())
156
+ .map((el, i) => i % 2 === 0 ? encodeURIComponent(el) : el)
157
+ .join('')
158
+ /* pathArray.forEach((el, i) => {
159
+ if (i % 2 === 0) pathArray[i] = encodeURIComponent(el)
160
+ }) */
161
+ // return pathArray.join('')
162
+ }
163
+
164
+ _decodePath (pathname) {
165
+ return pathname.split(this._exceptSlash())
166
+ .map((el, i) => i % 2 === 0 ? decodeURIComponent(el) : el)
167
+ .join('')
168
+ /* const pathArray = pathname.split(this._exceptSlash())
169
+ pathArray.forEach((el, i) => {
170
+ if (i % 2 === 0) pathArray[i] = decodeURIComponent(el)
171
+ })
172
+ return pathArray.join('') */
173
+ }
174
+
152
175
  // Parses a URL into hostname and pathname
153
176
  _parseUrl (url) {
154
177
  // URL specified as string
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "solid-server",
3
3
  "description": "Solid server on top of the file-system",
4
- "version": "5.7.0",
4
+ "version": "5.7.3",
5
5
  "author": {
6
6
  "name": "Tim Berners-Lee",
7
7
  "email": "timbl@w3.org"
@@ -59,46 +59,46 @@
59
59
  "homepage": "https://github.com/solid/node-solid-server",
60
60
  "bugs": "https://github.com/solid/node-solid-server/issues",
61
61
  "dependencies": {
62
- "@fastify/busboy": "^1.0.0",
62
+ "@fastify/busboy": "^1.1.0",
63
63
  "@solid/acl-check": "^0.4.5",
64
- "@solid/oidc-auth-manager": "^0.24.2",
64
+ "@solid/oidc-auth-manager": "^0.24.3",
65
65
  "@solid/oidc-op": "^0.11.6",
66
- "async-lock": "^1.3.0",
67
- "body-parser": "^1.19.1",
66
+ "async-lock": "^1.3.2",
67
+ "body-parser": "^1.20.0",
68
68
  "bootstrap": "^3.4.1",
69
- "cached-path-relative": "^1.0.2",
69
+ "cached-path-relative": "^1.1.0",
70
70
  "camelize": "^1.0.0",
71
- "cheerio": "^1.0.0-rc.10",
72
- "colorette": "^2.0.16",
71
+ "cheerio": "^1.0.0-rc.12",
72
+ "colorette": "^2.0.19",
73
73
  "commander": "^8.3.0",
74
74
  "cors": "^2.8.5",
75
- "debug": "^4.3.3",
76
- "express": "^4.17.2",
77
- "express-handlebars": "^5.3.4",
78
- "express-session": "^1.17.2",
75
+ "debug": "^4.3.4",
76
+ "express": "^4.18.1",
77
+ "express-handlebars": "^5.3.5",
78
+ "express-session": "^1.17.3",
79
79
  "extend": "^3.0.2",
80
80
  "from2": "^2.3.0",
81
- "fs-extra": "^10.0.0",
81
+ "fs-extra": "^10.1.0",
82
82
  "get-folder-size": "^2.0.1",
83
- "glob": "^7.2.0",
83
+ "glob": "^7.2.3",
84
84
  "global-tunnel-ng": "^2.7.1",
85
85
  "handlebars": "^4.7.7",
86
- "http-proxy-middleware": "^2.0.1",
87
- "inquirer": "^8.2.0",
86
+ "http-proxy-middleware": "^2.0.6",
87
+ "inquirer": "^8.2.4",
88
88
  "into-stream": "^6.0.0",
89
89
  "ip-range-check": "0.2.0",
90
90
  "is-ip": "^3.1.0",
91
91
  "li": "^1.3.0",
92
- "mashlib": "^1.8.0",
93
- "mime-types": "^2.1.34",
94
- "negotiator": "^0.6.2",
92
+ "mashlib": "^1.8.4",
93
+ "mime-types": "^2.1.35",
94
+ "negotiator": "^0.6.3",
95
95
  "node-fetch": "^2.6.7",
96
- "node-forge": "^1.2.1",
96
+ "node-forge": "^1.3.1",
97
97
  "node-mailer": "^0.1.1",
98
- "nodemailer": "^6.7.2",
98
+ "nodemailer": "^6.7.8",
99
99
  "oidc-op-express": "^0.0.3",
100
100
  "owasp-password-strength-test": "^1.3.0",
101
- "rdflib": "^2.2.17",
101
+ "rdflib": "^2.2.20",
102
102
  "recursive-readdir": "^2.2.2",
103
103
  "request": "^2.88.2",
104
104
  "rimraf": "^3.0.2",
@@ -108,7 +108,7 @@
108
108
  "text-encoder-lite": "^2.0.0",
109
109
  "the-big-username-blacklist": "^1.5.2",
110
110
  "ulid": "^2.3.0",
111
- "urijs": "^1.19.10",
111
+ "urijs": "^1.19.11",
112
112
  "uuid": "^8.3.2",
113
113
  "valid-url": "^1.0.9",
114
114
  "validator": "^13.7.0",
@@ -116,23 +116,23 @@
116
116
  },
117
117
  "devDependencies": {
118
118
  "@solid/solid-auth-oidc": "^0.3.0",
119
- "chai": "4.3.4",
119
+ "chai": "^4.3.6",
120
120
  "chai-as-promised": "7.1.1",
121
121
  "cross-env": "7.0.3",
122
122
  "dirty-chai": "2.0.1",
123
123
  "eslint": "^7.32.0",
124
124
  "localstorage-memory": "1.0.3",
125
- "mocha": "9.1.3",
126
- "nock": "^13.2.1",
125
+ "mocha": "^9.2.2",
126
+ "nock": "^13.2.9",
127
127
  "node-mocks-http": "1.11.0",
128
128
  "nyc": "15.1.0",
129
129
  "pre-commit": "1.2.2",
130
130
  "randombytes": "2.1.0",
131
131
  "sinon": "12.0.1",
132
132
  "sinon-chai": "3.7.0",
133
- "snyk": "^1.809.0",
133
+ "snyk": "^1.997.0",
134
134
  "standard": "16.0.4",
135
- "supertest": "6.1.6",
135
+ "supertest": "^6.2.4",
136
136
  "turtle-validator": "1.1.1",
137
137
  "whatwg-url": "11.0.0"
138
138
  },