diff --git a/apps/OpenSign/src/constant/Utils.js b/apps/OpenSign/src/constant/Utils.js index da258c3306..c35e93280e 100644 --- a/apps/OpenSign/src/constant/Utils.js +++ b/apps/OpenSign/src/constant/Utils.js @@ -2980,34 +2980,34 @@ export const saveLanguageInLocal = (i18n) => { const detectedLanguage = i18n.language || "en"; localStorage.setItem("i18nextLng", detectedLanguage); }; -//function to get default signatur eof current user from `contracts_Signature` class + +// function to get default signature of current user from `contracts_Signature` class export const getDefaultSignature = async (objectId) => { try { - const query = new Parse.Query("contracts_Signature"); - query.equalTo("UserId", { - __type: "Pointer", - className: "_User", - objectId: objectId - }); - - const result = await query.first(); - if (result) { - const res = JSON.parse(JSON.stringify(result)); - const defaultSignature = res?.ImageURL - ? await getBase64FromUrl(res?.ImageURL, true) - : ""; - const defaultInitial = res?.Initials - ? await getBase64FromUrl(res?.Initials, true) - : ""; + if (objectId) { + const result = await Parse.Cloud.run("getdefaultsignature", { + userId: objectId + }); + if (result) { + const res = JSON.parse(JSON.stringify(result)); + const defaultSignature = res?.ImageURL + ? await getBase64FromUrl(res?.ImageURL, true) + : ""; + const defaultInitial = res?.Initials + ? await getBase64FromUrl(res?.Initials, true) + : ""; - return { - status: "success", - res: { - id: result?.id, - defaultSignature: defaultSignature, - defaultInitial: defaultInitial - } - }; + return { + status: "success", + res: { + id: result?.id, + defaultSignature: defaultSignature, + defaultInitial: defaultInitial + } + }; + } + } else { + return { status: "error" }; } } catch (err) { console.log( diff --git a/apps/OpenSign/src/pages/Managesign.jsx b/apps/OpenSign/src/pages/Managesign.jsx index eb5b267300..5d0828f3f2 100644 --- a/apps/OpenSign/src/pages/Managesign.jsx +++ b/apps/OpenSign/src/pages/Managesign.jsx @@ -46,10 +46,9 @@ const ManageSign = () => { objectId: User.id }; try { - const signCls = "contracts_Signature"; - const signQuery = new Parse.Query(signCls); - signQuery.equalTo("UserId", userId); - const signRes = await signQuery.first(); + const signRes = await Parse.Cloud.run("getdefaultsignature", { + userId: User.id + }); if (signRes) { const res = signRes.toJSON(); setId(res.objectId); @@ -226,44 +225,23 @@ const ManageSign = () => { }; const saveEntry = async (obj) => { - const signCls = "contracts_Signature"; - const User = Parse?.User?.current()?.id; - const userId = { __type: "Pointer", className: "_User", objectId: User }; - if (id) { - try { - const updateSign = new Parse.Object(signCls); - updateSign.id = id; - updateSign.set("Initials", obj.initialsUrl ? obj.initialsUrl : ""); - updateSign.set("ImageURL", obj.url ? obj.url : ""); - updateSign.set("SignatureName", obj.name); - updateSign.set("UserId", userId); - const res = await updateSign.save(); - setIsAlert({ type: "success", message: t("signature-saved-alert") }); - return res; - } catch (err) { - console.log(err); - setIsAlert({ type: "danger", message: `${err.message}` }); - } finally { - setIsLoader(false); - setTimeout(() => setIsAlert({}), 2000); - } - } else { - try { - const updateSign = new Parse.Object(signCls); - updateSign.set("Initials", obj.initialsUrl ? obj.initialsUrl : ""); - updateSign.set("ImageURL", obj.url); - updateSign.set("SignatureName", obj.name); - updateSign.set("UserId", userId); - const res = await updateSign.save(); - setIsAlert({ type: "success", message: t("signature-saved-alert") }); - return res; - } catch (err) { - console.log(err); - setIsAlert({ type: "success", message: `${err.message}` }); - } finally { - setIsLoader(false); - setTimeout(() => setIsAlert({}), 2000); - } + try { + const User = Parse?.User?.current()?.id; + const res = await Parse.Cloud.run("managesign", { + signature: obj.url, + userId: User, + initials: obj.initialsUrl, + id: id, + title: obj.name + }); + setIsAlert({ type: "success", message: t("signature-saved-alert") }); + return res; + } catch (err) { + console.log(err); + setIsAlert({ type: "danger", message: `${err.message}` }); + } finally { + setIsLoader(false); + setTimeout(() => setIsAlert({}), 2000); } }; diff --git a/apps/OpenSign/src/utils/widgetUtils.js b/apps/OpenSign/src/utils/widgetUtils.js index 8a58fe855e..eec0a0b1ff 100644 --- a/apps/OpenSign/src/utils/widgetUtils.js +++ b/apps/OpenSign/src/utils/widgetUtils.js @@ -16,22 +16,20 @@ export const saveToMySign = async (widget) => { : `${replaceSpace}__initials`; const file = base64StringtoFile(base64, fileName); const fileUrl = await uploadFile(file, User?.id); - // below code is used to save or update default signature, initials, stamp - const signCls = new Parse.Object("contracts_Signature"); - if (widget?.defaultSignId) { - signCls.id = widget.defaultSignId; - } + const params = { + id: widget?.defaultSignId, // pass id to update existing signature/initials + userId: User.id + }; if (widget?.type === "initials") { - signCls.set("Initials", fileUrl); + params.initials = fileUrl; // save initials image url } else if (widget?.type === "signature") { - signCls.set("ImageURL", fileUrl); + params.signature = fileUrl; // save signature image url } - signCls.set("UserId", Parse.User.createWithoutData(User.id)); - const signRes = await signCls.save(); + const signRes = await Parse.Cloud.run("savesignature", params); return { base64File: base64, id: signRes?.id }; } catch (err) { console.log("Err while saving signature", err); - return url; + return err; } } }; diff --git a/apps/OpenSignServer/cloud/main.js b/apps/OpenSignServer/cloud/main.js index 25a0932df9..e76836c490 100644 --- a/apps/OpenSignServer/cloud/main.js +++ b/apps/OpenSignServer/cloud/main.js @@ -57,6 +57,9 @@ import addUser from './parsefunction/addUser.js'; import filterDocs from './parsefunction/filterDocs.js'; import sendDeleteUserMail from './parsefunction/sendDeleteUserMail.js'; import resetPassword from './parsefunction/resetPassword.js'; +import saveSignature from './parsefunction/saveSignature.js'; +import manageSign from './parsefunction/manageSign.js'; +import getSignature from './parsefunction/getSignature.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); @@ -124,3 +127,6 @@ Parse.Cloud.define('adduser', addUser); Parse.Cloud.define('filterdocs', filterDocs); Parse.Cloud.define('senddeleterequest', sendDeleteUserMail); Parse.Cloud.define('resetpassword', resetPassword); +Parse.Cloud.define('savesignature', saveSignature); +Parse.Cloud.define('managesign', manageSign); +Parse.Cloud.define('getdefaultsignature', getSignature); diff --git a/apps/OpenSignServer/cloud/parsefunction/getSignature.js b/apps/OpenSignServer/cloud/parsefunction/getSignature.js new file mode 100644 index 0000000000..5517090713 --- /dev/null +++ b/apps/OpenSignServer/cloud/parsefunction/getSignature.js @@ -0,0 +1,18 @@ +export default async function getSignature(request) { + const { userId } = request.params; + if (!userId) { + throw new Parse.Error(Parse.Error.INVALID_QUERY, 'Missing userId parameter.'); + } + if (userId !== request.user?.id) { + throw new Parse.Error(Parse.Error.INVALID_QUERY, 'Cannot save signature for the current user.'); + } + try { + const query = new Parse.Query('contracts_Signature'); + query.equalTo('UserId', { __type: 'Pointer', className: '_User', objectId: userId }); + const result = await query.first({ useMasterKey: true }); + return result; + } catch (err) { + console.error('Error fetching signature:', err); + throw err; + } +} diff --git a/apps/OpenSignServer/cloud/parsefunction/manageSign.js b/apps/OpenSignServer/cloud/parsefunction/manageSign.js new file mode 100644 index 0000000000..625cf1fbde --- /dev/null +++ b/apps/OpenSignServer/cloud/parsefunction/manageSign.js @@ -0,0 +1,28 @@ +export default async function manageSign(request) { + const { signature, userId, initials, id, title } = request.params; + + if (!userId) { + throw new Parse.Error(Parse.Error.INVALID_QUERY, 'Missing userId parameter.'); + } + if (userId !== request.user?.id) { + throw new Parse.Error(Parse.Error.INVALID_QUERY, 'Cannot save signature for the current user.'); + } + const userPtr = { __type: 'Pointer', className: '_User', objectId: userId }; + try { + const signatureCls = new Parse.Object('contracts_Signature'); + if (id) { + signatureCls.id = id; + } + signatureCls.set('Initials', initials ? initials : ''); + signatureCls.set('ImageURL', signature ? signature : ''); + signatureCls.set('SignatureName', title ? title : ''); + if (userPtr) { + signatureCls.set('UserId', userPtr); + } + const signRes = await signatureCls.save(null, { useMasterKey: true }); + return signRes; + } catch (err) { + console.error('Error saving signature:', err); + throw err; + } +} diff --git a/apps/OpenSignServer/cloud/parsefunction/saveSignature.js b/apps/OpenSignServer/cloud/parsefunction/saveSignature.js new file mode 100644 index 0000000000..8e3e18fa5a --- /dev/null +++ b/apps/OpenSignServer/cloud/parsefunction/saveSignature.js @@ -0,0 +1,33 @@ +export default async function saveSignature(request) { + const { signature, userId, initials, id, title } = request.params; + + if (!userId) { + throw new Parse.Error(Parse.Error.INVALID_QUERY, 'Missing userId parameter.'); + } + if (userId !== request.user?.id) { + throw new Parse.Error(Parse.Error.INVALID_QUERY, 'Cannot save signature for the current user.'); + } + const userPtr = { __type: 'Pointer', className: '_User', objectId: userId }; + try { + const signatureCls = new Parse.Object('contracts_Signature'); + if (id) { + signatureCls.id = id; + } + if (initials) { + signatureCls.set('Initials', initials); + } + if (signature) { + signatureCls.set('ImageURL', signature); + } + if (title) { + signatureCls.set('SignatureName', title); + } + if (userPtr) { + signatureCls.set('UserId', userPtr); + } + const signRes = await signatureCls.save(null, { useMasterKey: true }); + return signRes; + } catch (err) { + throw err; + } +} diff --git a/apps/OpenSignServer/cloud/parsefunction/sendMailv3.js b/apps/OpenSignServer/cloud/parsefunction/sendMailv3.js index 3f5cae0e0c..86a7155d90 100644 --- a/apps/OpenSignServer/cloud/parsefunction/sendMailv3.js +++ b/apps/OpenSignServer/cloud/parsefunction/sendMailv3.js @@ -12,15 +12,23 @@ async function sendMailProvider(req, plan, monthchange) { let mailgunClient; let mailgunDomain; if (smtpenable) { - transporterSMTP = createTransport({ + let transporterConfig = { host: process.env.SMTP_HOST, port: process.env.SMTP_PORT || 465, secure: smtpsecure, - auth: { + }; + + // ✅ Add auth only if BOTH username & password exist + const smtpUser = process.env.SMTP_USERNAME; + const smtpPass = process.env.SMTP_PASS; + + if (smtpUser && smtpPass) { + transporterConfig.auth = { user: process.env.SMTP_USERNAME ? process.env.SMTP_USERNAME : process.env.SMTP_USER_EMAIL, - pass: process.env.SMTP_PASS, - }, - }); + pass: smtpPass, + }; + } + transporterSMTP = createTransport(transporterConfig); } else { if (mailgunApiKey) { const mailgun = new Mailgun(formData); @@ -185,7 +193,7 @@ async function sendMailProvider(req, plan, monthchange) { } } } catch (err) { - console.log('err in sendmailv3', err); + console.log(`Error in sendmailv3: ${err}`); if (fs.existsSync(testPdf)) { try { fs.unlinkSync(testPdf); @@ -236,7 +244,7 @@ async function sendMailProvider(req, plan, monthchange) { } } } catch (err) { - console.log('err in sendmailv3', err); + console.log(`Error in sendmailv3: ${err}`); if (err) { return { status: 'error' }; } diff --git a/apps/OpenSignServer/index.js b/apps/OpenSignServer/index.js index 10ab88fa0d..8f7e1d82a5 100644 --- a/apps/OpenSignServer/index.js +++ b/apps/OpenSignServer/index.js @@ -61,20 +61,28 @@ let mailgunDomain; let isMailAdapter = false; if (smtpenable) { try { - transporterMail = createTransport({ + let transporterConfig = { host: process.env.SMTP_HOST, port: process.env.SMTP_PORT || 465, secure: smtpsecure, - auth: { + }; + + // ✅ Add auth only if BOTH username & password exist + const smtpUser = process.env.SMTP_USERNAME; + const smtpPass = process.env.SMTP_PASS; + + if (smtpUser && smtpPass) { + transporterConfig.auth = { user: process.env.SMTP_USERNAME ? process.env.SMTP_USERNAME : process.env.SMTP_USER_EMAIL, - pass: process.env.SMTP_PASS, - }, - }); + pass: smtpPass, + }; + } + transporterMail = createTransport(transporterConfig); await transporterMail.verify(); isMailAdapter = true; } catch (err) { isMailAdapter = false; - console.log('Please provide valid SMTP credentials'); + console.log(`Please provide valid SMTP credentials: ${err}`); } } else if (process.env.MAILGUN_API_KEY) { try { diff --git a/apps/OpenSignServer/package-lock.json b/apps/OpenSignServer/package-lock.json index 3345a65a17..f606c23693 100644 --- a/apps/OpenSignServer/package-lock.json +++ b/apps/OpenSignServer/package-lock.json @@ -29,7 +29,7 @@ "googleapis": "^161.0.0", "libreoffice-convert": "^1.7.0", "mailgun.js": "^12.1.0", - "mongodb": "^6.20.0", + "mongodb": "^5.9.2", "multer": "^2.0.2", "multer-s3": "^3.0.1", "node-forge": "^1.3.1", @@ -15147,6 +15147,15 @@ "resolved": "https://registry.npmjs.org/intersect/-/intersect-1.0.1.tgz", "integrity": "sha512-qsc720yevCO+4NydrJWgEWKccAQwTOvj2m73O/VBA6iUL2HGZJ9XqBiyraNrBXX/W1IAjdpXdRZk24sq8TzBRg==" }, + "node_modules/ip-address": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.0.1.tgz", + "integrity": "sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -16190,26 +16199,27 @@ } }, "node_modules/mongodb": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.20.0.tgz", - "integrity": "sha512-Tl6MEIU3K4Rq3TSHd+sZQqRBoGlFsOgNrH5ltAcFBV62Re3Fd+FcaVf8uSEQFOJ51SDowDVttBTONMfoYWrWlQ==", + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.9.2.tgz", + "integrity": "sha512-H60HecKO4Bc+7dhOv4sJlgvenK4fQNqqUIlXxZYQNbfEWSALGAwGoyJd/0Qwk4TttFXUOHJ2ZJQe/52ScaUwtQ==", "license": "Apache-2.0", "dependencies": { - "@mongodb-js/saslprep": "^1.3.0", - "bson": "^6.10.4", - "mongodb-connection-string-url": "^3.0.2" + "bson": "^5.5.0", + "mongodb-connection-string-url": "^2.6.0", + "socks": "^2.7.1" }, "engines": { - "node": ">=16.20.1" + "node": ">=14.20.1" + }, + "optionalDependencies": { + "@mongodb-js/saslprep": "^1.1.0" }, "peerDependencies": { "@aws-sdk/credential-providers": "^3.188.0", - "@mongodb-js/zstd": "^1.1.0 || ^2.0.0", - "gcp-metadata": "^5.2.0", - "kerberos": "^2.0.1", - "mongodb-client-encryption": ">=6.0.0 <7", - "snappy": "^7.3.2", - "socks": "^2.7.1" + "@mongodb-js/zstd": "^1.0.0", + "kerberos": "^1.0.0 || ^2.0.0", + "mongodb-client-encryption": ">=2.3.0 <3", + "snappy": "^7.2.2" }, "peerDependenciesMeta": { "@aws-sdk/credential-providers": { @@ -16218,9 +16228,6 @@ "@mongodb-js/zstd": { "optional": true }, - "gcp-metadata": { - "optional": true - }, "kerberos": { "optional": true }, @@ -16229,9 +16236,6 @@ }, "snappy": { "optional": true - }, - "socks": { - "optional": true } } }, @@ -16292,6 +16296,107 @@ "mongodb-runner": "bin/runner.js" } }, + "node_modules/mongodb-runner/node_modules/mongodb": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.20.0.tgz", + "integrity": "sha512-Tl6MEIU3K4Rq3TSHd+sZQqRBoGlFsOgNrH5ltAcFBV62Re3Fd+FcaVf8uSEQFOJ51SDowDVttBTONMfoYWrWlQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@mongodb-js/saslprep": "^1.3.0", + "bson": "^6.10.4", + "mongodb-connection-string-url": "^3.0.2" + }, + "engines": { + "node": ">=16.20.1" + }, + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.188.0", + "@mongodb-js/zstd": "^1.1.0 || ^2.0.0", + "gcp-metadata": "^5.2.0", + "kerberos": "^2.0.1", + "mongodb-client-encryption": ">=6.0.0 <7", + "snappy": "^7.3.2", + "socks": "^2.7.1" + }, + "peerDependenciesMeta": { + "@aws-sdk/credential-providers": { + "optional": true + }, + "@mongodb-js/zstd": { + "optional": true + }, + "gcp-metadata": { + "optional": true + }, + "kerberos": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "snappy": { + "optional": true + }, + "socks": { + "optional": true + } + } + }, + "node_modules/mongodb/node_modules/@types/whatwg-url": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.2.tgz", + "integrity": "sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/webidl-conversions": "*" + } + }, + "node_modules/mongodb/node_modules/bson": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/bson/-/bson-5.5.1.tgz", + "integrity": "sha512-ix0EwukN2EpC0SRWIj/7B5+A6uQMQy6KMREI9qQqvgpkV2frH63T0UDVd1SYedL6dNCmDBYB3QtXi4ISk9YT+g==", + "license": "Apache-2.0", + "engines": { + "node": ">=14.20.1" + } + }, + "node_modules/mongodb/node_modules/mongodb-connection-string-url": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz", + "integrity": "sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==", + "license": "Apache-2.0", + "dependencies": { + "@types/whatwg-url": "^8.2.1", + "whatwg-url": "^11.0.0" + } + }, + "node_modules/mongodb/node_modules/tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "license": "MIT", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/mongodb/node_modules/whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "license": "MIT", + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -18770,6 +18875,30 @@ "node": ">=10" } }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.7", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", + "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", + "license": "MIT", + "dependencies": { + "ip-address": "^10.0.1", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", diff --git a/apps/OpenSignServer/package.json b/apps/OpenSignServer/package.json index d3f3c4df78..598d3f54ed 100644 --- a/apps/OpenSignServer/package.json +++ b/apps/OpenSignServer/package.json @@ -38,7 +38,7 @@ "googleapis": "^161.0.0", "libreoffice-convert": "^1.7.0", "mailgun.js": "^12.1.0", - "mongodb": "^6.20.0", + "mongodb": "^5.9.2", "multer": "^2.0.2", "multer-s3": "^3.0.1", "node-forge": "^1.3.1", @@ -74,4 +74,4 @@ "engines": { "node": "18 || 20 || 22" } -} \ No newline at end of file +}