Skip to content

Commit

Permalink
Feature/42573 chore dependency updates (#1698)
Browse files Browse the repository at this point in the history
* [admin] remove tedious warning message on ../restart.sh

* [admin] add SQL documentation env vars

* [admin] add env var to remove a wanrning from tedious

* [admin] security updates

* [admin] sort alphabetically

* [admin] doc - remove broken link

* [admin] NB developer env var required

In order to make the tedioius option `trustServerCertificate` safe out of the box it is now set to false, meaning the client will always verify the server certificate by default.

Devs need the following line in the .env file:--

SQL_TRUST_SERVER_CERTIFICATE=1

* [admin] bump dependencies

Update mssql and postgrator
Correctly pass SQL_ENCRYPT option into createDatabase

* [admin] remove direct dependency on tedious

* [admin] remove express-validator

* [admin] remove moment

Type errors are liable to arise between moment-timezone and moment as moment-timezone installs it's own version of moment.  It seems easier just to install that version,
which at the time of writing is at n-1 versions out of date, and n+5 versions ahead of our installed version.

Win-win: we don't have to add ts-ignore messages everywhere and we get a newer version of moment.

* [admin]  switch to nocache module instead on helmet.nocache which is deprecated

* [load-test] bump dependencies

* [tslib] bump dependencies

* [func-consumption] bump dependencies

* Fix func-consumption issue on circleci

* [pupil-api] bump dependencies

* [admin] buggy tedious - don't verify SQL Server certificate for now

* [admin] remove useless test

* [admin] refactor pupil-add-service tests

* remove dependcies sinon, proxyquire

* [admin] refactor pupil-validator.spec

* remove sinon

* [admin] clean up access arrangments routes

* [admin] clean up check-window routes

* [admin] clean up routes

* [admin] clean up routes

* [admin] clean up routes

* [admin] Clean up helpdesk routes

* NB - one route is unused / bad route

* [admin] Clean up routes

Co-authored-by: Guy Harwood <[email protected]>
  • Loading branch information
jon-shipley and GuyHarwood authored Aug 4, 2020
1 parent 820a2dc commit 17030dd
Show file tree
Hide file tree
Showing 63 changed files with 3,563 additions and 3,007 deletions.
22 changes: 12 additions & 10 deletions admin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,33 +87,35 @@ The solution will fail to operate correctly without the following environment va
* SAS_TIMEOUT_HOURS - number - the timeout in hours of the SAS token used to submit the completed check to the client
* AZURE_QUEUE_PREFIX - string - a prefix used to construct environment-specific queue names: e.g. `prefix` or `some-prefix`
* AZURE_TABLE_PREFIX - string - a prefix used to construct environment-specific table names: e.g. `prefix` or `somPrefix`
* DEFAULT_ADMIN_PASSWORDHASH - string - a password hash which will be used to overwrite all the `[mtc_admin].[user].[passwordHash]` values when running seeds (`node data/sql/seed-sql.js`)
* DEFAULT_ADMIN_PASSWORDHASH - string - a bcrypt password hash which will be used to overwrite all the `[mtc_admin].[user].[passwordHash]` values when running seeds (`node data/sql/seed-sql.js`)
* WEBSITE_OFFLINE - boolean - disables the admin app and shows a downtime message
* FEATURE_TOGGLE_SCHOOL_RESULTS_ALLOW_FETCH_FROM_DB - allow the schools results to be retrieved from the DB if not in Redis

SQL Server specific environment variables
* SQL_POOL_MIN_COUNT - the minimum number of connections in the pool
* SQL_POOL_MAX_COUNT - the maximum number of connections in the pool
* SQL_POOL_LOG_ENABLED - enables console logging of connection pool activity
* SQL_ADMIN_USER - the server level user account used to perform database migrations.
* SQL_ADMIN_USER_PASSWORD - password for the SQL_ADMIN_USER_PASSWORD.
* SQL_APP_NAME - the name of the application added to log traces. very useful for debugging
* SQL_APP_USER - the username that the application connects as (should be a database level user _only_)
* SQL_APP_USER_PASSWORD - password for the SQL_APP_USER
* SQL_ADMIN_USER - the server level user account used to perform database migrations.
* SQL_ADMIN_USER_PASSWORD - password for the SQL_ADMIN_USER_PASSWORD.
* SQL_SERVER - the server to connect to
* SQL_AZURE_SCALE - the azure specific scale setting for the database. Such as S1, S2, S3 etc. When this is left blank, migrations are assumed to be running in a docker instance of SQL Server
* SQL_DATABASE - the database to connect to
* SQL_ENABLE_ARITH_ABORT - defaults to true. See the [docs](https://tediousjs.github.io/tedious/api-connection.html)
* SQL_ENCRYPT - use encryption to connect to the DB. Defaults to true.
* SQL_POOL_LOG_ENABLED - enables console logging of connection pool activity
* SQL_POOL_MAX_COUNT - the maximum number of connections in the pool
* SQL_POOL_MIN_COUNT - the minimum number of connections in the pool
* SQL_PORT - the port to connect on, defaults to 1433
* SQL_SERVER - the server to connect to
* SQL_TIMEOUT - the time in milliseconds before an operation times out
* SQL_AZURE_SCALE - the azure specific scale setting for the database. Such as S1, S2, S3 etc. When this is left blank, migrations are assumed to be running in a docker instance of SQL Server
* SQL_TRUST_SERVER_CERTIFICATE - if false tedious will verify the server SSL cert. Defaults to false. See the [docs](https://tediousjs.github.io/tedious/api-connection.html)


`config.js` contains defaults for a local sql server instance with matching credentials for the docker compose instance.

#### Using SQL Server

We use [tedious](http://tediousjs.github.io/tedious/) package for SQL Server data operations. This has been abstracted with a connection pool implementation and methods for querying and modifying data have been surfaced via the [sqlService](./services/data-access/sql.service.js) object.

Example usage can be found [here](./sql.usage.example.js)

### Running the test suite

`yarn test`
Expand Down
2 changes: 0 additions & 2 deletions admin/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ const busboy = require('express-busboy')
const config = require('./config')
const csurf = require('csurf')
const express = require('express')
const expressValidator = require('express-validator')
const featureToggles = require('feature-toggles')
const flash = require('connect-flash')
const LocalStrategy = require('passport-local').Strategy
Expand Down Expand Up @@ -210,7 +209,6 @@ app.use(session(sessionOptions))
app.use(passport.initialize())
app.use(passport.session())
app.use(flash())
app.use(expressValidator())

// Breadcrumbs
app.use(breadcrumbs.init())
Expand Down
9 changes: 8 additions & 1 deletion admin/config/sql.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ module.exports = {
options: {
appName: process.env.SQL_APP_NAME || 'mtc-local-dev', // docker default
encrypt: {}.hasOwnProperty.call(process.env, 'SQL_ENCRYPT') ? toBool(process.env.SQL_ENCRYPT) : true,
enableArithAbort: {}.hasOwnProperty.call(process.env, 'SQL_ENABLE_ARITH_ABORT') ? toBool(process.env.SQL_ENABLE_ARITH_ABORT) : true
enableArithAbort: {}.hasOwnProperty.call(process.env, 'SQL_ENABLE_ARITH_ABORT') ? toBool(process.env.SQL_ENABLE_ARITH_ABORT) : true,

// trustServerCertificate: in order to make this app safe by default we *ought* to set the default to false (in
// order to make the client verify the TLS certificate). However, when connecting to Azure this does not work because
// of a bug in the tedious library (https://github.com/tediousjs/tedious/issues/1081) which is resolved in release
// 8.3.1. Our version of tedious comes bundled with mssql - currently at 6.2.0 with tedious version 6.6.2. Once
// the version of tedious is >= 8.3.1 we can reset this back to false by default, which is the more secure setting.
trustServerCertificate: {}.hasOwnProperty.call(process.env, 'SQL_TRUST_SERVER_CERTIFICATE') ? toBool(process.env.SQL_TRUST_SERVER_CERTIFICATE) : true
}
}
35 changes: 30 additions & 5 deletions admin/controllers/access-arrangements.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const controller = {}
* @param next
* @returns {Promise.<void>}
*/
controller.getOverview = async (req, res, next) => {
controller.getOverview = async function getOverview (req, res, next) {
res.locals.pageTitle = 'Enable access arrangements for pupils who need them'
req.breadcrumbs(res.locals.pageTitle)
let pupils
Expand Down Expand Up @@ -63,7 +63,7 @@ controller.getOverview = async (req, res, next) => {
* @param error
* @returns {Promise.<void>}
*/
controller.getSelectAccessArrangements = async (req, res, next, error = null) => {
controller.getSelectAccessArrangements = async function getSelectAccessArrangements (req, res, next, error = null) {
res.locals.pageTitle = 'Select access arrangement for pupil'
req.breadcrumbs('Enable access arrangements for pupils who need them', '/access-arrangements/overview')
req.breadcrumbs('Select pupils and access arrangements')
Expand Down Expand Up @@ -104,7 +104,7 @@ controller.getSelectAccessArrangements = async (req, res, next, error = null) =>
* @param next
* @returns {Promise.<void>}
*/
controller.postSubmitAccessArrangements = async (req, res, next) => {
controller.postSubmitAccessArrangements = async function postSubmitAccessArrangements (req, res, next) {
let pupil
try {
const checkWindowData = await checkWindowV2Service.getActiveCheckWindow()
Expand Down Expand Up @@ -143,7 +143,7 @@ controller.postSubmitAccessArrangements = async (req, res, next) => {
* @param error
* @returns {Promise.<void>}
*/
controller.getEditAccessArrangements = async (req, res, next, error = null) => {
controller.getEditAccessArrangements = async function getEditAccessArrangements (req, res, next, error = null) {
res.locals.pageTitle = 'Edit access arrangement for pupil'
req.breadcrumbs('Enable access arrangements for pupils who need them', '/access-arrangements/overview')
req.breadcrumbs('Edit pupils and access arrangements')
Expand Down Expand Up @@ -195,7 +195,7 @@ controller.getEditAccessArrangements = async (req, res, next, error = null) => {
* @param next
* @returns {Promise.<void>}
*/
controller.getDeleteAccessArrangements = async (req, res, next) => {
controller.getDeleteAccessArrangements = async function getDeleteAccessArrangements (req, res, next) {
let pupil
try {
const checkWindowData = await checkWindowV2Service.getActiveCheckWindow()
Expand All @@ -209,4 +209,29 @@ controller.getDeleteAccessArrangements = async (req, res, next) => {
return res.redirect(`/access-arrangements/overview?hl=${pupil.urlSlug}`)
}

controller.getAddInputAssistant = async function (req, res, next) {
res.locals.pageTitle = 'Record input assistant used for official check'
req.breadcrumbs('Select pupils and access arrangements', 'select-access-arrangements')
req.breadcrumbs('Record input assistant')

try {
const checkWindowData = await checkWindowV2Service.getActiveCheckWindow()
await businessAvailabilityService.determineAccessArrangementsEligibility(checkWindowData)
} catch (error) {
next(error)
}

let pupils
try {
pupils = await pupilAccessArrangementsService.getEligiblePupilsWithFullNames(req.user.schoolId)
} catch (error) {
return next(error)
}
return res.render('access-arrangements/retro-add-input-assistant', {
breadcrumbs: req.breadcrumbs(),
pupils,
error: new ValidationError()
})
}

module.exports = controller
10 changes: 5 additions & 5 deletions admin/controllers/check-window.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const controller = {
* @param next
* @returns {Promise.<void>}
*/
getManageCheckWindows: async (req, res, next) => {
getManageCheckWindows: async function getManageCheckWindows (req, res, next) {
res.locals.pageTitle = 'Manage check windows'
req.breadcrumbs(res.locals.pageTitle)
let checkWindows
Expand All @@ -41,7 +41,7 @@ const controller = {
* @param next
* @returns {Promise.<void>}
*/
createCheckWindow: async (req, res, next) => {
createCheckWindow: async function createCheckWindow (req, res, next) {
res.locals.pageTitle = 'Create check window'
req.breadcrumbs('Manage check windows', '/check-window/manage-check-windows')
req.breadcrumbs(res.locals.pageTitle)
Expand All @@ -60,7 +60,7 @@ const controller = {
* @param next
* @returns {Promise.<void>}
*/
submitCheckWindow: async (req, res, next) => {
submitCheckWindow: async function submitCheckWindow (req, res, next) {
const requestData = req.body
const { checkWindowUrlSlug } = requestData
let flashMessage
Expand Down Expand Up @@ -102,7 +102,7 @@ const controller = {
* @param next
* @returns {Promise.<*>}
*/
removeCheckWindow: async (req, res, next) => {
removeCheckWindow: async function removeCheckWindow (req, res, next) {
const urlSlug = req.params.checkWindowUrlSlug
let checkWindow
try {
Expand All @@ -123,7 +123,7 @@ const controller = {
* @returns {Promise.<void>}
*/

getCheckWindowEditForm: async (req, res, next) => {
getCheckWindowEditForm: async function getCheckWindowEditForm (req, res, next) {
req.breadcrumbs('Manage check windows', '/check-window/manage-check-windows')
res.locals.pageTitle = 'Edit check window'
req.breadcrumbs(res.locals.pageTitle)
Expand Down
10 changes: 5 additions & 5 deletions admin/controllers/group.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const businessAvailabilityService = require('../services/business-availability.s
* @param next
* @returns {Promise<void>}
*/
const groupPupilsPage = async (req, res, next) => {
const groupPupilsPage = async function groupPupilsPage (req, res, next) {
res.locals.pageTitle = 'Organise pupils into groups'

let checkWindowData
Expand Down Expand Up @@ -53,7 +53,7 @@ const groupPupilsPage = async (req, res, next) => {
* @param next
* @returns {Promise<void>}
*/
const manageGroupPage = async (req, res, next) => {
const manageGroupPage = async function manageGroupPage (req, res, next) {
let pupilsList
const selectedPupils = []
let group
Expand Down Expand Up @@ -109,7 +109,7 @@ const manageGroupPage = async (req, res, next) => {
* @param next
* @returns {Promise<*>}
*/
const addGroup = async (req, res, next) => {
const addGroup = async function addGroup (req, res, next) {
if (!req.body.name || !req.body.pupil) {
req.flash('error', 'Missing fields.')
return res.redirect('/group/pupils-list/add')
Expand Down Expand Up @@ -182,7 +182,7 @@ const addGroup = async (req, res, next) => {
* @param next
* @returns {Promise<*>}
*/
const editGroup = async (req, res, next) => {
const editGroup = async function editGroup (req, res, next) {
if (!req.body.name || !req.body.pupil || !req.body.groupId) {
req.flash('error', 'Missing fields.')
return res.redirect('/group/pupils-list/edit')
Expand Down Expand Up @@ -254,7 +254,7 @@ const editGroup = async (req, res, next) => {
return res.redirect('/group/pupils-list')
}

const removeGroup = async (req, res, next) => {
const removeGroup = async function (req, res, next) {
if (!req.params.groupId) {
req.flash('error', 'Missing group id.')
return res.redirect('/group/pupils-list')
Expand Down
22 changes: 11 additions & 11 deletions admin/controllers/hdf.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const attendanceCodeService = require('../services/attendance.service')

const controller = {}

controller.getResults = async (req, res, next) => {
controller.getResults = async function getResults (req, res, next) {
res.locals.pageTitle = 'Results'
const checkWindowData = await checkWindowV2Service.getActiveCheckWindow()
const pupils = await pupilService.findPupilsBySchoolId(req.user.schoolId)
Expand Down Expand Up @@ -55,7 +55,7 @@ controller.getResults = async (req, res, next) => {
}

// TODO: refactor this into a service call
controller.downloadResults = async (req, res, next) => {
controller.downloadResults = async function downloadResults (req, res, next) {
// TODO: refactor to make it smaller
// @ts-ignore needs refactoring to csv.format() - https://c2fo.io/fast-csv/docs/migration-guides/v2.x-to-v3.x/
const csvStream = csv.createWriteStream()
Expand Down Expand Up @@ -128,7 +128,7 @@ controller.downloadResults = async (req, res, next) => {
csvStream.end()
}

controller.getReviewPupilDetails = async (req, res, next) => {
controller.getReviewPupilDetails = async function getReviewPupilDetails (req, res, next) {
res.locals.pageTitle = 'Review pupil details'
req.breadcrumbs("Headteacher's declaration form", '/attendance/declaration-form')
req.breadcrumbs(res.locals.pageTitle)
Expand All @@ -147,7 +147,7 @@ controller.getReviewPupilDetails = async (req, res, next) => {
}
}

controller.getEditReason = async (req, res, next) => {
controller.getEditReason = async function getEditReason (req, res, next) {
res.locals.pageTitle = 'Edit reason for not taking the check'
req.breadcrumbs("Headteacher's declaration form", '/attendance/declaration-form')
req.breadcrumbs('Review pupil details', '/attendance/review-pupil-details')
Expand Down Expand Up @@ -175,7 +175,7 @@ controller.getEditReason = async (req, res, next) => {
})
}

controller.postSubmitEditReason = async (req, res, next) => {
controller.postSubmitEditReason = async function postSubmitEditReason (req, res, next) {
const { urlSlug, attendanceCode } = req.body
try {
const pupil = await headteacherDeclarationService.findPupilBySlugAndSchoolId(urlSlug, req.user.schoolId)
Expand All @@ -188,7 +188,7 @@ controller.postSubmitEditReason = async (req, res, next) => {
}
}

controller.getConfirmSubmit = async (req, res, next) => {
controller.getConfirmSubmit = async function getConfirmSubmit (req, res, next) {
res.locals.pageTitle = 'Confirm and submit'
req.breadcrumbs("Headteacher's declaration form", '/attendance/declaration-form')
req.breadcrumbs('Review pupil details', '/attendance/review-pupil-details')
Expand Down Expand Up @@ -222,7 +222,7 @@ controller.getConfirmSubmit = async (req, res, next) => {
}
}

controller.postConfirmSubmit = async (req, res, next) => {
controller.postConfirmSubmit = async function postConfirmSubmit (req, res, next) {
let validationError = await hdfConfirmValidator.validate(req.body)
if (validationError.hasError()) {
res.error = validationError
Expand All @@ -247,7 +247,7 @@ controller.postConfirmSubmit = async (req, res, next) => {
return res.redirect('/attendance/submitted')
}

controller.getDeclarationForm = async (req, res, next) => {
controller.getDeclarationForm = async function getDeclarationForm (req, res, next) {
res.locals.pageTitle = "Headteacher's declaration form"
req.breadcrumbs(res.locals.pageTitle)

Expand Down Expand Up @@ -278,7 +278,7 @@ controller.getDeclarationForm = async (req, res, next) => {
})
}

controller.postDeclarationForm = async (req, res, next) => {
controller.postDeclarationForm = async function postDeclarationForm (req, res, next) {
const { firstName, lastName, isHeadteacher, jobTitle } = req.body
const form = { firstName, lastName, isHeadteacher, jobTitle }
const checkWindowData = await checkWindowV2Service.getActiveCheckWindow()
Expand Down Expand Up @@ -307,7 +307,7 @@ controller.postDeclarationForm = async (req, res, next) => {
return res.redirect('/attendance/review-pupil-details')
}

controller.getHDFSubmitted = async (req, res, next) => {
controller.getHDFSubmitted = async function getHDFSubmitted (req, res, next) {
res.locals.pageTitle = "Headteacher's declaration form"
req.breadcrumbs(res.locals.pageTitle)
try {
Expand All @@ -327,7 +327,7 @@ controller.getHDFSubmitted = async (req, res, next) => {
}
}

controller.getHDFSubmittedForm = async (req, res, next) => {
controller.getHDFSubmittedForm = async function getHDFSubmittedForm (req, res, next) {
res.locals.pageTitle = 'View submission'
req.breadcrumbs("Headteacher's declaration form", '/attendance/declaration-form')
req.breadcrumbs(res.locals.pageTitle)
Expand Down
6 changes: 3 additions & 3 deletions admin/controllers/helpdesk-impersonation.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const controller = {}
* @param {object} error
* @returns {Promise.<void>}
*/
controller.getSchoolImpersonation = async (req, res, next, error = null) => {
controller.getSchoolImpersonation = async function getSchoolImpersonation (req, res, next, error = null) {
res.locals.pageTitle = 'MTC Helpdesk School Impersonation'
try {
res.locals.isSubmitImpersonationUrl = true
Expand All @@ -34,7 +34,7 @@ controller.getSchoolImpersonation = async (req, res, next, error = null) => {
* @param {function} next
* @returns {Promise.<void>}
*/
controller.postAddSchoolImpersonation = async (req, res, next) => {
controller.postAddSchoolImpersonation = async function postAddSchoolImpersonation (req, res, next) {
const { dfeNumber } = req.body
try {
const validationError = await schoolImpersonationService.setSchoolImpersonation(req.user, dfeNumber)
Expand All @@ -54,7 +54,7 @@ controller.postAddSchoolImpersonation = async (req, res, next) => {
* @param {function} next
* @returns {Promise.<void>}
*/
controller.postRemoveSchoolImpersonation = async (req, res, next) => {
controller.postRemoveSchoolImpersonation = async function postRemoveSchoolImpersonation (req, res, next) {
try {
schoolImpersonationService.removeImpersonation(req.user)
req.flash('info', 'School impersonation has been removed')
Expand Down
2 changes: 1 addition & 1 deletion admin/controllers/helpdesk-summary.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const controller = {}
* @param {function} next
* @returns {Promise.<void>}
*/
controller.getSummary = async (req, res, next) => {
controller.getSummary = async function getSummary (req, res, next) {
res.locals.pageTitle = 'School Summary'
try {
const summaryData = await schoolSummaryService.getSummary(req.user.schoolId)
Expand Down
Loading

0 comments on commit 17030dd

Please sign in to comment.