ERR! parse-server-push-adapter APNS cannot find vaild connection - node.js

Whenever i use the following cloud code to send a push notification on Parse Server 2.2.24
Parse.Push.send({
where: query,
data: {
alert: "You have a new comment on " + rift.get("title")
}
}, { useMasterKey: true }).then(() => {
console.log('Push ok');
}, (e) => {
console.log('Push error', e);
});
I get the following logs with verbose = 1 set on heroku.
2016-11-06T05:08:06.783331+00:00 app[web.1]: verbose: RESPONSE from [POST] /api/1/push: {
2016-11-06T05:08:06.783333+00:00 app[web.1]: "headers": {
2016-11-06T05:08:06.783334+00:00 app[web.1]: "X-Parse-Push-Status-Id": "NbZCxyCOgc"
2016-11-06T05:08:06.783334+00:00 app[web.1]: },
2016-11-06T05:08:06.783335+00:00 app[web.1]: "response": {
2016-11-06T05:08:06.783336+00:00 app[web.1]: "result": true
2016-11-06T05:08:06.783336+00:00 app[web.1]: }
2016-11-06T05:08:06.783337+00:00 app[web.1]: } X-Parse-Push-Status-Id=NbZCxyCOgc, result=true
2016-11-06T05:08:06.787076+00:00 app[web.1]: Push ok
2016-11-06T05:08:06.788233+00:00 app[web.1]: verbose: sending push to 1 installations
2016-11-06T05:08:06.789569+00:00 app[web.1]: verb parse-server-push-adapter APNS APNS Connection 0 Notification transmitted to 443d4d770217648350c5c7cd7bb22d2da77223e23c06f3eb016b2e2ca76d6202
2016-11-06T05:08:06.790600+00:00 app[web.1]: verbose: sent push! 1 success, 0 failures
2016-11-06T05:08:06.867209+00:00 app[web.1]: ERR! parse-server-push-adapter APNS cannot find vaild connection for 443d4d770217648350c5c7cd7bb22d2da77223e23c06f3eb016b2e2ca76d6202
2016-11-06T05:08:06.868965+00:00 app[web.1]: verb parse-server-push-adapter APNS APNS Connection 0 Disconnected
2016-11-06T05:08:06.928135+00:00 app[web.1]: verb parse-server-push-adapter APNS APNS Connection 0 Connected
So it says it was sent successfully (we recieve NO notification to the device) and we get an ERR! parse-server.... for every device token registered from a valid device on a app distributed on Apple's TestFlight Application. I have read multiple posts regarding ways to fix this and have tried everything out there but nothing works. IF anyone has any insight on why this could be happening please let me know! I will be ever grateful
our index.js has the following config setup... we have checked the production cert and even rejected all our certs and generated new ones just to be sure.
push: {
ios: {
pfx: 'cert-prod.p12',
bundleId: 'a.bundle.id'
}
}

I had this issue recently. Did you make sure the path to the pfx file is a complete path? I used the path module to remedy this:
var path = require('path');
opts.push.ios = {
// The filename of private key and certificate in PFX
pfx: path.join(__dirname, env.IOS_PUSH_PFX),
bundleId: env.IOS_BUNDLE_ID
}
Reference from https://github.com/ParsePlatform/parse-server/issues/3025#issuecomment-258957541

Related

Node: Cannot set headers after they are sent to the client

