Skip to content

Commit

Permalink
reset email template and mailer
Browse files Browse the repository at this point in the history
  • Loading branch information
ak-appinventiv committed Feb 13, 2019
1 parent c0b106c commit b248c78
Show file tree
Hide file tree
Showing 53 changed files with 405 additions and 275 deletions.
3 changes: 2 additions & 1 deletion environments/development.env
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@

MONGODB_URI=mongodb://localhost:27017/local
PORT=3001
TOKEN_SECRET=asdfghjkl
AUTH_TOKEN_SECRET=asdfghjkl
MAIL_TOKEN_SECRET=lkjhgfdsa
3 changes: 2 additions & 1 deletion environments/local.env
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@

MONGODB_URI=mongodb://localhost:27017/local
PORT=3001
TOKEN_SECRET=asdfghjklas
AUTH_TOKEN_SECRET=asdfghjkl
MAIL_TOKEN_SECRET=lkjhgfdsa
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"@types/mongoose": "^5.3.5",
"@types/morgan": "^1.7.35",
"@types/node": "10.12.18",
"@types/nodemailer": "^4.6.5",
"@types/passport": "^1.0.0",
"@types/passport-jwt": "^3.0.1",
"@types/passport-local": "^1.0.33",
Expand All @@ -40,6 +41,7 @@
"jsonwebtoken": "^8.4.0",
"mongoose": "^5.4.1",
"morgan": "^1.9.1",
"nodemailer": "^5.1.1",
"passport": "^0.4.0",
"passport-jwt": "^4.0.0",
"passport-local": "^1.0.0",
Expand Down
Binary file added public/client/facebook.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/client/github.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion public/client/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,5 @@
</div>
</div>

<script type="text/javascript" src="javascripts/script.js"></script>
</body>
</html>
Binary file added public/client/linkedin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/client/twitter.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 26 additions & 0 deletions public/templates/forgot.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<div style="padding: 20px 0;min-height: 100%;background-color: #F5F5F5;font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'">
<div style="margin: auto;padding: 24px;width: calc(100% - 48px);background-color: #FFF;max-width: 320px;text-align: center;box-shadow: 0 2px 1px -1px rgba(0,0,0,.2), 0 1px 1px 0 rgba(0,0,0,.14), 0 1px 3px 0 rgba(0,0,0,.12)">
<img src="/favicon.png" /><br/>
<h3 style="color: #2ecc71;">Hello Ashish Gurjar</h3>
<p style="color: rgba(0,0,0,.96);font-size: 15px;">Seems like you forgot your password for TEA App. If this is true, click below to reset your password.</p>
<a href="#" style="display: inline-flex;height: 36px;line-height: 36px;padding: 0 12px;background-color: #e74c3c;color: #FFF;border-radius: 2px;text-decoration: none;font-size: 14px;font-weight: bold;text-shadow: 0 0 2px rgba(0,0,0,.12);">Reset Password</a>
<p style="color: rgba(0,0,0,.96);font-size: 15px;">If you did not forgot your password you can safely ignore this email.</p>
</div>
<div style="margin: 5px auto;padding: 24px;width: calc(100% - 48px);background-color: #FFF;max-width: 320px;text-align: center;box-shadow: 0 2px 1px -1px rgba(0,0,0,.2), 0 1px 1px 0 rgba(0,0,0,.14), 0 1px 3px 0 rgba(0,0,0,.12)">
<div class="center" style="flex-direction: row">
<a href="#" style="display: inline-block;margin: 0 5px;text-decoration: none;border-radius: 32px;overflow: hidden">
<img src="/facebook.png" style="height: 32px"/>
</a>
<a href="#" style="display: inline-block;margin: 0 5px;text-decoration: none;border-radius: 32px;overflow: hidden">
<img src="/twitter.png" style="height: 32px"/>
</a>
<a href="#" style="display: inline-block;margin: 0 5px;text-decoration: none;border-radius: 32px;overflow: hidden">
<img src="/github.png" style="height: 32px"/>
</a>
<a href="#" style="display: inline-block;margin: 0 5px;text-decoration: none;border-radius: 32px;overflow: hidden">
<img src="/linkedin.png" style="height: 32px"/>
</a>
</div><br/>
<span style="font-size: 13px;color: #666;">@ 2018 TEA App. All rights reserved.</span>
</div>
</div>
52 changes: 27 additions & 25 deletions src/app.ts
Original file line number Diff line number Diff line change
@@ -1,43 +1,44 @@
import * as bodyParser from "body-parser";
import * as cookieParser from "cookie-parser";
import { connect, connection } from "mongoose";
import * as ejs from "ejs";
import * as express from "express";
import * as favicon from "serve-favicon";
import * as logger from "morgan";
import * as path from "path";
import { environment, Bootstrap, DbLoagger, ResponseError } from "./utils";
import * as bodyParser from 'body-parser';
import * as cookieParser from 'cookie-parser';
import { connect, connection } from 'mongoose';
import * as ejs from 'ejs';
import * as express from 'express';
import * as favicon from 'serve-favicon';
import * as logger from 'morgan';
import * as path from 'path';
import { environment, Bootstrap, DbLoagger, ResponseError, Mailer } from './utils';

