Merge branch 'dev' into UH-registroComunidadVivienda

This commit is contained in:
Mariela 2022-07-18 21:38:44 -06:00
commit d4be2ae969
19 changed files with 6080 additions and 214 deletions

View File

@ -296,4 +296,38 @@ export class AppController {
) {
return this.appService.findReport(paramReport);
}
@Post('email/sendMail')
senMail(
@Body('email') email: string,
) {
return this.appService.sendMail(email);
}
@Post('email/html')
html(
@Body('email') email: string,
@Body('name') name: string,
) {
return this.appService.html(email, name);
}
// #==== API Users
@Post('user/testSendMail')
testSendMail(
@Body('dni') dni: string,
@Body('name') name: string,
@Body('last_name') last_name: string,
@Body('email') email: string,
@Body('phone') phone: number,
@Body('password') password: string,
@Body('user_type') user_type: string,
@Body('status') status: string,
@Body('date_entry') date_entry: Date,
) {
return this.appService.testSendMail(dni, name, last_name, email, phone, password,
user_type, status, date_entry);
}
}

View File

@ -50,6 +50,20 @@ export class AppService {
);
}
testSendMail(dni: string, name: string, last_name: string, email: string, phone: number
, password: string, user_type: string, status: string, date_entry: Date) {
const pattern = { cmd: 'testSendMail' };
const payload = {
dni: dni, name: name, last_name: last_name, email: email, phone: phone,
password: password, user_type: user_type, status: status, date_entry: date_entry
};
return this.clientUserApp
.send<string>(pattern, payload)
.pipe(
map((message: string) => ({ message })),
);
}
allUsers() {
const pattern = { cmd: 'findAllUsers' };
const payload = {};
@ -419,4 +433,25 @@ export class AppService {
map((message: string) => ({ message })),
);
}
sendMail(email: string) {
const pattern = { cmd: 'sendMail' };
const payload = { email: email};
return this.clientNotificationtApp
.send<string>(pattern, payload)
.pipe(
map((message: string) => ({ message })),
);
}
html(email: string, name: string) {
const pattern = { cmd: 'html' };
const payload = { email: email, name: name};
return this.clientNotificationtApp
.send<string>(pattern, payload)
.pipe(
map((message: string) => ({ message })),
);
}
}

View File

@ -0,0 +1,8 @@
# mail
MAIL_HOST=smtp.gmail.com
MAIL_USER=mbonilla.guti@gmail.com
MAIL_PASSWORD=laofghlofgffmyry
MAIL_FROM=noreply@example.com
# optional
MAIL_TRANSPORT=smtp://${MAIL_USER}:${MAIL_PASSWORD}@${MAIL_HOST}

View File

@ -1,5 +1,9 @@
{
"$schema": "https://json.schemastore.org/nest-cli",
"collection": "@nestjs/schematics",
"sourceRoot": "src"
"sourceRoot": "src",
"compilerOptions": {
"assets": ["mails/**/*"],
"watchAssets": true
}
}

File diff suppressed because it is too large Load Diff

View File

