Error while trying to login with through Steam from node.js - node.js

I'm trying to login through steam from my webapp but I'm having an hard time.
This is the code in my backend (I'm using Firebase cloud functions) that let me authenticate my user.
const steam = new SteamAuth({
realm: "https://storm.co.gg", // Site name displayed to users on logon
returnUrl: "http://localhost:5001/stormtestfordota/europe-west1/api/auth/steam/authenticate", // Your return route
apiKey: apiKey // Steam API key
});
let loggedUser = "";
const redirectSteamAuth = async (req, res) => {
loggedUser = req.user.username;
const redirectUrl = await steam.getRedirectUrl();
return res.json(redirectUrl);
}
So this is the first endpoint that the user calls when trying to login to Steam. And it works, so the steamcommunity.com opens without problem.
But when I click login in steamcommunity page I'm prompted with this error
So over the name of my account you can see "ERRORE" that stands for "ERROR"
This is the endpoint that should be called after authentication:
const loginWithSteam = async (req, res) => {
try {
const user = await steam.authenticate(req);
db.collection("users").doc(loggedUser).update({
steamId: user.steamid
})
activeDota2(loggedUser, user.steamid);
return res.redirect("https://storm.co.gg/dashboard/home");
} catch (error) {
console.error(error);
return res.status(401).json(error)
}
}
These are the two endpoints:
app.post("/auth/steam", (req, res, next) => validateFirebaseIdToken(req, res, next), redirectSteamAuth);
app.get("/auth/steam/authenticate", loginWithSteam);

I solved this issue. The problem was in the urls of the steam object AND there was a problem with CORS options, I didn't add the DNS of steamcommunity in origins accepted by CORS.

Related

Google OpenId - redirect_uri/callback not happening. Is the issue localhost?

Following the the Google OpenID doc, I am attempting to send an authentication request to Google.
When the request goes out to https://accounts.google.com/o/oauth2/v2/auth, the request is not redirected back to my redirect_uri http://localhost:5901. I also am not getting the google login screen(not sure if I am supposed to get a login screen).
I checked the CLIENT_ID and it is correct.
Is the issue here localhost?
const URL = 'https://accounts.google.com/o/oauth2/v2/auth';
// initial login; redirect to get permissions
const constructCodeURI = () => {
const queryString =
`client_id=${CLIENT_ID}`
+ `&scope=openidemail`
+ '&state=019146662993491234567890'
+ '&login_hint=foo.bar#gmail.com'
+ '&nonce=03852-31485-24958'
+ `&redirect_uri=http://${HOST}/auth/google/callback`
+ '&response_type=code';
return `${URL}?${queryString}`;
};
// user gives permissions and you get user code
const redirectToGoogleLogin = (req, res) => {
const url = constructCodeURI();
console.log('aaa');
console.log(url);
res.redirect(url);
};
const callbackStack = (req, res) => {
console.log('This is not being hit');
if (Object.keys(req.query).length > 0) {
getTokenAndProfileStack(req, res, code, 'google')
.then(e => res.redirect('http://localhost:5000/forms/ui/list_forms'))
.catch(e => console.log('google login call back err ' + e))
}
};
export default callbackStack;
// google login
app.route('/auth/google/login')
.get(redirectToGoogleLogin);
app.route('/auth/google/callback')
.get(callbackStack);
Request that goes out (modified to remove sensitive info)
https://accounts.google.com/o/oauth2/v2/auth?client_id=20oogleusercontent.com&scope=openidemail&state=034912340&login_hint=foo.bar#gmail.com&nonce=02-31905-8&redirect_uri=http://127.0.0.1:5901/auth/google/callback&response_type=code
Answering from my own experience:
Add http://localhost (without a port) to the authorized redirect URIs list while keeping the other options you have setup.
Within constructCodeURI make sure to replace 127.0.0.1 with localhost.

How to perform an api call from a middleware in express - NodeJS

First of all, I'm working with express in NodeJS.
I want to create an API call for updating the user's personal account informations.
Before doing this I should ask the user for the password for more security, this operation will be handled in this middleware isPasswordCorrect inside the request:
const isPasswordCorrect = (req, res, next) => {
const password = req.password
// perform the login call, to confirm the user identity
// if password is correct call next()
}
I already created this endpoint to log in:
router.post('/login', (req, res) => {
const { login, password } = req.body
// do some logic for checking if the login data are correct
res.json({"accessToken": accessToken})
})
So to facilitate the task, I want to call the above-mentionned login endpoint inside the middleware isPasswordCorrect, to check the identity of the user before updating his data
I would not do such an "internal API call", it will cause coupling between the APIs. As a result, the code is difficult to maintain.
I would create a repository or service layer to confirm the user identity.
E.g.
user-service.js
export const identifyUser = (password) => {
// confirm the user identity
// throw new Error('user identity error');
return password
}
Then, in your middleware
const isPasswordCorrect = (req, res, next) => {
try {
userService.identifyUser(req.password)
next()
} catch (e) {
next(e);
}
}

Express Middleware not rendering the view

I have written an auth middleware , which when fails , I want to render a page instead of sending response to my xhr request . How to do it ?
const jwt = require('jsonwebtoken')
const User = require('../models/users')
const express = require('express')
const auth = async (req, res ,next) => {
try {
//res.render("404")
const token = req.header('Authorization').replace('Bearer ' , '') //token comes from client in the header section named Auth(here)
const data = jwt.verify(token , 'itistechvaulttoken') //this gives back the id of the user and also iat :- issued at , a callback can be attached to
// .verify :-- see jsonwebtoken documentation for details .
const user = await User.findOne({ _id : data._id})
if(!user) {
throw new Error()
}
req.token = token //this is being use mainly for logout route handler
req.user = user
next()
} catch(e) {
res.status(401).render("404")
}
}
module.exports = auth
I have create a form and sending that data to my backend using xhr request to route and from there i am redirecting it to another route where I want to render the view .
My routes :-
router.post('/users' ,async (req, res) => {
console.log("Request Recieved")
const user = new User(req.body)
try {
await user.save()
const token = await user.generateAuthToken()
//console.log(token)
//res.status(201).send({ user , token})
req.accesstoken = token
res.redirect(302 , "/users/me" )
}
catch(e) {
console.log(e)
res.status(400).send("User not created" + e)
}
})
/user/me :-
router.get('/users/me', auth, async (req, res) => {
console.log("in users/me")
res.send(req.user)
})
I know here authentication has to fail, and code under the catch of middleware should run ,where I am trying to render a view but failing .
I guess you want your xhr endpoint code on your server to make your user's browser display an error page of some kind upon auth failure.
To do that you need the Javascript code in your browser to detect an error message in the response to the xhr request and navigate to the error page. Your nodejs app can't force any kind of redirect when responding to an xhr request without cooperation from the browser.

problems trying to use the Instagram api

I am working with Angular and Node.js with Express.js. I have all day trying to get the posts from my Instagram account but I have not even been able to get the API token. I understand that you first have to make a request to this URL: https://api.instagram.com/oauth/authorize?client_id=[instagram-app-id-lex.europa.eu&redirect_uri=[redirect-uriíritu&scope=[scope-lex.europa.eu&response_type=code&state = {state} (replacing the id and redirect-uri obviously) but I get no response. I already created my app in the instagram api following its documentation and add the tester and accept the authorization from the account settings.
At the moment I have this code en node.js:
const instagram = require('../controllers/instagram/instagram.controller');
const route = '/auth'
module.exports= (app,db, protegerRutas)=> {
app.get(`${route}/instagram`, (req, res)=> instagram.auth(req, res));
app.get(`/handle`, (req,res)=> instagram.handleauth(req,res));
// app.get(`${}`)
// app.post(`${route}/actualizar`, protegerRutas, (req, res)=> actualizar.actualizarDatos(req, res, db))
}
controller:
const Instagram = require('node-instagram').default;
const axios = require('axios');
const clavesInstagram = require('../../config/config').instagram;
const {clientId, clientSecret}= clavesInstagram;
const urlInstagram = 'https://api.instagram.com/oauth/authorize?client_id=201577004938695&redirect_uri=https://localhost:3008/auth/handle&scope={scope}&response_type=code';
const redirectUri = 'https://b4ae544459e3.ngrok.io/handle';
const instagram = new Instagram({
clientId: clientId,
clientSecret: clientSecret
})
module.exports= {
auth: (req,res)=> {
axios.get(urlInstagram)
.then( res => {
console.log('\n\nRespuesta: ',res);
})
.catch( err => {
console.log('\n\nError: ',err);
})
},
// auth: (req, res)=> {
// console.log('\n\nAuth Controller...')
// res.redirect(
// instagram.getAuthorizationUrl(redirectUri, {
// scope: ['basic','likes'],
// state: 'your state'
// })
// )
// },
handleauth: async (req, res)=> {
try {
console.log('\n\n\n\nHandleAuth....\n\n\n\n\n')
const code = req.query.code; //código devuelto por Instagram
const data= await instagram.authorizeUser(code, redirectUri);
console.log('\n\nData Instagram:', data)
res.json(data);
} catch(e) {
// statements
console.log(e);
res.json(e)
}
}
}
I understand that in the instagram API configuration the URL of my app is added to which they redirect and send the token, the url of my local app is something like this: http://localhost:3008/ and the path to which I want instagram to redirect would be this: https://localhost:3008/auth/handle (I must put it with 'https' in instagram because it does not allow http, so I don't know if this would include me). The problem is that with this code I am not getting the token that should be sent to my route https://localhost:3008/auth/handle. What am I doing wrong? I've been at this for many hours and honestly I can't find a solution. I read the documentation and try to do what it says but I can't do it. Could someone help me with this? I would be enormously grateful.
Thanks in advance.

Salesforce Login Page not coming for OAuth using NodeJS

I'm trying to login to Salesforce from Google Assistant (using dialogflow) using OAuth. Whatever I say to Google Assistant is supposed to be fulfilled (matched to intent which is then gets matched to the code that fulfills the intent of the user. So, basically the fulfillment code resides on a server (node js express) hosted on Heroku.
The problem is whenever I start by saying 'Talk to test app' I expect to see the Salesforce login page coming up (where I would enter the creds and then the consent part comes) but this page never comes. I'm sure that there might be something missing on my configuration of account linking / code but i'm not able to understand it.
const express = require('express');
const bodyParser = require('body-parser');
const jsforce = require('jsforce');
const { dialogflow } = require('actions-on-google');
const {
SimpleResponse,
BasicCard,
Image,
Suggestions,
Button
} = require('actions-on-google');
var options;
var port = process.env.PORT || 3000;
const expApp = express().use(bodyParser.json());
//app instance
const app = dialogflow({
debug: true
});
app.intent('Default Welcome Intent', (conv) => {
expApp.get('/oauth2/auth', function(req, res) {
const oauth2 = new jsforce.OAuth2({
clientId: process.env.SALESFORCE_CONSUMER_KEY,
clientSecret: process.env.SALESFORCE_CONSUMER_SECRET,
redirectUri: process.env.REDIRECT_URI
});
res.redirect(oauth2.getAuthorizationUrl({}));
});
//
// Pass received authorization code and get access token
//
expApp.get('/getAccessToken', function(req,res) {
const oauth2 = new jsforce.OAuth2({
clientId: process.env.SALESFORCE_CONSUMER_KEY,
clientSecret: process.env.SALESFORCE_CONSUMER_SECRET,
redirectUri: process.env.REDIRECT_URI
});
const conn = new jsforce.Connection({ oauth2 : oauth2 });
conn.authorize(req.query.code, function(err, userInfo) {
if (err) {
return console.error(err);
}
const conn2 = new jsforce.Connection({
instanceUrl : conn.instanceUrl,
accessToken : conn.accessToken
});
conn2.identity(function(err, res) {
if (err) { return console.error(err); }
console.log("user ID: " + res.user_id);
console.log("organization ID: " + res.organization_id);
console.log("username: " + res.username);
console.log("display name: " + res.display_name);
options = { Authorization: 'Bearer '+conn.accessToken};
});
});
});
conv.ask(new SimpleResponse({
speech:'Hi, how is it going? You are being guided to the login page',
text:'Hi, how is it going? You are being guided to the login page',
}));
});
expApp.get('/', function (req, res) {
res.send('Hello World!');
});
expApp.listen(port, function () {
expApp.post('/fulfillment', app);
console.log('Example app listening on port !');
});
OAuth with Google Assistant is managed from the Actions on Google project that you create for your assistant. In these settings you manage which Token and OAuth URL have to be used for the sign-in in your app. If you want the users to sign-in through the assistant app, you will have to choose the OAuth sign-in option.
So you don't have to use your own code to get the OAuth page, you can just use the SignIn() response given to you in the Actions on Google SDK. This will trigger the account linking flow for Google Assistant.
app.intent('Start Signin', (conv) => {
conv.ask(new SignIn('To get your account details'));
});
app.intent('ask_for_sign_in_confirmation', (conv, params, signin) => {
if (signin.status !== 'OK') {
return conv.ask('You need to sign in before using the app.');
}
// const access = conv.user.access.token;
// possibly do something with access token
return conv.ask('Great! Thanks for signing in.');
});

Resources