node.js variables from a module - javascript

I cannot figure out how to get a variable from a node.js module. I'm creating a module that will interface with an authentication mechanism, and currently it only returns a token. I need this token in the main.js, as I will be calling other modules, and passing this token for authentication.
//auth.js
var request = require("request");
var authModule = {};
var authToken = "";
var options = {
method: 'POST',
url: 'https://dummy.url/oauth/token',
headers: {
'authorization': 'Basic secretkeystring',
'accept': 'application/json',
'content-type': 'application/x-www-form-urlencoded'
},
form: {
grant_type: 'password',
username: 'indegomontoya',
password: 'sixfingeredman'
}
};
authModule.getToken = function getToken(){
request(options, requestToken);
};
function requestToken (error, response, body) {
if (error) throw new Error(error);
authToken = response.body.toString().split('\n')[1].split(":")[1].split('"')[1];
console.log("auth.js says: " + authToken);
// ^^ this works, and spits out the correct token to the console
return authToken;
};
module.exports = authModule;
module.exports.token = authToken;
And here is my main.js:
//main.js
var auth = require("./auth.js");
var token;
token = auth.getToken();
console.log("main.js says :"+ token);
// ^^ comes back undefined
I've seen examples of sending a variable from main.js to module.js, but I need to do the opposite. Any help is greatly appreciated!
EDIT: typo in code.

Try passing a hash instead.
module.exports = {
module: authModule,
token: authToken
}
var gcdm = require("./gcdm.js");
gcdm.module();
gcdm.token;

It appears that the request module (from here), is asynchronous in nature, meaning that it can take any length of time to return its data. This means that you may need to use a callback when using the getToken method.
Currently, your main.js app does not give suffiecient time for the auth.js module to fetch the token data. It requests the token and then in the same breath (or tick of the processor) it tries to print it to the console. To get around this problem, you need to utilise callbacks.
I would probably adjust your two auth module methods like so:
authModule.getToken = function getToken(callback){
request(options, function(error, response, body){
if (error) throw new Error(error);
callback( requestToken(body) );
});
};
function requestToken (body) {
authToken = response.body.toString().split('\n')[1].split(":")[1].split('"')[1];
return authToken;
};
Also, remove this uneeded line, as your callback will be the delivery mechanism back to your main app:
module.exports.token = authToken; // remove this
You would then use something like this to get the token in your main app:
gcdm.getToken( function (token) {
console.log('main.js says :' + token);
});
You may want to look a bit more into Asynchronous Programming in JavaScript. It's a key ingredient in the NodeJS toolbox.

#shennan thank you very much! You were right on track, and you are correct, request is async. I'm fairly new to node.js, so thanks for bearing with me, and am still trying to wrap my head around callbacks. (thanks #Drazisil for your link to callbackhell.com)
Your answers got me int he right direction, and I ended up with this:
//auth.js
var request = require("request");
var authModule = function () {};
var authToken = "";
var options = {
method: 'POST',
url: 'https://dummy.url/oauth/token',
headers: {
'authorization': 'Basic secretkeystring',
'accept': 'application/json',
'content-type': 'application/x-www-form-urlencoded'
},
form: {
grant_type: 'password',
username: 'indegomontoya',
password: 'sixfingeredman'
}
};
authModule.getToken = function getToken(callback){
request(options, function(error, response, body){
if (error) throw new Error(error);
authToken = response.body;
callback( requestToken(body) );
});
};
function requestToken (body) {
return authToken;
};
module.exports = authModule;
And:
//main.js
var auth = require("./auth.js");
var authTokenData;
function parseAuthJson(data) {
var jsonData = JSON.parse(data);
return jsonData;
}
auth.getToken( function (authTokenData) {
var jsonData = parseAuthJson(authTokenData);
console.log(jsonData.access_token);
});
I gathered help about parsing the JSON here.
Thanks for your help!

Related

unable to parse json string in node js

