Nodemailer / Sendgrid with apikey - sendgrid

I am trying to get a simple contact form up and running in node.js with sendgrid using an apikey. It's unclear where I am going wrong.
I tried the following:
1.
var options = {
auth: {
api_user: 'xjh-4XqZGH6$HLT-IEOPFG',
api_key: 'SG.xjh-4XqZGH6$HLT-IEOPFG.Wl2rB-CN00-nj3x5NiKno7MpDk8DxTtvgJeZfDGGI' // fake obviously, but I would like to show the structure as I am not sure whether this is correct
}
};
and
2.
var options = {
auth: {
api_user: 'xjh-4XqZGH6$HLT-IEOPFG',
api_key: 'Wl2rB-CN00-nj3x5NiKno7MpDk8DxTtvgJeZfDGGI' // fake obviously, but I would like to show the structure as I am not sure whether this is correct
}
};
and
3.
var options = {
auth: {
api_user: 'apikey',
api_key: 'SG.xnh-4XqZGH6$HLT-IEOPFG.Wl2rB-CN00-nj3x5NiKno7MpDk8DxTtvgJeZfDGGI' // fake obviously, but I would like to show the structure as I am not sure whether this is correct
}
};
It keeps coming back with badusername / password.
It works fine with my username (api_user) and password (api_key).
Can anyone explain what I need to do?
Cheers, Mike

OK, I figured it out. You remove the api_user in this case and use the long key. E.g.
var options = {
auth: {
api_key: 'SG.xnh-4XqZGH6$HLT-IEOPFG.Wl2rB-CN00-nj3x5NiKno7MpDk8DxTtvgJeZfDGGI' // fake
}
};
Best, Mike

You can use SMTP and API key together:
const mailer = nodemailer.createTransport({
host: 'smtp.sendgrid.net',
port: 465,
secure: true,
auth: {
user: 'apikey',
pass: 'SG.XXXX.XXXX',
},
});
Official docs: : https://sendgrid.com/docs/API_Reference/SMTP_API/integrating_with_the_smtp_api.html

For anybody stumbling over this: The preferred way now seems to be to install the nodemailer-sendgrid package which allows you to set an apiKey property - see my answer here https://stackoverflow.com/a/64726992/769726

Related

Using Mongodb Adapter in NextAuth not working

I git clone & copy MUI Nextjs example project & start from there.
From NextAuth portal, they said I can just copy mongodb adapter setup here and basically it will work well out of the box. I placed this file in this path: /src/lib/mongodb.js
Here I'm using CredentialsProvider. Basically I'm using my own form for login & authentication process.
Here my /pages/api/auth/[...nextauth].js file:
import { MongoDBAdapter } from "#next-auth/mongodb-adapter";
import NextAuth from 'next-auth';
import CredentialsProvider from 'next-auth/providers/credentials';
import clientPromise from "../../../src/lib/mongodb";
export default NextAuth({
secret: process.env.SECRET,
adapter: MongoDBAdapter(clientPromise),
providers: [
CredentialsProvider({
async authorize(credentials) {
const { email, password } = credentials
if(email !== 'test#test.com' || password !== 'password123') {
throw new Error('User does not exists. Please make sure you insert the correct email & password.')
}
return {
id: 1,
name: 'Tester',
email: 'test#test.com'
}
}
})
],
callbacks: {
redirect: async ({ url, baseUrl }) => {
return baseUrl
}
}
})
What I understood, I can just straight away use this adapter & it will create 4 models/tables (User, Session, Account, VerificationToken) by default. So I don't need to create them myself. Ref doc here
According to the NextAuth MongoDB Adapter documentation, I just need to specify the MONGODB_URI in .env.local.
so here my /.env.local file content:
NEXTAUTH_URL=http://localhost:3000
MONGODB_URI=mongodb+srv://<username>:<password>#rest.lvnpm.mongodb.net/<database_name>?retryWrites=true&w=majority
SECRET=someSecret
NODE_ENV=development
So currently, it does nothing at all. I don't need to specify session.strategy to database since by default NextAuth will recognized that if I use adapter option.
What do I need to do here to make this work? Any helps is appreciated. Here my github project
I just found out that in NextAuth, if I use CredentialsProvider. I won't be able to persist data using database strategy. You may go here to NextAuth documentation itself to know why

Set request header in Protractor

