Express server communicating with React App - node.js

I am trying to redirect to my React App after authenticating the login.
But its not working, don't know why.
React App at port 3000
Server at port 3001
I am routing to server on login submit -> server authenticate using passport -> it should redirect to React App route '/secured'. Instead it is showing GET http://localhost:3001/secured 404 (Not Found)
It is routing to the server address. How to resolve this?
Authentication is working fine. I have checked it all using postman.
EXPRESS SERVER
//middleware
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))
app.use(cors({
origin: 'http://localhost:3000', //location of frontend app (react app here)
credentials: true,
}))
app.use(expressSession({
secret: 'secret',
resave: true,
saveUninitialized: true,
}))
app.use(cookieParser('secret'))
app.use(passport.initialize())
app.use(passport.session())
require('./models/passport-config')(passport)
// routes
app.get('/', (req, res) => {
res.send('Home route')
})
app.post('/login', (req, res, next) => {
passport.authenticate('local', (err, user, info) => {
if (err) { return next(err) }
if (!user) { return res.redirect('/') }
req.logIn(user, (err) => {
if (err) { return next(err) }
return res.redirect('/secured')
})
})(req, res, next)
})
app.post('/register', (req, res) => {
console.log(req.body)
})
app.get('/user', (req, res) => {
res.send(req.user)
})
// server init
app.listen(3001, () => {
console.log('serving at http://localhost:3001...')
})
"REACT APP - App.js
import './App.css';
import Register from './components/Register';
import Login from './components/Login';
import {BrowserRouter, Route} from 'react-router-dom'
function App() {
return (
<div className="App">
<BrowserRouter>
<div>
<Route exact path="/" component={Login} />
<Route path="/secured" component={Register} />
</div>
</BrowserRouter>
</div>
);
}
export default App;
REACT APP - Login.js
import React, { Component } from 'react'
import "./login.css"
import axios from 'axios'
class Login extends Component {
constructor(props) {
super(props)
this.state = {
username: null,
password: null,
}
}
handleChange = (event) => {
event.preventDefault()
this.setState({
...this.state,
[event.target.name]: event.target.value,
})
}
handleSubmit = (event) => {
event.preventDefault()
axios({
method: "post",
data: this.state,
withCredentials: true,
url: 'http://localhost:3001/login'
})
// .then(this.getData())
}
getData = () => {
axios({
method: "get",
data: this.state,
withCredentials: true,
url: 'http://localhost:3001/user'
}).then(res => {
this.setState({
username: res.data['0'].username,
email: res.data['0'].email,
password: null
});
})
}
render() {
return (
<div >
<div>
<form id='login' onSubmit={this.handleSubmit}>
<div>
<h3>Login</h3>
</div>
<div >
<div >
<input onChange={this.handleChange} id="icon_prefix" type="text" name='username' />
<label htmlFor="icon_prefix">Username</label>
</div>
</div>
<div>
<div >
<input onChange={this.handleChange} id="icon_prefix" type="password" name='password' />
<label htmlFor="icon_prefix2">Password</label>
</div>
</div>
<div >
<div >
<input type='submit' />
</div>
</div>
</form>
<div>
Already a member? Register here
</div>
</div>
</div>
)
}
}
export default Login

Inside your handleSubmit function in your <Login /> component, you should add the .then() callback, check the response for error/success and then either show an error to the user in the UI or use React Router History to push or replace the current route.
Another option would maybe be to store a state variable in your <Login /> component, like this.state.isAuthenticated which you could then check in your render() method and choose to return a React Router Redirect like:
render() {
if (this.state.isAuthenticated) {
return <Redirect to="/somewhere/else" />
}
return (
<div>
...
</div>
)
}

Related

Using CSURF in Express app with session package without using body-parser

