Skip to content

Commit 66f71fe

Browse files
author
Greg Wilson
committed
Initial update to support Hapi v17
1 parent 7ab3c3b commit 66f71fe

File tree

13 files changed

+6401
-239
lines changed

13 files changed

+6401
-239
lines changed

package-lock.json

Lines changed: 6112 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
22
"name": "typescript-node",
3-
"version": "1.2.0",
3+
"version": "1.3.0",
44
"description": "",
55
"license": "MIT",
66
"repository": {
7-
"url": "https://github.com/Talento90/typescript-node.git"
7+
"url": "https://github.com/dwyl/hapi-typescript-example.git"
88
},
99
"author": "Talento90",
1010
"keywords": [
@@ -22,48 +22,48 @@
2222
"watch": "nodemon --watch build/src build/src/index.js"
2323
},
2424
"dependencies": {
25+
"@salzhrani/hapi-auth-jwt2": "^7.3.0",
2526
"bcryptjs": "^2.4.3",
26-
"boom": "^4.3.1",
27+
"boom": "~7.1.0",
2728
"fs": "0.0.1-security",
28-
"good": "^7.2.0",
29-
"good-console": "^6.4.0",
29+
"good": "^8.1.0",
30+
"good-console": "^7.0.1",
3031
"good-squeeze": "^5.0.2",
31-
"hapi": "^16.1.1",
32-
"hapi-auth-jwt2": "^7.2.4",
33-
"hapi-swagger": "^7.7.0",
34-
"inert": "^4.2.0",
35-
"joi": "^10.5.0",
36-
"jsonwebtoken": "^7.4.1",
37-
"mongoose": "^4.10.0",
38-
"nconf": "^0.8.4",
32+
"hapi": "17.2.0",
33+
"hapi-swagger": "^9.1.1",
34+
"inert": "~5.1.0",
35+
"joi": "~13.1.2",
36+
"jsonwebtoken": "^8.1.1",
37+
"mongoose": "^5.0.4",
38+
"nconf": "^0.10.0",
3939
"nodemon": "^1.11.0",
4040
"path": "^0.12.7",
41-
"vision": "^4.1.1"
41+
"vision": "~5.3.1"
4242
},
4343
"devDependencies": {
4444
"@types/bcryptjs": "^2.4.0",
45-
"@types/boom": "^4.3.2",
46-
"@types/chai": "^3.5.2",
47-
"@types/hapi": "^16.1.2",
48-
"@types/joi": "^10.3.2",
45+
"@types/boom": "^7.1.1",
46+
"@types/chai": "^4.1.2",
47+
"@types/hapi": "^17.0.0",
48+
"@types/joi": "^13.0.5",
4949
"@types/jsonwebtoken": "^7.2.0",
5050
"@types/mocha": "^2.2.41",
51-
"@types/mongoose": "^4.7.13",
52-
"@types/nconf": "0.0.34",
53-
"@types/node": "^7.0.21",
54-
"@types/sinon": "^2.2.2",
55-
"chai": "^3.5.0",
51+
"@types/mongoose": "^5.0.1",
52+
"@types/nconf": "0.0.37",
53+
"@types/node": "^9.4.5",
54+
"@types/sinon": "^4.1.3",
55+
"chai": "^4.1.2",
5656
"gulp": "^3.9.1",
5757
"gulp-env": "^0.4.0",
58-
"gulp-mocha": "^4.3.1",
58+
"gulp-mocha": "^5.0.0",
5959
"gulp-rimraf": "^0.2.1",
6060
"gulp-shell": "^0.6.3",
6161
"gulp-tslint": "^8.0.0",
62-
"mocha": "^3.4.1",
63-
"node": "0.0.0",
64-
"sinon": "^2.2.0",
65-
"tslint": "^5.2.0",
66-
"typescript": "^2.3.2"
62+
"mocha": "^5.0.0",
63+
"node": "9.5.0",
64+
"sinon": "^4.3.0",
65+
"tslint": "^5.4.3",
66+
"typescript": "^2.4.1"
6767
},
6868
"engines": {
6969
"node": ">=7.6.0"

src/configurations/config.dev.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"database": {
3-
"connectionString": "mongodb://localhost:27017/taskdb-dev"
3+
"connectionString": "mongodb://localhost:32768/taskdb-dev"
44
},
55
"server": {
66
"port": 5000,

src/configurations/config.test.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"database": {
3-
"connectionString": "mongodb://localhost:27017/taskdb-test"
3+
"connectionString": "mongodb://localhost:32768/taskdb-test"
44
},
55
"server": {
66
"port": 5000,

src/index.ts

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as Server from "./server";
22
import * as Database from "./database";
33
import * as Configs from "./configurations";
44

5-
console.log(`Running enviroment ${process.env.NODE_ENV || "dev"}`);
5+
console.log(`Running enviroment ${process.env.NODE_ENV || 'dev'}`);
66

77
// Catch unhandling unexpected exceptions
88
process.on('uncaughtException', (error: Error) => {
@@ -14,15 +14,27 @@ process.on('unhandledRejection', (reason: any) => {
1414
console.error(`unhandledRejection ${reason}`);
1515
});
1616

17+
// Define async start function
18+
const start = async ({ config, db }) => {
19+
try {
20+
const server = await Server.init(config, db);
21+
await server.start();
22+
console.log('Server running at:', server.info.uri);
23+
} catch (err) {
24+
console.error('Error starting server: ', err.message);
25+
throw err;
26+
}
27+
};
28+
1729
// Init Database
1830
const dbConfigs = Configs.getDatabaseConfig();
1931
const database = Database.init(dbConfigs);
2032

2133
// Starting Application Server
2234
const serverConfigs = Configs.getServerConfigs();
2335

24-
Server.init(serverConfigs, database).then((server) => {
25-
server.start(() => {
26-
console.log('Server running at:', server.info.uri);
27-
});
36+
// Start the server
37+
start({
38+
config: serverConfigs,
39+
db: database
2840
});

src/interfaces/request.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import * as Hapi from 'hapi';
2+
3+
export interface ICredentials extends Hapi.AuthCredentials {
4+
id: string;
5+
}
6+
7+
export interface IRequestAuth extends Hapi.RequestAuth {
8+
credentials: ICredentials;
9+
}
10+
11+
export interface IRequest extends Hapi.Request {
12+
auth: IRequestAuth;
13+
}
14+
15+
export interface ILoginRequest extends IRequest {
16+
payload: {
17+
email: string;
18+
password: string;
19+
};
20+
}

src/plugins/jwt-auth/index.ts

Lines changed: 46 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,55 @@
1-
import { IPlugin, IPluginOptions } from "../interfaces";
2-
import * as Hapi from "hapi";
3-
import { IUser, UserModel } from "../../users/user";
1+
import { IPlugin, IPluginOptions } from '../interfaces';
2+
import * as Hapi from 'hapi';
3+
import { IUser, UserModel } from '../../users/user';
4+
import { IRequest } from '../../interfaces/request';
5+
6+
const register = async (server: Hapi.Server, options: IPluginOptions): Promise<void> => {
7+
try {
8+
const database = options.database;
9+
const serverConfig = options.serverConfigs;
10+
11+
const validateUser = async (decoded: any, request: IRequest, h: Hapi.ResponseToolkit) => {
12+
const user = await database.userModel.findById(decoded.id).lean(true);
13+
if (!user) {
14+
return { isValid: false };
15+
}
16+
17+
return { isValid: true };
18+
};
19+
20+
await server.register(require('@salzhrani/hapi-auth-jwt2'));
21+
22+
return setAuthStrategy(server, {
23+
config: serverConfig,
24+
validate: validateUser
25+
});
26+
27+
} catch (err) {
28+
console.log(`Error registering jwt plugin: ${err}`);
29+
throw err;
30+
}
31+
};
32+
33+
const setAuthStrategy = async (server, { config, validate }) => {
34+
server.auth.strategy('jwt', 'jwt', {
35+
key: config.jwtSecret,
36+
validate,
37+
verifyOptions: { algorithms: ['HS256'] }
38+
});
39+
40+
server.auth.default('jwt');
41+
42+
return;
43+
};
444

545
export default (): IPlugin => {
646
return {
7-
register: (server: Hapi.Server, options: IPluginOptions): Promise<void> => {
8-
const database = options.database;
9-
const serverConfig = options.serverConfigs;
10-
11-
const validateUser = (decoded, request, cb) => {
12-
database.userModel.findById(decoded.id).lean(true)
13-
.then((user: IUser) => {
14-
if (!user) {
15-
return cb(null, false);
16-
}
17-
18-
return cb(null, true);
19-
});
20-
};
21-
22-
return new Promise<void>((resolve) => {
23-
server.register({
24-
register: require('hapi-auth-jwt2')
25-
}, (error) => {
26-
if (error) {
27-
console.log(`Error registering jwt plugin: ${error}`);
28-
} else {
29-
server.auth.strategy('jwt', 'jwt', false,
30-
{
31-
key: serverConfig.jwtSecret,
32-
validateFunc: validateUser,
33-
verifyOptions: { algorithms: ['HS256'] }
34-
});
35-
}
36-
37-
resolve();
38-
});
39-
});
40-
},
47+
register,
4148
info: () => {
4249
return {
43-
name: "JWT Authentication",
44-
version: "1.0.0"
50+
name: 'JWT Authentication',
51+
version: '1.0.0'
4552
};
4653
}
4754
};
4855
};
49-
50-

src/plugins/logger/index.ts

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,44 @@
1-
import { IPlugin } from "../interfaces";
2-
import * as Hapi from "hapi";
1+
import { IPlugin } from '../interfaces';
2+
import * as Hapi from 'hapi';
33

4-
export default (): IPlugin => {
5-
return {
6-
register: (server: Hapi.Server): Promise<void> => {
7-
const opts = {
4+
const register = async (server: Hapi.Server): Promise<void> => {
5+
try {
6+
return server.register({
7+
plugin: require('good'),
8+
options: {
89
ops: {
910
interval: 1000
1011
},
1112
reporters: {
12-
consoleReporter: [{
13-
module: 'good-squeeze',
14-
name: 'Squeeze',
15-
args: [{ error: '*', log: '*', response: '*', request: '*' }]
16-
}, {
17-
module: 'good-console'
18-
}, 'stdout']
13+
consoleReporter: [
14+
{
15+
module: 'good-squeeze',
16+
name: 'Squeeze',
17+
args: [{ error: '*', log: '*', response: '*', request: '*' }]
18+
},
19+
{
20+
module: 'good-console'
21+
},
22+
'stdout'
23+
]
1924
}
20-
};
25+
}
26+
});
2127

22-
return new Promise<void>((resolve) => {
23-
server.register({
24-
register: require('good'),
25-
options: opts
26-
}, (error) => {
27-
if (error) {
28-
console.log(`Error registering logger plugin: ${error}`);
29-
}
28+
} catch (err) {
29+
console.log(`Error registering logger plugin: ${err}`);
30+
throw err;
31+
}
32+
};
3033

31-
resolve();
32-
});
33-
});
34-
},
34+
export default (): IPlugin => {
35+
return {
36+
register,
3537
info: () => {
3638
return {
37-
name: "Good Logger",
38-
version: "1.0.0"
39+
name: 'Good Logger',
40+
version: '1.0.0'
3941
};
4042
}
4143
};
42-
};
44+
};

0 commit comments

Comments
 (0)