NodeJS express redirect page after login - node.js

i have a weird problem and i could't solve it. First of all here is my code;
exports.postLogin = async (req, res, next) => {
try {
const inputs = await loginSchema.validateAsync(req.body);
pool.connect(async (error, client, release) => {
if (error) {
return console.error("ERROR", error.stack);
}
const isExisting = await client.query(
`SELECT * FROM users WHERE email = '${inputs.email}'`
);
if (isExisting.rowCount == 0) {
release();
return next(Boom.notFound("User not found!"));
} else {
const isCorrectPwd = await bcrypt.compare(
inputs.password,
isExisting.rows[0].password
);
if (!isCorrectPwd) {
return next(Boom.unauthorized("Wrong password!"));
}
const accessToken = await signAccessToken(isExisting.rows[0].userid);
const refreshToken = await signRefreshToken(isExisting.rows[0].userid);
if (accessToken.length !== 0) {
res.cookie("jwt", refreshToken, {
httpOnly: true,
maxAge: 31556952000
});
// res.header("Authorization", "Bearer " + accessToken);
res.redirect(303, '/');
}
}
});
} catch (error) {
if (error.isJoi === true)
return next(createError.BadRequest("Invalid username/password"));
next(error);
}
};
This is my login controller for post request. It works perfectly when i finalise it with res.json(accessToken,refreshToken). But i want to redirect user to homepage when login process succesfull. With this code nodejs tries to do POST request to "/" my homepage. I have no idea why my redirect request appear to be a post request. What's wrong with my code? Thanks in advance...
here is homepage controller;
exports.getHomePage = async (req, res, next) => {
res.render("home", { path: "/" });
};
and here is it's route;
const express = require("express");
const protectController = require("../controller/protect");
const { verifyAccessToken } = require("../helpers/jwt_helper");
const router = express.Router();
router.get("/secretpage", verifyAccessToken, protectController.getPage);
router.get("/", protectController.getHomePage);
module.exports = router;
and here is my terminal logs;
Express server listening on port 3000
Client connected to redis
Client connected to redis and ready to use
POST /auth/login 303 761.269 ms - 36
POST / 404 7.056 ms - 69

Related

passport-apple Node.js login error - Failed to obtain access token

