InAppBrowser close() freeze UI - user-interface

My application is using Ionic 2. When a user launches, they are met by the splashscreen. After a few seconds an instance of InAppBrowser launches for them to login to a company portal. Once the browser is redirected, the browsers listens for the 'loaderror'. At which point the browser closes, and Splashscreen.hide() is used. 9 times out of 10, the UI is frozen and the user tap or touch anything on the screen. If I put a done button to close the browser manually, 5 times out of 10 the UI freezes. My code is below:
public freshPOST() {
//declare ESO login page as well as open Inappbrowser
var url_code: any;
let url = "CLIENT_AUTH_ENDPOINT_URL";
let browser = new InAppBrowser(url, '_blank', 'location=no,zoom=yes,enableViewportScale=yes,toolbar=no');
//on redirect browser shows load error, and not url
browser.on("loaderror").subscribe((event: InAppBrowserEvent) => {
//pull code from url and store in variable
let token = event.url.split('=')[1].split('&')[0];
url_code = token;
localStorage.setItem('url_code', url_code);
//SETUP FOR POST
//headers to be sent
var headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
let options = new RequestOptions({ headers: headers });
//parameters for POST request
let details = "code=" + url_code + "&client_id=CLIENT_ID&client_secret=CLIENT_SECRET&redirect_uri=REDIRECT_URI&grant_type=authorization_code";
//POST request with parameters injected
this.http.post('CLIENT_TOKEN_ENDPOINT', details, options)
.map(res => res.json())
.subscribe(
data => {
//convert response to string, pull access token, and store in variable
this.data = JSON.stringify(data)
var access_token = data.access_token;
var expires_in = data.expires_in;
var refresh_token = data.refresh_token;
//store all responses to local storage for retrieval
localStorage.setItem('access_token', access_token);
localStorage.setItem('expires_in', expires_in);
localStorage.setItem('refresh_token', refresh_token);
//launch app
//write to console success
//close browser
console.log("Successful POST and Authentication");
browser.close();
Splashscreen.hide();
},
(err) => {
//POST Failure
//close browser
console.log("post didnt work");
});
});
}
I am launching this from App.Component, and only if platform is ready. The first page is an intro page that you skip to get to the tabbed view. Thank you for any help you can provide.

Related

Window object is undefined after deploy to netlify

I want to build an email verification. After the user registers, the user gets an email and clicks on it for verification purposes. The email-link invokes a netlify lambda function (api end point). Inside the link is a jwt token, which I decode on the backend. I used
window.location.href
for it and sliced the part I needed and decoded it. On localhost, it works fine, however, if I deploy it to netlify, I get an
window is undefined
error. I read that you have to check for
typeof window !== 'undefined'
However, if I add that to my lambda function I don't get any console.log statements.
exports.handler = async (event, context, callback) => {
if (typeof window !== 'undefined') {
let url = window.location.href
let index = url.indexOf("=");
let token = url.slice(index+1)
console.log(token, 'token here')
const decoded = jwt.verify(token, process.env.SECRET);
console.log('confirm registration route triggered',decoded)
if (decoded) {
const { email } = decoded;
console.log(decoded, 'decoded here')
User.findOneAndUpdate({email: email}, {verified: true },(...e)=>{
console.log(e)
});
} else {
console.log('could not update user')
//redirect user to page with message about email confirmation link expiration
//and proposal to register again
}
console.log('confirm registration got invoked')
}
return {
statusCode: 400,
body: "Oops"
}
};
I read that the function first runs on the server when deployed and afterwards on the client. Seems like it does not run on my client, as I invoke the api-endpoint directly? I'm quite a beginner when it comes to API-Endpoints, thanks for reading!
In case you have the same issue when deploying to netlify, you have to run
event.queryStringParameters
which gives you access to the query parts of your url.

Fitbit URL callback giving a response of NULL

I'm having trouble getting a response from a callback uri and I would really appreciate any help you could give me.
I am trying to use the Fitbit API which requires you to use a callback url to get an Auth Code.
Workflow:
1. Go to Fitbit url to get user to allow the app access to their personal data.
2. User agrees to the conditions
3. User gets redirected to my API
4. The API returns the code from (Code is located in URL and I can access it)
5. I console.log the code out to verify it
6. API returns the code
7. I work with code then exchanging it for an access token.
The problem is that I don't return the code (Or anything )when I return to the app even though I can console.log it on the API. The response I get is NULL
Here is the URL:
url = "https://www.fitbit.com/oauth2/authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=https://REDIRECT_URL&scope=activity%20heartrate%20location%20nutrition%20profile%20settings%20sleep%20social%20weight&expires_in=604800";
I then open the URL in the InAPPBrowser successfully:
if (url !== "") {
const canOpen = await Linking.canOpenURL(url)
if (canOpen) {
try {
const isAvailable = await InAppBrowser.isAvailable()
if (isAvailable) {
const result =InAppBrowser.open(url, {
// iOS Properties
dismissButtonStyle: 'done',
preferredBarTintColor: 'gray',
preferredControlTintColor: 'white',
// Android Properties
showTitle: true,
toolbarColor: '#6200EE',
secondaryToolbarColor: 'black',
enableDefaultShare: true,
}).then((result) => {
console.log("Response:",JSON.stringify(result))
Linking.getInitialURL().then(url => {
console.log("Tests: ",url)
this._setTracker(url as string);
});
})
} else Linking.openURL(url)
} catch (error) {
console.log("Error: ",error)
}
}
}
From here the URL opens successfully.
Here is the API now which is done in Typescript on AWS serverless and Lambda
export const handler: APIGatewayProxyHandler = async (event, _context, callback) =>{
let provider = event.path
//prints code
let x = event.queryStringParameters
console.log("Code: ",x)
const response = {
statusCode: 200,
body: "Success"
};
return response;
}
Please let me know if further detail is required?
Thank you!
Right so it turns out what I was doing was correct apart from the response should have been 301 which is a redirect response.
const response= {
statusCode: 301,
headers: {
"location": `app://CALLBACK RESPONSE ADDRESS?type=${provider}`
},
body: "Boom"
}

