Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

7.2.0.oc merge oc main #215

Merged
merged 8 commits into from
Oct 9, 2024
4 changes: 2 additions & 2 deletions packages/enketo-core/src/js/reasons.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default {
<header class="reason-for-change__header">
<h5>${t('fieldsubmission.reason.heading')}</h5>
<div class="question reason-for-change__header__apply-to-all">
<input class="ignore" type="text" name="common-rfc" placeholder="${t(
<input autocomplete="off" class="ignore" type="text" name="common-rfc" placeholder="${t(
'fieldsubmission.reason.placeholder1'
)}"/>
<div class="option-wrapper">
Expand Down Expand Up @@ -81,7 +81,7 @@ export default {
const fieldFragment = range.createContextualFragment(
`<div class="reason-for-change__item">
<span class="reason-for-change__item__label">${labelText}</span>${repeatNumberHtml}
<input class="ignore" type="text" placeholder="${t(
<input autocomplete="off" class="ignore" type="text" placeholder="${t(
'fieldsubmission.reason.placeholder2'
)}"/>
</div>`
Expand Down
7 changes: 6 additions & 1 deletion packages/enketo-core/src/widget/date/datepicker-extended.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,12 @@ class DatepickerExtended extends Widget {
_setChangeHandler($fakeDateI) {
const { settings } = this;

$fakeDateI.on('change paste', (e) => {
let changeEvent = 'change';
if (!$fakeDateI.closest('label').hasClass('readonly')) {
changeEvent += ' paste';
}

$fakeDateI.on(changeEvent, (e) => {
let convertedValue = '';
let value =
e.type === 'paste'
Expand Down
9 changes: 9 additions & 0 deletions packages/enketo-core/src/widget/text-print/text-print.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,15 @@ class TextPrintWidget extends Widget {
this.element.after(printElement);
this.element.classList.add('print-hide');

// If previous element is a fake input in date widget, hide it as well
const previousElement = this.element.previousElementSibling;
if (
previousElement !== null &&
previousElement.classList.contains('date')
) {
previousElement.classList.add('print-hide');
}

this.widget = this.element.parentElement.querySelector(
`.${className}`
);
Expand Down
6 changes: 4 additions & 2 deletions packages/enketo-express/app/lib/media.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ const markupEntities = {
/**
* @param {string} fileName
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const escapeFileName = (fileName) =>
transformer
.escapeURLPath(fileName)
Expand Down Expand Up @@ -132,6 +133,7 @@ const getMediaMap = async (resourceId, media, options) => {

await Promise.all(
mediaEntries.map(({ filename, hash, downloadUrl }) => {
filename = encodeURIComponent(filename);
const mediaURL = createMediaURL({
basePath,
fileName: filename,
Expand All @@ -149,7 +151,7 @@ const getMediaMap = async (resourceId, media, options) => {
* escaping logic here to ensure keys match file names when they have
* special URL characters.
*/
result[escapeFileName(filename)] = mediaURL;
result[filename] = mediaURL;

if (resourceType === ResourceType.MANIFEST) {
return cacheModel.cacheManifestItem(
Expand Down Expand Up @@ -213,7 +215,7 @@ const getInstanceAttachments = async (instanceId) => {

return Object.fromEntries(
Object.entries(instanceAttachments).map(([key, value]) => [
escapeFileName(key),
encodeURIComponent(key),
escapeURL(value),
])
);
Expand Down
26 changes: 26 additions & 0 deletions packages/enketo-express/app/lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
const crypto = require('crypto');
const evpBytesToKey = require('evp_bytestokey');
const validUrl = require('valid-url');
const qs = require('qs');
// var debug = require( 'debug' )( 'utils' );

/**
Expand Down Expand Up @@ -224,6 +225,30 @@ function areOwnPropertiesEqual(a, b) {
return true;
}

/**
* Custom URL parser that preserves certain URLs in their original form.
*
* @param {string} str - The string to be parsed
* @return {object} The parsed object
*/
function preserveURLParser(str) {
const parsed = qs.parse(str, {
decoder: (str, defaultDecoder, charset, type) => {
// Preserve URLs that start with 'http' or 'https:'
if (
type === 'value' &&
(str.startsWith('http') || str.startsWith('https'))
) {
// Return the original string without decoding for URLs
return str;
}
// For non-URL values, use the default decoder
return defaultDecoder(str);
},
});
return parsed;
}

module.exports = {
getOpenRosaKey,
getXformsManifestHash,
Expand All @@ -235,4 +260,5 @@ module.exports = {
areOwnPropertiesEqual,
insecureAes192Decrypt,
insecureAes192Encrypt,
preserveURLParser,
};
12 changes: 12 additions & 0 deletions packages/enketo-express/config/express.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const I18nextBackend = require('i18next-fs-backend');
const i18nextMiddleware = require('i18next-http-middleware');
const compression = require('compression');
const errorHandler = require('../app/controllers/error-handler');
const { preserveURLParser } = require('../app/lib/utils');

const controllersPath = path.join(__dirname, '../app/controllers');
const app = express();
Expand Down Expand Up @@ -77,8 +78,19 @@ app.use(
bodyParser.urlencoded({
limit: config.server['payload limit'],
extended: true,
verify: (req, res, buf, encoding) => {
if (buf && buf.length) {
req.rawBody = buf.toString(encoding || 'utf8');
}
},
})
);
app.use((req, res, next) => {
if (req.rawBody) {
req.body = preserveURLParser(req.rawBody);
}
next();
});
app.use(cookieParser(app.get('encryption key')));
app.use(
i18nextMiddleware.handle(i18next, {
Expand Down
1 change: 1 addition & 0 deletions packages/enketo-express/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"pkg-dir": "^5.0.0",
"pug": "^3.0.2",
"puppeteer": "^13.7.0",
"qs": "^6.13.0",
"redis": "^3.1.2",
"@cypress/request": "^3.0.1",
"serve-favicon": "^2.5.0",
Expand Down
79 changes: 79 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2563,6 +2563,17 @@ call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5:
get-intrinsic "^1.2.1"
set-function-length "^1.1.1"

call-bind@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9"
integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==
dependencies:
es-define-property "^1.0.0"
es-errors "^1.3.0"
function-bind "^1.1.2"
get-intrinsic "^1.2.4"
set-function-length "^1.2.1"

callsites@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
Expand Down Expand Up @@ -3233,6 +3244,15 @@ define-data-property@^1.0.1, define-data-property@^1.1.1:
gopd "^1.0.1"
has-property-descriptors "^1.0.0"

define-data-property@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e"
integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==
dependencies:
es-define-property "^1.0.0"
es-errors "^1.3.0"
gopd "^1.0.1"

define-lazy-prop@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f"
Expand Down Expand Up @@ -3598,6 +3618,18 @@ es-abstract@^1.22.1:
unbox-primitive "^1.0.2"
which-typed-array "^1.1.13"

es-define-property@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845"
integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==
dependencies:
get-intrinsic "^1.2.4"

es-errors@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f"
integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==

es-iterator-helpers@^1.0.12:
version "1.0.15"
resolved "https://registry.yarnpkg.com/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz#bd81d275ac766431d19305923707c3efd9f1ae40"
Expand Down Expand Up @@ -4764,6 +4796,17 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@
has-symbols "^1.0.3"
hasown "^2.0.0"

get-intrinsic@^1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd"
integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==
dependencies:
es-errors "^1.3.0"
function-bind "^1.1.2"
has-proto "^1.0.1"
has-symbols "^1.0.3"
hasown "^2.0.0"

get-package-type@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a"
Expand Down Expand Up @@ -5198,6 +5241,13 @@ has-property-descriptors@^1.0.0:
dependencies:
get-intrinsic "^1.2.2"

has-property-descriptors@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854"
integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==
dependencies:
es-define-property "^1.0.0"

has-proto@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0"
Expand Down Expand Up @@ -8235,6 +8285,13 @@ qs@^6.11.0, qs@^6.11.2, qs@^6.4.0:
dependencies:
side-channel "^1.0.4"

qs@^6.13.0:
version "6.13.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906"
integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==
dependencies:
side-channel "^1.0.6"

querystringify@^2.1.1:
version "2.2.0"
resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6"
Expand Down Expand Up @@ -8825,6 +8882,18 @@ set-function-length@^1.1.1:
gopd "^1.0.1"
has-property-descriptors "^1.0.0"

set-function-length@^1.2.1:
version "1.2.2"
resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449"
integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==
dependencies:
define-data-property "^1.1.4"
es-errors "^1.3.0"
function-bind "^1.1.2"
get-intrinsic "^1.2.4"
gopd "^1.0.1"
has-property-descriptors "^1.0.2"

set-function-name@^2.0.0, set-function-name@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.1.tgz#12ce38b7954310b9f61faa12701620a0c882793a"
Expand Down Expand Up @@ -8892,6 +8961,16 @@ side-channel@^1.0.4:
get-intrinsic "^1.0.2"
object-inspect "^1.9.0"

side-channel@^1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2"
integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==
dependencies:
call-bind "^1.0.7"
es-errors "^1.3.0"
get-intrinsic "^1.2.4"
object-inspect "^1.13.1"

siginfo@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/siginfo/-/siginfo-2.0.0.tgz#32e76c70b79724e3bb567cb9d543eb858ccfaf30"
Expand Down
Loading