I have this below function in which i am calling another function "uploadContentVersion" which is a request POST. This also includes a callback which i am capturing in the below function .
The issue which i am facing is this line "console.log(data)" is giving me result like this
{"id":"11111111111111","success":true,"errors":[]}
But when i am trying to print console.log(data.id) i am getting undefined.Not sure where i am doing wrong.
const createFileFromJSON = async() => {
if (fs.existsSync('./templates/officetemplate.docx')) {
const templateFile = fs.readFileSync('./templates/officetemplate.docx');
//console.log(templateFile.toString('utf8'))
var doc = await handler.process(templateFile, data);
// 3. save output
fs.writeFileSync('./templates/' + data.accPlanId + '.docx', doc);
uploadContentVersion(sfdc_token.access_token, sfdc_token.instance_url, data.accPlanId, function(data) {
var conn = new sf.Connection({});
conn.initialize({
instanceUrl: sfdc_token.instance_url,
accessToken: sfdc_token.access_token
});
console.log(data) -- > {
"id": "11111111111111",
"success": true,
"errors": []
}
console.log(data.id) -- > undefined
attachFileToRecord(conn, data)
})
// console.log(contentversionres)
} else {
console.log('Template is not present..')
}
var uploadContentVersion = function(token, instUrl, fname, callback) {
var options = {
'method': 'POST',
'url': some url,
'headers': {
'Authorization': 'Bearer ' + token,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"VersionData": fs.readFileSync(`./templates/${fname}.docx`).toString('base64')
})
};
request(options, function(error, response) {
if (response.statusCode === 201) {
callback(response.body);
}
if (error) throw new Error(error);
});
}
Your issue appears to be that you are recieving data as a string, not as an Object. In your answer, you responded saying that adding JSON.parse() (mdn) worked. This is because JavaScript interpreters have no way of knowing that you want it treated as an object, so the JSON.parse function was made to fix that. There is also the opposite, JSON.stringify.
I don't know what was the issue. I just passed JSON.parse(response.body).id from request and it solved the issue

Bad respond when trying to get authentication token for Reddit api 'Application Only OAuth'

So i been trying to get access to the reddit api.
I registered to reddit. verified my mail. opened an app and got my credentials.
Followed this official documentation and also came across to this tutorial
All my efforts have failed and don't get any respond.
I am using nodejs. but also tried in postman and failed.
Tried 2 options using fetch and using axios:
const axios = require('axios');
const fetch = require('node-fetch')
const { URLSearchParams } = require('url')
class RedditApi {
clientId2 = "get ur own credentials by opening an app here https://www.reddit.com/prefs/apps";
clientSecret2 = "get ur own credentials by opening an app here https://www.reddit.com/prefs/apps";
authenticationUrl = `https://www.reddit.com/api/v1/access_token`;
BASE_URL = 'https://www.reddit.com/';
tokenAuth = null;
tokenExpirationTime = null;
currencyObj = null;
constructor(currencyObj) {
this.currencyObj = currencyObj;
console.log("constructor service")
}
async getAuthToken() {
const bodyParams = new URLSearchParams({
grant_type: "https://oauth.reddit.com/grants/installed_client",
device_id: "DO_NOT_TRACK_THIS_DEVICE"
});
console.log(this.clientId2, 'this.clientId');
debugger;
const headersObj = {
'Authorization': `Basic ${Buffer.from(`${this.clientId2}:`).toString('base64')}`,
'Content-Type': 'application/x-www-form-urlencoded',
};
let response = null;
try {
response = await axios.post(this.authenticationUrl,
bodyParams,
{
headers: headersObj
});
debugger;
} catch (error) {
debugger;
console.error(error);
console.log(error.stack);
return null;
}
}
async getAuthToken2() {
try {
// Creating Body for the POST request which are URL encoded
const params = new URLSearchParams()
params.append('grant_type', 'https://www.reddit.com/api/v1/access_token')
params.append('device_id', 'DO_NOT_TRACK_THIS_DEVICE')
// Trigger POST to get the access token
const tokenData = await fetch('https://oauth.reddit.com/grants/installed_client', {
method: 'POST',
body: params,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': `Basic ${Buffer.from(`${this.clientId2}:`).toString('base64')}` // Put password as empty
}
}).then(res => {
debugger;
return res.text()
})
debugger;
if (!tokenData.error) {
debugger;
res.send(trendingResult)
}
res.status(tokenData.error).send(tokenData.message)
} catch (error) {
debugger;
console.log(error)
}
}
}
module.exports = RedditApi;
when using axios i get this respond: "Request failed with status code 401"
When using fetch i get this respond: "'403 Forbidden\nRequest forbidden by administrative rules.\n\n'"
Anybody knows what is the problem and how can i fix it?
Many thanks!

