diff --git a/.env.local_dev b/.env.local_dev index 969ede16c..d208d296e 100644 --- a/.env.local_dev +++ b/.env.local_dev @@ -7,7 +7,7 @@ PUBLIC_URL=http://localhost:3000 # Set it to true if you want to generate the Sourcemap for debugging GENERATE_SOURCEMAP=false # Set it to the URL from where APIs will be accessible, for local development it should be localhost:3000/api/app (use your local port number instead) -REACT_APP_SERVERURL=http://localhost:8080/app +# REACT_APP_SERVERURL=http://localhost:8080/app # A 12 character long random app identifier. The value of this should be same as APP_ID which is a variable used by backend API. REACT_APP_APPID=opensign @@ -46,7 +46,7 @@ USE_LOCAL=true MAILGUN_API_KEY= MAILGUN_DOMAIN=mail.yourdomain.com MAILGUN_SENDER=postmaster@mail.yourdomain.com -SMTP_ENABLE= +SMTP_ENABLE=true SMTP_HOST=smtp.yourhost.com SMTP_PORT=443 SMTP_USER_EMAIL=mailer@yourdomain.com diff --git a/.github/workflows/Docker.yml b/.github/workflows/Docker.yml index 612955230..01c74a80d 100644 --- a/.github/workflows/Docker.yml +++ b/.github/workflows/Docker.yml @@ -2,7 +2,7 @@ name: ci on: push: branches: - - 'staging' + - 'main' jobs: docker: diff --git a/Caddyfile b/Caddyfile new file mode 100644 index 000000000..c3a000662 --- /dev/null +++ b/Caddyfile @@ -0,0 +1,7 @@ +{$HOST_URL} { + reverse_proxy client:3000 + handle_path /app/* { + reverse_proxy server:8080 + rewrite * /app{uri} + } +} diff --git a/Makefile b/Makefile index 7c70890cf..3741a2bc0 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,10 @@ build: + @echo "Building with HOST_URL=${HOST_URL}" cp .env.local_dev .env cd apps/OpenSign && cp ../../.env.local_dev .env && npm install && npm run build - docker compose up --build --force-recreate + HOST_URL=${HOST_URL} docker compose up --build --force-recreate run: + @echo "Building with HOST_URL=${HOST_URL}" cp .env.local_dev .env - docker compose up -d \ No newline at end of file + docker compose up -d diff --git a/apps/OpenSign/public/version.txt b/apps/OpenSign/public/version.txt index 1defe531b..f1893d2be 100644 Binary files a/apps/OpenSign/public/version.txt and b/apps/OpenSign/public/version.txt differ diff --git a/apps/OpenSign/src/App.js b/apps/OpenSign/src/App.js index 69ef95f98..e7183f4ce 100644 --- a/apps/OpenSign/src/App.js +++ b/apps/OpenSign/src/App.js @@ -20,6 +20,7 @@ import SSOVerify from "./pages/SSOVerify"; import Loader from "./primitives/Loader"; import TeamList from "./pages/TeamList"; import UserList from "./pages/UserList"; +import { serverUrl_fn } from "./constant/appinfo"; const DebugPdf = lazy(() => import("./pages/DebugPdf")); const ForgetPassword = lazy(() => import("./pages/ForgetPassword")); const GuestLogin = lazy(() => import("./pages/GuestLogin")); @@ -53,9 +54,7 @@ function App() { const appId = process.env.REACT_APP_APPID ? process.env.REACT_APP_APPID : "opensign"; - const baseurl = process.env.REACT_APP_SERVERURL - ? process.env.REACT_APP_SERVERURL - : window.location.origin + "/api/app"; + const baseurl = serverUrl_fn(); try { localStorage.setItem("baseUrl", `${baseurl}/`); localStorage.setItem("parseAppId", appId); diff --git a/apps/OpenSign/src/constant/appinfo.js b/apps/OpenSign/src/constant/appinfo.js index 5ca46758e..64dbd87b2 100644 --- a/apps/OpenSign/src/constant/appinfo.js +++ b/apps/OpenSign/src/constant/appinfo.js @@ -1,10 +1,23 @@ import logo from "../assets/images/logo.png"; +import { isEnableSubscription } from "./const"; + +export function serverUrl_fn() { + let baseUrl; + if (isEnableSubscription) { + baseUrl = process.env.REACT_APP_SERVERURL + ? process.env.REACT_APP_SERVERURL + : window.location.origin + "/api/app"; + } else { + baseUrl = process.env.REACT_APP_SERVERURL + ? process.env.REACT_APP_SERVERURL + : window.location.origin + "/app"; + } + return baseUrl; +} export const appInfo = { applogo: logo, appId: process.env.REACT_APP_APPID ? process.env.REACT_APP_APPID : "opensign", - baseUrl: process.env.REACT_APP_SERVERURL - ? process.env.REACT_APP_SERVERURL - : window.location.origin + "/api/app", + baseUrl: serverUrl_fn(), defaultRole: "contracts_User", fbAppId: process.env.REACT_APP_FBAPPID ? `${process.env.REACT_APP_FBAPPID}` diff --git a/apps/OpenSign/src/constant/saveFileSize.js b/apps/OpenSign/src/constant/saveFileSize.js index d15aa9089..f2f8ba657 100644 --- a/apps/OpenSign/src/constant/saveFileSize.js +++ b/apps/OpenSign/src/constant/saveFileSize.js @@ -1,11 +1,9 @@ import axios from "axios"; +import { serverUrl_fn } from "./appinfo"; const parseAppId = process.env.REACT_APP_APPID ? process.env.REACT_APP_APPID : "opensign"; -const serverUrl = process.env.REACT_APP_SERVERURL - ? process.env.REACT_APP_SERVERURL - : window.location.origin + "/api/app"; - +const serverUrl = serverUrl_fn(); export const SaveFileSize = async (size, imageUrl, tenantId) => { //checking server url and save file's size const tenantPtr = { diff --git a/apps/OpenSign/src/index.js b/apps/OpenSign/src/index.js index cf719abc2..271c10bac 100644 --- a/apps/OpenSign/src/index.js +++ b/apps/OpenSign/src/index.js @@ -17,14 +17,13 @@ import DragElement from "./components/pdf/DragElement"; import TagManager from "react-gtm-module"; import Parse from "parse"; import "./polyfills"; +import { serverUrl_fn } from "./constant/appinfo"; import "./i18n"; const appId = process.env.REACT_APP_APPID ? process.env.REACT_APP_APPID : "opensign"; -const serverUrl = process.env.REACT_APP_SERVERURL - ? process.env.REACT_APP_SERVERURL - : window.location.origin + "/api/app"; +const serverUrl = serverUrl_fn(); Parse.initialize(appId); Parse.serverURL = serverUrl; diff --git a/apps/OpenSign/src/primitives/GetReportDisplay.js b/apps/OpenSign/src/primitives/GetReportDisplay.js index f6cc15ca6..d00497c26 100644 --- a/apps/OpenSign/src/primitives/GetReportDisplay.js +++ b/apps/OpenSign/src/primitives/GetReportDisplay.js @@ -28,6 +28,7 @@ import Loader from "./Loader"; import Select from "react-select"; import SubscribeCard from "./SubscribeCard"; import { validplan } from "../json/plansArr"; +import { serverUrl_fn } from "../constant/appinfo"; import { useTranslation } from "react-i18next"; const ReportTable = (props) => { @@ -396,9 +397,7 @@ const ReportTable = (props) => { Templates: "contracts_Template" }; try { - const serverUrl = process.env.REACT_APP_SERVERURL - ? process.env.REACT_APP_SERVERURL - : window.location.origin + "/api/app"; + const serverUrl = serverUrl_fn(); const cls = clsObj[props.ReportName] || "contracts_Document"; const url = serverUrl + `/classes/${cls}/`; const body = diff --git a/apps/OpenSignServer/Utils.js b/apps/OpenSignServer/Utils.js index 99a92dab2..6f6603405 100644 --- a/apps/OpenSignServer/Utils.js +++ b/apps/OpenSignServer/Utils.js @@ -1,9 +1,6 @@ -import axios from 'axios'; import dotenv from 'dotenv'; dotenv.config(); -const appId = process.env.APP_ID; -const serverUrl = process.env.SERVER_URL; export const cloudServerUrl = 'http://localhost:8080/app'; export function customAPIurl() { const url = new URL(cloudServerUrl); @@ -38,17 +35,12 @@ export function replaceMailVaribles(subject, body, variables) { replacedBody = replacedBody.replace(regex, variables[variable]); } } - - const result = { - subject: replacedSubject, - body: replacedBody, - }; + const result = { subject: replacedSubject, body: replacedBody }; return result; } -export const saveFileUsage = async (size, imageUrl, userId) => { +export const saveFileUsage = async (size, fileUrl, userId) => { //checking server url and save file's size - try { const tenantQuery = new Parse.Query('partners_Tenant'); tenantQuery.equalTo('UserId', { @@ -58,53 +50,28 @@ export const saveFileUsage = async (size, imageUrl, userId) => { }); const tenant = await tenantQuery.first(); if (tenant) { - const tenantPtr = { - __type: 'Pointer', - className: 'partners_Tenant', - objectId: tenant.id, - }; - const _tenantPtr = JSON.stringify(tenantPtr); + const tenantPtr = { __type: 'Pointer', className: 'partners_Tenant', objectId: tenant.id }; try { - const res = await axios.get( - `${serverUrl}/classes/partners_TenantCredits?where={"PartnersTenant":${_tenantPtr}}`, - { - headers: { - 'Content-Type': 'application/json', - 'X-Parse-Application-Id': appId, - }, - } - ); - const response = res.data.results; - - let data; - // console.log("response", response); - if (response && response.length > 0) { - data = { - usedStorage: response[0].usedStorage ? response[0].usedStorage + size : size, - }; - await axios.put( - `${serverUrl}/classes/partners_TenantCredits/${response[0].objectId}`, - data, - { - headers: { - 'Content-Type': 'application/json', - 'X-Parse-Application-Id': appId, - }, - } - ); + const tenantCredits = new Parse.Query('partners_TenantCredits'); + tenantCredits.equalTo('PartnersTenant', tenantPtr); + const res = await tenantCredits.first({ useMasterKey: true }); + if (res) { + const response = JSON.parse(JSON.stringify(res)); + const usedStorage = response?.usedStorage ? response.usedStorage + size : size; + const updateCredit = new Parse.Object('partners_TenantCredits'); + updateCredit.id = res.id; + updateCredit.set('usedStorage', usedStorage); + await updateCredit.save(null, { useMasterKey: true }); } else { - data = { usedStorage: size, PartnersTenant: tenantPtr }; - await axios.post(`${serverUrl}/classes/partners_TenantCredits`, data, { - headers: { - 'Content-Type': 'application/json', - 'X-Parse-Application-Id': appId, - }, - }); + const newCredit = new Parse.Object('partners_TenantCredits'); + newCredit.set('usedStorage', size); + newCredit.set('PartnersTenant', tenantPtr); + await newCredit.save(null, { useMasterKey: true }); } } catch (err) { console.log('err in save usage', err); } - saveDataFile(size, imageUrl, tenantPtr); + saveDataFile(size, fileUrl, tenantPtr); } } catch (err) { console.log('err in fetch tenant Id', err); @@ -112,21 +79,13 @@ export const saveFileUsage = async (size, imageUrl, userId) => { }; //function for save fileUrl and file size in particular client db class partners_DataFiles -const saveDataFile = async (size, imageUrl, tenantPtr) => { - const data = { - FileUrl: imageUrl, - FileSize: size, - TenantPtr: tenantPtr, - }; - - // console.log("data save",file, data) +const saveDataFile = async (size, fileUrl, tenantPtr) => { try { - await axios.post(`${serverUrl}/classes/partners_DataFiles`, data, { - headers: { - 'Content-Type': 'application/json', - 'X-Parse-Application-Id': appId, - }, - }); + const newDataFiles = new Parse.Object('partners_DataFiles'); + newDataFiles.set('FileUrl', fileUrl); + newDataFiles.set('FileSize', size); + newDataFiles.set('TenantPtr', tenantPtr); + await newDataFiles.save(null, { useMasterKey: true }); } catch (err) { console.log('error in save usage ', err); } diff --git a/apps/OpenSignServer/cloud/parsefunction/sendMailGmailProvider.js b/apps/OpenSignServer/cloud/parsefunction/sendMailGmailProvider.js index abff5b61c..0a826f701 100644 --- a/apps/OpenSignServer/cloud/parsefunction/sendMailGmailProvider.js +++ b/apps/OpenSignServer/cloud/parsefunction/sendMailGmailProvider.js @@ -28,7 +28,7 @@ const refreshAccessToken = async refreshToken => { // Function to create a raw email message const makeEmail = async (to, from, subject, html, url, pdfName) => { - const protocol = new URL(process.env.SERVER_URL); + const publicUrl = new URL(process.env.SERVER_URL); const htmlContent = html; const boundary = 'boundary_' + Date.now().toString(16); let str; @@ -37,13 +37,15 @@ const makeEmail = async (to, from, subject, html, url, pdfName) => { let Pdf = fs.createWriteStream('test.pdf'); const writeToLocalDisk = () => { return new Promise((resolve, reject) => { - if (useLocal !== 'true' && protocol.hostname !== 'localhost') { + if (useLocal !== 'true') { https.get(url, async function (response) { response.pipe(Pdf); response.on('end', () => resolve('success')); }); } else { - http.get(url, async function (response) { + const path = new URL(url)?.pathname; + const localurl = 'http://localhost:8080' + path; + http.get(localurl, async function (response) { response.pipe(Pdf); response.on('end', () => resolve('success')); }); diff --git a/apps/OpenSignServer/cloud/parsefunction/sendMailv3.js b/apps/OpenSignServer/cloud/parsefunction/sendMailv3.js index eca34a922..eb23be4e4 100644 --- a/apps/OpenSignServer/cloud/parsefunction/sendMailv3.js +++ b/apps/OpenSignServer/cloud/parsefunction/sendMailv3.js @@ -7,7 +7,7 @@ import { smtpenable, smtpsecure, updateMailCount, useLocal } from '../../Utils.j import sendMailGmailProvider from './sendMailGmailProvider.js'; import { createTransport } from 'nodemailer'; async function sendMailProvider(req) { - const protocol = new URL(process.env.SERVER_URL); + const mailgunApiKey = process.env.MAILGUN_API_KEY; try { let transporterSMTP; let mailgunClient; @@ -23,24 +23,25 @@ async function sendMailProvider(req) { }, }); } else { - const mailgun = new Mailgun(formData); - mailgunClient = mailgun.client({ - username: 'api', - key: process.env.MAILGUN_API_KEY, - }); - mailgunDomain = process.env.MAILGUN_DOMAIN; + if (mailgunApiKey) { + const mailgun = new Mailgun(formData); + mailgunClient = mailgun.client({ username: 'api', key: mailgunApiKey }); + mailgunDomain = process.env.MAILGUN_DOMAIN; + } } if (req.params.url) { let Pdf = fs.createWriteStream('test.pdf'); const writeToLocalDisk = () => { return new Promise((resolve, reject) => { - if (useLocal !== 'true' && protocol.hostname !== 'localhost') { + if (useLocal !== 'true') { https.get(req.params.url, async function (response) { response.pipe(Pdf); response.on('end', () => resolve('success')); }); } else { - http.get(req.params.url, async function (response) { + const path = new URL(req.params.url)?.pathname; + const localurl = 'http://localhost:8080' + path; + http.get(localurl, async function (response) { response.pipe(Pdf); response.on('end', () => resolve('success')); }); @@ -108,20 +109,27 @@ async function sendMailProvider(req) { return { status: 'success' }; } } else { - const res = await mailgunClient.messages.create(mailgunDomain, messageParams); - console.log('Res ', res); - if (res.status === 200) { - if (req.params?.extUserId) { - await updateMailCount(req.params.extUserId); + if (mailgunApiKey) { + const res = await mailgunClient.messages.create(mailgunDomain, messageParams); + console.log('Res ', res); + if (res.status === 200) { + if (req.params?.extUserId) { + await updateMailCount(req.params.extUserId); + } + try { + fs.unlinkSync('./exports/certificate.pdf'); + } catch (err) { + console.log('Err in unlink certificate sendmailv3'); + } + return { status: 'success' }; } + } else { try { fs.unlinkSync('./exports/certificate.pdf'); } catch (err) { console.log('Err in unlink certificate sendmailv3'); } - return { - status: 'success', - }; + return { status: 'error' }; } } } @@ -147,13 +155,17 @@ async function sendMailProvider(req) { return { status: 'success' }; } } else { - const res = await mailgunClient.messages.create(mailgunDomain, messageParams); - console.log('Res ', res); - if (res.status === 200) { - if (req.params?.extUserId) { - await updateMailCount(req.params.extUserId); + if (mailgunApiKey) { + const res = await mailgunClient.messages.create(mailgunDomain, messageParams); + console.log('Res ', res); + if (res.status === 200) { + if (req.params?.extUserId) { + await updateMailCount(req.params.extUserId); + } + return { status: 'success' }; } - return { status: 'success' }; + } else { + return { status: 'error' }; } } } diff --git a/apps/OpenSignServer/index.js b/apps/OpenSignServer/index.js index 2f4208db2..8634a231c 100644 --- a/apps/OpenSignServer/index.js +++ b/apps/OpenSignServer/index.js @@ -92,7 +92,7 @@ export const config = { cloud: function () { import('./cloud/main.js'); }, - appId: process.env.APP_ID || 'myAppId', + appId: process.env.APP_ID || 'opensign', logLevel: ['error'], maxLimit: 500, maxUploadSize: '30mb', diff --git a/apps/mongo/Dockerfile b/apps/mongo/Dockerfile index a43e4fac6..1bc9e2b35 100644 --- a/apps/mongo/Dockerfile +++ b/apps/mongo/Dockerfile @@ -2,7 +2,7 @@ FROM mongo:latest # Create a directory to host initialization scripts -RUN mkdir -p /docker-entrypoint-initdb.d +# RUN mkdir -p /docker-entrypoint-initdb.d # Copy default data JSON files to the initialization directory # COPY ./default-data/*.json /docker-entrypoint-initdb.d/ diff --git a/docker-compose.yml b/docker-compose.yml index 3b2bf2520..b7f6455f5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,31 +1,20 @@ -version: '3.7' - services: server: - build: - context: ./apps/OpenSignServer - dockerfile: Dockerfile - image: opensignserver-image + image: opensign/opensignserver:main container_name: OpenSignServer-container - command: /usr/src/app/node_modules/.bin/nodemon server.js - volumes: - - ./apps/OpenSignServer/:/usr/src/app - - /usr/src/app/node_modules ports: - "8080:8080" depends_on: - mongo - env_file: .env + env_file: .env.prod environment: - - NODE_ENV=development + - NODE_ENV=production + - SERVER_URL=${HOST_URL:-https://localhost:3001/app} networks: - app-network mongo: - build: - context: ./apps/mongo - dockerfile: Dockerfile + image: mongo:latest container_name: mongo-container - image: opensign-mongo volumes: - data-volume:/data/db ports: @@ -33,29 +22,37 @@ services: networks: - app-network client: - build: - context: ./apps/OpenSign - dockerfile: Dockerfile - image: opensign-image + image: opensign/opensign:main container_name: OpenSign-container - command: npm start - env_file: .env - volumes: - - ./apps/OpenSign/:/usr/app - - /usr/app/node_modules depends_on: - server + env_file: .env.prod ports: - "3000:3000" networks: - app-network - + caddy: + image: caddy:latest + container_name: caddy-container + ports: + - "3001:3001" + - "80:80" + - "443:443" + - "443:443/udp" + volumes: + - ./Caddyfile:/etc/caddy/Caddyfile + - caddy_data:/data + - caddy_config:/config + networks: + - app-network + environment: + - HOST_URL=${HOST_URL:-localhost:3001} networks: - app-network: - driver: bridge + app-network: + driver: bridge volumes: - data-volume: - node_modules: - web-root: - driver: local + data-volume: + web-root: + caddy_data: + caddy_config: