Merge pull request

This commit is contained in:
prafull-opensignlabs
2025-04-05 06:01:24 +00:00
parent fca45ced38
commit d7b7ad6285
49 changed files with 992 additions and 1443 deletions
@@ -61,7 +61,7 @@ async function addTeamAndOrg(extUser) {
async function saveUser(userDetails) {
const userQuery = new Parse.Query(Parse.User);
userQuery.equalTo('username', userDetails.email);
userQuery.equalTo('username', userDetails.email?.toLowerCase()?.replace(/\s/g, ''));
const userRes = await userQuery.first({ useMasterKey: true });
if (userRes) {
@@ -83,9 +83,9 @@ async function saveUser(userDetails) {
return { id: login.objectId, sessionToken: login.sessionToken };
} else {
const user = new Parse.User();
user.set('username', userDetails.email);
user.set('username', userDetails.email?.toLowerCase()?.replace(/\s/g, ''));
user.set('password', userDetails.password);
user.set('email', userDetails.email);
user.set('email', userDetails.email?.toLowerCase()?.replace(/\s/g, ''));
if (userDetails?.phone) {
user.set('phone', userDetails.phone);
}
@@ -111,7 +111,6 @@ export default async function AddAdmin(request) {
if (extUser) {
return { message: 'User already exist' };
} else {
// console.log("role ", role);
const partnerQuery = new Parse.Object('partners_Tenant');
partnerQuery.set('UserId', {
__type: 'Pointer',
@@ -123,7 +122,7 @@ export default async function AddAdmin(request) {
partnerQuery.set('ContactNumber', userDetails.phone);
}
partnerQuery.set('TenantName', userDetails.company);
partnerQuery.set('EmailAddress', userDetails.email);
partnerQuery.set('EmailAddress', userDetails.email?.toLowerCase()?.replace(/\s/g, ''));
partnerQuery.set('IsActive', true);
partnerQuery.set('CreatedBy', {
__type: 'Pointer',
@@ -154,7 +153,7 @@ export default async function AddAdmin(request) {
objectId: user.id,
});
newObj.set('UserRole', userDetails.role);
newObj.set('Email', userDetails.email);
newObj.set('Email', userDetails.email?.toLowerCase()?.replace(/\s/g, ''));
newObj.set('Name', userDetails.name);
if (userDetails?.phone) {
newObj.set('Phone', userDetails?.phone);
@@ -177,7 +176,7 @@ export default async function AddAdmin(request) {
const extUser = {
objectId: extRes.id,
Name: userDetails.name,
Email: userDetails.email,
Email: userDetails.email?.toLowerCase()?.replace(/\s/g, ''),
Phone: userDetails?.phone ? userDetails.phone : '',
TenantId: { objectId: tenantRes.id },
UserId: { objectId: user.id },
@@ -28,6 +28,7 @@ export default async function forwardDoc(request) {
const docName = _docRes.Name;
const fileAdapterId = _docRes?.FileAdapterId || '';
const extUserId = _docRes?.ExtUserPtr?.objectId;
const TenantAppName = appName;
const from = _docRes?.ExtUserPtr?.Email;
const replyTo = _docRes?.ExtUserPtr?.Email;
const senderName = _docRes?.ExtUserPtr?.Name;
@@ -51,8 +52,8 @@ export default async function forwardDoc(request) {
`<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/></head><body><div style='background-color:#f5f5f5;padding:20px'><div style='background-color:white'><div>` +
`${logo}</div><div style='padding:2px;font-family:system-ui;background-color:${themeColor}'><p style='font-size:20px;font-weight:400;color:white;padding-left:20px'>Document Copy</p></div><div>` +
`<p style='padding:20px;font-family:system-ui;font-size:14px'>A copy of the document <strong>${docName}</strong> is attached to this email. Kindly download the document from the attachment.</p>` +
`</div></div><div><p>This is an automated email from ${appName}. For any queries regarding this email, please contact the sender ${replyTo} directly. ` +
`If you think this email is inappropriate or spam, you may file a complaint with ${appName}${opurl}.</p></div></div></body></html>`,
`</div></div><div><p>This is an automated email from ${TenantAppName}. For any queries regarding this email, please contact the sender ${replyTo} directly. ` +
`If you think this email is inappropriate or spam, you may file a complaint with ${TenantAppName}${opurl}.</p></div></div></body></html>`,
};
mailRes = await axios.post(`${cloudServerUrl}/functions/sendmailv3`, params, {
headers: {
@@ -6,13 +6,17 @@ export default async function GetLogoByDomain(request) {
try {
const tenantCreditsQuery = new Parse.Query('partners_Tenant');
tenantCreditsQuery.equalTo('Domain', domain);
const res = await tenantCreditsQuery.first();
const res = await tenantCreditsQuery.first({ useMasterKey: true });
if (res) {
const updateRes = JSON.parse(JSON.stringify(res));
return { logo: updateRes?.Logo, appname: appName, user: 'exist' };
return {
logo: updateRes?.Logo,
appname: appName,
user: 'exist',
};
} else {
const tenantCreditsQuery = new Parse.Query('partners_Tenant');
const tenantRes = await tenantCreditsQuery.first();
const tenantRes = await tenantCreditsQuery.first({ useMasterKey: true });
if (tenantRes) {
return { logo: '', appname: appName, user: 'exist' };
} else {
@@ -1,7 +1,7 @@
import axios from 'axios';
export default async function Newsletter(request) {
const name = request.params.name;
const email = request.params.email;
const email = request.params?.email?.toLowerCase()?.replace(/\s/g, '');
const domain = request.params.domain;
try {
const envAppId = process.env.REACT_APP_APPID || 'opensign';
@@ -22,19 +22,20 @@ async function sendMailOTPv1(request) {
//--for elearning app side
let code = Math.floor(1000 + Math.random() * 9000);
let email = request.params.email;
var TenantId = request.params.TenantId ? request.params.TenantId : undefined;
let TenantId = request.params.TenantId ? request.params.TenantId : undefined;
const AppName = appName;
if (email) {
const recipient = request.params.email;
const mailsender = smtpenable ? process.env.SMTP_USER_EMAIL : process.env.MAILGUN_SENDER;
try {
await Parse.Cloud.sendEmail({
from: appName + ' <' + mailsender + '>',
from: AppName + ' <' + mailsender + '>',
recipient: recipient,
subject: `Your ${appName} OTP`,
subject: `Your ${AppName} OTP`,
text: 'This email is a test.',
html:
`<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /></head><body><div style='background-color:#f5f5f5;padding:20px'><div style='box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px;background-color:white;'><div style='background-color:red;padding:2px;font-family:system-ui; background-color:#47a3ad;'> <p style='font-size:20px;font-weight:400;color:white;padding-left:20px',>OTP Verification</p></div><div style='padding:20px'><p style='font-family:system-ui;font-size:14px'>Your OTP for ${appName} verification is:</p><p style=' text-decoration: none; font-weight: bolder; color:blue;font-size:45px;margin:20px'>` +
`<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /></head><body><div style='background-color:#f5f5f5;padding:20px'><div style='box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px;background-color:white;'><div style='background-color:red;padding:2px;font-family:system-ui; background-color:#47a3ad;'> <p style='font-size:20px;font-weight:400;color:white;padding-left:20px',>OTP Verification</p></div><div style='padding:20px'><p style='font-family:system-ui;font-size:14px'>Your OTP for ${AppName} verification is:</p><p style=' text-decoration: none; font-weight: bolder; color:blue;font-size:45px;margin:20px'>` +
code +
'</p></div> </div> </div></body></html>',
});
@@ -1,108 +0,0 @@
import axios from 'axios';
import { cloudServerUrl } from '../../Utils.js';
export default async function callWebhook(request) {
const event = request.params.event;
const body = request.params.body;
const docId = body.objectId;
const contactId = request.params.contactId;
const serverUrl = cloudServerUrl; //process.env.SERVER_URL;
const appId = process.env.APP_ID;
try {
const docQuery = new Parse.Query('contracts_Document');
docQuery.include('ExtUserPtr.TenantId');
const docRes = await docQuery.get(docId, { useMasterKey: true });
const isEnableOTP = docRes?.get('IsEnableOTP') || false;
let userId;
if (isEnableOTP) {
const userRes = await axios.get(serverUrl + '/users/me', {
headers: {
'X-Parse-Application-Id': appId,
'X-Parse-Session-Token': request.headers['sessiontoken'],
},
});
userId = userRes.data && userRes.data.objectId;
}
if (!isEnableOTP || userId) {
if (event === 'viewed' && contactId) {
if (docRes) {
const _docRes = docRes.toJSON();
const userPtr = {
__type: 'Pointer',
className: 'contracts_Contactbook',
objectId: contactId,
};
const date = new Date().toISOString();
const obj = {
UserPtr: userPtr,
SignedUrl: _docRes.SignedUrl,
Activity: 'Viewed',
ipAddress: request.headers['x-real-ip'],
ViewedOn: date,
};
const isUserExist = _docRes?.AuditTrail?.some(
x => x.UserPtr.objectId === contactId && x?.ViewedOn
);
if (!isUserExist) {
const updateDoc = new Parse.Object('contracts_Document');
updateDoc.id = docRes.id;
if (_docRes?.AuditTrail && _docRes?.AuditTrail?.length > 0) {
updateDoc.set('AuditTrail', [..._docRes?.AuditTrail, obj]);
} else {
updateDoc.set('AuditTrail', [obj]);
}
await updateDoc.save(null, { useMasterKey: true });
}
}
}
const extendcls = new Parse.Query('contracts_Users');
extendcls.equalTo('objectId', docRes.get('ExtUserPtr')?.id);
// extendcls.equalTo('UserId', { __type: 'Pointer', className: '_User', objectId: userId });
const resExt = await extendcls.first({ useMasterKey: true });
if (resExt) {
const extUser = JSON.parse(JSON.stringify(resExt));
if (extUser?.Webhook) {
const params = { event: event, ...body };
await axios
.post(extUser?.Webhook, params, {
headers: { 'Content-Type': 'application/json' },
})
.then(res => {
try {
const webhook = new Parse.Object('contracts_Webhook');
webhook.set('Log', res?.status);
webhook.set('UserId', {
__type: 'Pointer',
className: '_User',
objectId: userId,
});
webhook.save(null, { useMasterKey: true });
} catch (err) {
console.log('err save in contracts_Webhook', err.message);
}
})
.catch(err => {
console.log('Err send data to webhook', err.message);
try {
const webhook = new Parse.Object('contracts_Webhook');
webhook.set('Log', err?.status);
webhook.set('UserId', {
__type: 'Pointer',
className: '_User',
objectId: userId,
});
webhook.save(null, { useMasterKey: true });
} catch (err) {
console.log('err save in contracts_Webhook', err.message);
}
});
}
return { message: 'webhook called!' };
}
} else {
return { message: 'User not found!' };
}
} catch (err) {
console.log('Err in callwebhook', err);
return { message: 'Something went wrong!' };
}
}
@@ -21,7 +21,7 @@ export default async function createBatchContact(req) {
TenantId: { __type: 'Pointer', className: 'partners_Tenant', objectId: x.TenantId },
CreatedBy: { __type: 'Pointer', className: '_User', objectId: req.user.id },
Name: x.Name,
Email: x.Email,
Email: x.Email?.toLowerCase()?.replace(/\s/g, ''),
IsDeleted: false,
IsImported: true,
...(x?.Phone ? { Phone: `${x?.Phone}` } : {}),
@@ -1,14 +1,8 @@
import axios from 'axios';
import {
cloudServerUrl,
replaceMailVaribles,
} from '../../Utils.js';
import { cloudServerUrl, replaceMailVaribles } from '../../Utils.js';
const serverUrl = cloudServerUrl; //process.env.SERVER_URL;
const appId = process.env.APP_ID;
async function deductcount(
docsCount,
extUserId,
) {
async function deductcount(docsCount, extUserId) {
try {
const extCls = new Parse.Object('contracts_Users');
extCls.id = extUserId;
@@ -18,9 +12,9 @@ async function deductcount(
console.log('Err in deduct in quick send', err);
}
}
async function sendMail(document) {
async function sendMail(document, publicUrl) {
//sessionToken
const baseUrl = new URL(process.env.PUBLIC_URL);
const baseUrl = new URL(publicUrl); //process.env.PUBLIC_URL
// console.log("pdfDetails", pdfDetails);
const timeToCompleteDays = document?.TimeToCompleteDays || 15;
@@ -33,10 +27,8 @@ async function sendMail(document) {
year: 'numeric',
});
let signerMail = document.Placeholders;
const senderName =
document.ExtUserPtr.Name;
const senderEmail =
document.ExtUserPtr.Email;
const senderName = document.ExtUserPtr.Name;
const senderEmail = document.ExtUserPtr.Email;
if (document.SendinOrder) {
signerMail = signerMail.slice();
@@ -70,6 +62,7 @@ async function sendMail(document) {
'</body></html>';
const variables = {
document_title: document?.Name,
note: document?.Note || '',
sender_name: senderName,
sender_mail: senderEmail,
sender_phone: senderObj?.Phone || '',
@@ -83,6 +76,7 @@ async function sendMail(document) {
replaceVar = replaceMailVaribles(mailSubject, htmlReqBody, variables);
}
const mailparam = {
note: document?.Note || '',
senderName: senderName,
senderMail: senderEmail,
title: document.Name,
@@ -94,8 +88,7 @@ async function sendMail(document) {
extUserId: document.ExtUserPtr.objectId,
recipient: objectId ? existSigner?.Email : signerMail[i].email,
subject: replaceVar?.subject ? replaceVar?.subject : mailTemplate(mailparam).subject,
from:
document.ExtUserPtr.Email,
from: document.ExtUserPtr.Email,
replyto: senderEmail || '',
html: replaceVar?.body ? replaceVar?.body : mailTemplate(mailparam).body,
};
@@ -108,13 +101,7 @@ async function sendMail(document) {
}
}
}
async function batchQuery(
userId,
Documents,
Ip,
parseConfig,
type
) {
async function batchQuery(userId, Documents, Ip, parseConfig, type, publicUrl) {
const extCls = new Parse.Query('contracts_Users');
extCls.equalTo('UserId', {
__type: 'Pointer',
@@ -199,22 +186,22 @@ async function batchQuery(
};
});
// console.log('requests ', requests);
if (requests?.length > 0) {
const newrequests = [requests?.[0]];
const response = await axios.post('batch', { requests: newrequests }, parseConfig);
// Handle the batch query response
// console.log('Batch query response:', response.data);
if (response.data && response.data.length > 0) {
const document = Documents?.[0];
const updateDocuments = {
...document,
objectId: response.data[0]?.success?.objectId,
createdAt: response.data[0]?.success?.createdAt,
};
deductcount(response.data.length, resExt.id);
sendMail(updateDocuments); //sessionToken
return 'success';
}
if (requests?.length > 0) {
const newrequests = [requests?.[0]];
const response = await axios.post('batch', { requests: newrequests }, parseConfig);
// Handle the batch query response
// console.log('Batch query response:', response.data);
if (response.data && response.data.length > 0) {
const document = Documents?.[0];
const updateDocuments = {
...document,
objectId: response.data[0]?.success?.objectId,
createdAt: response.data[0]?.success?.createdAt,
};
deductcount(response.data.length, resExt.id);
sendMail(updateDocuments, publicUrl); //sessionToken
return 'success';
}
}
} catch (error) {
const code = error?.response?.data?.code || error?.response?.status || error?.code || 400;
@@ -236,6 +223,8 @@ export default async function createBatchDocs(request) {
const type = request.headers?.type || 'quicksend';
const Documents = JSON.parse(strDocuments);
const Ip = request?.headers?.['x-real-ip'] || '';
// Access the host from the headers
const publicUrl = request.headers.public_url;
const parseConfig = {
baseURL: serverUrl,
headers: {
@@ -246,9 +235,8 @@ export default async function createBatchDocs(request) {
};
try {
if (request?.user) {
return await batchQuery(request.user.id, Documents, Ip, parseConfig, '', type);
}
else {
return await batchQuery(request.user.id, Documents, Ip, parseConfig, '', type, publicUrl);
} else {
throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'User is not authenticated.');
}
} catch (err) {
@@ -15,7 +15,7 @@ export default async function editContact(request) {
const query = new Parse.Query('contracts_Contactbook');
query.equalTo('CreatedBy', createdBy);
query.notEqualTo('IsDeleted', true);
query.equalTo('Email', email);
query.equalTo('Email', email?.toLowerCase()?.replace(/\s/g, ''));
const isContactExist = await query.first({ useMasterKey: true });
if (isContactExist) {
throw new Parse.Error(Parse.Error.DUPLICATE_VALUE, 'Contact already exists.');
@@ -25,7 +25,7 @@ export default async function editContact(request) {
if (phone) {
contactQuery.set('Phone', phone);
}
contactQuery.set('Email', email);
contactQuery.set('Email', email?.toLowerCase()?.replace(/\s/g, ''));
contactQuery.set('UserRole', 'contracts_Guest');
contactQuery.set('IsDeleted', false);
contactQuery.set('TenantId', {
@@ -37,9 +37,9 @@ export default async function editContact(request) {
const _users = Parse.Object.extend('User');
const _user = new _users();
_user.set('name', name);
_user.set('username', email);
_user.set('email', email);
_user.set('password', email);
_user.set('username', email?.toLowerCase()?.replace(/\s/g, ''));
_user.set('email', email?.toLowerCase()?.replace(/\s/g, ''));
_user.set('password', email?.toLowerCase()?.replace(/\s/g, ''));
if (phone) {
_user.set('phone', phone);
}
@@ -52,7 +52,8 @@ const saveRoleContact = async contact => {
// `linkContactToDoc` cloud function is used to create contact, add this contact in contracts_Guest role and
// save contact pointer in placeholder, signers and ACL of Document
export default async function linkContactToDoc(req) {
const email = req.params.email;
const requestemail = req.params?.email;
const email = requestemail?.toLowerCase()?.replace(/\s/g, '');
const docId = req.params.docId;
const name = req.params.name;
const phone = req.params.phone;
@@ -19,9 +19,6 @@ const APPID = process.env.APP_ID;
const masterKEY = process.env.MASTER_KEY;
const eSignName = 'OpenSign';
const eSigncontact = 'hello@opensignlabs.com';
const logo =
"<img src='https://qikinnovation.ams3.digitaloceanspaces.com/logo.png' height='50' style='padding:20px'/>";
const opurl = ` <a href=www.opensignlabs.com target=_blank>here</a>`;
// `updateDoc` is used to create url in from pdfFile
async function uploadFile(pdfName, filepath) {
@@ -93,8 +90,12 @@ async function updateDoc(docId, url, userId, ipAddress, data, className, sign) {
}
// `sendNotifyMail` is used to send notification mail of signer signed the document
async function sendNotifyMail(doc, signUser, mailProvider) {
async function sendNotifyMail(doc, signUser, mailProvider, publicUrl) {
try {
const TenantAppName = appName;
const logo =
"<img src='https://qikinnovation.ams3.digitaloceanspaces.com/logo.png' height='50' style='padding:20px'/>";
const opurl = ` <a href=www.opensignlabs.com target=_blank>here</a>`;
const auditTrailCount = doc?.AuditTrail?.filter(x => x.Activity === 'Signed')?.length || 0;
const signersCount = doc?.Placeholders?.length;
const remaingsign = signersCount - auditTrailCount;
@@ -105,18 +106,18 @@ async function sendNotifyMail(doc, signUser, mailProvider) {
const creatorEmail = doc.ExtUserPtr.Email;
const signerName = signUser.Name;
const signerEmail = signUser.Email;
const viewDocUrl = `${process.env.PUBLIC_URL}/recipientSignPdf/${doc.objectId}`;
const viewDocUrl = `${publicUrl}/recipientSignPdf/${doc.objectId}`; // ` ${process.env.PUBLIC_URL}/recipientSignPdf/${doc.objectId}`;
const subject = `Document "${pdfName}" has been signed by ${signerName}`;
const body =
"<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/></head><body><div style='background-color:#f5f5f5;padding:20px'><div style='background-color:white'>" +
`<div>${logo}</div><div style='padding:2px;font-family:system-ui;background-color:#47a3ad'><p style='font-size:20px;font-weight:400;color:white;padding-left:20px'>Document signed by ${signerName}</p>` +
`</div><div style='padding:20px;font-family:system-ui;font-size:14px'><p>Dear ${creatorName},</p><p>${pdfName} has been signed by ${signerName} "${signerEmail}" successfully</p>` +
`<p><a href=${viewDocUrl} target=_blank>View Document</a></p></div></div><div><p>This is an automated email from ${appName}. For any queries regarding this email, ` +
`please contact the sender ${creatorEmail} directly. If you think this email is inappropriate or spam, you may file a complaint with ${appName}${opurl}.</p></div></div></body></html>`;
`<p><a href=${viewDocUrl} target=_blank>View Document</a></p></div></div><div><p>This is an automated email from ${TenantAppName}. For any queries regarding this email, ` +
`please contact the sender ${creatorEmail} directly. If you think this email is inappropriate or spam, you may file a complaint with ${TenantAppName}${opurl}.</p></div></div></body></html>`;
const params = {
extUserId: sender.objectId,
from: appName,
from: TenantAppName,
recipient: creatorEmail,
subject: subject,
pdfName: pdfName,
@@ -142,6 +143,10 @@ async function sendCompletedMail(obj) {
const doc = obj.doc;
const sender = obj.doc.ExtUserPtr;
const pdfName = doc.Name;
const TenantAppName = appName;
const logo =
"<img src='https://qikinnovation.ams3.digitaloceanspaces.com/logo.png' height='50' style='padding:20px'/>";
const opurl = ` <a href=www.opensignlabs.com target=_blank>here</a>`;
let signersMail;
if (doc?.Signers?.length > 0) {
const isOwnerExistsinSigners = doc?.Signers?.find(x => x.Email === sender.Email);
@@ -157,8 +162,8 @@ async function sendCompletedMail(obj) {
"<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /></head><body><div style='background-color:#f5f5f5;padding:20px'><div style='background-color:white'>" +
`<div>${logo}</div><div style='padding:2px;font-family:system-ui;background-color:#47a3ad'><p style='font-size:20px;font-weight:400;color:white;padding-left:20px'>Document signed successfully</p></div><div>` +
`<p style='padding:20px;font-family:system-ui;font-size:14px'>All parties have successfully signed the document <b>"${pdfName}"</b>. Kindly download the document from the attachment.</p>` +
`</div></div><div><p>This is an automated email from ${appName}. For any queries regarding this email, please contact the sender ${sender.Email} directly.` +
`If you think this email is inappropriate or spam, you may file a complaint with ${appName}${opurl}.</p></div></div></body></html>`;
`</div></div><div><p>This is an automated email from ${TenantAppName}. For any queries regarding this email, please contact the sender ${sender.Email} directly.` +
`If you think this email is inappropriate or spam, you may file a complaint with ${TenantAppName}${opurl}.</p></div></div></body></html>`;
if (obj?.isCustomMail) {
const tenant = sender?.TenantId;
@@ -175,7 +180,7 @@ async function sendCompletedMail(obj) {
className: '_User',
objectId: userId,
});
const tenantRes = await tenantQuery.first();
const tenantRes = await tenantQuery.first({ useMasterKey: true });
if (tenantRes) {
const _tenantRes = JSON.parse(JSON.stringify(tenantRes));
subject = _tenantRes?.CompletionSubject || '';
@@ -214,7 +219,7 @@ async function sendCompletedMail(obj) {
const params = {
extUserId: sender.objectId,
url: url,
from: appName,
from: TenantAppName,
replyto: doc?.ExtUserPtr?.Email || '',
recipient: recipient,
subject: subject,
@@ -301,6 +306,7 @@ async function PDF(req) {
const isCustomMail = req.params.isCustomCompletionMail || false;
const mailProvider = req.params.mailProvider || '';
const sign = req.params.signature || '';
const publicUrl = req.headers.public_url;
// below bode is used to get info of docId
const docQuery = new Parse.Query('contracts_Document');
docQuery.include('ExtUserPtr,Signers,ExtUserPtr.TenantId,Bcc');
@@ -426,7 +432,7 @@ async function PDF(req) {
className, // className based on flow
sign // sign base64
);
sendNotifyMail(_resDoc, signUser, mailProvider);
sendNotifyMail(_resDoc, signUser, mailProvider, publicUrl);
saveFileUsage(pdfSize, data.imageUrl, _resDoc?.CreatedBy?.objectId);
if (updatedDoc && updatedDoc.isCompleted) {
const doc = { ..._resDoc, AuditTrail: updatedDoc.AuditTrail, SignedUrl: data.imageUrl };
@@ -0,0 +1,87 @@
const randomId = () => Math.floor(1000 + Math.random() * 9000);
export default async function saveAsTemplate(request) {
const docId = request.params.docId;
const Ip = request?.headers?.['x-real-ip'] || '';
if (!request.user) {
throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'user is not authenticated.');
}
try {
const docQuery = new Parse.Query('contracts_Document');
docQuery.equalTo('objectId', docId);
docQuery.equalTo('CreatedBy', request.user);
docQuery.include('ExtUserPtr');
docQuery.include('ExtUserPtr.TenantId');
docQuery.notEqualTo('IsArchive', true);
const docRes = await docQuery.first({ useMasterKey: true });
if (docRes) {
const _docRes = docRes?.toJSON();
const templateCls = new Parse.Object('contracts_Template');
templateCls.set('URL', _docRes?.URL);
templateCls.set('Name', _docRes?.Name);
templateCls.set('Note', _docRes?.Note);
templateCls.set('Description', _docRes?.Description);
templateCls.set('OriginIp', Ip);
templateCls.set('SendinOrder', _docRes?.SendinOrder || false);
templateCls.set('AutomaticReminders', _docRes?.AutomaticReminders || false);
templateCls.set('ExtUserPtr', _docRes?.ExtUserPtr);
templateCls.set('CreatedBy', _docRes?.CreatedBy);
templateCls.set('IsEnableOTP', _docRes?.IsEnableOTP === true ? true : false);
templateCls.set('IsTourEnabled', _docRes?.IsTourEnabled === true ? true : false);
templateCls.set('AllowModifications', _docRes?.AllowModifications || false);
templateCls.set('EmailSenderName', _docRes?.EmailSenderName);
templateCls.set('SenderName', _docRes?.SenderName);
templateCls.set('SenderMail', _docRes?.SenderMail);
templateCls.set('FileAdapterId', _docRes?.FileAdapterId);
templateCls.set('RequestBody', _docRes?.RequestBody);
templateCls.set('RequestSubject', _docRes?.RequestSubject);
templateCls.set('NextReminderDate', _docRes?.NextReminderDate);
templateCls.set('RedirectUrl', _docRes?.RedirectUrl);
templateCls.set(
'NotifyOnSignatures',
_docRes?.NotifyOnSignatures !== undefined ? _docRes?.NotifyOnSignatures : false
);
templateCls.set(
'TimeToCompleteDays',
_docRes?.TimeToCompleteDays ? parseInt(_docRes?.TimeToCompleteDays) : 15
);
if (_docRes?.RemindOnceInEvery) {
templateCls.set('RemindOnceInEvery', parseInt(_docRes?.RemindOnceInEvery));
}
if (_docRes?.Placeholders?.length > 0) {
if (_docRes?.IsSignyourself) {
const placeHolders = {
signerObjId: '',
signerPtr: {},
Id: randomId(),
blockColor: '#93a3db',
Role: 'Role 1',
email: '',
placeHolder: _docRes?.Placeholders,
};
templateCls.set('Placeholders', [placeHolders]);
} else {
const placeHolders = _docRes?.Placeholders?.map((x, i) => {
const email = x.email ? { email: '' } : {};
return { ...x, signerObjId: '', signerPtr: {}, Role: 'Role ' + (i + 1), ...email };
});
templateCls.set('Placeholders', placeHolders);
}
}
if (_docRes?.SignatureType?.length > 0) {
templateCls.set('SignatureType', _docRes?.SignatureType);
}
if (_docRes?.Bcc?.length > 0) {
templateCls.set('Bcc', _docRes?.Bcc);
}
const res = await templateCls.save(null, { useMasterKey: true });
return res;
} else {
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'document not found.');
}
} catch (err) {
console.log('Err in save as template', err);
throw err;
}
}
@@ -1,7 +1,8 @@
export default async function savecontact(request) {
const name = request.params.name;
const phone = request.params.phone;
const email = request.params.email;
const requestemail = request.params?.email;
const email = requestemail?.toLowerCase()?.replace(/\s/g, '');
const tenantId = request.params.tenantId;
if (request.user) {
@@ -0,0 +1,27 @@
export default async function updateTenant(request) {
const { tenantId, details } = request.params;
if (!tenantId || !details) {
throw new Parse.Error(400, 'Missing tenantId or details.');
}
if (!request.user) {
throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'unauthorized');
}
try {
const tenant = new Parse.Object('partners_Tenant');
tenant.id = tenantId;
// Update tenant details
Object.keys(details).forEach(key => {
tenant.set(key, details?.[key]);
});
const tenantRes = await tenant.save(null, { useMasterKey: true });
if (tenantRes) {
const res = JSON.parse(JSON.stringify(tenantRes));
return res;
}
} catch (error) {
throw error;
}
}
@@ -1,7 +1,5 @@
import axios from 'axios';
import {
cloudServerUrl,
} from '../../Utils.js';
import { cloudServerUrl } from '../../Utils.js';
const serverUrl = cloudServerUrl; //process.env.SERVER_URL;
const APPID = process.env.APP_ID;
const masterKEY = process.env.MASTER_KEY;
@@ -32,7 +30,7 @@ async function saveUser(userDetails) {
const user = new Parse.User();
user.set('username', userDetails.email);
user.set('password', userDetails.password);
user.set('email', userDetails.email);
user.set('email', userDetails?.email?.toLowerCase()?.replace(/\s/g, ''));
if (userDetails?.phone) {
user.set('phone', userDetails.phone);
}
@@ -73,7 +71,7 @@ export default async function usersignup(request) {
partnerQuery.set('ContactNumber', userDetails.phone);
}
partnerQuery.set('TenantName', userDetails.company);
partnerQuery.set('EmailAddress', userDetails.email);
partnerQuery.set('EmailAddress', userDetails?.email?.toLowerCase()?.replace(/\s/g, ''));
partnerQuery.set('IsActive', true);
partnerQuery.set('CreatedBy', {
__type: 'Pointer',
@@ -105,7 +103,7 @@ export default async function usersignup(request) {
objectId: user.id,
});
newObj.set('UserRole', userDetails.role);
newObj.set('Email', userDetails.email);
newObj.set('Email', userDetails?.email?.toLowerCase()?.replace(/\s/g, ''));
newObj.set('Name', userDetails.name);
if (userDetails?.phone) {
newObj.set('Phone', userDetails?.phone);
@@ -131,4 +129,3 @@ export default async function usersignup(request) {
console.log('Err ', err);
}
}