Skip to content

Commit 81af6a6

Browse files
Merge pull request #15 from OpenSignLabs/staging
update
2 parents d208a90 + c326849 commit 81af6a6

File tree

12 files changed

+868
-788
lines changed

12 files changed

+868
-788
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,5 @@ npm-debug.log*
2323
yarn-debug.log*
2424
yarn-error.log*
2525
apps/OpenSign/public/mfbuild/*
26-
microfrontends/SignDocuments/build/*
26+
microfrontends/SignDocuments/build/*
27+
apps/OpenSignServer/files/files/*

INSTALLATION.md

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,24 @@ openssl pkcs12 -inkey ./cert/local_dev.key -in ./cert/local_dev.crt -export -out
127127
openssl base64 -in ./cert/local_dev.pfx -out ./cert/base64_pfx
128128
```
129129

130-
#Build Local Environment
130+
# CORS Configuration
131131

132-
Below are the steps to follow -
132+
As document storage is delegated to S3-compatible services that reside in a different host than the OpenSign one, document operations (loading, storing, deleting) are subject to [Cross-Origin Resource Sharing](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing) restriction policies; as a consequence, OpenSign app may fail with (browser console) errors like the following:
133+
```
134+
Access to fetch at 'https://foo.nyc3.digitaloceanspaces.com/exported_file_4627_0000-00-00T00%3A45%3A43.344Z.pdf'
135+
from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header
136+
is present on the requested resource. If an opaque response serves your needs, set the request's mode to
137+
'no-cors' to fetch the resource with CORS disabled.
138+
```
139+
140+
In order to address this, your document storage system must be instructed to accept requests from other hosts; below the relevant documentation links:
141+
- [How to Configure CORS on DigitalOcean Spaces](https://docs.digitalocean.com/products/spaces/how-to/configure-cors/)
142+
- [Configuring cross-origin resource sharing on AWS S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/enabling-cors-examples.html)
143+
144+
# Build Local Environment
145+
146+
Command to build project -
133147
- Execute `make build`
148+
149+
Command to run project -
150+
- Execute `make run`

Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
11
build:
2+
cp .env.local_dev .env
3+
rm -rf apps/OpenSign/public/mfbuild
4+
cd microfrontends/SignDocuments && npm install && npm run build
5+
docker compose up -d
6+
7+
run:
28
cp .env.local_dev .env
39
docker compose up -d

apps/OpenSign/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,5 @@ EXPOSE 3000
2121
# ENV NODE_ENV production
2222

2323
# Run the application
24-
CMD ["npm", "start"]
24+
ENTRYPOINT npm run start-dev
2525

apps/OpenSign/public/mfbuild/.gitkeep

Whitespace-only changes.

apps/OpenSignServer/cloud/customRoute/uploadFile.js

Lines changed: 52 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ import multerS3 from 'multer-s3';
44
import aws from 'aws-sdk';
55
import dotenv from 'dotenv';
66
dotenv.config();
7+
8+
function sanitizeFileName(fileName) {
9+
// Remove spaces and invalid characters
10+
return fileName.replace(/[^a-zA-Z0-9._-]/g, '');
11+
}
12+
713
async function uploadFile(req, res) {
814
try {
915
//--size extended to 100 mb
@@ -50,16 +56,28 @@ async function uploadFile(req, res) {
5056
region: process.env.DO_REGION,
5157
});
5258

53-
// const s3 = new aws.S3();
54-
const upload = multer({
55-
fileFilter: function (req, file, cb) {
56-
if (accepted_extensions.some(ext => file.originalname.toLowerCase().endsWith('.' + ext))) {
57-
return cb(null, true);
59+
const parseBaseUrl = process.env.SERVER_URL;
60+
const parseAppId = process.env.APP_ID;
61+
62+
if (process.env.USE_LOCAL == "TRUE") {
63+
var fileStorage = multer.diskStorage({
64+
destination: function(req, file, cb) {
65+
cb(null, "files/files");
66+
},
67+
metadata: function (req, file, cb) {
68+
cb(null, { fieldName: 'OPENSIGN_METADATA' });
69+
},
70+
filename: function(req, file, cb) {
71+
let filename = file.originalname;
72+
let newFileName = filename.split('.')[0];
73+
let extension = filename.split('.')[1];
74+
newFileName = sanitizeFileName(newFileName + '_' + new Date().toISOString() + '.' + extension)
75+
console.log(newFileName);
76+
cb(null, newFileName);
5877
}
59-
// otherwise, return error
60-
return cb('Only ' + accepted_extensions.join(', ') + ' files are allowed!');
61-
},
62-
storage: multerS3({
78+
});
79+
} else {
80+
var fileStorage = multerS3({
6381
acl: 'public-read',
6482
s3,
6583
bucket: DO_SPACE,
@@ -69,14 +87,25 @@ async function uploadFile(req, res) {
6987
key: function (req, file, cb) {
7088
//console.log(file);
7189
let filename = file.originalname;
72-
let filenam = filename.split('.')[0];
90+
let newFileName = filename.split('.')[0];
7391
let extension = filename.split('.')[1];
74-
filenam = filenam + '_' + new Date().toISOString() + '.' + extension;
75-
console.log(filenam);
76-
cb(null, filenam);
77-
},
78-
}),
92+
newFileName = sanitizeFileName(newFileName + '_' + new Date().toISOString() + '.' + extension)
93+
console.log(newFileName);
94+
cb(null, newFileName);
95+
}
96+
});
97+
}
7998

99+
// const s3 = new aws.S3();
100+
const upload = multer({
101+
fileFilter: function (req, file, cb) {
102+
if (accepted_extensions.some(ext => file.originalname.toLowerCase().endsWith('.' + ext))) {
103+
return cb(null, true);
104+
}
105+
// otherwise, return error
106+
return cb('Only ' + accepted_extensions.join(', ') + ' files are allowed!');
107+
},
108+
storage: fileStorage,
80109
limits: { fileSize: size },
81110
}).single('file');
82111

@@ -93,7 +122,14 @@ async function uploadFile(req, res) {
93122
const status = 'Success';
94123
//res.header("Access-Control-Allow-Headers", "Content-Type");
95124
//res.setHeader("Access-Control-Allow-Origin", "*");
96-
return res.json({ status, imageUrl: req.file.location });
125+
if (process.env.USE_LOCAL == "TRUE") {
126+
console.log(req.file);
127+
var fileUrl = `${parseBaseUrl}/files/${parseAppId}/${req.file.filename}`;
128+
} else {
129+
var fileUrl = req.file.location;
130+
}
131+
132+
return res.json({ status, imageUrl: fileUrl });
97133
});
98134
} catch (err) {
99135
console.log('Exeption in query ' + err.stack);

microfrontends/SignDocuments/src/Component/component/header.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ function Header({
3737
}) {
3838
const isMobile = window.innerWidth < 767;
3939
const navigate = useNavigate();
40-
40+
const isGuestSigner = localStorage.getItem("isGuestSigner");
4141
//for go to previous page
4242
function previousPage() {
4343
changePage(-1);
@@ -81,14 +81,16 @@ function Header({
8181

8282
return (
8383
<div
84-
style={{ paddingBottom: "5px", paddingTop: "5px" }}
84+
style={{ padding: !isGuestSigner && "5px 0px 5px 0px" }}
8585
className="mobileHead"
8686
>
8787
{isMobile && isShowHeader ? (
8888
<div
8989
id="navbar"
90-
className="stickyHead"
91-
style={{ width: window.innerWidth - 30 + "px" }}
90+
className={isGuestSigner ? "stickySignerHead" : "stickyHead"}
91+
style={{
92+
width: isGuestSigner ? window.innerWidth : window.innerWidth - 30 + "px"
93+
}}
9294
>
9395
<div className="preBtn2">
9496
<div

microfrontends/SignDocuments/src/Component/component/renderPdf.js

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,42 @@ function RenderPdf({
4242
const isMobile = window.innerWidth < 767;
4343
const newWidth = window.innerWidth;
4444
const scale = isMobile ? pdfOriginalWidth / newWidth : 1;
45-
//function for render placeholder block over pdf document
45+
46+
// handle signature block width and height according to screen
47+
const posWidth = (pos) => {
48+
let width;
49+
if (isMobile) {
50+
if (!pos.isMobile) {
51+
width = pos.Width / scale ? pos.Width / scale : 150 / scale;
52+
return width;
53+
} else {
54+
width = pos.Width ? pos.Width : 150;
55+
return width;
56+
}
57+
} else {
58+
width = pos.Width ? pos.Width : 150;
59+
return width;
60+
}
61+
};
62+
const posHeight = (pos) => {
63+
let width;
64+
if (isMobile) {
65+
if (!pos.isMobile) {
66+
width = pos.Height / scale ? pos.Height / scale : 60 / scale;
67+
return width;
68+
} else {
69+
width = pos.Height ? pos.Height : 60;
70+
return width;
71+
}
72+
} else {
73+
width = pos.Height ? pos.Height : 60;
74+
return width;
75+
}
76+
};
77+
//check isGuestSigner is present in local if yes than handle login flow header in mobile view
78+
const isGuestSigner = localStorage.getItem("isGuestSigner");
4679

80+
//function for render placeholder block over pdf document
4781
const checkSignedSignes = (data) => {
4882
const checkSign = signedSigners.filter(
4983
(sign) => sign.objectId === data.signerObjId
@@ -56,7 +90,7 @@ function RenderPdf({
5690
if (isMobile) {
5791
//if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale
5892
if (!pos.isMobile) {
59-
return pos.xPosition / scale;
93+
return pos.xPosition / scale - 20;
6094
}
6195
//pos.isMobile true -- placeholder save from mobile view(small device) handle position in mobile view(small screen) view divided by scale
6296
else {
@@ -134,8 +168,8 @@ function RenderPdf({
134168
borderWidth: "0.2px"
135169
}}
136170
size={{
137-
width: pos.Width ? pos.Width : 150,
138-
height: pos.Height ? pos.Height : 60
171+
width: posWidth(pos),
172+
height: posHeight(pos)
139173
}}
140174
lockAspectRatio={pos.Width && 2.5}
141175
default={{
@@ -205,8 +239,8 @@ function RenderPdf({
205239
y: yPos(pos)
206240
}}
207241
size={{
208-
width: pos.Width ? pos.Width : 150,
209-
height: pos.Height ? pos.Height : 60
242+
width: posWidth(pos),
243+
height: posHeight(pos)
210244
}}
211245
lockAspectRatio={pos.Width ? pos.Width / pos.Height : 2.5}
212246
>
@@ -235,7 +269,8 @@ function RenderPdf({
235269
{isMobile && scale ? (
236270
<div
237271
style={{
238-
border: "0.1px solid #ebe8e8"
272+
border: "0.1px solid #ebe8e8",
273+
marginTop: isGuestSigner && "30px"
239274
}}
240275
ref={drop}
241276
id="container"
@@ -294,12 +329,11 @@ function RenderPdf({
294329
borderWidth: "0.2px"
295330
}}
296331
size={{
297-
width: pos.Width ? pos.Width : 150,
298-
height: pos.Height ? pos.Height : 60
332+
width: posWidth(pos),
333+
height: posHeight(pos)
299334
}}
300335
lockAspectRatio={pos.Width && 2.5}
301336
//if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divide by scale
302-
303337
//else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale
304338
default={{
305339
x: !pos.isMobile
@@ -361,14 +395,13 @@ function RenderPdf({
361395
borderWidth: "0.2px"
362396
}}
363397
size={{
364-
width: pos.Width ? pos.Width : 150,
365-
height: pos.Height ? pos.Height : 60
398+
width: posWidth(pos),
399+
height: posHeight(pos)
366400
}}
367401
disableDragging={true}
368402
default={{
369403
//if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divide by scale
370404
//else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale
371-
372405
x: !pos.isMobile
373406
? pos.xPosition / scale
374407
: pos.xPosition * (pos.scale / scale) - 50,
@@ -1281,4 +1314,4 @@ function RenderPdf({
12811314
);
12821315
}
12831316

1284-
export default RenderPdf;
1317+
export default RenderPdf;

microfrontends/SignDocuments/src/Component/login.js

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,15 @@ function Login() {
3838

3939
const handleChange = (event) => {
4040
const { value } = event.target;
41-
4241
setOTP(value);
4342
};
4443

4544
//send email OTP function
46-
4745
const SendOtp = async (e) => {
4846
const serverUrl =
4947
localStorage.getItem("baseUrl") && localStorage.getItem("baseUrl");
50-
5148
const parseId =
5249
localStorage.getItem("parseAppId") && localStorage.getItem("parseAppId");
53-
5450
if (serverUrl && localStorage) {
5551
setLoading(true);
5652
e.preventDefault();
@@ -84,13 +80,10 @@ function Login() {
8480
e.preventDefault();
8581
const serverUrl =
8682
localStorage.getItem("baseUrl") && localStorage.getItem("baseUrl");
87-
8883
const parseId =
8984
localStorage.getItem("parseAppId") && localStorage.getItem("parseAppId");
90-
9185
if (OTP) {
9286
setLoading(true);
93-
9487
try {
9588
let url = `${serverUrl}functions/AuthLoginAsMail/`;
9689
const headers = {
@@ -102,7 +95,6 @@ function Login() {
10295
otp: OTP
10396
};
10497
let user = await axios.post(url, body, { headers: headers });
105-
10698
if (user.data.result === "Invalid Otp") {
10799
alert("Invalid Otp");
108100
setLoading(false);
@@ -114,10 +106,12 @@ function Login() {
114106
localStorage.setItem("UserInformation", JSON.stringify(_user));
115107
localStorage.setItem("username", _user.name);
116108
localStorage.setItem("accesstoken", _user.sessionToken);
109+
//save isGuestSigner true in local to handle login flow header in mobile view
110+
localStorage.setItem("isGuestSigner", true);
117111
setLoading(false);
118-
//navigate user to on signature page
119-
// navigate(`/recipientSignPdf/${id}/${contactBookId}`);
120-
navigate(`/loadmf/signmicroapp/recipientSignPdf/${id}/${contactBookId}`);
112+
navigate(
113+
`/loadmf/signmicroapp/recipientSignPdf/${id}/${contactBookId}`
114+
);
121115
}
122116
} catch (error) {}
123117
} else {
@@ -173,9 +167,7 @@ function Login() {
173167
<span className="KNLO">
174168
Verification code is sent to your email
175169
</span>
176-
<div className="card card-box"
177-
style={{borderRadius:"0px"}}
178-
>
170+
<div className="card card-box" style={{ borderRadius: "0px" }}>
179171
<div className="card-body">
180172
<input
181173
type="email"
@@ -190,7 +182,6 @@ function Login() {
190182
<div className="btnContainer">
191183
{loading ? (
192184
<button
193-
// className="btn btn-info loadinBtn "
194185
type="button"
195186
style={{
196187
background: themeColor(),
@@ -214,15 +205,7 @@ function Login() {
214205
color: "white",
215206
marginLeft: "0px !important"
216207
}}
217-
// className="btn btn-sm otpButton"
218208
onClick={(e) => SendOtp(e)}
219-
// style={{
220-
// marginBottom: "4px",
221-
// width: "210px",
222-
// background: themeColor(),
223-
// color: "white",
224-
// fontWeight: "600"
225-
// }}
226209
>
227210
Send OTP
228211
</button>

0 commit comments

Comments
 (0)