-
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-13133 simplified account settings - edit service name
- added middlewares and router supporting simplified account routes - simplified account opt in: directs the user to an appropriate error message if a simplified account route is accessed without the user being opted in and the feature being enabled for the environment - simplified account strategy: retrieves the correct gateway account for the service and account type and makes this available on the request object - added service settings navigation nunjucks template and supporting sass - added settings controllers - index: redirects the user to the correct default setting based on the account type and go live stage of the service - service name: get and post actions for viewing and updating the current service name in english and welsh - email notifications: bare bones implementation of the view - external dependency: express-validations, creates easy to understand validation chains used for parsing request bodies - added utilities - nunjucks filter for correctly capitalising service settings and categories - generator for simplified account paths - settings builder: determines which settings should be visible based on the service go live stage, account type and permissions of the viewing user
- Loading branch information
Showing
29 changed files
with
682 additions
and
15 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
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,35 @@ | ||
// https://getbem.com/naming/ | ||
|
||
.service-settings-nav { | ||
@include govuk-font(16); | ||
} | ||
|
||
.service-settings-nav__h3 { | ||
@include govuk-font(19); | ||
@include govuk-typography-weight-regular(); | ||
margin: 0; | ||
padding: govuk-spacing(2) govuk-spacing(3) govuk-spacing(2) 0; | ||
color: govuk-colour("dark-grey"); | ||
} | ||
|
||
.service-settings-nav__li { | ||
@include govuk-font(16); | ||
position: relative; | ||
margin-bottom: govuk-spacing(1); | ||
padding-top: govuk-spacing(1); | ||
padding-bottom: govuk-spacing(1); | ||
} | ||
|
||
.service-settings-nav__li--active:before { | ||
content: ''; | ||
position: absolute; | ||
left: -14px; | ||
top: 0; | ||
height: 100%; | ||
width: 4px; | ||
background-color: $govuk-brand-colour; | ||
} | ||
|
||
.service-settings-nav__li--active { | ||
@include govuk-typography-weight-bold(); | ||
} |
9 changes: 9 additions & 0 deletions
9
...rollers/simplified-account/settings/email-notifications/email-notifications.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,9 @@ | ||
const { response } = require('../../../../utils/response') | ||
|
||
function get (req, res) { | ||
return response(req, res, 'simplified-account/settings/email-notifications/index') | ||
} | ||
|
||
module.exports = { | ||
get | ||
} |
Empty file.
22 changes: 22 additions & 0 deletions
22
app/controllers/simplified-account/settings/index.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 @@ | ||
'use strict' | ||
|
||
const formatSimplifiedAccountPathsFor = require('../../../utils/simplified-account/format/format-simplified-account-paths-for') | ||
const paths = require('../../../paths') | ||
const { LIVE } = require('../../../models/go-live-stage') | ||
|
||
function get (req, res) { | ||
const account = req.account | ||
const service = req.service | ||
// the default setting for the index view is dependent on the account type and go live state | ||
if (account.type === 'test' && service.currentGoLiveStage !== LIVE) { | ||
return res.redirect(formatSimplifiedAccountPathsFor(paths.simplifiedAccount.settings.serviceName.index, req.account.service_id, req.account.type)) | ||
} else if (account.type === 'live') { | ||
return res.redirect(formatSimplifiedAccountPathsFor(paths.simplifiedAccount.settings.serviceName.index, req.account.service_id, req.account.type)) | ||
} else { | ||
return res.redirect(formatSimplifiedAccountPathsFor(paths.simplifiedAccount.settings.emailNotifications.index, req.account.service_id, req.account.type)) | ||
} | ||
} | ||
|
||
module.exports = { | ||
get | ||
} |
Empty file.
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,5 @@ | ||
'use strict' | ||
|
||
module.exports.index = require('./index.controller') | ||
module.exports.serviceName = require('./service-name/service-name.controller') | ||
module.exports.emailNotifications = require('./email-notifications/email-notifications.controller') |
70 changes: 70 additions & 0 deletions
70
app/controllers/simplified-account/settings/service-name/service-name.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,70 @@ | ||
'use strict' | ||
const { body, validationResult } = require('express-validator') | ||
const { SERVICE_NAME_MAX_LENGTH } = require('../../../../utils/validation/server-side-form-validations') | ||
const { response } = require('../../../../utils/response') | ||
const { updateServiceName } = require('../../../../services/service.service') | ||
const paths = require('../../../../paths') | ||
const formatSimplifiedAccountPathsFor = require('../../../../utils/simplified-account/format/format-simplified-account-paths-for') | ||
const formatValidationErrors = require('../../../../utils/simplified-account/format/format-validation-errors') | ||
|
||
function get (req, res) { | ||
const context = { | ||
service_name_en: req.service.serviceName.en, | ||
service_name_cy: req.service.serviceName.cy, | ||
manage_en: formatSimplifiedAccountPathsFor(paths.simplifiedAccount.settings.serviceName.edit, req.account.service_id, req.account.type), | ||
manage_cy: formatSimplifiedAccountPathsFor(paths.simplifiedAccount.settings.serviceName.edit, req.account.service_id, req.account.type) + '?cy=true' | ||
} | ||
return response(req, res, 'simplified-account/settings/service-name/index', context) | ||
} | ||
|
||
function getEditServiceName (req, res) { | ||
const editCy = req.query.cy === 'true' | ||
const context = { | ||
edit_cy: editCy, | ||
back_link: formatSimplifiedAccountPathsFor(paths.simplifiedAccount.settings.serviceName.index, req.account.service_id, req.account.type), | ||
submit_link: formatSimplifiedAccountPathsFor(paths.simplifiedAccount.settings.serviceName.edit, req.account.service_id, req.account.type) | ||
} | ||
if (editCy) { | ||
Object.assign(context, { service_name: req.service.serviceName.cy }) | ||
} else { | ||
Object.assign(context, { service_name: req.service.serviceName.en }) | ||
} | ||
return response(req, res, 'simplified-account/settings/service-name/edit-service-name', context) | ||
} | ||
|
||
async function postEditServiceName (req, res) { | ||
const editCy = req.body.cy === 'true' | ||
const validations = [ | ||
body('service-name-input').trim().isLength({ max: SERVICE_NAME_MAX_LENGTH }).withMessage(`Service name must be ${SERVICE_NAME_MAX_LENGTH} characters or fewer`) | ||
] | ||
// we don't check presence for welsh names | ||
if (!editCy) { | ||
validations.push(body('service-name-input').trim().notEmpty().withMessage('Service name is required')) | ||
} | ||
|
||
await Promise.all(validations.map(validation => validation.run(req))) | ||
const errors = validationResult(req) | ||
if (!errors.isEmpty()) { | ||
const formattedErrors = formatValidationErrors(errors) | ||
return response(req, res, 'simplified-account/settings/service-name/edit-service-name', { | ||
errors: { | ||
summary: formattedErrors.errorSummary, | ||
formErrors: formattedErrors.formErrors | ||
}, | ||
edit_cy: editCy, | ||
service_name: req.body['service-name-input'], | ||
back_link: formatSimplifiedAccountPathsFor(paths.simplifiedAccount.settings.serviceName.index, req.account.service_id, req.account.type), | ||
submit_link: formatSimplifiedAccountPathsFor(paths.simplifiedAccount.settings.serviceName.edit, req.account.service_id, req.account.type) | ||
}) | ||
} | ||
|
||
const newServiceName = req.body['service-name-input'] | ||
editCy ? await updateServiceName(req.account.service_id, req.service.serviceName.en, newServiceName) : await updateServiceName(req.account.service_id, newServiceName, req.service.serviceName.cy) | ||
res.redirect(formatSimplifiedAccountPathsFor(paths.simplifiedAccount.settings.serviceName.index, req.account.service_id, req.account.type)) | ||
} | ||
|
||
module.exports = { | ||
get, | ||
getEditServiceName, | ||
postEditServiceName | ||
} |
Empty file.
9 changes: 9 additions & 0 deletions
9
app/middleware/simplified-account/simplified-account-opt-in.middleware.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,9 @@ | ||
const { InvalidConfigurationError } = require('../../errors') | ||
|
||
module.exports = function checkDegatewayParameters (req, res, next) { | ||
const user = req.user | ||
if (user.isDegatewayed()) { | ||
return next() | ||
} | ||
return next(new InvalidConfigurationError(`User with id ${user.externalId} not opted in to account simplification or feature is disabled in this environment.`)) | ||
} |
101 changes: 101 additions & 0 deletions
101
app/middleware/simplified-account/simplified-account-strategy.middleware.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,101 @@ | ||
'use strict' | ||
// EXTERNAL IMPORTS | ||
const _ = require('lodash') | ||
const { keys } = require('@govuk-pay/pay-js-commons').logging | ||
// LOCAL IMPORTS | ||
const { addField } = require('../../services/clients/base/request-context') | ||
const Connector = require('../../services/clients/connector.client.js').ConnectorClient | ||
const { getSwitchingCredentialIfExists } = require('../../utils/credentials') | ||
const { SERVICE_EXTERNAL_ID, ACCOUNT_TYPE, ENVIRONMENT_ID } = require('../../paths').keys | ||
const logger = require('../../utils/logger')(__filename) | ||
const connectorClient = new Connector(process.env.CONNECTOR_URL) | ||
|
||
function getService (user, serviceExternalId, gatewayAccountId) { | ||
let service | ||
const serviceRoles = _.get(user, 'serviceRoles', []) | ||
|
||
if (serviceRoles.length > 0) { | ||
if (serviceExternalId) { | ||
service = _.get(serviceRoles.find(serviceRole => { | ||
return (serviceRole.service.externalId === serviceExternalId && | ||
(!gatewayAccountId || serviceRole.service.gatewayAccountIds.includes(String(gatewayAccountId)))) | ||
}), 'service') | ||
} | ||
} | ||
|
||
return service | ||
} | ||
|
||
async function getGatewayAccountByServiceIdAndAccountType (serviceExternalId, accountType) { | ||
try { | ||
const params = { | ||
serviceId: serviceExternalId, | ||
accountType | ||
} | ||
let account = await connectorClient.getAccountByServiceIdAndAccountType(params) | ||
|
||
account = _.extend({}, account, { | ||
supports3ds: ['worldpay', 'stripe', 'epdq', 'smartpay'].includes(account.payment_provider), | ||
disableToggle3ds: account.payment_provider === 'stripe' | ||
}) | ||
|
||
const switchingCredential = getSwitchingCredentialIfExists(account) | ||
const isSwitchingToStripe = switchingCredential && switchingCredential.payment_provider === 'stripe' | ||
if (account.payment_provider === 'stripe' || isSwitchingToStripe) { | ||
const stripeAccountSetup = await connectorClient.getStripeAccountSetup(account.gateway_account_id) | ||
if (stripeAccountSetup) { | ||
account.connectorGatewayAccountStripeProgress = stripeAccountSetup | ||
} | ||
} | ||
|
||
return account | ||
} catch (err) { | ||
const logContext = { | ||
error: err.message, | ||
error_code: err.errorCode | ||
} | ||
|
||
if (err.errorCode === 404) { | ||
logger.info('Gateway account not found', logContext) | ||
} else { | ||
logger.error('Error retrieving gateway account', logContext) | ||
} | ||
} | ||
} | ||
|
||
module.exports = async function getSimplifiedAccount (req, res, next) { | ||
try { | ||
if (req.user) { | ||
const serviceExternalId = req.params[SERVICE_EXTERNAL_ID] | ||
const accountType = req.params[ACCOUNT_TYPE] | ||
const environment = req.params[ENVIRONMENT_ID] | ||
|
||
if (!serviceExternalId || !accountType) { | ||
throw new Error('Could not resolve service external ID or gateway account type from request params') | ||
} | ||
|
||
let gatewayAccount = await getGatewayAccountByServiceIdAndAccountType(serviceExternalId, accountType) | ||
if (gatewayAccount) { | ||
req.account = gatewayAccount | ||
addField(keys.GATEWAY_ACCOUNT_ID, gatewayAccount.gateway_account_id) | ||
addField(keys.GATEWAY_ACCOUNT_TYPE, gatewayAccount.type) | ||
req.gateway_account = { | ||
currentGatewayAccountExternalId: gatewayAccount.external_id | ||
} | ||
} | ||
const service = getService(req.user, serviceExternalId, gatewayAccount.gateway_account_id) | ||
if (service) { | ||
req.service = service | ||
addField(keys.SERVICE_EXTERNAL_ID, service.externalId) | ||
} | ||
|
||
if (environment) { | ||
req.isLive = environment === 'live' | ||
} | ||
} | ||
|
||
next() | ||
} catch (err) { | ||
next(err) | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
'use strict' | ||
|
||
module.exports = str => { | ||
if (str === undefined) return | ||
return str.charAt(0).toUpperCase() + str.slice(1) | ||
} |
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
Oops, something went wrong.