@ -21,12 +21,16 @@
"test:e2e": "jest --config ./test/jest-e2e.json"
},
"dependencies": {
"@nestjs-modules/mailer": "^1.7.1",
"@nestjs/common": "^8.0.0",
"@nestjs/config": "^2.2.0",
"@nestjs/core": "^8.0.0",
"@nestjs/mapped-types": "*",
"@nestjs/microservices": "^8.4.7",
"@nestjs/platform-express": "^8.0.0",
"@nestjs/swagger": "^5.2.1",
"handlebars": "^4.7.7",
"nodemailer": "^6.7.7",
"reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2",
"rxjs": "^7.2.0",

View File

@ -1,11 +1,45 @@
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { NotificationsModule } from './notifications/notifications.module';
import { MailerModule } from '@nestjs-modules/mailer';
import { ClientsModule, Transport } from "@nestjs/microservices";
import { AuthModule } from './auth/auth.module';
import { EmailController } from './email.controller';
import { join } from 'path';
import { HandlebarsAdapter } from '@nestjs-modules/mailer/dist/adapters/handlebars.adapter';
import { ConfigModule, ConfigService } from '@nestjs/config';
@Module({
imports: [
MailerModule.forRootAsync({
// imports: [ConfigModule], // import module if not enabled globally
useFactory: async (config: ConfigService) => ({
// transport: config.get("MAIL_TRANSPORT"),
// or
transport: {
host: config.get('MAIL_HOST'),
secure: false,
auth: {
user: config.get('MAIL_USER'),
pass: config.get('MAIL_PASSWORD'),
},
},
defaults: {
from: `"No Reply" <${config.get('MAIL_USER')}>`,
},
template: {
dir: join(__dirname, 'mails'),
adapter: new HandlebarsAdapter(),
options: {
strict: true,
},
},
}),
inject: [ConfigService],
}),
ConfigModule.forRoot({
isGlobal: true, // no need to import into other modules
}),
ClientsModule.register([
{
name: "SERVICIO_NOTIFICACIONES",
@ -16,8 +50,8 @@ import { ClientsModule, Transport } from "@nestjs/microservices";
}
}
]),
NotificationsModule],
controllers: [AppController],
AuthModule],
controllers: [AppController, EmailController],
providers: [],
})
export class AppModule {}

View File

