Node.js cannot use import statement outside a module - node.js

I'm working on a Authentification system and defaulted to jsrsasign, I started writting a node and everything was alright it opened a localhost to connect to another site worked jsut fine however I went to work on what mattered, the encoding and the code worked as plain JS
import KJUR from "./jsrsasign";
else if (pathName === '/signature') {
res.end("we code here");
function generateToken(sdkKey,sdkSecret, topic, password, Key, userIdentity, role=1){
const iat = Math.round(new Date().getTime() / 1000);
const exp = iat + 60 * 60 * 2;
const oHeader = {alg: 'HS256', typ: ' JWT'};
const oPayload = {
app_key: sdkKey,
iat: iat,
exp: exp,
version: 1,
tpc: topic,
pwd: password,
user_identity: userIdentity,
key: Key,
role_type: role
};
const sHeader = JSON .stringify(oHeader);
const sPayload = JSON.stringify(oPayload);
const signature = KJUR.jws.JWS.sign('HS256', sHeader, sPayload, sdkSecret);
return signature;
}
const Token = generateToken(sdkKey, sdkSecret, topic, password, sessionKey);
console.log(Token);
}
(if i comment this out the rest of the node works just fine) so I copied it into the node and SyntaxError: Cannot use import statement outside a module
I search online and I found out I needed a package.json and {"type" : "module"} so I did just tha went to my terminal and wrote npm install I got the packages and added the little type thing and it didn't find the file I'm trying to run called queue.js, i figured I installed them in the wrong folder , so I erased them and installed them further back and only got 1 file this time package-lock.json the other one went on a vacation or something i went to the recicling bin and got it back and move it manually and still no queue.js file could be found so I'm kinda out of ideas

Related

Why does my Firebase/Postmark email despatch function fail to deploy?

Firebase deployment of my function fails with the following error:
"Function failed on loading user code. This is likely due to a bug in the user code."
Here's the function code:
const postmark = require("postmark");
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp()
exports.sendPostmarkEmailFunction = functions.firestore.
document('/postmarklogs/{documentId}').
onCreate((snapShot, context) => {
var serverToken = "_my_client_key_";
var client = new postmark.ServerClient(serverToken);
try {
client.sendEmail({
"From": "_my_depatch_address_",
"To": "_my_receipt_address_",
"Subject": snapShot.data().subject,
"HtmlBody": snapShot.data().message
});
return true;
} catch (error) {
console.log("Error : " + error.ErrorCode + " : " + error.Message);
return false;
}
});
This code works just fine in the Firebase emulator. As far as I can see, the deployment issue is triggered specifically by the const postmark = require("postmark"); line. If I comment this out, the function deploys - but then of course it doesn't work!
Advice would be greatly appreciated.
Postmark needs to be installed in the project's 'functions' folder. I'd installed it into the body of the project and so Postmark was missing from the 'functions/package.json' file that guides deployment's build stage. The 'functions' folder created by firebase init functions is like a project within a project and needs to be treated as such.
I got onto the problem from the deployment "build" logs
Once Postmark had been installed in the 'functions' folder my sendPostmarkEmailFunction function worked perfectly.
In passing, unless you already know this, the Postmark API token really needs to be squirreled securely away in the Firebase environment variable store. Also, while you might be tempted to use an https.onRequest trigger rather than the onCreate() used here, you might like to know that this is likely to land you in endless CORS issues when used with Postmark.

getting a parse error and cannot find eslint file

I've realized that you can't send messages directly from the client with the FCM v1 API so now I'm using node.js and I wan't to deploy this cloud function, but I am getting a parse error like so:
This is my function:
const functions = require("firebase-functions");
const admin = require("firebase-admin");
const { event } = require("firebase-functions/lib/providers/analytics");
admin.initializeApp(functions.config().firebase);
exports.sendNotificationsToTopic =
functions.firestore.document("school_users/{uid}/events/{docID}").onWrite(async (event) => {
let docID = event.after.id;
let schoolID = event.after.get("school_id")
let title = "New Event!!"
let notificationBody = "A new event has been added to the dashboard!!"
var message = {
notification: {
title: title,
body: notificationBody,
},
topic: schoolID,
};
let response = await admin.messaging().sendToTopic(message);
console.log(response);
});
I did some research and found people were getting similar errors with their projects, and answers were saying to update the version of eslint so it picks up on the shorthand syntax, I can't figure out where to find the eslint file to update the version. Does anybody know where I can find this file?
All I needed to do was show my hidden files in my functions directory. Once I seen the .eslintrc.js file, I simply removed a part of a value from the "eslint" key, and the function deployed perfectly fine.