I did some research on the following error:
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
I understood the idea and what's causing it but I am not sure how to fix it for my controller code:
exports.isServerOnline = (req, res, next) => {
const sock = new net.Socket();
sock.setTimeout(2500);
sock.on('connect', function () {
sock.destroy();
return res.json({
"server": "online"
});
}).on('error', function (e) {
return res.json({
"server": "offline"
});
}).on('timeout', function (e) {
return res.json({
"server": "offline"
});
}).connect(LS_PORT, LS_HOST);
}
I'm using socket to check if a remote host is up or down. Here is my client code (Vue.js):
created() {
this.getServerStatus();
},
methods: {
getServerStatus() {
axios
.get(`${process.env.VUE_APP_BACKEND_URL}/server/status`)
.then(response => {
if (response.data.server === "online") {
// no interesting code here
} else {
// no interesting code here
}
/* eslint-disable no-console */
})
.catch(error => {
console.log(error);
});
}
}
Complete error stack trace:
2020-07-02T07:40:47.743193+00:00 app[web.1]: _http_outgoing.js:518
2020-07-02T07:40:47.743201+00:00 app[web.1]: throw new ERR_HTTP_HEADERS_SENT('set');
2020-07-02T07:40:47.743202+00:00 app[web.1]: ^
2020-07-02T07:40:47.743202+00:00 app[web.1]:
2020-07-02T07:40:47.743204+00:00 app[web.1]: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
2020-07-02T07:40:47.743205+00:00 app[web.1]: at ServerResponse.setHeader (_http_outgoing.js:518:11)
2020-07-02T07:40:47.743206+00:00 app[web.1]: at ServerResponse.header (/app/node_modules/express/lib/response.js:771:10)
2020-07-02T07:40:47.743206+00:00 app[web.1]: at ServerResponse.json (/app/node_modules/express/lib/response.js:264:10)
2020-07-02T07:40:47.743206+00:00 app[web.1]: at Socket.<anonymous> (/app/src/controllers/status.js:15:20)
2020-07-02T07:40:47.743207+00:00 app[web.1]: at Socket.emit (events.js:315:20)
2020-07-02T07:40:47.743207+00:00 app[web.1]: at emitErrorNT (internal/streams/destroy.js:92:8)
2020-07-02T07:40:47.743208+00:00 app[web.1]: at emitErrorAndCloseNT (internal/streams/destroy.js:60:3)
2020-07-02T07:40:47.743208+00:00 app[web.1]: at processTicksAndRejections (internal/process/task_queues.js:84:21) {
2020-07-02T07:40:47.743209+00:00 app[web.1]: code: 'ERR_HTTP_HEADERS_SENT'
2020-07-02T07:40:47.743209+00:00 app[web.1]: }
I would highly appreciate if someone could point me on the right track.
I don't think that approach is correct mate. You are trying to create a socket inside http endpoint, that will not work. Here's gist I found that demonstrates using NodeJS Socket.
https://gist.github.com/tedmiston/5935757
I'll recommend using into something like Socket.io. They have good amount of documentation to get off the ground.

Connect Node.js BOT to MS Azure SQL database

