diff --git a/src/apps.js b/src/apps.js index 2733df6ec..5d999060e 100644 --- a/src/apps.js +++ b/src/apps.js @@ -1049,7 +1049,7 @@ function setAutomaticUpdate(appId, enable, auditSource, callback) { function setRobotsTxt(appId, robotsTxt, auditSource, callback) { assert.strictEqual(typeof appId, 'string'); - assert(!robotsTxt || typeof robotsTxt === 'string'); + assert(robotsTxt === null || typeof robotsTxt === 'string'); assert.strictEqual(typeof auditSource, 'object'); assert.strictEqual(typeof callback, 'function'); @@ -1059,14 +1059,17 @@ function setRobotsTxt(appId, robotsTxt, auditSource, callback) { error = validateRobotsTxt(robotsTxt); if (error) return callback(error); - appdb.update(appId, { robotsTxt: robotsTxt }, function (error) { - if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new AppsError(AppsError.NOT_FOUND, 'No such app')); - if (error) return callback(new AppsError(AppsError.INTERNAL_ERROR, error)); + reverseProxy.writeAppConfig(_.extend({}, app, { robotsTxt }), function (error) { + if (error) return callback(new AppsError(AppsError.EXTERNAL_ERROR, 'Error writing nginx config')); - // TODO: call reverseProxy config re-write here - eventlog.add(eventlog.ACTION_APP_CONFIGURE, auditSource, { appId: appId, app: app, robotsTxt: robotsTxt }); + appdb.update(appId, { robotsTxt: robotsTxt }, function (error) { + if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new AppsError(AppsError.NOT_FOUND, 'No such app')); + if (error) return callback(new AppsError(AppsError.INTERNAL_ERROR, error)); - callback(); + eventlog.add(eventlog.ACTION_APP_CONFIGURE, auditSource, { appId: appId, app: app, robotsTxt: robotsTxt }); + + callback(); + }); }); }); } diff --git a/src/reverseproxy.js b/src/reverseproxy.js index 5ee758885..f69f2b37c 100644 --- a/src/reverseproxy.js +++ b/src/reverseproxy.js @@ -23,6 +23,7 @@ exports = module.exports = { unconfigureApp: unconfigureApp, writeAdminConfig: writeAdminConfig, + writeAppConfig: writeAppConfig, reload: reload, removeAppConfigs: removeAppConfigs, @@ -502,6 +503,27 @@ function writeAppRedirectNginxConfig(app, fqdn, bundle, callback) { reload(callback); } +function writeAppConfig(app, callback) { + assert.strictEqual(typeof app, 'object'); + assert.strictEqual(typeof callback, 'function'); + + getCertificate(app.fqdn, app.domain, function (error, bundle) { + if (error) return callback(error); + + writeAppNginxConfig(app, bundle, function (error) { + if (error) return callback(error); + + async.eachSeries(app.alternateDomains, function (alternateDomain, iteratorDone) { + getCertificate(alternateDomain.fqdn, alternateDomain.domain, function (error, bundle) { + if (error) return iteratorDone(error); + + writeAppRedirectNginxConfig(app, alternateDomain.fqdn, bundle, iteratorDone); + }); + }, callback); + }); + }); +} + function configureApp(app, auditSource, callback) { assert.strictEqual(typeof app, 'object'); assert.strictEqual(typeof auditSource, 'object'); @@ -513,11 +535,11 @@ function configureApp(app, auditSource, callback) { writeAppNginxConfig(app, bundle, function (error) { if (error) return callback(error); - async.eachSeries(app.alternateDomains, function (alternateDomain, callback) { + async.eachSeries(app.alternateDomains, function (alternateDomain, iteratorDone) { ensureCertificate(alternateDomain.fqdn, alternateDomain.domain, auditSource, function (error, bundle) { - if (error) return callback(error); + if (error) return iteratorDone(error); - writeAppRedirectNginxConfig(app, alternateDomain.fqdn, bundle, callback); + writeAppRedirectNginxConfig(app, alternateDomain.fqdn, bundle, iteratorDone); }); }, callback); }); diff --git a/src/routes/test/apps-test.js b/src/routes/test/apps-test.js index 860f74a88..1092a221a 100644 --- a/src/routes/test/apps-test.js +++ b/src/routes/test/apps-test.js @@ -1040,6 +1040,47 @@ describe('App API', function () { }); }); + describe('configure robotsTxt', function () { + it('fails with missing robotsTxt', function (done) { + superagent.post(SERVER_URL + '/api/v1/apps/' + APP_ID + '/configure/robots_txt') + .query({ access_token: token }) + .end(function (err, res) { + expect(res.statusCode).to.equal(400); + done(); + }); + }); + + it('fails with bad robotsTxt', function (done) { + superagent.post(SERVER_URL + '/api/v1/apps/' + APP_ID + '/configure/robots_txt') + .query({ access_token: token }) + .send({ robotsTxt: 34 }) + .end(function (err, res) { + expect(res.statusCode).to.equal(400); + done(); + }); + }); + + it('can set robotsTxt', function (done) { + superagent.post(SERVER_URL + '/api/v1/apps/' + APP_ID + '/configure/robots_txt') + .query({ access_token: token }) + .send({ robotsTxt: 'any string is good' }) + .end(function (err, res) { + expect(res.statusCode).to.equal(200); + done(); + }); + }); + + it('can reset robotsTxt', function (done) { + superagent.post(SERVER_URL + '/api/v1/apps/' + APP_ID + '/configure/robots_txt') + .query({ access_token: token }) + .send({ robotsTxt: null }) + .end(function (err, res) { + expect(res.statusCode).to.equal(200); + done(); + }); + }); + }); + describe('configure location', function () { it('cannot reconfigure app with missing domain', function (done) { superagent.post(SERVER_URL + '/api/v1/apps/' + APP_ID + '/configure/location')