Consuming RESTful APIs using Electron - node.js

I would like to make some requests (GET, POST, PUT ...) for a RESTful API before displaying any window of my Electron application (use Electron app as a client). Is it possible to use ClientRequest to do this? Would anyone has an example?
Thank you very much.

Just clone this repo - git clone https://github.com/AldoHub/Electron-Weather.git.
Also the video for the same is at - https://www.youtube.com/watch?v=5_r7UQvnbtQ.
Also you need to register with the https://weatherstack.com/ and get 'Your API Access Key' and paste it in the file
Electron-Weather/src/public/functions.js
at line number 5
await fetch(`http://api.weatherstack.com/current?access_key=<your_access_key>&query=${city}`)
Also, for debugging the electron app, see the link - https://discuss.atom.io/t/how-to-make-developer-tools-appear/16232/6
Finally, to run the electron app,execute the command
1. npm install or yarn install
2. npm start or yarn start
Another POST example:
Method: POST
Url: http://161.117.231.37/api/v1/login
Body:
{
"email": "admin#gmail.com",
"password": "12345678"
}
Sample response is:
{
"success": true,
"data": {
"expiresIn": 6000,
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFkbWluQGdtYWlsLmNvbSIsImlhdCI6MTYxNDMxNzM1MiwiZXhwIjoxNjE0MzIzMzUyfQ.wPcSA9Mx8PSLUgi1Okxwl8LBfx3Ia8m9bL5PEndcrs8",
"type": "Admin",
"verification": {
"mobile": true,
"email": true,
"isProfileCompleted": 0,
"isOnboardingComplete": false,
"forcePasswordChange": true
}
}
}
Now, the code for the same is
function.js
const cityForm = document.querySelector("#weatherForm");
document.addEventListener("DOMContentLoaded", (e) => {
cityForm.addEventListener("submit", (e) => {
e.preventDefault();
if(document.querySelector("#email").value != ""){
let conditionsDiv = document.querySelector("#conditions");
if(conditionsDiv){
document.querySelector("main").removeChild(conditionsDiv);
}
getToken(document.getElementById("email").value, document.getElementById("password").value);
}else{
console.log("You must provide a email and password");
}
})
})
const getToken = async(_email, _password) => {
let _body = {email: _email, password: _password}
console.log({email: _email, password: _password})
await fetch('http://161.117.231.37/api/v1/login',{
method: 'POST', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, *cors, same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json'
// 'Content-Type': 'application/x-www-form-urlencoded',
},
redirect: 'follow', // manual, *follow, error
referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
body: JSON.stringify({email: _email, password: _password}) // body data type must match "Content-Type" header
})
.then(res => res.json())
.then(data => {
console.log(data)
let div = document.createElement("div");
div.setAttribute("id", "conditions");
let temp = document.createElement("div");
let tempNode = document.createTextNode("Your token is this......" + data.data.token );
temp.appendChild(tempNode);
div.appendChild(temp);
document.querySelector("main").appendChild(div);
}).catch(err => console.log(err))
}
In the index.html, you have:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="../public/main.css" type="text/css" />
<title>Electron Weather</title>
</head>
<body>
<img id="hero" src="../public/images/taxi-autopilot.png" />
<header>
<h1>Electron <br/> Weather</h1>
<p>illustration by <strong>Ouch.pics</strong></p>
</header>
<main>
<p>Type the email and password to find out the token ...</p>
<form method="POST" id="weatherForm">
<input type="text" id="email" placeholder="Email Name" />
<input type="text" id="password" placeholder="Password Name" />
<input id="postSubmit" type="submit" value="Submit" />
</form>
</main>
<script src="../public/functions.js"></script>
</body>
</html>
After hitting Ctrl + Shift +I two times, you get the console window in the electron app as:

Related

EJS: Trying to use PATCH method with html form

