Skip to content

Commit b1d0ce1

Browse files
committed
Merge branch 'master' into cookiesAndCaching
2 parents 9308347 + 90b9784 commit b1d0ce1

File tree

14 files changed

+48291
-12
lines changed

14 files changed

+48291
-12
lines changed

week-5/streamsAndBuffers/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules

week-5/streamsAndBuffers/illiad.txt

+26,175
Large diffs are not rendered by default.

week-5/streamsAndBuffers/mobydick.txt

+21,831
Large diffs are not rendered by default.

week-5/streamsAndBuffers/out.txt

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
hello
2+
my
3+
name
4+
is
5+
this

week-5/streamsAndBuffers/package.json

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"name": "streams-and-buffers",
3+
"version": "1.0.0",
4+
"description": "Learn about streams",
5+
"main": "readStr.js",
6+
"scripts": {
7+
"test": "echo \"Error: no test specified\" && exit 1"
8+
},
9+
"author": "Mavis and Jack",
10+
"license": "ISC",
11+
"devDependencies": {
12+
"split": "^1.0.0"
13+
}
14+
}

week-5/streamsAndBuffers/readStr.js

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
const fs = require('fs');
2+
3+
//Need to require this to split by lines
4+
const split = require('split');
5+
6+
// our programm can take three flags, which are then assigned below, or default with the OR operator:
7+
var filepath = process.argv[2]||'./test.txt'
8+
var hwm = process.argv[3] || 100
9+
var timeout = process.argv[4] || 500
10+
11+
// Create the readable stream of the filepath specified and the hwm and set the econding to utf8
12+
var file = fs.createReadStream(filepath, {highWaterMark:hwm, encoding: 'utf8'});
13+
14+
//creat empty data
15+
var data =''
16+
17+
//You pipe the readable stream into split which sends it back as chunks split by a new line
18+
file.pipe(split())
19+
20+
//listen for error event
21+
file.on('error', function(err) {
22+
console.log('Error '+err);
23+
return err
24+
});
25+
26+
//listen for data events
27+
file.on('data', function(bits) {
28+
29+
//add new bits to the data str
30+
data +=bits
31+
32+
//print the new bit as a string (it comes buffered)
33+
process.stdout.write(bits);
34+
35+
//pause the reading
36+
file.pause();
37+
38+
//set a timeout as specified by the flag (def: 500ms) to then resume the read
39+
setTimeout(() => {
40+
file.resume();
41+
}, timeout);
42+
})
43+
44+
// listen for the end event
45+
file.on('end', function(){
46+
console.log('Finished reading all of the data');
47+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Streams & Buffers
2+
3+
### 1) Streams
4+
5+
#### Data Access in Node
6+
- Fully buffered access vs. partially buffered access - these differ in terms of:
7+
- How the data is exposed
8+
- The amount of memory used to store the data
9+
10+
#### Fully Buffered Access
11+
- Asynchronous `readFile()`
12+
- Synchronous `readFileSync()`
13+
- The data is returned in **one big chunk** after all of it has been read
14+
- Node needs to allocate enough memory to store all of that data
15+
16+
#### Partially Buffered Access
17+
- Asynchronous `read()` `createReadStream()`
18+
- Synchronous `readSync()`
19+
- Data input is treated as a **series of events**, occurring as the data is being read or written - this allows us to **access data as it is being read**
20+
- Partially-buffered methods (listed above) allow us to specify the size of the buffer and read the data in small chunks
21+
22+
#### Streams
23+
- Streams are a form of **partially buffered access**
24+
- Streams return small pieces of data (using a buffer) and trigger an event when each new piece of data is available for processing
25+
- Since streams are partially buffered, we can process each piece of data **as soon as it is read** - this means we don't necessarily need to buffer / save the whole file into memory
26+
- The Node stream interface consists of two parts:
27+
- Readable streams
28+
- Writeable streams
29+
30+
#### Readable Streams
31+
- Readable streams emit the following events:
32+
- `data` emits a buffer / string
33+
- `end` is emitted when the stream receives an EOF (End of Function) - this indicates that there will be no more `data` events
34+
- `error` is emitted if there's an error receiving data
35+
- To bind a callback to an event, use `stream.on(eventname, callback)` - the HTTP request object is one example of a readable stream that we've already covered:
36+
- `request.on('error', function(err) { ... });`
37+
- `request.on('data', function(data) { ... });`
38+
- `request.on('end', function() { ... });`
39+
- Readable streams also have the following methods:
40+
- `request.pause()` pauses incoming data events
41+
- `request.resume()` resumes after a `pause()`
42+
- `request.destroy()` stops the stream emitting any more events
43+
44+
### 2) Buffers
45+
- In Node, buffers are a **high-performance alternative** to strings, representing raw C memory allocation
46+
- Buffers act like fixed-size arrays of integers, each represented as a **hexidecimal number** when run through `console.log()`
47+
48+
```js
49+
var buffer = new Buffer(10);
50+
buffer[0] = 255;
51+
console.log(buffer); // <Buffer ff 00 00 00 00 4a 00 00 00 00>
52+
```
53+
- Since buffers represent raw memory, any buffer content you haven't assigned (anything other than `buffer[0]` in the above example) will be whatever happens to sit in that position in memory (e.g. the `4a` seen above)
54+
- Compared to strings, buffers are fixed in size, and have very limited predefined functions (missing convenient ones like `String.replace()` for example)
55+
- If you want to use string functions on buffers, you can convert them to strings with `buffer.toString()` first
56+
57+
## Resources
58+
- http://book.mixu.net/node/ch9.html
59+
- https://www.sitepoint.com/basics-node-js-streams/
60+
- https://www.tutorialspoint.com/nodejs/nodejs_streams.htm

week-5/streamsAndBuffers/test.txt

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
this is just a test of this line repeated a lotx1
2+
this is just a test of this line repeated a lotx2
3+
this is just a test of this line repeated a lotx3
4+
this is just a test of this line repeated a lotx4
5+
this is just a test of this line repeated a lotx5
6+
this is just a test of this line repeated a lotx6
7+
this is just a test of this line repeated a lotx7
8+
this is just a test of this line repeated a lotx8
9+
this is just a test of this line repeated a lotx9
10+
this is just a test of this line repeated a lotx10
11+
this is just a test of this line repeated a lotx11
12+
this is just a test of this line repeated a lotx12
13+
this is just a test of this line repeated a lotx13
14+
this is just a test of this line repeated a lotx14
15+
this is just a test of this line repeated a lotx15
16+
this is just a test of this line repeated a lotx16
17+
this is just a test of this line repeated a lotx17
18+
this is just a test of this line repeated a lotx18
19+
this is just a test of this line repeated a lotx19
20+
this is just a test of this line repeated a lotx20
21+
this is just a test of this line repeated a lotx21
22+
this is just a test of this line repeated a lotx22
23+
this is just a test of this line repeated a lotx23
24+
this is just a test of this line repeated a lotx24
25+
this is just a test of this line repeated a lotx25
26+
this is just a test of this line repeated a lotx26
27+
this is just a test of this line repeated a lotx27
28+
this is just a test of this line repeated a lotx28
29+
this is just a test of this line repeated a lotx29

week-5/streamsAndBuffers/writeStr.js

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//Require the file system module
2+
var fs = require('fs');
3+
4+
5+
//Create a writeable stream (i.e. a stream we can write to, which will go to ./out.txt)
6+
var file = fs.createWriteStream('./out.txt');
7+
8+
//Process.stdin (opposite of process.stdout) is a readable stream, that reads data that we input into the terminal
9+
10+
//So here when we read data from process.stdin.on we write that data to our file, the writable stream we created
11+
process.stdin.on('data', function(data) {
12+
file.write(data);
13+
});
14+
15+
//When the readable stream ends, we close the writeable stream
16+
process.stdin.on('end', function() {
17+
file.end();
18+
});
19+
20+
//Resume the incoming data stream after a pause
21+
process.stdin.resume();

week-7/authentication.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[Click here for README](https://github.com/FACN1/research/blob/master/week-7/authentication/authentication.md)

week-7/authentication/authentication.md

+29-5
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,39 @@ In the realm of the web,
55
authentication is **the process of verifying the identity an individual, usually using a password.**
66

77
## Hashing
8-
What is it and why is it useful?
9-
10-
118
### Hashing a password
129

13-
![password_hash](https://github.com/FACN1/research/blob/master/week-7/authentication/password_hash.gif "Password hashing")
10+
![password_hash](https://github.com/FACN1/research/raw/master/week-7/authentication/password_hash.gif)
1411

1512
### Checking the password:
1613

17-
![password_check](https://github.com/FACN1/research/blob/master/week-7/authentication/password_check.gif "Password check")
14+
![password_check](https://github.com/FACN1/research/raw/master/week-7/authentication/password_check.gif) "Password check"
15+
16+
### What is it?
17+
- A hash function will take an input of any size, and give an output of fixed size, which is like a fingerprint. It should be mathematically irreversible (can't get a password from a hash). Theoretically, the chance of a hash collision (two inputs/passwords with the same output/hash) is very small, so two outputs of a hash function can be compared to determine if two files or strings are identical.
18+
19+
**Types of hash**
20+
- A cryptographic hash, such as md5, SHA-1, SHA-256, etc is designed to be as fast as possible.
21+
- However, a password hash (such as bcrypt, PBKDF2) is designed to take as long as possible.
22+
- This also means that password hashing should always be run asynchronously.
23+
24+
**Salting**
25+
26+
- While hashing functions are one-way (can't be reversed), crackers can have pre-calculated enormous amounts of input/output pairs - these are called rainbow tables.
27+
- a salt is generally a random string of characters to add complexity
28+
- bcrypt generates a unique salt for each user, and adds this salt
29+
30+
### Why is it useful?
31+
32+
- If a database is hacked (which should always be assumed - data breaches happen all the time), then if passwords are stored in plaintext, crackers can publish all the passwords on the internet, and anyone can try using the same passwords on other websites that the user uses, such as emails.
33+
- However, if passwords are sufficiently hashed, and sensitive data such as credit card details is well encrypted, then the data is less useful for crackers.
34+
35+
**Compute Time**
36+
- The longer it takes to calculate the hash of a password, the better. This is because if a database is compromised, a cracker will try to brute force passwords to get the original password.
37+
- A cryptographic hash such as SHA-1 can be tried 10,000s of times a second or more; however, if bcrypt is used, only a few passwords could be tested each second (assuming a normal computer is used for brute forcing)
38+
39+
40+
1841

1942

2043
## Example
@@ -32,3 +55,4 @@ hapi-auth-basic:
3255
- Is outdated as it uses a pop-up to request username and password
3356

3457
## Links
58+
- [Brian Krebs article on Password Security](https://krebsonsecurity.com/2012/06/how-companies-can-beef-up-password-security/)

week-7/authentication/server.js

+8-4
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,19 @@ const users = {
3333
}
3434
}
3535
// Create hashed passwords of 'password'. First arg 'user-pword' Second 'Salting rounds'
36-
console.log(bcrypt.hashSync('password', 0))
37-
console.log(bcrypt.hashSync('password', 0))
38-
3936
console.log(bcrypt.hashSync('password', 1))
4037
console.log(bcrypt.hashSync('password', 1))
4138

39+
// Creates the same passwords because using same salt
40+
bcrypt.genSalt(5, function(err, salt){
41+
console.log(bcrypt.hashSync('password', salt))
42+
console.log(bcrypt.hashSync('password', salt))
43+
})
44+
4245
// Find out how many rounds of hashing were used to produce hashed password
4346
console.log(bcrypt.getRounds('$2a$10$iqJSHD.BGr0E2IxQwYgJmeP3NvhPrXAeLSaGCj6IR/XU5QtjVu5Tm'))
4447

45-
// Bad easily crackable hashing function
48+
// Create bad easily crackable hashing function
4649
String.prototype.hashCode = function(){
4750
var hash = 0;
4851
if (this.length == 0) return hash;
@@ -93,3 +96,4 @@ server.register(basic, (err) => {
9396
console.log(`Server running on port: ${server.info.uri}`)
9497
})
9598
})
99+

week-7/validation/README.md

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# The Joi of Validation with Hapi
2+
3+
### WHY?
4+
Its important to check data being inputted into your programme. Invalid data can throw errors, which are better caught as soon as possible, rather than after they've crashed your server!
5+
6+
### WHAT?
7+
Joi is a hapi module which checks the payloads of requests and responses going in and out of a server.
8+
9+
Joi allows you to create blueprints or schemas for javascript objects to ensure validation of key information.
10+
11+
By default, all validators are set to ```true```, which means no validation is being performed, and everything passes through unchecked.
12+
13+
14+
### HOW?
15+
16+
Install and require ```hapi``` and ```joi ``` into your server file.
17+
18+
In your route, in addition to your method, path and handler, you can set validation parameters in the ```config``` object on a route, and is able to validate headers, path parameters, query parameters, and payload data.
19+
20+
``` js
21+
22+
server.route({
23+
method: 'GET',
24+
path: '/hello/{name}',
25+
handler: function (request, reply) {
26+
reply('Hello ' + request.params.name + '!');
27+
},
28+
config: {
29+
validate: {
30+
params: {
31+
name: Joi.string().min(3).max(10)
32+
}
33+
}
34+
}
35+
});
36+
```
37+
38+
Example using a schema:
39+
40+
``` js
41+
42+
const bookSchema = Joi.object({
43+
title: Joi.string().required(),
44+
author: Joi.string().required(),
45+
isbn: Joi.string().length(10),
46+
pageCount: Joi.number(),
47+
datePublished: Joi.date().iso()
48+
});
49+
50+
```
51+
52+
``` js
53+
54+
joi.validate(data, schema, callback)
55+
56+
// callback is an optional callback function which takes an error and the validated data.
57+
58+
```
59+
60+
Useful links:
61+
62+
[Joi Documentation](https://github.com/hapijs/joi)
63+
64+
[Hapi Validation documentation](https://hapijs.com/tutorials/validation)
65+
66+
[The Joi Of Validation](http://vawks.com/blog/2014/03/22/the-joi-of-validation/)
67+
68+
https://github.com/hapijs/joi/blob/master/API.md#joi

week-7/validation/src/server.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ server.connection({
88
port: 3000
99
})
1010

11-
// const schema = joi.object().keys({
12-
// });
1311

1412
const routes = [
1513
{
@@ -22,7 +20,8 @@ const routes = [
2220
validate: {
2321
params: {
2422
email: joi.string().email().required(),
25-
password: joi.string().regex(/^[a-zA-Z0-9]{8,20}$/).required()
23+
// password: joi.string().regex(/^[a-zA-Z0-9]{8,20}$/).required()
24+
password: joi.string().alphanum().required()
2625
}
2726
}
2827
}

0 commit comments

Comments
 (0)