I am a junior engineer working in a start-up in Seoul, Korea.
In the current project, I am trying to use the passport module to develop apple login.
I have already finished developing google social login, but I faced some problems while trying to do the same with apple.
The problem is that I get an error that states : "Failed to obtain access token".
I got really confused that you have to use the POST method in order to get the profile info from apple.
Can someone please help me?? Thanks in advance!
IT would be wonderful if I could success. Thanks again
The main problem I am expecting is that
passport.authenticate('apple') calls the function which handles passport module for google that I have already developed.
I send the redirect url to Frontend, in order to open the browser in my application.
ROUTER.get('/apple/login', async function (req, res) {
const result = { status: 'N' };
const config = {
client_id: APPLE_AUTH.CLIENT_ID, // This is the service ID we created.
redirect_uri: APPLE_AUTH.REDIRECT_URI, // As registered along with our service ID
response_type: 'code id_token',
// state: 'origin:web', // Any string of your choice that you may use for some logic. It's optional and you may omit it.
scope: 'name email', // To tell apple we want the user name and emails fields in the response it sends us.
response_mode: 'form_post',
m: 11,
v: '1.5.4',
};
const queryString = Object.entries(config)
.map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
.join('&');
const redirectUrl = `https://appleid.apple.com/auth/authorize?${queryString}`;
result['redirectUrl'] = redirectUrl;
result['status'] = 'Y';
res.json(result);
});
I get the url, and open the browser
async openAppleSignIn() {
const result = await this.authService.postAppleLogin();
// await this.authService.postAppleLogin();
if (result.data.status === 'Y') {
const { redirectUrl } = result.data;
console.log(redirectUrl);
if (this.deviceInfo.platform !== 'web') {
// this.browserService.openBrowser(redirectUrl);
window.open(redirectUrl, '_self');
console.log('enter');
} else {
const timer = setInterval(async () => {
if (this.newWindowForLogin.closed) {
clearInterval(timer);
}
}, 500);
const isChrome = this.commonService.checkBrowserIsChrome();
if (!this.newWindowForLogin || isChrome) {
// this.newWindowForLogin = window.open();
window.open(redirectUrl);
}
// this.newWindowForLogin.location.href = redirectUrl;
}
} else {
}
Apple strategy
const passport = require('passport');
// var AppleStrategy = require('passport-google-oauth20').Strategy;
var AppleStrategy = require('passport-apple').Strategy;
const jwt = require('jsonwebtoken');
// var fs = require('fs');
const APPLE_AUTH = require('../../../config/secret_key').get('APPLE_AUTH');
const UserModelService = require('../../api/user/model/user_model_service');
// const applePrivateKey = fs.readFileSync('config/AuthKey_Y8BG5JY7P3.p8');
// console.log(applePrivateKey);
module.exports = () => {
passport.use(
'apple',
new AppleStrategy(
{
clientID: APPLE_AUTH.CLIENT_ID,
teamID: APPLE_AUTH.TEAM_ID,
callbackURL: APPLE_AUTH.LOGIN_CALLBACK_URL,
keyID: APPLE_AUTH.KEY_ID,
privateKeyLocation: 'config/AuthKey_Y8BG5JY7P3.p8',
privateKeyString: APPLE_AUTH.privateKey,
passReqToCallback: true,
},
async (accessToken, refreshToken, idToken, profile, done) => {
try {
// console.log(profile._json.email);
// const socialLoginEmail = req.user.emails[0].value;
// console.log(email);
//화면에서 백으로
// console.log(profile._json.email);
// const user = await UserModelService.getUser(profile._json.email);
// console.log(user);
console.log('jwt', jwt.decode(idToken));
console.log('strategy', req);
done(null, idToken);
} catch (error) {
console.error(error);
// done(error);
}
},
),
);
};
index.js
const passport = require('passport');
const apple = require('./apple_auth');
const google = require('./google_auth');
module.exports = () => {
apple();
google();
};
5.Then, I intended to get the results in callback
ROUTER.post(
'/apple/callback',
passport.authenticate('apple', { failureRedirect: '/', session: false }),
async (req, res) => {
try {
console.log(res);
console.log(req);
} catch (err) {}
},
);
I customized the passport-apple usage into this way, not following the instructions in the passport docs, because the way they listed in the official document did not work for my code.
Thanks again, and I hope to find an answer in stack overflow!!

Post Request stuck on Postman

I am learning to build API using Node.js, Express and MongoDB. I am on early learning phase.
My code are as follow.
const app = express();
const mongojs = require("mongojs");
const { body, param, validationResult } = require("express-validator");
const db = mongojs("travel", ["records"]);
const bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.get("/api/records", function (req, res) {
const options = req.query;
const sort = options.sort || {};
const filter = options.filter || {};
const limit = 2;
const page = parseInt(options.page) || 1;
const skip = (page - 1) * limit;
for (var i in sort) {
sort[i] = parseInt(sort[i]);
}
db.records
.find(filter)
.sort(sort)
.skip(skip)
.limit(limit, function (err, data) {
if (err) {
return res.sendStatus(500);
} else {
return res.status(200).json({
meta: {
filter,
sort,
skip,
limit,
page,
total: data.length,
},
data,
links: {
self: req.originalUrl,
},
});
}
});
});
app.post("/api/records", function (req, res) {
db.records.insert(req.body, function (err, data) {
if (err) {
return res.status(500);
}
const _id = data._id;
res.append("Location", "/api/records/" + _id);
return res.send(201).json({
meta: { _id },
data,
});
});
});
app.listen(8000, function () {
console.log("Server running at port 8000...");
});
When I try GET request on Postman, it works fine. But when I try POST request, it shows like the following. error msg image link.
Please let me know what is wrong here.
Thanks in advance

node.js Why data from post requests that is saved in a json file resets to initial empty array after restart server?

I am working with express node.js, and I am trying to save datas from post request in a json file. but for some reason when I restart the server, my data from post request was supposed to save in roomDB.json file doesnt remain instead it resets to initial empty array...
Could anyone please advice? thank you very much.
here is my code
//saving function
const fs = require("fs");
exports.save =(data, PATH) =>{
return new Promise((resolve, reject) => {
fs.writeFile(PATH, JSON.stringify(data), function(err) {
if (err) {
reject(err);
} else {
resolve();
}
});
});
}
// code in router file to make requests
const express = require("express");
const router = express.Router();
const fs = require("fs");
const rooms = ("./roomDB.json");
const { addRoom} = require("./rooms");
router.get("/", (req, res)=>{
fs.readFile("roomDB.json", (err, data)=>{
if(err) return res.status(400);
res.send(roomDB_PATH)
})
});
router.get("/:id", (req, res)=>{
res.send("connect to a room");
});
router.post("/", (req, res)=>{
let roomName = req.body;
if(!roomName.name){
res.status(404);
res.end();
return;
}
let room =addRoom(roomName.name);
res.status(201).send(room)
})
module.exports = router;
*/
const uuid = require("uuid");
let roomdatas;
const {save} = require("./save");
const roomDB_PATH = "roomDB.json";
try {
roomdatas = JSON.parse(fs.readFileSync(roomDB_PATH));
} catch (e) {
roomdatas = []
save(roomdatas, roomDB_PATH);
}
const addRoom = (roomName) => {
roomName = roomName.trim().toLowerCase();
const existingRoom = roomdatas.find((room) => room.name === roomName);
if (existingRoom) {
return { error: 'chatroom has existed' };
}
let room = {
name: roomName,
id: uuid.v4(),
messages: [],
users: [],
created: +new Date()
};
roomdatas.push(room);
save(roomdatas, roomDB_PATH);
return { room };
};
module.exports ={addRoom};
I'm assuming that you are encountering an error with the JSON.parse(fs.readFileSync(roomDB_PATH)); call. This code runs every time your server is started (when you import the file into your router file), and if it encounters an error it is resetting the file to an empty array. Try logging the error to see what is causing it. You're currently completely suppressing the error with no way to tell why it is failing.

asynchronous code not working with event listener

*Edited for clarity and to reflect changes:
Hello. I'm struggling to understand why my async functions are working just fine individually, and when chained together, but not when chained together and fired off in an event listener....
worth noting: when i try to run this without an even listener, data passes from my app, through my post route, and to my endpoint the way it should, it is then returned to my app through the correct route, etc. However, i do get an error in the console that says :
error SyntaxError: Unexpected token < in JSON at position 0
however, when i try to run my chain of async functions on the click of a dom element i don't get the above error, data is passed to my post route, i can log the object that is posted:
Object: null prototype] { zipcode: '97206', feel: 'confused' }
but then my server doesn't save any data, and my get route is never triggered, and nothing gets sent back to my app.......
i'm fairly lost.....
full server and app code below:
server:
const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cors());
app.use(express.static('public'));
//test values
let projectData = {
date: "today",
temp: "38",
feelings: "confused"
};
app.get("/", (req, res) => {
});
app.post("/postData", (req, res) => {
console.log(req.body)
projectData = {
date: req.body.date,
temp: req.body.temp,
feelings: req.body.feelings
}
console.log("post route was hit, saved:", projectData);
res.redirect("/")
});
app.get("/getData", (req, res) => {
console.log("getData route was hit, sent: ", projectData)
res.send(projectData);
})
app.listen(3000, (req, res) => {
console.log("Listening on port 3000");
});
app
let newDate = getDate();
const apiKey = "5fd7b3a253e67a551e88ff34a92b9e02";
const baseURL = "http://api.openweathermap.org/data/2.5/weather?";
// zip=${}&APPID=${}&units=metric;
const userData = {};
// returns the date //
function getDate() {
let d = new Date();
let newDate = d.getMonth() + "." + d.getDate() + "." + d.getFullYear();
return newDate;
}
//constructs string for api call, adds temp to userData object
const getData = async (apiUrl, zip, key) => {
const url = `${apiUrl}zip=${zip}&APPID=${key}&units=metric`;
const result = await fetch(url);
try {
let newData = await result.json()
// console.log(newData.main.temp)
userData.temp = newData.main.temp
}catch(error) {
console.log("error", error);
}
}
// getData(baseURL, 97206, apiKey)
// .then(result => {
// console.log(userData)
// })
//saves contents of userData Object to server
const postData = async (url, data) => {
const result = await fetch(url, {
method: "POST",
credentials: "same-origin",
headers: {
"Content-type": "application/json"
},
body: JSON.stringify(data)
});
try {
const newData = await result.json();
// console.log(newData);
return newData;
} catch (error) {
console.log("error", error);
}
};
// postData('/postData', userData);
//updates interface with projectData values from server
const updateUI = async url => {
const result = await fetch(url);
try {
const newData = await result.json();
document.getElementById("date").innerHTML = newData.date;
document.getElementById("temp").innerHTML = newData.temp;
document.getElementById("feelings").innerHTML = newData.feelings;
} catch (error) {
console.log("error", error);
}
};
// updateUI("/getData")
// THIS WORKS
userData.date = newDate;
userData.feelings = document.getElementById("feel").value;
const zipCode = document.getElementById("zipcode").value;
getData(baseURL, 97206, apiKey).then(result => {
postData("/postData", userData).then(result => {
updateUI("/getData");
});
});
// THIS DOESNT WORK
// document.getElementById("btn").addEventListener("click", e => {
// userData.date = newDate;
// userData.feelings = document.getElementById("feel").value;
// const zipCode = document.getElementById("zipcode").value;
// getData(baseURL, zipCode, apiKey).then(result => {
// postData("/postData", userData).then(result => {
// updateUI("/getData");
// });
// });
// });
EDIT:
I realized that the information that was being passed through the post route when my async functions are fired off by an event listener was actually just the form input element values, rather than the contents of the fetch/post request. after i removed the name attributes from the form inputs, i'm getting no data at all hitting my post route......yet the corosponding function works fine with not in the event listener.
I'm stumped.
well, the syntax error was solved by using .text() instead of .json() on the results of my post request.
adding e.preventDefault() as the first line of my event listener callback fixed the event listener, and now everything is working as it should.

