Nodemailer Invalid Login 535 when setting environment variables with ZEIT Now - node.js

When I use this configuration for Nodemailer:
const transporter = nodemailer.createTransport({
service: process.env.EMAIL_SERVICE,
auth: {
user: process.env.EMAIL_USER,
pass: process.env.EMAIL_PASSWORD
}
});
Variables:
EMAIL_SERVICE: 'Hotmail',
EMAIL_USER: 'MyEmail#outlook.com',
EMAIL_PASSWORD: 'MyPassword'
And I send the email like this:
transporter.sendMail({
to: email,
subject: 'Confirmar cambio de contraseƱa',
html: `Para cambiar la contraseƱa entre a ${url} <br> Este token solo dura 24 horas.`
});
In development it works perfectly but when I deploy this in Now, It throws me this error:
How can I resolve it?
Here a little example about this:
https://github.com/MontoyaAndres/NowProblemNodemailer
And here in now:
https://nowemail-owcypiqzsr.now.sh
Thank you :)

You probably need to add a secret and then add the environment variables to your now.json.
Run these commands once to add secrets in your ZEIT Now account (use now switch if you have multiple accounts).
now secret add email-service 'Hotmail'
now secret add email-user 'MyEmail#outlook.com'
now secret add email-password 'MyPassword'
Then add the env key to your now.json file like so:
{
"version": 2,
"builds": [/* your builds go here */],
"env": {
"EMAIL_SERVICE": "#email-service",
"EMAIL_USER": "#email-user",
"EMAIL_PASSWORD": "#email-password"
}
}

Related

How can I configure Hardhat to work with RSK regtest blockchain?

I intend to develop my smart contracts in Hardhat, and to test them on RSK regtest local node. I was able to find a Truffle regtest configuration.
development: {
host: "127.0.0.1",
port: 4444,
network_id: "*"
},
What hardhat.config.js configuration do I need to run my tests on RSK regtest?
To deploy and test your smart contracts on RSK regtest yourhardhat.config.js should look as follows:
/**
* #type import('hardhat/config').HardhatUserConfig
*/
require("#nomiclabs/hardhat-waffle");
module.exports = {
solidity: "0.7.3",
defaultNetwork: "rskregtest",
networks: {
rskregtest: {
url: "http://localhost:4444/",
},
},
};
Then you'll be able to run your tests by typing in the terminal
% npx hardhat test

GSuite Error: Can't create new access token for user - OAuth2 Nodemailer

