cannot connect to Gmail using imap - node.js

I am trying to view the contents of the emails received in my gmail inbox using imap but when I'm running the code, I am getting the following error.
ERROR
Error [ERR_STREAM_DESTROYED]: Cannot call write after a stream was destroyed
at doWrite (_stream_writable.js:427:19)
at clearBuffer (_stream_writable.js:551:7)
at Socket.Writable.uncork (_stream_writable.js:325:7)
at JSStreamSocket.doWrite (internal/js_stream_socket.js:162:17)
at JSStream.onwrite (internal/js_stream_socket.js:20:57)
at Socket.ondata (internal/js_stream_socket.js:64:22)
at Socket.emit (events.js:210:5)
at addChunk (_stream_readable.js:309:12)
at readableAddChunk (_stream_readable.js:290:11)
at Socket.Readable.push (_stream_readable.js:224:10) {
code: 'ERR_STREAM_DESTROYED',
source: 'socket'
}
events.js:187
throw er; // Unhandled 'error' event
^
Error: self signed certificate
at TLSSocket.onConnectSecure (_tls_wrap.js:1321:34)
at TLSSocket.emit (events.js:210:5)
at TLSSocket._finishInit (_tls_wrap.js:794:8)
at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:608:12)
at Socket.ondata (internal/js_stream_socket.js:64:22)
at Socket.emit (events.js:210:5)
at addChunk (_stream_readable.js:309:12)
at readableAddChunk (_stream_readable.js:290:11)
at Socket.Readable.push (_stream_readable.js:224:10)
at TCP.onStreamRead (internal/stream_base_commons.js:182:23)
Emitted 'error' event on Connection instance at:
at TLSSocket._onError (C:\Users\debdutgoswami\node_modules\imap\lib\Connection.js:151:10)
at TLSSocket.emit (events.js:210:5)
at emitErrorNT (internal/streams/destroy.js:92:8)
at emitErrorAndCloseNT (internal/streams/destroy.js:60:3)
at processTicksAndRejections (internal/process/task_queues.js:80:21) {
code: 'DEPTH_ZERO_SELF_SIGNED_CERT',
source: 'socket'
}
CODE
var Imap = require('imap'),
inspect = require('util').inspect;
var imap = new Imap({
user: 'mygmailname#gmail.com',
password: 'mygmailpassword',
host: 'imap.gmail.com',
port: 993,
tls: true
});
function openInbox(cb) {
imap.openBox('INBOX', true, cb);
}
imap.once('ready', function() {
openInbox(function(err, box) {
if (err) throw err;
var f = imap.seq.fetch('1:3', {
bodies: 'HEADER.FIELDS (FROM TO SUBJECT DATE)',
struct: true
});
f.on('message', function(msg, seqno) {
console.log('Message #%d', seqno);
var prefix = '(#' + seqno + ') ';
msg.on('body', function(stream, info) {
var buffer = '';
stream.on('data', function(chunk) {
buffer += chunk.toString('utf8');
});
stream.once('end', function() {
console.log(prefix + 'Parsed header: %s', inspect(Imap.parseHeader(buffer)));
});
});
msg.once('attributes', function(attrs) {
console.log(prefix + 'Attributes: %s', inspect(attrs, false, 8));
});
msg.once('end', function() {
console.log(prefix + 'Finished');
});
});
f.once('error', function(err) {
console.log('Fetch error: ' + err);
});
f.once('end', function() {
console.log('Done fetching all messages!');
imap.end();
});
});
});
imap.once('error', function(err) {
console.log(err);
});
imap.once('end', function() {
console.log('Connection ended');
});
imap.connect();