How do I generate the correct TOTP with Node with correct Headers and SHA512 hashed Token?

A recent school project I was assigned has a coding challenge we have to complete. The challenge has multiple parts, and the final part is uploading to a private GitHub repo and submitting a completion request by making a POST request under certain conditions.
I have successfully completed the other parts of the challenge and am stuck on submitting the request. The submission has to follow these rules:
Build your solution request
First, construct a JSON string like below:
{
"github_url": "https://github.com/YOUR_ACCOUNT/GITHUB_REPOSITORY",
"contact_email": "YOUR_EMAIL"
}
Fill in your email address for YOUR_EMAIL, and the private Github repository with your solution in YOUR_ACCOUNT/GITHUB_REPOSITORY.
Then, make an HTTP POST request to the following URL with the JSON string as the body part.
CHALLENGE_URL
Content type
The Content-Type: of the request must be application/json.
Authorization
The URL is protected by HTTP Basic Authentication, which is explained on Chapter 2 of RFC2617, so you have to provide an Authorization: header field in your POST request.
For the userid of HTTP Basic Authentication, use the same email address you put in the JSON string.
For the password , provide a 10-digit time-based one time password conforming to RFC6238
TOTP.
Authorization password
For generating the TOTP password, you will need to use the following setup:
You have to generate a correct TOTP password according to RFC6238
TOTP's Time Step X is 30 seconds. T0 is 0.
Use HMAC-SHA-512 for the hash function, instead of the default HMAC-SHA-1.
Token shared secret is the userid followed by ASCII string value "APICHALLENGE" (not including double quotations).
Shared secret examples
For example, if the userid is "email#example.com", the token shared secret is "email#example.comAPICHALLENGE" (without quotes).
If your POST request succeeds, the server returns HTTP status code 200 .
I have tried to follow this outline very carefully, and testing my work in different ways. However, it seems I can't get it right. We are supposed to make the request from a Node server backend. This is what I have done so far. I created a new npm project with npm init and installed the dependencies you will see in the code below:
const axios = require('axios');
const base64 = require('base-64');
const utf8 = require('utf8');
const { totp } = require('otplib');
const reqJSON =
{
github_url: GITHUB_URL,
contact_email: MY_EMAIL
}
const stringData = JSON.stringify(reqJSON);
const URL = CHALLENGE_URL;
const sharedSecret = reqJSON.contact_email + "APICHALLENGE";
totp.options = { digits: 10, algorithm: "sha512" }
const myTotp = totp.generate(sharedSecret);
const isValid = totp.check(myTotp, sharedSecret);
console.log("Token Info:", {myTotp, isValid});
const authStringUTF = reqJSON.contact_email + ":" + myTotp;
const bytes = utf8.encode(authStringUTF);
const encoded = base64.encode(bytes);
const createReq = async () =>
{
try
{
// set the headers
const config = {
headers: {
'Content-Type': 'application/json',
"Authorization": "Basic " + encoded
}
};
console.log("Making req", {URL, reqJSON, config});
const res = await axios.post(URL, stringData, config);
console.log(res.data);
}
catch (err)
{
console.error(err.response.data);
}
};
createReq();
As far as I understand, I'm not sure where I'm making a mistake. I have tried to be very careful in my understanding of the requirements. I have briefly looked into all of the documents the challenge outlines, and gathered the necessary requirements needed to correctly generate a TOTP under the given conditions.
I have found the npm package otplib can satisfy these requirements with the options I have passed in.
However, my solution is incorrect. When I try to submit my solution, I get the error message, "Invalid token, wrong code". Can someone please help me see what I'm doing wrong?
I really don't want all my hard work to be for nothing, as this was a lengthy project.
Thank you so much in advance for your time and help on this. I am very grateful.
The Readme of the package otplib states:
// TOTP defaults
{
// ...includes all HOTP defaults
createHmacKey: totpCreateHmacKey,
epoch: Date.now(),
step: 30,
window: 0,
}
So the default value for epoch (T0) is Date.now() which is the RFC standard. The task description defines that T0 is 0.
You need to change the default value for epoch to 0:
totp.options = { digits: 10, algorithm: "sha512", epoch: 0 }

Changing Wit.ai Default Max Steps