I have a working MS Teams bot written in Node.js. The bot asks a series of questions and currently displays the responses at the end by accessing the session variables. All well and good.
Now I am attempting to store the session variables in a MS Azure SQL DB. The DB is correctly set up in Azure as I can access and write data to it in SSMS. But I believe I am probably connecting incorrectly to the DB in my bot code. The bot code I am using is pulled from:
connecting to SQL using Node.js
That code makes sense to me. But how do I use that code in my bot? Here is what I have attempted thus far...
Currently I am using the local memory MemoryBotStorage() and setting to that.
var inMemoryStorage = new builder.MemoryBotStorage();
.set('storage', inMemoryStorage)
In another Microsoft article dealing with the Azure Cosmos DB it states "4.Specify that you want to use your custom database instead of the in-memory storage." So from this I deduce that I hafta add my instantiated sql db to the .set('storage', DB Goes Here) but my attempts have failed and I am not sure if I am even correct?
So my question is how do I correctly access the Azure sql server DB form my bot code - and is the link I provided even the correct way?
Thank you
Note - This code sample worked for me - I was able to connect and query my Azure DB - but it is only DB code and does not take into consideration bot code.
EDIT - Code:
const builder = require('botbuilder');
const builderTeams = require('botbuilder-teams');
const restify = require('restify');
const connector = new builderTeams.TeamsChatConnector(
{
appId: "My app ID,
appPassword: "My App PW",
}
);
var inMemoryStorage = new builder.MemoryBotStorage();
const bot = new builder.UniversalBot(connector, [
function (session) {
session.send("Welcome.");
builder.Prompts.text(session, "Question1?");
},
function (session, results) {
session.dialogData.question1 = results.response;
builder.Prompts.text(session, "Question2?");
},
function (session, results) {
session.dialogData.Question2 = results.response;
builder.Prompts.text(session, "Question3?");
},
function (session, results) {
session.dialogData.Question3 = results.response;
// Begin DB
var Connection = require('tedious').Connection;
var config = {
userName: 'myusername',
password: 'mypw',
server: 'myserver.database.windows.net',
// If you are on Azure SQL Database, you need these next options.
options: { encrypt: true, database: 'mydb' }
};
var connection = new Connection(config);
connection.on('connect', function (err) {
// If no error, then good to proceed.
console.log("Connected");
executeStatement1();
});
var Request = require('tedious').Request
var TYPES = require('tedious').TYPES;
function executeStatement1() {
request = new Request("INSERT my (Username, Question1, Question2, Question3, StatusDate) VALUES (#Username, #Question1, #Question2, #Question3, CURRENT_TIMESTAMP);", function (err) {
if (err) {
console.log(err);
}
});
request.addParameter('Username', TYPES.NVarChar, session.userData.userName);
request.addParameter('Question1', TYPES.NVarChar, session.dialogData.Question1);
request.addParameter('Question2', TYPES.NVarChar, session.dialogData.Question2);
request.addParameter('Question3', TYPES.NVarChar, session.dialogData.Question3);
request.on('row', function (columns) {
columns.forEach(function (column) {
if (column.value === null) {
console.log('NULL');
} else {
console.log("ID of inserted item is " + column.value);
}
});
});
connection.execSql(request);
// End DB
// Process request and display details
session.endDialog();
}
]).set('storage', inMemoryStorage)
const server = restify.createServer();
server.post('api/messages', connector.listen());
server.listen(portnumber)
Error when running with npm start:
npm start
> simplebot#1.0.0 start C:\Developer\dailyStatus
> node index.js
C:\Developer\dailyStatus\index.js:81
]).set('storage', inMemoryStorage)
^
SyntaxError: Unexpected token ]
at createScript (vm.js:80:10)
at Object.runInThisContext (vm.js:139:10)
at Module._compile (module.js:616:28)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)
at Function.Module.runMain (module.js:693:10)
at startup (bootstrap_node.js:188:16)
at bootstrap_node.js:609:3
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! simplebot#1.0.0 start: `node index.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the simplebot#1.0.0 start script.
npm ERR! This is probably not a problem with npm. There is likely...
npm ERR! A complete log of this run can be found in:
npm ERR! C: etc.
FINAL
I was able to able to get this working with this tutorial. Thanks also to Marc LeFleur.
You have several typos. For example, you're missing the closing " on appId:
const connector = new builderTeams.TeamsChatConnector(
{
appId: "My app ID",
appPassword: "My App PW",
}
);
You also can't declare the function executeStatement1() {...} function within the your IDialogWaterfallStep function. This needs to live outside the constructor and called from the IDialogWaterfallStep.

Connect ETIMEDOUT on Azure App Service when calling HTTP endpoint without specify maxSockets

