mirror of
https://github.com/OpenSignLabs/OpenSign.git
synced 2026-09-05 01:07:39 +02:00
Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8833018027 | ||
|
|
d1c405912b | ||
|
|
745aca1754 | ||
|
|
672eeea851 | ||
|
|
98efff65c9 |
@@ -3,13 +3,13 @@
|
|||||||
"version": "2.26.0",
|
"version": "2.26.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@formkit/auto-animate": "^0.8.4",
|
"@formkit/auto-animate": "^0.9.0",
|
||||||
"@imgly/background-removal": "^1.7.0",
|
"@imgly/background-removal": "^1.7.0",
|
||||||
"@lottiefiles/dotlottie-react": "^0.15.2",
|
"@lottiefiles/dotlottie-react": "^0.16.2",
|
||||||
"@pdf-lib/fontkit": "^1.1.1",
|
"@pdf-lib/fontkit": "^1.1.1",
|
||||||
"@radix-ui/themes": "^3.2.1",
|
"@radix-ui/themes": "^3.2.1",
|
||||||
"@reduxjs/toolkit": "^2.8.2",
|
"@reduxjs/toolkit": "^2.8.2",
|
||||||
"axios": "^1.11.0",
|
"axios": "^1.12.2",
|
||||||
"date-fns-tz": "^3.2.0",
|
"date-fns-tz": "^3.2.0",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"i18next": "^25.4.0",
|
"i18next": "^25.4.0",
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
"react-quill-new": "^3.6.0",
|
"react-quill-new": "^3.6.0",
|
||||||
"react-redux": "^9.2.0",
|
"react-redux": "^9.2.0",
|
||||||
"react-rnd": "^10.5.2",
|
"react-rnd": "^10.5.2",
|
||||||
"react-router": "^7.8.2",
|
"react-router": "^7.9.1",
|
||||||
"react-scrollbars-custom": "^4.1.1",
|
"react-scrollbars-custom": "^4.1.1",
|
||||||
"react-select": "^5.10.2",
|
"react-select": "^5.10.2",
|
||||||
"react-signature-canvas": "^1.1.0-alpha.2",
|
"react-signature-canvas": "^1.1.0-alpha.2",
|
||||||
@@ -101,7 +101,7 @@
|
|||||||
"@testing-library/jest-dom": "^6.8.0",
|
"@testing-library/jest-dom": "^6.8.0",
|
||||||
"@testing-library/react": "^16.3.0",
|
"@testing-library/react": "^16.3.0",
|
||||||
"@testing-library/user-event": "^14.6.1",
|
"@testing-library/user-event": "^14.6.1",
|
||||||
"@types/react": "^19.1.12",
|
"@types/react": "^19.1.13",
|
||||||
"@vitejs/plugin-react": "^4.7.0",
|
"@vitejs/plugin-react": "^4.7.0",
|
||||||
"@vitest/ui": "^3.2.4",
|
"@vitest/ui": "^3.2.4",
|
||||||
"autoprefixer": "^10.4.21",
|
"autoprefixer": "^10.4.21",
|
||||||
@@ -113,7 +113,7 @@
|
|||||||
"eslint": "^9.34.0",
|
"eslint": "^9.34.0",
|
||||||
"eslint-plugin-prettier": "^5.5.4",
|
"eslint-plugin-prettier": "^5.5.4",
|
||||||
"eslint-plugin-react": "^7.37.5",
|
"eslint-plugin-react": "^7.37.5",
|
||||||
"jsdom": "^26.1.0",
|
"jsdom": "^27.0.0",
|
||||||
"lint-staged": "^16.1.6",
|
"lint-staged": "^16.1.6",
|
||||||
"postcss": "^8.5.6",
|
"postcss": "^8.5.6",
|
||||||
"prettier": "^3.6.2",
|
"prettier": "^3.6.2",
|
||||||
|
|||||||
@@ -671,18 +671,21 @@ function WidgetsValueModal(props) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isTab === "type") {
|
if (isTab === "type") {
|
||||||
|
const signerName = localStorage.getItem("signer")
|
||||||
|
? JSON.parse(localStorage.getItem("signer"))?.Name
|
||||||
|
: currentUserName;
|
||||||
//trim user name or typed name value to show in initial signature
|
//trim user name or typed name value to show in initial signature
|
||||||
const trimmedName = typedSignature
|
const trimmedName = typedSignature
|
||||||
? typedSignature?.trim()
|
? typedSignature?.trim()
|
||||||
: props?.journey === "kiosk-signing" && kiosk_signer
|
: props?.journey === "kiosk-signing" && kiosk_signer
|
||||||
? kiosk_signer[0]?.Name?.trim()
|
? kiosk_signer[0]?.Name?.trim()
|
||||||
: currentUserName?.trim();
|
: signerName?.trim();
|
||||||
//get full name of user
|
//get full name of user
|
||||||
const fullUserName =
|
const fullUserName =
|
||||||
typedSignature ||
|
typedSignature ||
|
||||||
(props?.journey === "kiosk-signing" && kiosk_signer
|
(props?.journey === "kiosk-signing" && kiosk_signer
|
||||||
? kiosk_signer[0]?.Name
|
? kiosk_signer[0]?.Name
|
||||||
: currentUserName);
|
: signerName);
|
||||||
const firstCharacter = trimmedName?.charAt(0);
|
const firstCharacter = trimmedName?.charAt(0);
|
||||||
const userName =
|
const userName =
|
||||||
currWidgetsDetails?.type === "initials" ? firstCharacter : fullUserName;
|
currWidgetsDetails?.type === "initials" ? firstCharacter : fullUserName;
|
||||||
@@ -1201,8 +1204,8 @@ function WidgetsValueModal(props) {
|
|||||||
)
|
)
|
||||||
) : isTab === "type" ? (
|
) : isTab === "type" ? (
|
||||||
<>
|
<>
|
||||||
<div className="flex justify-between items-center tabWidth">
|
<div className="flex justify-between items-center tabWidth rounded-[4px]">
|
||||||
<span className="mr-[5px] text-[12px]">
|
<span className="ml-[5px] text-[12px] text-base-content">
|
||||||
{currWidgetsDetails?.type === "initials"
|
{currWidgetsDetails?.type === "initials"
|
||||||
? t("initial-teb")
|
? t("initial-teb")
|
||||||
: t("signature-tab")}
|
: t("signature-tab")}
|
||||||
@@ -1229,7 +1232,7 @@ function WidgetsValueModal(props) {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="border-[1px] border-[#d6d3d3] mt-[10px] ml-[5px]">
|
<div className="border-[1px] border-[#d6d3d3] mt-[10px] rounded-[4px]">
|
||||||
{fontOptions.map((font, ind) => {
|
{fontOptions.map((font, ind) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@@ -1252,7 +1255,7 @@ function WidgetsValueModal(props) {
|
|||||||
>
|
>
|
||||||
{typedSignature
|
{typedSignature
|
||||||
? typedSignature
|
? typedSignature
|
||||||
: "Your signature"}
|
: t("Your-Signature")}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -1656,7 +1659,7 @@ function WidgetsValueModal(props) {
|
|||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
return (
|
return (
|
||||||
<span className="text-center text-[12px]">
|
<span className="text-center text-[12px] text-base-content">
|
||||||
{t("required-mssg", { leftRequiredWidget, totalWidget })}
|
{t("required-mssg", { leftRequiredWidget, totalWidget })}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
@@ -1888,15 +1891,15 @@ function WidgetsValueModal(props) {
|
|||||||
{isFinish ? (
|
{isFinish ? (
|
||||||
<>
|
<>
|
||||||
<div className="p-1 mt-3">
|
<div className="p-1 mt-3">
|
||||||
<span className="text-base">{t("finish-mssg")}</span>
|
<span className="text-base text-base-content">
|
||||||
|
{t("finish-mssg")}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex gap-3 items-center mt-4">
|
<div className="flex gap-3 items-center mt-4">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="op-btn op-btn-primary op-btn-sm px-4"
|
className="op-btn op-btn-primary op-btn-sm px-4"
|
||||||
onClick={() => {
|
onClick={() => handleFinish()}
|
||||||
handleFinish();
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{t("finish")}
|
{t("finish")}
|
||||||
</button>
|
</button>
|
||||||
@@ -1956,9 +1959,7 @@ function WidgetsValueModal(props) {
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="op-btn op-btn-primary op-btn-sm"
|
className="op-btn op-btn-primary op-btn-sm"
|
||||||
onClick={() => {
|
onClick={() => handleClickOnNext()}
|
||||||
handleClickOnNext();
|
|
||||||
}}
|
|
||||||
disabled={handleDisable()}
|
disabled={handleDisable()}
|
||||||
>
|
>
|
||||||
{t("save")}
|
{t("save")}
|
||||||
@@ -1968,10 +1969,7 @@ function WidgetsValueModal(props) {
|
|||||||
type="button"
|
type="button"
|
||||||
className="op-btn op-btn-primary op-btn-sm"
|
className="op-btn op-btn-primary op-btn-sm"
|
||||||
disabled={handleDisable()}
|
disabled={handleDisable()}
|
||||||
onClick={() => {
|
onClick={() => handleClickOnNext(true)} // isFinishDoc
|
||||||
const isFinishDoc = true;
|
|
||||||
handleClickOnNext(isFinishDoc);
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{t("done")}
|
{t("done")}
|
||||||
</button>
|
</button>
|
||||||
@@ -1979,9 +1977,7 @@ function WidgetsValueModal(props) {
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="op-btn op-btn-primary op-btn-sm text-xs md:text-sm"
|
className="op-btn op-btn-primary op-btn-sm text-xs md:text-sm"
|
||||||
onClick={() => {
|
onClick={() => handleClickOnNext()}
|
||||||
handleClickOnNext();
|
|
||||||
}}
|
|
||||||
disabled={handleDisable()}
|
disabled={handleDisable()}
|
||||||
>
|
>
|
||||||
{t("next-field")}
|
{t("next-field")}
|
||||||
|
|||||||
@@ -253,7 +253,7 @@ const AddAdmin = () => {
|
|||||||
/[A-Z]/.test(newPassword) &&
|
/[A-Z]/.test(newPassword) &&
|
||||||
/\d/.test(newPassword)
|
/\d/.test(newPassword)
|
||||||
);
|
);
|
||||||
setSpecialCharValid(/[!@#$%^&*()\-_=+{};:,<.>]/.test(newPassword));
|
setSpecialCharValid(/[!@#$%^&*()\-_=+{};:,<.>?]/.test(newPassword));
|
||||||
};
|
};
|
||||||
const subscribeNewsletter = async () => {
|
const subscribeNewsletter = async () => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -4,6 +4,18 @@ import { Navigate } from "react-router";
|
|||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
function ChangePassword() {
|
function ChangePassword() {
|
||||||
|
const [lengthValid, setLengthValid] = useState(false);
|
||||||
|
const [caseDigitValid, setCaseDigitValid] = useState(false);
|
||||||
|
const [specialCharValid, setSpecialCharValid] = useState(false);
|
||||||
|
const handlePasswordChange = (e) => {
|
||||||
|
const value = e.target.value;
|
||||||
|
setnewpassword(value);
|
||||||
|
setLengthValid(value.length >= 8);
|
||||||
|
setCaseDigitValid(
|
||||||
|
/[a-z]/.test(value) && /[A-Z]/.test(value) && /\d/.test(value)
|
||||||
|
);
|
||||||
|
setSpecialCharValid(/[!@#$%^&*()\-_=+{};:,<.>?]/.test(value));
|
||||||
|
};
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [currentpassword, setCurrentPassword] = useState("");
|
const [currentpassword, setCurrentPassword] = useState("");
|
||||||
const [newpassword, setnewpassword] = useState("");
|
const [newpassword, setnewpassword] = useState("");
|
||||||
@@ -84,13 +96,26 @@ function ChangePassword() {
|
|||||||
type="password"
|
type="password"
|
||||||
name="newpassword"
|
name="newpassword"
|
||||||
value={newpassword}
|
value={newpassword}
|
||||||
onChange={(e) => setnewpassword(e.target.value)}
|
onChange={handlePasswordChange}
|
||||||
className="op-input op-input-bordered op-input-sm text-xs w-full"
|
className="op-input op-input-bordered op-input-sm text-xs w-full"
|
||||||
placeholder={t("new-password")}
|
placeholder={t("new-password")}
|
||||||
onInvalid={(e) => e.target.setCustomValidity(t("input-required"))}
|
onInvalid={(e) => e.target.setCustomValidity(t("input-required"))}
|
||||||
onInput={(e) => e.target.setCustomValidity("")}
|
onInput={(e) => e.target.setCustomValidity("")}
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
|
{newpassword.length > 0 && (
|
||||||
|
<div className="mt-1 text-[11px]">
|
||||||
|
<p className={lengthValid ? "text-green-600" : "text-red-600"}>
|
||||||
|
{lengthValid ? "✓" : "✗"} Password length ≥ 8
|
||||||
|
</p>
|
||||||
|
<p className={caseDigitValid ? "text-green-600" : "text-red-600"}>
|
||||||
|
{caseDigitValid ? "✓" : "✗"} Uppercase, lowercase, and number
|
||||||
|
</p>
|
||||||
|
<p className={specialCharValid ? "text-green-600" : "text-red-600"}>
|
||||||
|
{specialCharValid ? "✓" : "✗"} Special character
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label htmlFor="newpassword" className="text-xs block ml-1">
|
<label htmlFor="newpassword" className="text-xs block ml-1">
|
||||||
|
|||||||
@@ -13,6 +13,18 @@ import { useTranslation } from "react-i18next";
|
|||||||
import Loader from "../primitives/Loader";
|
import Loader from "../primitives/Loader";
|
||||||
|
|
||||||
function ForgotPassword() {
|
function ForgotPassword() {
|
||||||
|
const [lengthValid, setLengthValid] = useState(false);
|
||||||
|
const [caseDigitValid, setCaseDigitValid] = useState(false);
|
||||||
|
const [specialCharValid, setSpecialCharValid] = useState(false);
|
||||||
|
const handlePasswordChange = (event) => {
|
||||||
|
let value = event.target.value;
|
||||||
|
setState({ ...state, password: value });
|
||||||
|
setLengthValid(value.length >= 8);
|
||||||
|
setCaseDigitValid(
|
||||||
|
/[a-z]/.test(value) && /[A-Z]/.test(value) && /\d/.test(value)
|
||||||
|
);
|
||||||
|
setSpecialCharValid(/[!@#$%^&*()\-_=+{};:,<.>?]/.test(value));
|
||||||
|
};
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@@ -124,6 +136,28 @@ function ForgotPassword() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-2 text-center text-xs font-bold">
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-2 text-center text-xs font-bold">
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
name="password"
|
||||||
|
className="op-input op-input-bordered op-input-sm w-full mt-2"
|
||||||
|
value={state.password}
|
||||||
|
onChange={handlePasswordChange}
|
||||||
|
placeholder="New password"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
{state.password.length > 0 && (
|
||||||
|
<div className="mt-1 text-[11px]">
|
||||||
|
<p className={lengthValid ? "text-green-600" : "text-red-600"}>
|
||||||
|
{lengthValid ? "✓" : "✗"} Password length ≥ 8
|
||||||
|
</p>
|
||||||
|
<p className={caseDigitValid ? "text-green-600" : "text-red-600"}>
|
||||||
|
{caseDigitValid ? "✓" : "✗"} Uppercase, lowercase, and number
|
||||||
|
</p>
|
||||||
|
<p className={specialCharValid ? "text-green-600" : "text-red-600"}>
|
||||||
|
{specialCharValid ? "✓" : "✗"} Special character
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<button type="submit" className="op-btn op-btn-primary">
|
<button type="submit" className="op-btn op-btn-primary">
|
||||||
{t("submit")}
|
{t("submit")}
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -631,10 +631,12 @@ const Forms = (props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="shadow-md rounded-box my-[2px] p-3 bg-base-100 text-base-content">
|
<div
|
||||||
|
className={`${isSubmit ? "" : "shadow-md rounded-box my-[2px] p-3 bg-base-100 text-base-content"}`}
|
||||||
|
>
|
||||||
{isAlert?.message && <Alert type={isAlert.type}>{isAlert.message}</Alert>}
|
{isAlert?.message && <Alert type={isAlert.type}>{isAlert.message}</Alert>}
|
||||||
{isSubmit ? (
|
{isSubmit ? (
|
||||||
<div className="h-[300px] flex justify-center items-center">
|
<div className="flex flex-col justify-center items-center h-[100vh]">
|
||||||
<Loader />
|
<Loader />
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -23,6 +23,18 @@ import { useTranslation } from "react-i18next";
|
|||||||
import SelectLanguage from "../components/pdf/SelectLanguage";
|
import SelectLanguage from "../components/pdf/SelectLanguage";
|
||||||
|
|
||||||
function Login() {
|
function Login() {
|
||||||
|
const [lengthValid, setLengthValid] = useState(false);
|
||||||
|
const [caseDigitValid, setCaseDigitValid] = useState(false);
|
||||||
|
const [specialCharValid, setSpecialCharValid] = useState(false);
|
||||||
|
const handlePasswordChange = (event) => {
|
||||||
|
let value = event.target.value;
|
||||||
|
setState({ ...state, password: value });
|
||||||
|
setLengthValid(value.length >= 8);
|
||||||
|
setCaseDigitValid(
|
||||||
|
/[a-z]/.test(value) && /[A-Z]/.test(value) && /\d/.test(value)
|
||||||
|
);
|
||||||
|
setSpecialCharValid(/[!@#$%^&*()\-_=+{};:,<.>?]/.test(value));
|
||||||
|
};
|
||||||
const appName =
|
const appName =
|
||||||
"OpenSign™";
|
"OpenSign™";
|
||||||
const { t, i18n } = useTranslation();
|
const { t, i18n } = useTranslation();
|
||||||
@@ -474,7 +486,7 @@ function Login() {
|
|||||||
name="password"
|
name="password"
|
||||||
value={state.password}
|
value={state.password}
|
||||||
autoComplete="current-password"
|
autoComplete="current-password"
|
||||||
onChange={handleChange}
|
onChange={handlePasswordChange}
|
||||||
onInvalid={(e) =>
|
onInvalid={(e) =>
|
||||||
e.target.setCustomValidity(
|
e.target.setCustomValidity(
|
||||||
t("input-required")
|
t("input-required")
|
||||||
@@ -495,6 +507,19 @@ function Login() {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="relative mt-1">
|
<div className="relative mt-1">
|
||||||
|
{state.password.length > 0 && (
|
||||||
|
<div className="mt-1 text-[11px]">
|
||||||
|
<p className={lengthValid ? "text-green-600" : "text-red-600"}>
|
||||||
|
{lengthValid ? "✓" : "✗"} Password length ≥ 8
|
||||||
|
</p>
|
||||||
|
<p className={caseDigitValid ? "text-green-600" : "text-red-600"}>
|
||||||
|
{caseDigitValid ? "✓" : "✗"} Uppercase, lowercase, and number
|
||||||
|
</p>
|
||||||
|
<p className={specialCharValid ? "text-green-600" : "text-red-600"}>
|
||||||
|
{specialCharValid ? "✓" : "✗"} Special character
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<NavLink
|
<NavLink
|
||||||
to="/forgetpassword"
|
to="/forgetpassword"
|
||||||
className="text-[13px] op-link op-link-primary underline-offset-1 focus:outline-none ml-1"
|
className="text-[13px] op-link op-link-primary underline-offset-1 focus:outline-none ml-1"
|
||||||
|
|||||||
@@ -487,7 +487,7 @@ function UserProfile() {
|
|||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
{deleteUserRes ? (
|
{deleteUserRes ? (
|
||||||
<div className="h-[100px] p-[20px] flex justify-center items-center text-sm md:text-base">
|
<div className="h-[100px] p-[20px] flex justify-center items-center text-base-content text-sm md:text-base">
|
||||||
{deleteUserRes}
|
{deleteUserRes}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { cloudServerUrl, generateId, serverAppId } from '../../../Utils.js';
|
import { cloudServerUrl, generateId, serverAppId } from '../../../Utils.js';
|
||||||
import sendmailtoSupport from '../sendMailToSupport.js';
|
|
||||||
import { deleteContactsInBatch, deleteDataFiles, deleteInBatches } from './deleteFileUrl.js';
|
import { deleteContactsInBatch, deleteDataFiles, deleteInBatches } from './deleteFileUrl.js';
|
||||||
import { MAX_ATTEMPTS } from './deleteUtils.js';
|
import { MAX_ATTEMPTS } from './deleteUtils.js';
|
||||||
const serverUrl = cloudServerUrl;
|
const serverUrl = cloudServerUrl;
|
||||||
@@ -55,7 +54,6 @@ export async function deleteUser(userId, adminId) {
|
|||||||
userDetails = { ...userDetails, UserId: userId };
|
userDetails = { ...userDetails, UserId: userId };
|
||||||
if (!userResult) {
|
if (!userResult) {
|
||||||
const errorMessage = 'User not found.';
|
const errorMessage = 'User not found.';
|
||||||
sendmailtoSupport(userDetails, errorMessage);
|
|
||||||
return { code: 400, message: errorMessage };
|
return { code: 400, message: errorMessage };
|
||||||
}
|
}
|
||||||
const contractsUserId = userResult.id;
|
const contractsUserId = userResult.id;
|
||||||
@@ -74,7 +72,6 @@ export async function deleteUser(userId, adminId) {
|
|||||||
};
|
};
|
||||||
if (adminId && isAdmin) {
|
if (adminId && isAdmin) {
|
||||||
const errorMessage = 'An error occurred while deleting your account.';
|
const errorMessage = 'An error occurred while deleting your account.';
|
||||||
sendmailtoSupport(userDetails, errorMessage);
|
|
||||||
return { code: 400, message: errorMessage };
|
return { code: 400, message: errorMessage };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +83,6 @@ export async function deleteUser(userId, adminId) {
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed during contracts_Template cleanup:', err);
|
console.error('Failed during contracts_Template cleanup:', err);
|
||||||
const errorMessage = 'Failed during contracts_Template cleanup:' + err?.message;
|
const errorMessage = 'Failed during contracts_Template cleanup:' + err?.message;
|
||||||
sendmailtoSupport(userDetails, errorMessage);
|
|
||||||
return { code: 400, message: errorMessage };
|
return { code: 400, message: errorMessage };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,7 +92,6 @@ export async function deleteUser(userId, adminId) {
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed during contactbook cleanup:', err);
|
console.error('Failed during contactbook cleanup:', err);
|
||||||
const errorMessage = 'Failed during contactbook cleanup:' + err?.message;
|
const errorMessage = 'Failed during contactbook cleanup:' + err?.message;
|
||||||
sendmailtoSupport(userDetails, errorMessage);
|
|
||||||
return { code: 400, message: errorMessage };
|
return { code: 400, message: errorMessage };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,7 +112,6 @@ export async function deleteUser(userId, adminId) {
|
|||||||
console.error('Failed during contactbook current user cleanup:', err);
|
console.error('Failed during contactbook current user cleanup:', err);
|
||||||
const errorMessage =
|
const errorMessage =
|
||||||
'Failed during contactbook current user cleanup: ' + (err?.message || err);
|
'Failed during contactbook current user cleanup: ' + (err?.message || err);
|
||||||
sendmailtoSupport(userDetails, errorMessage);
|
|
||||||
return { code: 400, message: errorMessage };
|
return { code: 400, message: errorMessage };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +125,6 @@ export async function deleteUser(userId, adminId) {
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to delete appToken entries:', err);
|
console.error('Failed to delete appToken entries:', err);
|
||||||
const errorMessage = 'Failed to delete appToken entries:' + err?.message;
|
const errorMessage = 'Failed to delete appToken entries:' + err?.message;
|
||||||
sendmailtoSupport(userDetails, errorMessage);
|
|
||||||
return { code: 400, message: errorMessage };
|
return { code: 400, message: errorMessage };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,7 +134,6 @@ export async function deleteUser(userId, adminId) {
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed during partners_DataFiles cleanup:', err);
|
console.error('Failed during partners_DataFiles cleanup:', err);
|
||||||
const errorMessage = 'Failed during partners_DataFiles cleanup:' + err?.message;
|
const errorMessage = 'Failed during partners_DataFiles cleanup:' + err?.message;
|
||||||
sendmailtoSupport(userDetails, errorMessage);
|
|
||||||
return { code: 400, message: errorMessage };
|
return { code: 400, message: errorMessage };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,7 +149,6 @@ export async function deleteUser(userId, adminId) {
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to delete contracts_Organizations entry:', err);
|
console.error('Failed to delete contracts_Organizations entry:', err);
|
||||||
const errorMessage = 'Failed to delete contracts_Organizations entry:' + err?.message;
|
const errorMessage = 'Failed to delete contracts_Organizations entry:' + err?.message;
|
||||||
sendmailtoSupport(userDetails, errorMessage);
|
|
||||||
return { code: 400, message: errorMessage };
|
return { code: 400, message: errorMessage };
|
||||||
}
|
}
|
||||||
// STEP 7: Delete each entry in contracts_Teams by objectId from teamIds
|
// STEP 7: Delete each entry in contracts_Teams by objectId from teamIds
|
||||||
@@ -171,7 +162,6 @@ export async function deleteUser(userId, adminId) {
|
|||||||
} catch (teamErr) {
|
} catch (teamErr) {
|
||||||
console.error(`Failed to delete team with ID ${team.id}:`, teamErr);
|
console.error(`Failed to delete team with ID ${team.id}:`, teamErr);
|
||||||
const errorMessage = `Failed to delete team with ID ${team.id}` + teamErr?.message;
|
const errorMessage = `Failed to delete team with ID ${team.id}` + teamErr?.message;
|
||||||
sendmailtoSupport(userDetails, errorMessage);
|
|
||||||
return { code: 400, message: errorMessage };
|
return { code: 400, message: errorMessage };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -179,7 +169,6 @@ export async function deleteUser(userId, adminId) {
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed during contracts_Teams deletion loop:', err);
|
console.error('Failed during contracts_Teams deletion loop:', err);
|
||||||
const errorMessage = 'Failed during contracts_Teams deletion loop:' + err?.message;
|
const errorMessage = 'Failed during contracts_Teams deletion loop:' + err?.message;
|
||||||
sendmailtoSupport(userDetails, errorMessage);
|
|
||||||
return { code: 400, message: errorMessage };
|
return { code: 400, message: errorMessage };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,7 +184,6 @@ export async function deleteUser(userId, adminId) {
|
|||||||
const msg = `Failed during partners_Tenant ${'cleanup:'} `;
|
const msg = `Failed during partners_Tenant ${'cleanup:'} `;
|
||||||
console.error(msg, err);
|
console.error(msg, err);
|
||||||
const errorMessage = msg + err?.message;
|
const errorMessage = msg + err?.message;
|
||||||
sendmailtoSupport(userDetails, errorMessage);
|
|
||||||
return { code: 400, message: errorMessage };
|
return { code: 400, message: errorMessage };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,7 +203,6 @@ export async function deleteUser(userId, adminId) {
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed during partners_TenantCredits cleanup:', err);
|
console.error('Failed during partners_TenantCredits cleanup:', err);
|
||||||
const errorMessage = 'Failed during partners_TenantCredits cleanup:' + err?.message;
|
const errorMessage = 'Failed during partners_TenantCredits cleanup:' + err?.message;
|
||||||
sendmailtoSupport(userDetails, errorMessage);
|
|
||||||
return { code: 400, message: errorMessage };
|
return { code: 400, message: errorMessage };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -229,7 +216,6 @@ export async function deleteUser(userId, adminId) {
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed during contracts_Signature cleanup:', err);
|
console.error('Failed during contracts_Signature cleanup:', err);
|
||||||
const errorMessage = 'Failed during contracts_Signature cleanup:' + err?.message;
|
const errorMessage = 'Failed during contracts_Signature cleanup:' + err?.message;
|
||||||
sendmailtoSupport(userDetails, errorMessage);
|
|
||||||
return { code: 400, message: errorMessage };
|
return { code: 400, message: errorMessage };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,14 +225,12 @@ export async function deleteUser(userId, adminId) {
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to delete contracts_Users entry:', err);
|
console.error('Failed to delete contracts_Users entry:', err);
|
||||||
const errorMessage = 'Failed to delete contracts_Users entry:' + err?.message;
|
const errorMessage = 'Failed to delete contracts_Users entry:' + err?.message;
|
||||||
sendmailtoSupport(userDetails, errorMessage);
|
|
||||||
return { code: 400, message: errorMessage };
|
return { code: 400, message: errorMessage };
|
||||||
}
|
}
|
||||||
return { code: 200, message: 'User and all associated data deleted successfully.' };
|
return { code: 200, message: 'User and all associated data deleted successfully.' };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('User deletion process failed:', error);
|
console.error('User deletion process failed:', error);
|
||||||
const errorMessage = `User deletion failed: ${error.message || error}`;
|
const errorMessage = `User deletion failed: ${error.message || error}`;
|
||||||
sendmailtoSupport(userDetails, errorMessage);
|
|
||||||
return { code: 400, message: errorMessage };
|
return { code: 400, message: errorMessage };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -272,8 +256,6 @@ export const deleteUserPost = async (req, res) => {
|
|||||||
const user = await userQuery.first({ useMasterKey: true });
|
const user = await userQuery.first({ useMasterKey: true });
|
||||||
if (!user) {
|
if (!user) {
|
||||||
const errorMessage = 'User not found.';
|
const errorMessage = 'User not found.';
|
||||||
// sendmailtoSupport(userDetails, errorMessage);
|
|
||||||
// return res.status(404).send(errorMessage);
|
|
||||||
return res.send(errorMessage);
|
return res.send(errorMessage);
|
||||||
}
|
}
|
||||||
const extUserQuery = new Parse.Query('contracts_Users');
|
const extUserQuery = new Parse.Query('contracts_Users');
|
||||||
@@ -321,8 +303,6 @@ export const deleteUserPost = async (req, res) => {
|
|||||||
await extUser.save(null, { useMasterKey: true });
|
await extUser.save(null, { useMasterKey: true });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log('err while validating password: ', err?.response?.data || err);
|
console.log('err while validating password: ', err?.response?.data || err);
|
||||||
// sendmailtoSupport(userDetails, errorMessage);
|
|
||||||
// return res.status(401).send(errorMessage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await deleteUser(userId);
|
const response = await deleteUser(userId);
|
||||||
@@ -332,7 +312,6 @@ export const deleteUserPost = async (req, res) => {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Account deletion error:', error);
|
console.error('Account deletion error:', error);
|
||||||
const errorMessage = error?.message || 'An error occurred while deleting your account.';
|
const errorMessage = error?.message || 'An error occurred while deleting your account.';
|
||||||
sendmailtoSupport(userDetails, errorMessage);
|
|
||||||
return res.status(500).send(errorMessage);
|
return res.status(500).send(errorMessage);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -371,7 +350,6 @@ export const deleteUserByAdmin = async (req, res) => {
|
|||||||
const user = await userQuery.first({ useMasterKey: true });
|
const user = await userQuery.first({ useMasterKey: true });
|
||||||
if (!user) {
|
if (!user) {
|
||||||
const errorMessage = 'User not found.';
|
const errorMessage = 'User not found.';
|
||||||
sendmailtoSupport(userDetails, errorMessage);
|
|
||||||
return res.status(400).json({ message: errorMessage });
|
return res.status(400).json({ message: errorMessage });
|
||||||
}
|
}
|
||||||
const response = await deleteUser(userId, adminId);
|
const response = await deleteUser(userId, adminId);
|
||||||
@@ -385,7 +363,6 @@ export const deleteUserByAdmin = async (req, res) => {
|
|||||||
error?.message ||
|
error?.message ||
|
||||||
'An error occurred while deleting your account.';
|
'An error occurred while deleting your account.';
|
||||||
console.error(`Account deletion error:`, errorMessage);
|
console.error(`Account deletion error:`, errorMessage);
|
||||||
sendmailtoSupport(userDetails, errorMessage);
|
|
||||||
return res.status(code).json({ message: errorMessage });
|
return res.status(code).json({ message: errorMessage });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,83 +0,0 @@
|
|||||||
import { appName, smtpenable } from '../../Utils.js';
|
|
||||||
|
|
||||||
export default async function sendmailtoSupport(userDetails, errorMessage) {
|
|
||||||
const mailsender = smtpenable ? process.env.SMTP_USER_EMAIL : process.env.MAILGUN_SENDER;
|
|
||||||
// Render a simple HTML form. In production, consider using a templating engine.
|
|
||||||
try {
|
|
||||||
await Parse.Cloud.sendEmail({
|
|
||||||
sender: appName + ' <' + mailsender + '>',
|
|
||||||
recipient: 'support@opensignlabs.com',
|
|
||||||
subject: `Error while deleting account – ${appName}`,
|
|
||||||
text: `Error while deleting account – ${appName}`,
|
|
||||||
html: `<html>
|
|
||||||
<head>
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
font-family: Arial, sans-serif;
|
|
||||||
background-color: #f8f9fa;
|
|
||||||
margin: 0;
|
|
||||||
padding: 40px;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
|
||||||
max-width: 600px;
|
|
||||||
margin: auto;
|
|
||||||
background: #ffffff;
|
|
||||||
border: 1px solid #dee2e6;
|
|
||||||
border-radius: 8px;
|
|
||||||
box-shadow: 0 4px 8px rgba(0,0,0,0.05);
|
|
||||||
padding: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
color: #dc3545;
|
|
||||||
font-size: 24px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-size: 20px;
|
|
||||||
color: #495057;
|
|
||||||
margin-top: 30px;
|
|
||||||
border-bottom: 1px solid #dee2e6;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.details p {
|
|
||||||
margin: 10px 0;
|
|
||||||
line-height: 1.6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.label {
|
|
||||||
font-weight: bold;
|
|
||||||
color: #212529;
|
|
||||||
}
|
|
||||||
|
|
||||||
.value {
|
|
||||||
color: #495057;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="container">
|
|
||||||
<h1>Error: ${errorMessage}</h1>
|
|
||||||
|
|
||||||
<h2>User Details</h2>
|
|
||||||
<div class="details">
|
|
||||||
<p><span class="label">UserRole:</span> <span class="value">${userDetails?.UserRole}</span></p>
|
|
||||||
<p><span class="label">Name:</span> <span class="value">${userDetails?.Name}</span></p>
|
|
||||||
<p><span class="label">Email:</span> <span class="value">${userDetails?.Email}</span></p>
|
|
||||||
<p><span class="label">UserId:</span> <span class="value">${userDetails?.UserId}</span></p>
|
|
||||||
<p><span class="label">ExtUserId:</span> <span class="value">${userDetails?.objectId}</span></p>
|
|
||||||
<p><span class="label">TenantId:</span> <span class="value">${userDetails?.TenantId}</span></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>`,
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
console.log('err while sending mail to support', err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Generated
+811
-811
File diff suppressed because it is too large
Load Diff
@@ -18,8 +18,8 @@
|
|||||||
"watch": "nodemon index.js"
|
"watch": "nodemon index.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aws-sdk/client-s3": "^3.886.0",
|
"@aws-sdk/client-s3": "^3.888.0",
|
||||||
"@aws-sdk/s3-request-presigner": "^3.886.0",
|
"@aws-sdk/s3-request-presigner": "^3.888.0",
|
||||||
"@parse/fs-files-adapter": "^3.0.0",
|
"@parse/fs-files-adapter": "^3.0.0",
|
||||||
"@parse/s3-files-adapter": "^4.2.0",
|
"@parse/s3-files-adapter": "^4.2.0",
|
||||||
"@pdf-lib/fontkit": "^1.1.1",
|
"@pdf-lib/fontkit": "^1.1.1",
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
"@signpdf/signer-p12": "^3.2.4",
|
"@signpdf/signer-p12": "^3.2.4",
|
||||||
"@signpdf/signpdf": "^3.2.5",
|
"@signpdf/signpdf": "^3.2.5",
|
||||||
"aws-sdk": "^2.1692.0",
|
"aws-sdk": "^2.1692.0",
|
||||||
"axios": "^1.11.0",
|
"axios": "^1.12.2",
|
||||||
"coherentpdf": "^2.5.5",
|
"coherentpdf": "^2.5.5",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"date-fns-tz": "^3.2.0",
|
"date-fns-tz": "^3.2.0",
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
"form-data": "^4.0.4",
|
"form-data": "^4.0.4",
|
||||||
"generate-api-key": "^1.0.2",
|
"generate-api-key": "^1.0.2",
|
||||||
"googleapis": "^159.0.0",
|
"googleapis": "^159.0.0",
|
||||||
"libreoffice-convert": "^1.6.1",
|
"libreoffice-convert": "^1.7.0",
|
||||||
"mailgun.js": "^12.0.3",
|
"mailgun.js": "^12.0.3",
|
||||||
"mongodb": "^6.19.0",
|
"mongodb": "^6.19.0",
|
||||||
"multer": "^2.0.2",
|
"multer": "^2.0.2",
|
||||||
@@ -49,9 +49,9 @@
|
|||||||
"parse-server": "^8.2.4",
|
"parse-server": "^8.2.4",
|
||||||
"parse-server-api-mail-adapter": "^4.1.0",
|
"parse-server-api-mail-adapter": "^4.1.0",
|
||||||
"pdf-lib": "^1.17.1",
|
"pdf-lib": "^1.17.1",
|
||||||
"posthog-node": "^5.8.3",
|
"posthog-node": "^5.8.4",
|
||||||
"qrcode": "^1.5.4",
|
"qrcode": "^1.5.4",
|
||||||
"rate-limiter-flexible": "^7.3.0",
|
"rate-limiter-flexible": "^7.3.1",
|
||||||
"sharp": "^0.34.3",
|
"sharp": "^0.34.3",
|
||||||
"speakeasy": "^2.0.0",
|
"speakeasy": "^2.0.0",
|
||||||
"ws": "^8.18.3"
|
"ws": "^8.18.3"
|
||||||
@@ -61,7 +61,7 @@
|
|||||||
"@babel/eslint-parser": "^7.28.4",
|
"@babel/eslint-parser": "^7.28.4",
|
||||||
"eslint": "^9.35.0",
|
"eslint": "^9.35.0",
|
||||||
"jasmine": "^5.10.0",
|
"jasmine": "^5.10.0",
|
||||||
"mongodb-runner": "^5.9.2",
|
"mongodb-runner": "^5.9.3",
|
||||||
"nodemon": "^3.1.10",
|
"nodemon": "^3.1.10",
|
||||||
"nyc": "^17.1.0",
|
"nyc": "^17.1.0",
|
||||||
"prettier": "^3.6.2"
|
"prettier": "^3.6.2"
|
||||||
|
|||||||
Reference in New Issue
Block a user