-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
PP-12395: Create API key functionality
Creating an API key consists of two pages: the "API key name" and "New API key" pages. Validation of the name/description and cypress test will be done in the next PRs.
- Loading branch information
1 parent
c9643af
commit c2a8d0c
Showing
11 changed files
with
268 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
5 changes: 4 additions & 1 deletion
5
app/controllers/simplified-account/settings/api-keys/api-keys.controller.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,17 @@ | ||
const { response } = require('@utils/response') | ||
const apiKeysService = require('@services/api-keys.service') | ||
const formatSimplifiedAccountPathsFor = require('@utils/simplified-account/format/format-simplified-account-paths-for') | ||
const paths = require('@root/paths') | ||
|
||
async function get (req, res) { | ||
const activeKeys = await apiKeysService.getActiveKeys(req.account.id) | ||
return response(req, res, 'simplified-account/settings/api-keys/index', { | ||
accountType: req.account.type, | ||
activeKeys, | ||
createApiKeyLink: '#', | ||
createApiKeyLink: formatSimplifiedAccountPathsFor(paths.simplifiedAccount.settings.apiKeys.create, req.service.externalId, req.account.type), | ||
showRevokedKeysLink: '#' | ||
}) | ||
} | ||
|
||
module.exports = { get } | ||
module.exports.createApiKey = require('./create/create-api-key.controller') |
22 changes: 22 additions & 0 deletions
22
app/controllers/simplified-account/settings/api-keys/create/create-api-key.controller.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
const { response } = require('@utils/response') | ||
const formatSimplifiedAccountPathsFor = require('@utils/simplified-account/format/format-simplified-account-paths-for') | ||
const paths = require('@root/paths') | ||
const { TOKEN_SOURCE, createApiKey } = require('@services/api-keys.service') | ||
|
||
async function get (req, res) { | ||
return response(req, res, 'simplified-account/settings/api-keys/api-key-name', { | ||
backLink: formatSimplifiedAccountPathsFor(paths.simplifiedAccount.settings.apiKeys.index, req.service.externalId, req.account.type) | ||
}) | ||
} | ||
|
||
async function post (req, res) { | ||
const description = req.body.description // TODO validate length - deal with this in another PR | ||
const newApiKey = await createApiKey(req.account, description, req.user.email, TOKEN_SOURCE.API) | ||
response(req, res, 'simplified-account/settings/api-keys/new-api-key-details', { | ||
description, | ||
apiKey: newApiKey, | ||
backToApiKeysLink: formatSimplifiedAccountPathsFor(paths.simplifiedAccount.settings.apiKeys.index, req.service.externalId, req.account.type) | ||
}) | ||
} | ||
|
||
module.exports = { get, post } |
85 changes: 85 additions & 0 deletions
85
...controllers/simplified-account/settings/api-keys/create/create-api-key.controller.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
const ControllerTestBuilder = require('@test/test-helpers/simplified-account/controllers/ControllerTestBuilder.class') | ||
const sinon = require('sinon') | ||
const { expect } = require('chai') | ||
const formatSimplifiedAccountPathsFor = require('@utils/simplified-account/format/format-simplified-account-paths-for') | ||
const paths = require('@root/paths') | ||
const { TOKEN_SOURCE } = require('@services/api-keys.service') | ||
|
||
const ACCOUNT_TYPE = 'live' | ||
const SERVICE_ID = 'service-id-123abc' | ||
const mockResponse = sinon.spy() | ||
const newApiKey = 'api_test_123' // pragma: allowlist secret | ||
const apiKeysService = { | ||
createApiKey: sinon.stub().resolves(newApiKey), | ||
TOKEN_SOURCE | ||
} | ||
|
||
const { | ||
req, | ||
res, | ||
nextRequest, | ||
call | ||
} = new ControllerTestBuilder('@controllers/simplified-account/settings/api-keys/create/create-api-key.controller') | ||
.withServiceExternalId(SERVICE_ID) | ||
.withAccountType(ACCOUNT_TYPE) | ||
.withStubs({ | ||
'@utils/response': { response: mockResponse }, | ||
'@services/api-keys.service': apiKeysService | ||
}) | ||
.build() | ||
|
||
describe('Controller: settings/create-api-key', () => { | ||
describe('get', () => { | ||
before(() => { | ||
call('get') | ||
}) | ||
|
||
it('should call the response method', () => { | ||
expect(mockResponse).to.have.been.calledOnce // eslint-disable-line | ||
}) | ||
|
||
it('should pass req, res and template path to the response method', () => { | ||
expect(mockResponse).to.have.been.calledWith(req, res, 'simplified-account/settings/api-keys/api-key-name') | ||
}) | ||
|
||
it('should pass context data to the response method', () => { | ||
expect(mockResponse.args[0][3]).to.have.property('backLink').to.equal( | ||
formatSimplifiedAccountPathsFor(paths.simplifiedAccount.settings.apiKeys.index, SERVICE_ID, ACCOUNT_TYPE)) | ||
}) | ||
}) | ||
|
||
describe('post', () => { | ||
before(() => { | ||
nextRequest({ | ||
body: { | ||
description: 'a test api key' | ||
}, | ||
user: { | ||
email: 'potter@wand.com' | ||
} | ||
}) | ||
call('post') | ||
}) | ||
|
||
it('should submit values to the api keys service', () => { | ||
expect(apiKeysService.createApiKey).to.have.been.calledWith( | ||
sinon.match.any, | ||
'a test api key', | ||
'potter@wand.com', | ||
TOKEN_SOURCE.API | ||
) | ||
}) | ||
|
||
it('should call the response method', () => { | ||
expect(mockResponse).to.have.been.calledOnce // eslint-disable-line | ||
}) | ||
|
||
it('should pass context data to the response method', () => { | ||
expect(mockResponse.args[0][2]).to.equal('simplified-account/settings/api-keys/new-api-key-details') | ||
expect(mockResponse.args[0][3]).to.have.property('backToApiKeysLink').to.equal( | ||
formatSimplifiedAccountPathsFor(paths.simplifiedAccount.settings.apiKeys.index, SERVICE_ID, ACCOUNT_TYPE)) | ||
expect(mockResponse.args[0][3]).to.have.property('apiKey').to.equal(newApiKey) | ||
expect(mockResponse.args[0][3]).to.have.property('description').to.equal('a test api key') | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
34 changes: 34 additions & 0 deletions
34
app/views/simplified-account/settings/api-keys/api-key-name.njk
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
{% extends "../settings-layout.njk" %} | ||
|
||
{% block settingsPageTitle %} | ||
API key name | ||
{% endblock %} | ||
|
||
{% block settingsContent %} | ||
|
||
<h1 class="govuk-heading-l page-title">API key name</h1> | ||
|
||
<form id="api-key-name" method="post" novalidate> | ||
<input id="csrf" name="csrfToken" type="hidden" value="{{ csrf }}"/> | ||
|
||
{{ govukInput({ | ||
id: "description", | ||
name: "description", | ||
type: "text", | ||
attributes: { | ||
maxlength: "100" | ||
}, | ||
classes: "govuk-input--width-40", | ||
label: { | ||
text: "Add a description for the key" | ||
}, | ||
hint: { | ||
text: "For example, “John Smith’s API key”" | ||
} | ||
}) }} | ||
|
||
{{ govukButton({ | ||
text: "Continue" | ||
}) }} | ||
</form> | ||
{% endblock %} |
69 changes: 69 additions & 0 deletions
69
app/views/simplified-account/settings/api-keys/new-api-key-details.njk
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
{% extends "../settings-layout.njk" %} | ||
|
||
{% block settingsPageTitle %} | ||
New API key | ||
{% endblock %} | ||
|
||
{% block settingsContent %} | ||
|
||
{{ govukBackLink({ | ||
text: "Back to API keys", | ||
href: backToApiKeysLink | ||
}) }} | ||
|
||
<h1 class="govuk-heading-l page-title">New API key</h1> | ||
|
||
{% set html %} | ||
<p class="govuk-body"> | ||
Copy your key to somewhere safe.</br></br>You won’t be able to see it again once you leave this page. | ||
</p> | ||
{% endset %} | ||
|
||
{{ govukInsetText({ | ||
html: html | ||
}) }} | ||
|
||
<p class="govuk-body"> | ||
You must copy the whole key, including the <span class="key-prefix">api_test_</span> or <span class="key-prefix">api_live_</span> prefix. | ||
</p> | ||
|
||
{{ govukWarningText( | ||
{ | ||
text: 'API security', | ||
iconFallbackText: 'Warning' | ||
} | ||
) }} | ||
|
||
<ul class="govuk-list govuk-list--bullet"> | ||
<li>You must store your API keys securely.</li> | ||
<li>You must not share this key in publicly accessible documents or repositories.</li> | ||
<li>You must not share it with anyone who should not be using the GOV.UK Pay API directly.</li> | ||
</ul> | ||
|
||
<p class="govuk-body"> | ||
More about <a class="govuk-link" href="https://docs.payments.service.gov.uk/security/#securing-your-developer-keys"> | ||
securing your API keys</a>. | ||
</p> | ||
|
||
<h2 class="govuk-heading-m"> | ||
{{ description }} | ||
</h2> | ||
<div> | ||
<span id="apiKey" class="code copy-this-api-key govuk-!-margin-top-6">{{ apiKey }}</span> | ||
</div> | ||
|
||
{{ govukButton({ | ||
text: "Copy API key to clipboard", | ||
classes: "govuk-button--secondary govuk-!-margin-top-6", | ||
attributes: { | ||
id: "generate-button", | ||
"data-copy-text": true, | ||
"data-target": "copy-this-api-key", | ||
"data-success": "API key has been copied", | ||
"data-notification-target": "copy-this-api-key-notification" | ||
} | ||
}) }} | ||
|
||
<div class="copy-this-api-key-notification govuk-visually-hidden" aria-live="assertive"></div> | ||
|
||
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters