Donate what you can now - No Bitcoins accepted!
\n{"properties":{"slack":"https://wit-hdip-comp-sci.slack.com/messages/C84S2LQSC/","moodle":"https://moodle.wit.ie/course/view.php?id=118143§ion=6","youtube":"https://www.youtube.com/playlist?list=PLMW4bgOfD3DwPrctMZ8WSaW7FA1rsjLWd","highlightstyle":"railscasts","parent":"course/wit-hdip-comp-sci-2018.netlify.app","credits":"Eamonn de Leastar, Jimmy McGibney","license":"Unless otherwise stated, this work is licensed under a Creative Commons Attribution 4.0 International License.","ects":10,"faPanelicon":"fas fa-server","faColour":"#2C59A6"},"title":"Enterprise Web Development ","type":"course","summary":"javascript · node · security · crypto · apis · tdd · frameworks","img":"https://{{COURSEURL}}//course.png","id":"repo","hide":false,"version":"1.0.8","los":[{"title":"00: Module Overview ","type":"topic","summary":"Module introduction & overview.","img":"https://{{COURSEURL}}/topic-00-overview/topic.png","id":"topic-00-overview","route":"#topic/{{COURSEURL}}/topic-00-overview","hide":false,"los":[{"title":" Course Overview ","type":"talk","summary":"A brief overview of the entire course","img":"https://{{COURSEURL}}/topic-00-overview/talk-0-overview/overview.png","id":"talk-0-overview","route":"#talk/{{COURSEURL}}/topic-00-overview/talk-0-overview/overview.pdf","hide":false,"pdf":"https://{{COURSEURL}}/topic-00-overview/talk-0-overview/overview.pdf"}]},{"title":"01: Javascript Client Review ","type":"topic","summary":"Javascript in the browser. The DOM, Jquery & Ajax to access APIs.","img":"https://{{COURSEURL}}/topic-01-js-client/unit-1/talk-4-js-browser/js-browser.png","id":"topic-01-js-client","route":"#topic/{{COURSEURL}}/topic-01-js-client","hide":false,"los":[{"title":"DOM & JQuery ","type":"unit","summary":"DOM & JQuery","img":"https://{{COURSEURL}}/topic-01-js-client/unit-1/talk-4-js-browser/js-browser.png","id":"unit-1","route":"#topic/{{COURSEURL}}/topic-01-js-client/","hide":false,"los":[{"title":"JS Browser Tools ","type":"talk","summary":"The script tags. Introducing Chrome Developer tools.","img":"https://{{COURSEURL}}/topic-01-js-client/unit-1/talk-4-js-browser/js-browser.png","id":"talk-4-js-browser","route":"#talk/{{COURSEURL}}/topic-01-js-client/unit-1/talk-4-js-browser/js-browser.pdf","hide":false,"pdf":"https://{{COURSEURL}}/topic-01-js-client/unit-1/talk-4-js-browser/js-browser.pdf"},{"title":"DOM ","type":"talk","summary":"Document Object Model : a data structure maintained by the browser to represent the page contents","img":"https://{{COURSEURL}}/topic-01-js-client/unit-1/talk-5-dom/dom.png","id":"talk-5-dom","route":"#talk/{{COURSEURL}}/topic-01-js-client/unit-1/talk-5-dom/dom.pdf","hide":false,"pdf":"https://{{COURSEURL}}/topic-01-js-client/unit-1/talk-5-dom/dom.pdf"},{"title":"JQuery ","type":"talk","summary":"jQuery: a library to facilitate and simplify access to the DOM","img":"https://{{COURSEURL}}/topic-01-js-client/unit-1/talk-6-jquery/jquery.png","id":"talk-6-jquery","route":"#talk/{{COURSEURL}}/topic-01-js-client/unit-1/talk-6-jquery/jquery.pdf","hide":false,"pdf":"https://{{COURSEURL}}/topic-01-js-client/unit-1/talk-6-jquery/jquery.pdf"},{"title":"Lab 01a JQuery","type":"lab","summary":"Use both native JavaScript and JQuery to access and manipulate the DOM.","img":"https://{{COURSEURL}}/topic-01-js-client/unit-1/book-3-jquery/img/main.jpg","id":"book-3-jquery","route":"#lab/{{COURSEURL}}/topic-01-js-client/unit-1/book-3-jquery","hide":false,"los":[{"title":"#Objectives","shortTitle":"Lab 01a JQuery","contentMd":"#Objectives\n\nUse both native JavaScript and JQuery to access and manipulate the DOM.\n\n","route":"#lab/{{COURSEURL}}/topic-01-js-client/unit-1/book-3-jquery/Lab 01a JQuery"},{"title":"# JQuery","shortTitle":"01","contentMd":"# JQuery\n\nMake sure you have the latest version of WebStorm installed. With your WIT Email, you will be able to obtain a full license. \n\n-
Click the button to change this text.
\n \n \n \n \n\n~~~\n\nAdd the following file to the project (in the `js` subdirectory):\n\n## dom-manip-1.js\n\n~~~\nfunction domAccess() {\n document.getElementById('demo').innerHTML = 'Hi ICTSkills';\n}\n~~~\n\nOpen index1.html in Chrome browser. You should be presented with something similar to that depicted in Figure 1.\n\n![Figure 1: Invitation to click](img/01.png)\n\nClick the button *Try it*. The text *Click the button to change this text* should be replaced with \"Hi ICTSkills\" (Figure 2).\n\n![Figure 2: Hi ICTSkills](img/02.png)\n\nLet's use Google Chrome debugger to better understand what's happening:\n\n- Open *index.html* in Chrome.\n- Select *Tools | Developer Tools* in the context menu: see Figure 3.\n\n![Figure 3: Launching Developer Tools](img/03.png)\n\nSelect the file *dom-manip-1.js* into the text window (see Figure 4).\n\n![Figure 4: Select dom-manip-1.js](img/04.png)\n\nThe file *dom-manip-1.js* should now be visible as shown in Figure 5.\n\n![Figure 5: dom-manip-1.js javaScript file](img/05.png)\n\nPlace a breakpoint on line 3, the statement *document.getElementById(\"demo\").innerHTML = \"Hi ICTSkills\";* You can do this by simply placing the mouse pointer on the number 3 and clicking. See Figure 6.\n\n![Figure 6: Breakpoint set](img/06.png)\n\nReload the page and press the button **Try it** As shown in Figure 7, the program stops at line 3, the breakpoint.\n\n![Figure 7: Program halts at breakpoint](img/07.png)\n\nLet's now replace the native JavaScript with jQuery to achieve the same goal. Replace the the function *domAccess* in with the following:\n\n## dom-manip-1.js\n\n~~~\nfunction domAccess() {\n $('#demo').html('Hi ICTSkills');\n}\n~~~\n\nReload the index1.html and press the **Try it** button. There's a problem. The text does not change. \n- The reason is that we have not loaded the jQuery library. \n- We can load a local or a cloud copy of jQuery. Let's do the latter. \n- The modified html follows: reload this file, press the **Try it** button and observe that the result should be exactly the same as before: the text changes to *Hi ICTSkills*.\n\n## index1.html\n\n~~~\n\n\n \nClick the button to change this text.
\n \n \n \n \n\n~~~\n\nStudy the jQuery syntax of \n\n- $(\"#demo\").html(\"Hi ICTSkills\");\n\nNote the following:\n\n- \\#demo refers to the *id* in the html paragraph nodeObserve that a hash (\\#) is prepended to the id as shown in the html file.\n- $(\"#demo\") is a jQuery object\n- $(\"#demo\").html(...): here a jQuery method *html(...)* is being invoked on the jQuery object.\n- The text parameter in *html(...)* replaces the existing text at the location identified by the id *\\#demo*.\n","route":"#lab/{{COURSEURL}}/topic-01-js-client/unit-1/book-3-jquery/01"},{"title":"#index2.html / dom-manip-2.js","shortTitle":"02","contentMd":"#index2.html / dom-manip-2.js\n\nIn this step we demonstrate both native JavaScript and jQuery to obtain information on a single DOM element using the element's *id* attribute.\n\n-Recall that an **id** uniquely identifies an element on a page.\n\nDownload the [img.zip](archive/img.zip), and expand athe folder *img* in your project.\n\n- The folder *img* contains three arbitrarily chosen png images, 01, 02 and 03.\n- Create a file index2.html in project and add the following content:\n\n## index2.html\n\n~~~\n\n\n \nWatch me appear and disappear
\n \n \n\n \n \n \n\n~~~\n\nCreate a corresponding JavaScript file in the *js* folder:\n\n# dom-manip-5.js\n\n~~~\nfunction hide() {\n document.getElementById(\"text\").style.visibility = \"hidden\";\n}\nfunction reveal() {\n document.getElementById(\"text\").style.visibility = \"visible\";\n}\n~~~\n\n\nOpen index5.html in Chrome. \n\n![Figure 1: Now you see me](img/13.png)\n\nPress Hide.\n\n![Figure 2: Now you don't](img/14.png)\n\nPress Reveal.\n\n![Figure 3: Can't get rid of me that easily](img/13.png)\n\nReplace the content of show.js with the jQuery equivalent:\n\n~~~\nfunction hide() {\n $('#text').hide();\n}\n\nfunction reveal() {\n $('#text').show();\n}\n~~~\n\nTest as before: the behaviour should be similar.\n\n\n","route":"#lab/{{COURSEURL}}/topic-01-js-client/unit-1/book-3-jquery/05"},{"title":"# Exercises","shortTitle":"Exercises","contentMd":"# Exercises\n\nArchive of the project so far:\n\n-Repo Name | \n
---|
Repo Name | \n
---|
Venue | \nCategory | \n
---|
Donate what you can now - No Bitcoins accepted!
\nDonate what you can now - No Bitcoins accepted!
\nDonate what you can now - No Bitcoins accepted!
\nAmount | \nMethod donated | \n
---|---|
{{amount}} | \n{{method}} | \n
Donate what you can now - No Bitcoins accepted!
\n {{> error }}\n\n OpenSSL 1.0.2g 1 Mar 2016\n\n\nYou can get a list of OpenSSL commands by entering any invalid command, or by reading the online [OpenSSL documentation online](https://www.openssl.org/docs/manpages.html).\n","route":"#lab/{{COURSEURL}}/topic-07-security-and-tdd/unit-1-security-foundations/book-1-openssl/2"},{"title":"## OpenSSL Batch mode","shortTitle":"3","contentMd":"## OpenSSL Batch mode\n\nAlternatively you can execute OpenSSL commands directly from the Linux prompt using the general command format:\n~~~\nopenssl command [options]\n~~~\n\nDepending on the command, there may be zero or more options. For example, you could enter:\n~~~\nopenssl version\n~~~\n
\n OpenSSL 1.0.2g 1 Mar 2016\n\n\nWe will use *Batch mode* in this exercise.\n\n","route":"#lab/{{COURSEURL}}/topic-07-security-and-tdd/unit-1-security-foundations/book-1-openssl/3"},{"title":"# Symmetric Encryption","shortTitle":"4","contentMd":"# Symmetric Encryption\n\n## Key generation\n\n1. Launch Linux or other environment that has OpenSSL installed and start a terminal session.\n\n1. Create a new folder and navigate into that folder (using the cd command).\n\n1. Generate random numbers of various lengths to be used as encryption keys for various symmetric algorithms. What key length do you need for DES? AES? Set things up for at least three different symmetric algorithms (look at the OpenSSL documentation to find another algorithm besides DES and AES). To generate a 128-bit key for example, enter the following:\n~~~\n openssl rand -out key1 16 # 128 bits is 16 bytes\n~~~\n\n## Encryption\n\n1. Create a new text file with some plaintext as its body e.g. “The quick brown fox jumped over the lazy dog”. Save this file in the folder you created. Choose a file name containing something like “plaintext” or “unencrypted” – e.g. plaintext.txt\n\n1. Encrypt the plaintext file using each of the three algorithms chosen, for example:\n~~~\nopenssl enc -aes-128-cbc -e -kfile key1 -in plaintext.txt -out ciphertext_aes.bin\nopenssl enc -des -e -kfile key2 -in plaintext.txt -out ciphertext_des.bin\netc\n~~~\n\n## Decryption\n\n1. You may wish to share an encrypted file with a classmate and see if they can decrypt it. You’ll also need to share the key.\n\n1. Try to read a ciphertext file to see if it makes any sense (it shouldn’t):\n~~~\ncat ciphertext_aes.bin # (or whatever the filename is)\n~~~\n\n* Decrypt each file using commands similar to this:\n~~~\nopenssl enc -aes-128-cbc -d -kfile key1 -in ciphertext_aes.bin -out decrypted.txt\n~~~\n\n1. Hopefully you can read the decrypted file:\n~~~\ncat decrypted.txt\n~~~\n\n## Effect of Compression on Encryption (Optional)\n\n1. Create a new file, this time with a lot of English language words or similar (say about 10MB in total - [here is an example you can download](archive/bigplaintext.txt). Call it bigplaintext.txt. Encrypt it using an algorithm of your choice to produce bigciphertext.bin.\nCheck the size of the encrypted file and compare with the original.\n~~~\nls -l # (this is letter “l”, not number “1”)\n~~~\nprovides a detailed listing of files in the current directory, including their sizes.
\n real 0m0.736s\n user 0m0.576s\n sys 0m0.057s\n\n(the sum of *user* and *sys* time is what matters)
\nconst fs = require('fs');\nconst server = Hapi.server({\n port: 3443,\n tls: {\n key: fs.readFileSync('private/webserver.key'),\n cert: fs.readFileSync('private/webserver.crt')\n }\n});\n\n\n\n* Next start the server (this assumes we've saved the edited file as *hapi_tls_example.js*)\n~~~\nnode hapi_tls_example.js\n~~~\n\n* Test that it’s working by pointing a web browser to [https://localhost:3443](https://localhost:3443) (replace *localhost* if published elsewhere).
https://ip_address(replacing *ip_address* with your instance’s public IP address)
\nnpm install hapi bcrypt hapi-auth-basic\nnode basic.js\n\n\nNow open a new browser tab and go to Developer Tools (right click and **Inspect** in Chrome). Select the **Network** tab and browse to http://localhost:3000.\n\nObserve that a **WWW-Authenticate:Basic** Response Header is set.\n![WWW-Authenticate:Basic Response Header](img/basic1.png)\n\nEntering the correct username and password (john/secret) sets an Authorization header in *all* requests to that domain until the browser is closed. Note that this the username and password are just encoded and not encrypted.\n\n![Base64-encoded Authorization header](img/basic2.png)\n\nTry any online Base64 decoder to find what *am9objpzZWNyZXQ* maps to.\n","route":"#lab/{{COURSEURL}}/topic-09-authentication-rest/unit-1-web-app-authentication/book-1-web-authentication/2-Basic Auth"},{"title":"# Using OAuth","shortTitle":"3-OAuth","contentMd":"# Using OAuth\n\nThis demo application uses the [bell](https://www.npmjs.com/package/bell) plugin for OAuth to enable users of the app to get privileged access to their GitHub account. This could be adapted for other supported services such as Facebook, Google, LinkedIn, Foursquare, etc.\n\nTo try out the application, you need to do the following:\n\n1. Log into your GitHub account and go to the [Settings page](https://github.com/settings/profile).\n\n2. Go to *Developer Settings* and **Register a new application**.\n\n3. Complete the form to give the app a name and define Homepage and Callback URLs (which can be http://localhost:3000/ for example).\n![Register an OAuth app on GitHub](img/register-oauth.png)\n\n4. Note the Client ID and Client Secret assigned to your app, You will need to insert these into the code at the designated placeholders.\n\n5. Download the [demo code and package.json file](archive/oauth-github.zip), extract from the zip archive and go to that folder. The code is also shown at the bottom of this page.\n * A full explanation of what is going on here is provided in [this tutorial from Sitepoint](https://www.sitepoint.com/oauth-integration-using-hapi/).\n\n6. Start the server\n~~~\nnpm install\nnode oauth-github.js\n~~~\n\n7. Now try to visit the app's *login* route:\n\n * http://localhost:3000/login\n\n You will be redirected from your app to GitHub to authorise giving the web app access to your data. You will also need to authenticate to GitHub if you're not already logged in.\n ![Authorisation](img/authorisation.png)\n\n8. Try the following routes and see what happens. Experiment with logging out and subsequently trying to get access.\n\n * http://localhost:3000/account\n * http://localhost:3000/userinfo\n * http://localhost:3000/\n * http://localhost:3000/logout\n * http://localhost:3000/\n\n## oauth-github.js\n\n~~~\n'use strict';\n\nconst os = require('os');\nos.tmpDir = os.tmpdir;\n\nconst Hapi = require('hapi');\nconst Bell = require('bell');\nconst AuthCookie = require('hapi-auth-cookie');\n\nconst main = async () => {\n\n const server = Hapi.server({ port: 3000 });\n\n // Register bell and hapi-auth-cookie with the server\n await server.register([Bell, AuthCookie]);\n\n var authCookieOptions = {\n password: 'cookie-encryption-password-secure', // String used to encrypt auth cookie (min 32 chars)\n cookie: 'demo-auth', // Name of cookie to set\n isSecure: false // Should be 'true' in production software (requires HTTPS)\n };\n\n server.auth.strategy('cookie-auth', 'cookie', authCookieOptions);\n\n var bellAuthOptions = {\n provider: 'github',\n password: 'github-encryption-password-secure', // String used to encrypt temporary cookie\n // used during authorisation steps only\n clientId: 'ENTER CLIENT ID', // *** Replace with your app Client Id ****\n clientSecret: 'ENTER CLIENT SECRET', // *** Replace with your app Client Secret ***\n isSecure: false // Should be 'true' in production software (requires HTTPS)\n };\n\n server.auth.strategy('github-oauth', 'bell', bellAuthOptions);\n\n server.auth.default('cookie-auth');\n\n //Set up the routes\n server.route([\n {\n method: 'GET',\n path: '/login',\n config: {\n auth: 'github-oauth',\n handler: function (request, h) {\n if (request.auth.isAuthenticated) {\n request.cookieAuth.set(request.auth.credentials);\n return ('Hello ' + request.auth.credentials.profile.displayName);\n }\n return('Not logged in...');\n }\n }\n }, {\n method: 'GET',\n path: '/account',\n config: {\n auth: 'cookie-auth',\n handler: function (request, h) {\n if (request.auth.isAuthenticated) {\n return(request.auth.credentials.profile);\n }\n }\n }\n }, {\n method: 'GET',\n path: '/userinfo',\n config: {\n auth: 'cookie-auth',\n handler: function (request, h) {\n if (request.auth.isAuthenticated) {\n return('
Last Name | \nFirst Name | \nOffice | \n
---|
Last Name | \nFirst Name | \nOffice | \n
---|
Amount | \nPayment Method | \nDonor | \nCandidate | \n
---|---|---|---|
${donation.amount} | \n${donation.method} | \n${donation.donor.lastName}, ${donation.donor.firstName} | \n${donation.candidate.lastName}, ${donation.candidate.firstName} | \n
Amount | \nPayment Method | \nCandidate | \n
---|---|---|
${donation.amount} | \n${donation.method} | \n${donation.candidate.lastName}, ${donation.candidate.firstName} | \n