I'm trying to send emails through gmail from nodejs but I keep running into this error.
Error: Can't create new access token for user
at XOAuth2.generateToken(c: \apps\node\myapp\node_modules\nodemailer\lib\xoauth2\index.js: 184: 33)
at XOAuth2.getToken(c: \apps\node\myapp\node_modules\nodemailer\lib\xoauth2\index.js: 123: 18)
at SMTPConnection._handleXOauth2Token(c: \apps\node\myapp\node_modules\nodemailer\lib\smtp - connection\index.js: 1697: 27)
at SMTPConnection.login(c: \apps\node\myapp\node_modules\nodemailer\lib\smtp - connection\index.js: 540: 22)
at c: \apps\node\myapp\node_modules\nodemailer\lib\smtp - transport\index.js: 374: 32
at SMTPConnection.<anonymous>(c: \apps\node\myapp\node_modules\nodemailer\lib\smtp - connection\index.js: 215: 17)
at Object.onceWrapper(events.js: 420: 28)
at SMTPConnection.emit(events.js: 314: 20)
at SMTPConnection._actionEHLO(c: \apps\node\myapp\node_modules\nodemailer\lib\smtp - connection\index.js: 1313: 14)
at SMTPConnection._processResponse(c: \apps\node\myapp\node_modules\nodemailer\lib\smtp - connection\index.js: 942: 20)
at SMTPConnection._onData(c: \apps\node\myapp\node_modules\nodemailer\lib\smtp - connection\index.js: 749: 14)
at TLSSocket.SMTPConnection._onSocketData(c: \apps\node\myapp\node_modules\nodemailer\lib\smtp - connection\index.js: 195: 44)
at TLSSocket.emit(events.js: 314: 20)
at addChunk(_stream_readable.js: 304: 12)
at readableAddChunk(_stream_readable.js: 280: 9)
at TLSSocket.Readable.push(_stream_readable.js: 219: 10) {
code: 'EAUTH',
command: 'AUTH XOAUTH2'
}
I have set up my G Suite account, created a service account and enabled the Gmail API for that project. I have also enabled G-Suite domain wide delegation for the service account and added the client ID and the proper scope to my G Suite account.
I downloaded my credentials file and renamed it to use .js so I could import it as an ES module.
import nodemailer from "nodemailer";
import * as key from "../credentials.js";
const SENDER_EMAIL = "support#domain.com";
const RECEIVER_EMAIL = "customer#gmail.com";
async function start() {
const transporter = nodemailer.createTransport({
host: "smtp.gmail.com",
port: 465,
secure: true,
auth: {
type: "OAuth2",
user: SENDER_EMAIL,
serviceClient: key.client_id,
privateKey: key.private_key,
},
});
try {
await transporter.verify();
await transporter.sendMail({
from: SENDER_EMAIL,
to: RECEIVER_EMAIL,
subject: "Hello Humans",
text: "The quick brown fox jumps over the lazy dog.",
});
} catch (err) {
console.error(err);
}
}
export default start;
Now, calling start() errors out with the above message. I can't figure it out. Help.
I hope you solved your issue 11 months ago but, for those who find this, I had the same issue and found the answer here. I believe this might be your case specially because you mentioned that hardcoding the value does work.
Apparently, the \n in the private key brings some issues when used this way. In my case, I'm taking the private key value from Firebase runtime config, and following suggestions in that link I ended up with a replace(/\\n/g, '\n') on the key:
const nodemailerTransporter = nodemailer.createTransport({
host: env.nodemailer.host,
port: 465,
secure: true, // true for TLS 465, false for other ports
auth: {
type: "OAuth2",
user: env.nodemailer.user,
serviceClient: env.nodemailer.clientid,
privateKey: env.nodemailer.privatekey.replace(/\\n/g, '\n'), // <=== HERE
accessUrl: env.nodemailer.tokenuri, // <== HERE
},
});
which does work. I'm using "host": "smtp-relay.gmail.com" but it's the same for your smtp.gmail.com case.
Also consider the accessUrl (the token_uri as taken from credentials.json):
"token_uri": "https://oauth2.googleapis.com/token"
which is not the same as the default used by nodemailer (https://accounts.google.com/o/oauth2/token). IDK if that matters.

nodemailer with virtualmin and postfix - authentication failed

Im using virtual min. I have a working email account no-reply#mydomain.com
I can login through webmin / virtual min and send emails.
Now I want to send mails from node.js using nodemailer.
Btw this also works from the command line.
mail -s "testing email" mygmail#gmail.com < /dev/null
Here is my nodemailer config:
{
"smtp" : {
"host": "localhost",
"secure": false,
"auth": {
"user": "no-reply#mydomain.com",
"pass": "mypass"
},
"tls": {
"rejectUnauthorized": false
},
"debug" : true
},
"from" : "Resourceful Network <no-reply#resourcefulnetwork.nl>"
}
I found the following config in postfix config file:
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
broken_sasl_auth_clients = yes
smtpd_recipient_restrictions = permit_mynetworks permit_sasl_authenticated reject_unauth_destination
smtp_tls_security_level = may
This is all set by virtual min.
I get this error
Error: Invalid login: 535 5.7.8 Error: authentication failed: authentication failure
code: 'EAUTH',
response: '535 5.7.8 Error: authentication failed: authentication failure',
responseCode: 535,
command: 'AUTH PLAIN'
I'm 100% sure the password is correct.
If I set "secure" : true in nodemailer config I get this error
errno: 'ECONNREFUSED',
code: 'ESOCKET',
syscall: 'connect',
address: '127.0.0.1',
port: 465,
So that doesn't seem to be the way to go.
Not sure what login protocol to use.. Do I need to set authMethod?
Secure or not secure?
I was able to fix this by removing auth from the nodemailer configuration.
I now realise smtpd_recipient_restrictions = permit_mynetworks means anyone on localhost is automatically allowed to send. And somehow still provider a (correct) username + password tripped things up?

Generate SSL certificates for multiple domains in SubjectAltName with Greenlock

I'm using greenlock to generate certificates, I pass it three domains, and only get 2 in my altnames:
const greenlock = Greenlock.create({
agreeTos: true,
email: myemail,
communityMember: false,
version: 'draft-12',
server: 'https://acme-v02.api.letsencrypt.org/directory',
configDir: '/etc/letsencrypt',
debug: true,
log: (debug) => { console.log(debug) },
})
console.log({ domains })
return greenlock.register({
domains,
email: myemail,
challengeType: 'dns-01',
})
.then((result) => {
console.log(result)
})
here are my logs:
{ domains:
[ 'domain1',
'domain3',
'domain2' ] }
true
true
true
{ result:
{
privkey: '-----BEGIN PRIVATE KEY-----\n\n-----END CERTIFICATE-----\n',
chain: '-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----\n',
subject: 'domain2',
altnames: [ 'domain1', 'domain2' ],
_issuedAt: 2018-09-19T14:43:31.000Z,
_expiresAt: 2018-12-18T14:43:31.000Z,
issuedAt: 1537368211000,
expiresAt: 1545144211000 } }
As you can see it's not even my first two domains that end up in my altnames but rather those that where already in the old certificate (not sure this is why tho).
I'm not married to greenlock, if someone as a better alternative I'm listening as well.
I tried passing approveDomains to my greenlock constructor and it doesn't seem to change much.
I still don't have my new domain (domain2) listed in my certificate :
openssl x509 -text < /etc/letsencrypt/live/domain1/fullchain.pem | grep 'DNS:' | sed 's/\s*DNS:\([a-z0-9.\-]*\)[,\s]\?/\1 /g'
domain1 domain3
Use Greenlock v2.7+
All of the code related to certificate generation and domain name and altname association has been updated.
Now when you change the domains array to include more domains it handles them individually rather than as a group.
Also, the information about the certificate is read directly from the certificate, so there can't be a mismatch between the "cache" and "the truth".
If you encounter further issues, please let us know directly:
https://git.rootprojects.org/root/greenlock.js/issues

How to add pem files to target in flightplan automated deployment script for nodejs applications

I am new to node applications deployment, I am using flightplan.js for automated deployments, however in most of the documents I have seen it is only about password less deployments where a user's key is added to server, I want to set up the target where I can specify the location of pem file in order to login to the server, is there a way to do that? right now the target looks like this
plan.target('staging', [
{
host: 'xxx.xxx.xxx',
username: username,
agent: process.env.SSH_AUTH_SOCK
}
]);
I would like to have something where I can pass the pem file path as well, something like this
plan.target('staging', [
{
host: 'xxx.xxx.xxx',
username: username,
key: PATH_TO_KEY
agent: process.env.SSH_AUTH_SOCK
}
]);
You can add your pem files like this,
plan.target('staging', [
{
host: 'xxx.xxx.xxx',
username: username,
privateKey: 'path/to/file/key.pem',
agent: process.env.SSH_AUTH_SOCK
}
]);

Resources