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

Commit

Permalink
Update packages, add tests, add type casts (#229)
Browse files Browse the repository at this point in the history
- 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
  • Loading branch information
CarlosSolrac authored and peterblazejewicz committed Sep 29, 2019
1 parent ca14e7c commit 1409fd7
Show file tree
Hide file tree
Showing 9 changed files with 1,531 additions and 1,157 deletions.
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"semi": ["error", "always"],
"quotes": ["error", "double"],
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/no-explicit-any": "off"
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-inferrable-types": "off"
}
}
2,441 changes: 1,395 additions & 1,046 deletions package-lock.json

Large diffs are not rendered by default.

195 changes: 99 additions & 96 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,98 +1,101 @@
{
"name": "express-typescript-starter",
"version": "0.1.0",
"description": "A starting point for Node.js express apps with TypeScript",
"repository": {
"type": "git",
"url": "https://github.com/Microsoft/TypeScript-Node-Starter"
},
"author": "Bowden Kelly",
"license": "MIT",
"scripts": {
"start": "npm run serve",
"build": "npm run build-sass && npm run build-ts && npm run lint && npm run copy-static-assets",
"serve": "node dist/server.js",
"watch-node": "nodemon dist/server.js",
"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\"",
"test": "jest --forceExit --coverage --verbose",
"watch-test": "npm run test -- --watchAll",
"build-ts": "tsc",
"watch-ts": "tsc -w",
"build-sass": "node-sass src/public/css/main.scss dist/public/css/main.css",
"watch-sass": "node-sass -w src/public/css/main.scss dist/public/css/main.css",
"lint": "tsc --noEmit && eslint \"**/*.{js,ts}\" --quiet --fix",
"copy-static-assets": "ts-node copyStaticAssets.ts",
"debug": "npm run build && npm run watch-debug",
"serve-debug": "nodemon --inspect dist/server.js",
"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\""
},
"dependencies": {
"async": "^3.0.1",
"bcrypt-nodejs": "^0.0.3",
"bluebird": "^3.5.5",
"body-parser": "^1.19.0",
"compression": "^1.7.4",
"connect-mongo": "^3.0.0",
"dotenv": "^8.0.0",
"errorhandler": "^1.5.1",
"express": "^4.17.1",
"express-flash": "0.0.2",
"express-session": "^1.16.2",
"express-validator": "^6.0.1",
"fbgraph": "^1.4.4",
"lodash": "^4.17.13",
"lusca": "^1.6.1",
"mongoose": "^5.6.0",
"nodemailer": "^6.2.1",
"passport": "^0.4.0",
"passport-facebook": "^3.0.0",
"passport-local": "^1.0.0",
"pug": "^2.0.4",
"request": "^2.88.0",
"request-promise": "^4.2.4",
"winston": "^2.4.2"
},
"devDependencies": {
"@types/async": "^3.0.0",
"@types/bcrypt-nodejs": "^0.0.30",
"@types/bluebird": "^3.5.27",
"@types/body-parser": "^1.17.0",
"@types/chai": "^4.1.7",
"@types/compression": "^0.0.36",
"@types/connect-mongo": "^0.0.42",
"@types/dotenv": "^6.1.1",
"@types/errorhandler": "^0.0.32",
"@types/express": "^4.17.0",
"@types/express-flash": "0.0.0",
"@types/express-session": "^1.15.13",
"@types/jest": "^24.0.15",
"@types/jquery": "^3.3.29",
"@types/lodash": "^4.14.134",
"@types/lusca": "^1.6.0",
"@types/mongodb": "^3.1.28",
"@types/mongoose": "^5.5.6",
"@types/morgan": "^1.7.35",
"@types/node": "^12.0.10",
"@types/nodemailer": "^6.2.0",
"@types/passport": "^1.0.0",
"@types/passport-facebook": "^2.1.9",
"@types/passport-local": "^1.0.33",
"@types/request": "^2.48.1",
"@types/shelljs": "^0.8.5",
"@types/supertest": "^2.0.7",
"@types/winston": "^2.3.9",
"@typescript-eslint/eslint-plugin": "^1.12.0",
"@typescript-eslint/parser": "^1.12.0",
"chai": "^4.2.0",
"concurrently": "^4.1.0",
"eslint": "^5.0.0",
"jest": "^24.8.0",
"node-sass": "^4.12.0",
"nodemon": "^1.19.1",
"shelljs": "^0.8.3",
"supertest": "^4.0.2",
"ts-jest": "^24.0.2",
"ts-node": "^8.3.0",
"typescript": "^3.5.2"
}
"name": "express-typescript-starter",
"version": "0.1.0",
"description": "A starting point for Node.js express apps with TypeScript",
"repository": {
"type": "git",
"url": "https://github.com/Microsoft/TypeScript-Node-Starter"
},
"author": "Bowden Kelly",
"license": "MIT",
"scripts": {
"start": "npm run serve",
"build": "npm run build-sass && npm run build-ts && npm run lint && npm run copy-static-assets",
"serve": "node dist/server.js",
"watch-node": "nodemon dist/server.js",
"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\"",
"test": "jest --forceExit --coverage --verbose",
"watch-test": "npm run test -- --watchAll",
"build-ts": "tsc",
"watch-ts": "tsc -w",
"build-sass": "node-sass src/public/css/main.scss dist/public/css/main.css",
"watch-sass": "node-sass -w src/public/css/main.scss dist/public/css/main.css",
"lint": "tsc --noEmit && eslint \"**/*.{js,ts}\" --quiet --fix",
"copy-static-assets": "ts-node copyStaticAssets.ts",
"debug": "npm run build && npm run watch-debug",
"serve-debug": "nodemon --inspect dist/server.js",
"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\""
},
"dependencies": {
"async": "^3.1.0",
"bcrypt-nodejs": "^0.0.3",
"bluebird": "^3.5.5",
"body-parser": "^1.19.0",
"compression": "^1.7.4",
"connect-mongo": "^3.0.0",
"dotenv": "^8.1.0",
"errorhandler": "^1.5.1",
"express": "^4.17.1",
"express-flash": "0.0.2",
"express-session": "^1.16.2",
"express-validator": "^6.2.0",
"fbgraph": "^1.4.4",
"lodash": "^4.17.15",
"lusca": "^1.6.1",
"mongoose": "^5.7.1",
"nodemailer": "^6.3.0",
"passport": "^0.4.0",
"passport-facebook": "^3.0.0",
"passport-local": "^1.0.0",
"pug": "^2.0.4",
"request": "^2.88.0",
"request-promise": "^4.2.4",
"winston": "^3.2.1"
},
"devDependencies": {
"@types/async": "^3.0.2",
"@types/bcrypt-nodejs": "^0.0.30",
"@types/bluebird": "^3.5.27",
"@types/body-parser": "^1.17.1",
"@types/chai": "^4.2.3",
"@types/compression": "^1.0.1",
"@types/concurrently": "^4.1.0",
"@types/connect-mongo": "^0.0.43",
"@types/dotenv": "^6.1.1",
"@types/errorhandler": "^0.0.32",
"@types/eslint": "^6.1.1",
"@types/express": "^4.17.1",
"@types/express-flash": "0.0.1",
"@types/express-session": "^1.15.14",
"@types/jest": "^24.0.18",
"@types/jquery": "^3.3.31",
"@types/lodash": "^4.14.141",
"@types/lusca": "^1.6.1",
"@types/mongoose": "^5.5.18",
"@types/node": "^12.7.8",
"@types/node-sass": "^4.11.0",
"@types/nodemailer": "^6.2.1",
"@types/passport": "^1.0.1",
"@types/passport-facebook": "^2.1.9",
"@types/passport-local": "^1.0.33",
"@types/pug": "^2.0.4",
"@types/request": "^2.48.3",
"@types/request-promise": "^4.1.44",
"@types/shelljs": "^0.8.5",
"@types/supertest": "^2.0.8",
"@types/winston": "^2.4.4",
"@typescript-eslint/eslint-plugin": "^2.3.1",
"@typescript-eslint/parser": "^2.3.1",
"chai": "^4.2.0",
"concurrently": "^4.1.2",
"eslint": "^6.4.0",
"jest": "^24.9.0",
"node-sass": "^4.12.0",
"nodemon": "^1.19.2",
"shelljs": "^0.8.3",
"supertest": "^4.0.2",
"ts-jest": "^24.1.0",
"ts-node": "^8.4.1",
"typescript": "^3.6.3"
}
}
2 changes: 1 addition & 1 deletion src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const app = express();
const mongoUrl = MONGODB_URI;
mongoose.Promise = bluebird;

