Skip to content

Commit f37b3d2

Browse files
committed
Merge branch 'release/v5.0.0' of github.com:solid/node-solid-server into release/v5.0.0
2 parents 5d482aa + c8986cf commit f37b3d2

File tree

13 files changed

+82
-39
lines changed

13 files changed

+82
-39
lines changed

bin/lib/options.js

+16-8
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ module.exports = [
102102
return true
103103
},
104104
when: function (answers) {
105-
return answers.useOwner
105+
return answers['use-owner']
106106
}
107107
},
108108
{
@@ -163,7 +163,7 @@ module.exports = [
163163
name: 'cors-proxy',
164164
help: 'Serve the CORS proxy on this path',
165165
when: function (answers) {
166-
return answers.useCorsProxy
166+
return answers['use-cors-proxy']
167167
},
168168
default: '/proxy',
169169
prompt: true
@@ -253,7 +253,7 @@ module.exports = [
253253
prompt: true,
254254
default: 'smtp.gmail.com',
255255
when: (answers) => {
256-
return answers.useEmail
256+
return answers['use-email']
257257
}
258258
},
259259
{
@@ -262,15 +262,15 @@ module.exports = [
262262
prompt: true,
263263
default: '465',
264264
when: (answers) => {
265-
return answers.useEmail
265+
return answers['use-email']
266266
}
267267
},
268268
{
269269
name: 'email-auth-user',
270270
help: 'User of your email service',
271271
prompt: true,
272272
when: (answers) => {
273-
return answers.useEmail
273+
return answers['use-email']
274274
},
275275
validate: (value) => {
276276
if (!value) {
@@ -285,7 +285,7 @@ module.exports = [
285285
type: 'password',
286286
prompt: true,
287287
when: (answers) => {
288-
return answers.useEmail
288+
return answers['use-email']
289289
}
290290
},
291291
{
@@ -301,7 +301,7 @@ module.exports = [
301301
prompt: true,
302302
validate: validPath,
303303
when: (answers) => {
304-
return answers.useApiApps
304+
return answers['use-api-apps']
305305
}
306306
},
307307
{ // copied from name: 'owner'
@@ -349,7 +349,15 @@ module.exports = [
349349
help: 'URI to your Terms & Conditions',
350350
prompt: true,
351351
validate: validUri,
352-
when: answers => answers.enforceToc
352+
when: answers => answers['enforce-toc']
353+
},
354+
{
355+
name: 'disable-password-checks',
356+
help: 'Do you want to disable password strength checking?',
357+
flag: true,
358+
prompt: true,
359+
default: false,
360+
when: answers => answers.multiuser
353361
},
354362
{
355363
name: 'support-email',

common/js/auth-buttons.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
(({ auth }) => {
44
// Wire up DOM elements
55
const [loginButton, logoutButton, registerButton, accountSettings] =
6-
['login', 'logout', 'register', 'accountSettings'].map(id =>
6+
['login', 'logout', 'register', 'account-settings'].map(id =>
77
document.getElementById(id) || document.createElement('a'))
88
loginButton.addEventListener('click', login)
99
logoutButton.addEventListener('click', logout)
@@ -15,6 +15,7 @@
1515
const isOwner = loggedIn && new URL(session.webId).origin === location.origin
1616
loginButton.classList.toggle('hidden', loggedIn)
1717
logoutButton.classList.toggle('hidden', !loggedIn)
18+
registerButton.classList.toggle('hidden', loggedIn)
1819
accountSettings.classList.toggle('hidden', !isOwner)
1920
})
2021

common/js/solid.js

+15-8
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545
PasswordValidator.prototype.fetchDomNodes = function () {
4646
this.form = this.passwordField.closest('form')
4747

48+
this.disablePasswordChecks = this.passwordField.classList.contains('disable-password-checks')
49+
4850
this.passwordGroup = this.passwordField.closest('.form-group')
4951
this.passwordFeedback = this.passwordGroup.querySelector('.form-control-feedback')
5052
this.passwordStrengthMeter = this.passwordGroup.querySelector('.progress-bar')
@@ -69,8 +71,10 @@
6971
this.errors = []
7072
this.resetValidation(this.passwordGroup)
7173
this.resetFeedbackIcon(this.passwordFeedback)
72-
this.displayPasswordErrors()
73-
this.instantFeedbackForPassword()
74+
if (!this.disablePasswordChecks) {
75+
this.displayPasswordErrors()
76+
this.instantFeedbackForPassword()
77+
}
7478
}
7579

7680
/**
@@ -99,14 +103,17 @@
99103
PasswordValidator.prototype.validatePassword = function () {
100104
this.errors = []
101105
const password = this.passwordField.value
102-
const passwordStrength = this.getPasswordStrength(password)
103-
this.currentStrengthLevel = this.getStrengthLevel(passwordStrength)
104106

105-
if (passwordStrength.errors) {
106-
this.addPasswordError(passwordStrength.errors)
107-
}
107+
if (!this.disablePasswordChecks) {
108+
const passwordStrength = this.getPasswordStrength(password)
109+
this.currentStrengthLevel = this.getStrengthLevel(passwordStrength)
110+
111+
if (passwordStrength.errors) {
112+
this.addPasswordError(passwordStrength.errors)
113+
}
108114

109-
this.checkLeakedPassword(password).then(this.handleLeakedPasswordResponse.bind(this))
115+
this.checkLeakedPassword(password).then(this.handleLeakedPasswordResponse.bind(this))
116+
}
110117

111118
this.setPasswordFeedback()
112119
}

config.json-default

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"logo": ""
1717
},
1818
"enforceToc": true,
19+
"disablePasswordChecks": false,
1920
"tocUri": "https://your-toc",
2021
"supportEmail": "Your support email address"
2122
}

default-views/account/register-form.hbs

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636

3737
<div class="form-group has-feedback">
3838
<label class="control-label" for="password">Password*</label>
39-
<input type="password" class="form-control control-progress" name="password" id="password" required/>
39+
<input type="password" class="form-control control-progress{{#if disablePasswordStrengthCheck}} disable-password-strength-check{{/if}}" name="password" id="password" required/>
4040
<span class="glyphicon glyphicon-remove form-control-feedback hidden" aria-hidden="true"></span>
4141
<div class="progress">
4242
<div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="4"></div>

default-views/auth/login-required.hbs

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
<div class="pull-right">
1414
<button id="register" type="button" class="btn btn-primary">Register</button>
1515
<button id="login" type="button" class="btn btn-success">Log in</button>
16+
<button id="logout" type="button" class="hidden btn btn-danger">Log out</button>
1617
</div>
1718
<h1>Log in to access this resource</h1>
1819
</div>

lib/create-app.js

+1
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ function initAppLocals (app, argv, ldp) {
137137
app.locals.tokenService = new TokenService()
138138
app.locals.enforceToc = argv.enforceToc
139139
app.locals.tocUri = argv.tocUri
140+
app.locals.disablePasswordChecks = argv.disablePasswordChecks
140141

141142
if (argv.email && argv.email.host) {
142143
app.locals.emailService = new EmailService(argv.templates.email, argv.email)

lib/handlers/allow.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ function allow (mode) {
5050
},
5151
suffix: ldp.suffixAcl,
5252
strictOrigin: ldp.strictOrigin,
53-
trustedOrigins: ldp.trustedOrigins
53+
trustedOrigins: [ldp.resourceMapper.resolveUrl(req.hostname)].concat(ldp.trustedOrigins)
5454
})
5555

5656
// Ensure the user has the required permission

lib/ldp-container.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const path = require('path')
1313

1414
async function addContainerStats (ldp, reqUri, filename, resourceGraph) {
1515
const containerStats = await ldp.stat(filename)
16-
addStats(resourceGraph, reqUri, containerStats)
16+
addStats(resourceGraph, reqUri, containerStats, filename)
1717
resourceGraph.add(
1818
resourceGraph.sym(reqUri),
1919
ns.rdf('type'),
@@ -24,7 +24,7 @@ async function addContainerStats (ldp, reqUri, filename, resourceGraph) {
2424
ns.ldp('Container'))
2525
}
2626

27-
async function addFile (ldp, resourceGraph, containerUri, reqUri, uri, container, file) {
27+
async function addFile (ldp, resourceGraph, containerUri, reqUri, container, file) {
2828
// Skip .meta and .acl
2929
if (file.endsWith(ldp.suffixMeta) || file.endsWith(ldp.suffixAcl)) {
3030
return null
@@ -42,7 +42,7 @@ async function addFile (ldp, resourceGraph, containerUri, reqUri, uri, container
4242
let memberUri = reqUri + (stats.isDirectory() ? '/' : '')
4343

4444
// Add fileStats to resource Graph
45-
addStats(resourceGraph, memberUri, stats)
45+
addStats(resourceGraph, memberUri, stats, file)
4646

4747
// Add to `contains` list
4848
resourceGraph.add(
@@ -106,7 +106,7 @@ async function addFile (ldp, resourceGraph, containerUri, reqUri, uri, container
106106
return null
107107
}
108108

109-
function addStats (resourceGraph, reqUri, stats) {
109+
function addStats (resourceGraph, reqUri, stats, filename) {
110110
resourceGraph.add(
111111
resourceGraph.sym(reqUri),
112112
ns.stat('mtime'), // Deprecate?
@@ -122,8 +122,8 @@ function addStats (resourceGraph, reqUri, stats) {
122122
ns.stat('size'),
123123
stats.size)
124124

125-
if (mime.lookup(reqUri)) { // Is the file has a well-known type,
126-
let type = 'http://www.w3.org/ns/iana/media-types/' + mime.lookup(reqUri) + '#Resource'
125+
if (mime.lookup(filename)) { // Is the file has a well-known type,
126+
let type = 'http://www.w3.org/ns/iana/media-types/' + mime.lookup(filename) + '#Resource'
127127
resourceGraph.add(
128128
resourceGraph.sym(reqUri),
129129
ns.rdf('type'), // convert MIME type to RDF

lib/ldp.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ class LDP {
113113
return this.readResource(url + this.suffixMeta)
114114
}
115115

116-
async listContainer (filename, reqUri, uri, containerData, contentType) {
116+
async listContainer (filename, reqUri, containerData, hostname) {
117117
const resourceGraph = $rdf.graph()
118118

119119
try {
@@ -129,9 +129,10 @@ class LDP {
129129
// read directory
130130
const files = await ldpContainer.readdir(filename)
131131
// iterate through all the files
132-
await Promise.all(files.map(file => {
133-
const fileUri = url.resolve(reqUri, encodeURIComponent(file))
134-
return ldpContainer.addFile(this, resourceGraph, reqUri, fileUri, uri, filename, file)
132+
await Promise.all(files.map(async file => {
133+
const { url: fileUri } = await this.resourceMapper.mapFileToUrl(
134+
{ path: path.join(filename, file), hostname })
135+
return await ldpContainer.addFile(this, resourceGraph, reqUri, fileUri, filename, file)
135136
}))
136137
} catch (err) {
137138
throw error(500, "Can't list container")
@@ -340,7 +341,6 @@ class LDP {
340341
} catch (err) {
341342
throw error(404, 'Can\'t find file requested: ' + options)
342343
}
343-
const baseUri = this.resourceMapper.resolveUrl(options.hostname)
344344

345345
// Just return, since resource exists
346346
if (!options.includeBody) {
@@ -355,7 +355,7 @@ class LDP {
355355
.catch(() => '') // Default to an empty meta file if it is missing
356356
let data
357357
try {
358-
data = await this.listContainer(filename, absContainerUri, baseUri, metaFile, contentType)
358+
data = await this.listContainer(filename, absContainerUri, metaFile, options.hostname)
359359
} catch (err) {
360360
debug.handlers('GET container -- Read error:' + err.message)
361361
throw err

lib/requests/create-account-request.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class CreateAccountRequest extends AuthRequest {
3838
this.username = options.username
3939
this.userAccount = options.userAccount
4040
this.acceptToc = options.acceptToc
41+
this.disablePasswordChecks = options.disablePasswordChecks
4142
}
4243

4344
/**
@@ -69,6 +70,7 @@ class CreateAccountRequest extends AuthRequest {
6970

7071
options.enforceToc = locals.enforceToc
7172
options.tocUri = locals.tocUri
73+
options.disablePasswordChecks = locals.disablePasswordChecks
7274

7375
switch (authMethod) {
7476
case 'oidc':
@@ -113,7 +115,8 @@ class CreateAccountRequest extends AuthRequest {
113115
multiuser: this.accountManager.multiuser,
114116
registerDisabled: authMethod === 'tls',
115117
returnToUrl: this.returnToUrl,
116-
tocUri: this.tocUri
118+
tocUri: this.tocUri,
119+
disablePasswordChecks: this.disablePasswordChecks
117120
})
118121

119122
if (error) {

test/integration/authentication-oidc-test.js

+19-1
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ describe('Authentication API (OIDC)', () => {
212212
})
213213
})
214214

215-
// Our origin isn't trusted by default
215+
// Our origin is trusted by default
216216
describe('with that cookie and our origin', () => {
217217
let response
218218
before(done => {
@@ -225,6 +225,24 @@ describe('Authentication API (OIDC)', () => {
225225
})
226226
})
227227

228+
it('should return a 200', () => {
229+
expect(response).to.have.property('status', 200)
230+
})
231+
})
232+
233+
// Another origin isn't trusted by default
234+
describe('with that cookie and our origin', () => {
235+
let response
236+
before(done => {
237+
alice.get('/')
238+
.set('Cookie', cookie)
239+
.set('Origin', 'https://some.other.domain.com')
240+
.end((err, res) => {
241+
response = res
242+
done(err)
243+
})
244+
})
245+
228246
it('should return a 403', () => {
229247
expect(response).to.have.property('status', 403)
230248
})

test/integration/ldp-test.js

+9-6
Original file line numberDiff line numberDiff line change
@@ -285,18 +285,18 @@ describe('LDP', function () {
285285
' dcterms:title "This is a container" ;' +
286286
' o:limit 500000.00 .', 'sampleContainer/basicContainerFile.ttl')
287287

288-
return ldp.listContainer(path.join(__dirname, '../resources/sampleContainer/'), 'https://server.tld/resources/sampleContainer/', 'https://server.tld', '', 'text/turtle')
288+
return ldp.listContainer(path.join(__dirname, '../resources/sampleContainer/'), 'https://server.tld/resources/sampleContainer/', '', 'server.tld')
289289
.then(data => {
290290
var graph = $rdf.graph()
291291
$rdf.parse(
292292
data,
293293
graph,
294-
'https://server.tld/sampleContainer',
294+
'https://localhost:8443/resources/sampleContainer',
295295
'text/turtle')
296296

297297
var basicContainerStatements = graph
298298
.each(
299-
$rdf.sym('https://server.tld/basicContainerFile.ttl'),
299+
$rdf.sym('https://localhost:8443/resources/sampleContainer/basicContainerFile.ttl'),
300300
ns.rdf('type'),
301301
undefined
302302
)
@@ -310,7 +310,7 @@ describe('LDP', function () {
310310

311311
var containerStatements = graph
312312
.each(
313-
$rdf.sym('https://server.tld/containerFile.ttl'),
313+
$rdf.sym('https://localhost:8443/resources/sampleContainer/containerFile.ttl'),
314314
ns.rdf('type'),
315315
undefined
316316
)
@@ -324,15 +324,18 @@ describe('LDP', function () {
324324
})
325325

326326
it('should ldp:contains the same files in dir', () => {
327-
ldp.listContainer(path.join(__dirname, '../resources/sampleContainer/'), 'https://server.tld/resources/sampleContainer/', 'https://server.tld', '', 'text/turtle')
327+
ldp.listContainer(path.join(__dirname, '../resources/sampleContainer/'), 'https://server.tld/resources/sampleContainer/', '', 'server.tld')
328328
.then(data => {
329329
fs.readdir(path.join(__dirname, '../resources/sampleContainer/'), function (err, expectedFiles) {
330+
// Strip dollar extension
331+
expectedFiles = expectedFiles.map(ldp.resourceMapper._removeDollarExtension)
332+
330333
if (err) {
331334
return Promise.reject(err)
332335
}
333336

334337
const graph = $rdf.graph()
335-
$rdf.parse(data, graph, 'https://server.tld/sampleContainer/', 'text/turtle')
338+
$rdf.parse(data, graph, 'https://localhost:8443/resources/sampleContainer/', 'text/turtle')
336339
const statements = graph.match(null, ns.ldp('contains'), null)
337340
const files = statements
338341
.map(s => s.object.value.replace(/.*\//, ''))

0 commit comments

Comments
 (0)