diff --git a/common/js/auth-buttons.js b/common/js/auth-buttons.js
index 49c28840e..248b17535 100644
--- a/common/js/auth-buttons.js
+++ b/common/js/auth-buttons.js
@@ -1,6 +1,7 @@
/* Provide functionality for authentication buttons */
+/* global URL, location, alert, solid */
-(({ auth }) => {
+(({ auth }, $rdf) => {
// Wire up DOM elements
const [loginButton, logoutButton, registerButton, accountSettings] =
['login', 'logout', 'register', 'account-settings'].map(id =>
@@ -8,6 +9,9 @@
loginButton.addEventListener('click', login)
logoutButton.addEventListener('click', logout)
registerButton.addEventListener('click', register)
+ if ($rdf) {
+ document.addEventListener('DOMContentLoaded', getAccountInfo)
+ }
// Track authentication status and update UI
auth.trackSession(session => {
@@ -46,4 +50,59 @@
registration.searchParams.set('returnToUrl', location)
location.href = registration
}
-})(solid)
+
+ async function getAccountInfo () {
+ const SOLID = $rdf.Namespace('http://www.w3.org/ns/solid/terms#')
+
+ // get DOM and data-dependencies
+ const storagePanel = document.getElementById('StoragePanel')
+ const storageQuota = document.getElementById('StorageQuota')
+ const storageUsage = document.getElementById('StorageUsage')
+ const storageUsedBar = document.getElementById('StorageUsedBar')
+ if (!storagePanel || !storageQuota || !storageUsage || !storageUsedBar) {
+ // If anything of these elements are not available, we do not need to do anything more
+ return
+ }
+
+ // load data
+ const accountUrl = new URL('/account', location).href
+ const accountStore = $rdf.graph()
+ const accountFetcher = new $rdf.Fetcher(accountStore)
+ await accountFetcher.load(accountUrl)
+ const quotaNode = accountStore.any($rdf.sym(accountUrl), SOLID('storageQuota'))
+ const usageNode = accountStore.any($rdf.sym(accountUrl), SOLID('storageUsage'))
+ if (!quotaNode || !usageNode) {
+ // If data is not available, we do not need to do anything more
+ return
+ }
+
+ // manipulate DOM to present data
+ storagePanel.classList.remove('hidden')
+ const quotaValue = quotaNode.value
+ storageQuota.innerText = formatBytes(quotaValue)
+ const usageValue = usageNode.value
+ storageUsage.innerText = formatBytes(usageValue)
+ const usagePercent = Math.floor(usageValue / quotaValue * 1000) / 10
+ storageUsedBar.innerText = `${usagePercent}%`
+ storageUsedBar.setAttribute('aria-valuenow', usagePercent)
+ storageUsedBar.style.width = `${usagePercent}%`
+ }
+
+ function formatBytes (number, units = [
+ 'B',
+ 'kB',
+ 'MB',
+ 'GB',
+ 'TB',
+ 'PB',
+ 'EB',
+ 'ZB',
+ 'YB'
+ ]) {
+ const unit = units.shift()
+ if (number > 1000 && units.length > 0) {
+ return formatBytes(number / 1000, units)
+ }
+ return `${Math.round(number * 100) / 100} ${unit}`
+ }
+})(solid, window.$rdf)
diff --git a/default-templates/new-account/index.html b/default-templates/new-account/index.html
index 7fe96bfa7..b1da6afef 100644
--- a/default-templates/new-account/index.html
+++ b/default-templates/new-account/index.html
@@ -69,6 +69,25 @@
Account settings
+
+
+ Storage
+
+
+ -
+ Storage used:
+ 0
+
+ -
+ Storage available:
+ 0
+
+
+
diff --git a/lib/acl-checker.js b/lib/acl-checker.js
index ece53a64d..ba22895b8 100644
--- a/lib/acl-checker.js
+++ b/lib/acl-checker.js
@@ -5,6 +5,8 @@ const debug = require('./debug').ACL
const HTTPError = require('./http-error')
const aclCheck = require('@solid/acl-check')
const { URL } = require('url')
+const { promisify } = require('util')
+const fs = require('fs')
const DEFAULT_ACL_SUFFIX = '.acl'
const ACL = rdf.Namespace('http://www.w3.org/ns/auth/acl#')
@@ -144,6 +146,49 @@ class ACLChecker {
isAcl (resource) {
return resource.endsWith(this.suffix)
}
+
+ static createFromLDPAndRequest (resource, ldp, req) {
+ const trustedOrigins = ldp.getTrustedOrigins(req)
+ return new ACLChecker(resource, {
+ agentOrigin: req.get('origin'),
+ // host: req.get('host'),
+ fetch: fetchFromLdp(ldp.resourceMapper),
+ fetchGraph: (uri, options) => {
+ // first try loading from local fs
+ return ldp.getGraph(uri, options.contentType)
+ // failing that, fetch remote graph
+ .catch(() => ldp.fetchGraph(uri, options))
+ },
+ suffix: ldp.suffixAcl,
+ strictOrigin: ldp.strictOrigin,
+ trustedOrigins
+ })
+ }
+}
+
+/**
+ * Returns a fetch document handler used by the ACLChecker to fetch .acl
+ * resources up the inheritance chain.
+ * The `fetch(uri, callback)` results in the callback, with either:
+ * - `callback(err, graph)` if any error is encountered, or
+ * - `callback(null, graph)` with the parsed RDF graph of the fetched resource
+ * @return {Function} Returns a `fetch(uri, callback)` handler
+ */
+function fetchFromLdp (mapper) {
+ return async function fetch (url, graph = rdf.graph()) {
+ // Convert the URL into a filename
+ let path, contentType
+ try {
+ ({ path, contentType } = await mapper.mapUrlToFile({ url }))
+ } catch (err) {
+ throw new HTTPError(404, err)
+ }
+ // Read the file from disk
+ const body = await promisify(fs.readFile)(path, {'encoding': 'utf8'})
+ // Parse the file as Turtle
+ rdf.parse(body, graph, url, contentType)
+ return graph
+ }
}
// Returns the index of the last slash before the given position
diff --git a/lib/api/accounts/user-accounts.js b/lib/api/accounts/user-accounts.js
index cc5daafd0..e2ed163bd 100644
--- a/lib/api/accounts/user-accounts.js
+++ b/lib/api/accounts/user-accounts.js
@@ -8,6 +8,7 @@ const CreateAccountRequest = require('../../requests/create-account-request')
const AddCertificateRequest = require('../../requests/add-cert-request')
const DeleteAccountRequest = require('../../requests/delete-account-request')
const DeleteAccountConfirmRequest = require('../../requests/delete-account-confirm-request')
+const GetAccountInfoRequest = require('../../requests/get-account-info-request')
/**
* Returns an Express middleware handler for checking if a particular account
@@ -70,6 +71,8 @@ function middleware (accountManager) {
router.post('/api/accounts/cert', bodyParser, newCertificate(accountManager))
+ router.get('/account', GetAccountInfoRequest.get)
+
router.get('/account/delete', DeleteAccountRequest.get)
router.post('/account/delete', bodyParser, DeleteAccountRequest.post)
diff --git a/lib/handlers/allow.js b/lib/handlers/allow.js
index 756f48554..80bbd4811 100644
--- a/lib/handlers/allow.js
+++ b/lib/handlers/allow.js
@@ -1,12 +1,8 @@
module.exports = allow
-const $rdf = require('rdflib')
const path = require('path')
const ACL = require('../acl-checker')
const debug = require('../debug.js').ACL
-const fs = require('fs')
-const { promisify } = require('util')
-const HTTPError = require('../http-error')
function allow (mode, checkPermissionsForDirectory) {
return async function allowHandler (req, res, next) {
@@ -43,25 +39,8 @@ function allow (mode, checkPermissionsForDirectory) {
resourcePath += '/'
}
- let trustedOrigins = [ldp.resourceMapper.resolveUrl(req.hostname)].concat(ldp.trustedOrigins)
- if (ldp.multiuser) {
- trustedOrigins.push(ldp.serverUri)
- }
// Obtain and store the ACL of the requested resource
- req.acl = new ACL(rootUrl + resourcePath, {
- agentOrigin: req.get('origin'),
- // host: req.get('host'),
- fetch: fetchFromLdp(ldp.resourceMapper),
- fetchGraph: (uri, options) => {
- // first try loading from local fs
- return ldp.getGraph(uri, options.contentType)
- // failing that, fetch remote graph
- .catch(() => ldp.fetchGraph(uri, options))
- },
- suffix: ldp.suffixAcl,
- strictOrigin: ldp.strictOrigin,
- trustedOrigins: trustedOrigins
- })
+ req.acl = ACL.createFromLDPAndRequest(rootUrl + resourcePath, ldp, req)
// Ensure the user has the required permission
const userId = req.session.userId
@@ -74,28 +53,3 @@ function allow (mode, checkPermissionsForDirectory) {
next(error)
}
}
-
-/**
- * Returns a fetch document handler used by the ACLChecker to fetch .acl
- * resources up the inheritance chain.
- * The `fetch(uri, callback)` results in the callback, with either:
- * - `callback(err, graph)` if any error is encountered, or
- * - `callback(null, graph)` with the parsed RDF graph of the fetched resource
- * @return {Function} Returns a `fetch(uri, callback)` handler
- */
-function fetchFromLdp (mapper) {
- return async function fetch (url, graph = $rdf.graph()) {
- // Convert the URL into a filename
- let path, contentType
- try {
- ({ path, contentType } = await mapper.mapUrlToFile({ url }))
- } catch (err) {
- throw new HTTPError(404, err)
- }
- // Read the file from disk
- const body = await promisify(fs.readFile)(path, {'encoding': 'utf8'})
- // Parse the file as Turtle
- $rdf.parse(body, graph, url, contentType)
- return graph
- }
-}
diff --git a/lib/ldp.js b/lib/ldp.js
index bcc7a5ee3..006bc2cc2 100644
--- a/lib/ldp.js
+++ b/lib/ldp.js
@@ -463,6 +463,14 @@ class LDP {
return ensureNotExists(this, path.join(containerURI, filename))
}
+ getTrustedOrigins (req) {
+ let trustedOrigins = [this.resourceMapper.resolveUrl(req.hostname)].concat(this.trustedOrigins)
+ if (this.multiuser) {
+ trustedOrigins.push(this.serverUri)
+ }
+ return trustedOrigins
+ }
+
static mimeTypeIsRdf (mimeType) {
return RDF_MIME_TYPES.has(mimeType)
}
diff --git a/lib/requests/get-account-info-request.js b/lib/requests/get-account-info-request.js
new file mode 100644
index 000000000..6243652fd
--- /dev/null
+++ b/lib/requests/get-account-info-request.js
@@ -0,0 +1,83 @@
+'use strict'
+
+const ACLChecker = require('../acl-checker')
+const AuthRequest = require('./auth-request')
+const { actualSize } = require('../utils')
+const $rdf = require('rdflib')
+const HTTPError = require('../http-error')
+
+const PIM = $rdf.Namespace('http://www.w3.org/ns/pim/space#')
+const SOLID = $rdf.Namespace('http://www.w3.org/ns/solid/terms#')
+
+class GetAccountInfoRequest extends AuthRequest {
+ static async get (req, res) {
+ const contentType = req.get('content-type') || 'text/turtle'
+ const body = await getBody(req, contentType)
+ if (body.status && body.status >= 400) {
+ return res.status(body.status).send(body.message)
+ }
+ return res.status(200).set('Content-Type', contentType).send(body)
+ }
+}
+
+async function getBody (req, contentType) {
+ const userId = req.session.userId
+ if (!userId) {
+ return new HTTPError(401, 'Requires authentication')
+ }
+ const ldp = req.app.locals.ldp
+ const rootUrl = `${ldp.resourceMapper.resolveUrl(req.hostname)}/`
+ const acl = ACLChecker.createFromLDPAndRequest(rootUrl, ldp, req)
+ const isAllowed = await acl.can(userId, 'Control')
+ if (!isAllowed) {
+ return await req.acl.getError(userId, 'Control')
+ }
+
+ // Dereference graph for webId
+ let userIdGraph
+ try {
+ userIdGraph = await ldp.getGraph(userId)
+ } catch (err) {
+ return err
+ }
+
+ // Get object value for pim:storage
+ const storageUrlNode = userIdGraph.any($rdf.sym(userId), PIM('storage'))
+ if (!storageUrlNode) {
+ return new HTTPError(404, 'Unable to find pim:storage for webId')
+ }
+
+ // Dereference graph for serverSide.ttl
+ const serverSideUrl = `${storageUrlNode.value}settings/serverSide.ttl` // needs to be hardcoded for now
+ let serverSideGraph
+ try {
+ serverSideGraph = await ldp.getGraph(serverSideUrl)
+ } catch (err) {
+ return err
+ }
+
+ // Get object value for solid:storageQuota
+ const quotaNode = serverSideGraph.any(storageUrlNode, SOLID('storageQuota'), null)
+ if (!quotaNode) {
+ return new HTTPError(404, 'Unable to find solid:storageQuota')
+ }
+
+ // Get size of user's POD
+ const root = ldp.resourceMapper.getFullPath(rootUrl)
+ const size = await actualSize(root)
+
+ // Add triples to graph
+ const store = $rdf.graph()
+ store.add(storageUrlNode, SOLID('storageUsage'), $rdf.lit(size))
+ store.add(storageUrlNode, SOLID('storageQuota'), quotaNode)
+ return await new Promise((resolve, reject) => {
+ $rdf.serialize(null, store, storageUrlNode.value, contentType, (err, result) => {
+ if (err) {
+ return reject(err)
+ }
+ resolve(result)
+ })
+ })
+}
+
+module.exports = GetAccountInfoRequest
diff --git a/lib/utils.js b/lib/utils.js
index 21e5f6870..79b76bd35 100644
--- a/lib/utils.js
+++ b/lib/utils.js
@@ -11,6 +11,7 @@ module.exports.getQuota = getQuota
module.exports.overQuota = overQuota
module.exports.getContentType = getContentType
module.exports.parse = parse
+module.exports.actualSize = actualSize
const fs = require('fs')
const path = require('path')
diff --git a/package-lock.json b/package-lock.json
index c59356d20..d1ac34b23 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1604,7 +1604,7 @@
},
"readable-stream": {
"version": "2.3.6",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"requires": {
"core-util-is": "~1.0.0",
@@ -1628,7 +1628,7 @@
},
"browserify-aes": {
"version": "1.2.0",
- "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
+ "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
"integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
"requires": {
"buffer-xor": "^1.0.3",
@@ -2052,7 +2052,7 @@
},
"readable-stream": {
"version": "2.3.6",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"requires": {
"core-util-is": "~1.0.0",
@@ -2194,7 +2194,7 @@
},
"create-hash": {
"version": "1.2.0",
- "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
+ "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
"integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
"requires": {
"cipher-base": "^1.0.1",
@@ -2206,7 +2206,7 @@
},
"create-hmac": {
"version": "1.1.7",
- "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
+ "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
"integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
"requires": {
"cipher-base": "^1.0.3",
@@ -2472,7 +2472,7 @@
"dependencies": {
"minimist": {
"version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
}
}
@@ -2494,7 +2494,7 @@
},
"diffie-hellman": {
"version": "5.0.3",
- "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
+ "resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
"integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
"requires": {
"bn.js": "^4.1.0",
@@ -2602,7 +2602,7 @@
},
"readable-stream": {
"version": "2.3.6",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"requires": {
"core-util-is": "~1.0.0",
@@ -3455,7 +3455,7 @@
},
"readable-stream": {
"version": "2.3.6",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"requires": {
"core-util-is": "~1.0.0",
@@ -3577,7 +3577,7 @@
},
"readable-stream": {
"version": "2.3.6",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
@@ -3861,7 +3861,7 @@
},
"http-errors": {
"version": "1.6.3",
- "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
+ "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
"integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
"requires": {
"depd": "~1.1.2",
@@ -4237,7 +4237,7 @@
},
"is-obj": {
"version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
+ "resolved": "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
"integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
"dev": true
},
@@ -4414,7 +4414,7 @@
},
"json5": {
"version": "0.5.1",
- "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
+ "resolved": "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
"integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE="
},
"jsonfile": {
@@ -4675,16 +4675,6 @@
"js-tokens": "^3.0.0 || ^4.0.0"
}
},
- "lru-cache": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.4.tgz",
- "integrity": "sha512-EPstzZ23znHUVLKj+lcXO1KvZkrlw+ZirdwvOmnAnA/1PB4ggyXJ77LRkCqkff+ShQ+cqoxCxLQOh4cKITO5iA==",
- "dev": true,
- "requires": {
- "pseudomap": "^1.0.2",
- "yallist": "^3.0.2"
- }
- },
"macos-release": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/macos-release/-/macos-release-1.1.0.tgz",
@@ -4923,7 +4913,7 @@
"dependencies": {
"commander": {
"version": "2.15.1",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
+ "resolved": "http://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
"integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==",
"dev": true
},
@@ -4990,7 +4980,7 @@
},
"readable-stream": {
"version": "2.3.6",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"requires": {
"core-util-is": "~1.0.0",
@@ -6539,7 +6529,7 @@
},
"os-locale": {
"version": "1.4.0",
- "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
+ "resolved": "http://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
"integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
"dev": true,
"requires": {
@@ -6644,7 +6634,7 @@
},
"parse-asn1": {
"version": "5.1.1",
- "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz",
+ "resolved": "http://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz",
"integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==",
"requires": {
"asn1.js": "^4.0.0",
@@ -6869,7 +6859,7 @@
},
"proxy-agent": {
"version": "2.3.1",
- "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-2.3.1.tgz",
+ "resolved": "http://registry.npmjs.org/proxy-agent/-/proxy-agent-2.3.1.tgz",
"integrity": "sha512-CNKuhC1jVtm8KJYFTS2ZRO71VCBx3QSA92So/e6NrY6GoJonkx3Irnk4047EsCcswczwqAekRj3s8qLRGahSKg==",
"dev": true,
"requires": {
@@ -6892,11 +6882,27 @@
"ms": "^2.1.1"
}
},
+ "lru-cache": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+ "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+ "dev": true,
+ "requires": {
+ "pseudomap": "^1.0.2",
+ "yallist": "^2.1.2"
+ }
+ },
"ms": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
"dev": true
+ },
+ "yallist": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
+ "dev": true
}
}
},
@@ -7042,7 +7048,7 @@
},
"readable-stream": {
"version": "2.3.6",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"requires": {
"core-util-is": "~1.0.0",
@@ -7412,7 +7418,7 @@
},
"sha.js": {
"version": "2.4.11",
- "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
+ "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
"integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
"requires": {
"inherits": "^2.0.1",
@@ -7733,7 +7739,7 @@
},
"external-editor": {
"version": "2.2.0",
- "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz",
+ "resolved": "http://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz",
"integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==",
"dev": true,
"requires": {
@@ -8161,11 +8167,27 @@
"ms": "^2.1.1"
}
},
+ "lru-cache": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+ "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+ "dev": true,
+ "requires": {
+ "pseudomap": "^1.0.2",
+ "yallist": "^2.1.2"
+ }
+ },
"ms": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
"dev": true
+ },
+ "yallist": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
+ "dev": true
}
}
},
@@ -8205,11 +8227,27 @@
"ms": "^2.1.1"
}
},
+ "lru-cache": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+ "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+ "dev": true,
+ "requires": {
+ "pseudomap": "^1.0.2",
+ "yallist": "^2.1.2"
+ }
+ },
"ms": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
"dev": true
+ },
+ "yallist": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
+ "dev": true
}
}
},
@@ -8495,7 +8533,7 @@
},
"readable-stream": {
"version": "2.3.6",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"requires": {
"core-util-is": "~1.0.0",
@@ -8533,7 +8571,7 @@
},
"readable-stream": {
"version": "2.3.6",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"requires": {
"core-util-is": "~1.0.0",
@@ -8574,7 +8612,7 @@
},
"readable-stream": {
"version": "2.3.6",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"requires": {
"core-util-is": "~1.0.0",
@@ -8612,7 +8650,7 @@
},
"readable-stream": {
"version": "2.3.6",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"requires": {
"core-util-is": "~1.0.0",
@@ -8730,7 +8768,7 @@
},
"readable-stream": {
"version": "2.3.6",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
@@ -8910,7 +8948,7 @@
},
"readable-stream": {
"version": "2.3.6",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"requires": {
"core-util-is": "~1.0.0",
@@ -9435,7 +9473,7 @@
},
"wrap-ansi": {
"version": "2.1.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+ "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
"integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
"dev": true,
"requires": {
@@ -9526,12 +9564,6 @@
"integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
"dev": true
},
- "yallist": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz",
- "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==",
- "dev": true
- },
"yargs": {
"version": "3.32.0",
"resolved": "http://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz",
diff --git a/package.json b/package.json
index 2568865e8..a4e8f6c67 100644
--- a/package.json
+++ b/package.json
@@ -43,8 +43,8 @@
"homepage": "https://github.com/solid/node-solid-server",
"bugs": "https://github.com/solid/node-solid-server/issues",
"dependencies": {
- "@solid/oidc-auth-manager": "^0.17.1",
"@solid/acl-check": "^0.1.3",
+ "@solid/oidc-auth-manager": "^0.17.1",
"body-parser": "^1.18.3",
"bootstrap": "^3.3.7",
"busboy": "^0.2.12",