I had the same issue for quite a long while... The real problem here is that, there is a complaint for self signed certificate and I got a way out. Just under your tls: true which is the self signed certificate, inside your var imap= new imap({ //inside here }) add a line: tlsOptions: { rejectUnauthorized: false } And you're good to go, the rest of the code is correct

You may also have to allow "less secure apps" on the account, see https://myaccount.google.com/lesssecureapps

I also have an issue and I just discovered that Google had disable "less secure apps" since june 2022.
Simple user/password login to GMAIL has been disabled for good.

I had same issue and resovled it by:
Google setting:
Enable two factor authtentification
generate application password
Gmail settings:
Enable IMAP in gmail settings
names could be little bit different as I was not using english version of google so the "names" are my translation ...

Related

Download from FTP with Node JS

I need help downloading more than one file from a remote FTP using Node js, the code is the following.
const FTPClient = require('ftp');
let ftp_client = new FTPClient();
const fs = require("fs");
let ftpConfig = {
host: "remoteHost",
port: 21,
user: 'username',
password: 'password',
}
//create a connection to ftp server
ftp_client.connect(ftpConfig);
ftp_client.on('ready', function() {
ftp_client.get('/file1.csv', function(err, stream) {
if (err) throw err;
//stream.once('close', function() { ftp_client.end(); });
stream.pipe(fs.createWriteStream('file1.csv'));
});
ftp_client.get('/dir/file2.dat', function(err, stream) {
if (err) throw err;
//stream.once('close', function() { ftp_client.end(); });
stream.pipe(fs.createWriteStream('file2.dat'));
});
ftp_client.get('/dir/file3.dat', function(err, stream) {
if (err) throw err;
stream.once('close', function() { ftp_client.end(); });
stream.pipe(fs.createWriteStream('file3.dat'));
});
});
And the error
Error: Unable to make data connection
at Socket.<anonymous> (C:\Proyectos\descargar_file\node_modules\ftp\lib\connection.js:935:10)
at Object.onceWrapper (events.js:421:28)
at Socket.emit (events.js:327:22)
at Object.cb (C:\Proyectos\descargar_file\node_modules\ftp\lib\connection.js:575:18)
at Parser.<anonymous> (C:\Proyectos\descargar_file\node_modules\ftp\lib\connection.js:117:20)
at Parser.emit (events.js:315:20)
at Parser._write (C:\Proyectos\descargar_file\node_modules\ftp\lib\parser.js:59:10)
at doWrite (_stream_writable.js:403:12)
at writeOrBuffer (_stream_writable.js:387:5)
at Parser.Writable.write (_stream_writable.js:318:11)
It is already downloading the 3 files, but also showing that error, so how can I correct this to do it in a safer way?
I also would like to add a console log while the process is downloading each file.
Thanks!

Nodemail x Node.js: Failed auth although tested with success

I am having a problem with a nodemailer Firebase Function supposed to send emails through an SMTP transporter.
It is strange because I am testing my connection with success using:
// check server readiness
const serverReady = await new Promise<boolean>(resolve => {
transporter.verify( (err: any, succ: any) => {
if (err) {
console.log(err);
resolve(false);
} else {
console.log('Server is ready to take our messages');
resolve(true);
}
});
})
Which prints Server is ready to take our messages.
Then after setting up my envelope andsending it with th .sendMail method I get this error:
Unhandled error { Error: Mail command failed: 530 5.5.1 Authentication Required.
at SMTPConnection._formatError (/srv/node_modules/nodemailer/lib/smtp-connection/index.js:777:19)
at SMTPConnection._actionMAIL (/srv/node_modules/nodemailer/lib/smtp-connection/index.js:1546:34)
at SMTPConnection._responseActions.push.str (/srv/node_modules/nodemailer/lib/smtp-connection/index.js:1028:18)
at SMTPConnection._processResponse (/srv/node_modules/nodemailer/lib/smtp-connection/index.js:935:20)
at SMTPConnection._onData (/srv/node_modules/nodemailer/lib/smtp-connection/index.js:742:14)
at TLSSocket.SMTPConnection._onSocketData.chunk (/srv/node_modules/nodemailer/lib/smtp-connection/index.js:195:44)
at emitOne (events.js:116:13)
at TLSSocket.emit (events.js:211:7)
at addChunk (_stream_readable.js:263:12)
at readableAddChunk (_stream_readable.js:250:11)
at TLSSocket.Readable.push (_stream_readable.js:208:10)
at TLSWrap.onread (net.js:601:20)
code: 'EENVELOPE',
response: '530 5.5.1 Authentication Required.',
responseCode: 530,
command: 'MAIL FROM' }
The error is pretty clear: Failed Auth but it's strange since the test worked earlier!
Connection parameters are:
// options to connect to server
const smtpOptions = {
host: 'smtp.zoho.eu',
port: 465,
secure: true,
auth: {
user: functions.config().nodemailer.user,
pass: functions.config().nodemailer.pass
}
};
// transporter for sending the email
const transporter = nodeMail.createTransport( smtpOptions );
Thank you guys in advance
transporter.verify only tests the connection and authentication, it looks like the that you are not authorised to use the particular MAIL FROM address.

Howo to get IPP endpoint

I'm using the ipp npm module to send a print job from a google cloud function. I believe I have set up the printer correctly but I don't know how I'm supposed to know the exact uri for sending the print job.
The printer model is Brother MFC-L3770CDW
Here is how my settings look in the web view for the printer configuration.
And here is the function code.:
var ipp = require('ipp');
var PDFDocument = require('pdfkit');
var doc = new PDFDocument;
doc.text("Hello World");
var buffers = [];
doc.on('data', buffers.push.bind(buffers));
doc.on('end', function () {
var printer = ipp.Printer("https://10.0.0.55:443");
var file = {
"operation-attributes-tag":{
"requesting-user-name": "User",
"job-name": "Print Job",
"document-format": "application/pdf"
},
data: Buffer.concat(buffers)
};
printer.execute("Print-Job", file, function (err, res) {
if(err) {
console.log(err);
}
else{
console.log("Printed: "+res.statusCode);
}
});
console.log('executing');
});
doc.end();
console.log('finished executing');
I have tried various uris such as
https://10.0.0.55:631
https://10.0.0.55:443
https://10.0.0.55:631/ipp
https://10.0.0.55:631/ipp/printer
Sometimes I get an error like:
"Error: socket hang up
at TLSSocket.onHangUp (_tls_wrap.js:1148:19)
at Object.onceWrapper (events.js:313:30)
at emitNone (events.js:111:20)
at TLSSocket.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1064:12)
at _combinedTickCallback (internal/process/next_tick.js:139:11)
at process._tickCallback (internal/process/next_tick.js:181:9)
code: 'ECONNRESET',
path: null,
host: '10.0.0.55',
port: '631',
localAddress: undefined }"

