mirror of
https://github.com/OpenSignLabs/OpenSign.git
synced 2026-09-05 09:17:39 +02:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d4c0051cd9 |
@@ -1,25 +0,0 @@
|
|||||||
# Use an official Node runtime as the base image
|
|
||||||
FROM node:18
|
|
||||||
|
|
||||||
# Set the working directory inside the container
|
|
||||||
WORKDIR /usr/src/app
|
|
||||||
|
|
||||||
# Copy package.json and package-lock.json first to leverage Docker cache
|
|
||||||
COPY ./package*.json ./
|
|
||||||
|
|
||||||
# Install application dependencies
|
|
||||||
RUN npm install
|
|
||||||
|
|
||||||
# Copy the current directory contents into the container
|
|
||||||
COPY ./ .
|
|
||||||
COPY ./.husky .
|
|
||||||
|
|
||||||
# Make port 3000 available to the world outside this container
|
|
||||||
EXPOSE 3000
|
|
||||||
|
|
||||||
# Define environment variables if needed
|
|
||||||
# ENV NODE_ENV production
|
|
||||||
|
|
||||||
# Run the application
|
|
||||||
ENTRYPOINT npm run start
|
|
||||||
|
|
||||||
@@ -13,6 +13,10 @@ RUN npm install
|
|||||||
# Copy the current directory contents into the container
|
# Copy the current directory contents into the container
|
||||||
COPY apps/OpenSign/ .
|
COPY apps/OpenSign/ .
|
||||||
COPY apps/OpenSign/.husky .
|
COPY apps/OpenSign/.husky .
|
||||||
|
COPY apps/OpenSign/entrypoint.sh .
|
||||||
|
|
||||||
|
# make the entrypoint.sh file executable
|
||||||
|
RUN chmod +x entrypoint.sh
|
||||||
|
|
||||||
# Define environment variables if needed
|
# Define environment variables if needed
|
||||||
ENV NODE_ENV=production
|
ENV NODE_ENV=production
|
||||||
@@ -20,8 +24,13 @@ ENV GENERATE_SOURCEMAP=false
|
|||||||
# build
|
# build
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
|
# Inject env.js loader into index.html
|
||||||
|
RUN sed -i '/<head>/a\<script src="/env.js"></script>' build/index.html
|
||||||
|
|
||||||
# Make port 3000 available to the world outside this container
|
# Make port 3000 available to the world outside this container
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
|
|
||||||
|
ENTRYPOINT ["./entrypoint.sh"]
|
||||||
|
|
||||||
# Run the application
|
# Run the application
|
||||||
CMD ["npm", "start"]
|
CMD ["npm", "start"]
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
ENV_FILE=./build/env.js
|
||||||
|
DOTENV_FILE=./.env.prod # ✅ use .env.prod
|
||||||
|
|
||||||
|
echo "Generating runtime env file at $ENV_FILE..."
|
||||||
|
|
||||||
|
echo "window.RUNTIME_ENV = {" > $ENV_FILE
|
||||||
|
|
||||||
|
# List of keys to include
|
||||||
|
RUNTIME_KEYS="REACT_APP_SERVERURL"
|
||||||
|
|
||||||
|
for key in $RUNTIME_KEYS; do
|
||||||
|
# First check docker env (-e), fallback to .env file
|
||||||
|
value=$(printenv "$key")
|
||||||
|
|
||||||
|
if [ -z "$value" ] && [ -f "$DOTENV_FILE" ]; then
|
||||||
|
# fallback: read from .env
|
||||||
|
value=$(grep "^$key=" "$DOTENV_FILE" | cut -d '=' -f2- | tr -d '\r\n' | sed 's/"/\\"/g')
|
||||||
|
else
|
||||||
|
value=$(echo "$value" | sed 's/"/\\"/g')
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo " $key: \"$value\"," >> $ENV_FILE
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "};" >> $ENV_FILE
|
||||||
|
|
||||||
|
exec "$@"
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"header-news": "Neue Funktion: Benutzer des Teams-Plans können jetzt ihre eigenen AWS S3-Buckets für die Dateispeicherung integrieren",
|
"header-news": "Neue Funktion: Benutzer des Teams-Plans können jetzt ihre eigenen AWS S3-Buckets für die Dateispeicherung integrieren",
|
||||||
"header-news-btn": "Jetzt einrichten",
|
"header-news-btn": "Jetzt einrichten",
|
||||||
|
"sandbox-news": "Dies ist eine Sandbox-Umgebung. Bitte nicht für produktive Zwecke verwenden.",
|
||||||
"create-account": "Konto erstellen",
|
"create-account": "Konto erstellen",
|
||||||
"login": "Anmelden",
|
"login": "Anmelden",
|
||||||
"language": "Sprache",
|
"language": "Sprache",
|
||||||
@@ -675,7 +676,7 @@
|
|||||||
"public-template-mssg-1": "Um OpenSign in Ihr React- oder Next.js-Projekt zu integrieren, führen Sie einfach den folgenden Befehl aus:",
|
"public-template-mssg-1": "Um OpenSign in Ihr React- oder Next.js-Projekt zu integrieren, führen Sie einfach den folgenden Befehl aus:",
|
||||||
"public-template-mssg-2": "Stellen Sie sicher, dass npm oder yarn in Ihrem Projekt eingerichtet ist. Wenn Sie Yarn verwenden, können Sie npm install durch yarn add @opensign/react ersetzen.",
|
"public-template-mssg-2": "Stellen Sie sicher, dass npm oder yarn in Ihrem Projekt eingerichtet ist. Wenn Sie Yarn verwenden, können Sie npm install durch yarn add @opensign/react ersetzen.",
|
||||||
"public-template-mssg-3": "Benötigen Sie weitere Details oder Beispiele?",
|
"public-template-mssg-3": "Benötigen Sie weitere Details oder Beispiele?",
|
||||||
"public-template-mssg-4": "Besuchen Sie die",
|
"public-template-mssg-4": "Besuchen Sie die ",
|
||||||
"public-template-mssg-5": " npm für die neuesten Updates, detaillierte Dokumentationen und Versionshistorie.",
|
"public-template-mssg-5": " npm für die neuesten Updates, detaillierte Dokumentationen und Versionshistorie.",
|
||||||
"public-template-mssg-6": "Bevor Sie diesen Code-Schnipsel verwenden können, müssen Sie diese Vorlage öffentlich machen.",
|
"public-template-mssg-6": "Bevor Sie diesen Code-Schnipsel verwenden können, müssen Sie diese Vorlage öffentlich machen.",
|
||||||
"public-template-mssg-7": "Bevor Sie einen öffentlichen Link generieren können, müssen Sie diese Vorlage öffentlich machen.",
|
"public-template-mssg-7": "Bevor Sie einen öffentlichen Link generieren können, müssen Sie diese Vorlage öffentlich machen.",
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"header-news": "New feature: Protect your account with Two-Factor Authentication (2FA) and enjoy the future of login with Passkeys — no passwords needed.",
|
"header-news": "New feature: Protect your account with Two-Factor Authentication (2FA) and enjoy the future of login with Passkeys — no passwords needed.",
|
||||||
"header-news-btn": "Setup now",
|
"header-news-btn": "Setup now",
|
||||||
|
"sandbox-news": "This is a sandbox environment. Please do not use it for production purposes.",
|
||||||
"create-account": "Create account",
|
"create-account": "Create account",
|
||||||
"login": "Login",
|
"login": "Login",
|
||||||
"language": "Language",
|
"language": "Language",
|
||||||
@@ -675,7 +676,7 @@
|
|||||||
"public-template-mssg-1": "To integrate OpenSign into your React or Next.js project, simply run the following command:",
|
"public-template-mssg-1": "To integrate OpenSign into your React or Next.js project, simply run the following command:",
|
||||||
"public-template-mssg-2": "Ensure you have npm or yarn set up in your project. If you're using Yarn, you can replace npm install with yarn add @opensign/react.",
|
"public-template-mssg-2": "Ensure you have npm or yarn set up in your project. If you're using Yarn, you can replace npm install with yarn add @opensign/react.",
|
||||||
"public-template-mssg-3": "Need more details or examples?",
|
"public-template-mssg-3": "Need more details or examples?",
|
||||||
"public-template-mssg-4": "Visit the",
|
"public-template-mssg-4": "Visit the ",
|
||||||
"public-template-mssg-5": " npm for the latest updates, detailed documentation, and version history.",
|
"public-template-mssg-5": " npm for the latest updates, detailed documentation, and version history.",
|
||||||
"public-template-mssg-6": "Before you can use this code snippet, you must make this template public.",
|
"public-template-mssg-6": "Before you can use this code snippet, you must make this template public.",
|
||||||
"public-template-mssg-7": "Before you can generate a public link you must make this template public.",
|
"public-template-mssg-7": "Before you can generate a public link you must make this template public.",
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"header-news": "Nueva característica: los usuarios del plan Teams ahora pueden integrar sus propios depósitos de AWS S3 para el almacenamiento de archivos",
|
"header-news": "Nueva característica: los usuarios del plan Teams ahora pueden integrar sus propios depósitos de AWS S3 para el almacenamiento de archivos",
|
||||||
"header-news-btn": "Configurar ahora",
|
"header-news-btn": "Configurar ahora",
|
||||||
|
"sandbox-news": "Este es un entorno sandbox. Por favor, no lo utilice con fines de producción.",
|
||||||
"create-account": "Crear cuenta",
|
"create-account": "Crear cuenta",
|
||||||
"login": "Iniciar sesión",
|
"login": "Iniciar sesión",
|
||||||
"language": "Idioma",
|
"language": "Idioma",
|
||||||
@@ -675,7 +676,7 @@
|
|||||||
"public-template-mssg-1": "Para integrar OpenSign a tu proyecto React o Next.js, simplemente ejecuta los siguientes comandos:",
|
"public-template-mssg-1": "Para integrar OpenSign a tu proyecto React o Next.js, simplemente ejecuta los siguientes comandos:",
|
||||||
"public-template-mssg-2": "Asegúrate de tener «npm» o «yarn» configurado en tu proyecto. Si estás usando «yarn», puedes reemplazar «npm install» con «yarn add @opensign/react».",
|
"public-template-mssg-2": "Asegúrate de tener «npm» o «yarn» configurado en tu proyecto. Si estás usando «yarn», puedes reemplazar «npm install» con «yarn add @opensign/react».",
|
||||||
"public-template-mssg-3": "¿Necesitas más detalles o ejemplos?",
|
"public-template-mssg-3": "¿Necesitas más detalles o ejemplos?",
|
||||||
"public-template-mssg-4": "Visita la",
|
"public-template-mssg-4": "Visita la ",
|
||||||
"public-template-mssg-5": " «npm» para las últimas actualizaciones, documentación detallada e historial de versiones.",
|
"public-template-mssg-5": " «npm» para las últimas actualizaciones, documentación detallada e historial de versiones.",
|
||||||
"public-template-mssg-6": "Antes de que puedas usar este fragmento de código, debes convertir esta plantilla en pública.",
|
"public-template-mssg-6": "Antes de que puedas usar este fragmento de código, debes convertir esta plantilla en pública.",
|
||||||
"public-template-mssg-7": "Antes de poder generar un enlace público, debes hacer que esta plantilla sea pública.",
|
"public-template-mssg-7": "Antes de poder generar un enlace público, debes hacer que esta plantilla sea pública.",
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"header-news": "Nouvelle fonctionnalité : les utilisateurs du forfait Teams peuvent désormais intégrer leurs propres compartiments AWS S3 pour le stockage de fichiers",
|
"header-news": "Nouvelle fonctionnalité : les utilisateurs du forfait Teams peuvent désormais intégrer leurs propres compartiments AWS S3 pour le stockage de fichiers",
|
||||||
"header-news-btn": "Configurer maintenant",
|
"header-news-btn": "Configurer maintenant",
|
||||||
|
"sandbox-news": "Ceci est un environnement sandbox. Veuillez ne pas l'utiliser à des fins de production.",
|
||||||
"create-account": "Créer un compte",
|
"create-account": "Créer un compte",
|
||||||
"login": "Se Connecter",
|
"login": "Se Connecter",
|
||||||
"language": "Langue",
|
"language": "Langue",
|
||||||
@@ -675,7 +676,7 @@
|
|||||||
"public-template-mssg-1": "Pour intégrer OpenSign dans votre projet React ou Next.js, exécutez simplement la commande suivante :",
|
"public-template-mssg-1": "Pour intégrer OpenSign dans votre projet React ou Next.js, exécutez simplement la commande suivante :",
|
||||||
"public-template-mssg-2": "Assurez-vous que npm ou Yarn est configuré dans votre projet. Si vous utilisez Yarn, vous pouvez remplacer npm install par Yarn Add @opensign/react.",
|
"public-template-mssg-2": "Assurez-vous que npm ou Yarn est configuré dans votre projet. Si vous utilisez Yarn, vous pouvez remplacer npm install par Yarn Add @opensign/react.",
|
||||||
"public-template-mssg-3": "Besoin de plus de détails ou d'exemples ?",
|
"public-template-mssg-3": "Besoin de plus de détails ou d'exemples ?",
|
||||||
"public-template-mssg-4": "Visitez le",
|
"public-template-mssg-4": "Visitez le ",
|
||||||
"public-template-mssg-5": "npm pour les dernières mises à jour, une documentation détaillée et l'historique des versions.",
|
"public-template-mssg-5": "npm pour les dernières mises à jour, une documentation détaillée et l'historique des versions.",
|
||||||
"public-template-mssg-6": "Avant de pouvoir utiliser cet extrait de code, vous devez rendre ce modèle public.",
|
"public-template-mssg-6": "Avant de pouvoir utiliser cet extrait de code, vous devez rendre ce modèle public.",
|
||||||
"public-template-mssg-7": "Avant de pouvoir générer un lien public, vous devez rendre ce modèle public.",
|
"public-template-mssg-7": "Avant de pouvoir générer un lien public, vous devez rendre ce modèle public.",
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"header-news": "Nuova funzionalità: Gli utenti del piano Teams possono ora integrare i propri bucket AWS S3 per l'archiviazione dei file",
|
"header-news": "Nuova funzionalità: Gli utenti del piano Teams possono ora integrare i propri bucket AWS S3 per l'archiviazione dei file",
|
||||||
"header-news-btn": "Configura Ora",
|
"header-news-btn": "Configura Ora",
|
||||||
|
"sandbox-news": "Questo è un ambiente sandbox. Si prega di non utilizzarlo per scopi di produzione.",
|
||||||
"create-account": "Crea Account",
|
"create-account": "Crea Account",
|
||||||
"login": "Accedi",
|
"login": "Accedi",
|
||||||
"language": "Lingua",
|
"language": "Lingua",
|
||||||
@@ -675,7 +676,7 @@
|
|||||||
"public-template-mssg-1": "Per integrare OpenSign nel tuo progetto React o Next.js, esegui semplicemente il seguente comando:",
|
"public-template-mssg-1": "Per integrare OpenSign nel tuo progetto React o Next.js, esegui semplicemente il seguente comando:",
|
||||||
"public-template-mssg-2": "Assicurati di avere npm o yarn configurato nel tuo progetto. Se usi Yarn, puoi sostituire npm install con yarn add @opensign/react.",
|
"public-template-mssg-2": "Assicurati di avere npm o yarn configurato nel tuo progetto. Se usi Yarn, puoi sostituire npm install con yarn add @opensign/react.",
|
||||||
"public-template-mssg-3": "Hai bisogno di maggiori dettagli o esempi?",
|
"public-template-mssg-3": "Hai bisogno di maggiori dettagli o esempi?",
|
||||||
"public-template-mssg-4": "Visita il",
|
"public-template-mssg-4": "Visita il ",
|
||||||
"public-template-mssg-5": " npm per gli aggiornamenti più recenti, documentazione dettagliata e cronologia delle versioni.",
|
"public-template-mssg-5": " npm per gli aggiornamenti più recenti, documentazione dettagliata e cronologia delle versioni.",
|
||||||
"public-template-mssg-6": "Prima di poter utilizzare questo frammento di codice, devi rendere questo modello pubblico.",
|
"public-template-mssg-6": "Prima di poter utilizzare questo frammento di codice, devi rendere questo modello pubblico.",
|
||||||
"public-template-mssg-7": "Prima di poter generare un link pubblico, devi rendere questo modello pubblico.",
|
"public-template-mssg-7": "Prima di poter generare un link pubblico, devi rendere questo modello pubblico.",
|
||||||
|
|||||||
@@ -106,10 +106,10 @@ function App() {
|
|||||||
element={<LazyPage Page={GuestLogin} />}
|
element={<LazyPage Page={GuestLogin} />}
|
||||||
/>
|
/>
|
||||||
<Route path="/debugpdf" element={<LazyPage Page={DebugPdf} />} />
|
<Route path="/debugpdf" element={<LazyPage Page={DebugPdf} />} />
|
||||||
<Route
|
<Route
|
||||||
path="/forgetpassword"
|
path="/forgetpassword"
|
||||||
element={<LazyPage Page={ForgetPassword} />}
|
element={<LazyPage Page={ForgetPassword} />}
|
||||||
/>
|
/>
|
||||||
<Route
|
<Route
|
||||||
element={
|
element={
|
||||||
<ValidateSession>
|
<ValidateSession>
|
||||||
@@ -165,7 +165,7 @@ function App() {
|
|||||||
path="/recipientSignPdf/:docId"
|
path="/recipientSignPdf/:docId"
|
||||||
element={<PdfRequestFiles />}
|
element={<PdfRequestFiles />}
|
||||||
/>
|
/>
|
||||||
<Route path="/users" element={<UserList />} />
|
<Route path="/users" element={<UserList />} />
|
||||||
<Route
|
<Route
|
||||||
path="/preferences"
|
path="/preferences"
|
||||||
element={<LazyPage Page={Preferences} />}
|
element={<LazyPage Page={Preferences} />}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ function DropdownWidgetOption(props) {
|
|||||||
|
|
||||||
const resetState = () => {
|
const resetState = () => {
|
||||||
setDropdownOptionList(["option-1", "option-2"]);
|
setDropdownOptionList(["option-1", "option-2"]);
|
||||||
setDropdownName( props.currWidgetsDetails?.options?.name || props.type);
|
setDropdownName(props.currWidgetsDetails?.options?.name || props.type);
|
||||||
setIsReadOnly(false);
|
setIsReadOnly(false);
|
||||||
setIsHideLabel(false);
|
setIsHideLabel(false);
|
||||||
setMinCount(0);
|
setMinCount(0);
|
||||||
@@ -115,7 +115,7 @@ function DropdownWidgetOption(props) {
|
|||||||
defaultData,
|
defaultData,
|
||||||
isHideLabel
|
isHideLabel
|
||||||
);
|
);
|
||||||
resetState()
|
resetState();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, {
|
import {
|
||||||
useState,
|
useState,
|
||||||
useRef,
|
useRef,
|
||||||
} from "react";
|
} from "react";
|
||||||
|
|||||||
@@ -168,34 +168,34 @@ function PlaceholderType(props) {
|
|||||||
<div style={{ zIndex: props.isSignYourself && "99" }}>
|
<div style={{ zIndex: props.isSignYourself && "99" }}>
|
||||||
{props.pos.options?.values?.map((data, ind) => {
|
{props.pos.options?.values?.map((data, ind) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div key={ind} className="select-none-cls pointer-events-none">
|
||||||
key={ind}
|
<label
|
||||||
className="select-none-cls flex items-center text-center gap-0.5 pointer-events-none"
|
htmlFor={`checkbox-${props.pos.key + ind}`}
|
||||||
>
|
style={{ fontSize: fontSize, color: fontColor }}
|
||||||
<input
|
className={`mb-0 flex items-center gap-1 ${
|
||||||
id={`checkbox-${props.pos.key + ind}`}
|
ind > 0 ? "mt-[3px]" : "mt-[0px]"
|
||||||
style={{ width: fontSize, height: fontSize }}
|
}`}
|
||||||
className={`${
|
>
|
||||||
ind === 0 ? "mt-0" : "mt-[5px]"
|
<input
|
||||||
} flex justify-center op-checkbox rounded-[1px] `}
|
id={`checkbox-${props.pos.key + ind}`}
|
||||||
disabled={
|
style={{
|
||||||
props.isNeedSign &&
|
width: fontSize,
|
||||||
(props.pos.options?.isReadOnly ||
|
height: fontSize
|
||||||
props.data?.signerObjId !== props.signerObjId)
|
}}
|
||||||
}
|
className="op-checkbox rounded-[1px]"
|
||||||
type="checkbox"
|
disabled={
|
||||||
readOnly
|
props.isNeedSign &&
|
||||||
checked={!!selectCheckbox(ind, selectedCheckbox)}
|
(props.pos.options?.isReadOnly ||
|
||||||
/>
|
props.data?.signerObjId !== props.signerObjId)
|
||||||
{!props.pos.options?.isHideLabel && (
|
}
|
||||||
<label
|
type="checkbox"
|
||||||
htmlFor={`checkbox-${props.pos.key + ind}`}
|
readOnly
|
||||||
style={{ fontSize: fontSize, color: fontColor }}
|
checked={!!selectCheckbox(ind, selectedCheckbox)}
|
||||||
className="text-xs mb-0 text-center"
|
/>
|
||||||
>
|
{!props.pos.options?.isHideLabel && (
|
||||||
{data}
|
<span className="leading-none">{data}</span>
|
||||||
</label>
|
)}
|
||||||
)}
|
</label>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
@@ -243,7 +243,6 @@ function PlaceholderType(props) {
|
|||||||
<i className="fa-light fa-circle-chevron-down mr-1 "></i>
|
<i className="fa-light fa-circle-chevron-down mr-1 "></i>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
case "initials":
|
case "initials":
|
||||||
return props.pos.SignUrl ? (
|
return props.pos.SignUrl ? (
|
||||||
<img
|
<img
|
||||||
@@ -444,36 +443,40 @@ function PlaceholderType(props) {
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={ind}
|
key={ind}
|
||||||
className="select-none-cls flex items-center text-center gap-0.5 pointer-events-none"
|
className="select-none-cls pointer-events-none"
|
||||||
>
|
>
|
||||||
<input
|
<label
|
||||||
readOnly
|
htmlFor={`radio-${props.pos.key + ind}`}
|
||||||
id={`radio-${props.pos.key + ind}`}
|
|
||||||
style={{
|
style={{
|
||||||
width: fontSize,
|
fontSize: fontSize,
|
||||||
height: fontSize,
|
color: fontColor,
|
||||||
marginTop: ind > 0 ? "10px" : "0px"
|
marginTop: ind > 0 ? "5px" : "0px"
|
||||||
}}
|
}}
|
||||||
className={`op-radio rounded-full border- border-black appearance-none bg-white inline-block align-middle relative ${
|
className="text-xs mb-0 flex items-center gap-1 "
|
||||||
handleRadioCheck(data) ? "checked-radio" : ""
|
>
|
||||||
}`}
|
<input
|
||||||
type="radio"
|
readOnly
|
||||||
disabled={
|
id={`radio-${props.pos.key + ind}`}
|
||||||
props.isNeedSign &&
|
style={{
|
||||||
(props.pos.options?.isReadOnly ||
|
width: fontSize,
|
||||||
props.data?.signerObjId !== props.signerObjId)
|
height: fontSize,
|
||||||
}
|
lineHeight: 2
|
||||||
checked={handleRadioCheck(data)}
|
}}
|
||||||
/>
|
className={`op-radio rounded-full border- border-black appearance-none bg-white inline-block align-middle relative ${
|
||||||
{!props.pos.options?.isHideLabel && (
|
handleRadioCheck(data) ? "checked-radio" : ""
|
||||||
<label
|
}`}
|
||||||
htmlFor={`radio-${props.pos.key + ind}`}
|
type="radio"
|
||||||
style={{ fontSize: fontSize, color: fontColor }}
|
disabled={
|
||||||
className="text-xs mb-0"
|
props.isNeedSign &&
|
||||||
>
|
(props.pos.options?.isReadOnly ||
|
||||||
{data}
|
props.data?.signerObjId !== props.signerObjId)
|
||||||
</label>
|
}
|
||||||
)}
|
checked={handleRadioCheck(data)}
|
||||||
|
/>
|
||||||
|
{!props.pos.options?.isHideLabel && (
|
||||||
|
<span className="leading-none">{data}</span>
|
||||||
|
)}
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -231,7 +231,9 @@ function WidgetsValueModal(props) {
|
|||||||
setXyPosition,
|
setXyPosition,
|
||||||
uniqueId,
|
uniqueId,
|
||||||
false,
|
false,
|
||||||
data?.format
|
data?.format,
|
||||||
|
currWidgetsDetails?.options?.fontSize || 12,
|
||||||
|
currWidgetsDetails?.options?.fontColor || "black"
|
||||||
);
|
);
|
||||||
setSelectDate({ date: date, format: data?.format });
|
setSelectDate({ date: date, format: data?.format });
|
||||||
};
|
};
|
||||||
@@ -1327,47 +1329,42 @@ function WidgetsValueModal(props) {
|
|||||||
<div className="border-[1px] border-gray-300 rounded-[2px] p-1 px-3">
|
<div className="border-[1px] border-gray-300 rounded-[2px] p-1 px-3">
|
||||||
{currWidgetsDetails?.options?.values?.map((data, ind) => {
|
{currWidgetsDetails?.options?.values?.map((data, ind) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div key={ind} className=" select-none-cls">
|
||||||
key={ind}
|
<label
|
||||||
className=" select-none-cls flex items-center text-center gap-0.5"
|
htmlFor={`checkbox-${currWidgetsDetails?.key + ind}`}
|
||||||
>
|
className="text-xs flex items-center gap-1"
|
||||||
<input
|
>
|
||||||
id={`checkbox-${currWidgetsDetails?.key + ind}`}
|
<input
|
||||||
className={`${
|
id={`checkbox-${currWidgetsDetails?.key + ind}`}
|
||||||
ind === 0 ? "mt-0" : "mt-[5px]"
|
className={`${
|
||||||
} op-checkbox op-checkbox-sm rounded-[1px] `}
|
ind === 0 ? "mt-0" : "mt-[5px]"
|
||||||
type="checkbox"
|
} op-checkbox op-checkbox-xs rounded-[1px] `}
|
||||||
checked={!!selectCheckbox(ind, selectedCheckbox)}
|
type="checkbox"
|
||||||
onChange={(e) => {
|
checked={!!selectCheckbox(ind, selectedCheckbox)}
|
||||||
if (e.target.checked) {
|
onChange={(e) => {
|
||||||
const maxRequired =
|
if (e.target.checked) {
|
||||||
currWidgetsDetails?.options?.validation
|
const maxRequired =
|
||||||
?.maxRequiredCount;
|
currWidgetsDetails?.options?.validation
|
||||||
const maxCountInt =
|
?.maxRequiredCount;
|
||||||
maxRequired && parseInt(maxRequired);
|
const maxCountInt =
|
||||||
if (maxCountInt > 0) {
|
maxRequired && parseInt(maxRequired);
|
||||||
if (
|
if (maxCountInt > 0) {
|
||||||
selectedCheckbox &&
|
if (
|
||||||
selectedCheckbox?.length <= maxCountInt - 1
|
selectedCheckbox &&
|
||||||
) {
|
selectedCheckbox?.length <= maxCountInt - 1
|
||||||
|
) {
|
||||||
|
handleCheckboxValue(e.target.checked, ind);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
handleCheckboxValue(e.target.checked, ind);
|
handleCheckboxValue(e.target.checked, ind);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
handleCheckboxValue(e.target.checked, ind);
|
handleCheckboxValue(e.target.checked, ind);
|
||||||
}
|
}
|
||||||
} else {
|
}}
|
||||||
handleCheckboxValue(e.target.checked, ind);
|
/>
|
||||||
}
|
{data}
|
||||||
}}
|
</label>
|
||||||
/>
|
|
||||||
{!currWidgetsDetails?.options?.isHideLabel && (
|
|
||||||
<label
|
|
||||||
htmlFor={`checkbox-${currWidgetsDetails?.key + ind}`}
|
|
||||||
className="text-xs mb-0 text-center"
|
|
||||||
>
|
|
||||||
{data}
|
|
||||||
</label>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
@@ -1515,32 +1512,23 @@ function WidgetsValueModal(props) {
|
|||||||
<div className="border-[1px] border-gray-300 rounded-[2px] p-1 px-3">
|
<div className="border-[1px] border-gray-300 rounded-[2px] p-1 px-3">
|
||||||
{currWidgetsDetails?.options?.values.map((data, ind) => {
|
{currWidgetsDetails?.options?.values.map((data, ind) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div key={ind} className="select-none-cls">
|
||||||
key={ind}
|
<label
|
||||||
className="select-none-cls flex items-center text-center gap-0.5"
|
htmlFor={`radio-${currWidgetsDetails?.key + ind}`}
|
||||||
>
|
className="cursor-pointer flex items-center text-sm gap-1"
|
||||||
<input
|
>
|
||||||
id={`radio-${currWidgetsDetails?.key + ind}`}
|
<input
|
||||||
style={{
|
id={`radio-${currWidgetsDetails?.key + ind}`}
|
||||||
marginTop: ind > 0 ? "10px" : "0px"
|
className={`op-radio op-radio-xs`}
|
||||||
}}
|
type="radio"
|
||||||
className={`flex justify-center op-radio`}
|
value={data}
|
||||||
type="radio"
|
checked={handleRadioCheck(data)}
|
||||||
value={data}
|
onChange={(e) => {
|
||||||
checked={handleRadioCheck(data)}
|
handleCheckRadio(e.target.value);
|
||||||
onChange={(e) => {
|
}}
|
||||||
handleCheckRadio(e.target.value);
|
/>
|
||||||
}}
|
{data}
|
||||||
/>
|
</label>
|
||||||
{!currWidgetsDetails?.options?.isHideLabel && (
|
|
||||||
<label
|
|
||||||
htmlFor={`radio-${currWidgetsDetails?.key + ind}`}
|
|
||||||
// style={{ fontSize: fontSize, color: fontColor }}
|
|
||||||
className="text-xs mb-0"
|
|
||||||
>
|
|
||||||
{data}
|
|
||||||
</label>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
@@ -1652,7 +1640,7 @@ function WidgetsValueModal(props) {
|
|||||||
const validateExpression = (regexValidation) => {
|
const validateExpression = (regexValidation) => {
|
||||||
if (widgetValue && regexValidation) {
|
if (widgetValue && regexValidation) {
|
||||||
let regexObject = regexValidation;
|
let regexObject = regexValidation;
|
||||||
if (props.pos?.options?.validation?.type === "regex") {
|
if (currWidgetsDetails?.options?.validation?.type === "regex") {
|
||||||
regexObject = RegexParser(regexValidation);
|
regexObject = RegexParser(regexValidation);
|
||||||
}
|
}
|
||||||
let isValidate = regexObject.test(widgetValue);
|
let isValidate = regexObject.test(widgetValue);
|
||||||
@@ -1675,7 +1663,8 @@ function WidgetsValueModal(props) {
|
|||||||
validateExpression(regexValidation);
|
validateExpression(regexValidation);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
regexValidation = props.pos?.options?.validation?.pattern || "";
|
regexValidation =
|
||||||
|
currWidgetsDetails?.options?.validation?.pattern || "";
|
||||||
validateExpression(regexValidation);
|
validateExpression(regexValidation);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,19 @@ import React, { useEffect, useState } from "react";
|
|||||||
import AsyncSelect from "react-select/async";
|
import AsyncSelect from "react-select/async";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
import { handleUnlinkSigner } from "../../../constant/Utils";
|
||||||
|
|
||||||
const SelectSigners = (props) => {
|
const SelectSigners = (props) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const {
|
||||||
|
signerPos,
|
||||||
|
setSignerPos,
|
||||||
|
signersData,
|
||||||
|
setSignersData,
|
||||||
|
uniqueId,
|
||||||
|
isRemove,
|
||||||
|
handleAddUser
|
||||||
|
} = props;
|
||||||
const [userList, setUserList] = useState([]);
|
const [userList, setUserList] = useState([]);
|
||||||
const [selected, setSelected] = useState();
|
const [selected, setSelected] = useState();
|
||||||
const [userData, setUserData] = useState({});
|
const [userData, setUserData] = useState({});
|
||||||
@@ -30,7 +40,7 @@ const SelectSigners = (props) => {
|
|||||||
//checking if user select no signer option from dropdown
|
//checking if user select no signer option from dropdown
|
||||||
if (item) {
|
if (item) {
|
||||||
//checking selected signer is already assign to the document or not
|
//checking selected signer is already assign to the document or not
|
||||||
const alreadyAssign = props.signersData.some(
|
const alreadyAssign = signersData.some(
|
||||||
(item2) => item2.objectId === item.value
|
(item2) => item2.objectId === item.value
|
||||||
);
|
);
|
||||||
if (alreadyAssign) {
|
if (alreadyAssign) {
|
||||||
@@ -49,7 +59,7 @@ const SelectSigners = (props) => {
|
|||||||
};
|
};
|
||||||
const handleAdd = () => {
|
const handleAdd = () => {
|
||||||
if (userData && userData.objectId) {
|
if (userData && userData.objectId) {
|
||||||
props.details(userData);
|
handleAddUser(userData);
|
||||||
if (props.closePopup) {
|
if (props.closePopup) {
|
||||||
props.closePopup();
|
props.closePopup();
|
||||||
}
|
}
|
||||||
@@ -60,7 +70,13 @@ const SelectSigners = (props) => {
|
|||||||
};
|
};
|
||||||
//function to use remove signer from assigned widgets in create template flow
|
//function to use remove signer from assigned widgets in create template flow
|
||||||
const handleRemove = () => {
|
const handleRemove = () => {
|
||||||
props.handleUnlinkSigner();
|
handleUnlinkSigner(
|
||||||
|
signerPos,
|
||||||
|
setSignerPos,
|
||||||
|
signersData,
|
||||||
|
setSignersData,
|
||||||
|
uniqueId
|
||||||
|
);
|
||||||
if (props.closePopup) {
|
if (props.closePopup) {
|
||||||
props.closePopup();
|
props.closePopup();
|
||||||
}
|
}
|
||||||
@@ -161,7 +177,7 @@ const SelectSigners = (props) => {
|
|||||||
<button className="op-btn op-btn-primary" onClick={() => handleAdd()}>
|
<button className="op-btn op-btn-primary" onClick={() => handleAdd()}>
|
||||||
{t("submit")}
|
{t("submit")}
|
||||||
</button>
|
</button>
|
||||||
{props.isExistSigner && props.handleUnlinkSigner && (
|
{props.isExistSigner && isRemove && (
|
||||||
<button
|
<button
|
||||||
className="op-btn op-btn-accent op-btn-outline"
|
className="op-btn op-btn-accent op-btn-outline"
|
||||||
onClick={() => handleRemove()}
|
onClick={() => handleRemove()}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import React from "react";
|
|
||||||
import { PDFDocument, rgb, degrees } from "pdf-lib";
|
import { PDFDocument, rgb, degrees } from "pdf-lib";
|
||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
import { appInfo } from "./appinfo";
|
import { appInfo } from "./appinfo";
|
||||||
@@ -21,7 +20,9 @@ export const isTabAndMobile = window.innerWidth < 1023;
|
|||||||
export const textInputWidget = "text input";
|
export const textInputWidget = "text input";
|
||||||
export const textWidget = "text";
|
export const textWidget = "text";
|
||||||
export const radioButtonWidget = "radio button";
|
export const radioButtonWidget = "radio button";
|
||||||
|
export function getEnv() {
|
||||||
|
return window?.RUNTIME_ENV || {};
|
||||||
|
}
|
||||||
|
|
||||||
//function for create list of year for date widget
|
//function for create list of year for date widget
|
||||||
export const range = (start, end, step) => {
|
export const range = (start, end, step) => {
|
||||||
@@ -1665,10 +1666,11 @@ export const multiSignEmbed = async (widgets, pdfDoc, signyourself, scale) => {
|
|||||||
].includes(position.type);
|
].includes(position.type);
|
||||||
if (position.type === "checkbox") {
|
if (position.type === "checkbox") {
|
||||||
let checkboxGapFromTop, isCheck;
|
let checkboxGapFromTop, isCheck;
|
||||||
let y = yPos(position);
|
let y = yPos(position) + 2;
|
||||||
const optionsFontSize = fontSize || 13;
|
//calculate checkbox size to draw on pdf
|
||||||
const checkboxSize = fontSize;
|
const checkboxSize = fontSize - 1;
|
||||||
const checkboxTextGapFromLeft = fontSize + 5 || 22;
|
//calculate gap between checkbox and options
|
||||||
|
const checkboxTextGapFromLeft = fontSize + 5;
|
||||||
if (position?.options?.values.length > 0) {
|
if (position?.options?.values.length > 0) {
|
||||||
position?.options?.values.forEach((item, ind) => {
|
position?.options?.values.forEach((item, ind) => {
|
||||||
const checkboxRandomId = "checkbox" + randomId();
|
const checkboxRandomId = "checkbox" + randomId();
|
||||||
@@ -1680,13 +1682,11 @@ export const multiSignEmbed = async (widgets, pdfDoc, signyourself, scale) => {
|
|||||||
} else if (position?.options?.defaultValue) {
|
} else if (position?.options?.defaultValue) {
|
||||||
isCheck = position?.options?.defaultValue?.includes(ind);
|
isCheck = position?.options?.defaultValue?.includes(ind);
|
||||||
}
|
}
|
||||||
|
|
||||||
const checkbox = form.createCheckBox(checkboxRandomId);
|
const checkbox = form.createCheckBox(checkboxRandomId);
|
||||||
|
|
||||||
if (ind > 0) {
|
if (ind > 0) {
|
||||||
y = y + checkboxGapFromTop;
|
y = y + checkboxGapFromTop;
|
||||||
} else {
|
} else {
|
||||||
checkboxGapFromTop = fontSize + 5 || 26;
|
checkboxGapFromTop = fontSize + 3.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!position?.options?.isHideLabel) {
|
if (!position?.options?.isHideLabel) {
|
||||||
@@ -1694,10 +1694,10 @@ export const multiSignEmbed = async (widgets, pdfDoc, signyourself, scale) => {
|
|||||||
const optionsPosition = compensateRotation(
|
const optionsPosition = compensateRotation(
|
||||||
page.getRotation().angle,
|
page.getRotation().angle,
|
||||||
xPos(position) + checkboxTextGapFromLeft,
|
xPos(position) + checkboxTextGapFromLeft,
|
||||||
y,
|
y - 3,
|
||||||
1,
|
1,
|
||||||
page.getSize(),
|
page.getSize(),
|
||||||
optionsFontSize,
|
fontSize,
|
||||||
updateColorInRgb,
|
updateColorInRgb,
|
||||||
font,
|
font,
|
||||||
page
|
page
|
||||||
@@ -1780,7 +1780,7 @@ export const multiSignEmbed = async (widgets, pdfDoc, signyourself, scale) => {
|
|||||||
: NewbreakTextIntoLines(textContent, fixedWidth);
|
: NewbreakTextIntoLines(textContent, fixedWidth);
|
||||||
// Set initial y-coordinate for the first line
|
// Set initial y-coordinate for the first line
|
||||||
let x = xPos(position);
|
let x = xPos(position);
|
||||||
let y = yPos(position);
|
let y = yPos(position) - 4;
|
||||||
// Embed each line on the page
|
// Embed each line on the page
|
||||||
for (const line of lines) {
|
for (const line of lines) {
|
||||||
const textPosition = compensateRotation(
|
const textPosition = compensateRotation(
|
||||||
@@ -1830,28 +1830,33 @@ export const multiSignEmbed = async (widgets, pdfDoc, signyourself, scale) => {
|
|||||||
} else if (position.type === radioButtonWidget) {
|
} else if (position.type === radioButtonWidget) {
|
||||||
const radioRandomId = "radio" + randomId();
|
const radioRandomId = "radio" + randomId();
|
||||||
const radioGroup = form.createRadioGroup(radioRandomId);
|
const radioGroup = form.createRadioGroup(radioRandomId);
|
||||||
let radioOptionGapFromTop;
|
//draw radio button on document and options if hide label is enable
|
||||||
const optionsFontSize = fontSize || 13;
|
let radioButtonFromTop;
|
||||||
const radioTextGapFromLeft = fontSize + 5 || 20;
|
//getting radio buttons options text font size
|
||||||
|
const optionsFontSize = fontSize;
|
||||||
|
//calculate value of gap between radio button and options
|
||||||
|
const radioTextGapFromLeft = fontSize + 6;
|
||||||
|
//getting radio button font size
|
||||||
const radioSize = fontSize;
|
const radioSize = fontSize;
|
||||||
|
//getting position of radio widget in y direction
|
||||||
let y = yPos(position);
|
let y = yPos(position);
|
||||||
|
//on the basic of option's length create radio button and message
|
||||||
if (position?.options?.values.length > 0) {
|
if (position?.options?.values.length > 0) {
|
||||||
position?.options?.values.forEach((item, ind) => {
|
position?.options?.values.forEach((item, ind) => {
|
||||||
if (ind > 0) {
|
if (ind > 0) {
|
||||||
y = y + radioOptionGapFromTop;
|
y = y + radioButtonFromTop;
|
||||||
} else {
|
} else {
|
||||||
radioOptionGapFromTop = fontSize + 10 || 25;
|
radioButtonFromTop = fontSize + 6;
|
||||||
}
|
}
|
||||||
if (!position?.options?.isHideLabel) {
|
if (!position?.options?.isHideLabel) {
|
||||||
// below line of code is used to embed label with radio button in pdf
|
// below line of code is used to embed label with radio button in pdf
|
||||||
|
|
||||||
const optionsPosition = compensateRotation(
|
const optionsPosition = compensateRotation(
|
||||||
page.getRotation().angle,
|
page.getRotation().angle,
|
||||||
xPos(position) + radioTextGapFromLeft,
|
xPos(position) + radioTextGapFromLeft,
|
||||||
y,
|
y - 2,
|
||||||
1,
|
1,
|
||||||
page.getSize(),
|
page.getSize(),
|
||||||
optionsFontSize,
|
fontSize,
|
||||||
updateColorInRgb,
|
updateColorInRgb,
|
||||||
font,
|
font,
|
||||||
page
|
page
|
||||||
@@ -1860,7 +1865,7 @@ export const multiSignEmbed = async (widgets, pdfDoc, signyourself, scale) => {
|
|||||||
page.drawText(item, optionsPosition);
|
page.drawText(item, optionsPosition);
|
||||||
}
|
}
|
||||||
let radioObj = {
|
let radioObj = {
|
||||||
x: xPos(position),
|
x: xPos(position) + 2,
|
||||||
y: y,
|
y: y,
|
||||||
width: radioSize,
|
width: radioSize,
|
||||||
height: radioSize
|
height: radioSize
|
||||||
@@ -3066,7 +3071,7 @@ export const mailTemplate = (param) => {
|
|||||||
"</td></tr><tr><td style='font-weight:bold;font-family:sans-serif;font-size:15px'>Note</td><td></td><td style='color:#626363;font-weight:bold'>" +
|
"</td></tr><tr><td style='font-weight:bold;font-family:sans-serif;font-size:15px'>Note</td><td></td><td style='color:#626363;font-weight:bold'>" +
|
||||||
param.note +
|
param.note +
|
||||||
"</td></tr><tr><td></td><td></td></tr></table></div> <div style='margin-left:70px'><a target=_blank href=" +
|
"</td></tr><tr><td></td><td></td></tr></table></div> <div style='margin-left:70px'><a target=_blank href=" +
|
||||||
param.sigingUrl +
|
param.signingUrl +
|
||||||
"><button style='padding:12px;background-color:#d46b0f;color:white;border:0px;font-weight:bold;margin-top:30px'>Sign here</button></a></div><div style='display:flex;justify-content:center;margin-top:10px'></div></div></div><div><p> This is an automated email from " +
|
"><button style='padding:12px;background-color:#d46b0f;color:white;border:0px;font-weight:bold;margin-top:30px'>Sign here</button></a></div><div style='display:flex;justify-content:center;margin-top:10px'></div></div></div><div><p> This is an automated email from " +
|
||||||
appName +
|
appName +
|
||||||
". For any queries regarding this email, please contact the sender " +
|
". For any queries regarding this email, please contact the sender " +
|
||||||
@@ -3161,3 +3166,22 @@ export const checkRegularExpress = (validateType, setValidatePlaceholder) => {
|
|||||||
setValidatePlaceholder("please enter value");
|
setValidatePlaceholder("please enter value");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
//function to use unlink signer from widgets
|
||||||
|
export const handleUnlinkSigner = (signerPos,setSignerPos,signersdata,setSignersData,uniqueId) => {
|
||||||
|
//remove existing signer's details from 'signerPos' array
|
||||||
|
const updatePlaceHolder = signerPos.map((x) => {
|
||||||
|
if (x.Id === uniqueId) {
|
||||||
|
return { ...x, signerPtr: {}, signerObjId: "" };
|
||||||
|
}
|
||||||
|
return { ...x };
|
||||||
|
});
|
||||||
|
setSignerPos(updatePlaceHolder);
|
||||||
|
//remove existing signer's details from 'signersdata' array and keep role and id
|
||||||
|
const updateSigner = signersdata.map((item) => {
|
||||||
|
if (item.Id == uniqueId) {
|
||||||
|
return { Role: item.Role, Id: item.Id, blockColor: item.blockColor };
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
setSignersData(updateSigner);
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
import logo from "../assets/images/logo.png";
|
import logo from "../assets/images/logo.png";
|
||||||
|
import { getEnv } from "./Utils";
|
||||||
|
|
||||||
export function serverUrl_fn() {
|
export function serverUrl_fn() {
|
||||||
let baseUrl = process.env.REACT_APP_SERVERURL
|
const env = getEnv();
|
||||||
? process.env.REACT_APP_SERVERURL
|
const serverurl = env?.REACT_APP_SERVERURL
|
||||||
: window.location.origin + "/api/app";
|
? env.REACT_APP_SERVERURL // env.REACT_APP_SERVERURL is used for prod
|
||||||
|
: process.env.REACT_APP_SERVERURL; // process.env.REACT_APP_SERVERURL is used for dev (locally)
|
||||||
|
let baseUrl = serverurl ? serverurl : window.location.origin + "/api/app";
|
||||||
return baseUrl;
|
return baseUrl;
|
||||||
}
|
}
|
||||||
export const appInfo = {
|
export const appInfo = {
|
||||||
|
|||||||
@@ -1,3 +1,13 @@
|
|||||||
|
const userssetting = [
|
||||||
|
{
|
||||||
|
icon: "fa-light fa-users fa-fw",
|
||||||
|
title: "Users",
|
||||||
|
target: "_self",
|
||||||
|
pageType: "",
|
||||||
|
description: "",
|
||||||
|
objectId: "users"
|
||||||
|
}
|
||||||
|
];
|
||||||
export const subSetting = [
|
export const subSetting = [
|
||||||
{
|
{
|
||||||
icon: "fa-light fa-sliders",
|
icon: "fa-light fa-sliders",
|
||||||
@@ -7,14 +17,7 @@ export const subSetting = [
|
|||||||
description: "",
|
description: "",
|
||||||
objectId: "preferences"
|
objectId: "preferences"
|
||||||
},
|
},
|
||||||
{
|
...userssetting
|
||||||
icon: "fa-light fa-users fa-fw",
|
|
||||||
title: "Users",
|
|
||||||
target: "_self",
|
|
||||||
pageType: "",
|
|
||||||
description: "",
|
|
||||||
objectId: "users"
|
|
||||||
}
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const sidebarList = [
|
const sidebarList = [
|
||||||
@@ -65,7 +68,7 @@ const sidebarList = [
|
|||||||
pageType: "report",
|
pageType: "report",
|
||||||
description: "",
|
description: "",
|
||||||
objectId: "6TeaPr321t"
|
objectId: "6TeaPr321t"
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ function Login() {
|
|||||||
setState({ ...state, loading: false, alertType: type, alertMsg: msg });
|
setState({ ...state, loading: false, alertType: type, alertMsg: msg });
|
||||||
setTimeout(() => setState({ ...state, alertMsg: "" }), 2000);
|
setTimeout(() => setState({ ...state, alertMsg: "" }), 2000);
|
||||||
};
|
};
|
||||||
|
|
||||||
const checkUserExt = async () => {
|
const checkUserExt = async () => {
|
||||||
const app = await getAppLogo();
|
const app = await getAppLogo();
|
||||||
if (app?.error === "invalid_json") {
|
if (app?.error === "invalid_json") {
|
||||||
@@ -82,11 +83,11 @@ function Login() {
|
|||||||
} else {
|
} else {
|
||||||
setImage(appInfo?.applogo || undefined);
|
setImage(appInfo?.applogo || undefined);
|
||||||
}
|
}
|
||||||
|
dispatch(fetchAppInfo());
|
||||||
if (localStorage.getItem("accesstoken")) {
|
if (localStorage.getItem("accesstoken")) {
|
||||||
setState({ ...state, loading: true });
|
setState({ ...state, loading: true });
|
||||||
GetLoginData();
|
GetLoginData();
|
||||||
}
|
}
|
||||||
dispatch(fetchAppInfo());
|
|
||||||
};
|
};
|
||||||
const handleChange = (event) => {
|
const handleChange = (event) => {
|
||||||
let { name, value } = event.target;
|
let { name, value } = event.target;
|
||||||
@@ -96,20 +97,15 @@ function Login() {
|
|||||||
setState({ ...state, [name]: value });
|
setState({ ...state, [name]: value });
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmit = async (event) => {
|
const handleLogin = async (
|
||||||
localStorage.removeItem("accesstoken");
|
) => {
|
||||||
event.preventDefault();
|
const email = state?.email
|
||||||
|
const password = state?.password
|
||||||
|
|
||||||
if (!emailRegex.test(state.email)) {
|
|
||||||
alert("Please enter a valid email address.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { email, password } = state;
|
|
||||||
if (!email || !password) {
|
if (!email || !password) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
localStorage.removeItem("accesstoken");
|
||||||
try {
|
try {
|
||||||
setState({ ...state, loading: true });
|
setState({ ...state, loading: true });
|
||||||
localStorage.setItem("appLogo", appInfo.applogo);
|
localStorage.setItem("appLogo", appInfo.applogo);
|
||||||
@@ -132,6 +128,14 @@ function Login() {
|
|||||||
showToast("danger", "Invalid username/password or region");
|
showToast("danger", "Invalid username/password or region");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
const handleLoginBtn = async (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
if (!emailRegex.test(state.email)) {
|
||||||
|
alert("Please enter a valid email address.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await handleLogin();
|
||||||
|
};
|
||||||
|
|
||||||
const setThirdpartyLoader = (value) => {
|
const setThirdpartyLoader = (value) => {
|
||||||
setState({ ...state, thirdpartyLoader: value });
|
setState({ ...state, thirdpartyLoader: value });
|
||||||
@@ -275,7 +279,6 @@ function Login() {
|
|||||||
const userInformation = JSON.parse(
|
const userInformation = JSON.parse(
|
||||||
localStorage.getItem("UserInformation")
|
localStorage.getItem("UserInformation")
|
||||||
);
|
);
|
||||||
// console.log("payload ", payload);
|
|
||||||
if (payload && payload.sessionToken) {
|
if (payload && payload.sessionToken) {
|
||||||
const params = {
|
const params = {
|
||||||
userDetails: {
|
userDetails: {
|
||||||
@@ -289,7 +292,6 @@ function Login() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
const userSignUp = await Parse.Cloud.run("usersignup", params);
|
const userSignUp = await Parse.Cloud.run("usersignup", params);
|
||||||
// console.log("userSignUp ", userSignUp);
|
|
||||||
if (userSignUp && userSignUp.sessionToken) {
|
if (userSignUp && userSignUp.sessionToken) {
|
||||||
const LocalUserDetails = {
|
const LocalUserDetails = {
|
||||||
name: userInformation.name,
|
name: userInformation.name,
|
||||||
@@ -430,7 +432,7 @@ function Login() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-2">
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-2">
|
||||||
<div>
|
<div>
|
||||||
<form onSubmit={handleSubmit} aria-label="Login Form">
|
<form onSubmit={handleLoginBtn} aria-label="Login Form">
|
||||||
<h1 className="text-[30px] mt-6">{t("welcome")}</h1>
|
<h1 className="text-[30px] mt-6">{t("welcome")}</h1>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend className="text-[12px] text-[#878787]">
|
<legend className="text-[12px] text-[#878787]">
|
||||||
@@ -488,15 +490,14 @@ function Login() {
|
|||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="relative mt-1">
|
||||||
<div className="relative mt-1">
|
<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"
|
>
|
||||||
>
|
{t("forgot-password")}
|
||||||
{t("forgot-password")}
|
</NavLink>
|
||||||
</NavLink>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-2 text-center text-xs font-bold mt-2">
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-2 text-center text-xs font-bold mt-2">
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useRef, useEffect } from "react";
|
import { useState, useRef, useEffect } from "react";
|
||||||
import { PDFDocument } from "pdf-lib";
|
import { PDFDocument } from "pdf-lib";
|
||||||
import "../styles/signature.css";
|
import "../styles/signature.css";
|
||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
@@ -916,7 +916,7 @@ function PdfRequestFiles(
|
|||||||
const htmlReqBody =
|
const htmlReqBody =
|
||||||
"<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /></head><body>" +
|
"<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /></head><body>" +
|
||||||
replacedRequestBody +
|
replacedRequestBody +
|
||||||
"</body> </html>";
|
"</body></html>";
|
||||||
|
|
||||||
const variables = {
|
const variables = {
|
||||||
document_title: documentName,
|
document_title: documentName,
|
||||||
@@ -929,7 +929,7 @@ function PdfRequestFiles(
|
|||||||
receiver_phone: user?.Phone || "",
|
receiver_phone: user?.Phone || "",
|
||||||
expiry_date: localExpireDate,
|
expiry_date: localExpireDate,
|
||||||
company_name: orgName,
|
company_name: orgName,
|
||||||
signing_url: `<a href=${signPdf} target=_blank>Sign here</a>`
|
signing_url: signPdf
|
||||||
};
|
};
|
||||||
replaceVar = replaceMailVaribles(
|
replaceVar = replaceMailVaribles(
|
||||||
requestSubject,
|
requestSubject,
|
||||||
@@ -944,7 +944,7 @@ function PdfRequestFiles(
|
|||||||
title: documentName,
|
title: documentName,
|
||||||
organization: orgName,
|
organization: orgName,
|
||||||
localExpireDate: localExpireDate,
|
localExpireDate: localExpireDate,
|
||||||
sigingUrl: signPdf
|
signingUrl: signPdf
|
||||||
};
|
};
|
||||||
let params = {
|
let params = {
|
||||||
replyto: senderEmail || "",
|
replyto: senderEmail || "",
|
||||||
|
|||||||
@@ -1220,7 +1220,7 @@ function PlaceHolderSign() {
|
|||||||
receiver_phone: signerMail[i]?.Phone || "",
|
receiver_phone: signerMail[i]?.Phone || "",
|
||||||
expiry_date: localExpireDate,
|
expiry_date: localExpireDate,
|
||||||
company_name: orgName,
|
company_name: orgName,
|
||||||
signing_url: `<a href=${signPdf} target=_blank>Sign here</a>`
|
signing_url: signPdf
|
||||||
};
|
};
|
||||||
replaceVar = replaceMailVaribles(
|
replaceVar = replaceMailVaribles(
|
||||||
requestSubject,
|
requestSubject,
|
||||||
@@ -1249,7 +1249,7 @@ function PlaceHolderSign() {
|
|||||||
receiver_phone: signerMail[i]?.Phone || "",
|
receiver_phone: signerMail[i]?.Phone || "",
|
||||||
expiry_date: localExpireDate,
|
expiry_date: localExpireDate,
|
||||||
company_name: orgName,
|
company_name: orgName,
|
||||||
signing_url: `<a href=${signPdf} target=_blank>Sign here</a>`
|
signing_url: signPdf
|
||||||
};
|
};
|
||||||
replaceVar = replaceMailVaribles(mailSubject, htmlReqBody, variables);
|
replaceVar = replaceMailVaribles(mailSubject, htmlReqBody, variables);
|
||||||
}
|
}
|
||||||
@@ -1260,7 +1260,7 @@ function PlaceHolderSign() {
|
|||||||
title: documentName,
|
title: documentName,
|
||||||
organization: orgName,
|
organization: orgName,
|
||||||
localExpireDate: localExpireDate,
|
localExpireDate: localExpireDate,
|
||||||
sigingUrl: signPdf
|
signingUrl: signPdf
|
||||||
};
|
};
|
||||||
let params = {
|
let params = {
|
||||||
extUserId: owner?.objectId,
|
extUserId: owner?.objectId,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useRef, useEffect } from "react";
|
import { useState, useRef, useEffect } from "react";
|
||||||
import { PDFDocument } from "pdf-lib";
|
import { PDFDocument } from "pdf-lib";
|
||||||
import "../styles/signature.css";
|
import "../styles/signature.css";
|
||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
|
|||||||
@@ -1149,25 +1149,6 @@ const TemplatePlaceholder = () => {
|
|||||||
const handleLinkUser = (id) => {
|
const handleLinkUser = (id) => {
|
||||||
setIsAddUser({ [id]: true });
|
setIsAddUser({ [id]: true });
|
||||||
};
|
};
|
||||||
//function to use unlink signer from widgets
|
|
||||||
const handleUnlinkSigner = () => {
|
|
||||||
//remove existing signer's details from 'signerPos' array
|
|
||||||
const updatePlaceHolder = signerPos.map((x) => {
|
|
||||||
if (x.Id === uniqueId) {
|
|
||||||
return { ...x, signerPtr: {}, signerObjId: "" };
|
|
||||||
}
|
|
||||||
return { ...x };
|
|
||||||
});
|
|
||||||
setSignerPos(updatePlaceHolder);
|
|
||||||
//remove existing signer's details from 'signersdata' array and keep role and id
|
|
||||||
const updateSigner = signersdata.map((item) => {
|
|
||||||
if (item.Id == uniqueId) {
|
|
||||||
return { Role: item.Role, Id: item.Id, blockColor: item.blockColor };
|
|
||||||
}
|
|
||||||
return item;
|
|
||||||
});
|
|
||||||
setSignersData(updateSigner);
|
|
||||||
};
|
|
||||||
// `handleAddUser` is used to adduser
|
// `handleAddUser` is used to adduser
|
||||||
const handleAddUser = (data) => {
|
const handleAddUser = (data) => {
|
||||||
const signerPtr = {
|
const signerPtr = {
|
||||||
@@ -1950,7 +1931,9 @@ const TemplatePlaceholder = () => {
|
|||||||
closePopup={closePopup}
|
closePopup={closePopup}
|
||||||
signersData={signersdata}
|
signersData={signersdata}
|
||||||
signerPos={signerPos}
|
signerPos={signerPos}
|
||||||
handleUnlinkSigner={handleUnlinkSigner}
|
setSignerPos={setSignerPos}
|
||||||
|
setSignersData={setSignersData}
|
||||||
|
isRemove={true}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -679,7 +679,7 @@ const ReportTable = (props) => {
|
|||||||
receiver_phone: userDetails?.Phone || "",
|
receiver_phone: userDetails?.Phone || "",
|
||||||
expiry_date: localExpireDate,
|
expiry_date: localExpireDate,
|
||||||
company_name: doc.ExtUserPtr.Company,
|
company_name: doc.ExtUserPtr.Company,
|
||||||
signing_url: `<a href=${signPdf} target=_blank>Sign here</a>`
|
signing_url: signPdf
|
||||||
};
|
};
|
||||||
const res = replaceMailVaribles(subject, "", variables);
|
const res = replaceMailVaribles(subject, "", variables);
|
||||||
setMail((prev) => ({ ...prev, subject: res.subject }));
|
setMail((prev) => ({ ...prev, subject: res.subject }));
|
||||||
@@ -710,7 +710,7 @@ const ReportTable = (props) => {
|
|||||||
receiver_phone: userDetails?.Phone || "",
|
receiver_phone: userDetails?.Phone || "",
|
||||||
expiry_date: localExpireDate,
|
expiry_date: localExpireDate,
|
||||||
company_name: doc.ExtUserPtr.Company,
|
company_name: doc.ExtUserPtr.Company,
|
||||||
signing_url: `<a href=${signPdf} target=_blank>Sign here</a>`
|
signing_url: signPdf
|
||||||
};
|
};
|
||||||
const res = replaceMailVaribles("", body, variables);
|
const res = replaceMailVaribles("", body, variables);
|
||||||
|
|
||||||
@@ -754,7 +754,7 @@ const ReportTable = (props) => {
|
|||||||
receiver_phone: user?.signerPtr?.Phone || "",
|
receiver_phone: user?.signerPtr?.Phone || "",
|
||||||
expiry_date: localExpireDate,
|
expiry_date: localExpireDate,
|
||||||
company_name: doc?.ExtUserPtr?.Company || "",
|
company_name: doc?.ExtUserPtr?.Company || "",
|
||||||
signing_url: `<a href=${signPdf} target=_blank>Sign here</a>`
|
signing_url: signPdf
|
||||||
};
|
};
|
||||||
const subject =
|
const subject =
|
||||||
doc?.RequestSubject ||
|
doc?.RequestSubject ||
|
||||||
|
|||||||
@@ -25,12 +25,10 @@ const LinkUserModal = (props) => {
|
|||||||
handleClose={props.closePopup}
|
handleClose={props.closePopup}
|
||||||
>
|
>
|
||||||
<SelectSigners
|
<SelectSigners
|
||||||
details={props.handleAddUser}
|
{...props}
|
||||||
closePopup={props.closePopup}
|
closePopup={props.closePopup}
|
||||||
signersData={props?.signersData}
|
|
||||||
isContact={isContact}
|
isContact={isContact}
|
||||||
setIsContact={setIsContact}
|
setIsContact={setIsContact}
|
||||||
handleUnlinkSigner={props.handleUnlinkSigner}
|
|
||||||
isExistSigner={isExistSigner}
|
isExistSigner={isExistSigner}
|
||||||
/>
|
/>
|
||||||
{isContact && (
|
{isContact && (
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
# Use an official Node runtime as the base image
|
|
||||||
FROM node:20
|
|
||||||
|
|
||||||
# Set the working directory inside the container
|
|
||||||
WORKDIR /usr/src/app
|
|
||||||
|
|
||||||
# Copy package.json and package-lock.json first to leverage Docker cache
|
|
||||||
COPY ./package*.json ./
|
|
||||||
|
|
||||||
# Install application dependencies
|
|
||||||
RUN npm install
|
|
||||||
|
|
||||||
# If you have native dependencies, you'll need extra tools. Uncomment the following line if needed.
|
|
||||||
# RUN apk add --no-cache make gcc g++ python3
|
|
||||||
|
|
||||||
# Copy the current directory contents into the container
|
|
||||||
COPY ./ .
|
|
||||||
|
|
||||||
# Make port 8080 available to the world outside this container
|
|
||||||
EXPOSE 8080
|
|
||||||
|
|
||||||
# Define environment variables if needed
|
|
||||||
# ENV NODE_ENV production
|
|
||||||
# ENV DATABASE_URL mongodb://db:27017
|
|
||||||
|
|
||||||
# Run the application
|
|
||||||
ENTRYPOINT npm start
|
|
||||||
@@ -252,7 +252,7 @@ export const mailTemplate = param => {
|
|||||||
"</td></tr><tr><td style='font-weight:bold;font-family:sans-serif;font-size:15px'>Note</td><td></td><td style='color:#626363;font-weight:bold'>" +
|
"</td></tr><tr><td style='font-weight:bold;font-family:sans-serif;font-size:15px'>Note</td><td></td><td style='color:#626363;font-weight:bold'>" +
|
||||||
param.note +
|
param.note +
|
||||||
"</td></tr><tr><td></td><td></td></tr></table></div> <div style='margin-left:70px'><a target=_blank href=" +
|
"</td></tr><tr><td></td><td></td></tr></table></div> <div style='margin-left:70px'><a target=_blank href=" +
|
||||||
param.sigingUrl +
|
param.signingUrl +
|
||||||
"><button style='padding:12px;background-color:#d46b0f;color:white;border:0px;font-weight:bold;margin-top:30px'>Sign here</button></a></div><div style='display:flex;justify-content:center;margin-top:10px'></div></div></div><div><p> This is an automated email from " +
|
"><button style='padding:12px;background-color:#d46b0f;color:white;border:0px;font-weight:bold;margin-top:30px'>Sign here</button></a></div><div style='display:flex;justify-content:center;margin-top:10px'></div></div></div><div><p> This is an automated email from " +
|
||||||
AppName +
|
AppName +
|
||||||
'. For any queries regarding this email, please contact the sender ' +
|
'. For any queries regarding this email, please contact the sender ' +
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ export default async function Newsletter(request) {
|
|||||||
const email = request.params?.email?.toLowerCase()?.replace(/\s/g, '');
|
const email = request.params?.email?.toLowerCase()?.replace(/\s/g, '');
|
||||||
const domain = request.params.domain;
|
const domain = request.params.domain;
|
||||||
try {
|
try {
|
||||||
const envAppId = process.env.REACT_APP_APPID || 'opensign';
|
const envAppId = 'opensign';
|
||||||
const headers = { 'Content-Type': 'application/json', 'X-Parse-Application-Id': envAppId };
|
const headers = { 'Content-Type': 'application/json', 'X-Parse-Application-Id': envAppId };
|
||||||
const envProdServer = process.env.REACT_APP_SERVERURL || 'https://app.opensignlabs.com/api/app';
|
const envProdServer = 'https://app.opensignlabs.com/api/app';
|
||||||
const newsletter = await axios.post(
|
const newsletter = await axios.post(
|
||||||
`${envProdServer}/classes/Newsletter`,
|
`${envProdServer}/classes/Newsletter`,
|
||||||
{ Name: name, Email: email, Domain: domain },
|
{ Name: name, Email: email, Domain: domain },
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ async function deductcount(docsCount, extUserId) {
|
|||||||
}
|
}
|
||||||
async function sendMail(document, publicUrl) {
|
async function sendMail(document, publicUrl) {
|
||||||
//sessionToken
|
//sessionToken
|
||||||
const baseUrl = new URL(publicUrl); //process.env.PUBLIC_URL
|
const baseUrl = new URL(publicUrl);
|
||||||
|
|
||||||
// console.log("pdfDetails", pdfDetails);
|
// console.log("pdfDetails", pdfDetails);
|
||||||
const timeToCompleteDays = document?.TimeToCompleteDays || 15;
|
const timeToCompleteDays = document?.TimeToCompleteDays || 15;
|
||||||
@@ -71,7 +71,7 @@ async function sendMail(document, publicUrl) {
|
|||||||
receiver_phone: existSigner?.Phone || '',
|
receiver_phone: existSigner?.Phone || '',
|
||||||
expiry_date: localExpireDate,
|
expiry_date: localExpireDate,
|
||||||
company_name: orgName,
|
company_name: orgName,
|
||||||
signing_url: `<a href=${signPdf} target=_blank>Sign here</a>`,
|
signing_url: signPdf,
|
||||||
};
|
};
|
||||||
replaceVar = replaceMailVaribles(mailSubject, htmlReqBody, variables);
|
replaceVar = replaceMailVaribles(mailSubject, htmlReqBody, variables);
|
||||||
}
|
}
|
||||||
@@ -82,7 +82,7 @@ async function sendMail(document, publicUrl) {
|
|||||||
title: document.Name,
|
title: document.Name,
|
||||||
organization: orgName,
|
organization: orgName,
|
||||||
localExpireDate: localExpireDate,
|
localExpireDate: localExpireDate,
|
||||||
sigingUrl: signPdf,
|
signingUrl: signPdf,
|
||||||
};
|
};
|
||||||
let params = {
|
let params = {
|
||||||
extUserId: document.ExtUserPtr.objectId,
|
extUserId: document.ExtUserPtr.objectId,
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ async function sendNotifyMail(doc, signUser, mailProvider, publicUrl) {
|
|||||||
const creatorEmail = doc.ExtUserPtr.Email;
|
const creatorEmail = doc.ExtUserPtr.Email;
|
||||||
const signerName = signUser.Name;
|
const signerName = signUser.Name;
|
||||||
const signerEmail = signUser.Email;
|
const signerEmail = signUser.Email;
|
||||||
const viewDocUrl = `${publicUrl}/recipientSignPdf/${doc.objectId}`; // ` ${process.env.PUBLIC_URL}/recipientSignPdf/${doc.objectId}`;
|
const viewDocUrl = `${publicUrl}/recipientSignPdf/${doc.objectId}`;
|
||||||
const subject = `Document "${pdfName}" has been signed by ${signerName}`;
|
const subject = `Document "${pdfName}" has been signed by ${signerName}`;
|
||||||
const body =
|
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'>" +
|
"<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'>" +
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ app.use(express.urlencoded({ limit: '50mb', extended: true }));
|
|||||||
app.use(function (req, res, next) {
|
app.use(function (req, res, next) {
|
||||||
req.headers['x-real-ip'] = getUserIP(req);
|
req.headers['x-real-ip'] = getUserIP(req);
|
||||||
const publicUrl = 'https://' + req?.get('host');
|
const publicUrl = 'https://' + req?.get('host');
|
||||||
req.headers['public_url'] = publicUrl; // process.env.PUBLIC_URL
|
req.headers['public_url'] = publicUrl;
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
function getUserIP(request) {
|
function getUserIP(request) {
|
||||||
|
|||||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "open_sign_server",
|
"name": "open_sign_server",
|
||||||
"version": "1.4.0",
|
"version": "2.21.1",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "open_sign_server",
|
"name": "open_sign_server",
|
||||||
"version": "1.4.0",
|
"version": "2.21.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aws-sdk/client-s3": "^3.812.0",
|
"@aws-sdk/client-s3": "^3.812.0",
|
||||||
|
|||||||
Reference in New Issue
Block a user