Skip to content
Permalink
Browse files
Completed Lab Sheet
  • Loading branch information
aa7401 committed Nov 10, 2019
2 parents 40b2dd1 + 783713a commit e471c1c1c581e5a4a52cc8c8a2ad547f7fff0cb6
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 32 deletions.
@@ -83,21 +83,18 @@ So how can we improve this security? The simplest way is to use AES256-GCM encry

In this section we will be implementing more granular authorisation by creating an admin-only area on the website:

1. Add an extra boolean field to the database called `admin` with a default value of `false`.
2. Manually modify one of your registered accounts and change the stored value to `true`, this will be your admin user.
3. When a user logs in, check this field and, if it is set to true, create a new session variable called `admin` and assign it a value of `true`.
4. Create a new admin page, `admin.handlebars` and make sure it is protected in the same way as the home page.
5. Create a link to this new page from the homepage.
6. Modify the page so that, if the user does not have admin authorisation they get redirected back to the home page which should display a message **You do not have admin privileges!**.

## 5 Extension Tasks

Congratulations, you now have a working secure website shell which can be used as the base code for your coursework. You should now consider the following:

1. Start by encrypting your cookies using an appropriate npm package.
2. The website is currently using a relational database (SQLite). If you plan on using a different form of persistence such as a document database (eg MongoDB) or a graph database (eg Neo4J) this is the time to make the change. Make sure the existing functionality works with your chosen persistence technology.
3. In your last lab you learned how to build list and details pages and connect these together. Read your assignment brief carefully and decide if and how you will implement these. You should start work on this part of your project at the earliest opportunity.
4. You will need to implement one or more forms as part of your assignment. Analyse the problem and build template files containing your required forms. Also implement the code required to process this data and add it to your preferred database.
1. Create a secure admin page:
1. Add an extra boolean field to the database called `admin` with a default value of `false`.
2. Manually modify one of your registered accounts and change the stored value to `true`, this will be your admin user.
3. When a user logs in, check this field and, if it is set to true, create a new session variable called `admin` and assign it a value of `true`.
4. Create a new admin page, `admin.handlebars` and make sure it is protected in the same way as the home page.
5. Create a link to this new page from the homepage.
6. Modify the page so that, if the user does not have admin authorisation they get redirected back to the home page which should display a message **You do not have admin privileges!**.
2. Modify the secure pages (home and admin) so that they displays the username of the currently logged-in user:
1. Start by modifying the `post('login')` callback, adding a second key called `username` to the `ctx.session` object to store the username.
2. Modify the code that logs the user out to remove this key.
3. Now change the callback for the secure home page so that it sends this data to the handlebars template.
4. Finally create a placeholder in the template to display this information.

## Advanced Topics

Binary file not shown.
@@ -1,6 +1,25 @@
#!/usr/bin/env bash

# force the script to exit on first fail
set -e

# create any directories needed by the test script
mkdir -p screenshots

# delete any local databases (if you are using them)
rm -rf *.db

# install packages if none found
# [ ! -d "node_modules" ] && echo "INSTALLING MODULES" && npm install

# start the web server in background mode
node index.js&

# run the test suite in background mode
node_modules/.bin/cucumber-js ./features -r ./steps &
sleep 2

# wait for the tests to complete
sleep 5

# kill the web server
pkill node
@@ -0,0 +1,23 @@
Feature: Adding Items
The user should be able to add items to the list.

Scenario: add single item
Given The browser is open on the home page
When I enter "bread" in the "item" field
When I enter "42" in the "qty" field
When I click on the submit button
Then the heading should be "ToDo List"
Then the list should contain "1" rows
Then the list should contain a single entry for "bread"
Then the item should be "bread"
Then the "bread" quantity should be "42"

Scenario: add multiple items
Given The browser is open on the home page
When I enter "butter" in the "item" field
When I enter "24" in the "qty" field
When I click on the submit button
Then the heading should be "ToDo List"
Then the list should contain "2" rows
Then the list should contain a single entry for "bread"
Then the item should be "bread"

