diff --git a/ui/app/services/token.js b/ui/app/services/token.js index c8e5d52fab70..c11453e23401 100644 --- a/ui/app/services/token.js +++ b/ui/app/services/token.js @@ -1,6 +1,6 @@ import Service, { inject as service } from '@ember/service'; import { computed } from '@ember/object'; -import { alias } from '@ember/object/computed'; +import { alias, reads } from '@ember/object/computed'; import { getOwner } from '@ember/application'; import { assign } from '@ember/polyfills'; import { task } from 'ember-concurrency'; @@ -42,6 +42,8 @@ export default class TokenService extends Service { }) fetchSelfToken; + @reads('fetchSelfToken.lastSuccessful.value') selfToken; + async exchangeOneTimeToken(oneTimeToken) { const TokenAdapter = getOwner(this).lookup('adapter:token'); @@ -49,12 +51,6 @@ export default class TokenService extends Service { this.secret = token.secret; } - @computed('secret', 'fetchSelfToken.lastSuccessful.value') - get selfToken() { - if (this.secret) return this.get('fetchSelfToken.lastSuccessful.value'); - return undefined; - } - @task(function*() { try { if (this.selfToken) { diff --git a/ui/tests/acceptance/proxy-test.js b/ui/tests/acceptance/proxy-test.js new file mode 100644 index 000000000000..582a57e767f1 --- /dev/null +++ b/ui/tests/acceptance/proxy-test.js @@ -0,0 +1,51 @@ +/* eslint-disable ember-a11y-testing/a11y-audit-called */ // Tests for non-UI behaviour. +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; +import { setupMirage } from 'ember-cli-mirage/test-support'; +import Jobs from 'nomad-ui/tests/pages/jobs/list'; + +let managementToken; + +module('Acceptance | reverse proxy', function(hooks) { + setupApplicationTest(hooks); + setupMirage(hooks); + + hooks.beforeEach(function() { + window.localStorage.clear(); + window.sessionStorage.clear(); + + server.create('agent'); + managementToken = server.create('token'); + + // Simulate a reverse proxy injecting X-Nomad-Token header for all requests + this._originalXMLHttpRequestSend = XMLHttpRequest.prototype.send; + (function(send) { + XMLHttpRequest.prototype.send = function(data) { + this.setRequestHeader('X-Nomad-Token', managementToken.secretId); + send.call(this, data); + }; + })(this._originalXMLHttpRequestSend); + }); + + hooks.afterEach(function() { + XMLHttpRequest.prototype.send = this._originalXMLHttpRequestSend; + }); + + test('when token is inserted by a reverse proxy, the UI is adjusted', async function(assert) { + // when token is inserted by reserve proxy, the token is reverse proxy + const { secretId } = managementToken; + + await Jobs.visit(); + assert.ok(window.localStorage.nomadTokenSecret == null, 'No token secret set'); + + // Make sure that server received the header + assert.ok( + server.pretender.handledRequests + .mapBy('requestHeaders') + .every(headers => headers['X-Nomad-Token'] === secretId), + 'The token header is always present' + ); + + assert.notOk(Jobs.runJobButton.isDisabled, 'Run job button is enabled'); + }); +});