From 308bde4d1907c98cb16569802b3c3d87f23b0371 Mon Sep 17 00:00:00 2001 From: nshandra <34254522+nshandra@users.noreply.github.com> Date: Sun, 25 Jan 2026 21:14:53 +0100 Subject: [PATCH 1/4] fix: solve "The application could not be loaded." issue caused by secure context (http non localhost sites). Additionally allows to use the app in private mode. --- package.json | 5 ++- .../capture-core-utils/hash/hashSHA256.ts | 14 +++++-- yarn.lock | 37 +++++-------------- 3 files changed, 22 insertions(+), 34 deletions(-) diff --git a/package.json b/package.json index b850e57214..cb360cc6e6 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "capture-app", "homepage": ".", - "version": "105.5.2", + "version": "105.5.2-ocg-1", "cacheVersion": "2", "license": "BSD-3-Clause", "private": true, @@ -10,11 +10,11 @@ ], "dependencies": { "@dhis2-ui/calendar": "^10.7.6", - "@dhis2/rules-engine-javascript": "105.5.2", "@dhis2/app-runtime": "^3.14.5", "@dhis2/d2-i18n": "^1.1.0", "@dhis2/d2-ui-rich-text": "^7.4.0", "@dhis2/rule-engine": "^3.4.1", + "@dhis2/rules-engine-javascript": "105.5.2", "@dhis2/ui": "^10.9.0", "@emotion/css": "^11.13.5", "@emotion/react": "^11.14.0", @@ -27,6 +27,7 @@ "d2-utilizr": "^0.2.15", "date-fns": "^1.29.0", "history": "^5.3.0", + "js-sha256": "^0.11.1", "leaflet": "^1.7.1", "leaflet-draw": "^1.0.4", "lodash": "^4.17.21", diff --git a/src/core_modules/capture-core-utils/hash/hashSHA256.ts b/src/core_modules/capture-core-utils/hash/hashSHA256.ts index 87e7775b3f..8db9756bdc 100644 --- a/src/core_modules/capture-core-utils/hash/hashSHA256.ts +++ b/src/core_modules/capture-core-utils/hash/hashSHA256.ts @@ -1,6 +1,12 @@ +import { sha256 } from 'js-sha256'; + export const hashSHA256 = async (input: string): Promise => { - const inputUint8 = new TextEncoder().encode(input); - const hashBuffer = await window.crypto.subtle.digest('SHA-256', inputUint8); - const hashArray = Array.from(new Uint8Array(hashBuffer)); - return hashArray.map(byte => byte.toString(16).padStart(2, '0')).join(''); + try { + const inputUint8 = new TextEncoder().encode(input); + const hashBuffer = await window.crypto.subtle.digest('SHA-256', inputUint8); + const hashArray = Array.from(new Uint8Array(hashBuffer)); + return hashArray.map(byte => byte.toString(16).padStart(2, '0')).join(''); + } catch (error) { + return sha256(input); + } }; diff --git a/yarn.lock b/yarn.lock index 4eae6ff3ee..2993e749d5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9943,6 +9943,11 @@ joi@^17.13.3: "@sideway/formula" "^3.0.1" "@sideway/pinpoint" "^2.0.0" +js-sha256@^0.11.1: + version "0.11.1" + resolved "https://registry.yarnpkg.com/js-sha256/-/js-sha256-0.11.1.tgz#712262e8fc9569d6f7f6eea72c0d8e5ccc7c976c" + integrity sha512-o6WSo/LUvY2uC4j7mO50a2ms7E/EAdbP0swigLV+nzHKTTaYnaLIWJ02VdXrsJX0vGedDESQnLsOekr94ryfjg== + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -13268,7 +13273,7 @@ string-natural-compare@^3.0.1: resolved "https://registry.yarnpkg.com/string-natural-compare/-/string-natural-compare-3.0.1.tgz#7a42d58474454963759e8e8b7ae63d71c1e7fdf4" integrity sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw== -"string-width-cjs@npm:string-width@^4.2.0": +"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -13294,15 +13299,6 @@ string-width@^3.0.0, string-width@^3.1.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^5.1.0" -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - string-width@^5.0.1, string-width@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" @@ -13394,14 +13390,7 @@ stringify-object@^3.3.0: is-obj "^1.0.1" is-regexp "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@6.0.1, strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@6.0.1, strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -14939,7 +14928,8 @@ workbox-window@7.3.0: "@types/trusted-types" "^2.0.2" workbox-core "7.3.0" -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: + name wrap-ansi-cjs version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -14966,15 +14956,6 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^8.0.1, wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" From e24f526bbc1faf3f32dedd44dab7801e8d1942cd Mon Sep 17 00:00:00 2001 From: nshandra <34254522+nshandra@users.noreply.github.com> Date: Mon, 26 Jan 2026 10:26:35 +0100 Subject: [PATCH 2/4] chore: undo packages sort --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cb360cc6e6..f9203bff1a 100644 --- a/package.json +++ b/package.json @@ -10,11 +10,11 @@ ], "dependencies": { "@dhis2-ui/calendar": "^10.7.6", + "@dhis2/rules-engine-javascript": "105.5.2", "@dhis2/app-runtime": "^3.14.5", "@dhis2/d2-i18n": "^1.1.0", "@dhis2/d2-ui-rich-text": "^7.4.0", "@dhis2/rule-engine": "^3.4.1", - "@dhis2/rules-engine-javascript": "105.5.2", "@dhis2/ui": "^10.9.0", "@emotion/css": "^11.13.5", "@emotion/react": "^11.14.0", From 3bc7d5833e0808096fca451c1309a8bd176f8679 Mon Sep 17 00:00:00 2001 From: nshandra <34254522+nshandra@users.noreply.github.com> Date: Mon, 26 Jan 2026 11:28:09 +0100 Subject: [PATCH 3/4] fix: switch try/catch to conditional to avoid masking unrelated problems --- i18n/en.pot | 4 ++-- .../capture-core-utils/hash/hashSHA256.ts | 13 +++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/i18n/en.pot b/i18n/en.pot index da070eb508..a9e6870a0d 100644 --- a/i18n/en.pot +++ b/i18n/en.pot @@ -5,8 +5,8 @@ msgstr "" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" -"POT-Creation-Date: 2026-01-19T10:20:44.571Z\n" -"PO-Revision-Date: 2026-01-19T10:20:44.571Z\n" +"POT-Creation-Date: 2026-01-26T10:28:11.244Z\n" +"PO-Revision-Date: 2026-01-26T10:28:11.244Z\n" msgid "Choose one or more dates..." msgstr "Choose one or more dates..." diff --git a/src/core_modules/capture-core-utils/hash/hashSHA256.ts b/src/core_modules/capture-core-utils/hash/hashSHA256.ts index 8db9756bdc..a637eadad8 100644 --- a/src/core_modules/capture-core-utils/hash/hashSHA256.ts +++ b/src/core_modules/capture-core-utils/hash/hashSHA256.ts @@ -1,12 +1,13 @@ import { sha256 } from 'js-sha256'; export const hashSHA256 = async (input: string): Promise => { - try { - const inputUint8 = new TextEncoder().encode(input); - const hashBuffer = await window.crypto.subtle.digest('SHA-256', inputUint8); - const hashArray = Array.from(new Uint8Array(hashBuffer)); - return hashArray.map(byte => byte.toString(16).padStart(2, '0')).join(''); - } catch (error) { + if (!window.crypto?.subtle) { + console.warn('SubtleCrypto API not available, falling back to js-sha256.'); return sha256(input); } + + const inputUint8 = new TextEncoder().encode(input); + const hashBuffer = await window.crypto.subtle.digest('SHA-256', inputUint8); + const hashArray = Array.from(new Uint8Array(hashBuffer)); + return hashArray.map(byte => byte.toString(16).padStart(2, '0')).join(''); }; From c2820f6afbca2e15730f686d7f2696ee11725e26 Mon Sep 17 00:00:00 2001 From: nshandra <34254522+nshandra@users.noreply.github.com> Date: Mon, 26 Jan 2026 11:39:54 +0100 Subject: [PATCH 4/4] chore: remove empty pot update --- i18n/en.pot | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/i18n/en.pot b/i18n/en.pot index a9e6870a0d..da070eb508 100644 --- a/i18n/en.pot +++ b/i18n/en.pot @@ -5,8 +5,8 @@ msgstr "" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" -"POT-Creation-Date: 2026-01-26T10:28:11.244Z\n" -"PO-Revision-Date: 2026-01-26T10:28:11.244Z\n" +"POT-Creation-Date: 2026-01-19T10:20:44.571Z\n" +"PO-Revision-Date: 2026-01-19T10:20:44.571Z\n" msgid "Choose one or more dates..." msgstr "Choose one or more dates..."