From 5707039002d9cd62bea2e97d13ad727c036d6871 Mon Sep 17 00:00:00 2001 From: prafull-opensignlabs Date: Wed, 21 Feb 2024 13:28:38 +0530 Subject: [PATCH] fix: handle uncaught err of file storage and email adapter --- apps/OpenSign/src/routes/ForgetPassword.js | 30 +++++- .../cloud/customRoute/uploadFile.js | 93 ++++++++++++------- .../cloud/parsefunction/sendMail.js | 43 +++++---- apps/OpenSignServer/index.js | 61 +++++++----- .../src/Component/placeHolderSign.js | 73 ++++++++++++++- 5 files changed, 215 insertions(+), 85 deletions(-) diff --git a/apps/OpenSign/src/routes/ForgetPassword.js b/apps/OpenSign/src/routes/ForgetPassword.js index 86cb9a6a8..e77ee1149 100644 --- a/apps/OpenSign/src/routes/ForgetPassword.js +++ b/apps/OpenSign/src/routes/ForgetPassword.js @@ -4,13 +4,15 @@ import { fetchAppInfo, forgetPassword } from "../redux/actions"; import Title from "../components/Title"; import { NavLink } from "react-router-dom"; import login_img from "../assets/images/login_img.svg"; - +import Parse from "parse"; +import Alert from "../primitives/Alert"; function ForgotPassword(props) { const [state, setState] = useState({ email: "", password: "", hideNav: "" }); + const [sentStatus, setSentStatus] = useState(""); const handleChange = (event) => { const { name, value } = event.target; setState({ ...state, [name]: value }); @@ -23,7 +25,7 @@ function ForgotPassword(props) { } }; - const handleSubmit = (event) => { + const handleSubmit = async (event) => { event.preventDefault(); localStorage.setItem("appLogo", props.appInfo.applogo); localStorage.setItem("appName", props.appInfo.appname); @@ -33,9 +35,21 @@ function ForgotPassword(props) { "userSettings", JSON.stringify(props.appInfo.settings) ); - if (state.email) { - props.forgetPassword(state.email); + const username = state.email; + let baseUrl = localStorage.getItem("BaseUrl12"); + let parseAppId = localStorage.getItem("AppID12"); + try { + Parse.serverURL = baseUrl; + Parse.initialize(parseAppId); + await Parse.User.requestPasswordReset(username); + setSentStatus("success"); + } catch (err) { + console.log("err ", err.code); + setSentStatus("failed"); + } finally { + setTimeout(() => setSentStatus(""), 1000); + } } }; @@ -51,6 +65,14 @@ function ForgotPassword(props) { return (
+ {sentStatus === "success" && ( + <Alert type="success"> + Reset password link has been sent to your email id + </Alert> + )} + {sentStatus === "failed" && ( + <Alert type={"danger"}>Please setup email adapter </Alert> + )} <div> <div className="md:m-10 lg:m-16 md:p-4 lg:p-10 p-5 bg-[#ffffff] md:border-[1px] md:border-gray-400 "> <div className="w-[250px] h-[66px] inline-block"> diff --git a/apps/OpenSignServer/cloud/customRoute/uploadFile.js b/apps/OpenSignServer/cloud/customRoute/uploadFile.js index b0152e1bd..352f7711b 100644 --- a/apps/OpenSignServer/cloud/customRoute/uploadFile.js +++ b/apps/OpenSignServer/cloud/customRoute/uploadFile.js @@ -47,53 +47,78 @@ async function uploadFile(req, res) { const DO_ACCESS_KEY_ID = process.env.DO_ACCESS_KEY_ID; const DO_SECRET_ACCESS_KEY = process.env.DO_SECRET_ACCESS_KEY; const DO_SPACE = process.env.DO_SPACE; - const spacesEndpoint = new aws.Endpoint(DO_ENDPOINT); - const s3 = new aws.S3({ - endpoint: spacesEndpoint, - accessKeyId: DO_ACCESS_KEY_ID, - secretAccessKey: DO_SECRET_ACCESS_KEY, - signatureVersion: 'v4', - region: process.env.DO_REGION, - }); const parseBaseUrl = process.env.SERVER_URL; const parseAppId = process.env.APP_ID; - - if (process.env.USE_LOCAL == "TRUE") { - var fileStorage = multer.diskStorage({ - destination: function(req, file, cb) { - cb(null, "files/files"); + let fileStorage; + if (process.env.USE_LOCAL == 'TRUE') { + fileStorage = multer.diskStorage({ + destination: function (req, file, cb) { + cb(null, 'files/files'); }, metadata: function (req, file, cb) { cb(null, { fieldName: 'OPENSIGN_METADATA' }); }, - filename: function(req, file, cb) { + filename: function (req, file, cb) { let filename = file.originalname; let newFileName = filename.split('.')[0]; let extension = filename.split('.')[1]; - newFileName = sanitizeFileName(newFileName + '_' + new Date().toISOString() + '.' + extension) + newFileName = sanitizeFileName( + newFileName + '_' + new Date().toISOString() + '.' + extension + ); console.log(newFileName); cb(null, newFileName); - } - }); - } else { - var fileStorage = multerS3({ - acl: 'public-read', - s3, - bucket: DO_SPACE, - metadata: function (req, file, cb) { - cb(null, { fieldName: 'OPENSIGN_METADATA' }); }, - key: function (req, file, cb) { - //console.log(file); - let filename = file.originalname; - let newFileName = filename.split('.')[0]; - let extension = filename.split('.')[1]; - newFileName = sanitizeFileName(newFileName + '_' + new Date().toISOString() + '.' + extension) - console.log(newFileName); - cb(null, newFileName); - } }); + } else { + try { + const spacesEndpoint = new aws.Endpoint(DO_ENDPOINT); + const s3 = new aws.S3({ + endpoint: spacesEndpoint, + accessKeyId: DO_ACCESS_KEY_ID, + secretAccessKey: DO_SECRET_ACCESS_KEY, + signatureVersion: 'v4', + region: process.env.DO_REGION, + }); + fileStorage = multerS3({ + acl: 'public-read', + s3, + bucket: DO_SPACE, + metadata: function (req, file, cb) { + cb(null, { fieldName: 'OPENSIGN_METADATA' }); + }, + key: function (req, file, cb) { + //console.log(file); + let filename = file.originalname; + let newFileName = filename.split('.')[0]; + let extension = filename.split('.')[1]; + newFileName = sanitizeFileName( + newFileName + '_' + new Date().toISOString() + '.' + extension + ); + console.log(newFileName); + cb(null, newFileName); + }, + }); + } catch (err) { + fileStorage = multer.diskStorage({ + destination: function (req, file, cb) { + cb(null, 'files/files'); + }, + metadata: function (req, file, cb) { + cb(null, { fieldName: 'OPENSIGN_METADATA' }); + }, + filename: function (req, file, cb) { + let filename = file.originalname; + let newFileName = filename.split('.')[0]; + let extension = filename.split('.')[1]; + newFileName = sanitizeFileName( + newFileName + '_' + new Date().toISOString() + '.' + extension + ); + console.log(newFileName); + cb(null, newFileName); + }, + }); + } } // const s3 = new aws.S3(); @@ -122,7 +147,7 @@ async function uploadFile(req, res) { const status = 'Success'; //res.header("Access-Control-Allow-Headers", "Content-Type"); //res.setHeader("Access-Control-Allow-Origin", "*"); - if (process.env.USE_LOCAL == "TRUE") { + if (process.env.USE_LOCAL == 'TRUE') { console.log(req.file); var fileUrl = `${parseBaseUrl}/files/${parseAppId}/${req.file.filename}`; } else { diff --git a/apps/OpenSignServer/cloud/parsefunction/sendMail.js b/apps/OpenSignServer/cloud/parsefunction/sendMail.js index c607c2822..f8fb5f8da 100644 --- a/apps/OpenSignServer/cloud/parsefunction/sendMail.js +++ b/apps/OpenSignServer/cloud/parsefunction/sendMail.js @@ -4,30 +4,29 @@ import formData from 'form-data'; import Mailgun from 'mailgun.js'; import { createTransport } from 'nodemailer'; -let transporterSMTP; -let mailgunClient; -let mailgunDomain; -if (process.env.SMTP_ENABLE) { - transporterSMTP = createTransport({ - host: process.env.SMTP_HOST, - port: process.env.SMTP_PORT || 465, - secure: process.env.SMTP_SECURE || true, - auth: { - user: process.env.SMTP_USER_EMAIL, - pass: process.env.SMTP_PASS, - }, - }); -} else { - const mailgun = new Mailgun(formData); - mailgunClient = mailgun.client({ - username: 'api', - key: process.env.MAILGUN_API_KEY, - }); - mailgunDomain = process.env.MAILGUN_DOMAIN; -} - async function sendmail(req) { try { + let transporterSMTP; + let mailgunClient; + let mailgunDomain; + if (process.env.SMTP_ENABLE) { + transporterSMTP = createTransport({ + host: process.env.SMTP_HOST, + port: process.env.SMTP_PORT || 465, + secure: process.env.SMTP_SECURE || true, + auth: { + user: process.env.SMTP_USER_EMAIL, + pass: process.env.SMTP_PASS, + }, + }); + } else { + const mailgun = new Mailgun(formData); + mailgunClient = mailgun.client({ + username: 'api', + key: process.env.MAILGUN_API_KEY, + }); + mailgunDomain = process.env.MAILGUN_DOMAIN; + } if (req.params.url) { let Pdf = fs.createWriteStream('test.pdf'); const writeToLocalDisk = () => { diff --git a/apps/OpenSignServer/index.js b/apps/OpenSignServer/index.js index 07da66812..ed80107c8 100644 --- a/apps/OpenSignServer/index.js +++ b/apps/OpenSignServer/index.js @@ -21,24 +21,32 @@ import { exec } from 'child_process'; import { createTransport } from 'nodemailer'; import { app as v1 } from './cloud/customRoute/v1/apiV1.js'; import { PostHog } from 'posthog-node'; -const spacesEndpoint = new AWS.Endpoint(process.env.DO_ENDPOINT); // console.log("configuration ", configuration); +let fsAdapter; if (process.env.USE_LOCAL !== 'TRUE') { - const s3Options = { - bucket: process.env.DO_SPACE, // globalConfig.S3FilesAdapter.bucket, - baseUrl: process.env.DO_BASEURL, - region: process.env.DO_REGION, - directAccess: true, - preserveFileName: true, - s3overrides: { - accessKeyId: process.env.DO_ACCESS_KEY_ID, - secretAccessKey: process.env.DO_SECRET_ACCESS_KEY, - endpoint: spacesEndpoint, - }, - }; - var fsAdapter = new S3Adapter(s3Options); + try { + const spacesEndpoint = new AWS.Endpoint(process.env.DO_ENDPOINT); + const s3Options = { + bucket: process.env.DO_SPACE, // globalConfig.S3FilesAdapter.bucket, + baseUrl: process.env.DO_BASEURL, + region: process.env.DO_REGION, + directAccess: true, + preserveFileName: true, + s3overrides: { + accessKeyId: process.env.DO_ACCESS_KEY_ID, + secretAccessKey: process.env.DO_SECRET_ACCESS_KEY, + endpoint: spacesEndpoint, + }, + }; + fsAdapter = new S3Adapter(s3Options); + } catch (err) { + console.log('err ', err); + fsAdapter = new FSFilesAdapter({ + filesSubDirectory: 'files', // optional, defaults to ./files + }); + } } else { - var fsAdapter = new FSFilesAdapter({ + fsAdapter = new FSFilesAdapter({ filesSubDirectory: 'files', // optional, defaults to ./files }); } @@ -78,14 +86,14 @@ export const config = { masterKey: process.env.MASTER_KEY || '', //Add your master key here. Keep it secret! masterKeyIps: ['0.0.0.0/0', '::1'], // '::1' serverURL: process.env.SERVER_URL || 'http://localhost:8080/app', // Don't forget to change to https if needed - verifyUserEmails: true, + verifyUserEmails: process.env.SMTP_ENABLE || process.env.MAILGUN_API_KEY ? true : false, publicServerURL: process.env.SERVER_URL || 'http://localhost:8080/app', // Your apps name. This will appear in the subject and body of the emails that are sent. appName: 'Open Sign', allowClientClassCreation: false, - emailAdapter: - process.env.SMTP_ENABLE || process.env.MAILGUN_API_KEY - ? { + ...(process.env.SMTP_ENABLE || process.env.MAILGUN_API_KEY + ? { + emailAdapter: { module: 'parse-server-api-mail-adapter', options: { // The email address from which emails are sent. @@ -116,8 +124,9 @@ export const config = { } else if (transporterMail) await transporterMail.sendMail(payload); }, }, - } - : null, + }, + } + : {}), filesAdapter: fsAdapter, auth: { google: { @@ -170,9 +179,13 @@ app.use('/public', express.static(path.join(__dirname, '/public'))); // Serve the Parse API on the /parse URL prefix if (!process.env.TESTING) { const mountPath = process.env.PARSE_MOUNT || '/app'; - const server = new ParseServer(config); - await server.start(); - app.use(mountPath, server.app); + try { + const server = new ParseServer(config); + await server.start(); + app.use(mountPath, server.app); + } catch (err) { + console.log('Err ', err); + } } // Mount your custom express app app.use('/', customRoute); diff --git a/microfrontends/SignDocuments/src/Component/placeHolderSign.js b/microfrontends/SignDocuments/src/Component/placeHolderSign.js index ec16c84ae..474fc40fd 100644 --- a/microfrontends/SignDocuments/src/Component/placeHolderSign.js +++ b/microfrontends/SignDocuments/src/Component/placeHolderSign.js @@ -84,6 +84,7 @@ function PlaceHolderSign() { const [signerExistModal, setSignerExistModal] = useState(false); const [isDontShow, setIsDontShow] = useState(false); const [isDragging, setIsDragging] = useState(false); + const [mailStatus, setMailStatus] = useState(""); const color = [ "#93a3db", "#e6c3db", @@ -724,6 +725,72 @@ function PlaceHolderSign() { } if (sendMail.data.result.status === "success") { + setMailStatus("success"); + const signers = signersdata?.map((x) => { + return { + __type: "Pointer", + className: "contracts_Contactbook", + objectId: x.objectId + }; + }); + const addExtraDays = pdfDetails[0]?.TimeToCompleteDays + ? pdfDetails[0].TimeToCompleteDays + : 15; + const currentUser = signersdata.find((x) => x.Email === currentId); + setCurrentId(currentUser?.objectId); + let updateExpiryDate, data; + updateExpiryDate = new Date(); + updateExpiryDate.setDate(updateExpiryDate.getDate() + addExtraDays); + + try { + if (updateExpiryDate) { + data = { + Placeholders: signerPos, + SignedUrl: pdfDetails[0].URL, + Signers: signers, + ExpiryDate: { + iso: updateExpiryDate, + __type: "Date" + } + }; + } else { + data = { + Placeholders: signerPos, + SignedUrl: pdfDetails[0].URL, + Signers: signers + }; + } + + await axios + .put( + `${localStorage.getItem("baseUrl")}classes/${localStorage.getItem( + "_appName" + )}_Document/${documentId}`, + data, + { + headers: { + "Content-Type": "application/json", + "X-Parse-Application-Id": localStorage.getItem("parseAppId"), + "X-Parse-Session-Token": localStorage.getItem("accesstoken") + } + } + ) + .then((result) => { + setIsSend(true); + setIsMailSend(true); + const loadObj = { + isLoad: false + }; + setIsLoading(loadObj); + }) + .catch((err) => { + console.log("axois err ", err); + }); + } catch (e) { + console.log("error", e); + } + } else { + setMailStatus("failed"); const signers = signersdata?.map((x) => { return { __type: "Pointer", @@ -1059,7 +1126,11 @@ function PlaceHolderSign() { }} > <div style={{ height: "100%", padding: 20 }}> - <p>You have successfully sent mails to all recipients!</p> + {mailStatus === "success" ? ( + <p>You have successfully sent mails to all recipients!</p> + ) : ( + <p>Please setup mail adapter to send mail!</p> + )} {currentId && ( <p>Do you want to sign documents right now ?</p> )}