I am trying to use CSURF package in Express App without using Body-Parser package. Body-Parser isn't needed in Express App because we can use app.use(express.json())to handle request.body instead of Body-Parser so I am trying to figure out a way to use CSURF without having Body-Parser in my app.
I have installed CSURF and following the instructions online without using Body-Parser but I got errors saying that the CSRF key is missing. My front-end is a login form and I have used EJS in order to send the CSRF Token from the server to the front-end.
Front-end:
<form id="login-form">
<div class="input-group form-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fas fa-user"></i></span>
</div>
**<input type="hidden" id="_csrf" name="_csrf" value= "<%= csrfToken %>" > **
<input type="text" class="form-control" id="username" placeholder="username">
</div>
<div class="input-group form-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fas fa-key"></i></span>
</div>
<input type="password" class="form-control" id="password" placeholder="password">
</div>
<div class="form-group">
<input type="submit" value="Login" class="btn float-right login_btn">
</div>
</form>
<script>
const form = document.querySelector('#login-form');
form.addEventListener('submit', (event) => {
event.preventDefault();
const username = form.elements.username.value;
const password = form.elements.password.value;
const csrf = form.elements._csrf.value
fetch('/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ username, password,csrf }),
})
</script>
Back-end:
router.post('/login', (req, res, next) => {
console.log(req.body.csrf);
if (!req.body.csrf) {
// Return an error if the CSRF token is missing
return res.send({ message: 'CSRF token missing' });
}
// Check if the CSRF token in the request body matches the one in the session
if (req.body.csrf !== req.csrfToken()) {
// Return an error if the CSRF token is invalid
return res.send({ message: 'CSRF token invalid' });
} else {
// Authenticate the user using the local strategy
passport.authenticate('local', (error, user, info) => {
if (error) {
return next(error);
}
if (!user) {
return res.send({ success: false, message: 'Invalid username or password' });
}
req.login(user, (error) => {
if (error) {
return next(error);
}
req.session.loggedIn = true;
res.send({ success: true, message: 'Login success, redirecting you to homepage in 3 seconds' });
return;
});
})
(req, res, next);
}
});
router.get('/login', (req, res) => {
console.log(req.csrfToken());
res.render('login', { csrfToken: req.csrfToken() });
});
App:
app.use(express.json());
express.urlencoded({ extended: true });
app.use(express.static('public'));
app.set('view engine', 'ejs');
app.use(
session({
store: new MSSQLStore(DBconfig, options),
secret: process.env.SESSION_KEY,
resave: false,
saveUninitialized: true,
cookie: {
maxAge: 1000 * 60 * 60 * 24, // 24 hours
secure: true
}
}));
app.use(csurf({ }));
app.use(function (req, res, next) {
res.locals.csrfToken = req.csrfToken();
next();
})
require('./routes/lib/passport.js');
app.use(passport.initialize());
app.use(passport.session());
app.use('/login', loginRouter); //define login route

how to take information from html input and pass into nodeJS variable

I have one question.
I have form in index.html page(see below).
<form action="/" method="post">
<input type="text" name="name" placeholder="customer name"/>
<button type="submit" name="submit">Submit</button>
</form>
and have also server.js page with code as you see in below
const express = require("express");
const bodyParser = require("body-parser");
const app = express();
app.use(bodyParser.urlencoded({ extended: true }));
app.get("/", function(req, res) {
res.sendFile(__dirname + "/index.html");
});
app.get("/api/customers", (req, res) => {
var name = req.body.name;
const customers = [
{ id: 1, firstName:name}
];
res.json(customers);
});
const port = 5000;
app.listen(port, () => console.log(`server ${port}`));
Now my question is:
When I am writing something in my input I want to take that text and pass it into my nodeJS.
For example if I write "Test" and press "Submit" button it should show "[{"id":1,"firstName":"Test"}]
you can use the fetch to make a request and then get it's response,
handleInputChange = (e) => {
this.setState({
name : e.target.value
})
}
handleSubmit = (e) => {
e.preventDefault();
const data = { name : this.state.name };
fetch('/api/customers', {
method: 'GET', // *GET, POST, PUT, DELETE, etc.
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data) // body data type must match "Content-Type" header
})
.then((response) => response.json())
.then((result) => {
this.setState({ customers : result}, () => {
console.log('Success:', result);
});
})
.catch((error) => {
console.error('Error:', error);
});
}
and you can use the handleInputChange and handleSubmit in the form,
<form onSubmit={this.handleSubmit} id="form">
<input type="text" name="name" onChange={this.handleInputChange} placeholder="customer name"/>
<button type="submit" name="submit">Submit</button>
<div id="result">{this.state.customers && this.state.customers.map(cust => {
return (
<span key={cust.id}>{cust.name}</span>
)
})}</div>
</form>

How to send data from React to Express