Is it possible to set request headers in Protractor?
In the following post (2014), Protractor confirmed that currently they don't have any way to do this (as protractor was not designed to interact with under-the-hood things.
here
Has anyone found out a way how to do this?
Thanks in advance :)
I had the same problem so I implemented a simple proxy to inject headers in the requests. I published it on npm repository. You can find it here https://www.npmjs.com/package/headers-injection-proxy
Very easy to use:
header-injection-proxy -p 3000 -t "https://www.google.com" -h "headers.json"
At that point you just send the requests to the proxy instead of the real server
You can use an external library like request. For me it worked as a charm with Protractor:
https://github.com/request/request#custom-http-headers
EDIT:
Here you have an example of implementation. It uses request-promise
import {browser} from 'protractor';
import {put} from 'request-promise';
import {ADMIN_URL} from '../data/definitions/urls';
export class CreateUser {
public setRoles(username: string, roles: string[]) {
return this.getUserId(username).then((userId) => {
const data = {
url: `${ADMIN_URL}/user/${userId}/role`,
headers: {
Authorization: browser.params.token
},
body: roles,
json: true,
rejectUnauthorized: false
};
return put(data);
});
}
}

How do I solve the keycloak refresh /#state on my angular7 project - i'm using keycloak-angular

I have also tried all varying combinations for web origins and valid redirect URIs
I login via keycloak and it continuously redirects me back and forth between my localhost application and this url: http://localhost:4200/#state=166446fd-daf6-4b76-b595-583c01c663df&session_state=57ead1f3-bf41-4117-9ddf-75e37c9248e7&code=8692b58b-0868-4762-b82e-acde9911dd34.57ead1f3-bf41-4117-9ddf-75e37c9248e7.1e8b5b9d-b590-453e-b396-62b46c18cc9f
I have tried it on firefox and chrome but with the same issue - it seems to be looking for the keycloak.json file in the network tab even though I can login to the correct realm via keycloak
GET http://localhost:4200/keycloak.json 404 (Not Found)
scheduleTask # zone.js:2969
ERROR An error happened during Keycloak initialization. core.js:1601
Unhandled Promise rejection: An error happened during Keycloak initialization. ; Zone: ; Task: Promise.then ; Value: An error happened during Keycloak initialization. undefined
static init(): Promise<any> {
const keycloakAuth: any = Keycloak({
url: 'http://localhost:8080/auth',
realm: 'ContractPortal',
clientId: 'secretkey2',
'ssl-required': 'external',
'public-client': true
});
KeycloakService.auth.loggedIn = false;
return new Promise((resolve, reject) => {
keycloakAuth.init({onLoad: 'login-required'})
.success(() => {
console.log(keycloakAuth);
KeycloakService.auth.loggedIn = true;
KeycloakService.auth.authz = keycloakAuth;
KeycloakService.auth.logoutUrl = keycloakAuth.authServerUrl
+ '/realms/angular_keycloak/protocol/openid-connect/logout?redirect_uri='
+ document.baseURI;
resolve();
})
.error(() => {
reject();
});
});
}
it'd be great if one of you guys can point me in the right direction to solve this issue...
I have found another similar question to what I have asked link but not sure how to implement this solution! this is my provider setup -
providers: [
{
provide: APP_INITIALIZER,
useFactory: initializer,
multi: true,
deps: [KeycloakService]
}
],
but OP puts the following in his provider
providers: [
KeyCloakService,
AssetService,
{
provide: LocationStrategy,
useClass: PathLocationStrategy
}
]
Please let me know if you require any other information
For anybody that ran into the same issue - I misunderstood the keycloak.json file and did not know where to get it - so I was exporting the complete json file from keycloak but THIS is not how you should get it!!
First you have to go to your realm > clients and click on installation
then download the keycloak OIDC json file
then place it next to the index.html file in your application
This solved my issue - hope it helps somebody else
I was researching on the internet and it is the same case, for me my angular page is reloading automatically in infnite loop
I did some changes in keycloak-init.ts file (please find following code and change checkLoginIframe from true to false)
Old Code: keycloak.init ({onLoad: 'login-required', "checkLoginIframe": true})
New Code: keycloak.init ({onLoad: 'login-required', "checkLoginIframe": false})
this.loadingService.isLoading$.pipe(delay(100)).subscribe((data => {
this.loading = data
}))
this.isLogging = await this.keycloak.isLoggedIn();
type roleUser = Array<{ id: number, text: string }>
if (this.isLogging) {
this.userProfile = await this.keycloak.loadUserProfile();
this.userRoles = await this.keycloak.getUserRoles();
}else {
// this.clearSession();
}
if you are using "this.keycloak.loadUserProfile()" Remove this "clear session"