mongoose.connect(mongoUrl, { useNewUrlParser: true, useCreateIndex: true } ).then(
mongoose.connect(mongoUrl, { useNewUrlParser: true, useCreateIndex: true, useUnifiedTopology: true } ).then(
() => { /** ready to use. The `mongoose.connect()` promise resolves to undefined. */ },
).catch(err => {
console.log("MongoDB connection error. Please make sure MongoDB is running. " + err);
Expand Down
5 changes: 3 additions & 2 deletions src/config/passport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import passportFacebook from "passport-facebook";
import _ from "lodash";

// import { User, UserType } from '../models/User';
import { User } from "../models/User";
import { User, UserDocument } from "../models/User";
import { Request, Response, NextFunction } from "express";

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

if (_.find(req.user.tokens, { kind: provider })) {
const user = req.user as UserDocument;
if (_.find(user.tokens, { kind: provider })) {
next();
} else {
res.redirect(`/auth/${provider}`);
Expand Down
6 changes: 4 additions & 2 deletions src/controllers/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import graph from "fbgraph";
import { Response, Request, NextFunction } from "express";
import { UserDocument } from "../models/User";


/**
Expand All @@ -19,9 +20,10 @@ export const getApi = (req: Request, res: Response) => {
* Facebook API example.
*/
export const getFacebook = (req: Request, res: Response, next: NextFunction) => {
const token = req.user.tokens.find((token: any) => token.kind === "facebook");
const user = req.user as UserDocument;
const token = user.tokens.find((token: any) => token.kind === "facebook");
graph.setAccessToken(token.accessToken);
graph.get(`${req.user.facebook}?fields=id,name,email,first_name,last_name,gender,link,locale,timezone`, (err: Error, results: graph.FacebookUser) => {
graph.get(`${user.facebook}?fields=id,name,email,first_name,last_name,gender,link,locale,timezone`, (err: Error, results: graph.FacebookUser) => {
if (err) { return next(err); }
res.render("api/facebook", {
title: "Facebook API",
Expand Down
12 changes: 8 additions & 4 deletions src/controllers/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@ export const postUpdateProfile = (req: Request, res: Response, next: NextFunctio
return res.redirect("/account");
}

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

User.findById(req.user.id, (err, user: UserDocument) => {
const user = req.user as UserDocument;
User.findById(user.id, (err, user: UserDocument) => {
if (err) { return next(err); }
user.password = req.body.password;
user.save((err: WriteError) => {
Expand All @@ -194,7 +196,8 @@ export const postUpdatePassword = (req: Request, res: Response, next: NextFuncti
* Delete user account.
*/
export const postDeleteAccount = (req: Request, res: Response, next: NextFunction) => {
User.remove({ _id: req.user.id }, (err) => {
const user = req.user as UserDocument;
User.remove({ _id: user.id }, (err) => {
if (err) { return next(err); }
req.logout();
req.flash("info", { msg: "Your account has been deleted." });
Expand All @@ -208,7 +211,8 @@ export const postDeleteAccount = (req: Request, res: Response, next: NextFunctio
*/
export const getOauthUnlink = (req: Request, res: Response, next: NextFunction) => {
const provider = req.params.provider;
User.findById(req.user.id, (err, user: any) => {
const user = req.user as UserDocument;
User.findById(user.id, (err, user: any) => {
if (err) { return next(err); }
user[provider] = undefined;
user.tokens = user.tokens.filter((token: AuthToken) => token.kind !== provider);
Expand Down
10 changes: 5 additions & 5 deletions src/util/logger.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { Logger, LoggerOptions, transports } from "winston";
import winston from "winston";

const options: LoggerOptions = {
const options: winston.LoggerOptions = {
transports: [
new transports.Console({
new winston.transports.Console({
level: process.env.NODE_ENV === "production" ? "error" : "debug"
}),
new transports.File({ filename: "debug.log", level: "debug" })
new winston.transports.File({ filename: "debug.log", level: "debug" })
]
};

const logger = new Logger(options);
const logger = winston.createLogger(options);

if (process.env.NODE_ENV !== "production") {
logger.debug("Logging initialized at debug level");
Expand Down
14 changes: 14 additions & 0 deletions test/user.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,27 @@ describe("GET /login", () => {
});
});


describe("GET /forgot", () => {
it("should return 200 OK", () => {
return request(app).get("/forgot")
.expect(200);
});
});

describe("GET /signup", () => {
it("should return 200 OK", () => {
return request(app).get("/signup")
.expect(200);
});
});

describe("GET /reset", () => {
it("should return 302 Found for redirection", () => {
return request(app).get("/reset/1")
.expect(302);
});
});

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

0 comments on commit 1409fd7

Please sign in to comment.