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

Commit

Permalink
augment express.Request with User model
Browse files Browse the repository at this point in the history
Update User model
update "any" types to more specific
  • Loading branch information
GrayStrider committed Oct 6, 2019
1 parent 1409fd7 commit eb9bc30
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 31 deletions.
18 changes: 7 additions & 11 deletions src/config/passport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@ import passport from "passport";
import passportLocal from "passport-local";
import passportFacebook from "passport-facebook";
import _ from "lodash";

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

const LocalStrategy = passportLocal.Strategy;
const FacebookStrategy = passportFacebook.Strategy;

passport.serializeUser<any, any>((user, done) => {
passport.serializeUser((user: UserDocument, done) => {
done(undefined, user.id);
});

Expand All @@ -25,12 +22,12 @@ passport.deserializeUser((id, done) => {
* Sign in using Email and Password.
*/
passport.use(new LocalStrategy({ usernameField: "email" }, (email, password, done) => {
User.findOne({ email: email.toLowerCase() }, (err, user: any) => {
User.findOne({ email: email.toLowerCase() }, (err, user: UserDocument) => {
if (err) { return done(err); }
if (!user) {
return done(undefined, false, { message: `Email ${email} not found.` });
}
user.comparePassword(password, (err: Error, isMatch: boolean) => {
user.comparePassword(password, (err, isMatch) => {
if (err) { return done(err); }
if (isMatch) {
return done(undefined, user);
Expand Down Expand Up @@ -66,15 +63,15 @@ passport.use(new FacebookStrategy({
callbackURL: "/auth/facebook/callback",
profileFields: ["name", "email", "link", "locale", "timezone"],
passReqToCallback: true
}, (req: any, accessToken, refreshToken, profile, done) => {
}, (req, accessToken, refreshToken, profile, done) => {
if (req.user) {
User.findOne({ facebook: profile.id }, (err, existingUser) => {
if (err) { return done(err); }
if (existingUser) {
req.flash("errors", { msg: "There is already a Facebook account that belongs to you. Sign in with that account or delete it, then link it with your current account." });
done(err);
} else {
User.findById(req.user.id, (err, user: any) => {
User.findById(req.user.id, (err, user) => {
if (err) { return done(err); }
user.facebook = profile.id;
user.tokens.push({ kind: "facebook", accessToken });
Expand All @@ -100,7 +97,7 @@ passport.use(new FacebookStrategy({
req.flash("errors", { msg: "There is already an account using this email address. Sign in to that account and link it with Facebook manually from Account Settings." });
done(err);
} else {
const user: any = new User();
const user: UserDocument = new User();
user.email = profile._json.email;
user.facebook = profile.id;
user.tokens.push({ kind: "facebook", accessToken });
Expand Down Expand Up @@ -133,8 +130,7 @@ 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];

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

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


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

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

const user = req.user as UserDocument;
User.findById(user.id, (err, user: UserDocument) => {
User.findById(req.user.id, (err, user) => {
if (err) { return next(err); }
user.password = req.body.password;
user.save((err: WriteError) => {
Expand All @@ -196,8 +194,7 @@ export const postUpdatePassword = (req: Request, res: Response, next: NextFuncti
* Delete user account.
*/
export const postDeleteAccount = (req: Request, res: Response, next: NextFunction) => {
const user = req.user as UserDocument;
User.remove({ _id: user.id }, (err) => {
User.remove({ _id: req.user.id }, (err) => {
if (err) { return next(err); }
req.logout();
req.flash("info", { msg: "Your account has been deleted." });
Expand All @@ -211,10 +208,8 @@ export const postDeleteAccount = (req: Request, res: Response, next: NextFunctio
*/
export const getOauthUnlink = (req: Request, res: Response, next: NextFunction) => {
const provider = req.params.provider;
const user = req.user as UserDocument;
User.findById(user.id, (err, user: any) => {
User.findById(req.user.id, (err, user) => {
if (err) { return next(err); }
user[provider] = undefined;
user.tokens = user.tokens.filter((token: AuthToken) => token.kind !== provider);
user.save((err: WriteError) => {
if (err) { return next(err); }
Expand Down Expand Up @@ -267,7 +262,7 @@ export const postReset = (req: Request, res: Response, next: NextFunction) => {
User
.findOne({ passwordResetToken: req.params.token })
.where("passwordResetExpires").gt(Date.now())
.exec((err, user: any) => {
.exec((err, user) => {
if (err) { return next(err); }
if (!user) {
req.flash("errors", { msg: "Password reset token is invalid or has expired." });
Expand Down Expand Up @@ -346,14 +341,14 @@ export const postForgot = (req: Request, res: Response, next: NextFunction) => {
});
},
function setRandomToken(token: AuthToken, done: Function) {
User.findOne({ email: req.body.email }, (err, user: any) => {
User.findOne({ email: req.body.email }, (err, user) => {
if (err) { return done(err); }
if (!user) {
req.flash("errors", { msg: "Account with that email address does not exist." });
return res.redirect("/forgot");
}
user.passwordResetToken = token;
user.passwordResetExpires = Date.now() + 3600000; // 1 hour
user.passwordResetExpires = new Date(Date.now() + 3600000); // 1 hour
user.save((err: WriteError) => {
done(err, token, user);
});
Expand Down
4 changes: 2 additions & 2 deletions src/models/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import mongoose from "mongoose";
export type UserDocument = mongoose.Document & {
email: string;
password: string;
passwordResetToken: string;
passwordResetToken: AuthToken;
passwordResetExpires: Date;

facebook: string;
Expand All @@ -23,7 +23,7 @@ export type UserDocument = mongoose.Document & {
gravatar: (size: number) => string;
};

type comparePasswordFunction = (candidatePassword: string, cb: (err: any, isMatch: any) => {}) => void;
type comparePasswordFunction = (candidatePassword: string, cb: (err: Error, isMatch: boolean) => void) => void;

export interface AuthToken {
accessToken: string;
Expand Down
9 changes: 9 additions & 0 deletions src/types/express-request-with-user.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import {UserDocument} from "../models/User";
import {Request} from "express";

declare module 'express' {
export interface User extends UserDocument {}
export interface Request {
user?: User;
}
}

0 comments on commit eb9bc30

Please sign in to comment.