This file was deleted.

@@ -41,6 +41,10 @@ When('I click on the submit button', async() => {
await page.click('#submit')
})

Then('take a screenshot called {string}', async filename => {
await page.screenshot({ path: `screenshots/${filename}.png` })
})

Then('the heading should be {string}', async heading => {
const text = await page.evaluate( () => {
const dom = document.querySelector('h1')
@@ -49,7 +53,8 @@ Then('the heading should be {string}', async heading => {
assert.equal(heading, text)
})

Then('the list should contain {string} row', async rowCount => {
Then('the list should contain {string} rows', async rowCount => {
rowCount = Number(rowCount)
const items = await page.evaluate( () => {
const dom = document.querySelectorAll('table tr td:first-child')
const arr = Array.from(dom)
@@ -66,3 +71,22 @@ Then('the item should be {string}', async item => {
})
assert.equal(item, items[0])
})

Then('the list should contain a single entry for {string}', async item => {
const items = await page.evaluate( () => {
const dom = document.querySelectorAll('table tr td:first-child')
const arr = Array.from(dom).map(td => td.innerText)
return arr
})
const count = items.reduce( (acc, val) => (val === item ? acc += 1 : acc), 0)
assert.equal(count, 1)
})

Then('the {string} quantity should be {string}', async(item, qty) => {
const items = await page.evaluate( () => {
const dom = document.querySelectorAll('table tr')
// const arr = Array.from(dom)
return dom
})
assert.equal(2, 2)
})
@@ -68,14 +68,20 @@ describe('todo list', () => {
const arr = Array.from(dom)
return arr.map(td => td.innerText)
})
const numRows = items.reduce( (acc, val) => (val === 'bread' ? acc += 1 : acc), 0)

// this is a more concise way to achieve the same result...
console.log(`numRows: ${numRows}`)

// returns the number of rows containing the given string
const items2 = await page.evaluate(() => Array
.from(document.querySelectorAll('table tr td:first-child'))
.map(td => td.innerHTML) )
.map(td => td.innerHTML)
.reduce( (acc, val) => (val === 'bread' ? acc += 1 : acc), 0)
)

expect(items.length).toBe(1)
expect(items[0]).toBe('bread')
expect(numRows).toBe(1)

// grab a screenshot
const image = await page.screenshot()
@@ -4,11 +4,13 @@
"description": "",
"main": "index.js",
"scripts": {
"start-server": "node index.js",
"linter": "node_modules/.bin/eslint .",
"test": "node_modules/.bin/jest --coverage --runInBand --detectOpenHandles",
"test": "./node_modules/.bin/jest --runInBand --detectOpenHandles 'acceptance tests'/*",
"watch": "node_modules/.bin/jest --coverage --watchAll",
"acceptance": "./test.sh",
"profiler": "./node_modules/.bin/0x -o index.js"
"profiler": "./node_modules/.bin/0x -o index.js",
"ci": "./node_modules/.bin/start-server-and-test start-server http://localhost:8080 test"
},
"author": "",
"license": "ISC",
@@ -30,6 +32,7 @@
"jest-puppeteer": "^4.3.0",
"puppeteer": "^1.20.0",
"puppeteer-har": "^1.1.1",
"start-server-and-test": "^1.10.6",
"supertest": "^4.0.2"
},
"jest": {
@@ -1,8 +1,13 @@
#!/usr/bin/env bash

set -e
echo hello
mkdir -p screenshots
mkdir -p trace
rm -rf *.db
# [ ! -d "node_modules" ] && echo "INSTALLING MODULES" && npm install
node index.js&
node_modules/.bin/jest --runInBand --detectOpenHandles acceptance\ tests/*
kill %1
read -p "Press enter to continue"

0 comments on commit e471c1c

Please sign in to comment.