http 401 error when providing an access token the outlook api

I am trying to create a folder for a user, and I have been unsuccessful with api call attempts. My code is able to receive the correct access token, so I believe the be bug would be in createFolderTestFunction below.
async function redirectToDashboard() {
console.log("redirect to dashboard");
// var response = await requestTokenSilent();
var response;
if (!response || !response.status == 200) {
response = await requestTokenPopup();
}
if (response.accessToken) {
console.log(response);
createFolderTest(response.accessToken);
// location.href = hostname;
} else {
console.log("Unable to acquire token");
}
}
function createFolderTest(accessToken) {
var options = {
method: "POST",
headers: {
Authorization: accessToken,
"Content-Type": "application/json"
},
mode: "cors",
body: JSON.stringify({
displayName: "#COOLMONDAY"
})
};
var graphEndpoint = "https://outlook.office.com/api/v2.0/me/Inbox/";
fetch(graphEndpoint, options)
.then(resp => {
console.log(resp);
})
.catch(err => {
console.log(err);
});
}
A recommendation would be to get this working in Graph Explorer first. As this eliminates any issues with language being used and access token permissions.
https://developer.microsoft.com/en-us/graph/graph-explorer/preview
The Microsoft Graph endpoint is actually https://graph.microsoft.com/ , you can use the outlook url but moving forward Graph is where we invest in documentation, sdks and tooling.
As per the documentation https://learn.microsoft.com/en-us/graph/api/user-post-mailfolders?view=graph-rest-1.0&tabs=http
You should be using, you're missing 'mailfolders'
POST /me/mailFolders
You could also use our JavaScript SDK which makes mistakes like these a little easier with intellisense and strongly typed objects.
const options = {
authProvider,
};
const client = Client.init(options);
const mailFolder = {
displayName: "displayName-value"
};
let res = await client.api('/me/mailFolders')
.post(mailFolder);
https://learn.microsoft.com/en-us/graph/api/user-post-mailfolders?view=graph-rest-1.0&tabs=javascript

Header section has more than 10240 bytes (maybe it is not properly terminated)

I'm using NodeJs to try to upload an attachment to a Jira Issue via the Jira Rest API.
The api expects multipart/form-data so this is how I'm calling it in Node:
function uploadAttachments(supportFormData, callback) {
const url =
'https://somewhere.com/jira/rest/api/2/issue/' +
supportFormData.issueId +
'/attachments';
var options = {
url: url,
headers: {
Authorization: { user: username, password: password },
'X-Atlassian-Token': 'nocheck'
}
};
var r = request.post(options, function(err, res, body) {
if (err) {
console.error(err);
callback(false);
} else {
console.log('Upload successful! Server responded with:', body);
callback(false);
}
});
var form = r.form();
form.append('file', supportFormData.attachments[0].contents, {
filename: supportFormData.attachments[0].fileName,
contentType: supportFormData.attachments[0].contents
});
}
The error I'm receiving is:
org.apache.commons.fileupload.FileUploadException: Header section
has more than 10240 bytes (maybe it is not properly terminated)
The "supportFormData.attachments[0].contents" is ofType Buffer.
Any suggestions as to what could be causing this error?
I ran into this same issue and it turns out JIRA (or Java) requires \r\n as new line character. After I changed \n to \r\n my requests went through without problem.
If its a basic auth change options object to
let auth = new Buffer(`${username}:${password}`).toString('base64');
var options = {
url: url,
headers: {
Authorization: `Basic ${auth}`,
'X-Atlassian-Token': 'nocheck'
}
};

Automatically Sending Notification Email w/ Server