expressjs returning controller object to res.send

I have a controller that makes an api call (few seconds delay) and then returns a JSON object that I want to send and appear on my view page. At the moment I am able to return the object and successfully load the route, but the object is not appearing on my browser page (status code: 200) and I'm not sure what I might be missing. Provided below is my route and controller.
Controller:
var express = require('express');
var apiRouter = express.Router();
var googleAnalytics = require('../google-analytics');
const { checkToken } = require("./components/token-validator");
apiRouter.use(checkToken);
apiRouter.get('/ga', function(req, res){
res.send(googleAnalytics())
});
module.exports = apiRouter;
Controller (googleAnalytics):
module.exports = () => {
console.log("google-analytics.js")
const {google} = require('googleapis');
const analyticsreporting = google.analyticsreporting('v4');
const view_id = '*view-id(';
... // resource: req information
analyticsreporting.reports.batchGet({
resource: req
}, (err, result) => {
if(err){
if(err.errors){
console.log(err.errors[0].message)
} else {
console.log(err)
}
} else {
return result.data;
}
//console.log("BREAK IN CONSOLE")
//console.log(err, result)
})
}
Object E.g.:
{"reports":[{"columnHeader":{"dimensions":["ga:sourceMedium"],"metricHeader":{"metricHeaderEntries":
...
]}}
You are not returning anything from the google-analytics.js. You need to make the function return a promise or use callback. analyticsreporting.reports.batchGet returns a promise so it is pretty easy to do that.
module.exports = () => {
console.log("google-analytics.js")
const {google} = require('googleapis');
const analyticsreporting = google.analyticsreporting('v4');
const view_id = '*view-id(';
... // resource: req information
return analyticsreporting.reports.batchGet({
resource: req
});
}
Now, in your /ga route, you can use async-await:
apiRouter.get('/ga', async function(req, res){
res.send(await googleAnalytics())
});

Resources