Open a web service url in meteor - javascript

I have this script in php that opnes a web service url to send an sms
<?php
$amount = 300;
$url = 'http://sms.com.co/webservice/sms.php?method=Submit&account=adam&password=123456&mobile=773839&content=helloworld;'
echo file_get_contents($url);
?>
In nodejs i have this
var urllib = require('urllib');
urllib.request('http://sms.com.co/webservice/sms.php?method=Submit&account=adam&password=123456&mobile=773839&content=helloworld');
I am looking for a function or package in meteor that i can use so that i can avoid installing the urllib npm package.

You can use "HTTP" for this.
HTTP.call('get', 'http://sms.com.co/webservice/sms.php', {
params: {
method: 'Submit',
account: 'adam',
password: '123456',
mobile: '773839',
content: 'helloworld'
}}, function(err, res) {
// do stuff
})
Upon calling this from your Meteor method will be asynchronous. Your method will not wait for the response from the HTTP call. In order to do so you need to use wrapAsync like this:
var convertAsyncToSync = Meteor.wrapAsync(HTTP.get),
apiCall = convertAsyncToSync(yourURLHere, {params});
if (apiCall.statusCode === 200) {
// do stuff
}

Sounds like you need "HTTP" from the Meteor core libraries. See http://docs.meteor.com/api/http.html for details. Install it using:
meteor add http
This lets you open a URL using either a method or without a method from the server:
HTTP.call('get', 'http://sms.com.co/webservice/sms.php', {
params: {
method: 'Submit',
account: 'adam',
password: '123456',
mobile: '773839',
content: 'helloworld'
}}, function(err, res) {
// do stuff
})

Related

Azure OAuth with Cypress: Infinite Loop

Trying to set up Cypress to test an application that uses OAuth against Azure AD. My login command is defined as follows:
Cypress.Commands.add('login', () => {
return cy.request('POST', Cypress.env('AccessTokenUrl') +
'?grant_type=' + Cypress.env('GrantType') +
'&client_id=' + Cypress.env('ClientId') +
'&client_secret=' + Cypress.env('ClientSecret'))
})
This is what I call in a test:
cy.login().then(response => {
expect(response.status).to.eq(200)
expect(response.body).to.have.property('access_token')
expect(response.body).to.have.property('token_type', 'Bearer')
const {access_token, expires_in, id_token} = response.body
cy.setCookie('access_token', access_token)
})
cy.visit('my-url')
The validations pass. The login response contains a valid token. However, the ct.visit call fails with infinite recursion, as the parameters like &iframe-request-id=[some uuid] become added over and over to a login.microsoftonline.com URL, until eventually returning HTTP Error 414. The request URL is too long.
Here's what the URL looks like, with some information redacted and with some formatting for clarity:
https://login.microsoftonline.com/
[tenant-id]/oauth2/v2.0/authorize
?response_type=code
&client_id=[client-id]
&redirect_uri=[my-url]
&scope=openid+profile+email+https%3A%2F%2Fgraph.microsoft.com%2Fuser.read
&iframe-request-id=1a9fdcbd-6b9e-46c8-93e3-ce0edf62b600
&iframe-request-id=b5b5cf2b-e0a6-4d92-9e55-cf32208ab900
&iframe-request-id=8471e17f-1d36-48f7-8419-f54e14b3b100
&iframe-request-id=56113dad-6029-4a37-9758-5828f93f0300
&iframe-request-id=51c06224-98f1-4b83-a8f2-84f8dfe9aa00
&iframe-request-id=09775645-505c-42e0-ac56-1335b5a7ba00
&iframe-request-id=5c98158b-b202-41fe-9d65-8fbfe4e46500
&[and-so-on]
I have found various suggestions on the web about using Puppeteer as a task for Azure AD SSO, but none of them works for my purposes. First, they try to resolve the problem of actually obtaining the token, which I have already solved. Second, they rely on the login URL presenting an HTML form, which is not the case with login.microsoftonline.com.
What do you suggest?
UPDATE: Trying a different solution, I receive an interesting error. The loginMS command:
import * as MSAL from '#azure/msal-browser'
Cypress.Commands.add('loginMS', () => {
cy.request({
method: 'POST',
url: `https://login.microsoftonline.com/${Cypress.env('TenantId')}/oauth2/token`,
form: true,
body: {
scope: Cypress.env('LoginScope'),
client_id: Cypress.env('ClientId'),
client_secret: Cypress.env('ClientSecret'),
redirect_uri: Cypress.env('LoginRedirect'),
grant_type: Cypress.env('GrantType'),
username: Cypress.env('Username'),
password: Cypress.env('Password'),
response_type: 'code'
}
}).then(response => {
console.log(response)
window.localStorage.setItem(`msal.idtoken`, response.body.access_token);
window.localStorage.setItem(`msal.client.info`, MSAL.clientInfo);
})
})
The error is:
Failed to find a valid digest in the 'integrity' attribute for resource
'https://aadcdn.msauth.net/shared/1.0/content/js/OldConvergedLogin_PCore_Up8WrFIk8-TG_eqBz8MSlw2.js'
with computed SHA-256 integrity 'NxfOkHjbTYDy/EOknsK0PMOfym7iLRGY+yBShyznzx4='.
The resource has been blocked.
It realy depends how the application under test handles requests. But I guess you use the adal libary.
With the help of https://mechanicalrock.github.io/2020/05/05/azure-ad-authentication-cypress.html it worked for me in a vuejs application using adal v1.
The important part is
localStorage.setItem("adal.token.keys", `${Cypress.config("clientId")}|`);
localStorage.setItem(`adal.access.token.key${Cypress.config("clientId")}`, ADALToken);
localStorage.setItem(`adal.expiration.key${Cypress.config("clientId")}`, expiresOn);
localStorage.setItem("adal.idtoken", ADALToken);
I actually did not request the token from azure but just copied in what I saw F12 tools as my token when using the application under test.
I managed to solve the Azure AD login by creating the following Cypress custom command for my Angular application:
Cypress.Commands.add('login', () => {
return cy
.request({
method: 'POST',
url: `https://login.microsoftonline.com/${tenantId}/oauth2/token`,
form: true,
body: {
grant_type: 'password',
tenant: 'tenantId',
client_id: 'clientId',
client_secret: 'clientSecret',
username: 'username',
password: 'password',
resource: 'clientId',
},
})
.then((response) => {
sessionStorage.setItem('access_token', response.body.access_token);
});
});

