diff --git a/package-lock.json b/package-lock.json
index d471d79..a27c0b9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -22,6 +22,8 @@
"class-transformer": "^0.5.1",
"class-validator": "^0.14.1",
"cookie-parser": "^1.4.7",
+ "handlebars": "^4.7.8",
+ "joi": "^17.13.3",
"jsonwebtoken": "^9.0.2",
"jwk-to-pem": "^2.0.7",
"mssql": "^10.0.4",
@@ -1422,6 +1424,21 @@
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
+ "node_modules/@hapi/hoek": {
+ "version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
+ "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@hapi/topo": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz",
+ "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@hapi/hoek": "^9.0.0"
+ }
+ },
"node_modules/@humanfs/core": {
"version": "0.19.1",
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
@@ -3320,6 +3337,27 @@
"url": "https://ko-fi.com/killymxi"
}
},
+ "node_modules/@sideway/address": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz",
+ "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@hapi/hoek": "^9.0.0"
+ }
+ },
+ "node_modules/@sideway/formula": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz",
+ "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@sideway/pinpoint": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz",
+ "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==",
+ "license": "BSD-3-Clause"
+ },
"node_modules/@sinclair/typebox": {
"version": "0.27.8",
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
@@ -8598,7 +8636,6 @@
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz",
"integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==",
"license": "MIT",
- "optional": true,
"dependencies": {
"minimist": "^1.2.5",
"neo-async": "^2.6.2",
@@ -8620,7 +8657,6 @@
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"license": "BSD-3-Clause",
- "optional": true,
"engines": {
"node": ">=0.10.0"
}
@@ -10351,6 +10387,19 @@
"url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
+ "node_modules/joi": {
+ "version": "17.13.3",
+ "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz",
+ "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@hapi/hoek": "^9.3.0",
+ "@hapi/topo": "^5.1.0",
+ "@sideway/address": "^4.1.5",
+ "@sideway/formula": "^3.0.1",
+ "@sideway/pinpoint": "^2.0.0"
+ }
+ },
"node_modules/js-beautify": {
"version": "1.15.4",
"resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.15.4.tgz",
@@ -12134,7 +12183,6 @@
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
- "devOptional": true,
"license": "MIT"
},
"node_modules/nice-try": {
@@ -16784,8 +16832,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
"integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==",
- "license": "MIT",
- "optional": true
+ "license": "MIT"
},
"node_modules/wrap-ansi": {
"version": "6.2.0",
diff --git a/package.json b/package.json
index 6f214e7..74c643a 100644
--- a/package.json
+++ b/package.json
@@ -33,6 +33,8 @@
"class-transformer": "^0.5.1",
"class-validator": "^0.14.1",
"cookie-parser": "^1.4.7",
+ "handlebars": "^4.7.8",
+ "joi": "^17.13.3",
"jsonwebtoken": "^9.0.2",
"jwk-to-pem": "^2.0.7",
"mssql": "^10.0.4",
diff --git a/public/mail-templates/a.hbs b/public/mail-templates/a.hbs
new file mode 100644
index 0000000..6867289
--- /dev/null
+++ b/public/mail-templates/a.hbs
@@ -0,0 +1,14 @@
+
+
+
🔐 Registration Initiated
+
A Registration has been successfully initiated for the email: {{to}}
+
Please click below to complete your registration:
+
+ Register Now
+
+
+
Powered by
+

+
+
+
diff --git a/public/mail-templates/demo.hbs b/public/mail-templates/demo.hbs
new file mode 100644
index 0000000..0228967
--- /dev/null
+++ b/public/mail-templates/demo.hbs
@@ -0,0 +1 @@
+Testing....
\ No newline at end of file
diff --git a/src/auth/auth.controller.ts b/src/auth/auth.controller.ts
index b5eb36e..b3d6de6 100644
--- a/src/auth/auth.controller.ts
+++ b/src/auth/auth.controller.ts
@@ -1,14 +1,21 @@
-import { Body, Controller, Get, HttpCode, Post, Put, Req, Res, UseInterceptors } from '@nestjs/common';
+import { Body, Controller, Get, HttpCode, Post, Put, Req, Res, UseGuards, UseInterceptors } from '@nestjs/common';
import { AuthService } from './auth.service';
import { ApiTags } from '@nestjs/swagger';
-import { AuthLoginDTO } from './auth.dto';
+import { AuthLoginDTO, SendMailDTO } from './auth.dto';
import { Request, Response } from 'express';
import { LogoutInterceptor } from 'src/interceptors/logout.interceptor';
+import { RegisterGuard } from 'src/guards/register.guard';
+import { UserMaintenanceService } from 'src/oracle/user-maintenance/user-maintenance.service';
+import { RolesGuard } from 'src/guards/roles.guard';
+import { Roles } from 'src/decorators/roles.decorator';
@ApiTags('Auth')
@Controller()
export class AuthController {
- constructor(private readonly authService: AuthService) { }
+ constructor(
+ private readonly authService: AuthService,
+ private readonly userMaintenanceService: UserMaintenanceService
+ ) { }
@Post('login')
@HttpCode(200)
@@ -36,7 +43,7 @@ export class AuthController {
return { statusCode: 200, message: "Logged-In Successfully", email: k.email }
}
- // @UseGuards(RegisterGuard)
+ @UseGuards(RegisterGuard)
@Post('register')
async register(@Body() body: AuthLoginDTO, @Req() req: Request) {
return this.authService.registerUser(body, req);
@@ -87,6 +94,15 @@ export class AuthController {
return { statusCode: 200, message: "Tokens refreshed successfully" }
}
+ @UseGuards(RolesGuard)
+ @Roles('sa')
+ @Post('sendmail')
+ @HttpCode(200)
+ async sendMail(@Body() body: SendMailDTO) {
+ // let token = await this.jwtService.generateToken({ email: mail })
+ return this.authService.sendMail(body);
+ }
+
// @Get('checkRoles')
// @UseGuards(JwtAuthGuard, RolesGuard)
// @Roles('ca')
diff --git a/src/auth/auth.dto.ts b/src/auth/auth.dto.ts
index b5e2dd1..0946576 100644
--- a/src/auth/auth.dto.ts
+++ b/src/auth/auth.dto.ts
@@ -1,5 +1,6 @@
import { ApiProperty } from '@nestjs/swagger';
-import { IsString } from 'class-validator';
+import { Transform, Type } from 'class-transformer';
+import { IsEmail, IsEnum, IsString, ValidateNested } from 'class-validator';
export class AuthLoginDTO {
@ApiProperty({ required: true })
@@ -9,4 +10,57 @@ export class AuthLoginDTO {
@ApiProperty({ required: true })
@IsString()
P_PASSWORD: string;
+}
+
+export enum MailTypeDTO {
+ REGISTER_CLIENT = "REGISTER_CLIENT",
+ REGISTER_SP = "REGISTER_SP",
+ REGISTER_USCIB = "REGISTER_USCIB",
+ FORGOT_PASSWORD = "FORGOT_PASSWORD"
+ // DEMO_MAIL = "DEMO_MAIL"
+}
+
+export class SendMailDTO {
+ @ApiProperty({ required: true, example: 'user@example.com' })
+ @IsEmail({}, { message: 'P_TO must be a valid email address' })
+ P_TO: string;
+
+ @ApiProperty({ enum: MailTypeDTO, required: true })
+ @Transform(({ value }) => value?.toUpperCase())
+ @IsEnum(MailTypeDTO, { message: "Invalid P_MAIL_TYPE" })
+ P_MAIL_TYPE: MailTypeDTO;
+}
+
+export class MailContextDTO {
+ @ApiProperty({ required: true })
+ @IsString()
+ to: string;
+
+ @ApiProperty({ required: true })
+ @IsString()
+ url: string;
+
+}
+
+export class MailTemplateDTO {
+ @ApiProperty({ required: true })
+ @IsString()
+ to: string;
+
+ @ApiProperty({ required: true })
+ @IsString()
+ subject: string;
+
+ // @ApiProperty({ required: true })
+ // @IsString()
+ // text: string;
+
+ @ApiProperty({ required: true })
+ @IsString()
+ template: string;
+
+ @ApiProperty({ type: () => MailContextDTO, required: true })
+ @ValidateNested()
+ @Type(() => MailContextDTO)
+ context: MailContextDTO;
}
\ No newline at end of file
diff --git a/src/auth/auth.module.ts b/src/auth/auth.module.ts
index 8e60c3f..4797f19 100644
--- a/src/auth/auth.module.ts
+++ b/src/auth/auth.module.ts
@@ -1,11 +1,59 @@
-import { Module } from '@nestjs/common';
+import { forwardRef, Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { DbModule } from 'src/db/db.module';
+import { ConfigService } from '@nestjs/config';
+import { JwtService } from '@nestjs/jwt';
+import { OracleModule } from 'src/oracle/oracle.module';
@Module({
- imports: [DbModule],
- providers: [AuthService],
+ imports: [DbModule, forwardRef(() => OracleModule)],
+ providers: [
+ AuthService,
+ {
+ provide: "REGISTER_SIGN_JWT",
+ useFactory: (config: ConfigService) => {
+ const base64Key = config.get('JWT_REGISTER_PRIVATE_KEY');
+ if (!base64Key) {
+ throw new Error('JWT_REGISTER_PRIVATE_KEY is not defined in the config');
+ }
+ const secretKey = Buffer.from(base64Key, 'base64').toString('utf-8');
+
+ const expiry = config.get('JWT_REGISTER_EXPIRY');
+
+ if (!expiry) {
+ throw new Error('JWT_REGISTER_PRIVATE_KEY is not defined in the config');
+ }
+
+ return new JwtService({
+ secret: secretKey,
+ signOptions: {
+ expiresIn: expiry,
+ algorithm: 'ES384'
+ },
+ })
+ },
+ inject: [ConfigService],
+ },
+ {
+ provide: "REGISTER_VERIFY_JWT",
+ useFactory: (config: ConfigService) => {
+ const base64Key = config.get('JWT_REGISTER_PUBLIC_KEY');
+ if (!base64Key) {
+ throw new Error('JWT_REGISTER_PRIVATE_KEY is not defined in the config');
+ }
+ const secretKey = Buffer.from(base64Key, 'base64').toString('utf-8');
+
+ return new JwtService({
+ secret: secretKey,
+ verifyOptions: {
+ algorithms: ['ES384']
+ }
+ })
+ },
+ inject: [ConfigService],
+ }
+ ],
controllers: [AuthController],
exports: [AuthService]
})
diff --git a/src/auth/auth.service.ts b/src/auth/auth.service.ts
index 9e5a48b..683b45d 100644
--- a/src/auth/auth.service.ts
+++ b/src/auth/auth.service.ts
@@ -1,6 +1,6 @@
-import { Injectable, InternalServerErrorException } from '@nestjs/common';
+import { Inject, Injectable, InternalServerErrorException } from '@nestjs/common';
import { OracleDBService } from 'src/db/db.service';
-import { AuthLoginDTO } from './auth.dto';
+import { AuthLoginDTO, MailTemplateDTO, MailTypeDTO, SendMailDTO } from './auth.dto';
import * as oracledb from 'oracledb';
import { ConfigService } from '@nestjs/config';
import axios, { AxiosRequestConfig } from 'axios';
@@ -10,6 +10,9 @@ import * as jwt from "jsonwebtoken"
import { UnauthorizedException } from 'src/exceptions/unauthorized.exception';
import { ConflictException } from 'src/exceptions/conflict.exception';
import { BadRequestException } from 'src/exceptions/badRequest.exception';
+import { MailerService } from '@nestjs-modules/mailer';
+import { JwtService } from '@nestjs/jwt';
+import { UserMaintenanceService } from 'src/oracle/user-maintenance/user-maintenance.service';
interface DecodedToken {
email: string;
@@ -33,11 +36,25 @@ export class AuthService {
private readonly CLIENT_SECRET: string;
private readonly TOKEN_URL: string;
private readonly USERS_URL: string;
+ private readonly JWT_REGISTER_PRIVATE_KEY: string;
+ private readonly JWT_REGISTER_PUBLIC_KEY: string;
constructor(
private readonly oracleDBService: OracleDBService,
private readonly configService: ConfigService,
+ private readonly mailService: MailerService,
+ private readonly userMaintenanceService: UserMaintenanceService,
+ @Inject("REGISTER_SIGN_JWT") readonly REGISTER_SIGN_JWT: JwtService,
+ @Inject("REGISTER_VERIFY_JWT") readonly REGISTER_VERIFY_JWT: JwtService
) {
+ const JWT_REGISTER_PRIVATE_KEY = this.configService.get('JWT_REGISTER_PRIVATE_KEY');
+ if (!JWT_REGISTER_PRIVATE_KEY) throw new Error('Environment variable JWT_REGISTER_PRIVATE_KEY is not set');
+ this.JWT_REGISTER_PRIVATE_KEY = Buffer.from(JWT_REGISTER_PRIVATE_KEY, 'base64').toString('utf-8');
+
+ const JWT_REGISTER_PUBLIC_KEY = this.configService.get('JWT_REGISTER_PUBLIC_KEY');
+ if (!JWT_REGISTER_PUBLIC_KEY) throw new Error('Environment variable JWT_REGISTER_PRIVATE_KEY is not set');
+ this.JWT_REGISTER_PUBLIC_KEY = Buffer.from(JWT_REGISTER_PUBLIC_KEY, 'base64').toString('utf-8');
+
const KEYCLOAK_URL = this.configService.get('KEYCLOAK_URL');
if (!KEYCLOAK_URL) throw new Error('Environment variable KEYCLOAK_URL is not set');
this.KEYCLOAK_URL = KEYCLOAK_URL;
@@ -190,7 +207,7 @@ export class AuthService {
}
}
- async getUserSession(email:string) {
+ async getUserSession(email: string) {
try {
const uid = await this.getUserIdByEmail(email);
@@ -258,7 +275,7 @@ export class AuthService {
if (access_token && refresh_token && userSession.length > 0) {
let tokens = await this.getTokenFromRefreshToken(req);
const decoded = jwt.decode(access_token, { complete: true });
- const email:any = (decoded && typeof decoded === 'object') ? (decoded as any).payload?.email : undefined;
+ const email: any = (decoded && typeof decoded === 'object') ? (decoded as any).payload?.email : undefined;
return { ...tokens, email }
}
@@ -323,25 +340,6 @@ export class AuthService {
password: `${'A1!bcdef'}`,
});
- let userID = await this.getUserIdByEmail("");
-
- let resetPasswordURL = `${this.USERS_URL}/${userID}/reset-password`;
-
- let adminAccessToken = await this.getAdminAccessToken();
-
- const options1: AxiosRequestConfig = {
- method: 'PUT',
- url: resetPasswordURL,
- headers: {
- Authorization: `Bearer ${adminAccessToken}`
- },
- data: {
- type: 'password',
- value: 'A1!bcdef',
- temporary: false,
- }
- };
-
const options2: AxiosRequestConfig = {
method: 'POST',
url: this.TOKEN_URL,
@@ -427,21 +425,45 @@ export class AuthService {
const uid = await this.getUserIdByEmail(body.P_EMAILADDR);
- const res = await this.assignRoleToUser(uid, "ca");
+ let ROLE = "";
+
+ const response: any = await this.userMaintenanceService.ValidateEmail({ P_EMAILADDR: body.P_EMAILADDR })
+
+
+ if (Array.isArray(response) && !response[0].ERRORMESG) {
+ switch (response[0].SOURCE) {
+ case "USCIB": ROLE = 'ua'; break;
+ case "SP": ROLE = 'sa'; break;
+ case "CLIENT": ROLE = 'ca'; break;
+ }
+ }
+ else if (Array.isArray(response) && response[0].ERRORMESG) {
+ throw new BadRequestException();
+ }
+
+ if (!ROLE) {
+ console.log("ERROR while giving access : ");
+ throw new InternalServerErrorException();
+ }
+
+ const res = await this.assignRoleToUser(uid, ROLE);
console.log(res);
- return { message: 'User created successfully' };
+ return { statusCode: 201, message: 'User registered successfully' };
}
} catch (error) {
- // handle errors like user exists, validation errors, etc.
console.log(error.message);
if (error.message === "Request failed with status code 409") {
throw new ConflictException("User already exist");
}
-
+ else if (error instanceof BadRequestException) {
+ console.log("ERROR while registering : ", error.message);
+ return error;
+ }
+ console.log("ERROR while giving access : ", error.message);
throw new InternalServerErrorException('Failed to create user');
}
}
@@ -601,4 +623,80 @@ export class AuthService {
throw new UnauthorizedException('Authentication failed');
}
}
+
+ async getMailTemplate(body: SendMailDTO, token: string, source: string): Promise {
+
+ switch (body.P_MAIL_TYPE) {
+ case MailTypeDTO.REGISTER_CLIENT:
+ return {
+ to: body.P_TO,
+ subject: `🔐 Register Your Account`,
+ template: 'a',
+ context: {
+ to: body.P_TO,
+ url: `https://client.alphaomegainfosys.com/register/${token}`
+ }
+ }
+ case MailTypeDTO.FORGOT_PASSWORD:
+ return {
+ to: body.P_TO,
+ subject: `🔐 Register Your Account`,
+ template: 'a',
+ context: {
+ to: body.P_TO,
+ url: `https://client.alphaomegainfosys.com/register/${token}`
+ }
+ }
+
+ // case MailTypeDTO.DEMO_MAIL:
+ // return {
+ // to: body.P_TO,
+ // subject: `Testing`,
+ // template: 'demo',
+ // context: {
+ // to: body.P_TO,
+ // url: `https://client.alphaomegainfosys.com/register/${token}`
+ // }
+ // }
+ default:
+ return null;
+ }
+ }
+
+ async sendMail(body: SendMailDTO) {
+ console.log("mail body : ", body);
+ let token: string;
+ let ROLE: string = "";
+
+ try {
+ token = this.REGISTER_SIGN_JWT.sign({ email: body.P_TO });
+ console.log("Register token : ", token);
+
+ if (!token) {
+ console.log("Register Token Generation failed");
+ throw new InternalServerErrorException();
+ }
+ }
+ catch (error) {
+ console.log(error.message);
+
+ throw new InternalServerErrorException("Register Token Generation failed")
+ }
+
+ const mailTemplate: MailTemplateDTO | null = await this.getMailTemplate(body, token, ROLE);
+
+ if (!mailTemplate) {
+ throw new BadRequestException();
+ }
+
+ try {
+ await this.mailService.sendMail({ ...mailTemplate });
+ console.log('Email sent successfully');
+ return { statusCode: 200, message: 'Email sent successfully' };
+ } catch (error) {
+ console.error('Failed to send email:', error.message, error);
+ return { statusCode: 500, message: 'Failed to send email' };
+ }
+ }
+
}
diff --git a/src/guards/register.guard.ts b/src/guards/register.guard.ts
index a0dffc2..3b762be 100644
--- a/src/guards/register.guard.ts
+++ b/src/guards/register.guard.ts
@@ -2,6 +2,7 @@
import {
CanActivate,
ExecutionContext,
+ Inject,
Injectable,
UnauthorizedException,
} from '@nestjs/common';
@@ -10,44 +11,28 @@ import { Request } from 'express';
@Injectable()
export class RegisterGuard implements CanActivate {
- constructor(private readonly jwtService: JwtService) {}
+ constructor(
+ @Inject("REGISTER_VERIFY_JWT") readonly REGISTER_VERIFY_JWT: JwtService
+ ) { }
canActivate(context: ExecutionContext): boolean {
const request = context.switchToHttp().getRequest();
const authHeader = request.headers['authorization'];
if (!authHeader || !authHeader.startsWith('Bearer ')) {
- throw new UnauthorizedException('Authorization header missing or malformed');
+ throw new UnauthorizedException('Invalid Request');
}
const token = authHeader.split(' ')[1];
try {
- // Decode without verifying to check expiry
- const decoded: any = this.jwtService.decode(token);
-
- console.log(decoded);
-
-
- if (!decoded || !decoded.exp) {
- throw new UnauthorizedException('Invalid token payload');
- }
-
- // Check expiration (exp is in seconds, Date.now() in ms)
- const now = Math.floor(Date.now() / 1000);
- if (decoded.exp < now) {
- throw new UnauthorizedException('Token expired');
- }
-
- // Verify the token (checks signature and expiration again)
- this.jwtService.verify(token, {secret:'yourSecretKey'});
-
- // Optionally attach user info to request object for further use
- request['user'] = decoded;
-
+ const payload = this.REGISTER_VERIFY_JWT.verify(token);
+ request['user'] = payload;
return true;
} catch (err) {
- throw new UnauthorizedException('Invalid or expired token');
+ console.log("Error in register guard : ", err.message);
+
+ throw new UnauthorizedException("Invalid Register Token");
}
}
}
diff --git a/src/mail/mail.module.ts b/src/mail/mail.module.ts
index 7f554dd..f763726 100644
--- a/src/mail/mail.module.ts
+++ b/src/mail/mail.module.ts
@@ -1,18 +1,47 @@
import { MailerModule } from '@nestjs-modules/mailer';
import { Module } from '@nestjs/common';
+import { ConfigModule, ConfigService } from '@nestjs/config';
+import { join } from 'path';
+import * as Joi from 'joi';
+import { HandlebarsAdapter } from '@nestjs-modules/mailer/dist/adapters/handlebars.adapter';
@Module({
imports: [
- MailerModule.forRoot({
- transport: {
- host: 'localhost',
- port: 1025,
- ignoreTLS: true,
- },
- defaults: {
- from: '"No Reply" ',
- },
+ ConfigModule.forRoot({
+ isGlobal: true,
+ validationSchema: Joi.object({
+ MAIL_USER: Joi.string().required(),
+ MAIL_PASS: Joi.string().required(),
+ }),
+ }),
+
+ MailerModule.forRootAsync({
+ imports: [ConfigModule],
+ useFactory: (configService: ConfigService) => ({
+ transport: {
+ host: 'smtp.gmail.com',
+ port: 587,
+ // ignoreTLS: true,
+ secure: false,
+ auth: {
+ user: configService.get('MAIL_USER'),
+ pass: configService.get('MAIL_PASS'),
+ },
+ },
+ defaults: {
+ from: `"Carnet APP" <${configService.get('MAIL_USER')}>`,
+ },
+ template: {
+ dir: join(__dirname, '../../..', 'public', 'mail-templates'),
+ adapter: new HandlebarsAdapter(), // import from '@nestjs-modules/mailer/dist/adapters/handlebars.adapter'
+ options: {
+ strict: true,
+ },
+ },
+ }),
+ inject: [ConfigService],
}),
],
})
+
export class MailModule { }
diff --git a/src/oracle/oracle.module.ts b/src/oracle/oracle.module.ts
index 5a6d034..d325bdc 100644
--- a/src/oracle/oracle.module.ts
+++ b/src/oracle/oracle.module.ts
@@ -26,6 +26,6 @@ import { AuthModule } from 'src/auth/auth.module';
],
providers: [OracleService],
controllers: [],
- exports: [OracleService],
+ exports: [OracleService, UserMaintenanceModule],
})
export class OracleModule {}
diff --git a/src/oracle/user-maintenance/user-maintenance.module.ts b/src/oracle/user-maintenance/user-maintenance.module.ts
index 798d15e..11db21b 100644
--- a/src/oracle/user-maintenance/user-maintenance.module.ts
+++ b/src/oracle/user-maintenance/user-maintenance.module.ts
@@ -6,6 +6,7 @@ import { AuthModule } from 'src/auth/auth.module';
@Module({
imports: [AuthModule],
controllers: [UserMaintenanceController],
- providers: [UserMaintenanceService]
+ providers: [UserMaintenanceService],
+ exports: [UserMaintenanceService]
})
export class UserMaintenanceModule { }