I have just started learning Node.js.
I have this following code where I need to submit the form using patch method to update an existing record.
Language/Edit.ejs
<form action="//localhost:3000/languages/6343eb83340e657a0321a9cc" method="post">
...
<div class="boxFooter grid gap-2">
<input type="hidden" name="_method" value="patch">
<button type="submit">Update</button>
</div>
</form>
Router
...
Router.patch('languages/:id', validations, update);
...
Controller
import Model from '#Models/Language.js';
...
const update = async (req, res) => {
try {
const item = await Model.findByIdAndUpdate(req.params.id, {
title: req.body.title,
description: req.body.description,
status: req.body.status,
}, {
new: true,
runValidators: true
});
res.send(item);
} catch (error) {
return res.status(400).json('Sorry, we have an error.');
}
};
But, I am getting this error always
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot POST /languages/6343eb83340e657a0321a9cc</pre>
</body>
</html>
I have also tried to use method="patch" instead of method="post". But, the outcome is still the same.
However, I tried to run this url with postman and it worked flawlessly.
Here is the peace of code that solved my problem. However, I am not sure whether this is the right way or not.
What I did was that I changed the method to patch and submitted the form with ajax.
Here is my code:
<form action="//localhost:3000/languages/6343eb83340e657a0321a9cc" method="patch">
...
<div class="boxFooter grid gap-2">
<button type="submit">Update</button>
</div>
</form>
<script type="text/javascript">
...
ajaxRequest({
...
type: $('form').attr('method'),
...
})
</script>
...
const ajaxRequest = (params) => {
return $.ajax($.extend(true, {
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
type: 'POST',
url: '',
data: {},
cache: false,
beforeSend: () => {},
success: (response) => {},
complete: (response) => {}
}, params));
};
...
Is this the right way..?

Notification not sending to Firefox client(Firebase Cloud Messaging)

I am using Node.JS on server side to send notification to 3 clients(browsers). Clients on Microsoft Edge and Chrome receive notifications, but Firefox do not (p.s. i'am testing on domain with https encryption)
Client code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script type="module">
// Import the functions you need from the SDKs you need
import { initializeApp } from "https://www.gstatic.com/firebasejs/9.9.1/firebase-app.js";
import {
getMessaging,
getToken,
onMessage,
} from "https://www.gstatic.com/firebasejs/9.9.1/firebase-messaging.js";
const firebaseConfig = {
/* <config> */
};
const app = initializeApp(firebaseConfig);
const vapidKey = "vapid";
window.messaging = getMessaging();
window.messaging.onMessageHandler = console.log;
getToken(window.messaging, { vapidKey }).then((token) => {
const p = document.createElement("p");
p.appendChild(document.createTextNode(token));
document.querySelector("html").appendChild(p);
});
</script>
</body>
</html>
Server side code:
const firebase = require("firebase-admin");
const serviceAccount = require("mycredentials.json");
const app = firebase.initializeApp({
credential: firebase.credential.cert(serviceAccount),
});
firebase
.messaging(app)
.sendMulticast({
tokens: [
"<edge token>",
"<chrome token>",
"<firefox token>"
],
data: {
test: "Test",
},
webpush: {
notification: {
body: "Halo!",
title: "notification_new_message",
},
},
})
.then((response) => {
console.log(JSON.stringify(response, null, 4));
});
Unfortunately, I receive error:
{
"responses": [
{
"success": true,
"messageId": "<messageId>"
},
{
"success": true,
"messageId": "<messageId>"
},
{
"success": false,
"error": {
"code": "messaging/third-party-auth-error",
"message": "Auth error from APNS or Web Push Service"
}
}
],
"successCount": 2,
"failureCount": 1
}
I tried sending single request(messages:send) to Firefox Client, but it fails with the same error. Also, I tried to manually build and send raw Batch Request, but result was the same.
How can I figure it out?

Node.js set Headers in HTTP GET request

I'm using Node.js 'https' module. And i'm sending a GET request with some headers option but I get the following error:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<TITLE>ERROR: The request could not be satisfied</TITLE>
</HEAD>
<BODY>
<H1>ERROR</H1>
<H2>The request could not be satisfied.</H2>
<HR noshade size="1px"> Bad request.
<BR clear="all">
<HR noshade size="1px">
<PRE> Generated by cloudfront (CloudFront) Request ID: 7H9MBMS_ullYt-ZSpdMw4WjAU0O1QlVaDNw_8QLwlXZa8olpjmRPDQ== </PRE>
<ADDRESS></ADDRESS>
</BODY> </HTML>
Following is my code
const var https = require('https')
var optionsget = {
headers: {
'client': process.env.MOVIEGLU_CLIENT,
'x-api-key': process.env.MOVIEGLUE_API_KEY,
'api-version': process.env.MOVIEGLU_API_VERSION,
'Authorization': process.env.MOVIEGLUE_AUTHORISATION,
'geolocation': user.loc[0] + ';' + user.loc[1],
'Content-Type':'application/x-www-form-urlencoded'
},
host: process.env.MOVIEGLU_HOST,
path: path,
method: 'GET'
};
// do the GET request
var content = ''
var reqGet = https.request(optionsget, function (response) {
response.on('data', function (data) {
// Append data.
content += data;
});
response.on('end', function () {
console.log('content ', content)
callback(null, content)
})
});
reqGet.end();
reqGet.on('error', function (e) {
callback(e, null)
});
});
Can someone please guide me what i'm doing wrong in setting headers? I'm really stuck.
Thanks