How to login to gmail account and read a mail in protractor not using the browser

I have a scenario which I need to login to a gmail account and read the content or the message. Then need to get a URL from that message. I can do this using a browser in protractor. But the issue is that gmail account enabled the 2FA. I have achieved this using the core Selenium which has jar files to log in to the gmail account using IMAP protocol.
Can someone please give me a good solution?
You can read emails from Gmail inside protractor tests using mail-listener2 npm package. Check the below example code.
mailListener.ts
const MailListenerClient = require("mail-listener2");
const cheerio = require('cheerio');
const simpleParser = require('mailparser').simpleParser;
export class MailListener {
public mailListener:any;
constructor() {
this.mailListener = new MailListenerClient({
username: "username#gmail.com",
password: "password",
host: "imap.gmail.com",
port: 993,
tls: true,
mailbox: "INBOX",
searchFilter: ["UNSEEN", ["FROM", "fromemail#gmail.com"],["SUBJECT","subject of the email"]],
/*it will search for are "unseen" mail send from "fromemail#gmail.com" with subject "fromemail#gmail.com"*/
connTimeout: 10000,
authTimeout: 5000,
markSeen: true,
mailParserOptions: {streamAttachments: true}, // options to be passed to mailParser lib.
attachments: true, // download attachments as they are encountered to the project directory
attachmentOptions: {directory: "attachments/"},
debug : console.log
});
}
init() {
this.mailListener.start();
}
close() {
this.mailListener.stop();
}
getLinkFromEmail() {
var self = this;
return new Promise((resolve, reject) => {
self.mailListener.on("mail", function (mail) {
/*simpleParser is used to convert string to HTML format*/
simpleParser(mail.eml).then(function (parsedEmail) {
var html = parsedEmail.html;
/* cheerio is used to write query on parsed HTML content
* refer https://www.npmjs.com/package/cheerio
*/
resolve(cheerio.load(html)("a").attr("href"));
});
});
self.mailListener.on("error", function (err) {
reject(err);
});
});
}
}
test.ts
import {MailListener} from "mailListner";
describe("Read email from gmail using imap", function () {
let mailListener = new MailListener();
beforeAll(function(){
mailListener.init();
});
afterAll(function(){
mailListener.close();
})
it("Test email recieved",function(){
let urlFromEmail = mailListener.getLinkFromEmail();
/*Perform some action on UI that triggers email.(Just for example im doing it)*/
element(by.id("email")).sendKeys("email#gmail.com");
element(by.buttonText("Send Email")).click();
expect(urlFromEmail).toEqual("some link");
})
});
I have written the code in typescript and hope you can rewrite the same in javascript. Let me know if this is clear or do I need to add more details to the code.
One of the best practice is to use Gmail API. Take a look at official documentation

Is there a way to send data to server using 'unload\navigator.sendBeacon' + 'GraphQL'?

