mirror of
https://github.com/OpenSignLabs/OpenSign.git
synced 2026-08-17 21:25:54 +02:00
feat: quick send feature to create & send multiple documents at a time
This commit is contained in:
@@ -38,6 +38,7 @@ import VerifyEmail from './parsefunction/VerifyEmail.js';
|
||||
import encryptedpdf from './parsefunction/encryptedPdf.js';
|
||||
import { getSignedUrl } from './parsefunction/getSignedUrl.js';
|
||||
import createBatchDocs from './parsefunction/createBatchDocs.js';
|
||||
import linkContactToDoc from './parsefunction/linkContactToDoc.js';
|
||||
|
||||
// This afterSave function triggers after an object is added or updated in the specified class, allowing for post-processing logic.
|
||||
Parse.Cloud.afterSave('contracts_Document', DocumentAftersave);
|
||||
@@ -86,3 +87,4 @@ Parse.Cloud.define('verifyemail', VerifyEmail);
|
||||
Parse.Cloud.define('encryptedpdf', encryptedpdf);
|
||||
Parse.Cloud.define('getsignedurl', getSignedUrl);
|
||||
Parse.Cloud.define('batchdocuments', createBatchDocs);
|
||||
Parse.Cloud.define('linkcontacttodoc', linkContactToDoc);
|
||||
|
||||
@@ -31,9 +31,9 @@ async function sendMail(document, sessionToken) {
|
||||
const hostUrl = baseUrl.origin;
|
||||
let encodeBase64;
|
||||
if (objectId) {
|
||||
encodeBase64 = btoa(`${document.objectId}}/${signerMail[i].signerPtr.Email}/${objectId}`);
|
||||
encodeBase64 = btoa(`${document.objectId}/${signerMail[i].signerPtr.Email}/${objectId}`);
|
||||
} else {
|
||||
encodeBase64 = btoa(`${document.objectId}}/${signerMail[i].email}`);
|
||||
encodeBase64 = btoa(`${document.objectId}/${signerMail[i].email}`);
|
||||
}
|
||||
let signPdf = `${hostUrl}/login/${encodeBase64}`;
|
||||
const openSignUrl = 'https://www.opensignlabs.com/';
|
||||
@@ -93,18 +93,12 @@ export default async function createBatchDocs(request) {
|
||||
try {
|
||||
const requests = Documents.map(x => {
|
||||
const Signers = x.Signers;
|
||||
const allSigner = x?.Placeholders?.map(item => {
|
||||
const signer = Signers?.find(e => item?.signerPtr?.objectId === e?.objectId);
|
||||
if (signer) {
|
||||
return signer;
|
||||
} else {
|
||||
return item?.signerPtr?.objectId && item?.signerPtr;
|
||||
}
|
||||
});
|
||||
const allSigner = x?.Placeholders?.map(
|
||||
item => Signers?.find(e => item?.signerPtr?.objectId === e?.objectId) || item?.signerPtr
|
||||
).filter(signer => Object.keys(signer).length > 0);
|
||||
const date = new Date();
|
||||
const isoDate = date.toISOString();
|
||||
let Acl = { [x.CreatedBy.objectId]: { read: true, write: true } };
|
||||
// console.log('allSigner ', allSigner);
|
||||
if (allSigner && allSigner.length > 0) {
|
||||
allSigner.forEach(x => {
|
||||
const obj = { [x.CreatedBy.objectId]: { read: true, write: true } };
|
||||
@@ -146,7 +140,7 @@ export default async function createBatchDocs(request) {
|
||||
objectId: y.objectId,
|
||||
})),
|
||||
ACL: Acl,
|
||||
RemindOnceInEvery: x.RemindOnceInEvery,
|
||||
RemindOnceInEvery: x.RemindOnceInEvery || 5,
|
||||
AutomaticReminders: x.AutomaticReminders || false,
|
||||
TimeToCompleteDays: x.TimeToCompleteDays || 15,
|
||||
OriginIp: Ip,
|
||||
|
||||
@@ -0,0 +1,276 @@
|
||||
// `saveRoleContact` is used to save user in contracts_Guest role and create contact
|
||||
const saveRoleContact = async contact => {
|
||||
try {
|
||||
const Role = new Parse.Query(Parse.Role);
|
||||
const guestRole = await Role.equalTo('name', 'contracts_Guest').first();
|
||||
if (guestRole) {
|
||||
// Check if the user is already in the role
|
||||
const relation = guestRole.relation('users');
|
||||
const usersInRoleQuery = relation.query();
|
||||
usersInRoleQuery.equalTo('objectId', contact.UserId.objectId);
|
||||
const usersInRole = await usersInRoleQuery.find();
|
||||
if (usersInRole.length > 0) {
|
||||
console.log('User already added to Guest role.');
|
||||
} else {
|
||||
relation.add({ __type: 'Pointer', className: '_User', id: contact.UserId.objectId });
|
||||
await guestRole.save(null, { useMasterKey: true });
|
||||
// console.log('User added to Guest role successfully.');
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('err in role save', err);
|
||||
}
|
||||
const contactQuery = new Parse.Object('contracts_Contactbook');
|
||||
contactQuery.set('Name', contact.Name);
|
||||
contactQuery.set('Email', contact.Email);
|
||||
if (contact?.Phone) {
|
||||
contactQuery.set('Phone', contact.Phone);
|
||||
}
|
||||
contactQuery.set('CreatedBy', contact.CreatedBy);
|
||||
contactQuery.set('UserId', contact.UserId);
|
||||
contactQuery.set('UserRole', 'contracts_Guest');
|
||||
contactQuery.set('TenantId', contact.TenantId);
|
||||
contactQuery.set('IsDeleted', false);
|
||||
const acl = new Parse.ACL();
|
||||
acl.setReadAccess(contact.CreatedBy.objectId, true);
|
||||
acl.setWriteAccess(contact.CreatedBy.objectId, true);
|
||||
acl.setReadAccess(contact.UserId.objectId, true);
|
||||
acl.setWriteAccess(contact.UserId.objectId, true);
|
||||
contactQuery.setACL(acl);
|
||||
const contactRes = await contactQuery.save();
|
||||
if (contactRes) {
|
||||
return contactRes;
|
||||
}
|
||||
};
|
||||
|
||||
// `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 docId = req.params.docId;
|
||||
const name = req.params.name;
|
||||
const phone = req.params.phone;
|
||||
try {
|
||||
if (docId) {
|
||||
// Execute the query to get the document with the specified 'docId'
|
||||
const docQuery = new Parse.Query('contracts_Document');
|
||||
docQuery.include('ExtUserPtr');
|
||||
const docRes = await docQuery.get(docId, { useMasterKey: true });
|
||||
// Check if the document was found; if not, throw an error indicating the document was not found
|
||||
if (!docRes) {
|
||||
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Document not found.');
|
||||
}
|
||||
const _docRes = JSON.parse(JSON.stringify(docRes));
|
||||
const Placeholders = _docRes?.Placeholders || [];
|
||||
const index = Placeholders?.findIndex(x => x.email && x.email === email);
|
||||
if (index !== -1) {
|
||||
// `signerObjectId` holds the value of `signerObjId` from the `Placeholders` array at the current index.
|
||||
// This value is used to check if `signerObjId` is present or not.
|
||||
const signerObjectId = Placeholders[index]?.signerObjId;
|
||||
if (signerObjectId) {
|
||||
return { contactId: signerObjectId };
|
||||
}
|
||||
// Execute the query to check if a contact already exists in the 'contracts_Contactbook' class
|
||||
const contactCls = new Parse.Query('contracts_Contactbook');
|
||||
contactCls.equalTo('Email', email);
|
||||
contactCls.equalTo('CreatedBy', _docRes.CreatedBy);
|
||||
contactCls.notEqualTo('IsDeleted', true);
|
||||
const existContact = await contactCls.first({ useMasterKey: true });
|
||||
if (existContact) {
|
||||
//update contact in placeholder, signers and update ACl in provide document
|
||||
const updateDoc = new Parse.Object('contracts_Document');
|
||||
updateDoc.id = docId;
|
||||
const signers = _docRes?.Signers || [];
|
||||
signers.push({
|
||||
__type: 'Pointer',
|
||||
className: 'contracts_Contactbook',
|
||||
objectId: existContact.id,
|
||||
});
|
||||
updateDoc.set('Signers', signers);
|
||||
|
||||
Placeholders[index] = {
|
||||
...Placeholders[index],
|
||||
signerObjId: existContact.id,
|
||||
signerPtr: {
|
||||
__type: 'Pointer',
|
||||
className: 'contracts_Contactbook',
|
||||
objectId: existContact.id,
|
||||
},
|
||||
};
|
||||
updateDoc.set('Placeholders', Placeholders);
|
||||
const Acl = docRes.getACL();
|
||||
Acl.setReadAccess(existContact.get('CreatedBy').id, true);
|
||||
Acl.setWriteAccess(existContact.get('CreatedBy').id, true);
|
||||
updateDoc.setACL(Acl);
|
||||
// const parseData = JSON.parse(JSON.stringify(res));
|
||||
const resDoc = await updateDoc.save(null, { useMasterKey: true });
|
||||
if (resDoc) {
|
||||
return { contactId: existContact.id };
|
||||
}
|
||||
} else {
|
||||
// Execute the query to check if a user already exists in the 'contracts_Users' class
|
||||
const extUserQuery = new Parse.Query('contracts_Users');
|
||||
extUserQuery.equalTo('Email', email);
|
||||
const extUser = await extUserQuery.first({ useMasterKey: true });
|
||||
if (extUser) {
|
||||
const _extUser = JSON.parse(JSON.stringify(extUser));
|
||||
const contact = {
|
||||
UserId: _extUser.UserId,
|
||||
Name: _extUser.Name,
|
||||
Email: email,
|
||||
Phone: _extUser?.Phone ? _extUser.Phone : '',
|
||||
CreatedBy: _docRes.CreatedBy,
|
||||
TenantId: _docRes.ExtUserPtr.TenantId,
|
||||
};
|
||||
// if user present on platform create contact on the basis of extended user details
|
||||
const contactRes = await saveRoleContact(contact);
|
||||
//update contact in placeholder, signers and update ACl in provide document
|
||||
const updateDoc = new Parse.Object('contracts_Document');
|
||||
updateDoc.id = docId;
|
||||
const signers = _docRes?.Signers || [];
|
||||
signers.push({
|
||||
__type: 'Pointer',
|
||||
className: 'contracts_Contactbook',
|
||||
objectId: contactRes.id,
|
||||
});
|
||||
updateDoc.set('Signers', signers);
|
||||
|
||||
Placeholders[index] = {
|
||||
...Placeholders[index],
|
||||
signerObjId: contactRes.id,
|
||||
signerPtr: {
|
||||
__type: 'Pointer',
|
||||
className: 'contracts_Contactbook',
|
||||
objectId: contactRes.id,
|
||||
},
|
||||
};
|
||||
updateDoc.set('Placeholders', Placeholders);
|
||||
const Acl = docRes.getACL();
|
||||
Acl.setReadAccess(_extUser.UserId.objectId, true);
|
||||
Acl.setWriteAccess(_extUser.UserId.objectId, true);
|
||||
updateDoc.setACL(Acl);
|
||||
// const parseData = JSON.parse(JSON.stringify(res));
|
||||
const resDoc = await updateDoc.save(null, { useMasterKey: true });
|
||||
if (resDoc) {
|
||||
return { contactId: contactRes.id };
|
||||
}
|
||||
} else if (name) {
|
||||
try {
|
||||
// Execute the query to check if a user already exists in the '_User' class
|
||||
const userQuery = new Parse.Query(Parse.User);
|
||||
userQuery.equalTo('email', email);
|
||||
const userRes = await userQuery.first({ useMasterKey: true });
|
||||
if (userRes) {
|
||||
const contact = {
|
||||
UserId: { __type: 'Pointer', className: '_User', objectId: userRes.id },
|
||||
Name: name,
|
||||
Email: email,
|
||||
Phone: phone,
|
||||
CreatedBy: _docRes.CreatedBy,
|
||||
TenantId: _docRes.ExtUserPtr.TenantId,
|
||||
};
|
||||
// Create new contract on the basis provided contact details by user and userId from _User class
|
||||
const contactRes = await saveRoleContact(contact);
|
||||
//update contact in placeholder, signers and update ACl in provide document
|
||||
const updateDoc = new Parse.Object('contracts_Document');
|
||||
updateDoc.id = docId;
|
||||
const signers = _docRes?.Signers || [];
|
||||
signers.push({
|
||||
__type: 'Pointer',
|
||||
className: 'contracts_Contactbook',
|
||||
objectId: contactRes.id,
|
||||
});
|
||||
updateDoc.set('Signers', signers);
|
||||
|
||||
Placeholders[index] = {
|
||||
...Placeholders[index],
|
||||
signerObjId: contactRes.id,
|
||||
signerPtr: {
|
||||
__type: 'Pointer',
|
||||
className: 'contracts_Contactbook',
|
||||
objectId: contactRes.id,
|
||||
},
|
||||
};
|
||||
updateDoc.set('Placeholders', Placeholders);
|
||||
const Acl = docRes.getACL();
|
||||
Acl.setReadAccess(userRes.id, true);
|
||||
Acl.setWriteAccess(userRes.id, true);
|
||||
updateDoc.setACL(Acl);
|
||||
// const parseData = JSON.parse(JSON.stringify(res));
|
||||
const resDoc = await updateDoc.save(null, { useMasterKey: true });
|
||||
if (resDoc) {
|
||||
return { contactId: contactRes.id };
|
||||
}
|
||||
} else {
|
||||
// create new user in _User class on the basis of details provide by user
|
||||
const _users = Parse.Object.extend('User');
|
||||
const _user = new _users();
|
||||
_user.set('name', name);
|
||||
_user.set('username', email);
|
||||
_user.set('email', email);
|
||||
if (phone) {
|
||||
_user.set('phone', phone);
|
||||
_user.set('password', phone);
|
||||
} else {
|
||||
_user.set('password', email);
|
||||
}
|
||||
const newUserRes = await _user.save();
|
||||
const contact = {
|
||||
UserId: { __type: 'Pointer', className: '_User', objectId: newUserRes.id },
|
||||
Name: name,
|
||||
Email: email,
|
||||
Phone: phone,
|
||||
CreatedBy: _docRes.CreatedBy,
|
||||
TenantId: _docRes.ExtUserPtr.TenantId,
|
||||
};
|
||||
// Create new contract on the basis provided contact details by user and userId from _User class
|
||||
const contactRes = await saveRoleContact(contact);
|
||||
//update contact in placeholder, signers and update ACl in provide document
|
||||
const updateDoc = new Parse.Object('contracts_Document');
|
||||
updateDoc.id = docId;
|
||||
const signers = _docRes?.Signers || [];
|
||||
signers.push({
|
||||
__type: 'Pointer',
|
||||
className: 'contracts_Contactbook',
|
||||
objectId: contactRes.id,
|
||||
});
|
||||
updateDoc.set('Signers', signers);
|
||||
|
||||
Placeholders[index] = {
|
||||
...Placeholders[index],
|
||||
signerObjId: contactRes.id,
|
||||
signerPtr: {
|
||||
__type: 'Pointer',
|
||||
className: 'contracts_Contactbook',
|
||||
objectId: contactRes.id,
|
||||
},
|
||||
};
|
||||
updateDoc.set('Placeholders', Placeholders);
|
||||
const Acl = docRes.getACL();
|
||||
Acl.setReadAccess(newUserRes.id, true);
|
||||
Acl.setWriteAccess(newUserRes.id, true);
|
||||
updateDoc.setACL(Acl);
|
||||
// const parseData = JSON.parse(JSON.stringify(res));
|
||||
const resDoc = await updateDoc.save(null, { useMasterKey: true });
|
||||
if (resDoc) {
|
||||
return { contactId: contactRes.id };
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('Err', err);
|
||||
}
|
||||
} else {
|
||||
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'User not found.');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, 'unauthorized');
|
||||
}
|
||||
} else {
|
||||
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Document not found.');
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('err in linkcontacttodoc', err);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user