Add HOST_LINK environment variable and update related configurations. Normalize email addresses to lowercase in login and registration handlers. Enhance email notifications for approved and rejected applications with HOST_LINK.

This commit is contained in:
2025-12-08 15:08:05 +05:30
parent 9abadba8f5
commit bbd55562af
9 changed files with 46 additions and 22 deletions

View File

@@ -43,6 +43,7 @@ provider:
MINGLAR_ADMIN_NAME: ${env:MINGLAR_ADMIN_NAME}
MINGLAR_ADMIN_EMAIL: ${env:MINGLAR_ADMIN_EMAIL}
AM_INVITATION_LINK: ${env:AM_INVITATION_LINK}
HOST_LINK: ${env:HOST_LINK}
iam:
role:

View File

@@ -82,7 +82,8 @@ const envVarsSchema = yup
//OTP Bypass
BYPASS_OTP: yup.boolean().default(false).required('Bypass OTP is required'),
// Email links
AM_INVITATION_LINK: yup.string().required('Link to send in AM invitation mail is required')
AM_INVITATION_LINK: yup.string().required('Link to send in AM invitation mail is required'),
HOST_LINK: yup.string().required('Link to host panel is required')
})
.noUnknown(true);
@@ -161,6 +162,7 @@ function getConfig() {
MinglarAdminEmail: envVars.MINGLAR_ADMIN_EMAIL,
MinglarAdminName: envVars.MINGLAR_ADMIN_NAME,
AM_INVITATION_LINK: envVars.AM_INVITATION_LINK,
HOST_LINK: envVars.HOST_LINK,
// oneSignal: {
// appID: envVars.ONESIGNAL_APPID,
// restApiKey: envVars.ONESIGNAL_REST_APIKEY,

View File

@@ -15,7 +15,7 @@ export const handler = safeHandler(async (
): Promise<APIGatewayProxyResult> => {
// Parse request body
let body: { emailAddress?: string; userPassword?: string };
try {
body = event.body ? JSON.parse(event.body) : {};
} catch (error) {
@@ -28,7 +28,9 @@ export const handler = safeHandler(async (
throw new ApiError(400, 'Email and password are required');
}
const loginForHost = await hostService.loginForHost(emailAddress, userPassword);
const emailToLowerCase = emailAddress.toLowerCase()
const loginForHost = await hostService.loginForHost(emailToLowerCase, userPassword);
if (!loginForHost) {
throw new ApiError(400, 'Failed to login');
@@ -40,7 +42,7 @@ export const handler = safeHandler(async (
const generateTokenForHost = await tokenService.generateAuthToken(
loginForHost.id
);
);
if (!generateTokenForHost) {
throw new ApiError(500, 'Failed to generate token');

View File

@@ -7,6 +7,7 @@ import ApiError from '../../../../../common/utils/helper/ApiError';
import { encryptUserId } from '../../../../../common/utils/helper/CodeGenerator';
import { OtpGeneratorSixDigit } from '../../../../../common/utils/helper/OtpGenerator';
import { HostService } from '../../../services/host.service';
import { sendOtpEmailForHost } from '@/modules/host/services/sendOTPEmail.service';
const hostService = new HostService(prismaClient);
@@ -44,10 +45,12 @@ export const handler = safeHandler(async (
throw new ApiError(400, 'Email is required');
}
const emailToLowerCase = email.toLowerCase()
// Use a single transaction for user creation/lookup and OTP storage
const transactionResult = await prismaClient.$transaction(async (tx) => {
const user = await tx.user.findUnique({
where: { emailAddress: email },
where: { emailAddress: emailToLowerCase },
select: { emailAddress: true, id: true, userPassword: true },
});
@@ -65,7 +68,7 @@ export const handler = safeHandler(async (
} else {
// create new user record within the transaction
newUserLocal = await tx.user.create({
data: { emailAddress: email, roleXid: ROLE.HOST, userRefNumber: referenceNumber },
data: { emailAddress: emailToLowerCase, roleXid: ROLE.HOST, userRefNumber: referenceNumber },
});
}
@@ -100,7 +103,7 @@ export const handler = safeHandler(async (
}
// Send OTP email outside the DB transaction
// await sendOtpEmailForHost(transactionResult.newUser.emailAddress, transactionResult.otp);
await sendOtpEmailForHost(transactionResult.newUser.emailAddress, transactionResult.otp);
return {
statusCode: 200,

View File

@@ -15,20 +15,22 @@ export const handler = safeHandler(async (
): Promise<APIGatewayProxyResult> => {
// Parse request body
let body: { emailAddress?: string; userPassword?: string };
try {
body = event.body ? JSON.parse(event.body) : {};
} catch (error) {
throw new ApiError(400, 'Invalid JSON in request body');
}
const { emailAddress ,userPassword} = body;
const { emailAddress, userPassword } = body;
if (!emailAddress) {
throw new ApiError(400, 'Email is required');
}
const loginForMinglar = await minglarSerivce.loginForMinglar(emailAddress ,userPassword);
const emailToLowerCase = emailAddress.toLowerCase()
const loginForMinglar = await minglarSerivce.loginForMinglar(emailToLowerCase, userPassword);
if (!loginForMinglar) {
throw new ApiError(400, 'Failed to login');

View File

@@ -5,6 +5,7 @@ import { safeHandler } from '../../../common/utils/handlers/safeHandler';
import ApiError from '../../../common/utils/helper/ApiError';
import { generateOtpHelper } from '../../../common/utils/helper/sendOtp';
import { MinglarService } from './../services/minglar.service';
import { sendOtpEmailForMinglarAdmin } from '../services/sendOTPEmail.service';
const minglarService = new MinglarService(prismaClient);
@@ -26,11 +27,15 @@ export const handler = safeHandler(async (
if (!email) {
throw new ApiError(400, 'Email is required');
}
console.log(email, " -: Email")
const emailToLowerCase = email.toLowerCase()
const user = await prismaClient.user.findUnique({
where: { emailAddress: email, isActive: true, userStatus: USER_STATUS.INVITED },
where: { emailAddress: emailToLowerCase, isActive: true, userStatus: USER_STATUS.INVITED },
select: { emailAddress: true, id: true, userPassword: true, roleXid: true },
});
console.log(user, "sljdfjdf")
if (!user) {
throw new ApiError(403, 'You are not allowed to register directly. Please contact minglar admin.');
@@ -66,7 +71,7 @@ export const handler = safeHandler(async (
throw new ApiError(500, 'Failed to send OTP');
}
// await sendOtpEmailForMinglarAdmin(newUser?.emailAddress, otpResult.otp);
await sendOtpEmailForMinglarAdmin(newUser?.emailAddress, otpResult.otp);
return {
statusCode: 200,

View File

@@ -61,6 +61,8 @@ export const handler = safeHandler(async (
throw new ApiError(400, 'Role is required');
}
const emailToLowerCase = emailAddress.toLowerCase()
// Validate role is either Co_Admin or Account_Manager
if (![ROLE.CO_ADMIN, ROLE.ACCOUNT_MANAGER].includes(roleXid)) {
throw new ApiError(400, 'Invalid role. Only Co_Admin and Account_Manager roles can be assigned.');
@@ -79,7 +81,7 @@ export const handler = safeHandler(async (
// Use single service method that encapsulates the transaction
await minglarService.inviteTeammate(
emailAddress,
emailToLowerCase,
roleXid,
isFixedSalary,
perValue || 0,
@@ -87,7 +89,7 @@ export const handler = safeHandler(async (
);
// send email after transaction commits
await sendInvitationEmailForMinglarAdmin(emailAddress, config.AM_INVITATION_LINK);
await sendInvitationEmailForMinglarAdmin(emailToLowerCase, config.AM_INVITATION_LINK);
return {
statusCode: 200,

View File

@@ -1,5 +1,6 @@
import { brevoService } from "@/common/email/brevoApi";
import ApiError from "@/common/utils/helper/ApiError";
import { brevoService } from "../../../common/email/brevoApi";
import ApiError from "../../../common/utils/helper/ApiError";
import config from "../../../config/config";
export async function sendEmailToHostForApprovedApplication(
emailAddress: string,
@@ -14,6 +15,8 @@ export async function sendEmailToHostForApprovedApplication(
<p>Dear Host,</p>
<p>Congratulations, Your application to minglar admin has been approved.</p>
<p>You can start onboarding your activities through the host panel.</p>
<p> You can login to your account using the link below:<br/>
<strong>Link:</strong> ${config.HOST_LINK} </p>
<p>Best regards,<br/>Minglar Team</p>
`;

View File

@@ -1,5 +1,6 @@
import { brevoService } from "@/common/email/brevoApi";
import ApiError from "@/common/utils/helper/ApiError";
import { brevoService } from "../../../common/email/brevoApi";
import ApiError from "../../../common/utils/helper/ApiError";
import config from "../../../config/config";
export async function sendEmailToHostForRejectedApplication(
emailAddress: string,
@@ -47,10 +48,13 @@ export async function sendAMRejectionMailtoHost(
const htmlContent = `
<p>Dear Host,</p>
<p>Your account manager has made some suggestions on your application.<br/>
Please improve it and re-submit the application to onboard on minglar.</p>
<p>If you have any questions please contact to minglar admin.</p>
<p>Best regards,<br/>Minglar Team</p>
<p> Your account manager has reviewed your application and provided some suggestions. <br/>
Please make the necessary improvements and re-submit your application to proceed with the onboarding process on Minglar.</p>
<p> You may access your application using the link below:<br/>
<strong>Link:</strong> ${config.HOST_LINK} </p>
<p> If you have any questions, please feel free to contact the Minglar Support Team. </p>
<p> Best regards,<br/>
<strong>Minglar Team</strong> </p>
`;
try {