diff --git a/etc/local.ini b/etc/local.ini index 961b231..10327c6 100644 --- a/etc/local.ini +++ b/etc/local.ini @@ -5,6 +5,12 @@ enable_cors = true origins = * credentials = true +[csp] +attachments_enable = true +; https://docs.couchdb.org/en/stable/cve/2021-38295.html +; use nginx instead to allow only signed couchapps when on deployed server +attachments_header_value = "child-src 'self' data: blob:; default-src 'self'; img-src 'self' data: https://secure.gravatar.com; font-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline';" + [couchdb] single_node=true diff --git a/nyc.config.js b/nyc.config.js index 8c8c223..2f9f2fe 100644 --- a/nyc.config.js +++ b/nyc.config.js @@ -7,7 +7,7 @@ module.exports = { ], 'check-coverage': true, branches: 65, - functions: 66, + functions: 65, lines: 76, statements: 76, reporter: ['text', 'lcov'], diff --git a/test/integration/install.js b/test/integration/install.js index bc500c4..085c01c 100644 --- a/test/integration/install.js +++ b/test/integration/install.js @@ -18,6 +18,8 @@ debug('replay localhosts', replay._localhosts); \"TLS server: In state wait_finished received CLIENT ALERT: Fatal - Certificate Unknown\\n\"}}}" */ let destination = 'http://admin:none@localhost:5984'; +const couchUrl = destination.replace('admin:none@', ''); + if (!destination) { destination = url.parse(config.usersDbConnection.url); destination.auth = `${config.couchKeys.username}:${config.couchKeys.password}`; @@ -525,6 +527,19 @@ describe('install', () => { expect(res.body.ok).to.equal(true); return supertest(destination) + .put(`/${dbnameToReplicate}/_security`) + .set('cookie', adminSessionCookie) + .set('Accept', 'application/json') + .send({ + // The couchapp is public but only admins can write to it + members: { roles: [] }, + admins: { roles: ["_admin"] }, + }); + }) + .then((res) => { + expect(res.body.ok).to.equal(true); + + return supertest(couchUrl) .get(`/${dbnameToReplicate}/_design/prototype`) .set('Accept', 'application/json'); }) @@ -532,12 +547,19 @@ describe('install', () => { debug('res.body prototype after ', res.body); expect(res.body.couchapp && res.body.couchapp.name).to.contain('Prototype (has the most features of the apps)', JSON.stringify(res.body)); - return supertest(destination) + return supertest(couchUrl) .get(`/${dbnameToReplicate}/_design/prototype/user.html`); }) .then((res) => { debug('res.body prototype after ', res.body); expect(res.status).to.equal(200); + + return supertest(couchUrl) + .get(`/${dbnameToReplicate}/_design/prototype/app/app.css`); + }) + .then((res) => { + debug('attachments prototype after ', res.body); + expect(res.status).to.equal(200); }); }); });