Spring security does not redirect after successful login authentication

I am using spring security + thymeleaf to recognise my css and javascript files. These css and javascript files make up my front end login page, and for special reasons, my login form is within a js file and i include this file in my main html file. To authenticate the login credentials, a custom /POST request needs to be called using javascript like below. This function below executes when the form submit button is pressed.
function submitForm() {
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/x-www-form-urlencoded");
var urlencoded = new URLSearchParams();
urlencoded.append("username", "<removed>");
urlencoded.append("password", "<removed>");
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: urlencoded,
redirect: 'follow'
};
fetch("http://localhost:8080/userAuth", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
}
Controller to handle successful login end point
#Controller
public class LoginSuccessController {
#GetMapping("/login_success")
public String success() {
return "success";
}
}
On the browser, I can infer that authentication is successful and there is something that happens related to my successful login endpoint. However, my browser remains at localhost:8080/login and does not redirect to the login_success endpoint. I am unable to figure out why so. Any help is much appreciated.
Browser network activity after submit button
because you use ajax. if you check networks tab I believe you will see response ans 301/302 with Location header.
Edit: you have to either use plain html form or redirect manually from js side
Edit 2:
fetch("http://localhost:8080/userAuth", requestOptions)
.then(response => response.text())
.then(result => {
// do some stuff with response
location.href = '/my-success-page-after-login'; // <- here is redirect
})
.catch(error => console.log('error', error));
Explanation: the problem is that browser doesn't follow redirect response for AJAX calls. Ajax call will just return you a response from server(redirect with 301/302 status code in your case) but this will NOT make browser to follow that redirect

Between express server and react.js - fetch does not work?

I am trying to get data in react by sending GET or POST request to express server.
But I can't receive response from server.
Below is my React component code.
handleButton() {
const sendData = {
"say" : "Hello",
"to" : "React App"
};
fetch("http://localhost:5000/", {
mode : "no-cors",
method : "POST",
body : JSON.stringify(sendData)
}).then(res => {
console.log(res);
alert(res);
});
}
handleButton() is called when I press the button.
I want to receive data from server when I click the button.
Then here is my express server code.
var express = require("express");
var bodyParser = require("body-parser");
var multer = require("multer");
var upload = multer();
var app = express();
app.get("/", function(req, res) {
res.render("form");
});
app.set("view engine", "pug");
app.set("views", "./views");
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended : true}));
app.use(upload.array());
app.use(express.static("public"));
app.post("/", function(req, res) {
console.log(req.body);
res.send("received your request!");
});
app.listen(5000);
My server is very simple but it doesn't work.
When I press the button, server console outputs empty object.
This is my server console capture image.
And then this is my google chrome browser console capture image.
Please help me with getting right result. I want to notice that server received request by alert in react.

Express.js res.render not redirecting, just displayed in console

This time I want to use res.render to display html as success of DB update. I did it several times, but this time it doesn't work. It's not render html file, just displayed on chrome's console.
I think it caused because of async problem or duplicated response. I tried to many ways but I couldn't solve it, so pointers appreciated.
The code is related when the user paid service, increase user's level.
Get Access Token => Validate => res.render
app.post('/payment/validate', function(req, res, next){
// Get access token
request.post({
url : 'https://payment-company/get/token'
}, function(err, response, body) {
if(!err & response.statusCode == 200) {
var result = JSON.parse(body);
var accessToken = result.response.access_token;
// Validate payment (compare paid and would be paid)
request.get({
headers : { 'Authorization' : accessToken }
url : 'https://payment-company/find/paymentid'
}, function (err, response, body) {
if (!err && response.statusCode == 200){
var result = JSON.parse(body);
if (result.response.amount == req.body.price){
Members.findOne({id : req.user.id}, function(err, member){
// If no problem, update user level
member.level = 2;
member.save(function(err, result){
if (err) return next();
res.render('payment.view.result.ejs',
{
title : 'Success !',
description : 'level up.'
});
});
});
}
} else {
...
}
});
}
})
});
sorry to verbose code I tried to shorten code, No problem until res.render, res.render will work but it's not display page instead it just send html code to chrome's console.
Looks like there's a bit of a misunderstanding of how these requests work. What I think you intend:
Browser makes a GET request, server responds with an HTML document, the browser renders it
User takes an action
Browser makes a POST request, server responds with an HTML document, the browser renders it
What you've started coded on the frontend is an alternate method:
You make a POST request via AJAX, server responds with some JSON, you modify the current document with JavaScript to let the user know

Resources