Skip to content
This repository was archived by the owner on Nov 16, 2023. It is now read-only.

Commit 1409fd7

Browse files
CarlosSolracpeterblazejewicz
authored andcommitted
Update packages, add tests, add type casts (#229)
- upgrade to latest packages - cast `req.user` as `UserDocument` - update logger to use latest Winston syntax - disable `no-inferrable-types`, Mongoose use unified topology Thx to @CarlosSolrac
1 parent ca14e7c commit 1409fd7

File tree

9 files changed

+1531
-1157
lines changed

9 files changed

+1531
-1157
lines changed

.eslintrc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"semi": ["error", "always"],
1010
"quotes": ["error", "double"],
1111
"@typescript-eslint/explicit-function-return-type": "off",
12-
"@typescript-eslint/no-explicit-any": "off"
12+
"@typescript-eslint/no-explicit-any": "off",
13+
"@typescript-eslint/no-inferrable-types": "off"
1314
}
1415
}

package-lock.json

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

package.json

Lines changed: 99 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -1,98 +1,101 @@
11
{
2-
"name": "express-typescript-starter",
3-
"version": "0.1.0",
4-
"description": "A starting point for Node.js express apps with TypeScript",
5-
"repository": {
6-
"type": "git",
7-
"url": "https://github.com/Microsoft/TypeScript-Node-Starter"
8-
},
9-
"author": "Bowden Kelly",
10-
"license": "MIT",
11-
"scripts": {
12-
"start": "npm run serve",
13-
"build": "npm run build-sass && npm run build-ts && npm run lint && npm run copy-static-assets",
14-
"serve": "node dist/server.js",
15-
"watch-node": "nodemon dist/server.js",
16-
"watch": "concurrently -k -p \"[{name}]\" -n \"Sass,TypeScript,Node\" -c \"yellow.bold,cyan.bold,green.bold\" \"npm run watch-sass\" \"npm run watch-ts\" \"npm run watch-node\"",
17-
"test": "jest --forceExit --coverage --verbose",
18-
"watch-test": "npm run test -- --watchAll",
19-
"build-ts": "tsc",
20-
"watch-ts": "tsc -w",
21-
"build-sass": "node-sass src/public/css/main.scss dist/public/css/main.css",
22-
"watch-sass": "node-sass -w src/public/css/main.scss dist/public/css/main.css",
23-
"lint": "tsc --noEmit && eslint \"**/*.{js,ts}\" --quiet --fix",
24-
"copy-static-assets": "ts-node copyStaticAssets.ts",
25-
"debug": "npm run build && npm run watch-debug",
26-
"serve-debug": "nodemon --inspect dist/server.js",
27-
"watch-debug": "concurrently -k -p \"[{name}]\" -n \"Sass,TypeScript,Node\" -c \"yellow.bold,cyan.bold,green.bold\" \"npm run watch-sass\" \"npm run watch-ts\" \"npm run serve-debug\""
28-
},
29-
"dependencies": {
30-
"async": "^3.0.1",
31-
"bcrypt-nodejs": "^0.0.3",
32-
"bluebird": "^3.5.5",
33-
"body-parser": "^1.19.0",
34-
"compression": "^1.7.4",
35-
"connect-mongo": "^3.0.0",
36-
"dotenv": "^8.0.0",
37-
"errorhandler": "^1.5.1",
38-
"express": "^4.17.1",
39-
"express-flash": "0.0.2",
40-
"express-session": "^1.16.2",
41-
"express-validator": "^6.0.1",
42-
"fbgraph": "^1.4.4",
43-
"lodash": "^4.17.13",
44-
"lusca": "^1.6.1",
45-
"mongoose": "^5.6.0",
46-
"nodemailer": "^6.2.1",
47-
"passport": "^0.4.0",
48-
"passport-facebook": "^3.0.0",
49-
"passport-local": "^1.0.0",
50-
"pug": "^2.0.4",
51-
"request": "^2.88.0",
52-
"request-promise": "^4.2.4",
53-
"winston": "^2.4.2"
54-
},
55-
"devDependencies": {
56-
"@types/async": "^3.0.0",
57-
"@types/bcrypt-nodejs": "^0.0.30",
58-
"@types/bluebird": "^3.5.27",
59-
"@types/body-parser": "^1.17.0",
60-
"@types/chai": "^4.1.7",
61-
"@types/compression": "^0.0.36",
62-
"@types/connect-mongo": "^0.0.42",
63-
"@types/dotenv": "^6.1.1",
64-
"@types/errorhandler": "^0.0.32",
65-
"@types/express": "^4.17.0",
66-
"@types/express-flash": "0.0.0",
67-
"@types/express-session": "^1.15.13",
68-
"@types/jest": "^24.0.15",
69-
"@types/jquery": "^3.3.29",
70-
"@types/lodash": "^4.14.134",
71-
"@types/lusca": "^1.6.0",
72-
"@types/mongodb": "^3.1.28",
73-
"@types/mongoose": "^5.5.6",
74-
"@types/morgan": "^1.7.35",
75-
"@types/node": "^12.0.10",
76-
"@types/nodemailer": "^6.2.0",
77-
"@types/passport": "^1.0.0",
78-
"@types/passport-facebook": "^2.1.9",
79-
"@types/passport-local": "^1.0.33",
80-
"@types/request": "^2.48.1",
81-
"@types/shelljs": "^0.8.5",
82-
"@types/supertest": "^2.0.7",
83-
"@types/winston": "^2.3.9",
84-
"@typescript-eslint/eslint-plugin": "^1.12.0",
85-
"@typescript-eslint/parser": "^1.12.0",
86-
"chai": "^4.2.0",
87-
"concurrently": "^4.1.0",
88-
"eslint": "^5.0.0",
89-
"jest": "^24.8.0",
90-
"node-sass": "^4.12.0",
91-
"nodemon": "^1.19.1",
92-
"shelljs": "^0.8.3",
93-
"supertest": "^4.0.2",
94-
"ts-jest": "^24.0.2",
95-
"ts-node": "^8.3.0",
96-
"typescript": "^3.5.2"
97-
}
2+
"name": "express-typescript-starter",
3+
"version": "0.1.0",
4+
"description": "A starting point for Node.js express apps with TypeScript",
5+
"repository": {
6+
"type": "git",
7+
"url": "https://github.com/Microsoft/TypeScript-Node-Starter"
8+
},
9+
"author": "Bowden Kelly",
10+
"license": "MIT",
11+
"scripts": {
12+
"start": "npm run serve",
13+
"build": "npm run build-sass && npm run build-ts && npm run lint && npm run copy-static-assets",
14+
"serve": "node dist/server.js",
15+
"watch-node": "nodemon dist/server.js",
16+
"watch": "concurrently -k -p \"[{name}]\" -n \"Sass,TypeScript,Node\" -c \"yellow.bold,cyan.bold,green.bold\" \"npm run watch-sass\" \"npm run watch-ts\" \"npm run watch-node\"",
17+
"test": "jest --forceExit --coverage --verbose",
18+
"watch-test": "npm run test -- --watchAll",
19+
"build-ts": "tsc",
20+
"watch-ts": "tsc -w",
21+
"build-sass": "node-sass src/public/css/main.scss dist/public/css/main.css",
22+
"watch-sass": "node-sass -w src/public/css/main.scss dist/public/css/main.css",
23+
"lint": "tsc --noEmit && eslint \"**/*.{js,ts}\" --quiet --fix",
24+
"copy-static-assets": "ts-node copyStaticAssets.ts",
25+
"debug": "npm run build && npm run watch-debug",
26+
"serve-debug": "nodemon --inspect dist/server.js",
27+
"watch-debug": "concurrently -k -p \"[{name}]\" -n \"Sass,TypeScript,Node\" -c \"yellow.bold,cyan.bold,green.bold\" \"npm run watch-sass\" \"npm run watch-ts\" \"npm run serve-debug\""
28+
},
29+
"dependencies": {
30+
"async": "^3.1.0",
31+
"bcrypt-nodejs": "^0.0.3",
32+
"bluebird": "^3.5.5",
33+
"body-parser": "^1.19.0",
34+
"compression": "^1.7.4",
35+
"connect-mongo": "^3.0.0",
36+
"dotenv": "^8.1.0",
37+
"errorhandler": "^1.5.1",
38+
"express": "^4.17.1",
39+
"express-flash": "0.0.2",
40+
"express-session": "^1.16.2",
41+
"express-validator": "^6.2.0",
42+
"fbgraph": "^1.4.4",
43+
"lodash": "^4.17.15",
44+
"lusca": "^1.6.1",
45+
"mongoose": "^5.7.1",
46+
"nodemailer": "^6.3.0",
47+
"passport": "^0.4.0",
48+
"passport-facebook": "^3.0.0",
49+
"passport-local": "^1.0.0",
50+
"pug": "^2.0.4",
51+
"request": "^2.88.0",
52+
"request-promise": "^4.2.4",
53+
"winston": "^3.2.1"
54+
},
55+
"devDependencies": {
56+
"@types/async": "^3.0.2",
57+
"@types/bcrypt-nodejs": "^0.0.30",
58+
"@types/bluebird": "^3.5.27",
59+
"@types/body-parser": "^1.17.1",
60+
"@types/chai": "^4.2.3",
61+
"@types/compression": "^1.0.1",
62+
"@types/concurrently": "^4.1.0",
63+
"@types/connect-mongo": "^0.0.43",
64+
"@types/dotenv": "^6.1.1",
65+
"@types/errorhandler": "^0.0.32",
66+
"@types/eslint": "^6.1.1",
67+
"@types/express": "^4.17.1",
68+
"@types/express-flash": "0.0.1",
69+
"@types/express-session": "^1.15.14",
70+
"@types/jest": "^24.0.18",
71+
"@types/jquery": "^3.3.31",
72+
"@types/lodash": "^4.14.141",
73+
"@types/lusca": "^1.6.1",
74+
"@types/mongoose": "^5.5.18",
75+
"@types/node": "^12.7.8",
76+
"@types/node-sass": "^4.11.0",
77+
"@types/nodemailer": "^6.2.1",
78+
"@types/passport": "^1.0.1",
79+
"@types/passport-facebook": "^2.1.9",
80+
"@types/passport-local": "^1.0.33",
81+
"@types/pug": "^2.0.4",
82+
"@types/request": "^2.48.3",
83+
"@types/request-promise": "^4.1.44",
84+
"@types/shelljs": "^0.8.5",
85+
"@types/supertest": "^2.0.8",
86+
"@types/winston": "^2.4.4",
87+
"@typescript-eslint/eslint-plugin": "^2.3.1",
88+
"@typescript-eslint/parser": "^2.3.1",
89+
"chai": "^4.2.0",
90+
"concurrently": "^4.1.2",
91+
"eslint": "^6.4.0",
92+
"jest": "^24.9.0",
93+
"node-sass": "^4.12.0",
94+
"nodemon": "^1.19.2",
95+
"shelljs": "^0.8.3",
96+
"supertest": "^4.0.2",
97+
"ts-jest": "^24.1.0",
98+
"ts-node": "^8.4.1",
99+
"typescript": "^3.6.3"
100+
}
98101
}

