Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34,138 changes: 20,222 additions & 13,916 deletions package-lock.json

Large diffs are not rendered by default.

126 changes: 66 additions & 60 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,137 +4,143 @@
"description": "A Node-Typescript/Express Boilerplate with Authentication(Local, Github, Facebook, Twitter, Google, Dropbox, LinkedIn, Instagram, Slack), Authorization, and CRUD functionality + PWA Support!",
"main": "dist/server.js",
"scripts": {
"start": "npm run build:dev",
"start": "yarn build:dev",
"lint": "./node_modules/.bin/eslint '**/*.ts' --fix --quiet",
"test": "cross-env NODE_ENV=development jest --runInBand --forceExit",
"serve:dev": "cross-env NODE_ENV=development nodemon dist/server.js --public ",
"docker:serve": "cross-env NODE_ENV=development nodemon dist/server.js --public",
"serve:prod": "cross-env NODE_ENV=production ./node_modules/.bin/nodemon app/dist/server.js --public",
"watch-node": "./node_modules/.bin/nodemon dist/server.js",
"watch": "concurrently \"npm run bundle:watch \" \"npm run watch-ts:dev \" \"npm run serve:dev \" --names \"💻,📦\" --prefix name",
"watch:serve": " concurrently \"npm run bundle:watch \" \"npm run serve:prod \" \"npm run watch-ts:prod \" --names \"💻,📦\" --prefix name",
"watch": "concurrently \"yarn bundle:watch \" \"yarn watch-ts:dev \" \"yarn serve:dev \" --names \"💻,📦\" --prefix name",
"watch:serve": " concurrently \"yarn bundle:watch \" \"yarn serve:prod \" \"yarn watch-ts:prod \" --names \"💻,📦\" --prefix name",
"build-ts:dev": "tsc -p tsconfig.json",
"watch-ts:dev": "tsc -w -p tsconfig.json",
"build-ts:prod": "tsc -p tsconfig-prod.json",
"watch-ts:prod": "tsc -w -p tsconfig-prod.json ",
"serve-debug": "nodemon --inspect dist/server.js",
"copy-assets": "ts-node copy-files.ts",
"serve:watch": "concurrently \"npm run serve:prod\" \"npm run watch-ts\" \"npm run bundle\" --names \"💻,📦\" --prefix name",
"prod": "npm run build-ts:prod && npm run bundle && ts-node copy-files.ts",
"prod:serve": "npm run build-ts:prod && ts-node copy-files.ts && npm run watch:serve",
"serve:watch": "concurrently \"yarn serve:prod\" \"yarn watch-ts\" \"yarn bundle\" --names \"💻,📦\" --prefix name",
"prod": "yarn build-ts:prod && yarn bundle && ts-node copy-files.ts",
"prod:serve": "yarn build-ts:prod && ts-node copy-files.ts && yarn watch:serve",
"bundle:watch": "webpack -w --display-max-modules 0",
"bundle": "webpack --display-max-modules 0",
"build:dev": "npm run build-ts:dev && npm run watch",
"docker:build": "npm run build-ts:prod && npm run bundle && npm run copy-assets",
"pm2": "npm run prod && pm2 start ecosystem.config.js --env production",
"bundle": "webpack",
"build:dev": "yarn build-ts:dev && yarn watch",
"docker:build": "yarn build-ts:prod && yarn bundle && yarn copy-assets",
"pm2": "yarn prod && pm2 start ecosystem.config.js --env production",
"release": "release-it --config .release-it.json --no-npm.publish"
},
"keywords": [],
"author": "Obinna Odirionye",
"license": "MIT",
"dependencies": {
"bson": "^6.10.1",
"compression": "^1.7.4",
"connect-ensure-login": "^0.1.1",
"connect-flash": "^0.1.1",
"connect-mongo": "^3.0.0",
"connect-mongo": "^5.1.0",
"cors": "^2.8.5",
"dotenv": "^8.0.0",
"dotenv": "^16.4.7",
"errorhandler": "^1.5.1",
"express": "^4.17.1",
"express-flash": "0.0.2",
"express-recaptcha": "^5.0.1",
"express-session": "^1.16.2",
"express-status-monitor": "^1.2.6",
"express-validator": "^6.0.1",
"helmet": "^3.21.0",
"express-validator": "^7.2.1",
"helmet": "^8.0.0",
"md5": "^2.2.1",
"mongoose": "^5.6.0",
"mongodb": "^6.12.0",
"mongoose": "^8.9.5",
"mongoose-mongodb-errors": "0.0.2",
"morgan": "^1.9.1",
"nodemailer": "^6.3.0",
"nodemailer-sendgrid-transport": "^0.2.0",
"passport": "^0.4.0",
"nodemailer-sendgrid": "^1.0.3",
"passport": "^0.7.0",
"passport-discord": "^0.1.3",
"passport-dropbox-oauth2": "^1.1.0",
"passport-facebook": "^3.0.0",
"passport-github": "^1.1.0",
"passport-github2": "^0.1.12",
"passport-google-oauth": "^2.0.0",
"passport-linkedin-oauth2": "^2.0.0",
"passport-local": "^1.0.0",
"passport-local-mongoose": "^5.0.1",
"passport-local-mongoose": "^8.0.0",
"passport-slack": "0.0.7",
"passport-slack-oauth2": "^1.2.0",
"passport-twitter": "^1.0.4",
"pug": "^2.0.4",
"pug": "^3.0.3",
"shelljs": "^0.8.3",
"validator": "^11.1.0"
"validator": "^13.12.0"
},
"devDependencies": {
"@babel/core": "^7.3.4",
"@babel/preset-env": "^7.3.4",
"@release-it/conventional-changelog": "^1.1.0",
"@types/compression": "^0.0.36",
"@release-it/conventional-changelog": "^10.0.0",
"@types/compression": "^1.7.5",
"@types/connect-ensure-login": "^0.1.5",
"@types/connect-flash": "0.0.35",
"@types/connect-mongo": "^0.0.42",
"@types/connect-flash": "^0.0.40",
"@types/connect-mongo": "^3.1.6",
"@types/cors": "^2.8.6",
"@types/dotenv": "^6.1.1",
"@types/errorhandler": "^0.0.32",
"@types/es6-promisify": "^5.0.0",
"@types/express": "^4.17.0",
"@types/express-flash": "0.0.0",
"@types/dotenv": "^8.2.3",
"@types/errorhandler": "^1.5.3",
"@types/es6-promisify": "^6.0.4",
"@types/express": "^5.0.0",
"@types/express-flash": "0.0.5",
"@types/express-session": "^1.15.13",
"@types/helmet": "0.0.44",
"@types/jest": "^24.0.18",
"@types/helmet": "4.0.0",
"@types/jest": "^29.5.14",
"@types/md5": "^2.1.33",
"@types/mongodb": "^3.1.28",
"@types/mongodb": "^4.0.7",
"@types/mongoose": "^5.5.6",
"@types/morgan": "^1.7.37",
"@types/node": "^12.0.10",
"@types/node": "^22.10.10",
"@types/nodemailer": "^6.2.1",
"@types/passport": "^1.0.0",
"@types/passport-discord": "^0.1.3",
"@types/passport-facebook": "^2.1.9",
"@types/passport-facebook": "^3.0.3",
"@types/passport-github": "^1.1.5",
"@types/passport-google-oauth": "^1.0.41",
"@types/passport-linkedin-oauth2": "^1.5.0",
"@types/passport-local": "^1.0.33",
"@types/passport-local-mongoose": "^4.0.12",
"@types/passport-local-mongoose": "^6.1.5",
"@types/passport-twitter": "^1.0.34",
"@types/shelljs": "^0.8.5",
"@types/supertest": "^2.0.8",
"@types/validator": "^10.11.1",
"@typescript-eslint/eslint-plugin": "^1.12.0",
"@typescript-eslint/parser": "^1.12.0",
"auto-changelog": "^1.16.1",
"autoprefixer": "^9.4.10",
"@types/supertest": "^6.0.2",
"@types/validator": "^13.12.2",
"@typescript-eslint/eslint-plugin": "^8.21.0",
"@typescript-eslint/parser": "^8.21.0",
"auto-changelog": "^2.5.0",
"autoprefixer": "^10.4.20",
"babel-core": "6.26.3",
"babel-loader": "8.0.5",
"babel-loader": "9.2.1",
"babel-plugin-transform-util-promisify": "^0.2.2",
"babel-preset-env": "^1.7.0",
"concurrently": "^4.1.2",
"concurrently": "^9.1.2",
"cross-env": "^7.0.2",
"css-loader": "^3.2.0",
"css-loader": "^7.1.2",
"cz-conventional-changelog": "^3.0.2",
"eslint": "^5.16.0",
"eslint-config-airbnb": "^17.1.0",
"eslint-config-prettier": "^4.1.0",
"eslint": "^8.0.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-prettier": "^10.0.1",
"eslint-import-resolver-alias": "^1.1.2",
"eslint-plugin-import": "^2.17.2",
"eslint-plugin-jsx-a11y": "^6.2.1",
"eslint-plugin-prettier": "^3.0.1",
"eslint-plugin-prettier": "^5.2.3",
"eslint-plugin-react": "^7.12.4",
"extract-text-webpack-plugin": "^3.0.2",
"jest": "^24.9.0",
"nodemon": "^1.19.2",
"pm2": "^3.5.1",
"postcss-loader": "^3.0.0",
"prettier": "^1.17.0",
"release-it": "^12.4.3",
"supertest": "^4.0.2",
"ts-jest": "^24.1.0",
"ts-node": "^8.3.0",
"typescript": "^3.5.2",
"webpack": "^3.4.1"
"jest": "^29.7.0",
"mini-css-extract-plugin": "^2.9.2",
"nodemon": "^3.1.9",
"pm2": "^5.4.3",
"postcss-loader": "^8.1.1",
"prettier": "^3.4.2",
"release-it": "^18.1.2",
"supertest": "^7.0.0",
"terser-webpack-plugin": "^5.3.11",
"ts-jest": "^29.2.5",
"ts-node": "^10.9.2",
"typescript": "^5.7.3",
"webpack": "^5.97.1",
"webpack-cli": "^6.0.1"
},
"config": {
"commitizen": {
Expand Down
21 changes: 8 additions & 13 deletions src/app.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import express from "express";

import dotenv from "dotenv";
import mongoose from "mongoose";
import session from "express-session";
import passport from "passport";
import logger from "morgan";
import mongo from "connect-mongo";
import MongoStore from "connect-mongo";
import path from "path";
import flash from "connect-flash";
import compression from "compression";
Expand All @@ -18,9 +16,6 @@ import indexRouter from "./routes/index";
import authRouter from "./routes/auth";
import "./handlers/passport";

// import environmental variables from our variables.env file

const MongoStore = mongo(session);
// Create Express server
const app = express();

Expand All @@ -32,27 +27,27 @@ app.get("env") === "development" ? app.use(require("express-status-monitor")())
app.use(logger("dev"));
app.use(compression());
app.use(express.json());
app.use(express.urlencoded({extended: true}));
app.use(express.urlencoded({ extended: true }));
app.use(cors());

// serves up static files from the public folder. Anything in public/ will just be served up as the file it is
app.use(express.static(path.join(__dirname, "../public")));

// Takes the raw requests and turns them into usable properties on req.body
app.use(express.json());
app.use(express.urlencoded({extended: true}));
app.use(express.urlencoded({ extended: true }));

app.use(
session({
name: process.env.SESSION_NAME,
secret: process.env.SECRET,
secret: process.env.SESSION_SECRET || "secret",
resave: false,
saveUninitialized: false,
store: new MongoStore({mongooseConnection: mongoose.connection}),
}),
store: MongoStore.create({mongoUrl: process.env.MONGODB_URI || "mongodb://localhost:27017/your-db-name"
})
})
);

