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

+ + 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",