mirror of
https://github.com/OpenSignLabs/OpenSign.git
synced 2026-09-05 01:07:39 +02:00
Compare commits
24
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7ef22eb220 | ||
|
|
2237358d8a | ||
|
|
0275762e20 | ||
|
|
618b4fa2fb | ||
|
|
37b41fca93 | ||
|
|
470ed8970a | ||
|
|
bb80324c35 | ||
|
|
a460b62233 | ||
|
|
412901b839 | ||
|
|
9b322913f6 | ||
|
|
248bb71ceb | ||
|
|
f62b241270 | ||
|
|
d95da53757 | ||
|
|
66323f9347 | ||
|
|
c65f17a216 | ||
|
|
277cc34e65 | ||
|
|
9bf93fb231 | ||
|
|
f418e02270 | ||
|
|
1ca33c0b76 | ||
|
|
403254a5c6 | ||
|
|
c893d96ad3 | ||
|
|
d8131a6199 | ||
|
|
3971118af8 | ||
|
|
4db0d93f41 |
+2
-2
@@ -77,6 +77,6 @@ Engage with the community on our [Gitter Channel](https://gitter.im/OpenSignLabs
|
||||
|
||||
## License
|
||||
|
||||
By contributing, you agree that your contributions will be licensed under its [MIT License](LICENSE).
|
||||
By contributing, you agree that your contributions will be licensed under its [AGPL-V3 License](LICENSE).
|
||||
|
||||
---
|
||||
---
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* All content that resides under the "apps/OpenSignServer/cloud/customRoute" directory of this repository, if that directory exists, is licensed under the license defined in "apps/OpenSignServer/cloud/customRoute".
|
||||
* All third party components incorporated into the OpenSign Software are licensed under the original license provided by the owner of the applicable component.
|
||||
* Content outside of the above mentioned directories or restrictions above is available under the "GNU AFFERO GENERAL PUBLIC LICENSE" as defined below -
|
||||
|
||||
|
||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"header-news": "New feature: Public profiles are now live! Easily create and share public templates",
|
||||
"header-news": "New feature: Teams plan users can now integrate their own AWS S3 buckets for file storage",
|
||||
"header-news-btn": "Setup Now",
|
||||
"create-account": "Create Account",
|
||||
"login": "Login",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"header-news": "Nueva funcionalidad: ¡Los perfiles públicos ahora están disponibles! Crea y comparte plantillas públicas fácilmente",
|
||||
"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",
|
||||
"create-account": "Crear cuenta",
|
||||
"login": "Iniciar sesión",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"header-news": "Nouvelle fonctionnalité : les profils publics sont désormais en ligne ! Créez et partagez facilement des modèles publics",
|
||||
"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",
|
||||
"create-account": "Créer un compte",
|
||||
"login": "Se Connecter",
|
||||
|
||||
@@ -140,15 +140,22 @@ const Header = ({ showSidebar, setIsMenu }) => {
|
||||
);
|
||||
setShowNotification(false);
|
||||
};
|
||||
const handleSetupNowNavigation = () => {
|
||||
const url = isStaging
|
||||
? "https://staging-console.opensignlabs.com/fileadapter"
|
||||
: "https://console.opensignlabs.com/fileadapter";
|
||||
|
||||
openInNewTab(url);
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
{isEnableSubscription && showNotification && (
|
||||
<div className="flex justify-between items-center shadow py-1 bg-[#CAE4FA] p-1">
|
||||
<div className="flex justify-between items-center shadow py-1 bg-[#CAE4FA] p-1">
|
||||
<div className="text-center text-[14px] ml-auto">
|
||||
{t("header-news")} —
|
||||
<span
|
||||
className="cursor-pointer font-medium underline text-blue-800"
|
||||
onClick={() => navigate("/profile")}
|
||||
onClick={() => handleSetupNowNavigation()}
|
||||
>
|
||||
{" " + t("header-news-btn") + "."}
|
||||
</span>
|
||||
|
||||
@@ -1453,7 +1453,6 @@ export const multiSignEmbed = async (widgets, pdfDoc, signyourself, scale) => {
|
||||
if (position?.options?.values.length > 0) {
|
||||
position?.options?.values.forEach((item, ind) => {
|
||||
const checkboxRandomId = "checkbox" + randomId();
|
||||
|
||||
if (
|
||||
position?.options?.response &&
|
||||
position?.options?.response?.length > 0
|
||||
@@ -1505,8 +1504,6 @@ export const multiSignEmbed = async (widgets, pdfDoc, signyourself, scale) => {
|
||||
});
|
||||
}
|
||||
} else if (widgetTypeExist) {
|
||||
const fontSize = position?.options?.fontSize || 12;
|
||||
parseInt(fontSize);
|
||||
let textContent;
|
||||
if (position?.options?.response) {
|
||||
textContent = position.options?.response;
|
||||
@@ -1541,7 +1538,6 @@ export const multiSignEmbed = async (widgets, pdfDoc, signyourself, scale) => {
|
||||
// Function to break text into lines based on when user go next line on press enter button
|
||||
const breakTextIntoLines = (textContent, width) => {
|
||||
const lines = [];
|
||||
|
||||
for (const word of textContent.split("\n")) {
|
||||
const lineWidth = font.widthOfTextAtSize(`${word}`, fontSize);
|
||||
//checking string length to container width
|
||||
@@ -1583,7 +1579,6 @@ export const multiSignEmbed = async (widgets, pdfDoc, signyourself, scale) => {
|
||||
y += 18; // Adjust the line height as needed
|
||||
}
|
||||
} else if (position.type === "dropdown") {
|
||||
const fontsize = parseInt(position?.options?.fontSize) || 12;
|
||||
const dropdownRandomId = "dropdown" + randomId();
|
||||
const dropdown = form.createDropdown(dropdownRandomId);
|
||||
dropdown.addOptions(position?.options?.values);
|
||||
@@ -1598,10 +1593,10 @@ export const multiSignEmbed = async (widgets, pdfDoc, signyourself, scale) => {
|
||||
// - `FontSize` is the size you want to set (e.g., 12)
|
||||
// - `Tf` specifies the font and size
|
||||
// - `0 g` sets the text color to black
|
||||
const defaultAppearance = `/Helv ${fontsize} Tf 0 g`;
|
||||
const defaultAppearance = `/Helv ${fontSize} Tf 0 g`;
|
||||
// Set the default appearance for the dropdown field
|
||||
dropdown.acroField.setDefaultAppearance(defaultAppearance);
|
||||
dropdown.setFontSize(fontsize);
|
||||
dropdown.setFontSize(fontSize);
|
||||
const dropdownObj = {
|
||||
x: xPos(position),
|
||||
y: yPos(position),
|
||||
|
||||
@@ -531,9 +531,9 @@ function PdfRequestFiles(props) {
|
||||
const obj = documentData?.[0];
|
||||
setSendInOrder(obj?.SendinOrder || false);
|
||||
if (
|
||||
obj &&
|
||||
obj?.Signers?.length > 0 &&
|
||||
obj?.Placeholders?.length > 0
|
||||
obj?.Signers?.length &&
|
||||
obj?.Placeholders?.length &&
|
||||
currUserId !== "undefined"
|
||||
) {
|
||||
const params = {
|
||||
event: "viewed",
|
||||
|
||||
@@ -580,22 +580,33 @@ function PlaceHolderSign() {
|
||||
}
|
||||
setSignerPos(updatesignerPos);
|
||||
} else {
|
||||
let updatesignerPos;
|
||||
//if condition when widget type is prefill label text widget
|
||||
if (dragTypeValue === textWidget) {
|
||||
const prefileTextWidget = {
|
||||
signerPtr: {},
|
||||
signerObjId: "",
|
||||
blockColor: "#f58f8c",
|
||||
placeHolder: [placeHolder],
|
||||
Role: "prefill",
|
||||
Id: key
|
||||
};
|
||||
signerPos.push(prefileTextWidget);
|
||||
setSignerPos(signerPos);
|
||||
//check text widgets data (prefill) already exist then and want to add text widget on new page
|
||||
//create new page entry with old data and update placeholder
|
||||
if (filterSignerPos) {
|
||||
const addPrefillData =
|
||||
filterSignerPos && filterSignerPos?.placeHolder;
|
||||
addPrefillData.push(placeHolder);
|
||||
const updatePrefillPos = signerPos.map((x) =>
|
||||
x.Role === "prefill" ? { ...x, placeHolder: addPrefillData } : x
|
||||
);
|
||||
setSignerPos(updatePrefillPos);
|
||||
} //else condition if user do not have any text widget data
|
||||
else {
|
||||
const prefillTextWidget = {
|
||||
signerPtr: {},
|
||||
signerObjId: "",
|
||||
blockColor: "#f58f8c",
|
||||
placeHolder: [placeHolder],
|
||||
Role: "prefill",
|
||||
Id: key
|
||||
};
|
||||
setSignerPos((prev)=>[...prev,prefillTextWidget]);
|
||||
}
|
||||
} else {
|
||||
//else condition to add placeholder widgets on multiple page first time
|
||||
updatesignerPos = signerPos.map((x) =>
|
||||
const updatesignerPos = signerPos.map((x) =>
|
||||
x.Id === uniqueId && x?.placeHolder
|
||||
? { ...x, placeHolder: [...x.placeHolder, placeHolder] }
|
||||
: x.Id === uniqueId
|
||||
@@ -770,15 +781,17 @@ function PlaceHolderSign() {
|
||||
signerupdate.push(newUpdatePos[0]);
|
||||
setSignerPos(signerupdate);
|
||||
} else {
|
||||
const updatedData = signerPos.map((item) => {
|
||||
if (item.Id === Id) {
|
||||
// Create a copy of the item object and delete the placeHolder field
|
||||
const updatedItem = { ...item };
|
||||
delete updatedItem.placeHolder;
|
||||
return updatedItem;
|
||||
}
|
||||
return item;
|
||||
});
|
||||
const updatedData = signerPos
|
||||
.filter((item) => !(item.Id === Id && item.Role === "prefill")) // Remove prefill object
|
||||
.map((item) => {
|
||||
if (item.Id === Id && item.Role !== "prefill") {
|
||||
// Create a copy of the item object and delete the placeHolder field
|
||||
const updatedItem = { ...item };
|
||||
delete updatedItem.placeHolder;
|
||||
return updatedItem;
|
||||
}
|
||||
return item;
|
||||
});
|
||||
setSignerPos(updatedData);
|
||||
}
|
||||
}
|
||||
@@ -1586,7 +1599,11 @@ function PlaceHolderSign() {
|
||||
}
|
||||
};
|
||||
const handleRecipientSign = () => {
|
||||
navigate(`/recipientSignPdf/${documentId}/${currentId}`);
|
||||
if (currentId) {
|
||||
navigate(`/recipientSignPdf/${documentId}/${currentId}`);
|
||||
} else {
|
||||
navigate(`/recipientSignPdf/${documentId}`);
|
||||
}
|
||||
};
|
||||
const handleLinkUser = (id) => {
|
||||
setIsAddUser({ [id]: true });
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"header-news": "New feature: Public profiles are now live! Easily create and share public templates",
|
||||
"header-news": "New feature: Teams plan users can now integrate their own AWS S3 buckets for file storage",
|
||||
"header-news-btn": "Setup Now",
|
||||
"create-account": "Create Account",
|
||||
"login": "Login",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"header-news": "Nueva funcionalidad: ¡Los perfiles públicos ahora están disponibles! Crea y comparte plantillas públicas fácilmente",
|
||||
"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",
|
||||
"create-account": "Crear cuenta",
|
||||
"login": "Iniciar sesión",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"header-news": "Nouvelle fonctionnalité : les profils publics sont désormais en ligne ! Créez et partagez facilement des modèles publics",
|
||||
"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",
|
||||
"create-account": "Créer un compte",
|
||||
"login": "Se Connecter",
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
The OpenSign Enterprise license (the “Enterprise License”)
|
||||
Copyright (c) 2020-2024 Qik Innovations Private Limited.
|
||||
|
||||
With regard to the OpenSign Software:
|
||||
|
||||
This software and associated documentation files (the "Software") may only be
|
||||
used in production, if you (and any entity that you represent) have agreed to,
|
||||
and are in compliance with, the OpenSign Subscription Terms of Service(the “Enterprise Terms”), or other
|
||||
agreement governing the use of the Software, as agreed by you and OpenSign,
|
||||
and otherwise have a valid OpenSign Enterprise license for the
|
||||
correct number of user seats. Subject to the foregoing sentence, you are free to
|
||||
modify this Software and publish patches to the Software. You agree that OpenSign
|
||||
and/or its licensors (as applicable) retain all right, title and interest in and
|
||||
to all such modifications and/or patches, and all such modifications and/or
|
||||
patches may only be used, copied, modified, displayed, distributed, or otherwise
|
||||
exploited with a valid OpenSign Enterprise license for the correct
|
||||
number of user seats. Notwithstanding the foregoing, you may copy and modify
|
||||
the Software for development and testing purposes, without requiring a
|
||||
subscription. You agree that OpenSign and/or its licensors (as applicable) retain
|
||||
all right, title and interest in and to all such modifications. You are not
|
||||
granted any other rights beyond what is expressly stated herein. Subject to the
|
||||
foregoing, it is forbidden to copy, merge, publish, distribute, sublicense,
|
||||
and/or sell the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
For all third party components incorporated into the OpenSign Software, those
|
||||
components are licensed under the original license provided by the owner of the
|
||||
applicable component.
|
||||
@@ -8,7 +8,7 @@ export default function getPresignedUrl(url, adapter) {
|
||||
AWS.config.update({ credentials: credentials, region: adapter?.region || process.env.DO_REGION });
|
||||
const spacesEndpoint = adapter?.endpoint || new AWS.Endpoint(process.env.DO_ENDPOINT);
|
||||
|
||||
const s3 = new AWS.S3({ endpoint: spacesEndpoint });
|
||||
const s3 = new AWS.S3({ endpoint: spacesEndpoint, signatureVersion: "v4" });
|
||||
|
||||
// Create a new URL object
|
||||
const parsedUrl = new URL(url);
|
||||
|
||||
@@ -95,13 +95,22 @@ export default async function getSubscription(request) {
|
||||
} else if (contactId) {
|
||||
try {
|
||||
const contactCls = new Parse.Query('contracts_Contactbook');
|
||||
contactCls.include('CreatedBy');
|
||||
const contactUser = await contactCls.get(contactId, { useMasterKey: true });
|
||||
if (contactUser) {
|
||||
const _contractUser = JSON.parse(JSON.stringify(contactUser));
|
||||
let TenantId = _contractUser?.TenantId?.objectId || '';
|
||||
if (!TenantId) {
|
||||
const extUserCls = new Parse.Query('contracts_Users');
|
||||
extUserCls.equalTo('Email', _contractUser.CreatedBy.email);
|
||||
const contactUser = await extUserCls.first({ useMasterKey: true });
|
||||
TenantId = contactUser?.get('TenantId')?.id || '';
|
||||
}
|
||||
const subscriptionCls = new Parse.Query('contracts_Subscriptions');
|
||||
subscriptionCls.equalTo('TenantId', {
|
||||
__type: 'Pointer',
|
||||
className: 'partners_Tenant',
|
||||
objectId: contactUser.get('TenantId').id,
|
||||
objectId: TenantId,
|
||||
});
|
||||
subscriptionCls.descending('createdAt');
|
||||
const subcripitions = await subscriptionCls.first({ useMasterKey: true });
|
||||
|
||||
@@ -458,17 +458,17 @@ export default async function GenerateCertificate(docDetails) {
|
||||
});
|
||||
|
||||
currentPage.drawText('Viewed on :', {
|
||||
x: half,
|
||||
x: half + 55,
|
||||
y: yPosition2,
|
||||
size: text,
|
||||
size: timeText,
|
||||
font: timesRomanFont,
|
||||
color: textKeyColor,
|
||||
});
|
||||
|
||||
currentPage.drawText(`${new Date(x.ViewedOn).toUTCString()}`, {
|
||||
x: half + 75,
|
||||
x: half + 112,
|
||||
y: yPosition2,
|
||||
size: text,
|
||||
size: timeText,
|
||||
font: timesRomanFont,
|
||||
color: textValueColor,
|
||||
});
|
||||
@@ -490,17 +490,17 @@ export default async function GenerateCertificate(docDetails) {
|
||||
});
|
||||
|
||||
currentPage.drawText('Signed on :', {
|
||||
x: half,
|
||||
y: yPosition3,
|
||||
size: text,
|
||||
x: half + 55,
|
||||
y: yPosition3 + 5,
|
||||
size: timeText,
|
||||
font: timesRomanFont,
|
||||
color: textKeyColor,
|
||||
});
|
||||
|
||||
currentPage.drawText(`${new Date(x.SignedOn).toUTCString()}`, {
|
||||
x: half + 70,
|
||||
y: yPosition3,
|
||||
size: text,
|
||||
x: half + 108,
|
||||
y: yPosition3 + 5,
|
||||
size: timeText,
|
||||
font: timesRomanFont,
|
||||
color: textValueColor,
|
||||
});
|
||||
@@ -520,22 +520,23 @@ export default async function GenerateCertificate(docDetails) {
|
||||
font: timesRomanFont,
|
||||
color: textValueColor,
|
||||
});
|
||||
currentPage.drawText('Security level :', {
|
||||
x: half,
|
||||
y: yPosition4,
|
||||
size: text,
|
||||
font: timesRomanFont,
|
||||
color: textKeyColor,
|
||||
});
|
||||
|
||||
currentPage.drawText(`Email, OTP Auth`, {
|
||||
x: half + 90,
|
||||
y: yPosition4,
|
||||
size: text,
|
||||
font: timesRomanFont,
|
||||
color: textValueColor,
|
||||
});
|
||||
|
||||
if (IsEnableOTP) {
|
||||
currentPage.drawText('Security level :', {
|
||||
x: half + 55,
|
||||
y: yPosition4 + 10,
|
||||
size: timeText,
|
||||
font: timesRomanFont,
|
||||
color: textKeyColor,
|
||||
});
|
||||
currentPage.drawText(`Email, OTP Auth`, {
|
||||
x: half + 125,
|
||||
y: yPosition4 + 10,
|
||||
size: timeText,
|
||||
font: timesRomanFont,
|
||||
color: textValueColor,
|
||||
});
|
||||
}
|
||||
currentPage.drawText('Signature :', {
|
||||
x: 30,
|
||||
y: yPosition5,
|
||||
|
||||
@@ -384,6 +384,7 @@ async function PDF(req) {
|
||||
isCompleted = true;
|
||||
}
|
||||
const randomNumber = Math.floor(Math.random() * 5000);
|
||||
// below regex is used to replace all word with "_" except A to Z, a to z, numbers
|
||||
const docName = _resDoc?.Name?.replace(/[^a-zA-Z0-9._-]/g, '_')?.toLowerCase();
|
||||
const name = `signed_${docName}_${randomNumber}.pdf`;
|
||||
const filePath = `./exports/${name}`;
|
||||
|
||||
@@ -37,7 +37,8 @@ const makeEmail = async (to, from, subject, html, url, pdfName) => {
|
||||
let Pdf = fs.createWriteStream('test.pdf');
|
||||
const writeToLocalDisk = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const isSecure = new URL(url)?.protocol === 'https:';
|
||||
const isSecure =
|
||||
new URL(url)?.protocol === 'https:' && new URL(url)?.hostname !== 'localhost';
|
||||
if (useLocal !== 'true' || isSecure) {
|
||||
https.get(url, async function (response) {
|
||||
response.pipe(Pdf);
|
||||
|
||||
@@ -33,7 +33,9 @@ async function sendMailProvider(req, plan, monthchange) {
|
||||
let Pdf = fs.createWriteStream('test.pdf');
|
||||
const writeToLocalDisk = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const isSecure = new URL(req.params.url)?.protocol === 'https:';
|
||||
const isSecure =
|
||||
new URL(req.params.url)?.protocol === 'https:' &&
|
||||
new URL(req.params.url)?.hostname !== 'localhost';
|
||||
if (useLocal !== 'true' || isSecure) {
|
||||
https.get(req.params.url, async function (response) {
|
||||
response.pipe(Pdf);
|
||||
@@ -200,7 +202,9 @@ async function sendcustomsmtp(extRes, req) {
|
||||
let Pdf = fs.createWriteStream('test.pdf');
|
||||
const writeToLocalDisk = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const isSecure = new URL(req.params.url)?.protocol === 'https:';
|
||||
const isSecure =
|
||||
new URL(req.params.url)?.protocol === 'https:' &&
|
||||
new URL(req.params.url)?.hostname !== 'localhost';
|
||||
if (useLocal !== 'true' || isSecure) {
|
||||
https.get(req.params.url, async function (response) {
|
||||
response.pipe(Pdf);
|
||||
|
||||
@@ -14,6 +14,7 @@ async function uploadFileToS3(buffer, fileName, mimeType, adapter) {
|
||||
client = new S3Client({
|
||||
region: adapter?.region,
|
||||
credentials: { accessKeyId: adapter?.accessKeyId, secretAccessKey: adapter?.secretAccessKey },
|
||||
signatureVersion: "v4"
|
||||
});
|
||||
}
|
||||
const prefixId = crypto.randomBytes(16).toString('hex');
|
||||
|
||||
Reference in New Issue
Block a user