I need to do a notification sender working on a linux server. The idea is once a week this sender do a query in JQL and, if it returns something, sends an email to a certain list.
I'm rather new to servers and javascript. I'm already doing the JQL query, but:
I need the Sender to know the right time to do it. What is the most efficient way to trigger the Sender?
How can I send an email in JS from an specific address to a list of emails?
A rough sketch:
//magic, part 1
WaitUntilMonday();
var result = DoJQLQuery();
if (result != '')
SendNotificationEmail(from,to,message);
//magic, part 2
I tried to search about it, but I don´t know where to start. I´d appreciate any suggest of reading material too. Thank you.
Well you can use NODEJS with sendgrid api for your server end and email api. The actual clientside, you could hook it up to a on a website or simply just run the nodejs application.
So the place to start would be https://nodejs.org/ and http://sendgrid.com
That would definitely handle your emailing needs. Here is a function I used stripped of my api key (obviously), the call to postEmail actually sends the mail, the rest is verification.
to send email its pretty easy. Good luck.
const SENDGRID_API_KEY = "SG.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
var helper = require('sendgrid').mail;
var sg = require('sendgrid')(SENDGRID_API_KEY);
var emptyRequest = require('sendgrid-rest').request;
var request = require("request");
function makeEmail(whereFrom, whereTo, mysubject, mycontent){
from_email = new helper.Email(whereFrom);
to_email = new helper.Email(whereTo);
subject = mysubject;
content = new helper.Content("text/html", mycontent);
mail = new helper.Mail(from_email, subject, to_email, content);
custom_arg = new helper.CustomArgs("OURGUID", "ourcustomarg");
mail.addCustomArg(custom_arg);
var finished = mail.toJSON();
var timer = 0;
function postEmail(){
var requestBody = finished;
var requestPost = JSON.parse(JSON.stringify(emptyRequest));
requestPost.method = 'POST';
requestPost.path = '/v3/mail/send';
requestPost.body = requestBody;
sg.API(requestPost, function (error, response) {
console.log(response.statusCode + ' STATUS')
console.log('MESSAGE ID = '+ response.headers['x-message-id'])
if(response.statusCode == '202') {
console.log(response.statusCode + ' EMAIL SENT TO SENDGRID AND QUED')
}//response if statement
if(response.statusCode != '202'){
console.log(response.statusCode + ' Something went wrong')}
})//end internal api function
}//end api
postEmail(finished);//actually sending the mail
function getEmail(){
var requestBody = finished;
var requestPost = JSON.parse(JSON.stringify(emptyRequest));
requestPost.method = 'GET';
requestPost.path = '/v3/mail/send';
requestPost.body = requestBody;
sg.API(requestPost, function (error, response) {
console.log(response.statusCode + ' SUCCESSFUL EMAIL');
console.log('MESSAGE ID = '+ response.headers['x-message-id']) ;
})//end internal api function
}//end api
function checkBounce(){
console.log('this is checkBounce');
var options = { method: 'GET',
url: 'https://api.sendgrid.com/v3/suppression/bounces/'+ whereTo,
headers: { authorization: 'Bearer your api key here' },
body: '{}' };
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(response.statusCode);
console.log(body);
});
}//check Bounce
function checkInvalid(){
console.log('This is check invalid');
var options = { method: 'GET',
url: 'https://api.sendgrid.com/v3/suppression/invalid_emails'+ whereTo,
headers: { authorization: 'Bearer your api key here' },
body: '{}' };
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(response.statusCode);
console.log(body);
});
}//check Invalid
function checkBlock(){
console.log('This is check Block');
var options = { method: 'GET',
url: 'https://api.sendgrid.com/v3/suppression/blocks'+ whereTo,
headers: { authorization: 'Bearer your api key here' },
body: '{}' };
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(response.statusCode);
console.log(body.created);
});
}//check Block
function checkTest(){
console.log('This is check Test');
var options = { method: 'GET',
url: 'https://api.sendgrid.com/v3/',
headers: { authorization: 'Bearer your api key here' },
body: '{}' };
request(options, function (error, response, body) {
if (error) throw new Error(error);
body = JSON.parse(body);
console.log(response.statusCode);
console.log(body);
});//end request
}//check Processed
}//make email end

Categories