src/app.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ const app = express();
3030
const mongoUrl = MONGODB_URI;
3131
mongoose.Promise = bluebird;
3232

33-
mongoose.connect(mongoUrl, { useNewUrlParser: true, useCreateIndex: true } ).then(
33+
mongoose.connect(mongoUrl, { useNewUrlParser: true, useCreateIndex: true, useUnifiedTopology: true } ).then(
3434
() => { /** ready to use. The `mongoose.connect()` promise resolves to undefined. */ },
3535
).catch(err => {
3636
console.log("MongoDB connection error. Please make sure MongoDB is running. " + err);

src/config/passport.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import passportFacebook from "passport-facebook";
44
import _ from "lodash";
55

66
// import { User, UserType } from '../models/User';
7-
import { User } from "../models/User";
7+
import { User, UserDocument } from "../models/User";
88
import { Request, Response, NextFunction } from "express";
99

1010
const LocalStrategy = passportLocal.Strategy;
@@ -133,7 +133,8 @@ export const isAuthenticated = (req: Request, res: Response, next: NextFunction)
133133
export const isAuthorized = (req: Request, res: Response, next: NextFunction) => {
134134
const provider = req.path.split("/").slice(-1)[0];
135135

136-
if (_.find(req.user.tokens, { kind: provider })) {
136+
const user = req.user as UserDocument;
137+
if (_.find(user.tokens, { kind: provider })) {
137138
next();
138139
} else {
139140
res.redirect(`/auth/${provider}`);

src/controllers/api.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import graph from "fbgraph";
44
import { Response, Request, NextFunction } from "express";
5+
import { UserDocument } from "../models/User";
56

67

78
/**
@@ -19,9 +20,10 @@ export const getApi = (req: Request, res: Response) => {
1920
* Facebook API example.
2021
*/
2122
export const getFacebook = (req: Request, res: Response, next: NextFunction) => {
22-
const token = req.user.tokens.find((token: any) => token.kind === "facebook");
23+
const user = req.user as UserDocument;
24+
const token = user.tokens.find((token: any) => token.kind === "facebook");
2325
graph.setAccessToken(token.accessToken);
24-
graph.get(`${req.user.facebook}?fields=id,name,email,first_name,last_name,gender,link,locale,timezone`, (err: Error, results: graph.FacebookUser) => {
26+
graph.get(`${user.facebook}?fields=id,name,email,first_name,last_name,gender,link,locale,timezone`, (err: Error, results: graph.FacebookUser) => {
2527
if (err) { return next(err); }
2628
res.render("api/facebook", {
2729
title: "Facebook API",

src/controllers/user.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,8 @@ export const postUpdateProfile = (req: Request, res: Response, next: NextFunctio
142142
return res.redirect("/account");
143143
}
144144

145-
User.findById(req.user.id, (err, user: UserDocument) => {
145+
const user = req.user as UserDocument;
146+
User.findById(user.id, (err, user: UserDocument) => {
146147
if (err) { return next(err); }
147148
user.email = req.body.email || "";
148149
user.profile.name = req.body.name || "";
@@ -178,7 +179,8 @@ export const postUpdatePassword = (req: Request, res: Response, next: NextFuncti
178179
return res.redirect("/account");
179180
}
180181

181-
User.findById(req.user.id, (err, user: UserDocument) => {
182+
const user = req.user as UserDocument;
183+
User.findById(user.id, (err, user: UserDocument) => {
182184
if (err) { return next(err); }
183185
user.password = req.body.password;
184186
user.save((err: WriteError) => {
@@ -194,7 +196,8 @@ export const postUpdatePassword = (req: Request, res: Response, next: NextFuncti
194196
* Delete user account.
195197
*/
196198
export const postDeleteAccount = (req: Request, res: Response, next: NextFunction) => {
197-
User.remove({ _id: req.user.id }, (err) => {
199+
const user = req.user as UserDocument;
200+
User.remove({ _id: user.id }, (err) => {
198201
if (err) { return next(err); }
199202
req.logout();
200203
req.flash("info", { msg: "Your account has been deleted." });
@@ -208,7 +211,8 @@ export const postDeleteAccount = (req: Request, res: Response, next: NextFunctio
208211
*/
209212
export const getOauthUnlink = (req: Request, res: Response, next: NextFunction) => {
210213
const provider = req.params.provider;
211-
User.findById(req.user.id, (err, user: any) => {
214+
const user = req.user as UserDocument;
215+
User.findById(user.id, (err, user: any) => {
212216
if (err) { return next(err); }
213217
user[provider] = undefined;
214218
user.tokens = user.tokens.filter((token: AuthToken) => token.kind !== provider);

src/util/logger.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
import { Logger, LoggerOptions, transports } from "winston";
1+
import winston from "winston";
22

3-
const options: LoggerOptions = {
3+
const options: winston.LoggerOptions = {
44
transports: [
5-
new transports.Console({
5+
new winston.transports.Console({
66
level: process.env.NODE_ENV === "production" ? "error" : "debug"
77
}),
8-
new transports.File({ filename: "debug.log", level: "debug" })
8+
new winston.transports.File({ filename: "debug.log", level: "debug" })
99
]
1010
};
1111

12-
const logger = new Logger(options);
12+
const logger = winston.createLogger(options);
1313

1414
if (process.env.NODE_ENV !== "production") {
1515
logger.debug("Logging initialized at debug level");

test/user.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,27 @@ describe("GET /login", () => {
99
});
1010
});
1111

12+
13+
describe("GET /forgot", () => {
14+
it("should return 200 OK", () => {
15+
return request(app).get("/forgot")
16+
.expect(200);
17+
});
18+
});
19+
1220
describe("GET /signup", () => {
1321
it("should return 200 OK", () => {
1422
return request(app).get("/signup")
1523
.expect(200);
1624
});
1725
});
1826

27+
describe("GET /reset", () => {
28+
it("should return 302 Found for redirection", () => {
29+
return request(app).get("/reset/1")
30+
.expect(302);
31+
});
32+
});
1933

2034
describe("POST /login", () => {
2135
it("should return some defined error message with valid parameters", (done) => {

0 commit comments

Comments
 (0)