Facebook login api still gives the error of https required even if app is in dev mode - facebook-javascript-sdk

I created a test app on facebook and set the domain and the site url to localhost and http://localhost:4200 respectively.
The app is in development mode, as the documentation says "You will still be able to use HTTP with “localhost” addresses, but only while your app is still in development mode", nevertheless I get the error "The method FB.login will soon stop working when called from http pages. Please update your site to use https for Facebook Login." when I invoke the FB.login() api.
Sometimes the facebook window to log the user is not displayed , other times the window opens with the error "Login Error: There is an error in logging you into this application. Please try again later." within.
Update
I'm over https in locale and the relative error is disappeared.
This is the function invoked by the "Login with Facebook" button
loginWithFacebook() {
this.btnLoaderFB = true;
this.auth.facebookInitializer()
.then(() => {
this.auth.facebookInitialized = true;
return this.auth.facebookLoginStatus();
})
.then((loginStatusResponse) => {
console.log(loginStatusResponse);
if (loginStatusResponse.status !== 'connected') {
return this.auth.facebookLogin();
} else {
return this.auth.getFacebookProfileInfo();
}
})
.then((profileInfo) => {
console.log(profileInfo);
this.auth.loginWithFacebookRemote(profileInfo)
.subscribe(
res => {
this.btnLoaderFB = false;
}
);
})
.catch(err => {
console.log(err);
this.translate.get('t.validation.error_fb_login').pipe(takeUntil(this.unsubscribe)).subscribe(
t => {
this.error = t;
this.btnLoaderFB = false;
});
});
The first time I call this function I receive the response from facebookLoginStatus() logged on the console
I enter the fb credential and I get this error
If I try to click again on the button I receive the same response from facebookLoginStatus() I showed in the first image and the facebook popup window shows the same error message in the previous image.
If I reload the page the facebookLoginStatus() response is what I expect for a logged user on facebook and the login process ends without error

I can recommend using https even on localhost, especially because you will have a system for testing that is more similar to the live environment. This solves the Facebook https issue once and for all.
For Node.js, it is very easy with this tool: https://github.com/davewasmer/devcert
For PHP, you may want to take a look at this thread: How do I allow HTTPS for Apache on localhost?
For Angular CLI: Get angular-cli to ng serve over HTTPS

Related

Give web app permanent control of google email

I recently got a domain from Google Domain and it provides professional emails for the domain. So, I made a support#domain email to send and receive emails. Right now, I built a web app that will use this email to send email-verification to new users who sign up.
I got the code working, however, I used OAuth2.0 from Google to allow the web app to sign into the support email. This causes the Access token to expire and forces me to into my .env file and replace BOTH tokens. How tedious! If I were to publish this web app, I can't just go into my heroku vars and replace the tokens every hour. Thats extremely impractical.
I looked into service accounts by google, but they seem to STILL need OAuth anyways as a 3 legged OAuth. As I am using Express.js, I wanted to know if there was a way to set the tokens and be done with it permanently. Essentially giving the web app permanent control of the google account. What do I do? And what do I use? All advice is greatly appreciated.
Code for sending email verification:
const nodemailer = require("nodemailer")
const dotenv = require("dotenv")
const {generateVerifyToken} = require("./auth")
const { print } = require("#AlecRuin/color-logger")
dotenv.config()
let transporter = nodemailer.createTransport({
service:"gmail",
auth: {
type: 'OAuth2',
user: process.env.EMAIL,
clientId: process.env.CLIENT_ID,
clientSecret: process.env.CLIENT_SECRET,
refreshToken: process.env.REFRESH_TOKEN,
accessToken: process.env.ACCESS_TOKEN
}
})
module.exports= async function(email){
try {
let mailOptions={
from: "support#domain.us",
to:email,
subject:"Verify your email",
text:`
Thank you for signing up with redacted!!
To verify your email (and make sure you're not some kind of annoying bot), simply follow this link:
${process.env.NODE_ENV === "production"?"www.redacted.com":"localhost:3001"}/api/user/verify/?token=${generateVerifyToken(email)}
`
}
print("sending email",new Error,{isClient:false})
transporter.sendMail(mailOptions,(err,data)=>{
if (err){
console.error(err);
return err
}else{
print("Email sent!",new Error,{isClient:false})
return true
}
})
} catch (error) {
print(error,new Error, {isClient:true,severity:4})
return error
}
}

Chrome Extension - Migration to Manifest v3 - chrome.permissions user gesture issue

I have built a chrome extension in manifest version 2 and am now looking at migrating to version 3. As part of this migration I have come across an issue when trying to toggle an optional permission to use the chrome notifications api.
Since you can't request a new permission from a content script as the api is not accessible from a content script, you have to send a message to the background script to perform the request and return the response to the content script. This worked as expected with version 2, now I am receiving this error:
Unchecked runtime.lastError: This function must be called during a user gesture
This means that the extension wants the permission request to be initiated on the back of an event initiated by a user action, such as a click. This indicates that the extension wishes the permission request to be completed from the content script but as stated above this is impossible.
Could anyone illuminate me if I'm missing something?
Content Script:
chrome.runtime.sendMessage(
{message: 'requestPermissions', permissions: ['notifications']},
(res) => console.log(res)
);
Background Script:
export function requestPermissions(request, sender, sendResponse) {
const {permissions} = request;
new Promise((resolve) => {
chrome.permissions.request(
{
permissions
},
(granted) => resolve(granted)
);
}).then((res) => sendResponse(res));
return true;
}

Handling errors if no network is available

I just implemented my first backend file where I fetch some user data, messages and so on.
Now I wanted to include error handling if there is no network available.
I don´t know if I did it right but this was my approach so far:
import axios from 'axios'
const host = process.env.VUE_APP_URL
export default {
person: async function (currentPerson) {
let params = {
currentPerson: localStorage.getItem("person"),
};
if (user) {
params['currentPerson'] = currentPerson;
}
return axios.get(`${host}/api/currentPerson`, {
params: params
})
//catching network errors
.catch (error => {
if (error.response) {
/*
* The request was made and the server responded with a
4xx/5xx error
*/
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
} else if (error.request) {
/*
* The request was made but no response was received
*/
console.log(error.request);
} else {
// Something happened in setting up the request and triggered an Error
console.log('Error', error.message);
}
console.log(error)
});
},
In my mounted() function of my main view I fetch the data from my backend file from above:
backend.matches().then(function (response) {
self.contacts = response.data.persons;
});
I tried to check in console if it is working but all I get is the following:
In the catch block I check for
response errors: like 4xx/5xx
request errors: if my network not responding in time
and any other errors
Would this be the right approach to check if a network is available or not? Or does it degrade the user experience when the user checks the error?
My backend file includes more methods.. do I have to write for each method these kind of requests?
In your backend file you don't react whether there is a network connection or not I think.
And only for reference: that is not the backend, but communicates with the backend - the backend is the part of your code what you communicate with, e.g. Laravel code, an API, ...
Try adding the following at the beginning of your catch part:
if (!error.response) {
//network error
console.log('No network connection');
} else if (error.response) {
//the rest of your code
This should print out No network connection in your console.
Run your application, turn off the internet connection and check the console.
These kind of code should always be located in your backend part.
My answer maybe different from your question.
When i create a .net core API with Angular i used three things to check is there network or not?
subscribe to windows's offline/online event
create signalR hub from layout component to API server
API request failed (it means lot of incident, but if 1. or 2. case is true i know what cause 3. case

How to send Oauth token from callback at the server to the client?

I am using expressJs and passport for authentication. I am using Google Oauth2.0 for login with standard Passport GoogleStrategy. At client I am using axios for sending a login request to the server. My login routes are :
router.get(
"/google",
passport.authenticate("google", { scope: ["profile", "email"] }));
router.get(
"/google/callback",
passport.authenticate("google", { failureRedirect: "/"}),
function(req, res) {
const token = jwt.sign({id: req.user.id}, configAuth.secretKey);
console.log("generated token: ", token);
res.json({success: true, token: 'bearer ' + token});
}
);
I am using the user information from the callback to generate the JWT which I want to sent the client.
At the client I am using axios to send request and get the JWT and store it in localstore.
axios.get('http://localhost:3001/google')
.then((result) => {
console.log("result", result);
localStorage.setItem('jwtToken', result.data.token);
})
.catch((error) => {
// if(error.response.status === 401) {
// this.setState({ message: 'Login failed. Username or password not match' });
// }
console.log("Login error", error);
});
But Axios doesn't wait for the redirect to happen and returns a HTML document with Loading... message. If you try to access the API in the browser, it returns the desired JSON object. Is there a way to wait for redirects. Should I use another library to send login request?
I tried sending the token as url parameter with
res.redirect()
but client and server are at different ports so it doesn't work.
Is there another way to do it?
Google's OAuth2 pathway redirects your browser, resulting in page reloads, a couple of times before it completes. As a result, your client-side code,
axios.get('http://localhost:3001/google')
.then((result) => {
console.log("result", result);
localStorage.setItem('jwtToken', result.data.token);
})...
will never reach the .then() block. You probably see this in the browser; you click a button or something to navigate to 'http://localhost:3001/google', and your localhost:3001 server re-directs your browser to a Google login page. Now that your browser is at the login page, it has no memory of the axios.get statement above--that webpage code is gone.
You need to handle the JWT in client-side code that your server sends in response to
axios.get('http://localhost:3001/google/callback').
This is your browser's final stop in the OAuth2 path--once you get there, you won't be re-directed again. You can put your axios.get function above inside that client-side code.
If you haven't solved the problem, there is a workaround use 'googleTokenStategy' instead of googleOAuth on passportjs. That way you can use react's GoogleLogin plugin to receive the access token from the front end and send it by axios.post to the backend link then set up the jwt. Reference here

electron certificates network

I am trying to write a simple electron app to interface with a REST server. The server doesn't have the appropriate certificates. When I try to make a 'GET' request (using fetch()), I get the following error message:
Failed to load resource: net::ERR_BAD_SSL_CLIENT_AUTH_CERT
Fixing the certs is not currently an option. I tried to use the 'ignore-certificates-error' flag (see below). It seems like it should allow me to skip over this error, but it doesn't.
var electron = require('electron');
var app = electron.app
app.commandLine.appendSwitch('ignore-certificate-errors');
...
The result is the same error.
Questions:
I am correct in assuming this options is supposed to help here?
If so, any ideas what I am doing wrong?
Electron version: 1.2.8
Thanks!
You can update your version of electron and use this callback:
app.on('certificate-error', (event, webContents, link, error, certificate, callback) => {
if ('yourURL/api/'.indexOf(link) !== -1) {
// Verification logic.
event.preventDefault();
callback(true);
} else {
callback(false);
}
});
That you going do the fetch to your api with https.