import { Request, Application, Response, NextFunction } from "express";
import { Request, Application, Response, NextFunction } from 'express';

import "./strategies";
import './strategies';

import routes from "./routes";
import routes from './routes';

type AppSingleton = App.Singleton<Application>;

export const app: AppSingleton = {
instance: express(),
async init(this: AppSingleton) {
this.initConfig();
await Mailer.init();
await this.initDatabase();
this.initRoutes();
},
/**
* It is used to setup view engine for templates rendering.
*/
initViewEngine(this: AppSingleton) {
this.instance.set("views", path.join(__dirname, "../public"));
this.instance.engine("html", ejs.renderFile);
this.instance.set("view engine", "html");
this.instance.set('views', path.join(__dirname, '../public'));
this.instance.engine('html', ejs.renderFile);
this.instance.set('view engine', 'html');
},
/**
* Initialize the database connection with MongoDB
*/
initDatabase(): Promise<void> {
return new Promise<void>((resolve, reject) => {
connection.once("open", async () => {
DbLoagger.info("Database Connected");
connection.once('open', async () => {
DbLoagger.info('Database Connected');
await Bootstrap.init();
resolve();
});
Expand All @@ -53,28 +54,29 @@ export const app: AppSingleton = {
*/
initConfig(this: AppSingleton) {
this.initViewEngine();
this.instance.use(favicon(path.join(__dirname, "../public/client", "favicon.png")));
this.instance.use(logger("dev"));
this.instance.use(favicon(path.join(__dirname, '../public/client', 'favicon.png')));
this.instance.use(logger('dev'));
this.instance.use(bodyParser.json());
this.instance.use(bodyParser.urlencoded({ extended: false }));
this.instance.use(cookieParser());
},
initRoutes(this: AppSingleton) {
this.instance.use("/", routes);
this.instance.use("/admin", express.static(path.join(__dirname, "../public/admin")));
this.instance.use(express.static(path.join(__dirname, "../public/client")));
this.instance.use('/', routes);
this.instance.use('/admin', express.static(path.join(__dirname, '../public/admin')));
this.instance.use('/templates', express.static(path.join(__dirname, '../public/templates')));
this.instance.use(express.static(path.join(__dirname, '../public/client')));

this.instance.use((req: Request, res: Response, next: NextFunction) => {
next(new ResponseError(404, "Not Found"));
next(new ResponseError(404, 'Not Found'));
});

this.instance.use((err: ResponseError, req: Request, res: Response, next: NextFunction) => {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get("env") === "development" ? err : {};
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render("client/error");
res.render('client/error');
});
},
};
40 changes: 20 additions & 20 deletions src/bin/server.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { app } from "../app";
import { Server } from "http";
import * as Debug from "debug";
import { environment, Console } from "../utils";
const debug = Debug("tea-app:server");
import { app } from '../app';
import { Server } from 'http';
import * as Debug from 'debug';
import { environment, Console } from '../utils';
const debug = Debug('tea-app:server');

/**
* Get port from environment and store in Express.
*/

const port = normalizePort(environment.PORT || "3000");
app.instance.set("port", port);
const port = normalizePort(environment.PORT || '3000');
app.instance.set('port', port);

/**
* Create HTTP server.
Expand All @@ -25,11 +25,11 @@ app.init().then(() => {
Console.info(`Listening on port ${port}`);
});
});
server.on("error", onError);
server.on("listening", onListening);
server.on('error', onError);
server.on('listening', onListening);

// function serverHandler(req: IncomingMessage, res: ServerResponse){
// res.end("Hello from server");
// res.end('Hello from server');
// }

/**
Expand All @@ -53,24 +53,24 @@ function normalizePort(val: any) {
}

/**
* Event listener for HTTP server "error" event.
* Event listener for HTTP server 'error' event.
*/

function onError(error: any) {
if (error.syscall !== "listen") {
if (error.syscall !== 'listen') {
throw error;
}

// const bind: any = typeof port === "string" ? "Pipe " + port : "Port " + port;
// const bind: any = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port;

// handle specific listen errors with friendly messages
switch (error.code) {
case "EACCES":
// console.error(bind + " requires elevated privileges");
case 'EACCES':
// console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case "EADDRINUSE":
// console.error(bind + " is already in use");
case 'EADDRINUSE':
// console.error(bind + ' is already in use');
process.exit(1);
break;
default:
Expand All @@ -79,11 +79,11 @@ function onError(error: any) {
}

/**
* Event listener for HTTP server "listening" event.
* Event listener for HTTP server 'listening' event.
*/

function onListening() {
const addr = server.address();
const bind = typeof addr === "string" ? "pipe " + addr : "port " + addr.port;
debug("Listening on " + bind);
const bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port;
debug('Listening on ' + bind);
}
2 changes: 1 addition & 1 deletion src/constants/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@

export * from "./messages";
export * from './messages';
16 changes: 8 additions & 8 deletions src/constants/messages.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@

export const ACCOUNT = {
CREATED: "Account created successfully.",
DETAILS: "Account details fetch successful.",
NOT_FOUND: "Account does not exists.",
CREATED: 'Account created successfully.',
DETAILS: 'Account details fetch successful.',
NOT_FOUND: 'Account does not exists.',
};

export const LOGIN = {
FAILED: "Invalid credentials.",
SUCCESS: "Logined Successfully.",
FAILED: 'Invalid credentials.',
SUCCESS: 'Logined Successfully.',
};

export const ERROR = {
INTERNAL: "Internal server error.",
INTERNAL: 'Internal server error.',
};

export const TOKEN = {
INVALID: "Token is not valid.",
VALID: "Token is verified.",
INVALID: 'Token is not valid.',
VALID: 'Token is verified.',
};
36 changes: 25 additions & 11 deletions src/controllers/admin.controller.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,42 @@
import { Response, Request, NextFunction } from "express";
import { ResponseError, Respond } from "../utils";
import { authenticate } from "passport";
import { TOKEN, ACCOUNT } from "../constants";
// import { ERROR } from "../constants";
import { Admin } from "../models/admin";
import * as Service from "../service";
import { Response, Request, NextFunction } from 'express';
import { ResponseError, Respond, Mailer, Console } from '../utils';
import { authenticate } from 'passport';
import { TOKEN, ACCOUNT, ERROR } from '../constants';
// import { ERROR } from '../constants';
import { Admin } from '../models/admin';
import * as Service from '../service';

export const adminController = {
login(req: Request, res: Response, next: NextFunction) {
const respond = new Respond(res);
authenticate("admin-login", (error: ResponseError, token, info) => {
authenticate('admin-login', (error: ResponseError, token, info) => {
if (error) {
console.log(error);
respond.error(error);
} else {
respond.success(info.message, token);
}
})(req, res, next);
},
validateToken(req: Request, res: Response) {
res.sendStatus(200);
forgot(req: Request, res: Response, next: NextFunction) {
const email = req.data.email;
Service.getId(Admin, {email}).then((id: string) => {
if (id) {
//
}
}).catch(() => {
Respond.error(res, new ResponseError(500, ERROR.INTERNAL));
});
Mailer​​.sendMail('forgot', email).then(() => {
Respond.success(res, 'Success');
}).catch((error) => {
Console.info(error);
Respond.error(res, error);
});
},
fetchProfile(req: Request, res: Response) {
const respond = new Respond(res);
if (req.user && req.user.ref === "admins") {
if (req.user && req.user.ref === 'admins') {
Service.details(Admin, req.user._id)
.then((result) => {
respond.success(ACCOUNT.DETAILS, result);
Expand Down
4 changes: 2 additions & 2 deletions src/controllers/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@

export * from "./admin.controller";
export * from "./user.controller";
export * from './admin.controller';
export * from './user.controller';
22 changes: 11 additions & 11 deletions src/controllers/user.controller.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { Response, Request, NextFunction } from "express";
import { Respond, ResponseError, Console } from "../utils";
import { authenticate } from "passport";
import { User } from "../models/user";
import * as Service from "../service";
import { ERROR, ACCOUNT, TOKEN } from "../constants";
import { Response, Request, NextFunction } from 'express';
import { Respond, ResponseError, Console } from '../utils';
import { authenticate } from 'passport';
import { User } from '../models/user';
import * as Service from '../service';
import { ERROR, ACCOUNT, TOKEN } from '../constants';

export const userController = {
login(req: Request, res: Response, next: NextFunction) {
const respond = new Respond(res);
authenticate("user-login", (error: ResponseError, token, info) => {
authenticate('user-login', (error: ResponseError, token, info) => {
if (error) {
respond.error(error);
} else {
Expand All @@ -21,7 +21,7 @@ export const userController = {
},
fetchProfile(req: Request, res: Response) {
const respond = new Respond(res);
if (req.user && req.user.ref === "users") {
if (req.user && req.user.ref === 'users') {
Service.details(User, req.user._id)
.then((result) => {
respond.success(ACCOUNT.DETAILS, result);
Expand All @@ -34,7 +34,7 @@ export const userController = {
},
fetchDetails(req: Request, res: Response) {
const respond = new Respond(res);
if (req.user && req.user.ref === "admins") {
if (req.user && req.user.ref === 'admins') {
Service.details(User, req.data.id)
.then((result) => {
respond.success(ACCOUNT.DETAILS, result);
Expand All @@ -60,10 +60,10 @@ export const userController = {
console.log(req.data);
const respond = new Respond(res);
Service.list(User, req.data).then((result) => {
respond.success("List Fetch Successfully", result);
respond.success('List Fetch Successfully', result);
}).catch((error: ResponseError) => {
Console.error(error);
});
// res.send("Listing");
// res.send('Listing');
},
};
Loading

0 comments on commit b248c78

Please sign in to comment.