diff --git a/apps/OpenSign/src/components/pdf/PlaceholderType.js b/apps/OpenSign/src/components/pdf/PlaceholderType.js index 15d911251..db9da0259 100644 --- a/apps/OpenSign/src/components/pdf/PlaceholderType.js +++ b/apps/OpenSign/src/components/pdf/PlaceholderType.js @@ -38,7 +38,7 @@ function PlaceholderType(props) { "December" ]; const validateExpression = (regexValidation) => { - if (textValue) { + if (textValue && regexValidation) { let regexObject = regexValidation; if (props.pos?.options?.validation?.type === "regex") { regexObject = RegexParser(regexValidation); @@ -56,7 +56,7 @@ function PlaceholderType(props) { props.setDraggingEnabled(true); const validateType = props.pos?.options?.validation?.type; let regexValidation; - if (validateType) { + if (validateType && validateType !== "text") { switch (validateType) { case "email": regexValidation = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/; @@ -66,12 +66,8 @@ function PlaceholderType(props) { regexValidation = /^[0-9\s]*$/; validateExpression(regexValidation); break; - case "text": - regexValidation = /^[a-zA-Z\s]+$/; - validateExpression(regexValidation); - break; default: - regexValidation = props.pos?.options.validation.pattern; + regexValidation = props.pos?.options?.validation?.pattern || ""; validateExpression(regexValidation); } } diff --git a/apps/OpenSign/src/components/pdf/WidgetNameModal.js b/apps/OpenSign/src/components/pdf/WidgetNameModal.js index 7bafe12ac..bde504d0e 100644 --- a/apps/OpenSign/src/components/pdf/WidgetNameModal.js +++ b/apps/OpenSign/src/components/pdf/WidgetNameModal.js @@ -53,7 +53,11 @@ const WidgetNameModal = (props) => { } }; const handleChange = (e) => { - setFormdata({ ...formdata, [e.target.name]: e.target.value }); + if (e) { + setFormdata({ ...formdata, [e.target.name]: e.target.value }); + } else { + setFormdata({ ...formdata, textvalidate: "" }); + } }; const handledefaultChange = (e) => { @@ -173,7 +177,10 @@ const WidgetNameModal = (props) => { onChange={(e) => handleChange(e)} onBlur={() => handleBlurRegex()} > - {inputOpt.map((data, ind) => { diff --git a/apps/OpenSignServer/cloud/customRoute/customApp.js b/apps/OpenSignServer/cloud/customRoute/customApp.js index 87ee28f32..aa4dccc89 100644 --- a/apps/OpenSignServer/cloud/customRoute/customApp.js +++ b/apps/OpenSignServer/cloud/customRoute/customApp.js @@ -6,6 +6,7 @@ import uploadFile from './uploadFile.js'; import saveSubscription from './saveSubscription.js'; import saveInvoice from './saveInvoice.js'; import savePayments from './savePayments.js'; +import gooogleauth from './googleauth.js'; export const app = express(); dotenv.config(); @@ -18,5 +19,7 @@ app.post('/file_upload', uploadFile); app.post('/savesubscription', saveSubscription) app.post('/saveinvoice', saveInvoice) app.post('/savepayment', savePayments) +app.post('/googleauth', gooogleauth) + diff --git a/apps/OpenSignServer/cloud/customRoute/googleauth.js b/apps/OpenSignServer/cloud/customRoute/googleauth.js new file mode 100644 index 000000000..818322249 --- /dev/null +++ b/apps/OpenSignServer/cloud/customRoute/googleauth.js @@ -0,0 +1,53 @@ +import axios from 'axios'; +const appId = process.env.APP_ID; +const serverUrl = process.env.SERVER_URL; +export default async function gooogleauth(request, response) { + const code = request.body.code; + const baseUrl = new URL(process.env.SERVER_URL); + // const sessiontoken = request.headers; + // console.log('sessiontoken', sessiontoken); + // console.log('google code', code); + try { + const userRes = await axios.get(serverUrl + '/users/me', { + headers: { + 'X-Parse-Application-Id': appId, + 'X-Parse-Session-Token': request.headers['sessiontoken'], + }, + }); + const userId = userRes.data && userRes.data.objectId; + if (userId) { + const clientId = process.env.GOOGLE_CLIENT_ID; // '918704711393-thhv3re2pfqvve76tgb86ulu1tlpssrk.apps.googleusercontent.com'; + const clientSecret = process.env.GOOGLE_CLIENT_SECRET; //'3NqyXVNm4jUhwNE4D8eVosII'; + const redirectUri = baseUrl.origin || 'http://localhost:3000'; // Should match the redirect URI used in the authorization request + const tokenEndpoint = 'https://oauth2.googleapis.com/token'; + + const params = new URLSearchParams(); + params.append('code', code); + params.append('client_id', clientId); + params.append('client_secret', clientSecret); + params.append('redirect_uri', redirectUri); + params.append('grant_type', 'authorization_code'); + + const res = await axios.post(tokenEndpoint, params); + // console.log('oauthres ', res.data); + const refresh_token = res.data.refresh_token; + const extUserCls = new Parse.Query('contracts_Users'); + extUserCls.equalTo('UserId', { __type: 'Pointer', className: '_User', objectId: userId }); + const extUser = await extUserCls.first({ useMasterKey: true }); + + if (extUser) { + const extUserCls = new Parse.Object('contracts_Users'); + extUserCls.id = extUser.id; + extUserCls.set('google_refresh_token', refresh_token); + const updateExtUser = await extUserCls.save(null, { useMasterKey: true }); + // console.log('updateExtUser ', updateExtUser); + } + return response.status(200).json({ status: 'success!' }); + } else { + return response.status(404).json({ message: 'user not found!' }); + } + } catch (err) { + console.log('err in google auth', err.message); + return response.status(404).json({ message: err.message }); + } +} diff --git a/apps/OpenSignServer/cloud/parsefunction/getUserDetails.js b/apps/OpenSignServer/cloud/parsefunction/getUserDetails.js index 671b91d9d..286a18c6e 100644 --- a/apps/OpenSignServer/cloud/parsefunction/getUserDetails.js +++ b/apps/OpenSignServer/cloud/parsefunction/getUserDetails.js @@ -5,6 +5,7 @@ async function getUserDetails(request) { userQuery.equalTo('Email', request.params.email); userQuery.include('TenantId'); userQuery.include('UserId'); + userQuery.exclude('google_refresh_token') if (userId) { userQuery.equalTo('CreatedBy', { __type: 'Pointer', className: '_User', objectId: userId }); } diff --git a/apps/OpenSignServer/cloud/parsefunction/pdf/PDF.min.js b/apps/OpenSignServer/cloud/parsefunction/pdf/PDF.min.js index 5f73f8c62..6b249f797 100644 --- a/apps/OpenSignServer/cloud/parsefunction/pdf/PDF.min.js +++ b/apps/OpenSignServer/cloud/parsefunction/pdf/PDF.min.js @@ -94,7 +94,7 @@ async function sendCompletedMail(e) { } catch (e) { console.log('error in fetch tenant in signpdf', e.message); } - e = { + g = { extUserId: s.objectId, url: a, from: 'OpenSign™', @@ -102,8 +102,9 @@ async function sendCompletedMail(e) { subject: o, pdfName: r, html: n, + mailProvider: e.mailProvider, }; - await axios.post(serverUrl + '/functions/sendmailv3', e, { + await axios.post(serverUrl + '/functions/sendmailv3', g, { headers: { 'Content-Type': 'application/json', 'X-Parse-Application-Id': APPID, @@ -173,8 +174,9 @@ async function PDF(o) { try { var n = o.params.docId, e = o.params.userId, - l = o.params.isCustomCompletionMail, - d = await axios.get( + l = o.params.isCustomCompletionMail || !1, + d = o.params.mailProvider || '', + c = await axios.get( serverUrl + '/classes/contracts_Document/' + n + '?include=ExtUserPtr,Signers', { headers: { @@ -184,33 +186,33 @@ async function PDF(o) { }, } ), - c = await axios.get(serverUrl + '/users/me', { + p = await axios.get(serverUrl + '/users/me', { headers: { 'X-Parse-Application-Id': APPID, 'X-Parse-Session-Token': o.headers.sessiontoken, }, }); - if (!c.data || !c.data.objectId) return { status: 'error', message: 'This user not allowed!' }; + if (!p.data || !p.data.objectId) return { status: 'error', message: 'This user not allowed!' }; { var a, t, s, - p = JSON.stringify({ objectId: e }); + m = JSON.stringify({ objectId: e }); let r, i; i = e - ? (a = await axios.get(serverUrl + '/classes/contracts_Contactbook?where=' + p, { + ? (a = await axios.get(serverUrl + '/classes/contracts_Contactbook?where=' + m, { headers: { 'X-Parse-Application-Id': APPID, 'X-Parse-Session-Token': o.headers.sessiontoken, }, })).data && 0 < a.data.results.length ? ((r = a), 'contracts_Contactbook') - : ((r = await axios.get(serverUrl + '/classes/contracts_Users?where=' + p, { + : ((r = await axios.get(serverUrl + '/classes/contracts_Users?where=' + m, { headers: { 'X-Parse-Application-Id': APPID, 'X-Parse-Master-Key': masterKEY }, })), 'contracts_Users') : ((t = JSON.stringify({ - UserId: { __type: 'Pointer', className: '_User', objectId: c.data.objectId }, + UserId: { __type: 'Pointer', className: '_User', objectId: p.data.objectId }, })), (s = await axios.get(serverUrl + '/classes/contracts_Users?where=' + t, { headers: { 'X-Parse-Application-Id': APPID, 'X-Parse-Master-Key': masterKEY }, @@ -223,68 +225,67 @@ async function PDF(o) { }, })), 'contracts_Contactbook')); - var m = r.data.results[0].Name, - g = r.data.results[0].Email; + var g = r.data.results[0].Name, + u = r.data.results[0].Email; if (!o.params.pdfFile) return { status: 'error', message: 'Pdf file not present!' }; { let e = Buffer.from(o.params.pdfFile, 'base64'); - var u = process.env.PFX_BASE64, - h = Buffer.from(u, 'base64'), - f = { + var h = process.env.PFX_BASE64, + f = Buffer.from(h, 'base64'), + P = { UserPtr: { __type: 'Pointer', className: i, objectId: r.data.results[0].objectId }, SignedUrl: '', Activity: 'Signed', ipAddress: o.headers['x-real-ip'], }; let a; - var P = (a = - d.data.AuditTrail && 0 < d.data.AuditTrail.length - ? [...d.data.AuditTrail, f] - : [f]).filter(e => 'Signed' === e.Activity); + var y = (a = + c.data.AuditTrail && 0 < c.data.AuditTrail.length + ? [...c.data.AuditTrail, P] + : [P]).filter(e => 'Signed' === e.Activity); let t = !1; !( - (d.data.Signers && 0 < d.data.Signers.length && P.length !== d.data.Signers.length) || + (c.data.Signers && 0 < c.data.Signers.length && y.length !== c.data.Signers.length) || !(t = !0) ); - var y, + var v, b, - v, U, I, w, - D = `exported_file_${Math.floor(5e3 * Math.random())}.pdf`, - S = './exports/' + D; + D, + S = `exported_file_${Math.floor(5e3 * Math.random())}.pdf`, + _ = './exports/' + S; let s = e.length; s = ( t - ? ((y = d.data.Signers?.map(e => e.Name + ' <' + e.Email + '>')), + ? ((v = c.data.Signers?.map(e => e.Name + ' <' + e.Email + '>')), (e = - y && 0 < y.length + v && 0 < v.length ? ((b = await PDFDocument.load(e)), pdflibAddPlaceholder({ pdfDoc: b, - reason: 'Digitally signed by OpenSign for ' + y?.join(', '), + reason: 'Digitally signed by OpenSign for ' + v?.join(', '), location: 'n/a', signatureLength: 15e3, }), - (v = await b.save()), - Buffer.from(v)) - : ((U = await PDFDocument.load(e)), + (U = await b.save()), + Buffer.from(U)) + : ((I = await PDFDocument.load(e)), pdflibAddPlaceholder({ - pdfDoc: U, - reason: 'Digitally signed by OpenSign for ' + m + ' <' + g + '>', + pdfDoc: I, + reason: 'Digitally signed by OpenSign for ' + g + ' <' + u + '>', location: 'n/a', signatureLength: 15e3, }), - (I = await U.save()), - Buffer.from(I))), - (w = await new SignPDF(e, h).signPDF()), - fs.writeFileSync(S, w), - w) - : (fs.writeFileSync(S, e), e) + (w = await I.save()), + Buffer.from(w))), + (D = await new SignPDF(e, f).signPDF()), + fs.writeFileSync(_, D), + D) + : (fs.writeFileSync(_, e), e) ).length; - var _, - A, + var A, x, E, j, @@ -292,56 +293,62 @@ async function PDF(o) { F, C, T, - N = await uploadFile(D, S); - if (N && N.imageUrl) + N, + M = await uploadFile(S, _); + if (M && M.imageUrl) return ( - (_ = await updateDoc( + (A = await updateDoc( o.params.docId, - N.imageUrl, + M.imageUrl, r.data.results[0].objectId, o.headers['x-real-ip'], - d.data, + c.data, i )), - sendDoctoWebhook(d, N.imageUrl, 'signed', r?.data.results?.[0]), - saveFileUsage(s, N.imageUrl, c.data.objectId), - _ && - _.isCompleted && - ((A = { ...d.data, AuditTrail: _.AuditTrail }), - (x = await GenerateCertificate(A)), - (E = await PDFDocument.load(x)), + sendDoctoWebhook(c, M.imageUrl, 'signed', r?.data.results?.[0]), + saveFileUsage(s, M.imageUrl, p.data.objectId), + A && + A.isCompleted && + ((x = { ...c.data, AuditTrail: A.AuditTrail }), + (E = await GenerateCertificate(x)), + (j = await PDFDocument.load(E)), pdflibAddPlaceholder({ - pdfDoc: E, + pdfDoc: j, reason: 'Digitally signed by OpenSign.', location: 'n/a', signatureLength: 15e3, }), - (j = await E.save()), - (k = Buffer.from(j)), - (F = await new SignPDF(k, h).signPDF()), - fs.writeFileSync('./exports/certificate.pdf', F), - (T = { - CertificateUrl: (C = await uploadFile( + (k = await j.save()), + (F = Buffer.from(k)), + (C = await new SignPDF(F, f).signPDF()), + fs.writeFileSync('./exports/certificate.pdf', C), + (N = { + CertificateUrl: (T = await uploadFile( 'certificate.pdf', './exports/certificate.pdf' )).imageUrl, }), - await axios.put(serverUrl + '/classes/contracts_Document/' + n, T, { + await axios.put(serverUrl + '/classes/contracts_Document/' + n, N, { headers: { 'Content-Type': 'application/json', 'X-Parse-Application-Id': APPID, 'X-Parse-Master-Key': masterKEY, }, }), - d.data.IsSendMail && !1 === d.data.IsSendMail + c.data.IsSendMail && !1 === c.data.IsSendMail ? console.log("don't send mail") - : sendCompletedMail({ url: N.imageUrl, isCustomMail: l, doc: d.data }), - saveFileUsage(k.length, C.imageUrl, c.data.objectId), - sendDoctoWebhook(d, N.imageUrl, 'completed')), - fs.unlinkSync(S), - console.log('New Signed PDF created called: ' + S), - 'success' === _.message - ? { status: 'success', data: N.imageUrl } + : sendCompletedMail({ + url: M.imageUrl, + isCustomMail: l, + doc: c.data, + mailProvider: d, + }), + saveFileUsage(F.length, T.imageUrl, p.data.objectId), + sendDoctoWebhook(c, M.imageUrl, 'completed')), + fs.unlinkSync(_), + console.log('New Signed PDF created called: ' + _), + 'success' === A.message + ? { status: 'success', data: M.imageUrl } : { status: 'error', message: 'Please provide required parameters!' } ); } diff --git a/apps/OpenSignServer/cloud/parsefunction/sendMailGmailProvider.js b/apps/OpenSignServer/cloud/parsefunction/sendMailGmailProvider.js new file mode 100644 index 000000000..35dc0fc0b --- /dev/null +++ b/apps/OpenSignServer/cloud/parsefunction/sendMailGmailProvider.js @@ -0,0 +1,141 @@ +import axios from 'axios'; +import { google } from 'googleapis'; +import fs from 'node:fs'; +import https from 'https'; +const clientId = process.env.GOOGLE_CLIENT_ID; +const clientSecret = process.env.GOOGLE_CLIENT_SECRET; +// Function to create a Gmail client +const createGmailClient = accessToken => { + const oauth2Client = new google.auth.OAuth2(); + oauth2Client.setCredentials({ access_token: accessToken }); + return google.gmail({ version: 'v1', auth: oauth2Client }); +}; + +// Function to exchange refresh token for new access token +const refreshAccessToken = async refreshToken => { + const tokenEndpoint = 'https://oauth2.googleapis.com/token'; + const params = new URLSearchParams(); + params.append('refresh_token', refreshToken); + params.append('client_id', clientId); + params.append('client_secret', clientSecret); + params.append('grant_type', 'refresh_token'); + + const response = await axios.post(tokenEndpoint, params); + return response.data.access_token; +}; + +// Function to create a raw email message +const makeEmail = async (to, from, subject, html, url, pdfName) => { + const htmlContent = html; + const boundary = 'boundary_' + Date.now().toString(16); + let str; + if (url) { + let attachments; + let Pdf = fs.createWriteStream('test.pdf'); + const writeToLocalDisk = () => { + return new Promise((resolve, reject) => { + https.get(url, async function (response) { + response.pipe(Pdf); + response.on('end', () => resolve('success')); + }); + }); + }; + // `writeToLocalDisk` is used to create pdf file from doc url + const ress = await writeToLocalDisk(); + if (ress) { + const file = { + filename: `${pdfName}.pdf` || 'exported.pdf', + type: 'application/pdf', + path: Pdf.path, + }; + + // `certificateBuffer` used to create buffer from pdf file + try { + const certificate = { + filename: 'certificate.pdf', + type: 'application/pdf', + path: './exports/certificate.pdf', + }; + attachments = [file, certificate]; + } catch (err) { + attachments = [file]; + console.log('Err in read certificate sendmailv3', err); + } + } + const attachmentParts = attachments.map(attachment => { + const content = fs.readFileSync(attachment.path); + const encodedContent = content.toString('base64'); + return [ + `Content-Type: ${attachment.type}\n`, + 'MIME-Version: 1.0\n', + `Content-Disposition: attachment; filename="${attachment.filename}"\n`, + `Content-Transfer-Encoding: base64\n\n`, + `${encodedContent}\n`, + ].join(''); + }); + + const attachmentBody = attachmentParts.join(`\n--${boundary}\n`); + + str = [ + 'Content-Type: multipart/mixed; boundary="' + boundary + '"\n', + 'MIME-Version: 1.0\n', + `To: ${to}\n`, + `From: ${from}\n`, + `Subject: ${subject}\n\n`, + '--' + boundary + '\n', + 'Content-Type: text/html; charset="UTF-8"\n', + 'MIME-Version: 1.0\n\n', + `${htmlContent}\n\n`, + `\n--${boundary}\n`, + attachmentBody, + '--' + boundary + '--', + ].join(''); + } else { + str = [ + 'Content-Type: multipart/mixed; boundary="' + boundary + '"\n', + 'MIME-Version: 1.0\n', + `To: ${to}\n`, + `From: ${from}\n`, + `Subject: ${subject}\n\n`, + '--' + boundary + '\n', + 'Content-Type: text/html; charset="UTF-8"\n', + 'MIME-Version: 1.0\n\n', + `${htmlContent}\n\n`, + '--' + boundary + '--', + ].join(''); + } + + const encodedMail = Buffer.from(str).toString('base64').replace(/\+/g, '-').replace(/\//g, '_'); + return encodedMail; +}; +export default async function sendMailGmailProvider(_extRes, template) { + const { sender, receiver, subject, html, url, pdfName } = template; + + if (_extRes) { + const refresh_token = _extRes.google_refresh_token; + // generate access token + const access_token = await refreshAccessToken(refresh_token); + + try { + // Construct email message + const from = sender || _extRes.Email || 'me'; + const to = receiver; + const email = await makeEmail(to, from, subject, html, url, pdfName); + // Update Gmail client with new access token + const newGmail = createGmailClient(access_token); + // sending email with new client + const response = await newGmail.users.messages.send({ + userId: 'me', + requestBody: { + raw: email, + }, + }); + // console.log('response ', response); + + return { code: 200, message: 'Email sent successfully' }; + } catch (error) { + console.error('Error sending email:', error); + return { code: 500, message: 'Failed to send email ' + error }; + } + } +} diff --git a/apps/OpenSignServer/cloud/parsefunction/sendMailv3.js b/apps/OpenSignServer/cloud/parsefunction/sendMailv3.js index 08a511d2e..c09694a4d 100644 --- a/apps/OpenSignServer/cloud/parsefunction/sendMailv3.js +++ b/apps/OpenSignServer/cloud/parsefunction/sendMailv3.js @@ -2,10 +2,9 @@ import fs from 'node:fs'; import https from 'https'; import formData from 'form-data'; import Mailgun from 'mailgun.js'; -import { createTransport } from 'nodemailer'; import { updateMailCount } from '../../Utils.js'; - -async function sendmailv3(req) { +import sendMailGmailProvider from './sendMailGmailProvider.js'; +async function sendMailProvider(req) { try { let transporterSMTP; let mailgunClient; @@ -98,9 +97,7 @@ async function sendmailv3(req) { } catch (err) { console.log('Err in unlink certificate sendmailv3'); } - return { - status: 'success', - }; + return { status: 'success' }; } } else { const res = await mailgunClient.messages.create(mailgunDomain, messageParams); @@ -141,9 +138,7 @@ async function sendmailv3(req) { if (req.params?.extUserId) { await updateMailCount(req.params.extUserId); } - return { - status: 'success', - }; + return { status: 'success' }; } } else { const res = await mailgunClient.messages.create(mailgunDomain, messageParams); @@ -152,9 +147,7 @@ async function sendmailv3(req) { if (req.params?.extUserId) { await updateMailCount(req.params.extUserId); } - return { - status: 'success', - }; + return { status: 'success' }; } } } @@ -165,5 +158,45 @@ async function sendmailv3(req) { } } } +async function sendmailv3(req) { + const mailProvider = req.params.mailProvider || 'default'; + if (mailProvider) { + try { + const extUserId = req.params.extUserId || ''; + const pdfName = req.params.pdfName || ''; + const template = { + sender: req.params.from || '', + receiver: req.params.recipient, + subject: req.params.subject, + html: req.params.html || '', + url: req.params.url ? req.params.url : '', + pdfName: pdfName, + }; + const extUserQuery = new Parse.Query('contracts_Users'); + const extRes = await extUserQuery.get(extUserId, { useMasterKey: true }); + if (extRes) { + const _extRes = JSON.parse(JSON.stringify(extRes)); + if (_extRes.google_refresh_token && mailProvider === 'google') { + const res = await sendMailGmailProvider(_extRes, template); + if (res.code === 200) { + await updateMailCount(req.params.extUserId); + return { status: 'success' }; + } else { + return { status: 'error' }; + } + } else { + const nonCustomMail = await sendMailProvider(req); + return nonCustomMail; + } + } + } catch (err) { + console.log('err in send custom mail', err); + return { status: 'error' }; + } + } else { + const nonCustomMail = await sendMailProvider(req); + return nonCustomMail; + } +} export default sendmailv3; diff --git a/apps/OpenSignServer/package-lock.json b/apps/OpenSignServer/package-lock.json index 63b14870e..4d464842a 100644 --- a/apps/OpenSignServer/package-lock.json +++ b/apps/OpenSignServer/package-lock.json @@ -18,6 +18,7 @@ "express-sse": "^0.5.3", "form-data": "^4.0.0", "generate-api-key": "^1.0.2", + "googleapis": "^134.0.0", "jsonschema": "^1.4.1", "mailgun.js": "^10.2.1", "mongoose": "^8.2.2", @@ -43,7 +44,8 @@ "mongodb-runner": "^5.5.4", "nodemon": "^3.1.0", "nyc": "15.1.0", - "prettier": "^3.2.5" + "prettier": "^3.2.5", + "uglify-js": "^3.17.4" }, "engines": { "node": ">=12.22.10 <21" @@ -3678,7 +3680,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", - "optional": true, "dependencies": { "debug": "^4.3.4" }, @@ -4001,7 +4002,6 @@ "version": "9.1.2", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", - "optional": true, "engines": { "node": "*" } @@ -5455,16 +5455,16 @@ } }, "node_modules/express": { - "version": "4.18.3", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.3.tgz", - "integrity": "sha512-6VyCijWQ+9O7WuVMTRBTl+cjNNIzD5cY5mQ1WM8r/LEkI2u8EYpOotESNwzNlyCn3g+dmjKYI6BmNneSr/FSRw==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", "body-parser": "1.20.2", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.5.0", + "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -5511,6 +5511,14 @@ "resolved": "https://registry.npmjs.org/express-sse/-/express-sse-0.5.3.tgz", "integrity": "sha512-DJF0nofFGq0IXJLGq95hfrryP3ZprVAVpyZUnmAk6QhHnm7zCzsHBNFP0i4FKFo2XjOf+JiYUKjT7jQhIeljpg==" }, + "node_modules/express/node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/express/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -6058,7 +6066,6 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.3.0.tgz", "integrity": "sha512-p+ggrQw3fBwH2F5N/PAI4k/G/y1art5OxKpb2J2chwNNHM4hHuAOtivjPuirMF4KNKwTTUal/lPfL2+7h2mEcg==", - "optional": true, "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", @@ -6073,7 +6080,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "optional": true, "engines": { "node": ">=8" }, @@ -6272,10 +6278,9 @@ } }, "node_modules/google-auth-library": { - "version": "9.7.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.7.0.tgz", - "integrity": "sha512-I/AvzBiUXDzLOy4iIZ2W+Zq33W4lcukQv1nl7C8WUA6SQwyQwUwu3waNmWNAvzds//FG8SZ+DnKnW/2k6mQS8A==", - "optional": true, + "version": "9.8.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.8.0.tgz", + "integrity": "sha512-TJJXFzMlVGRlIH27gYZ6XXyPf5Y3OItsKFfefsDAafNNywYRTkei83nEO29IrYj8GtdHWU78YnW+YZdaZaXIJA==", "dependencies": { "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", @@ -6292,7 +6297,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==", - "optional": true, "dependencies": { "gaxios": "^6.0.0", "json-bigint": "^1.0.0" @@ -6337,6 +6341,46 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/googleapis": { + "version": "134.0.0", + "resolved": "https://registry.npmjs.org/googleapis/-/googleapis-134.0.0.tgz", + "integrity": "sha512-o8LhD1754W6MHWtpwAPeP1WUHgNxuMxCnLMDFlMKAA5kCMTNqX9/eaTXnkkAIv6YRfoKMQ6D1vyR6/biXuhE9g==", + "dependencies": { + "google-auth-library": "^9.0.0", + "googleapis-common": "^7.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/googleapis-common": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/googleapis-common/-/googleapis-common-7.1.0.tgz", + "integrity": "sha512-p3KHiWDBBWJEXk6SYauBEvxw5+UmRy7k2scxGtsNv9eHsTbpopJ3/7If4OrNnzJ9XMLg3IlyQXpVp8YPQsStiw==", + "dependencies": { + "extend": "^3.0.2", + "gaxios": "^6.0.3", + "google-auth-library": "^9.7.0", + "qs": "^6.7.0", + "url-template": "^2.0.8", + "uuid": "^9.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/googleapis-common/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -6401,7 +6445,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", - "optional": true, "dependencies": { "gaxios": "^6.0.0", "jws": "^4.0.0" @@ -6613,7 +6656,6 @@ "version": "7.0.4", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", - "optional": true, "dependencies": { "agent-base": "^7.0.2", "debug": "4" @@ -7370,7 +7412,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", - "optional": true, "dependencies": { "bignumber.js": "^9.0.0" } @@ -7522,7 +7563,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", - "optional": true, "dependencies": { "buffer-equal-constant-time": "1.0.1", "ecdsa-sig-formatter": "1.0.11", @@ -7549,7 +7589,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", - "optional": true, "dependencies": { "jwa": "^2.0.0", "safe-buffer": "^5.0.1" @@ -11039,9 +11078,9 @@ } }, "node_modules/tar": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", - "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", "dev": true, "dependencies": { "chownr": "^2.0.0", @@ -11365,6 +11404,18 @@ "is-typedarray": "^1.0.0" } }, + "node_modules/uglify-js": { + "version": "3.17.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", + "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", + "dev": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/unbzip2-stream": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", @@ -11476,6 +11527,11 @@ "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" }, + "node_modules/url-template": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", + "integrity": "sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw==" + }, "node_modules/url/node_modules/punycode": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", diff --git a/apps/OpenSignServer/package.json b/apps/OpenSignServer/package.json index 26b9b9789..f3773756c 100644 --- a/apps/OpenSignServer/package.json +++ b/apps/OpenSignServer/package.json @@ -27,6 +27,7 @@ "express-sse": "^0.5.3", "form-data": "^4.0.0", "generate-api-key": "^1.0.2", + "googleapis": "^134.0.0", "jsonschema": "^1.4.1", "mailgun.js": "^10.2.1", "mongoose": "^8.2.2", @@ -53,7 +54,8 @@ "mongodb-runner": "^5.5.4", "nodemon": "^3.1.0", "nyc": "15.1.0", - "prettier": "^3.2.5" + "prettier": "^3.2.5", + "uglify-js": "^3.17.4" }, "engines": { "node": ">=12.22.10 <21"