@ -0,0 +1,9 @@
import { Module } from '@nestjs/common';
//import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
@Module({
//controllers: [AuthController],
providers: [AuthService],
})
export class AuthModule {}

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AuthService } from './auth.service';
describe('AuthService', () => {
let service: AuthService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [AuthService],
}).compile();
service = module.get<AuthService>(AuthService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

View File

@ -0,0 +1,13 @@
import { Injectable } from '@nestjs/common';
import { User } from './../user/user.entity';
@Injectable()
export class AuthService {
async signUp(user: User) {
const token = Math.floor(1000 + Math.random() * 9000).toString();
// create user in db
// ...
// send confirmation mail
}
}

View File

@ -0,0 +1,46 @@
import { Controller, Get, Query } from '@nestjs/common';
import { MessagePattern, Payload } from '@nestjs/microservices';
import { MailerService } from '@nestjs-modules/mailer';
import { User } from './user/user.entity';
@Controller()
export class EmailController {
constructor(private mailService: MailerService) { }
@MessagePattern({ cmd: 'sendMail' })
sendMail(@Payload() toEmail: string) {
var response = this.mailService.sendMail({
to: toEmail["email"],
from: "mbonilla.guti@gmail.com",
subject: 'Plain Text Email ✔',
text: 'Welcome NestJS Email Sending Tutorial',
});
return response;
}
@MessagePattern({ cmd: 'html' })
async postHTMLEmail(@Payload() user: any) {
const url = "http://localhost:3000/";
const image = "images/email.ong";
var response = await this.mailService.sendMail({
to: user["email"],
from: "mbonilla.guti@gmail.com",
subject: 'HTML Dynamic Template',
template: 'templateEmail',
context: {
name: user["name"],
url
},
attachments: [
{
filename: 'email.png',
path: __dirname +'/mails/images/email.png',
cid: 'logo' //my mistake was putting "cid:logo@cid" here!
}
]
});
return response;
}
}

View File

@ -0,0 +1,7 @@
<p>Hey {{ name }},</p>
<p>Please click below to confirm your email</p>
<p>
<a href="{{ url }}">Confirm</a>
</p>
<p>If you did not request this email you can safely ignore it.</p>

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -0,0 +1,452 @@
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:o="urn:schemas-microsoft-com:office:office">
<head>
<meta charset="utf-8"> <!-- utf-8 works for most cases -->
<meta name="viewport" content="width=device-width"> <!-- Forcing initial-scale shouldn't be necessary -->
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <!-- Use the latest (edge) version of IE rendering engine -->
<meta name="x-apple-disable-message-reformatting"> <!-- Disable auto-scale in iOS 10 Mail entirely -->
<title></title> <!-- The title tag shows in email notifications, like Android 4.4. -->
<link href="https://fonts.googleapis.com/css?family=Lato:300,400,700" rel="stylesheet">
<!-- CSS Reset : BEGIN -->
<style>
html,
body {
margin: 0 auto !important;
padding: 0 !important;
height: 100% !important;
width: 100% !important;
background: #f1f1f1;
}
/* What it does: Stops email clients resizing small text. */
* {
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}
/* What it does: Centers email on Android 4.4 */
div[style*="margin: 16px 0"] {
margin: 0 !important;
}
/* What it does: Stops Outlook from adding extra spacing to tables. */
table,
td {
mso-table-lspace: 0pt !important;
mso-table-rspace: 0pt !important;
}
/* What it does: Fixes webkit padding issue. */
table {
border-spacing: 0 !important;
border-collapse: collapse !important;
table-layout: fixed !important;
margin: 0 auto !important;
}
/* What it does: Uses a better rendering method when resizing images in IE. */
img {
-ms-interpolation-mode: bicubic;
}
/* What it does: Prevents Windows 10 Mail from underlining links despite inline CSS. Styles for underlined links should be inline. */
a {
text-decoration: none;
}
/* What it does: A work-around for email clients meddling in triggered links. */
*[x-apple-data-detectors],
/* iOS */
.unstyle-auto-detected-links *,
.aBn {
border-bottom: 0 !important;
cursor: default !important;
color: inherit !important;
text-decoration: none !important;
font-size: inherit !important;
font-family: inherit !important;
font-weight: inherit !important;
line-height: inherit !important;
}
/* What it does: Prevents Gmail from displaying a download button on large, non-linked images. */
.a6S {
display: none !important;
opacity: 0.01 !important;
}
/* What it does: Prevents Gmail from changing the text color in conversation threads. */
.im {
color: inherit !important;
}
/* If the above doesn't work, add a .g-img class to any image in question. */
img.g-img+div {
display: none !important;
}
/* What it does: Removes right gutter in Gmail iOS app: https://github.com/TedGoas/Cerberus/issues/89 */
/* Create one of these media queries for each additional viewport size you'd like to fix */
/* iPhone 4, 4S, 5, 5S, 5C, and 5SE */
@media only screen and (min-device-width: 320px) and (max-device-width: 374px) {
u~div .email-container {
min-width: 320px !important;
}
}
/* iPhone 6, 6S, 7, 8, and X */
@media only screen and (min-device-width: 375px) and (max-device-width: 413px) {
u~div .email-container {
min-width: 375px !important;
}
}
/* iPhone 6+, 7+, and 8+ */
@media only screen and (min-device-width: 414px) {
u~div .email-container {
min-width: 414px !important;
}
}
</style>
<!-- CSS Reset : END -->
<!-- Progressive Enhancements : BEGIN -->
<style>
.primary {
background: #30e3ca;
}
.bg_white {
background: #ffffff;
}
.bg_light {
background: #fafafa;
}
.bg_black {
background: #000000;
}
.bg_dark {
background: rgba(0, 0, 0, .8);
}
.email-section {
padding: 2.5em;
}
/*BUTTON*/
.btn {
padding: 10px 15px;
display: inline-block;
}
.btn.btn-primary {
border-radius: 5px;
background: #30e3ca;
color: #ffffff;
}
.btn.btn-white {
border-radius: 5px;
background: #ffffff;
color: #000000;
}
.btn.btn-white-outline {
border-radius: 5px;
background: transparent;
border: 1px solid #fff;
color: #fff;
}
.btn.btn-black-outline {
border-radius: 0px;
background: transparent;
border: 2px solid #000;
color: #000;
font-weight: 700;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: 'Lato', sans-serif;
color: #000000;
margin-top: 0;
font-weight: 400;
}
body {
font-family: 'Lato', sans-serif;
font-weight: 400;
font-size: 15px;
line-height: 1.8;
color: rgba(0, 0, 0, .4);
}
a {
color: #30e3ca;
}
table {}
/*LOGO*/
.logo h1 {
margin: 0;
}
.logo h1 a {
color: #30e3ca;
font-size: 24px;
font-weight: 700;
font-family: 'Lato', sans-serif;
}
/*HERO*/
.hero {
position: relative;
z-index: 0;
}
.hero .text {
color: rgba(0, 0, 0, .3);
}
.hero .text h2 {
color: #000;
font-size: 40px;
margin-bottom: 0;
font-weight: 400;
line-height: 1.4;
}
.hero .text h3 {
font-size: 24px;
font-weight: 300;
}
.hero .text h2 span {
font-weight: 600;
color: #30e3ca;
}
/*HEADING SECTION*/
.heading-section {}
.heading-section h2 {
color: #000000;
font-size: 28px;
margin-top: 0;
line-height: 1.4;
font-weight: 400;
}
.heading-section .subheading {
margin-bottom: 20px !important;
display: inline-block;
font-size: 13px;
text-transform: uppercase;
letter-spacing: 2px;
color: rgba(0, 0, 0, .4);
position: relative;
}
.heading-section .subheading::after {
position: absolute;
left: 0;
right: 0;
bottom: -10px;
content: '';
width: 100%;
height: 2px;
background: #30e3ca;
margin: 0 auto;
}
.heading-section-white {
color: rgba(255, 255, 255, .8);
}
.heading-section-white h2 {
font-family:
line-height: 1;
padding-bottom: 0;
}
.heading-section-white h2 {
color: #ffffff;
}
.heading-section-white .subheading {
margin-bottom: 0;
display: inline-block;
font-size: 13px;
text-transform: uppercase;
letter-spacing: 2px;
color: rgba(255, 255, 255, .4);
}
ul.social {
padding: 0;
}
ul.social li {
display: inline-block;
margin-right: 10px;
}
/*FOOTER*/
.footer {
border-top: 1px solid rgba(0, 0, 0, .05);
color: rgba(0, 0, 0, .5);
}
.footer .heading {
color: #000;
font-size: 20px;
}
.footer ul {
margin: 0;
padding: 0;
}
.footer ul li {
list-style: none;
margin-bottom: 10px;
}
.footer ul li a {
color: rgba(0, 0, 0, 1);
}
@media screen and (max-width: 500px) {}
</style>
</head>
<body width="100%" style="margin: 0; padding: 0 !important; mso-line-height-rule: exactly; background-color: #f1f1f1;">
<center style="width: 100%; background-color: #f1f1f1;">
<div
style="display: none; font-size: 1px;max-height: 0px; max-width: 0px; opacity: 0; overflow: hidden; mso-hide: all; font-family: sans-serif;">
&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;
</div>
<div style="max-width: 600px; margin: 0 auto;" class="email-container">
<!-- BEGIN BODY -->
<table align="center" role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%"
style="margin: auto;">
<tr>
<td valign="top" class="bg_white" style="padding: 1em 2.5em 0 2.5em;">
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td class="logo" style="text-align: center;">
<h1><a href="#">e-Verify</a></h1>
</td>
</tr>
</table>
</td>
</tr><!-- end tr -->
<tr>
<td valign="middle" class="hero bg_white" style="padding: 3em 0 2em 0;">
<img src="cid:logo" alt=""
style="width: 300px; max-width: 600px; height: auto; margin: auto; display: block;">
</td>
</tr><!-- end tr -->
<tr>
<td valign="middle" class="hero bg_white" style="padding: 2em 0 4em 0;">
<table>
<tr>
<td>
<div class="text" style="padding: 0 2.5em; text-align: center;">
<h2>Hi, {{ name }}</h2>
<h2>Please verify your email</h2>
<h3>Amazing deals, updates, interesting news right in your inbox</h3>
<p><a href="{{ url }}" class="btn btn-primary">Yes! Subscribe Me</a></p>
</div>
</td>
</tr>
</table>
</td>
</tr><!-- end tr -->
<!-- 1 Column Text + Button : END -->
</table>
<table align="center" role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%"
style="margin: auto;">
<tr>
<td valign="middle" class="bg_light footer email-section">
<table>
<tr>
<td valign="top" width="33.333%" style="padding-top: 20px;">
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
<tr>
<td style="text-align: left; padding-right: 10px;">
<h3 class="heading">About</h3>
<p>A small river named Duden flows by their place and supplies it with
the necessary regelialia.</p>
</td>
</tr>
</table>
</td>
<td valign="top" width="33.333%" style="padding-top: 20px;">
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
<tr>
<td style="text-align: left; padding-left: 5px; padding-right: 5px;">
<h3 class="heading">Contact Info</h3>
<ul>
<li><span class="text">203 Fake St. Mountain View, San Francisco,
California, USA</span></li>
<li><span class="text">+2 392 3929 210</span></a></li>
</ul>
</td>
</tr>
</table>
</td>
<td valign="top" width="33.333%" style="padding-top: 20px;">
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
<tr>
<td style="text-align: left; padding-left: 10px;">
<h3 class="heading">Useful Links</h3>
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Services</a></li>
<li><a href="#">Work</a></li>
</ul>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr><!-- end: tr -->
<tr>
<td class="bg_light" style="text-align: center;">
<p>No longer want to receive these email? You can <a href="#"
style="color: rgba(0,0,0,.8);">Unsubscribe here</a></p>
</td>
</tr>
</table>
</div>
</center>
</body>
</html>

View File

@ -0,0 +1,4 @@
export interface User {
email: string;
name: string;
}

View File

@ -5,6 +5,7 @@
"requires": true,
"packages": {
"": {
"name": "servicio-usuarios",
"version": "0.0.1",
"license": "UNLICENSED",
"dependencies": {

View File

@ -5,7 +5,7 @@ import { UsersService } from './users.service';
@Controller()
export class UsersController {
constructor(private readonly userService: UsersService) {}
constructor(private readonly userService: UsersService) { }
@MessagePattern({ cmd: 'createUser' })
create(@Payload() user: UserDocument) {
@ -17,6 +17,8 @@ export class UsersController {
return this.userService.create(user);
}
@MessagePattern({ cmd: 'findAllUsers' })
findAll() {
return this.userService.findAll();
@ -27,7 +29,7 @@ export class UsersController {
let dni = id['dni'];
return this.userService.findOneByDNI(dni);
}
@MessagePattern({ cmd: 'updateUser' })
update(@Payload() user: UserDocument) {
return this.userService.update(user.id, user);
@ -41,10 +43,10 @@ export class UsersController {
//inicio de sesion
@MessagePattern({ cmd: 'loginUser' })
findLogin(@Payload() body:string) {
let pemail= body['email'];
let ppassword= body['password'];
return this.userService.findLogin(pemail,ppassword);
findLogin(@Payload() body: string) {
let pemail = body['email'];
let ppassword = body['password'];
return this.userService.findLogin(pemail, ppassword);
}
//buscar solo admins del sistema
@ -53,9 +55,15 @@ export class UsersController {
return this.userService.allUsersAdminSistema();
}
//buscar solo admins de comunidad
@MessagePattern({ cmd: 'findAdminComunidad' })
allUsersAdminComunidad() {
return this.userService.allUsersAdminComunidad();
}
//buscar solo admins de comunidad
@MessagePattern({ cmd: 'findAdminComunidad' })
allUsersAdminComunidad() {
return this.userService.allUsersAdminComunidad();
}
//Prueba de envio de correo despues de registro, llamando a microservicio notificaciones
@MessagePattern({ cmd: 'testSendMail' })
testSendMail(@Payload() user: UserDocument) {
return this.userService.testSendMail(user);
}
}

View File

@ -4,9 +4,20 @@ import { MongooseModule } from '@nestjs/mongoose';
import { UsersController } from './users.controller';
import { User, UserSchema } from '../schemas/user.schema';
import { ClientsModule, Transport } from "@nestjs/microservices";
@Module({
imports: [
ClientsModule.register([
{
name: "SERVICIO_NOTIFICACIONES",
transport: Transport.TCP,
options: {
host: "127.0.0.1",
port: 3009
}
}
]),
MongooseModule.forFeature([{ name: User.name, schema: UserSchema }]),
],
controllers: [UsersController],

View File

@ -1,25 +1,32 @@
import { Injectable } from '@nestjs/common';
import { Injectable, Inject } from '@nestjs/common';
import { Model } from 'mongoose';
import { User, UserDocument } from '../schemas/user.schema';
import { InjectModel } from '@nestjs/mongoose';
import {Md5} from "md5-typescript";
import { Md5 } from "md5-typescript";
import { map } from 'rxjs/operators';
import { RpcException, ClientProxy } from '@nestjs/microservices';
@Injectable()
export class UsersService {
constructor(
@InjectModel(User.name) private readonly userModel: Model<UserDocument>,
) {}
@Inject('SERVICIO_NOTIFICACIONES') private readonly clientNotificationtApp: ClientProxy,
) { }
private publicKey: string;
async create(user: UserDocument): Promise<User> {
let passwordEncriptada=Md5.init(user.password);
user.password=passwordEncriptada;
let passwordEncriptada = Md5.init(user.password);
user.password = passwordEncriptada;
return this.userModel.create(user);
}
async findAll(): Promise<User[]> {
async findAll(): Promise<User[]> {
return this.userModel
.find()
.setOptions({ sanitizeFilter: true })
.find()
.setOptions({ sanitizeFilter: true })
.exec();
}
async findOne(id: string): Promise<User> {
@ -41,18 +48,18 @@ export class UsersService {
}
//inicio de sesion
async findLogin(email: string, password: string) : Promise<User> {
let repo1=this.userModel;
async findLogin(email: string, password: string): Promise<User> {
let repo1 = this.userModel;
let userReturn = new Promise<User>((resolve, reject) => {
let repo =repo1;
let repo = repo1;
repo.find({ email : email }).exec((err, res) => {
repo.find({ email: email }).exec((err, res) => {
if (err) {
reject(err);
}
else {
let passwordEncriptada=Md5.init(password);
if (res[0].password==passwordEncriptada) {
let passwordEncriptada = Md5.init(password);
if (res[0].password == passwordEncriptada) {
resolve(res[0]);
}
else {
@ -61,19 +68,35 @@ export class UsersService {
}
});
});
return userReturn;
return userReturn;
}
//find admin del sistema
async allUsersAdminSistema(): Promise<User[]> {
async allUsersAdminSistema(): Promise<User[]> {
return this.userModel.find({ user_type: 1 }).exec();
}
//find admin de comunidad
async allUsersAdminComunidad(): Promise<User[]> {
return this.userModel.find({ user_type: 2 }).exec();
}
//find admin de comunidad
async allUsersAdminComunidad(): Promise<User[]> {
return this.userModel.find({ user_type: 2 }).exec();
}
async testSendMail(user: UserDocument) {
let passwordEncriptada = Md5.init(user.password);
user.password = passwordEncriptada;
this.userModel.create(user)
/*.then(() => {
} );*/
const pattern = { cmd: 'html' };
const payload = { email: user['email'], name: user['name'] };
return this.clientNotificationtApp
.send<string>(pattern, payload)
.pipe(
map((message: string) => ({ message })),
);
}
}