On tab\browser close I need to send data to server. I found this answer (based on this blog) which recommends to use sendBeacon. Here is shown how the data must be prepared in order to send them to server via Ajax. I repeated the structure from the answer:
window.addEventListener('unload', this.sendDataToServer, false)
sendDataToServer () {
myData = JSON.stringify({
'mutation': `mutation EmailAuth($email: String!, $password: String!) {
getOrCreateUser(email: $email, password: $password) {
token
}
}
`,
'variables': {email: 'test#test.net', password: 'Test'}
})
navigator.sendBeacon('http://localhost:8000/graphql', myData)
}
In this case Django shows: "POST /graphql HTTP/1.1" 400 53
I also found in internet the version with Blob:
window.addEventListener('unload', this.sendDataToServer, false)
sendDataToServer () {
let headers = {
type: 'application/json'
}
let myBlob = new Blob([JSON.stringify({
'mutation': `mutation EmailAuth($email: String!, $password: String!) {
getOrCreateUser(email: $email, password: $password) {
token
}
}
`,
'variables': {email: 'test#test.net', password: 'Test'}
})], headers)
navigator.sendBeacon('http://localhost:8000/graphql', myBlob)
}
but in this case there is no any Django's reaction at all.
How can I wrap my data on a frontend side into GraphQL format and put it in sendBeacon in the way, which can be accepted by server side?
Found why Blob does not work, with a help of using button instead of unload. The issue is with chrome browser. Console shows: Uncaught DOMException: Failed to execute 'sendBeacon' on 'Navigator': sendBeacon() with a Blob whose type is not any of the CORS-safelisted values for the Content-Type request header is disabled temporarily. See http://crbug.com/490015 for details.
Django is waiting for request of application/json type, which according to the link from error is not safe.
For Firefox this issue can be fixed using Django's package corsheaders and add CORS_ALLOW_CREDENTIALS = True to the settings.

Triggering Javascript Code from PHP Laravel Controller

I'm using OAuth for login in my Laravel Controller. Its working fine but the thing is when the user is registered for the first time, I wanna trigger the HTML 5 geolocation API to fetch the user's current location and do some mixpanel stuff. Earlier I was using AJAX in the JS for the login so there was no such problem but now that I've implemented a complete server side solution, I'm stuck with this one problem.
The Laravel Controller code looks something like this :
function callback(){
\\ fetch the access token and graph data
if($res = \Auth::mjAuthenticate('facebook', $fbData)){
$user = \Auth::scope()->getUser();
return \Redirect::to('events');
}
if (\Auth::mjRegister('facebook', $fbData)) {
$user = \Auth::scope()->getUser();
return \Redirect::to('events');
}
return $this->handleFailure('Some Problem Occured');
}
The Earlier JS Code was :
ajax
.post('auth/login', {
data: {
oauth_provider: 'facebook',
oauth_token: accessToken
},
cache: false
})
.done(function(data) {
mixpanel.track('User Logged In', {
id: data.resource.id,
provider: 'Facebook',
email: data.resource.email,
first_name: data.resource.first_name,
last_name: data.resource.last_name
});
if (data.msg == 'Resource registered') {
if(navigator.geolocation){
// Prompt for Allow Deny Geolocation popup.
}
}
});

How to execute Orientdb server side function from Orientjs?

I am using Orientjs to access a Orientdb database from a nodejs script, but the server side function does not effect the database.
Server side script:
This Javascript function addTxt() takes the argument author and text
var db = orient.getGraph();
db.command('sql','insert into Message (author, text) VALUES ("'+author+'", "'+text+'")');
return "1";
Query: This function has been tested in Orient Studio and the following query works:
SELECT addTxt("Testuser","foo")
Nodejs/Orientjs: When invoking this function from a nodejs script using Orientjs, it only returns
[ { '#type': 'd', addTxt: '1', '#rid': { cluster: -2, position: 1 } } ]
and the database remains untouched.
I have tried:
//some code
var OrientDB = require('orientjs');
var server = OrientDB({
host: 'localhost',
port: 2424,
});
var db = server.use({
name: 'database',
username: 'admin',
password: 'pass'
db.query('SELECT addTxt(:arg1, :arg2)', {
params: {arg1:"Testuser",arg2:"foo"}
}).then(function (response){
console.log(response);
});
Other queries from Orientjs works.
What am I doing wrong? Is there an other way to invoke a server side function?
You explicit returns "1"
it is right that returns
[ { '#type': 'd', addTxt: '1', '#rid': { cluster: -2, position: 1 } } ]
try to directly explicit the commit in your function
db.commit()

Categories

Resources