feat: check latex dependency on start & add security headers
This commit is contained in:
parent
b359bb049e
commit
fecf789f58
14
app.js
14
app.js
|
@ -2,13 +2,25 @@ const express = require('express');
|
|||
const config = require('./config');
|
||||
const app = express();
|
||||
const path = require('path');
|
||||
const { verifyLatexBinary } = require('./helpers/latex');
|
||||
const helmet = require('helmet');
|
||||
|
||||
app.set('view engine', 'ejs');
|
||||
app.set('views', path.join(__dirname, 'templates'));
|
||||
app.use('/', express.static(path.join(__dirname, 'public')));
|
||||
|
||||
// TODO: add security headers
|
||||
app.use(helmet({
|
||||
contentSecurityPolicy: {
|
||||
directives: {
|
||||
"script-src": ["'self'", "'unsafe-inline'", "https://unpkg.com/feather-icons"],
|
||||
"script-src-attr": ["'self'", "'unsafe-inline'"]
|
||||
},
|
||||
},
|
||||
}))
|
||||
|
||||
app.use('/', require('./controllers/index'));
|
||||
|
||||
// check if pdf binaries are installed
|
||||
verifyLatexBinary();
|
||||
|
||||
app.listen(config.port, () => console.log(`pdfgen is listening on port ${config.port}`))
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
const { spawnSync } = require('child_process');
|
||||
|
||||
function verifyLatexBinary() {
|
||||
const { error } = spawnSync('latex', ['--version'], {encoding: 'utf8'});
|
||||
if (error) {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
} else {
|
||||
console.log('latex binaries seem ok');
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { verifyLatexBinary };
|
|
@ -12,6 +12,7 @@
|
|||
"ejs": "^3.1.9",
|
||||
"express": "^4.18.3",
|
||||
"formidable": "^3.1.5",
|
||||
"helmet": "^7.1.0",
|
||||
"node-latex": "^3.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -755,6 +756,14 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/helmet": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/helmet/-/helmet-7.1.0.tgz",
|
||||
"integrity": "sha512-g+HZqgfbpXdCkme/Cd/mZkV0aV3BZZZSugecH03kl38m/Kmdx8jKjBikpDj2cr+Iynv4KpYEviojNdTJActJAg==",
|
||||
"engines": {
|
||||
"node": ">=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/hexoid": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz",
|
||||
|
@ -2335,6 +2344,11 @@
|
|||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
|
||||
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
|
||||
},
|
||||
"helmet": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/helmet/-/helmet-7.1.0.tgz",
|
||||
"integrity": "sha512-g+HZqgfbpXdCkme/Cd/mZkV0aV3BZZZSugecH03kl38m/Kmdx8jKjBikpDj2cr+Iynv4KpYEviojNdTJActJAg=="
|
||||
},
|
||||
"hexoid": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz",
|
||||
|
|
|
@ -9,13 +9,13 @@
|
|||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"minify": "minify public/css.css > public/css.min.css && minify public/js.js > public/js.min.js",
|
||||
"start": "node app.js",
|
||||
"dev": "NODE_ENV=development nodemon -V .",
|
||||
"tmux": "NODE_ENV=development ./tmux_dev.sh"
|
||||
"dev": "NODE_ENV=development nodemon -V ."
|
||||
},
|
||||
"dependencies": {
|
||||
"ejs": "^3.1.9",
|
||||
"express": "^4.18.3",
|
||||
"formidable": "^3.1.5",
|
||||
"helmet": "^7.1.0",
|
||||
"node-latex": "^3.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -1 +1 @@
|
|||
window.pdfgen={data:{},conf:{disabled:[]}};const $=e=>{const t=document.querySelectorAll(e);if(!t)throw new Error(`DOM elem '${e}' not found`);return 1==t.length?t[0]:t};function merge_obj(e,t){return e?(Object.keys(t).forEach((a=>{"object"!=typeof t[a]?e[a]=t[a]:e[a]=merge_obj(e[a],t[a])})),e):t}function error(e){console.log("error(): ",e),e.name&&e.message?alert(`${e.name}\n${e.message}`):"string"==typeof e?alert(e):console.error(e),e.el&&"object"==typeof e.el&&document.body.contains(e.el)&&setTimeout((()=>{e.el.focus(),e.el.select()}),100)}async function cvrapi(e){const t=e.value;let a=null;if(!/\d{8}/g.test(t))return error({el:e,name:"Forkert CVR format",message:" "});const r=await fetch(`/api/cvr/${t}`);try{a=await r.json()}catch(t){return console.log("json error:",t),error({el:e,name:"Kunne ikke parse respons body til JSON",message:"Serveren svarede ikke korrekt, skriv gerne en fejlrapport."})}return 404===r.status?error({el:e,name:"Kunne ikke finde et firma",message:`med CVR-nummer ${t}`}):r.ok?a:error({el:e,name:"Server error",message:e.error})}function format_date(e=new Date){const t="[object Date]"===Object.prototype.toString.call(e);if(t||"string"!=typeof e){if(!t)throw new Error("Invalid date!")}else try{e=new Date(e)}catch(e){throw console.error("Invalid date!"),e}return`${e.getDate()}/${e.getMonth()+1}/${e.getFullYear()}`}function populate(){return new Promise((async(e,t)=>{let a=Array.from(document.getElementsByClassName("var"));a=a.filter((e=>!window.pdfgen.conf.disabled.includes(e.id)));const r=(e,t)=>{if(e.includes(".")){[].concat(e.split("."));const a=e.split(".").reverse();let r={};r[a.shift()]=t,a.forEach(((e,t)=>{const a={};a[e]=r,r=a})),window.pdfgen.data=merge_obj(window.pdfgen.data,r)}else window.pdfgen.data[e]=t};await Promise.all(a.map((async e=>{if("number"===e.dataset.is)try{const t=parseInt(e.value);r(e.dataset.var,t)}catch(t){throw{el:e,name:"Client-side input validering",message:"Værdien kunne ikke konverteres til et tal"}}else if("boolean"===e.dataset.is){if("boolean"!=typeof e.checked)throw{el:e,name:"Client-side input validering",message:"Checkboxens værdi er ikke gyldig :S"};r(e.dataset.var,e.checked)}else if("string"===e.dataset.is){if("string"!=typeof e.value||""===e.value)throw{el:e,name:"Client-side input validering",message:"Teksten kunne ikke valideres"};r(e.dataset.var,e.value)}}))).then((()=>e())).catch((e=>(e.el&&(e.el.className+=" vali_err",setTimeout((()=>e.el.className=e.el.className.replace(/\ vali_err/g,"")),3800)),t(e))))}))}function modal_toggle(e){const t=document.querySelector(`#modal-${e}`);t.className.includes("show")?t.className=t.className.replace(/\ show/g,""):t.className+=" show"}window.addEventListener("DOMContentLoaded",(e=>{Array.from(document.querySelectorAll('input.var[type="file"]')).filter((e=>"image"===e.dataset.is)).forEach((e=>{e.addEventListener("change",(async t=>{let a;window.pdfgen.data.files||(window.pdfgen.data.files={});const r=new FormData;if(!e.files[0])throw{el:e,name:"Client-side input validering",message:"Du mangler at vælge en fil til upload"};r.append("file",e.files[0]);const n=await fetch("/pdf/upload/image",{method:"POST",body:r});try{a=await n.json()}catch(t){throw{el:e,name:"Kunne ikke parse respons body til JSON",message:"Serveren svarede ikke korrekt, skriv gerne en fejlrapport."}}if(!n.ok){if(!a.error)return reject(a);throw{el:e,name:"Kunne ikke uploade fil",message:a.error}}if(window.file_reset_timer&&setTimeout((()=>{delete window.pdfgen.data.files[e.dataset.var],e.dataset.preview&&($(`#${e.dataset.preview}`).innerHTML="")}),window.file_reset_timer),e.dataset.preview){const t=$(`#${e.dataset.preview}`);t.innerHTML="";const r=document.createElement("img");r.className="image_preview",r.src=`file/${a.fileid}`,t.appendChild(r)}window.pdfgen.data.files[e.dataset.var]=a.fileid}))}))}));
|
||||
var A=a=>typeof a=='string',{keys:b}=Object,$=_=>{const B=document.querySelectorAll(_);if(!B)throw Error(`DOM elem '${_}' not found`);return (B.length==1)?B[0]:B};window.pdfgen={data:{},conf:{disabled:[]}};function d(c,C){if(!c)return C;for(const k of b(C))typeof C[k]!=='object'?c[k]=C[k]:c[k]=d(c[k],C[k]);return c}window.addEventListener('DOMContentLoaded',()=>{var _a=[...document.querySelectorAll('input.var[type="file"]')];_a.filter(D=>D.dataset.is=='image').forEach(_A=>_A.addEventListener('change',async ()=>{!window.pdfgen.data.files&&(window.pdfgen.data.files={});let e;var _b=new FormData();if(!_A.files[0])throw {el:_A,name:'Client-side input validering',message:'Du mangler at vælge en fil til upload'};_b.append('file',_A.files[0]);var _c=await fetch('/pdf/upload/image',{method:'POST',body:_b});try {e=await _c.json()} catch {throw {el:_A,name:'Kunne ikke parse respons body til JSON',message:'Serveren svarede ikke korrekt, skriv gerne en fejlrapport.'}}if(!_c.ok){if(!e.error)return reject(e);throw {el:_A,name:'Kunne ikke uploade fil',message:e.error}}window.file_reset_timer&&setTimeout(()=>{delete window.pdfgen.data.files[_A.dataset.var];if(_A.dataset.preview)$(`#${_A.dataset.preview}`).innerHTML=''},window.file_reset_timer);if(_A.dataset.preview){var _d=$(`#${_A.dataset.preview}`),E=document.createElement('img');_d.innerHTML='';E.className='image_preview';E.src=`file/${e.fileid}`;_d.appendChild(E)}window.pdfgen.data.files[_A.dataset.var]=e.fileid}))});
|
||||
|
|
Loading…
Reference in New Issue