For some reason I'm unable to increase the default max steps for my chat bot.
It seems that this number is now defined in lib/config.js rather than lib/wit.js like it used to be. No matter what I change the DEFAULT_MAX_STEPS constant to in my config file my bot seems to hit the same limit (5) before throwing the 'Max steps reached, stopping' error in my log when I want the bot to send a few responses/execute a few actions in a row.
I've tried linking the file the same way the example project seems to link to the wit.js and log.js files in the module via node-wit/lib
The config file:
How I've tried to link it to my index.js file:
I'm assuming I'm not referencing the config.js file properly...
I'll write example steps of using node-wit
1) create and app folder, go to it and run: npm init
2) run npm i --save node-wit
3) app.js :
const {Wit, log, config} = require('node-wit');
const client = new Wit({accessToken: 'MY_TOKEN'});
4) from documentation:
runActions
A higher-level method to the Wit converse API. runActions resets the
last turn on new messages and errors.
Takes the following parameters:
sessionId - a unique identifier describing the user session
message - the text received from the user
context - the object representing the session state
maxSteps - (optional) the maximum number of actions to execute (defaults to 5)
so I'll add MAX_STEPS to example there:
const MAX_STEPS = 25;
const sessionId = 'some-session-id';
const context0 = {};
client
.runActions(sessionId, 'events nearby', context0, MAX_STEPS)
.then((context1) => {
return client.runActions(sessionId, 'how about in London?', context1, MAX_STEPS - 1);
})
.then((context2) => {
console.log('The session state is now: ' + JSON.stringify(context2));
})
.catch((e) => {
console.log('Oops! Got an error: ' + e);
});

APN-Node: Error when loading PEM file

I am trying to get apn-node to push to my devices. The server is hosted on Heroku, so I do not want to commit the file. Also, I do not want to fetch it from a remote server but instead put it in an environment variable.
I already tried the following (source):
I created and downloaded the certificate from Apple and now have it in my Keychain. I exported it as a *.p12 file and converted it with openssl pkcs12 -in dev.p12 -out dev.pem -nodes into a *.pem file.
To set the environment variable, I did export APN_CERT="$(cat dev.pem)". When I print it out in my application it shows the certificate perfectly fine.
However, when I actually send a notification (and node-apn opens the connection) it throws an [Error: wrong tag].
This error is emitted by the crypto module:
apn Raising error: +4ms [Error: wrong tag] undefined undefined
apn Error occurred with trace: +1ms Error: wrong tag
at Object.exports.createCredentials (crypto.js:176:17)
at Object.exports.connect (tls.js:1344:27)
at apnSocketLegacy
The module also throws a APN transmission error: moduleInitialisationFailed (Code: 513).
I was unable to find any useful information other than that this could be related to the crypto module itself of node itself. That's why I suspect I did something wrong when creating the certificate but thankful for any guiding advice.
I found this guide for apns-sharp which actually described how to generate a valid .p12 file.
Still, writing it into an environment variable did not work. My code for reading it is: new Buffer(certString, 'binary') but I thought it still was not supplied in a correct format.
The solution for me was to actually read the buffer directly from a file via fs.readFileSync.
To get the env variable to work you could encode the file via cat cert.p12 | base64 and load it as such with new Buffer(certString, 'base64'). This finally worked for me.
The preference here would be to use an encrypted p12 stored alongside the applciation and specify a passphrase which you set via an environment variable.
I was unable to replicate your problem using the following script
var apn = require("apn");
var token = "<token>; // iPad
var service = new apn.connection({
cert: process.env.APN_CERT, key: process.env.APN_KEY
});
service.on("connected", function() {
console.log("Connected");
});
service.on("error", function(err) {
console.log("Standard error", err);
});
function pushNotification() {
var note = new apn.notification().setAlertText("Hello");
service.pushNotification(note, token);
service.shutdown();
}
pushNotification();
Run with:
$ export APN_CERT=$(cat certificates/cert.pem)
$ export APN_KEY=$(cat certificates/key.pem)
$ node apn-env.js
The error you are seeing "wrong tag" is from OpenSSL and suggests a parsing error of the data contained within the certificate data itself rather than the data being loaded incorrectly from the env. Loading PEM files from environment variables works correctly
var apn = require("apn");
var deviceToken = "device token";
var service = new apn.Provider({
cert: '.path to /cert.pem', key:'pat to ./key.pem'
});
var note = new apn.Notification();
note.expiry = Math.floor(Date.now() / 1000) + 60; // Expires 1 minute from now.
note.badge = 3;
note.sound = "ping.aiff";
note.alert = " You have a new message";
note.payload = {'messageFrom': 'Rahul test apn'};
note.topic = "(Bundle_id).voip";
note.priority = 10;
note.pushType = "alert";
service.send(note, deviceToken).then( (err,result) => {
if(err) return console.log(JSON.stringify(err));
return console.log(JSON.stringify(result))
});
Load the pem files and run with the tokens

Resources