Cloud Functions for Firebase Image download function Error

I am building a web application using Firebase and the new feature Cloud Functions for Firebase. I have created a function that takes a URL and downloads the image into a 64-bit encoded string as below using the node modules request and request-promise-native:
module.exports = {
downloadImageFromUrl: function (url) {
var options = {
method: 'GET',
uri: url,
resolveWithFullResponse: true,
simple: false,
family: 4
};
return rp.get(options)
.then(function (res) {
return "data:" + res.headers["content-type"] + ";base64," + new Buffer(res.body).toString('base64');
})
.catch(function (error) {
console.log("ERROR GETTING image", error);
return error;
});
}
};
The top function works perfectly running locally but once on firebase it gives the error:
RequestError: Error: getaddrinfo EAI_AGAIN lh6.googleusercontent.com:443
at new RequestError (/user_code/node_modules/request-promise/node_modules/request-promise-core/lib/errors.js:14:15)
at Request.plumbing.callback (/user_code/node_modules/request-promise/node_modules/request-promise-core/lib/plumbing.js:87:29)
at Request.RP$callback [as _callback] (/user_code/node_modules/request-promise/node_modules/request-promise-core/lib/plumbing.js:46:31)
at self.callback (/user_code/node_modules/request/request.js:188:22)
at emitOne (events.js:96:13)
at Request.emit (events.js:188:7)
at Request.onRequestError (/user_code/node_modules/request/request.js:884:8)
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 connectErrorNT (net.js:1020:8)
at _combinedTickCallback (internal/process/next_tick.js:74:11)
at process._tickDomainCallback (internal/process/next_tick.js:122:9)
I am calling the function in the firebase auth trigger when a user is created as below:
exports.createUser = functions.auth.user().onCreate(event => {
if (event.data.photoURL) {
utils.downloadImageFromUrl(event.data.photoURL)
.then(function(res){
console.log("User Photo", res);
})
.catch(function(error){
console.log("Error", error);
})
}
});
Any help would be greatly appreciated.
Not entirely sure yet if this is the answer, but after reading the documentation, I read their free plan which says you cannot make any out bound requests. So I guess getting an image from a Url counts as an outbound request. After I start paying for their service, I will come back to verify if this was the problem.

Host-based ssh authentication using nodejs

I have installed the ssh2 package for node but can not get the host based authentication working.
var Connection = require('./node_modules/bis-package/node_modules/ssh2');
var conn = new Connection();
conn.on('ready', function() {
conn.exec('cmviewcl -v -f line', function(err, stream) {
if (err) throw err;
stream.on('exit', function(code, signal) {
console.log('Stream :: exit :: code: ' + code + ', signal: ' + signal);
}).on('close', function() {
console.log('Stream :: close');
conn.end();
}).on('data', function(data) {
console.log('STDOUT: ' + data);
}).stderr.on('data', function(data) {
console.log('STDERR: ' + data);
});
});
}).connect({
host: 'server',
port: 22,
username: 'root'
});
I get the following error
Error: Authentication failure. Available authentication methods: publickey,gssapi-with-mic,password,hostbased
at Connection._tryNextAuth (/opt/bis/node/node_modules/bis-package/node_modules/ssh2/lib/Connection.js:1010:13)
at onUSERAUTH_FAILURE (/opt/bis/node/node_modules/bis-package/node_modules/ssh2/lib/Connection.js:2449:8)
at Parser.<anonymous> (/opt/bis/node/node_modules/bis-package/node_modules/ssh2/lib/Connection.js:141:5)
at Parser.emit (events.js:98:17)
at Parser.parsePacket (/opt/bis/node/node_modules/bis-package/node_modules/ssh2/lib/Parser.js:488:12)
at Parser.execute (/opt/bis/node/node_modules/bis-package/node_modules/ssh2/lib/Parser.js:249:14)
at Socket.<anonymous> (/opt/bis/node/node_modules/bis-package/node_modules/ssh2/lib/Connection.js:536:18)
at Socket.emit (events.js:95:17)
at Socket.<anonymous> (_stream_readable.js:748:14)
at Socket.emit (events.js:92:17)
We use host based authentication which allows us password free logins. In Perl I use the following:
my( $SSH ) = "/usr/bin/ssh -t -o PreferredAuthentications=hostbased 2>/dev/null";
$run->run( map { qq{$SSH $_ "$CMD"} } #hosts );
I am not sure how I could do that with the nodejs ssh2 package.
Any idea how I could do that?
There is no support for hostbased authentication yet. I plan to add support for it in the upcoming next major release. The relevant issue is here.

Resources