I'm using NestJs Mailer Module, the latest stable version. You can find the documentation here.
I've search a solution for this error but I found nothing:
Error: self signed certificate in certificate chain
app.module.ts:
#Module({
imports: [
MailerModule.forRoot({
transport: 'smtps://user#domain.com:pass#smtp.domain.com',
defaults: {
from:'"nest-modules" <modules#nestjs.com>',
},
template: {
dir: __dirname + '/templates',
adapter: new HandlebarsAdapter(),
options: {
strict: true,
},
},
}),
],
})
export class AppModule {}
sending the email:
this.mailerService.sendMail({
to: 'example#domain.com',
subject: 'subject'
text: 'blahblahblah'
html: 'blahblahblah'
}).then(() => {
this.logger.log('Error email sent!', 'HttpExceptionFilter');
}).catch(err => {
this.logger.error('Error while sending error email.', err, 'HttpExceptionFilter');
});
As a solution, you can use tls: { rejectUnauthorized: false } in your transport options.
Related
so I am using the Godaddy smtp relayer service and trying to send email using the nestjs-moudles/mailere library for this which implements actually the nodemailer. It works locally fine but when deploying to the server I am getting a timeout issue.
here is the node mailer config:
export const MAIL_CONFIG: MailerOptions = {
transport: {
host: 'relay-hosting.secureserver.net',
port: 25,
tls: { rejectUnauthorized: false },
enableSsl: false,
secure: false,
secureConnection: false,
auth: {
user: config.mailer.user,
pass: config.mailer.pass
}
},
defaults: {
from: config.mailer.from
},
template: {
dir: path.resolve(__dirname, '../../modules/secondary/mail/templates'),
adapter: new HandlebarsAdapter(),
options: {
strict: true
}
}
};
Anyone can help with this?
expect to be able to send emails.
I am using AWS SES for SMTP credentials and this nestjs module #nestjs-modules/mailerit was working 4/5 days ago but suddenly, what happened 🤔
I am pretty sure that my credentials are right.
Error: Unexpected socket close
at Timeout._onTimeout
node_modules/nodemailer/lib/smtp-transport/index.js:189:31)
at listOnTimeout (internal/timers.js:557:17)
at processTimers (internal/timers.js:500:7)
transport: {
host: process.env.EMAIL_SERVER_HOST,
secure: false,
port: +process.env.EMAIL_SERVER_PORT,
auth: {
user: process.env.EMAIL_SERVER_USER,
pass: process.env.EMAIL_SERVER_PASSWORD,
},
},
defaults: {
from: `${process.env.EMAIL_FROM}`,
},
template: {
dir: join(__dirname, 'templates'),
adapter: new HandlebarsAdapter(),
options: {
strict: true,
},
},
}),
Edit 1: it is working on the production environment, then why it is not working on my local machine, app is hosted on cloud run :(
I got it; it is because of the wifi I am using. If I use my mobile network, it works properly.
It works on the local environment and production environment as well. I hope it helps. It requires the AWS SES key and secret, the SES SMTP user and password and the correct region.
import { Module, Global } from '#nestjs/common';
import { MailerModule } from '#nestjs-modules/mailer';
import { HandlebarsAdapter } from '#nestjs-modules/mailer/dist/adapters/handlebars.adapter';
import { MailService } from './mail.service';
import { join } from 'path';
import { ConfigService } from '#nestjs/config';
import * as AWS from 'aws-sdk';
const upperCaseFn = (name: string) => {
return name.toUpperCase();
};
#Global()
#Module({
imports: [
MailerModule.forRootAsync({
useFactory: async (config: ConfigService) => ({
transport: {
SES: new AWS.SES({
region: config.get('AWS_SES_REGION'),
accessKeyId: config.get('AWS_SES_ACCESS_KEY'),
secretAccessKey: config.get('AWS_SES_KEY_SECRET'),
}),
host: config.get('MAIL_HOST'),
port: config.get('MAIL_PORT'),
secure: false,
ignoreTLS:true,
requireTLS:false,
auth: {
user: config.get('MAIL_USERNAME'),
pass: config.get('MAIL_PASSWORD'),
},
debug: true
},
defaults: {
from: `"${config.get('MAIL_FROM_NAME')}" <${config.get(
'MAIL_FROM_ADDRESS',
)}>`,
},
template: {
dir: join(__dirname, '/templates'),
adapter: new HandlebarsAdapter({ upperCase: upperCaseFn }), // or new PugAdapter() or new EjsAdapter()
options: {
strict: true,
},
},
options: {
partials: {
dir: join(__dirname, '/templates/partials'),
options: {
strict: true,
},
},
},
}),
inject: [ConfigService],
}),
],
providers: [MailService],
exports: [MailService],
})
export class MailModule {}
I want to use handle bars template in my nest js application:
<!--confirmation.hbs-->
<p>Hello template</p>
This file is located in src/mail/templates/confirmation.hbs. Also i try to send this template as email:
//mail service
#Injectable()
export class EmailService {
constructor(private readonly mailerService: MailerService) {}
public example(): void {
this.mailerService
.sendMail({
to: 'mail', // list of receivers
from: 'test#nestjs.com', // sender address
subject: 'Testing Nest MailerModule ✔', // Subject line
template: './confirmation',
})
.then((r) => {
console.log(r, 'email is sent');
})
.catch((e) => {
console.log(e, 'error sending email');
});
}
}
My app.module.ts looks:
#Module({
imports: [
MailerModule.forRoot({
transport: {
service: 'Gmail',
auth: {
user: '---secret',
pass: '---secret',
},
},
defaults: {
from: '"No Reply" <no-reply#localhost>',
},
template: {
dir: __dirname + '/templates',
adapter: new HandlebarsAdapter(),
options: {
strict: true,
},
},
}),
TypeOrmModule.forRoot({
type: 'postgres',
host: 'localhost',
port: 5433,
username: '-',
password: '-',
database: '-',
entities: [RegisterEntity],
synchronize: true,
}),
AuthenticationModule,
],
controllers: [AppController, AuthenticationController],
providers: [AppService, AuthenticationService],
})
This is my main.ts
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.setGlobalPrefix(CONSTANTS.GLOBAL_PREFIX);
await app.listen(3000);
}
bootstrap();
This is my nest-cli.hbs
{
"collection": "#nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"assets": [
"mail/templates/**/*.hbs"
],
"watchAssets": true
}
}
The email is sent if don't send a template, so the code is working. Trying to send an email template like is my code above i get this error: TypeError: Cannot destructure property 'templateName' of 'precompile(...)' as it is undefined. Question: Why i get this issue and how to get rid of it?
Your files are located inside src/mail/templates/.
But in your module you have dir: __dirname + '/templates',.
Here __dirname returns app.module.ts folder location path which is src/.
change
dir: __dirname + '/templates',
to
dir: __dirname + '/mail/templates',
Since this bug is not yet released #743 (to this date), I rolled back to previous version:
npm i --save #nestjs-modules/mailer#1.6.0 --force
For me,this is a template file path issue.
Review your template.dir in your MailerModule config, and compare it to your project "dist" directory.
if your template file path is "dist/templates/template.hbs"
then your template.dir should be ${process.cwd()}/templates
else if your dist directory is "dist/src/templates/template.hbs" ,which is depend on your compile configs.
then your template.dir config should be join(__dirname, 'templates')
I'm trying to send an ejs template with email-templates but I'm not having much joy.
The email sends fine, however it doesn't contain any template data.
const email = new Email ({
template: 'activateAccount',
message: {
from: "noreply#domain.com",
subject: "Activate your account!",
to: data.email
},
locals: {
name: data.name,
url: data.url
},
send: true,
transport: {
host: "domain.com",
port: 2525,
auth: {
user: "abc",
pass: "123"
}
},
views: {
options: {
extension: 'ejs'
}
}
});
return await email.send();
Does anyone know why the templates aren't being populated?
Use the locals when .sending the email,
const email = new Email({
message: {
from: "noreply#domain.com",
subject: "Activate your account!",
to: data.email
},
send: true,
transport: {
host: "domain.com",
port: 2525,
auth: {
user: "abc",
pass: "123"
}
},
views: {
options: {
extension: 'ejs'
}
}
});
await email.send({
template: 'activateAccount',
locals: {
name: data.name,
url: data.url
}
});
Basically, you can use all the options is .send function itself.
Basically the router.beforeEach() method is doing something I don't understand.
I get the jist of the issue being that when my route is re-directing to /login it will do it around 960 times or so until the error occurs.
my code is like so:
Router:
let router = new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path:'/login',
name: 'login',
component: Login,
meta: {
requiresAuth: 'false'
}
},
{
path:'/register',
name: 'register',
component: Register,
meta: {
requiresAuth: 'false'
}
},
{
path: '/',
name: 'home',
component: Home,
meta: {
requiresAuth: 'True'
}
}
]
})
the beforeEach() method
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
console.log(to.matched.some(record => record.meta.requiresAuth))
if (localStorage.getItem('jwt') == null) {
next({
path: '/login',
params: { nextUrl: to.fullPath }
})
} else {
next()
}
} else {
if (localStorage.getItem('jwt') != null) {
next({
path: '/',
params: { nextUrl: '/' }
})
} else {
next()
}
}
})
I've looked through countless threads and other places and none have the same issue as me (or I'm overlooking things). Anyone got an idea on how to fix, and what is actually happening to make the error occur in this? from what I can tell I have nothing named twice or any other function/component fire off when it shouldn't.
Fixed it. I'm a bit special in the head. For anyone with the same issue just change the routes to
routes: [
{
path: '/login',
name: 'login',
component: Login,
meta: {
requiresAuth: false
}
},
{
path:'/register',
name: 'register',
component: Register,
meta: {
requiresAuth: false
}
},
{
path: '/',
name: 'home',
component: Home,
meta: {
requiresAuth: true
}
}
]
For anyone who gets this error without any obvious mistake, try deleting node_modules and running npm install again.
I got this error when switching git branches and the only thing that changes were the packages, so I tried the above and it got rid of the problem :)