I have some timeout problems when calling multiple times an HTTP[S] endpoint from node.js inside an Azure App Service.
Here my code to demostrate the problem.
const fetch = require('node-fetch');
const https = require("https");
const agent = new https.Agent();
function doWork() {
const works = [];
for (let i = 0; i < 50; i++) {
const wk = fetch('https://www.microsoft.com/robots.txt', { agent })
.then(res => res.text())
.then(body => console.log("OK", i))
.catch((err) => console.log("ERROR", i, err));
works.push(wk);
}
return Promise.all(works);
}
doWork()
.catch((err) => {
console.log(err);
});
When running this app 3 or 4 times inside a Standard Medium App Service (I'm running it using Kudu but I discover this error inside a standard web app) I get the following error for every requests:
{ FetchError: request to https://www.microsoft.com/robots.txt failed, reason: connect ETIMEDOUT 23.206.106.109:443
at ClientRequest.<anonymous> (D:\home\site\test\test-forge-calls\node_modules\node-fetch\lib\index.js:1393:11)
at emitOne (events.js:96:13)
at ClientRequest.emit (events.js:188:7)
at TLSSocket.socketErrorListener (_http_client.js:310:9)
at emitOne (events.js:96:13)
at TLSSocket.emit (events.js:188:7)
at emitErrorNT (net.js:1276:8)
at _combinedTickCallback (internal/process/next_tick.js:74:11)
at process._tickCallback (internal/process/next_tick.js:98:9)
message: 'request to https://www.microsoft.com/robots.txt failed, reason: connect ETIMEDOUT 23.206.106.109:443',
type: 'system',
errno: 'ETIMEDOUT',
code: 'ETIMEDOUT' }
After some minutes (5/6) without performing requests the above code works again.
I have tried with both node-fetch (https://www.npmjs.com/package/node-fetch) and request (https://www.npmjs.com/package/request). Same results.
The same problem occurs if I not specify an agent and is not related to the destination endpoint, I have tried with many different endpoints (private or public).
According to Microsoft Best Practices node.js applications should use a keep alive agent with the following configuration:
var keepaliveAgent = new Agent({
maxSockets: 40,
maxFreeSockets: 10,
timeout: 60000,
keepAliveTimeout: 300000
});
In fact when creating the agent with:
const agent = new https.Agent({ maxSockets: 100 });
everything works as expected.
Is this behavior expected? What is the best practice for node.js? It is fine to always specify an agent with maxSockets also outside Azure?
UPDATE:
The other strange behavior is that if I run the above code using node index 3 or 4 times I expect that connections are closed when node process exit, but seems that the connections remain open for some minutes. This can be the effect of the TIME_WAIT state?

HTTP 400: Bad Request error in ADFS HTTPS Request

I am writing a Node.js app and am trying to integrate an ADFS server to get authentication. For that, I am using wstrust-client, and using the ADFS Server URL as my endpoint. My code so far is:
app.get('/login', function(req, res) {
trustClient.requestSecurityToken({
scope: 'https://mycompany.com',
username: "username",
password: "password",
endpoint: 'https://[adfs server]/adfs/services/trust/13/usernamemixed'
}, function (rstr) {
// Access the token
var rawToken = rstr.token;
console.log('raw: ' + rawToken);
}, function(error) {
console.log(error)
});
});
I am requesting https through wstrust-client
My code in wstrustclient.js so far is:
var req = https.request(post_options, function(res) {
res.setEncoding('utf8');
res.on('data', function(data) {
console.log("Entered res")
var rstr = {
token: parseRstr(data),
response: res,
};
callback(rstr);
});
});
req.write(message);
req.end();
req.on('error', function (e) {
console.log("******************************");
console.log(e);
console.log("******************************");
However, it is throwing this error:
******************************
{ [Error: UNABLE_TO_VERIFY_LEAF_SIGNATURE]
stack: 'Error: UNABLE_TO_VERIFY_LEAF_SIGNATURE\n
at SecurePair.<anonymous> (tls.js:1253:32)\n
at SecurePair.EventEmitter.emit (events.js:91:17)\n
at SecurePair.maybeInitFinished (tls.js:865:10)\n
at CleartextStream.read [as _read] (tls.js:416:15)\n
at CleartextStream.Readable.read (_stream_readable.js:231:10)\n
at EncryptedStream.write [as _write] (tls.js:329:25)\n
at EncryptedStream.Writable.write (_stream_writable.js:176:8)\n
at write (_stream_readable.js:496:24)\n
at flow (_stream_readable.js:506:7)\n
at Socket.pipeOnReadable (_stream_readable.js:538:5)' }
******************************
******************************
{ [Error: read ECONNRESET]
stack: 'Error: read ECONNRESET\n
at errnoException (net.js:846:11)\n
at TCP.onread (net.js:508:19)',
code: 'ECONNRESET',
errno: 'ECONNRESET',
syscall: 'read' }
******************************
When I browse the same endpoint URL in a browser, it throws HTTP 400: Bad Request
I know that it's an SSL type error, and that it's from the server-side. However, I don't know why it's throwing the error and what might be wrong server-side. What do I need to change?
As per the OpenSSL manual here:
21 X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: unable to verify the
first certificate no signatures could be verified because the chain
contains only one certificate and it is not self signed.
With that in mind, it seems that you may need to sign your certificate.

Node.js and Sendgrid mailer error on res.end

I'm a bit new to node. I'm using express and the sendgrid api to send an email (collected REST-fully). After sendgrid succeeds or fails, I want to respond with a json object. Here's the sample case:
var SendGrid = require('sendgrid-nodejs').SendGrid;
var sendgrid = new SendGrid(user, key);
app.get('/LGP/:email', function (req, res){
sendgrid.send({
to: req.params.email,
from: 'me#example.com',
subject: 'Hello World',
text: 'This email sent through SendGrid'
}, function(success, message) {
if (!success) {
console.log(message);
} else {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.write(JSON.stringify({ result: 'success' }));
res.end(); //error occurs: "Can't use mutable header APIs after sent."
}
}
);
});
On my local server (using foreman), everything works fine. But when I push it to heroku, it gives me this stack trace:
2013-02-27T22:12:46+00:00 app[web.1]: http.js:543
2013-02-27T22:12:46+00:00 app[web.1]: throw new Error("Can't use mutable header APIs after sent.");
2013-02-27T22:12:46+00:00 app[web.1]: ^
2013-02-27T22:12:46+00:00 app[web.1]: Error: Can't use mutable header APIs after sent.
2013-02-27T22:12:46+00:00 app[web.1]: at ServerResponse.getHeader (http.js:543:11)
2013-02-27T22:12:46+00:00 app[web.1]: at /app/node_modules/express/node_modules/connect/lib/middleware/logger.js:229:26
2013-02-27T22:12:46+00:00 app[web.1]: at ServerResponse.<anonymous> (/app/node_modules/express/node_modules/connect/lib/middleware/logger.js:149:20)
2013-02-27T22:12:46+00:00 app[web.1]: at /app/app.js:60:13
2013-02-27T22:12:46+00:00 app[web.1]: at IncomingMessage.<anonymous> (/app/node_modules/sendgrid/lib/sendgrid.js:74:9)
2013-02-27T22:12:46+00:00 app[web.1]: at IncomingMessage.emit (events.js:81:20)
2013-02-27T22:12:46+00:00 app[web.1]: at HTTPParser.onMessageComplete (http.js:133:23)
2013-02-27T22:12:46+00:00 app[web.1]: at CleartextStream.ondata (http.js:1213:22)
2013-02-27T22:12:46+00:00 app[web.1]: at CleartextStream._push (tls.js:291:27)
2013-02-27T22:12:46+00:00 app[web.1]: at SecurePair._cycle (tls.js:565:20)
2013-02-27T22:12:48+00:00 heroku[web.1]: Process exited with status 1
2013-02-27T22:12:48+00:00 heroku[web.1]: State changed from up to crashed
/app/app.js:60:13 refers to the line with "res.end()". What am I doing wrong?
To maximize your chances of your app behaving the same locally and on heroku, you should make sure you specify specific versions for all modules and avoid using "*" for the main dependencies.
Should also should specify the node version in package.json:
"engines": {
"node": "0.8.20"
}
(use whatever version is appropriate).

Resources