how to sync data from ydn-db web app to backend server?

With ydn-dn, i want to automatically synchronise data from my web app with my REST back end.
I read the documentation and searched in examples but i cannot make it work.
https://yathit.github.io/ydn-db/synchronization.html
http://dev.yathit.com/api/ydn/db/schema.html#sync
I tried to define a schema with sync configuration like that :
var schema = {
stores: [ {
name: 'contact',
keyPath: 'id',
Sync: {
format: 'rest',
transport: service,
Options: {
baseUri: '/'
}
}
}
]
};
and created a function for transport :
var service = function(args) {
console.log("contact synch");
};
but my service function is never called.
I certainly misunderstood how YDN-db work, but i didn't found any example.
To complete, here is a jsfiddle :
http://jsfiddle.net/asicfr/y7sL7b3j/
Please see the example http://yathit.github.io/ydndb-demo/entity-sync/app.html
Older example http://yathit.github.io/sprintly-service/playground.html from https://github.com/yathit/sprintly-service

node.js email doesn't get sent with gmail smtp

I'm trying to send the email gmail smtp but I'm getting the error:
My email and password is correct I'm using the nodemailer for sending the mail;
var nodemailer = require('nodemailer');
// create reusable transporter object using SMTP transport
var transporter = nodemailer.createTransport({
service: 'Gmail',
auth: {
admin: 'myuseremail.com',
pass: 'password'
}
});
var mailOptions = {
from: 'sender address', // sender address
to: to, // list of receivers
subject: 'Password Reset', // Subject line
html: 'Your one time password is : <b>' + temporaryPassword + ' </b>' // html body
};
transporter.sendMail(mailOptions, function (error, info) {
console.log(error,info);
}
in log i'm getting the error:
{
[Error: Invalid login]
code: 'EAUTH',
response: '535-5.7.8 Username and Password not accepted. Learn more at\n535 5.7.8 https://support.google.com/mail/answer/14257 k5sm20957041pdo.48 - gsmtp',
responseCode: 535
}
I try some link but that doesn't work:
https://laracasts.com/discuss/channels/general-discussion/help-email-doesnt-get-sent-with-gmail-smtp
var transporter = nodemailer.createTransport({
service: 'Gmail',
auth: {
user: 'user#gmail.com',
pass: 'password'
}
});
Try the above, and do the following which worked for me.
Login to https://www.google.com/settings/security/lesssecureapps and TURN ON Access for less secure apps.
I hope it will work for you too.
Thank you.
First of all, you have to enable the settings to allow less secure apps for the gmail account that you are using. Here is the link : https://myaccount.google.com/lesssecureapps
Secondly, Allow access for "Display Unlock captcha option" (Allow access to your Google account). Here is the link : https://accounts.google.com/DisplayUnlockCaptcha
https://myaccount.google.com/lesssecureapps
Click on this link, On your Less secure app access. so after that gmail will send email to your device , confirm that it is you. You are done happy coding
Google don't allow you to send direct e-mail to other's. First of all you have to create a app password .For that thing please follow below steps to get it done
Go to your manage account section.
Then click on the security link in left side.
In the signing in to the google click on app password and it will ask you to sign in again after sign in
It will ask "select app", for mail purpose "select mail" and after that select device from which you want to send mail.
After all these steps, it will generate password for that thing and insert that like this
var smtpTransport = nodemailer.createTransport({
service: "Gmail",
auth: {
user: "example#example.com",
pass: "password"
}
That's it.
In case you're using OAuth2 and you're facing the issue above, configuring my transporter as shown below resolved my issue.
const transporter = nodemailer.createTransport({
host: 'smtp.gmail.com',
port: 465,
secure: true,
auth: {
type: 'OAuth2',
user: process.env.MAIL_USER,
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
refreshToken: process.env.GOOGLE_CLIENT_REFRESH_TOKEN
}
});
var transporter = nodemailer.createTransport({
service: 'Gmail',
auth: {
user: 'user#gmail.com',
pass: 'password'
}
});
Try this.
For me
secure:true was giving ssl errors.
I changed
secure:false as below and worked for me.
let transporter = nodeMailer.createTransport({
host: 'smtp.gmail.com',
port: 587,
secure: false, //<<here
auth: {
user: 'example#gmail.com',
pass:'your gmail pass'
}
});
let transporter = nodeMailer.createTransport({
host: 'smtp.gmail.com',
port: 587,
secure: true,
auth: {
user: 'example#gmail.com',
pass:'your gmail pass'
}
});