I'm trying to create login/registration for an app using React/Node/Express/Postgres. Where I'm getting stuck is receiving data on the server side from my form in React.
I have a register component for the form in register.js
import React from 'react';
import useForm from '../form/useForm';
const Register = () => {
const { values, handleChange, handleSubmit } = useForm({
name: '',
email: '',
password: "",
password2: ""
}, register);
function register() {
console.log(values);
}
return (
<div className="row mt-5">
<div className="col-md-6 m-auto">
<div className="card card-body">
<h1 className="text-center mb-3">
<i className="fas fa-user-plus"></i> Register
</h1>
<form
action="/users/register"
method="POST"
onSubmit={handleSubmit}>
<div className="form-group">
<label htmlFor="name">Name</label>
<input
className="form-control"
type="name"
name="name"
onChange={handleChange}
placeholder="Enter Name"
value={values.name}
required />
</div>
<div className="form-group">
<label htmlFor="email">Email</label>
<input
className="form-control"
type="email"
name="email"
onChange={handleChange}
placeholder="Enter Email"
value={values.email}
required />
</div>
<div className="form-group">
<label htmlFor="email">Password</label>
<input
className="form-control"
type="password"
name="password"
onChange={handleChange}
placeholder="Create Password"
value={values.password}
required />
</div>
<div className="form-group">
<label htmlFor="email">Confirm Password</label>
<input
className="form-control"
type="password"
name="password2"
onChange={handleChange}
placeholder="Confirm Password"
value={values.password2}
required />
</div>
<button type="submit" className="btn btn-primary btn-block">
Register
</button>
</form>
<p className="lead mt-4">Have An Account? Login</p>
</div>
</div>
</div>
);
};
export default Register;
A hook to handle the form actions in useForm.js
import {useState, useEffect} from 'react';
const useForm = (initialValues, callback) => {
const [hasError, setErrors] = useState(false);
const [values, setValues] = useState(initialValues);
const handleSubmit = (event) => {
if (event) event.preventDefault();
const options = {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(setValues(values => ({ ...values, [event.target.name]: event.target.value })))
}
fetch("/users/register", options)
}
const handleChange = (event) => {
event.persist();
setValues(values => ({ ...values, [event.target.name]: event.target.value }));
};
return {
handleChange,
handleSubmit,
values,
}
};
export default useForm;
Then I have a file to manage the routes for logging in/registering in users.js
const express = require("express");
const Router = require("express-promise-router");
const db = require("../db");
const router = new Router();
//Login page
router.get('/login', (req, res) => res.send("Login"));
//Register page
router.get('/register', (req, res) => res.send("Register"));
//Register Handle
router.post('/register', (req, res) => {
console.log(req.body);
res.send('hecks');
});
module.exports = router;
I have tried messing with things inside of the handleSubmit function in my useForm.js hook, but everything leads to the console.log(req.body) from my users.js file to return as undefined. Where am I going wrong?
Edit #1: Snip from Postman sending post request
Edit #2: basic project structure
.
./client
./client/src
./client/src/components
./client/src/components/register
./client/src/components/register/register.js
./client/src/components/form
./client/src/components/form/useForm.js
./client/src/App.js
./routes
./routes/index.js
./routes/users.js
./server.js
Edit #3: Main server.js file
const express = require("express");
const mountRoutes = require("./routes");
const app = express();
mountRoutes(app);
var bodyParser = require("body-parser");
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
//catch all other routes
app.get("*", function(req, res) {
res.send("<h1>Page does not exist, sorry</h1>");
});
const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Server started on port ${port}`));
You’re setting state in JSON.stringify which returns undefined. you’ve to pass values in it:
const handleSubmit = (event) => {
if (event) event.preventDefault();
const options = {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(values)
}
fetch("/users/register", options)
}
You need to apply bodyParser before mounting routes.
So change like this:
var bodyParser = require("body-parser");
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
mountRoutes(app);
You don't use then or await in the handleSubmit function which may cause problem.
Can you update the handleSubmit function like this and try?
const handleSubmit = async event => {
if (event) event.preventDefault();
const options = {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(values)
};
try {
const response = await fetch("/users/register", options);
const responseData = await response.json();
if (response.ok) {
console.log("response ok");
callback();
} else {
console.log("response NOT ok");
throw new Error(responseData.message);
}
} catch (err) {
console.log(err);
if (err.response) {
console.log(err.response.data);
}
}
};
πŸ‘¨β€πŸ« You can try with this code below:
userForm.js: Make sure your handleSubmit in your userForm.js it's looks like this code below: πŸ‘‡
const handleSubmit = async(event) => {
if (event) event.preventDefault();
const options = {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(values)
}
try {
// change with your endpoint
const endpoint = 'http://localhost:3001/users/register';
const result = await fetch(endpoint, options);
// send value to your register function
callback(result);
} catch (ex) {
console.log('Something failed');
console.log(ex);
}
}
You've to use callback(result), so you can console.log that value on your register function.
express server: Make sure in your express server, you've been add body-parser, it's will looks like this code below: πŸ‘‡
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
That code above will make your req.body works.
I hope it can help you πŸ™.

How to send contact form details to email in angular 6?

I am using a contact form in my application.In this i am sending the contact form details on a particular email id. All this i have to do in angular 6. I have tried this using nodemailer but not getting proper procedure to implement it. Thanks in advance
this is support.ts
import { Component, OnInit } from '#angular/core';
import { FormGroup, FormBuilder, Validators } from '#angular/forms';
import { client, response } from '../../interface'
import { ClientService } from '../../services/client.service'
import { EmailService } from '../../services/email.service'
import { Store } from '#ngrx/store'
import { AppState } from '../../app.state'
#Component({
selector: 'app-support',
templateUrl: './support.component.html',
styleUrls: ['./support.component.css']
})
export class SupportComponent implements OnInit {
angForm: FormGroup;
osVersion: {};
browserName: {};
browserVersion: {};
userAgent: {};
appVersion: {};
platform: {};
vendor: {};
osName : {};
clientList: client[]
clientListLoading: boolean = false;
orgMail: any;
user: any;
constructor(public clientService: ClientService,private store: Store<AppState>,
private fb: FormBuilder,
private emailService: EmailService) {
store.select('client').subscribe(clients => this.clientList = clients.filter(cli => cli.enabled == 0))
this.user = JSON.parse(localStorage.getItem('user'))
console.log(this.user);
{
this.createForm();
}
}
createForm() {
this.angForm = this.fb.group({
name: ['', Validators.required],
email: ['', Validators.required],
message: ['', Validators.required],
});
}
sendMail(name, email, message) {
this.emailService.sendEmail(name, email, message).subscribe(success => {
console.log(success);
}, error => {
console.log(error);
});
}
ngOnInit() {
// this.browser_details();
}
}
Html File:
<form [formGroup]="angForm" novalidate>
<div class="message">
<h3> Write to us </h3>
</div>
<div class="form__top">
<div class="form__left">
<div class="form__group">
<input class="form__input form__input--name" type="text" formControlName="name" placeholder="name" #name>
</div>
<div *ngIf="angForm.controls['name'].invalid && (angForm.controls['name'].dirty || angForm.controls['name'].touched)" class="alert alert-danger">
<div *ngIf="angForm.controls['name'].errors.required">
Name is required.
</div>
</div>
<div class="form__group">
<input class="form__input form__input--email" type="email" formControlName="email" placeholder="email" #email>
</div>
<div *ngIf="angForm.controls['email'].invalid && (angForm.controls['message'].dirty || angForm.controls['message'].touched)"
class="alert alert-danger">
<div *ngIf="angForm.controls['message'].errors.required">
message is required.
</div>
</div>
</div>
<div class="form__right">
<div class="form__group">
<textarea class="form__input form__input--textarea" placeholder="Message" formControlName="message" #message
rows="3"></textarea>
</div>
<div *ngIf="angForm.controls['message'].invalid && (angForm.controls['message'].dirty || angForm.controls['message'].touched)"
class="alert alert-danger">
<div *ngIf="angForm.controls['message'].errors.required">
message is required.
</div>
</div>
</div>
</div>
<div class="form__down">
<div class="form__group">
<button (click)="sendMail(name.value, email.value, message.value)" [disabled]="angForm.pristine || angForm.invalid" class="form__input form__input--submit" name="submit" type="submit" value="SEND MESSAGE">SEND MESSAGE
</button>
</div>
</div>
contact.js
const express = require('express');
const router = express.Router();
const request = require('request');
const nodemailer = require('nodemailer');
const cors = require('cors');
router.options('/send', cors());
router.get('/send', cors(), (req, res) => {
const outputData = `
<p>You have a new contact request</p>
<h3>Contact Details</h3>
<ul>
<li>Name: ${req.body.name}</li>
<li>Email: ${req.body.email}</li>
</ul>
<h3>Message</h3>
<p>${req.body.message}</p>
`;
let transporter = nodemailer.createTransport({
host: 'smtp.gmail.com',
port: 465,
secure: false,
port: 25,
auth: {
user: 'email',
pass: 'pass'
},
tls: {
rejectUnauthorized: false
}
});
let HelperOptions = {
from: '"kutomba" <email',
to: 'email',
subject: 'Majeni Contact Request',
text: 'Hello',
html: outputData
};
transporter.sendMail(HelperOptions, (error, info) => {
if (error) {
return console.log(error);
}
console.log("The message was sent!");
console.log(info);
});
});
module.exports = router;
server.js
// server.js
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const path = require('path');
const app = express();
// CORS Middleware
app.use(cors());
// Port Number
const port = process.env.PORT || 3000
// Run the app by serving the static files
// in the dist directory
app.use(express.static(path.join(__dirname, '/majeni/dist/majeni')));
// Body Parser Middleware
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
//routes
const contact = require('./app/components/support/contact');
app.use('/contact', contact);
// If an incoming request uses
// a protocol other than HTTPS,
// redirect that request to the
// same url but with HTTPS
const forceSSL = function () {
return function (req, res, next) {
if (req.headers['x-forwarded-proto'] !== 'https') {
return res.redirect(
['https://', req.get('Host'), req.url].join('')
);
}
next();
}
}
// Instruct the app
// to use the forceSSL
// middleware
// app.use(forceSSL());
app.use(function (req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
if ('OPTIONS' == req.method) {
res.sendStatus(200);
} else {
next();
}
});
// For all GET requests, send back index.html
// so that PathLocationStrategy can be used
app.get('/*', function (req, res) {
res.sendFile(path.join(__dirname + '/majeni/dist/majeni/index.html'));
});
// Start Server
app.listen(port, () => {
console.log('Server started on port '+port);
});
This my email.service.ts
import { Injectable } from '#angular/core';
import { Headers, Http, Response } from '#angular/http';
#Injectable({
providedIn: 'root'
})
export class EmailService {
constructor(private http: Http) { }
sendEmail(name, email, message) {
const uri = 'http://localhost:4200/support/contact';
const obj = {
name: name,
email: email,
message: message,
};
return this.http.post(uri, obj);
}
}
You should not use two ports on contact.js and the port 465 is the port secure so replace:
port: 465,
secure: false,
port: 25,
auth: {
user: 'email',
pass: 'pass'
},
tls: {
rejectUnauthorized: false
}
for:
port: 465,
secure: true,
auth: {
user: email,
pass: pass
}
On the variables email and pass you should set the email and password of account who go sent the email (I recommended create a new email account just for the form contact because gmail accounts by default not allows clients login without set up DMARK e DKIM) and always make sure to keep this informations out of public code repositories like GitHub.
You can see a similar code who I did on my github: https://github.com/anajuliabit/my-website-backend/blob/master/src/Controllers/ContactController.js

POST http://localhost:4200/contact/send 404 (Not Found)

I have a bootstrap form for email services for angular 6 app and nodejs, I am using nodemailer for sendemail in my app, unfortunatelly does not work. I am getting the following error when I submit the form:
zone.js:2969 POST http://localhost:4200/contact/send 404 (Not Found)
here is the form HTML
<form [formGroup]="angForm" novalidate method="POST">
<div class="message">
<h3> Write to us </h3>
</div>
<div class="form__top">
<div class="form__left">
<div class="form__group">
<input class="form__input form__input--name" type="text" formControlName="name" placeholder="name" #name>
</div>
<div *ngIf="angForm.controls['name'].invalid && (angForm.controls['name'].dirty || angForm.controls['name'].touched)" class="alert alert-danger">
<div *ngIf="angForm.controls['name'].errors.required">
Name is required.
</div>
</div>
<div class="form__group">
<input class="form__input form__input--email" type="email" formControlName="email" placeholder="email" #email>
</div>
<div *ngIf="angForm.controls['email'].invalid && (angForm.controls['message'].dirty || angForm.controls['message'].touched)"
class="alert alert-danger">
<div *ngIf="angForm.controls['message'].errors.required">
message is required.
</div>
</div>
</div>
<div class="form__right">
<div class="form__group">
<textarea class="form__input form__input--textarea" placeholder="Message" formControlName="message" #message
rows="3"></textarea>
</div>
<div *ngIf="angForm.controls['message'].invalid && (angForm.controls['message'].dirty || angForm.controls['message'].touched)"
class="alert alert-danger">
<div *ngIf="angForm.controls['message'].errors.required">
message is required.
</div>
</div>
</div>
</div>
<flash-messages></flash-messages>
<div class="form__down">
<div class="form__group">
<button (click)="sendMail(name.value, email.value, message.value)" [disabled]="angForm.pristine || angForm.invalid" class="form__input form__input--submit" name="submit" type="submit" value="SEND MESSAGE">SEND MESSAGE
</button>
</div>
</div>
</form>
Here is component.ts
import { Component, OnInit } from '#angular/core';
import { ContactService } from '../../contact.service';
import { FormGroup, FormBuilder, Validators } from '#angular/forms';
import { FlashMessagesModule, FlashMessagesService } from 'angular2-flash-messages';
#Component({
selector: 'app-footer',
templateUrl: './footer.component.html',
styleUrls: ['./footer.component.scss']
})
export class FooterComponent implements OnInit {
angForm: FormGroup;
constructor(
private flashMessages: FlashMessagesService,
private fb: FormBuilder,
private contactService: ContactService) {
this.createForm();
}
createForm() {
this.angForm = this.fb.group({
name: ['', Validators.required],
email: ['', Validators.required],
message: ['', Validators.required],
});
}
sendMail(name, email, message) {
this.contactService.sendEmail(name, email, message).subscribe(success => {
this.flashMessages.show('You are data we succesfully submitted', { cssClass: 'alert-success', timeout: 3000 });
console.log(success);
}, error => {
this.flashMessages.show('Something went wrong', { cssClass: 'alert-danger', timeout: 3000 });
});
}
ngOnInit() {
}
}
Here is service.ts
import { Injectable } from '#angular/core';
import { Headers, Http, Response } from '#angular/http';
import { Jsonp } from '#angular/http';
import { HttpClient, HttpHeaders, HttpErrorResponse } from '#angular/common/http';
import { Observable } from '../../node_modules/rxjs';
const httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};
const apiUrl = 'http://localhost:4200/contact';
#Injectable({
providedIn: 'root'
})
export class ContactService {
sendEmailUrl = '/send';
constructor(private http: Http) { }
sendEmail(name, email, message): Observable<any> {
const uri = `${apiUrl + this.sendEmailUrl}`;
const obj = {
name: name,
email: email,
message: message,
};
return this.http.post(uri, obj);
}
}
Here is the server .js
// server.js
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const path = require('path');
const app = express();
// CORS Middleware
app.use(cors());
// Port Number
const port = process.env.PORT || 3000
// Run the app by serving the static files
// in the dist directory
app.use(express.static(path.join(__dirname, '/majeni/dist/majeni')));
// Body Parser Middleware
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(bodyParser.json());
//routes
const contact = require('./app/routes/contact');
app.use('/contact', contact);
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
// For all GET requests, send back index.html
// so that PathLocationStrategy can be used
app.get('/*', function (req, res, next) {
res.sendFile(path.join(__dirname + '/majeni/dist/majeni/index.html'));
});
// Start Server
app.listen(port, () => {
console.log('Server started on port ' + port);
});
Here is contact.js (routes settings)
const express = require('express');
const router = express.Router();
const request = require('request');
const nodemailer = require('nodemailer');
router.post('/send', (req, res) => {
const outputData = `
<p>You have a new contact request</p>
<h3>Contact Details</h3>
<ul>
<li>Name: ${req.body.name}</li>
<li>Email: ${req.body.email}</li>
</ul>
<h3>Message</h3>
<p>${req.body.message}</p>
`;
let transporter = nodemailer.createTransport({
host: 'smtp.gmail.com',
port: 465,
secure: false,
port: 25,
auth: {
user: 'Myemail',
pass: 'my pass'
},
tls: {
rejectUnauthorized: false
}
});
let HelperOptions = {
from: '"Jini" <myEmail',
to: 'myEmail',
subject: 'Majeni Contact Request',
text: 'Hello',
html: outputData
};
transporter.sendMail(HelperOptions, (error, info) => {
if (error) {
return console.log(error);
}
console.log("The message was sent!");
console.log(info);
});
});
module.exports = router;
what is missing in my code?
The port of your server is 3000
const port = process.env.PORT || 3000
so you have to change this:
const apiUrl = 'http://localhost:4200/contact';
to
const apiUrl = 'http://localhost:3000/contact';

Resources