redirect_uri_mismatch with Google Sign-In for server-side apps

I have a problem with my Google Sign in.
I follow the steps on Google Sign-In for server-side apps
After all this step, i have this html file that run on a server :
<!DOCTYPE html>
<html itemscope itemtype="http://schema.org/Article">
<head>
<link rel="stylesheet" href="theme.css">
<!-- BEGIN Pre-requisites -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="https://apis.google.com/js/client:platform.js?onload=start" async defer></script>
<!-- END Pre-requisites -->
<script>
function start() {
gapi.load('auth2', function() {
auth2 = gapi.auth2.init({
client_id: 'CLIENT_ID'
});
});
}
</script>
</head>
<body>
<button id="googleBtn">Connect</button>
<script>
$('#googleBtn').click(function() {
auth2.grantOfflineAccess().then(googleCallback);
});
</script>
<script>
function googleCallback(authResult) {
if (authResult['code']) {
console.log(authResult);
} else {
console.log(authResult);
}
}
</script>
</body>
</html>
This first part work perfectly (I think), when I click on button, a window popup, I select an account and I get a code. So now, I want to get email and profile, so I make this request in nodejs to exchange the code with an access token.
var form = {
code: 'XXXXXXXXXXXX',
client_id: 'CLIENT_ID,
client_secret: 'CLIENT',
grant_type:'authorization_code'
};
var formData = querystring.stringify(form);
var contentLength = formData.length;
request({
headers: {
'Content-Length': contentLength,
'Content-Type': 'application/x-www-form-urlencoded'
},
uri: 'https://www.googleapis.com/oauth2/v4/token',
body: formData,
method: 'POST'
}, function (err, rep, body) {
console.log(err);
console.log(rep.statusCode);
console.log(body);
});
But in response, I have this
{
"error": "redirect_uri_mismatch",
"error_description": "Bad Request"
}
And I don't understand why, because I don't use any redirect_uri in primary request in html file. I have try some cases like add redirect_uri on Console API and in request, but I have the same result...
Can you help me ?
From a client side auth2.grantOfflineAccess process, to get accessToken on server, you have to pass redirect_uri=postmessage in request params.
From your example :
var form = {
code: 'XXXXXXXXXXXX',
client_id: 'CLIENT_ID,
client_secret: 'CLIENT',
grant_type:'authorization_code',
redirect_uri: 'postmessage' // the line to add
};
You need to define your callback url to Google via console.developer.google.com
So you need to follow this steps for define the callback URL:
Go to console.developer.google.com
Select your project.
Click 'Credentials' on the left menu.
Click your client on the 'OAuth 2.0 client IDs' list.
Add your callback url to 'Authorized redirect URIs' list.
And done.

Angularjs REST API Interaction failure

I am a Angularjs New bee.This is my first Angularjs application, i am just trying to interact with Nodejs service call and to print the response. But I am receiving different error in Chrome and Firefox.
In chrome i got uncaught error and in firefox i got Error: [$injector:modulerr]
Here is my coding:
index.html:
<!doctype html>
<html data-ng-app="myapp">
<head>
<title>Monitoring</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.min.js">
</script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular-route.js">
</script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular-resource.js">
</script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular-route.js">
</script>
<script type="text/javascript" src="controller/controller.js"></script>
</head>
<body>
<div ng-controller="CommonMetricsCtrl">
{{data}}
</div>
</body>
</html>
controller.js
var App = angular.module('myapp', ['ngRoute', 'ngResource']);
App.controller('CommonMetricsCtrl', ['$scope', '$resource',
function($scope, $resource) {
function createResource(url) {
return $resource(url + '?alt=:alt&method=:callback', {
alt: 'json',
callback: 'JSON_CALLBACK'
}, {
get: {
method: 'JSONP',
headers: [{
'Content-Type': 'application/json'
}, {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
}]
},
isArray: false
});
}
URL = "http://localhost:1111/servicelist";
var resource = createResource(URL);
resource.get({}, function processResponse(response) {
console.log(response);
$scope.data = response;
if (response.error) {
console.log('Error here');
}
});
}
]);
I dont know where i went wrong, Can any one sort out the issue please?
You're adding the angular-route module twice.

Resources