// Passport JS is what we use to handle our logins
// Initialize Passport and restore authentication state, if any, from the session.
app.use(passport.initialize());
app.use(passport.session());

Expand Down
12 changes: 8 additions & 4 deletions src/controllers/authController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@ export const login = (req: Request, res: Response) => {
res.render("login", {title: "Login | Hackathon Starter Kit"});
};

export const logout = (req: Request, res: Response) => {
req.logout();
req.flash("success", "You are now logged out! 👋");
res.redirect("/login");
export const logout = (req: Request, res: Response, next) => {
req.logout((err) => {
if (err) {
return next(err);
}
req.flash("success", "You are now logged out! 👋");
res.redirect("/login");
});
};

export const loginForm = (req: Request, res: Response) => {
Expand Down
56 changes: 29 additions & 27 deletions src/handlers/mail.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,32 @@
//@ts-ignore
import sgTransport from "nodemailer-sendgrid-transport";
import nodemailer from "nodemailer";
import nodemailer from 'nodemailer';
import nodemailerSendgrid from 'nodemailer-sendgrid';

// Step 1: Configure Nodemailer with SendGrid
const transport = nodemailer.createTransport(
sgTransport({
service: "SendGrid",
auth: {
api_user: `${process.env.SENDGRID_USERNAME}`, //Enter your Sendgrid username
api_key: `${process.env.SENDGRID_PASSWORD}`, // Enter your Sendgrid password
},
}),
nodemailerSendgrid({
apiKey: process.env.SENDGRID_API_KEY || '', // Ensure your API key is stored securely
})
);

export const send = (req: any, res: any) => {
const mailOptions = {
to: req.body.email, // Enter the email address that will receive emails. Defaults: Sends email to the `from` object.
from: `${req.body.name} ${req.body.surname} <${req.body.email}>`,
subject: `Choice of Framework is: ${req.body.need}`,
text: req.body.message,
};
transport.sendMail(mailOptions, function(err) {
if (err) {
req.flash("error", "Error! We did Something wrong");
res.redirect("/contact");
} else {
req.flash("success", "Email has been sent successfully!");
res.redirect("/contact");
}
});
};
// Step 2: Send an Email
export const send = async (req: any, res: any) => {
try {
const mailOptions = {
to: req.body.email, // Enter the email address that will receive emails. Defaults: Sends email to the `from` object.
from: `${req.body.name} ${req.body.surname} <${req.body.email}>`,
subject: `Choice of Framework is: ${req.body.need}`,
text: req.body.message,
};
transport.sendMail(mailOptions, (error) => {
if (error) {
req.flash("error", "Error! We did Something wrong");
res.redirect("/contact");
} else {
req.flash("success", "Email has been sent successfully!");
res.redirect("/contact");
}
});
} catch (error) {
console.error('Error sending email:', error);
}
}
Loading