Skip to main content

Safe HTML Viewer - Releases

← App details

Nextcloud 33

Safe HTML Viewer 0.1.4
Release Details
UpdatedJuly 27, 2026, 11:48 a.m.
Changelog

Fixed

  • Closing tags written inside a <script> or <style> body were deleted from the preview. libxml's HTML parser ends a raw-text body at any </, not only at the element's own end tag, and drops the rest of it, so var t = "<button><i></i>X</button>" arrived as var t = "<button><i>X". Every DOM the script then built came out mis-nested and the layout collapsed; CSS lost content: "</td>" the same way. Raw-text bodies are now held out of the document while it is parsed and put back verbatim afterwards. Present since 0.1.0, hidden behind the non-ASCII corruption that 0.1.3 fixed.
  • A <script> body that spelled out the internal <?xml encoding="utf-8" ?> parsing prefix lost that string, because the prefix was stripped from the serialized document only after the body had been reinserted.

Added

  • NOTICES.md lists the third-party licenses that travel inside the js/main.js bundle. The list is taken from a webpack stats run, so it is what the bundle actually holds after tree shaking (17 packages) rather than the whole dependency closure (59). Regenerate with npm run notices; npm run notices:check fails when it is stale.

Changed

  • LICENSE now holds the full text of the GNU Affero General Public License, version 3. It previously contained only the "how to apply" notice and a link to the text, so no copy of the license travelled with the release tarball even though that notice says one did — and GitHub could not identify the license either. The copyright line and the definition of this app's "source code" moved to the License section of the README.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhN2MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwNjIzMDczNzAyWhcNMzYwOTI4MDczNzAyWjAbMRkwFwYD
VQQDDBBzYWZlX2h0bWxfdmlld2VyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAxGMMlgiIp7gqLruDW6Qi9hVAw1z6pTuhAMaZTUv1cvhRLyBTDhnHfgoZ
zy0ocEOSfNJJcNPDtcYg3yM5ndLvShwQEx6JJC8cgmNSlTQMQRr2iVYV31ukV1tw
0KlXBvrPYanqQs34Hyjvj7KFcY2AcFIMoFZj410msp2SgcKmRXP7TC/xqnC6IDgv
Taqy3j6TuQh2Z66ODgUwgxHwA+7XGd8r8oivMOdcRVWZhbjl6mCU5OMqoGwss+oq
7hpFJCcKas3lwMoE4eBrWHrpsuHv4Gq8iwma5rTk4T0p1S60hcLdFgBChuL2dhb9
XkuWlt6NZTct085za5/o7c1xsTlYyiIWK/BGPTkQSsX80CdVScda21debxFAsxBF
Z0r0MbvwRKB5kjEzQQPiia+RLPKVb/+USDlbaycRXZAthK6L4Vb1cgiYo+TwqRBa
p7YHJxGXnozs3WC3M6/ihKf4Yu630wJHWU5sH9HG3hz5BtmOWLDfHIUGOUP9O04m
1QA6lq+v3Mq0BMCF8H/EnEhK3z7noh24KL5vhmjc1E40RdTG/tK6L6YjvbIIeDtB
numfI3xsPZwDqqnN9PUEtdcbBGN+H93xipb9GB/dL6hBLa3Xe2RgYLPO/n43Goqe
p+fm+bgEHcQRZ1hAUzKkuCOKT2H9/QbL3TBfkpBwm+u9/udkarMCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAW0Vj6POpPcSRy1uErGomZAur80+IWV50hu6P2hEwTWsZ
XlaBWeveY/lfAbXJJAua33x1cmbw09SDja0FCneYf0kKNpyGoMyq+yDgM2NddSI1
ftVxhWO/1qlbkTAboLsuwbePtZqyfYMML/Cgl4DPaHu1Kx+IIJmj2A+iAryCetGe
jdlhwWbk+SZ6/KtyZy1wirPDQib8MWMGlv/RcJyZiWC4L8y1vAjqsmCDpn5r2qq+
0isqzdcR7kMy89PovRuHN5lDyocf/+GECyE8x+Y3zhm7kq4qc2SC33RGGT4IHsg+
6sTGnvQSrZPq66kqiFoQFTN/FP7KF7dUB6NX5OIZNg==
-----END CERTIFICATE-----
Signaturepen7RR2L7DOYaTWIXcLeLFcZ/Oc6wSIokN+buzdsKkFE9MCnvRhKFwJpAWAgQW+69q9/bo+vVM2YWcwsO4SbdU+UMs3qMAWVpRvOtL5ysv/gwI3dzwoNh4yY3ToL8Tofdmb5wSpd6oPm4T9riaK3UUCKwDAMzacEqUMfhMLv1tQocq4/7TqyTwd2WtfsgUi57rTluA+QgEVMjCnMiaJEcJAZ5w42AGQUlRSuWOYuDZQ+qXxxvLxXo5pzYMl75UyrCqzUrw+26GAhXtnK/LvZ/AD18ONQm2BrINwlkPW6kEdgwKzfW4k/xAZulXjQS6Lpr1VsKfALjE01OSQ7tMMzUvbKlapjMxdIcjsIb5Hesp98c6blRccvA/HUahf5YQVPaZRcHES/8i9+OeS96QPY2zSU/oBDM9NcEzTN14pr0aiuxxsXrrrLnIE+LQst7BraimLFNwT99//BW9HFGD3zfZ5cwFQvxzgOE+nmcZbhWcN+GpM2ZnrK/qkDbOatEHNkzZv/pN+b7+MJCioHmK3ToTThh9a+4qIYjTXte2t7ZnPldYAe9FtGsTESdRh/sqVpIzRtyzG1oQIqpaYlc6a1Mj86yMvzgMXJSFagULfs66R7jEqYpo+xExpyBjK4/ivFvEAKkJxNJTvgmaGHjS4WS3NJLBzkpJq9ePROcqwFtWU=
Signature digestsha512
Dependencies
Required Nextcloud versions >=28.0.0,<34.0.0
Minimum Integer bits32
Safe HTML Viewer 0.1.3
Release Details
UpdatedJuly 27, 2026, 9:50 a.m.
Changelog

Fixed

  • Non-ASCII content (Japanese, other non-Latin scripts, emoji) was served as decimal numeric character references. DOMDocument::saveHTML() escapes every code point

    = 0x80, and browsers do not decode those inside <script> / <style> bodies, so previews of pages that build labels in JavaScript or set CSS content rendered raw &#21517; text and broken layout. Non-ASCII runs are now placeholder-swapped around serialization, so the served preview keeps the original UTF-8.

  • ISO dates in prose were redacted as phone numbers. The phone pattern allows spaces and parentheses, so a match carried its surrounding padding and the ISO-date guard never fired: 検証資料 2026-07-17 became 検証資料[REDACTED-PHONE]. Padding is now split off before the date check and re-emitted, which also preserves the spacing around genuinely redacted phone numbers.
  • A leading UTF-8 BOM made the preview come back empty. The BOM ended up between the internal encoding declaration and the document, so parsing stopped right after it — which hit every file written by an editor that emits a BOM by default (Notepad, Excel's web export, PowerShell's ConvertTo-Html).
  • Base64 data: URI payloads were redacted as opaque secrets, blanking out inline images. Such a payload is encoded binary, so the heuristics cannot recognise a secret in it but do match it by accident; base64 data URIs are now passed through. Data URIs that are not base64 stay in scope, since those carry readable text.
  • Redaction walked only the first top-level node, so content following a <script> or <style> sibling was served unredacted.
  • The <?xml encoding="utf-8" ?> prefix used to force UTF-8 parsing leaked into previews.
  • Credential patterns (password=, token=, ...) were only matched inside query strings, and the replacement dropped the parameter name. The value is now matched as bounded ASCII, so prose in scripts without ASCII word breaks (Japanese, Chinese) is not swallowed up to the end of the text node.
  • Long-token heuristic no longer swallows a host plus path as a single secret.
  • Private/localhost URL matching required a real host boundary, so public hosts such as internal.example.com are no longer treated as private.
  • Bare IPv4 redaction no longer overrides the [REDACTED-PRIVATE-URL] label.

Changed

  • The preview endpoint now serves HTML only (.html / .htm / text/html / application/xhtml+xml) and returns 415 otherwise, rejects files over 5 MiB with 413, and maps file-access failures to 404/500 instead of surfacing an exception.
  • Content-Security-Policy is extended with frame-ancestors 'self'; base-uri 'none' alongside the existing sandbox allow-scripts allow-popups (still no allow-same-origin).
  • File action id handling accepts large numeric ids as strings instead of parseInt, and preview tabs are opened with noopener,noreferrer.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhN2MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwNjIzMDczNzAyWhcNMzYwOTI4MDczNzAyWjAbMRkwFwYD
VQQDDBBzYWZlX2h0bWxfdmlld2VyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAxGMMlgiIp7gqLruDW6Qi9hVAw1z6pTuhAMaZTUv1cvhRLyBTDhnHfgoZ
zy0ocEOSfNJJcNPDtcYg3yM5ndLvShwQEx6JJC8cgmNSlTQMQRr2iVYV31ukV1tw
0KlXBvrPYanqQs34Hyjvj7KFcY2AcFIMoFZj410msp2SgcKmRXP7TC/xqnC6IDgv
Taqy3j6TuQh2Z66ODgUwgxHwA+7XGd8r8oivMOdcRVWZhbjl6mCU5OMqoGwss+oq
7hpFJCcKas3lwMoE4eBrWHrpsuHv4Gq8iwma5rTk4T0p1S60hcLdFgBChuL2dhb9
XkuWlt6NZTct085za5/o7c1xsTlYyiIWK/BGPTkQSsX80CdVScda21debxFAsxBF
Z0r0MbvwRKB5kjEzQQPiia+RLPKVb/+USDlbaycRXZAthK6L4Vb1cgiYo+TwqRBa
p7YHJxGXnozs3WC3M6/ihKf4Yu630wJHWU5sH9HG3hz5BtmOWLDfHIUGOUP9O04m
1QA6lq+v3Mq0BMCF8H/EnEhK3z7noh24KL5vhmjc1E40RdTG/tK6L6YjvbIIeDtB
numfI3xsPZwDqqnN9PUEtdcbBGN+H93xipb9GB/dL6hBLa3Xe2RgYLPO/n43Goqe
p+fm+bgEHcQRZ1hAUzKkuCOKT2H9/QbL3TBfkpBwm+u9/udkarMCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAW0Vj6POpPcSRy1uErGomZAur80+IWV50hu6P2hEwTWsZ
XlaBWeveY/lfAbXJJAua33x1cmbw09SDja0FCneYf0kKNpyGoMyq+yDgM2NddSI1
ftVxhWO/1qlbkTAboLsuwbePtZqyfYMML/Cgl4DPaHu1Kx+IIJmj2A+iAryCetGe
jdlhwWbk+SZ6/KtyZy1wirPDQib8MWMGlv/RcJyZiWC4L8y1vAjqsmCDpn5r2qq+
0isqzdcR7kMy89PovRuHN5lDyocf/+GECyE8x+Y3zhm7kq4qc2SC33RGGT4IHsg+
6sTGnvQSrZPq66kqiFoQFTN/FP7KF7dUB6NX5OIZNg==
-----END CERTIFICATE-----
SignaturerSin+ZMVn/oSIPKmIDImyuPw6gug82xtr+w9CxHVwP4U+n+469SmAYAaG5EDbtOcBVBnkMDj6f4S6PYxriMk0Ws6jyAS291cICi0mVjRftPxgfp5RjgaLCAfTCtjMubLWwF1oW/3AbY7Dn6Y72IWk79Hx9gpLM0Rk3INFGdcL/GUCGlat80bb2heAZFy4a0a7xwXpC4FwaWkWOpAV2sVd63zia+4+4RdARfnQS7R01KUfTEAuT4Gqq46cvgcpnUQhAvxzFXzjeP8opzg+kBL0yiBdeBazwE++Fw+tvM05/M16g57JslbT9xkNWdoNiEqb/A6ug19fFy0zh2YrKZt3ixTpDolURPDr0SZXICyj7f46fmXNZIELAhOyPzIVF5XQUSVKg0pTd14QQL+NuQJpg1XKBElU7btzBa9ODDDpVpdVuUMV+3lBWV1JfQtpBNOCeMcJsndcLqYHUHfiEtQGlULeYfj1ETbYYRruBvton1ZFIpkYNUYZHYV63e1cyQSf0LqgdxiJ4/o16q0sKPEpxX35XcGT9ZVZemb+L9bPQv8l4TDSzEoEW4FHEMG3p3PbB+kYNmU2Tw4MKwEewfryU0vTtVTKhPW2wLkwByV2jIQ71/83bVZbFNbzxfxWD6+M1st9Vmz9KEideXdGwYblKhW+BqLpR/xDCc1hJkMu8A=
Signature digestsha512
Dependencies
Required Nextcloud versions >=28.0.0,<34.0.0
Minimum Integer bits32
Safe HTML Viewer 0.1.2
Release Details
UpdatedJuly 3, 2026, 3:37 a.m.
Changelog

Fixed

  • App Store description rendered raw HTML tags as text: the App Store treats info.xml description as Markdown, so the description is now written in Markdown instead of HTML.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhN2MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwNjIzMDczNzAyWhcNMzYwOTI4MDczNzAyWjAbMRkwFwYD
VQQDDBBzYWZlX2h0bWxfdmlld2VyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAxGMMlgiIp7gqLruDW6Qi9hVAw1z6pTuhAMaZTUv1cvhRLyBTDhnHfgoZ
zy0ocEOSfNJJcNPDtcYg3yM5ndLvShwQEx6JJC8cgmNSlTQMQRr2iVYV31ukV1tw
0KlXBvrPYanqQs34Hyjvj7KFcY2AcFIMoFZj410msp2SgcKmRXP7TC/xqnC6IDgv
Taqy3j6TuQh2Z66ODgUwgxHwA+7XGd8r8oivMOdcRVWZhbjl6mCU5OMqoGwss+oq
7hpFJCcKas3lwMoE4eBrWHrpsuHv4Gq8iwma5rTk4T0p1S60hcLdFgBChuL2dhb9
XkuWlt6NZTct085za5/o7c1xsTlYyiIWK/BGPTkQSsX80CdVScda21debxFAsxBF
Z0r0MbvwRKB5kjEzQQPiia+RLPKVb/+USDlbaycRXZAthK6L4Vb1cgiYo+TwqRBa
p7YHJxGXnozs3WC3M6/ihKf4Yu630wJHWU5sH9HG3hz5BtmOWLDfHIUGOUP9O04m
1QA6lq+v3Mq0BMCF8H/EnEhK3z7noh24KL5vhmjc1E40RdTG/tK6L6YjvbIIeDtB
numfI3xsPZwDqqnN9PUEtdcbBGN+H93xipb9GB/dL6hBLa3Xe2RgYLPO/n43Goqe
p+fm+bgEHcQRZ1hAUzKkuCOKT2H9/QbL3TBfkpBwm+u9/udkarMCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAW0Vj6POpPcSRy1uErGomZAur80+IWV50hu6P2hEwTWsZ
XlaBWeveY/lfAbXJJAua33x1cmbw09SDja0FCneYf0kKNpyGoMyq+yDgM2NddSI1
ftVxhWO/1qlbkTAboLsuwbePtZqyfYMML/Cgl4DPaHu1Kx+IIJmj2A+iAryCetGe
jdlhwWbk+SZ6/KtyZy1wirPDQib8MWMGlv/RcJyZiWC4L8y1vAjqsmCDpn5r2qq+
0isqzdcR7kMy89PovRuHN5lDyocf/+GECyE8x+Y3zhm7kq4qc2SC33RGGT4IHsg+
6sTGnvQSrZPq66kqiFoQFTN/FP7KF7dUB6NX5OIZNg==
-----END CERTIFICATE-----
Signaturebx/keT27YaqA8wIFCi8LoWdXOvGQ/1+9fQPdoUJv/e0Z0FViwWpolmow0juKxyzQl5aKSUqPb9AsLf1m9f8yVpFtcziSry0nPzOEufBH6gq+fc6ng1JS7naLpljunVsJX4HiAFVCF/mqaoaR9J6faXXYbHSLfFIx1eLilrWUujBulCdzS2sja60Aw7tvTigFY/xkcTCNEyOU+/QdhqYQCgPlRMGFFRxpPFhPTo7p7KqETbk5J0mr7I2g/fx6xOWtCUPju6NSmqPxbqOKHrxXDfwITxCfrFsAM530gf57rHHYF16vVXcSX2K9O7Gl/cHFeCSDBh9BpBnZzQp6dzx4jDz65BUIl+O9Bex/8rGzCj7NV7tWXjmEOtIVNj0vsn+kUmqSuvE7kui+FUVwUaHPiaV4jUeFXCOV288SBACbD8IWIU2XCD3Un8kGp//fRfvd1/avtkIL5sp4ShR5N2tAuv6F7e/Gvyci75IZvJLxmbF1fNL2NnJI4+9GYgZWNYqKZeG3Zx3gcYp63owU6HncvumewDjqyiF1H4T3ah2v2/iBKUoJftSq5BYJ9u5+3KWygC0mdSQa3ib9xpuROg7kFEjT5GUxsp95IVI+h/9l+JLg2/H9EvgaLXFXLiTSxlLo66mld0T/kzfWyDn2LdmqpH/qWsUxaOm1RSoQ56UsyQc=
Signature digestsha512
Dependencies
Required Nextcloud versions >=28.0.0,<34.0.0
Minimum Integer bits32
Safe HTML Viewer 0.1.1
Release Details
UpdatedJuly 3, 2026, 3:27 a.m.
Changelog

Changed

  • Expanded the App Store description (features list, sandbox behaviour, limitations).
  • Unified author/copyright attribution to "Hiroshi Ishizaka (ishizakahiroshi)" across info.xml, composer.json, package.json and LICENSE.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhN2MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwNjIzMDczNzAyWhcNMzYwOTI4MDczNzAyWjAbMRkwFwYD
VQQDDBBzYWZlX2h0bWxfdmlld2VyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAxGMMlgiIp7gqLruDW6Qi9hVAw1z6pTuhAMaZTUv1cvhRLyBTDhnHfgoZ
zy0ocEOSfNJJcNPDtcYg3yM5ndLvShwQEx6JJC8cgmNSlTQMQRr2iVYV31ukV1tw
0KlXBvrPYanqQs34Hyjvj7KFcY2AcFIMoFZj410msp2SgcKmRXP7TC/xqnC6IDgv
Taqy3j6TuQh2Z66ODgUwgxHwA+7XGd8r8oivMOdcRVWZhbjl6mCU5OMqoGwss+oq
7hpFJCcKas3lwMoE4eBrWHrpsuHv4Gq8iwma5rTk4T0p1S60hcLdFgBChuL2dhb9
XkuWlt6NZTct085za5/o7c1xsTlYyiIWK/BGPTkQSsX80CdVScda21debxFAsxBF
Z0r0MbvwRKB5kjEzQQPiia+RLPKVb/+USDlbaycRXZAthK6L4Vb1cgiYo+TwqRBa
p7YHJxGXnozs3WC3M6/ihKf4Yu630wJHWU5sH9HG3hz5BtmOWLDfHIUGOUP9O04m
1QA6lq+v3Mq0BMCF8H/EnEhK3z7noh24KL5vhmjc1E40RdTG/tK6L6YjvbIIeDtB
numfI3xsPZwDqqnN9PUEtdcbBGN+H93xipb9GB/dL6hBLa3Xe2RgYLPO/n43Goqe
p+fm+bgEHcQRZ1hAUzKkuCOKT2H9/QbL3TBfkpBwm+u9/udkarMCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAW0Vj6POpPcSRy1uErGomZAur80+IWV50hu6P2hEwTWsZ
XlaBWeveY/lfAbXJJAua33x1cmbw09SDja0FCneYf0kKNpyGoMyq+yDgM2NddSI1
ftVxhWO/1qlbkTAboLsuwbePtZqyfYMML/Cgl4DPaHu1Kx+IIJmj2A+iAryCetGe
jdlhwWbk+SZ6/KtyZy1wirPDQib8MWMGlv/RcJyZiWC4L8y1vAjqsmCDpn5r2qq+
0isqzdcR7kMy89PovRuHN5lDyocf/+GECyE8x+Y3zhm7kq4qc2SC33RGGT4IHsg+
6sTGnvQSrZPq66kqiFoQFTN/FP7KF7dUB6NX5OIZNg==
-----END CERTIFICATE-----
SignaturefVBl4DuXEO4qJ13HX0BQTQPTJ6DCZazoiprU2vZQhaksRZwl6gadG3Fkxbq1iGK9fIEfQKvj2gLxLzxWq+WNruBIvXTdQZm30rzQSY4sksRj7ewgDGe6libZf1Q8kfQQ6pwd0c+Wboxz+cmdZhettNKBuLNKsl2s+zIIOyMYl4x7CjP90Kl7YoZdIbgnVPeOY4X4Auti+FvrANb4JMP3uzkflg4S+E7La5DILPHFsWag2c6JivrQ6AOOluDbXlddMdMY7vwrJ8zKCzZetqCUaTBCifSuvQ6JORujThAdGm52xr4BZjQ7C8QH9laTr6Zzj1v4PQVDuLU7NRzeIH9m6euK6z4bSt2bQUY3mQ21/dvD5HI40jS9yXns17fdKRFPgsgdZdyQtOGJjlZN4+lK3anJ02a3oDtsVbQq0FrQAkb0ALB53/j1A4y2K3n4MkzhIOWuxYyXsbkeQjWO2eB6DC26tfXt6O5VOntcI7caQcKjazDZnPvyam/QRSuTL4xDgLi6KR3sbwyxbQaU6+IIeUfZkykJngV/SU1iZ8YctfudJmsXmkIFfDpVBsoQPoe64S+vPJYHJ3z/sU5J9FIcufVw8HYww1uT2Settt3U1yIIFZ33oLzfcNbeWj6gXsHBs6QG5vKsBzxeBGu+194KhNh9MAfopvtLlXRnY/C0A+c=
Signature digestsha512
Dependencies
Required Nextcloud versions >=28.0.0,<34.0.0
Minimum Integer bits32
Safe HTML Viewer 0.1.0
Release Details
UpdatedJuly 3, 2026, 3:01 a.m.
Changelog

Added

  • Initial public release of safe_html_viewer.
  • File action registration for .html / text/html files.
  • /apps/safe_html_viewer/raw/{fileId} endpoint returning HTML under strict CSP sandbox (sandbox allow-scripts allow-popups, no allow-same-origin).
  • ACL enforcement via user folder view (only accessible files are returned).
  • RedactionService with best-effort display-time redaction for:
  • Email addresses
  • Phone-like strings
  • IPv4 addresses
  • Private/localhost URLs
  • Credential query patterns (password=, token=, api_key=, ...)
  • Long opaque token-like strings
  • Redaction only affects the served preview; original file content is untouched.
  • Basic PHPUnit coverage for redaction rules.
  • Documentation: README, SECURITY, CHANGELOG, AGENTS/CLAUDE guidance files.

Security

  • Sandbox is intentionally restrictive.
  • Redaction is documented as best-effort (see README and SECURITY.md).
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhN2MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwNjIzMDczNzAyWhcNMzYwOTI4MDczNzAyWjAbMRkwFwYD
VQQDDBBzYWZlX2h0bWxfdmlld2VyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAxGMMlgiIp7gqLruDW6Qi9hVAw1z6pTuhAMaZTUv1cvhRLyBTDhnHfgoZ
zy0ocEOSfNJJcNPDtcYg3yM5ndLvShwQEx6JJC8cgmNSlTQMQRr2iVYV31ukV1tw
0KlXBvrPYanqQs34Hyjvj7KFcY2AcFIMoFZj410msp2SgcKmRXP7TC/xqnC6IDgv
Taqy3j6TuQh2Z66ODgUwgxHwA+7XGd8r8oivMOdcRVWZhbjl6mCU5OMqoGwss+oq
7hpFJCcKas3lwMoE4eBrWHrpsuHv4Gq8iwma5rTk4T0p1S60hcLdFgBChuL2dhb9
XkuWlt6NZTct085za5/o7c1xsTlYyiIWK/BGPTkQSsX80CdVScda21debxFAsxBF
Z0r0MbvwRKB5kjEzQQPiia+RLPKVb/+USDlbaycRXZAthK6L4Vb1cgiYo+TwqRBa
p7YHJxGXnozs3WC3M6/ihKf4Yu630wJHWU5sH9HG3hz5BtmOWLDfHIUGOUP9O04m
1QA6lq+v3Mq0BMCF8H/EnEhK3z7noh24KL5vhmjc1E40RdTG/tK6L6YjvbIIeDtB
numfI3xsPZwDqqnN9PUEtdcbBGN+H93xipb9GB/dL6hBLa3Xe2RgYLPO/n43Goqe
p+fm+bgEHcQRZ1hAUzKkuCOKT2H9/QbL3TBfkpBwm+u9/udkarMCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAW0Vj6POpPcSRy1uErGomZAur80+IWV50hu6P2hEwTWsZ
XlaBWeveY/lfAbXJJAua33x1cmbw09SDja0FCneYf0kKNpyGoMyq+yDgM2NddSI1
ftVxhWO/1qlbkTAboLsuwbePtZqyfYMML/Cgl4DPaHu1Kx+IIJmj2A+iAryCetGe
jdlhwWbk+SZ6/KtyZy1wirPDQib8MWMGlv/RcJyZiWC4L8y1vAjqsmCDpn5r2qq+
0isqzdcR7kMy89PovRuHN5lDyocf/+GECyE8x+Y3zhm7kq4qc2SC33RGGT4IHsg+
6sTGnvQSrZPq66kqiFoQFTN/FP7KF7dUB6NX5OIZNg==
-----END CERTIFICATE-----
SignatureLIHeXIJmSLq1g/KyD/WijCOZX+Yo9A2LHW9B/WRhd2q0GcE1Jw+4bCiax7E6m7GpIm/jLmxBi6Y6gdFtKhtCnTr5pxmnL7txji8rt0CaDMUjodZ1jIK+sym+oMRhgZlmdlwJd8V1tbvZBhTDfEzFQ0atJDuymE5IhMDyHN4703aJEQ0wEDy9c14A6mo9gW6K1Ew6YicJm83/9fgPJjoI8WpvZWtq7Oylj3HzSVqzrbVO2I5PvPCUnwkEyQ4iwo0nhFeU8aRzn0a/JPlHtfmlnPjkVXU4sHKR7HopNADqIPa000N37gofqeTP6MZ3O/dgQJkHWGRjgcPxD2LDUkn4ntaizNAK3KrMSPlormfoNyQae6Z9PZqpT+DsQr54u+0iNI88pZ2sSjl2HfNdGIYLSp4K6sPZAJRa32KzgjfgQWj8UeVSvEk9lRhXzeYdCz8PckWAdaldbQaNfs6MoigqcY1gCqZxkVOKadIsiduWLkatVSUs1zNNb8y2qyiPExV2sK16wotQbxi+Z2qqpbT1lCznZdreTHKz8jBBTBe9Bt+TzESUOq8z+04DgG254BHUq9CNYWt0FvLfwjdKzbVNud5DNGCYWBz9U/qsgynYjSGy1Uz5mkKZxCeiOVuQ660mSu1/BXqEywkFnHp0/in/rxH9P8ddw3pHj5DEs0tydqY=
Signature digestsha512
Dependencies
Required Nextcloud versions >=28.0.0,<34.0.0
Minimum Integer bits32

Nextcloud 32

Safe HTML Viewer 0.1.4
Release Details
UpdatedJuly 27, 2026, 11:48 a.m.
Changelog

Fixed

  • Closing tags written inside a <script> or <style> body were deleted from the preview. libxml's HTML parser ends a raw-text body at any </, not only at the element's own end tag, and drops the rest of it, so var t = "<button><i></i>X</button>" arrived as var t = "<button><i>X". Every DOM the script then built came out mis-nested and the layout collapsed; CSS lost content: "</td>" the same way. Raw-text bodies are now held out of the document while it is parsed and put back verbatim afterwards. Present since 0.1.0, hidden behind the non-ASCII corruption that 0.1.3 fixed.
  • A <script> body that spelled out the internal <?xml encoding="utf-8" ?> parsing prefix lost that string, because the prefix was stripped from the serialized document only after the body had been reinserted.

Added

  • NOTICES.md lists the third-party licenses that travel inside the js/main.js bundle. The list is taken from a webpack stats run, so it is what the bundle actually holds after tree shaking (17 packages) rather than the whole dependency closure (59). Regenerate with npm run notices; npm run notices:check fails when it is stale.

Changed

  • LICENSE now holds the full text of the GNU Affero General Public License, version 3. It previously contained only the "how to apply" notice and a link to the text, so no copy of the license travelled with the release tarball even though that notice says one did — and GitHub could not identify the license either. The copyright line and the definition of this app's "source code" moved to the License section of the README.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhN2MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwNjIzMDczNzAyWhcNMzYwOTI4MDczNzAyWjAbMRkwFwYD
VQQDDBBzYWZlX2h0bWxfdmlld2VyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAxGMMlgiIp7gqLruDW6Qi9hVAw1z6pTuhAMaZTUv1cvhRLyBTDhnHfgoZ
zy0ocEOSfNJJcNPDtcYg3yM5ndLvShwQEx6JJC8cgmNSlTQMQRr2iVYV31ukV1tw
0KlXBvrPYanqQs34Hyjvj7KFcY2AcFIMoFZj410msp2SgcKmRXP7TC/xqnC6IDgv
Taqy3j6TuQh2Z66ODgUwgxHwA+7XGd8r8oivMOdcRVWZhbjl6mCU5OMqoGwss+oq
7hpFJCcKas3lwMoE4eBrWHrpsuHv4Gq8iwma5rTk4T0p1S60hcLdFgBChuL2dhb9
XkuWlt6NZTct085za5/o7c1xsTlYyiIWK/BGPTkQSsX80CdVScda21debxFAsxBF
Z0r0MbvwRKB5kjEzQQPiia+RLPKVb/+USDlbaycRXZAthK6L4Vb1cgiYo+TwqRBa
p7YHJxGXnozs3WC3M6/ihKf4Yu630wJHWU5sH9HG3hz5BtmOWLDfHIUGOUP9O04m
1QA6lq+v3Mq0BMCF8H/EnEhK3z7noh24KL5vhmjc1E40RdTG/tK6L6YjvbIIeDtB
numfI3xsPZwDqqnN9PUEtdcbBGN+H93xipb9GB/dL6hBLa3Xe2RgYLPO/n43Goqe
p+fm+bgEHcQRZ1hAUzKkuCOKT2H9/QbL3TBfkpBwm+u9/udkarMCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAW0Vj6POpPcSRy1uErGomZAur80+IWV50hu6P2hEwTWsZ
XlaBWeveY/lfAbXJJAua33x1cmbw09SDja0FCneYf0kKNpyGoMyq+yDgM2NddSI1
ftVxhWO/1qlbkTAboLsuwbePtZqyfYMML/Cgl4DPaHu1Kx+IIJmj2A+iAryCetGe
jdlhwWbk+SZ6/KtyZy1wirPDQib8MWMGlv/RcJyZiWC4L8y1vAjqsmCDpn5r2qq+
0isqzdcR7kMy89PovRuHN5lDyocf/+GECyE8x+Y3zhm7kq4qc2SC33RGGT4IHsg+
6sTGnvQSrZPq66kqiFoQFTN/FP7KF7dUB6NX5OIZNg==
-----END CERTIFICATE-----
Signaturepen7RR2L7DOYaTWIXcLeLFcZ/Oc6wSIokN+buzdsKkFE9MCnvRhKFwJpAWAgQW+69q9/bo+vVM2YWcwsO4SbdU+UMs3qMAWVpRvOtL5ysv/gwI3dzwoNh4yY3ToL8Tofdmb5wSpd6oPm4T9riaK3UUCKwDAMzacEqUMfhMLv1tQocq4/7TqyTwd2WtfsgUi57rTluA+QgEVMjCnMiaJEcJAZ5w42AGQUlRSuWOYuDZQ+qXxxvLxXo5pzYMl75UyrCqzUrw+26GAhXtnK/LvZ/AD18ONQm2BrINwlkPW6kEdgwKzfW4k/xAZulXjQS6Lpr1VsKfALjE01OSQ7tMMzUvbKlapjMxdIcjsIb5Hesp98c6blRccvA/HUahf5YQVPaZRcHES/8i9+OeS96QPY2zSU/oBDM9NcEzTN14pr0aiuxxsXrrrLnIE+LQst7BraimLFNwT99//BW9HFGD3zfZ5cwFQvxzgOE+nmcZbhWcN+GpM2ZnrK/qkDbOatEHNkzZv/pN+b7+MJCioHmK3ToTThh9a+4qIYjTXte2t7ZnPldYAe9FtGsTESdRh/sqVpIzRtyzG1oQIqpaYlc6a1Mj86yMvzgMXJSFagULfs66R7jEqYpo+xExpyBjK4/ivFvEAKkJxNJTvgmaGHjS4WS3NJLBzkpJq9ePROcqwFtWU=
Signature digestsha512
Dependencies
Required Nextcloud versions >=28.0.0,<34.0.0
Minimum Integer bits32
Safe HTML Viewer 0.1.3
Release Details
UpdatedJuly 27, 2026, 9:50 a.m.
Changelog

Fixed

  • Non-ASCII content (Japanese, other non-Latin scripts, emoji) was served as decimal numeric character references. DOMDocument::saveHTML() escapes every code point

    = 0x80, and browsers do not decode those inside <script> / <style> bodies, so previews of pages that build labels in JavaScript or set CSS content rendered raw &#21517; text and broken layout. Non-ASCII runs are now placeholder-swapped around serialization, so the served preview keeps the original UTF-8.

  • ISO dates in prose were redacted as phone numbers. The phone pattern allows spaces and parentheses, so a match carried its surrounding padding and the ISO-date guard never fired: 検証資料 2026-07-17 became 検証資料[REDACTED-PHONE]. Padding is now split off before the date check and re-emitted, which also preserves the spacing around genuinely redacted phone numbers.
  • A leading UTF-8 BOM made the preview come back empty. The BOM ended up between the internal encoding declaration and the document, so parsing stopped right after it — which hit every file written by an editor that emits a BOM by default (Notepad, Excel's web export, PowerShell's ConvertTo-Html).
  • Base64 data: URI payloads were redacted as opaque secrets, blanking out inline images. Such a payload is encoded binary, so the heuristics cannot recognise a secret in it but do match it by accident; base64 data URIs are now passed through. Data URIs that are not base64 stay in scope, since those carry readable text.
  • Redaction walked only the first top-level node, so content following a <script> or <style> sibling was served unredacted.
  • The <?xml encoding="utf-8" ?> prefix used to force UTF-8 parsing leaked into previews.
  • Credential patterns (password=, token=, ...) were only matched inside query strings, and the replacement dropped the parameter name. The value is now matched as bounded ASCII, so prose in scripts without ASCII word breaks (Japanese, Chinese) is not swallowed up to the end of the text node.
  • Long-token heuristic no longer swallows a host plus path as a single secret.
  • Private/localhost URL matching required a real host boundary, so public hosts such as internal.example.com are no longer treated as private.
  • Bare IPv4 redaction no longer overrides the [REDACTED-PRIVATE-URL] label.

Changed

  • The preview endpoint now serves HTML only (.html / .htm / text/html / application/xhtml+xml) and returns 415 otherwise, rejects files over 5 MiB with 413, and maps file-access failures to 404/500 instead of surfacing an exception.
  • Content-Security-Policy is extended with frame-ancestors 'self'; base-uri 'none' alongside the existing sandbox allow-scripts allow-popups (still no allow-same-origin).
  • File action id handling accepts large numeric ids as strings instead of parseInt, and preview tabs are opened with noopener,noreferrer.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhN2MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwNjIzMDczNzAyWhcNMzYwOTI4MDczNzAyWjAbMRkwFwYD
VQQDDBBzYWZlX2h0bWxfdmlld2VyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAxGMMlgiIp7gqLruDW6Qi9hVAw1z6pTuhAMaZTUv1cvhRLyBTDhnHfgoZ
zy0ocEOSfNJJcNPDtcYg3yM5ndLvShwQEx6JJC8cgmNSlTQMQRr2iVYV31ukV1tw
0KlXBvrPYanqQs34Hyjvj7KFcY2AcFIMoFZj410msp2SgcKmRXP7TC/xqnC6IDgv
Taqy3j6TuQh2Z66ODgUwgxHwA+7XGd8r8oivMOdcRVWZhbjl6mCU5OMqoGwss+oq
7hpFJCcKas3lwMoE4eBrWHrpsuHv4Gq8iwma5rTk4T0p1S60hcLdFgBChuL2dhb9
XkuWlt6NZTct085za5/o7c1xsTlYyiIWK/BGPTkQSsX80CdVScda21debxFAsxBF
Z0r0MbvwRKB5kjEzQQPiia+RLPKVb/+USDlbaycRXZAthK6L4Vb1cgiYo+TwqRBa
p7YHJxGXnozs3WC3M6/ihKf4Yu630wJHWU5sH9HG3hz5BtmOWLDfHIUGOUP9O04m
1QA6lq+v3Mq0BMCF8H/EnEhK3z7noh24KL5vhmjc1E40RdTG/tK6L6YjvbIIeDtB
numfI3xsPZwDqqnN9PUEtdcbBGN+H93xipb9GB/dL6hBLa3Xe2RgYLPO/n43Goqe
p+fm+bgEHcQRZ1hAUzKkuCOKT2H9/QbL3TBfkpBwm+u9/udkarMCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAW0Vj6POpPcSRy1uErGomZAur80+IWV50hu6P2hEwTWsZ
XlaBWeveY/lfAbXJJAua33x1cmbw09SDja0FCneYf0kKNpyGoMyq+yDgM2NddSI1
ftVxhWO/1qlbkTAboLsuwbePtZqyfYMML/Cgl4DPaHu1Kx+IIJmj2A+iAryCetGe
jdlhwWbk+SZ6/KtyZy1wirPDQib8MWMGlv/RcJyZiWC4L8y1vAjqsmCDpn5r2qq+
0isqzdcR7kMy89PovRuHN5lDyocf/+GECyE8x+Y3zhm7kq4qc2SC33RGGT4IHsg+
6sTGnvQSrZPq66kqiFoQFTN/FP7KF7dUB6NX5OIZNg==
-----END CERTIFICATE-----
SignaturerSin+ZMVn/oSIPKmIDImyuPw6gug82xtr+w9CxHVwP4U+n+469SmAYAaG5EDbtOcBVBnkMDj6f4S6PYxriMk0Ws6jyAS291cICi0mVjRftPxgfp5RjgaLCAfTCtjMubLWwF1oW/3AbY7Dn6Y72IWk79Hx9gpLM0Rk3INFGdcL/GUCGlat80bb2heAZFy4a0a7xwXpC4FwaWkWOpAV2sVd63zia+4+4RdARfnQS7R01KUfTEAuT4Gqq46cvgcpnUQhAvxzFXzjeP8opzg+kBL0yiBdeBazwE++Fw+tvM05/M16g57JslbT9xkNWdoNiEqb/A6ug19fFy0zh2YrKZt3ixTpDolURPDr0SZXICyj7f46fmXNZIELAhOyPzIVF5XQUSVKg0pTd14QQL+NuQJpg1XKBElU7btzBa9ODDDpVpdVuUMV+3lBWV1JfQtpBNOCeMcJsndcLqYHUHfiEtQGlULeYfj1ETbYYRruBvton1ZFIpkYNUYZHYV63e1cyQSf0LqgdxiJ4/o16q0sKPEpxX35XcGT9ZVZemb+L9bPQv8l4TDSzEoEW4FHEMG3p3PbB+kYNmU2Tw4MKwEewfryU0vTtVTKhPW2wLkwByV2jIQ71/83bVZbFNbzxfxWD6+M1st9Vmz9KEideXdGwYblKhW+BqLpR/xDCc1hJkMu8A=
Signature digestsha512
Dependencies
Required Nextcloud versions >=28.0.0,<34.0.0
Minimum Integer bits32
Safe HTML Viewer 0.1.2
Release Details
UpdatedJuly 3, 2026, 3:37 a.m.
Changelog

Fixed

  • App Store description rendered raw HTML tags as text: the App Store treats info.xml description as Markdown, so the description is now written in Markdown instead of HTML.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhN2MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwNjIzMDczNzAyWhcNMzYwOTI4MDczNzAyWjAbMRkwFwYD
VQQDDBBzYWZlX2h0bWxfdmlld2VyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAxGMMlgiIp7gqLruDW6Qi9hVAw1z6pTuhAMaZTUv1cvhRLyBTDhnHfgoZ
zy0ocEOSfNJJcNPDtcYg3yM5ndLvShwQEx6JJC8cgmNSlTQMQRr2iVYV31ukV1tw
0KlXBvrPYanqQs34Hyjvj7KFcY2AcFIMoFZj410msp2SgcKmRXP7TC/xqnC6IDgv
Taqy3j6TuQh2Z66ODgUwgxHwA+7XGd8r8oivMOdcRVWZhbjl6mCU5OMqoGwss+oq
7hpFJCcKas3lwMoE4eBrWHrpsuHv4Gq8iwma5rTk4T0p1S60hcLdFgBChuL2dhb9
XkuWlt6NZTct085za5/o7c1xsTlYyiIWK/BGPTkQSsX80CdVScda21debxFAsxBF
Z0r0MbvwRKB5kjEzQQPiia+RLPKVb/+USDlbaycRXZAthK6L4Vb1cgiYo+TwqRBa
p7YHJxGXnozs3WC3M6/ihKf4Yu630wJHWU5sH9HG3hz5BtmOWLDfHIUGOUP9O04m
1QA6lq+v3Mq0BMCF8H/EnEhK3z7noh24KL5vhmjc1E40RdTG/tK6L6YjvbIIeDtB
numfI3xsPZwDqqnN9PUEtdcbBGN+H93xipb9GB/dL6hBLa3Xe2RgYLPO/n43Goqe
p+fm+bgEHcQRZ1hAUzKkuCOKT2H9/QbL3TBfkpBwm+u9/udkarMCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAW0Vj6POpPcSRy1uErGomZAur80+IWV50hu6P2hEwTWsZ
XlaBWeveY/lfAbXJJAua33x1cmbw09SDja0FCneYf0kKNpyGoMyq+yDgM2NddSI1
ftVxhWO/1qlbkTAboLsuwbePtZqyfYMML/Cgl4DPaHu1Kx+IIJmj2A+iAryCetGe
jdlhwWbk+SZ6/KtyZy1wirPDQib8MWMGlv/RcJyZiWC4L8y1vAjqsmCDpn5r2qq+
0isqzdcR7kMy89PovRuHN5lDyocf/+GECyE8x+Y3zhm7kq4qc2SC33RGGT4IHsg+
6sTGnvQSrZPq66kqiFoQFTN/FP7KF7dUB6NX5OIZNg==
-----END CERTIFICATE-----
Signaturebx/keT27YaqA8wIFCi8LoWdXOvGQ/1+9fQPdoUJv/e0Z0FViwWpolmow0juKxyzQl5aKSUqPb9AsLf1m9f8yVpFtcziSry0nPzOEufBH6gq+fc6ng1JS7naLpljunVsJX4HiAFVCF/mqaoaR9J6faXXYbHSLfFIx1eLilrWUujBulCdzS2sja60Aw7tvTigFY/xkcTCNEyOU+/QdhqYQCgPlRMGFFRxpPFhPTo7p7KqETbk5J0mr7I2g/fx6xOWtCUPju6NSmqPxbqOKHrxXDfwITxCfrFsAM530gf57rHHYF16vVXcSX2K9O7Gl/cHFeCSDBh9BpBnZzQp6dzx4jDz65BUIl+O9Bex/8rGzCj7NV7tWXjmEOtIVNj0vsn+kUmqSuvE7kui+FUVwUaHPiaV4jUeFXCOV288SBACbD8IWIU2XCD3Un8kGp//fRfvd1/avtkIL5sp4ShR5N2tAuv6F7e/Gvyci75IZvJLxmbF1fNL2NnJI4+9GYgZWNYqKZeG3Zx3gcYp63owU6HncvumewDjqyiF1H4T3ah2v2/iBKUoJftSq5BYJ9u5+3KWygC0mdSQa3ib9xpuROg7kFEjT5GUxsp95IVI+h/9l+JLg2/H9EvgaLXFXLiTSxlLo66mld0T/kzfWyDn2LdmqpH/qWsUxaOm1RSoQ56UsyQc=
Signature digestsha512
Dependencies
Required Nextcloud versions >=28.0.0,<34.0.0
Minimum Integer bits32
Safe HTML Viewer 0.1.1
Release Details
UpdatedJuly 3, 2026, 3:27 a.m.
Changelog

Changed

  • Expanded the App Store description (features list, sandbox behaviour, limitations).
  • Unified author/copyright attribution to "Hiroshi Ishizaka (ishizakahiroshi)" across info.xml, composer.json, package.json and LICENSE.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhN2MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwNjIzMDczNzAyWhcNMzYwOTI4MDczNzAyWjAbMRkwFwYD
VQQDDBBzYWZlX2h0bWxfdmlld2VyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAxGMMlgiIp7gqLruDW6Qi9hVAw1z6pTuhAMaZTUv1cvhRLyBTDhnHfgoZ
zy0ocEOSfNJJcNPDtcYg3yM5ndLvShwQEx6JJC8cgmNSlTQMQRr2iVYV31ukV1tw
0KlXBvrPYanqQs34Hyjvj7KFcY2AcFIMoFZj410msp2SgcKmRXP7TC/xqnC6IDgv
Taqy3j6TuQh2Z66ODgUwgxHwA+7XGd8r8oivMOdcRVWZhbjl6mCU5OMqoGwss+oq
7hpFJCcKas3lwMoE4eBrWHrpsuHv4Gq8iwma5rTk4T0p1S60hcLdFgBChuL2dhb9
XkuWlt6NZTct085za5/o7c1xsTlYyiIWK/BGPTkQSsX80CdVScda21debxFAsxBF
Z0r0MbvwRKB5kjEzQQPiia+RLPKVb/+USDlbaycRXZAthK6L4Vb1cgiYo+TwqRBa
p7YHJxGXnozs3WC3M6/ihKf4Yu630wJHWU5sH9HG3hz5BtmOWLDfHIUGOUP9O04m
1QA6lq+v3Mq0BMCF8H/EnEhK3z7noh24KL5vhmjc1E40RdTG/tK6L6YjvbIIeDtB
numfI3xsPZwDqqnN9PUEtdcbBGN+H93xipb9GB/dL6hBLa3Xe2RgYLPO/n43Goqe
p+fm+bgEHcQRZ1hAUzKkuCOKT2H9/QbL3TBfkpBwm+u9/udkarMCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAW0Vj6POpPcSRy1uErGomZAur80+IWV50hu6P2hEwTWsZ
XlaBWeveY/lfAbXJJAua33x1cmbw09SDja0FCneYf0kKNpyGoMyq+yDgM2NddSI1
ftVxhWO/1qlbkTAboLsuwbePtZqyfYMML/Cgl4DPaHu1Kx+IIJmj2A+iAryCetGe
jdlhwWbk+SZ6/KtyZy1wirPDQib8MWMGlv/RcJyZiWC4L8y1vAjqsmCDpn5r2qq+
0isqzdcR7kMy89PovRuHN5lDyocf/+GECyE8x+Y3zhm7kq4qc2SC33RGGT4IHsg+
6sTGnvQSrZPq66kqiFoQFTN/FP7KF7dUB6NX5OIZNg==
-----END CERTIFICATE-----
SignaturefVBl4DuXEO4qJ13HX0BQTQPTJ6DCZazoiprU2vZQhaksRZwl6gadG3Fkxbq1iGK9fIEfQKvj2gLxLzxWq+WNruBIvXTdQZm30rzQSY4sksRj7ewgDGe6libZf1Q8kfQQ6pwd0c+Wboxz+cmdZhettNKBuLNKsl2s+zIIOyMYl4x7CjP90Kl7YoZdIbgnVPeOY4X4Auti+FvrANb4JMP3uzkflg4S+E7La5DILPHFsWag2c6JivrQ6AOOluDbXlddMdMY7vwrJ8zKCzZetqCUaTBCifSuvQ6JORujThAdGm52xr4BZjQ7C8QH9laTr6Zzj1v4PQVDuLU7NRzeIH9m6euK6z4bSt2bQUY3mQ21/dvD5HI40jS9yXns17fdKRFPgsgdZdyQtOGJjlZN4+lK3anJ02a3oDtsVbQq0FrQAkb0ALB53/j1A4y2K3n4MkzhIOWuxYyXsbkeQjWO2eB6DC26tfXt6O5VOntcI7caQcKjazDZnPvyam/QRSuTL4xDgLi6KR3sbwyxbQaU6+IIeUfZkykJngV/SU1iZ8YctfudJmsXmkIFfDpVBsoQPoe64S+vPJYHJ3z/sU5J9FIcufVw8HYww1uT2Settt3U1yIIFZ33oLzfcNbeWj6gXsHBs6QG5vKsBzxeBGu+194KhNh9MAfopvtLlXRnY/C0A+c=
Signature digestsha512
Dependencies
Required Nextcloud versions >=28.0.0,<34.0.0
Minimum Integer bits32
Safe HTML Viewer 0.1.0
Release Details
UpdatedJuly 3, 2026, 3:01 a.m.
Changelog

Added

  • Initial public release of safe_html_viewer.
  • File action registration for .html / text/html files.
  • /apps/safe_html_viewer/raw/{fileId} endpoint returning HTML under strict CSP sandbox (sandbox allow-scripts allow-popups, no allow-same-origin).
  • ACL enforcement via user folder view (only accessible files are returned).
  • RedactionService with best-effort display-time redaction for:
  • Email addresses
  • Phone-like strings
  • IPv4 addresses
  • Private/localhost URLs
  • Credential query patterns (password=, token=, api_key=, ...)
  • Long opaque token-like strings
  • Redaction only affects the served preview; original file content is untouched.
  • Basic PHPUnit coverage for redaction rules.
  • Documentation: README, SECURITY, CHANGELOG, AGENTS/CLAUDE guidance files.

Security

  • Sandbox is intentionally restrictive.
  • Redaction is documented as best-effort (see README and SECURITY.md).
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhN2MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwNjIzMDczNzAyWhcNMzYwOTI4MDczNzAyWjAbMRkwFwYD
VQQDDBBzYWZlX2h0bWxfdmlld2VyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAxGMMlgiIp7gqLruDW6Qi9hVAw1z6pTuhAMaZTUv1cvhRLyBTDhnHfgoZ
zy0ocEOSfNJJcNPDtcYg3yM5ndLvShwQEx6JJC8cgmNSlTQMQRr2iVYV31ukV1tw
0KlXBvrPYanqQs34Hyjvj7KFcY2AcFIMoFZj410msp2SgcKmRXP7TC/xqnC6IDgv
Taqy3j6TuQh2Z66ODgUwgxHwA+7XGd8r8oivMOdcRVWZhbjl6mCU5OMqoGwss+oq
7hpFJCcKas3lwMoE4eBrWHrpsuHv4Gq8iwma5rTk4T0p1S60hcLdFgBChuL2dhb9
XkuWlt6NZTct085za5/o7c1xsTlYyiIWK/BGPTkQSsX80CdVScda21debxFAsxBF
Z0r0MbvwRKB5kjEzQQPiia+RLPKVb/+USDlbaycRXZAthK6L4Vb1cgiYo+TwqRBa
p7YHJxGXnozs3WC3M6/ihKf4Yu630wJHWU5sH9HG3hz5BtmOWLDfHIUGOUP9O04m
1QA6lq+v3Mq0BMCF8H/EnEhK3z7noh24KL5vhmjc1E40RdTG/tK6L6YjvbIIeDtB
numfI3xsPZwDqqnN9PUEtdcbBGN+H93xipb9GB/dL6hBLa3Xe2RgYLPO/n43Goqe
p+fm+bgEHcQRZ1hAUzKkuCOKT2H9/QbL3TBfkpBwm+u9/udkarMCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAW0Vj6POpPcSRy1uErGomZAur80+IWV50hu6P2hEwTWsZ
XlaBWeveY/lfAbXJJAua33x1cmbw09SDja0FCneYf0kKNpyGoMyq+yDgM2NddSI1
ftVxhWO/1qlbkTAboLsuwbePtZqyfYMML/Cgl4DPaHu1Kx+IIJmj2A+iAryCetGe
jdlhwWbk+SZ6/KtyZy1wirPDQib8MWMGlv/RcJyZiWC4L8y1vAjqsmCDpn5r2qq+
0isqzdcR7kMy89PovRuHN5lDyocf/+GECyE8x+Y3zhm7kq4qc2SC33RGGT4IHsg+
6sTGnvQSrZPq66kqiFoQFTN/FP7KF7dUB6NX5OIZNg==
-----END CERTIFICATE-----
SignatureLIHeXIJmSLq1g/KyD/WijCOZX+Yo9A2LHW9B/WRhd2q0GcE1Jw+4bCiax7E6m7GpIm/jLmxBi6Y6gdFtKhtCnTr5pxmnL7txji8rt0CaDMUjodZ1jIK+sym+oMRhgZlmdlwJd8V1tbvZBhTDfEzFQ0atJDuymE5IhMDyHN4703aJEQ0wEDy9c14A6mo9gW6K1Ew6YicJm83/9fgPJjoI8WpvZWtq7Oylj3HzSVqzrbVO2I5PvPCUnwkEyQ4iwo0nhFeU8aRzn0a/JPlHtfmlnPjkVXU4sHKR7HopNADqIPa000N37gofqeTP6MZ3O/dgQJkHWGRjgcPxD2LDUkn4ntaizNAK3KrMSPlormfoNyQae6Z9PZqpT+DsQr54u+0iNI88pZ2sSjl2HfNdGIYLSp4K6sPZAJRa32KzgjfgQWj8UeVSvEk9lRhXzeYdCz8PckWAdaldbQaNfs6MoigqcY1gCqZxkVOKadIsiduWLkatVSUs1zNNb8y2qyiPExV2sK16wotQbxi+Z2qqpbT1lCznZdreTHKz8jBBTBe9Bt+TzESUOq8z+04DgG254BHUq9CNYWt0FvLfwjdKzbVNud5DNGCYWBz9U/qsgynYjSGy1Uz5mkKZxCeiOVuQ660mSu1/BXqEywkFnHp0/in/rxH9P8ddw3pHj5DEs0tydqY=
Signature digestsha512
Dependencies
Required Nextcloud versions >=28.0.0,<34.0.0
Minimum Integer bits32

Nextcloud 31

Safe HTML Viewer 0.1.4
Release Details
UpdatedJuly 27, 2026, 11:48 a.m.
Changelog

Fixed

  • Closing tags written inside a <script> or <style> body were deleted from the preview. libxml's HTML parser ends a raw-text body at any </, not only at the element's own end tag, and drops the rest of it, so var t = "<button><i></i>X</button>" arrived as var t = "<button><i>X". Every DOM the script then built came out mis-nested and the layout collapsed; CSS lost content: "</td>" the same way. Raw-text bodies are now held out of the document while it is parsed and put back verbatim afterwards. Present since 0.1.0, hidden behind the non-ASCII corruption that 0.1.3 fixed.
  • A <script> body that spelled out the internal <?xml encoding="utf-8" ?> parsing prefix lost that string, because the prefix was stripped from the serialized document only after the body had been reinserted.

Added

  • NOTICES.md lists the third-party licenses that travel inside the js/main.js bundle. The list is taken from a webpack stats run, so it is what the bundle actually holds after tree shaking (17 packages) rather than the whole dependency closure (59). Regenerate with npm run notices; npm run notices:check fails when it is stale.

Changed

  • LICENSE now holds the full text of the GNU Affero General Public License, version 3. It previously contained only the "how to apply" notice and a link to the text, so no copy of the license travelled with the release tarball even though that notice says one did — and GitHub could not identify the license either. The copyright line and the definition of this app's "source code" moved to the License section of the README.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhN2MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwNjIzMDczNzAyWhcNMzYwOTI4MDczNzAyWjAbMRkwFwYD
VQQDDBBzYWZlX2h0bWxfdmlld2VyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAxGMMlgiIp7gqLruDW6Qi9hVAw1z6pTuhAMaZTUv1cvhRLyBTDhnHfgoZ
zy0ocEOSfNJJcNPDtcYg3yM5ndLvShwQEx6JJC8cgmNSlTQMQRr2iVYV31ukV1tw
0KlXBvrPYanqQs34Hyjvj7KFcY2AcFIMoFZj410msp2SgcKmRXP7TC/xqnC6IDgv
Taqy3j6TuQh2Z66ODgUwgxHwA+7XGd8r8oivMOdcRVWZhbjl6mCU5OMqoGwss+oq
7hpFJCcKas3lwMoE4eBrWHrpsuHv4Gq8iwma5rTk4T0p1S60hcLdFgBChuL2dhb9
XkuWlt6NZTct085za5/o7c1xsTlYyiIWK/BGPTkQSsX80CdVScda21debxFAsxBF
Z0r0MbvwRKB5kjEzQQPiia+RLPKVb/+USDlbaycRXZAthK6L4Vb1cgiYo+TwqRBa
p7YHJxGXnozs3WC3M6/ihKf4Yu630wJHWU5sH9HG3hz5BtmOWLDfHIUGOUP9O04m
1QA6lq+v3Mq0BMCF8H/EnEhK3z7noh24KL5vhmjc1E40RdTG/tK6L6YjvbIIeDtB
numfI3xsPZwDqqnN9PUEtdcbBGN+H93xipb9GB/dL6hBLa3Xe2RgYLPO/n43Goqe
p+fm+bgEHcQRZ1hAUzKkuCOKT2H9/QbL3TBfkpBwm+u9/udkarMCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAW0Vj6POpPcSRy1uErGomZAur80+IWV50hu6P2hEwTWsZ
XlaBWeveY/lfAbXJJAua33x1cmbw09SDja0FCneYf0kKNpyGoMyq+yDgM2NddSI1
ftVxhWO/1qlbkTAboLsuwbePtZqyfYMML/Cgl4DPaHu1Kx+IIJmj2A+iAryCetGe
jdlhwWbk+SZ6/KtyZy1wirPDQib8MWMGlv/RcJyZiWC4L8y1vAjqsmCDpn5r2qq+
0isqzdcR7kMy89PovRuHN5lDyocf/+GECyE8x+Y3zhm7kq4qc2SC33RGGT4IHsg+
6sTGnvQSrZPq66kqiFoQFTN/FP7KF7dUB6NX5OIZNg==
-----END CERTIFICATE-----
Signaturepen7RR2L7DOYaTWIXcLeLFcZ/Oc6wSIokN+buzdsKkFE9MCnvRhKFwJpAWAgQW+69q9/bo+vVM2YWcwsO4SbdU+UMs3qMAWVpRvOtL5ysv/gwI3dzwoNh4yY3ToL8Tofdmb5wSpd6oPm4T9riaK3UUCKwDAMzacEqUMfhMLv1tQocq4/7TqyTwd2WtfsgUi57rTluA+QgEVMjCnMiaJEcJAZ5w42AGQUlRSuWOYuDZQ+qXxxvLxXo5pzYMl75UyrCqzUrw+26GAhXtnK/LvZ/AD18ONQm2BrINwlkPW6kEdgwKzfW4k/xAZulXjQS6Lpr1VsKfALjE01OSQ7tMMzUvbKlapjMxdIcjsIb5Hesp98c6blRccvA/HUahf5YQVPaZRcHES/8i9+OeS96QPY2zSU/oBDM9NcEzTN14pr0aiuxxsXrrrLnIE+LQst7BraimLFNwT99//BW9HFGD3zfZ5cwFQvxzgOE+nmcZbhWcN+GpM2ZnrK/qkDbOatEHNkzZv/pN+b7+MJCioHmK3ToTThh9a+4qIYjTXte2t7ZnPldYAe9FtGsTESdRh/sqVpIzRtyzG1oQIqpaYlc6a1Mj86yMvzgMXJSFagULfs66R7jEqYpo+xExpyBjK4/ivFvEAKkJxNJTvgmaGHjS4WS3NJLBzkpJq9ePROcqwFtWU=
Signature digestsha512
Dependencies
Required Nextcloud versions >=28.0.0,<34.0.0
Minimum Integer bits32
Safe HTML Viewer 0.1.3
Release Details
UpdatedJuly 27, 2026, 9:50 a.m.
Changelog

Fixed

  • Non-ASCII content (Japanese, other non-Latin scripts, emoji) was served as decimal numeric character references. DOMDocument::saveHTML() escapes every code point

    = 0x80, and browsers do not decode those inside <script> / <style> bodies, so previews of pages that build labels in JavaScript or set CSS content rendered raw &#21517; text and broken layout. Non-ASCII runs are now placeholder-swapped around serialization, so the served preview keeps the original UTF-8.

  • ISO dates in prose were redacted as phone numbers. The phone pattern allows spaces and parentheses, so a match carried its surrounding padding and the ISO-date guard never fired: 検証資料 2026-07-17 became 検証資料[REDACTED-PHONE]. Padding is now split off before the date check and re-emitted, which also preserves the spacing around genuinely redacted phone numbers.
  • A leading UTF-8 BOM made the preview come back empty. The BOM ended up between the internal encoding declaration and the document, so parsing stopped right after it — which hit every file written by an editor that emits a BOM by default (Notepad, Excel's web export, PowerShell's ConvertTo-Html).
  • Base64 data: URI payloads were redacted as opaque secrets, blanking out inline images. Such a payload is encoded binary, so the heuristics cannot recognise a secret in it but do match it by accident; base64 data URIs are now passed through. Data URIs that are not base64 stay in scope, since those carry readable text.
  • Redaction walked only the first top-level node, so content following a <script> or <style> sibling was served unredacted.
  • The <?xml encoding="utf-8" ?> prefix used to force UTF-8 parsing leaked into previews.
  • Credential patterns (password=, token=, ...) were only matched inside query strings, and the replacement dropped the parameter name. The value is now matched as bounded ASCII, so prose in scripts without ASCII word breaks (Japanese, Chinese) is not swallowed up to the end of the text node.
  • Long-token heuristic no longer swallows a host plus path as a single secret.
  • Private/localhost URL matching required a real host boundary, so public hosts such as internal.example.com are no longer treated as private.
  • Bare IPv4 redaction no longer overrides the [REDACTED-PRIVATE-URL] label.

Changed

  • The preview endpoint now serves HTML only (.html / .htm / text/html / application/xhtml+xml) and returns 415 otherwise, rejects files over 5 MiB with 413, and maps file-access failures to 404/500 instead of surfacing an exception.
  • Content-Security-Policy is extended with frame-ancestors 'self'; base-uri 'none' alongside the existing sandbox allow-scripts allow-popups (still no allow-same-origin).
  • File action id handling accepts large numeric ids as strings instead of parseInt, and preview tabs are opened with noopener,noreferrer.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhN2MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwNjIzMDczNzAyWhcNMzYwOTI4MDczNzAyWjAbMRkwFwYD
VQQDDBBzYWZlX2h0bWxfdmlld2VyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAxGMMlgiIp7gqLruDW6Qi9hVAw1z6pTuhAMaZTUv1cvhRLyBTDhnHfgoZ
zy0ocEOSfNJJcNPDtcYg3yM5ndLvShwQEx6JJC8cgmNSlTQMQRr2iVYV31ukV1tw
0KlXBvrPYanqQs34Hyjvj7KFcY2AcFIMoFZj410msp2SgcKmRXP7TC/xqnC6IDgv
Taqy3j6TuQh2Z66ODgUwgxHwA+7XGd8r8oivMOdcRVWZhbjl6mCU5OMqoGwss+oq
7hpFJCcKas3lwMoE4eBrWHrpsuHv4Gq8iwma5rTk4T0p1S60hcLdFgBChuL2dhb9
XkuWlt6NZTct085za5/o7c1xsTlYyiIWK/BGPTkQSsX80CdVScda21debxFAsxBF
Z0r0MbvwRKB5kjEzQQPiia+RLPKVb/+USDlbaycRXZAthK6L4Vb1cgiYo+TwqRBa
p7YHJxGXnozs3WC3M6/ihKf4Yu630wJHWU5sH9HG3hz5BtmOWLDfHIUGOUP9O04m
1QA6lq+v3Mq0BMCF8H/EnEhK3z7noh24KL5vhmjc1E40RdTG/tK6L6YjvbIIeDtB
numfI3xsPZwDqqnN9PUEtdcbBGN+H93xipb9GB/dL6hBLa3Xe2RgYLPO/n43Goqe
p+fm+bgEHcQRZ1hAUzKkuCOKT2H9/QbL3TBfkpBwm+u9/udkarMCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAW0Vj6POpPcSRy1uErGomZAur80+IWV50hu6P2hEwTWsZ
XlaBWeveY/lfAbXJJAua33x1cmbw09SDja0FCneYf0kKNpyGoMyq+yDgM2NddSI1
ftVxhWO/1qlbkTAboLsuwbePtZqyfYMML/Cgl4DPaHu1Kx+IIJmj2A+iAryCetGe
jdlhwWbk+SZ6/KtyZy1wirPDQib8MWMGlv/RcJyZiWC4L8y1vAjqsmCDpn5r2qq+
0isqzdcR7kMy89PovRuHN5lDyocf/+GECyE8x+Y3zhm7kq4qc2SC33RGGT4IHsg+
6sTGnvQSrZPq66kqiFoQFTN/FP7KF7dUB6NX5OIZNg==
-----END CERTIFICATE-----
SignaturerSin+ZMVn/oSIPKmIDImyuPw6gug82xtr+w9CxHVwP4U+n+469SmAYAaG5EDbtOcBVBnkMDj6f4S6PYxriMk0Ws6jyAS291cICi0mVjRftPxgfp5RjgaLCAfTCtjMubLWwF1oW/3AbY7Dn6Y72IWk79Hx9gpLM0Rk3INFGdcL/GUCGlat80bb2heAZFy4a0a7xwXpC4FwaWkWOpAV2sVd63zia+4+4RdARfnQS7R01KUfTEAuT4Gqq46cvgcpnUQhAvxzFXzjeP8opzg+kBL0yiBdeBazwE++Fw+tvM05/M16g57JslbT9xkNWdoNiEqb/A6ug19fFy0zh2YrKZt3ixTpDolURPDr0SZXICyj7f46fmXNZIELAhOyPzIVF5XQUSVKg0pTd14QQL+NuQJpg1XKBElU7btzBa9ODDDpVpdVuUMV+3lBWV1JfQtpBNOCeMcJsndcLqYHUHfiEtQGlULeYfj1ETbYYRruBvton1ZFIpkYNUYZHYV63e1cyQSf0LqgdxiJ4/o16q0sKPEpxX35XcGT9ZVZemb+L9bPQv8l4TDSzEoEW4FHEMG3p3PbB+kYNmU2Tw4MKwEewfryU0vTtVTKhPW2wLkwByV2jIQ71/83bVZbFNbzxfxWD6+M1st9Vmz9KEideXdGwYblKhW+BqLpR/xDCc1hJkMu8A=
Signature digestsha512
Dependencies
Required Nextcloud versions >=28.0.0,<34.0.0
Minimum Integer bits32
Safe HTML Viewer 0.1.2
Release Details
UpdatedJuly 3, 2026, 3:37 a.m.
Changelog

Fixed

  • App Store description rendered raw HTML tags as text: the App Store treats info.xml description as Markdown, so the description is now written in Markdown instead of HTML.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhN2MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwNjIzMDczNzAyWhcNMzYwOTI4MDczNzAyWjAbMRkwFwYD
VQQDDBBzYWZlX2h0bWxfdmlld2VyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAxGMMlgiIp7gqLruDW6Qi9hVAw1z6pTuhAMaZTUv1cvhRLyBTDhnHfgoZ
zy0ocEOSfNJJcNPDtcYg3yM5ndLvShwQEx6JJC8cgmNSlTQMQRr2iVYV31ukV1tw
0KlXBvrPYanqQs34Hyjvj7KFcY2AcFIMoFZj410msp2SgcKmRXP7TC/xqnC6IDgv
Taqy3j6TuQh2Z66ODgUwgxHwA+7XGd8r8oivMOdcRVWZhbjl6mCU5OMqoGwss+oq
7hpFJCcKas3lwMoE4eBrWHrpsuHv4Gq8iwma5rTk4T0p1S60hcLdFgBChuL2dhb9
XkuWlt6NZTct085za5/o7c1xsTlYyiIWK/BGPTkQSsX80CdVScda21debxFAsxBF
Z0r0MbvwRKB5kjEzQQPiia+RLPKVb/+USDlbaycRXZAthK6L4Vb1cgiYo+TwqRBa
p7YHJxGXnozs3WC3M6/ihKf4Yu630wJHWU5sH9HG3hz5BtmOWLDfHIUGOUP9O04m
1QA6lq+v3Mq0BMCF8H/EnEhK3z7noh24KL5vhmjc1E40RdTG/tK6L6YjvbIIeDtB
numfI3xsPZwDqqnN9PUEtdcbBGN+H93xipb9GB/dL6hBLa3Xe2RgYLPO/n43Goqe
p+fm+bgEHcQRZ1hAUzKkuCOKT2H9/QbL3TBfkpBwm+u9/udkarMCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAW0Vj6POpPcSRy1uErGomZAur80+IWV50hu6P2hEwTWsZ
XlaBWeveY/lfAbXJJAua33x1cmbw09SDja0FCneYf0kKNpyGoMyq+yDgM2NddSI1
ftVxhWO/1qlbkTAboLsuwbePtZqyfYMML/Cgl4DPaHu1Kx+IIJmj2A+iAryCetGe
jdlhwWbk+SZ6/KtyZy1wirPDQib8MWMGlv/RcJyZiWC4L8y1vAjqsmCDpn5r2qq+
0isqzdcR7kMy89PovRuHN5lDyocf/+GECyE8x+Y3zhm7kq4qc2SC33RGGT4IHsg+
6sTGnvQSrZPq66kqiFoQFTN/FP7KF7dUB6NX5OIZNg==
-----END CERTIFICATE-----
Signaturebx/keT27YaqA8wIFCi8LoWdXOvGQ/1+9fQPdoUJv/e0Z0FViwWpolmow0juKxyzQl5aKSUqPb9AsLf1m9f8yVpFtcziSry0nPzOEufBH6gq+fc6ng1JS7naLpljunVsJX4HiAFVCF/mqaoaR9J6faXXYbHSLfFIx1eLilrWUujBulCdzS2sja60Aw7tvTigFY/xkcTCNEyOU+/QdhqYQCgPlRMGFFRxpPFhPTo7p7KqETbk5J0mr7I2g/fx6xOWtCUPju6NSmqPxbqOKHrxXDfwITxCfrFsAM530gf57rHHYF16vVXcSX2K9O7Gl/cHFeCSDBh9BpBnZzQp6dzx4jDz65BUIl+O9Bex/8rGzCj7NV7tWXjmEOtIVNj0vsn+kUmqSuvE7kui+FUVwUaHPiaV4jUeFXCOV288SBACbD8IWIU2XCD3Un8kGp//fRfvd1/avtkIL5sp4ShR5N2tAuv6F7e/Gvyci75IZvJLxmbF1fNL2NnJI4+9GYgZWNYqKZeG3Zx3gcYp63owU6HncvumewDjqyiF1H4T3ah2v2/iBKUoJftSq5BYJ9u5+3KWygC0mdSQa3ib9xpuROg7kFEjT5GUxsp95IVI+h/9l+JLg2/H9EvgaLXFXLiTSxlLo66mld0T/kzfWyDn2LdmqpH/qWsUxaOm1RSoQ56UsyQc=
Signature digestsha512
Dependencies
Required Nextcloud versions >=28.0.0,<34.0.0
Minimum Integer bits32
Safe HTML Viewer 0.1.1
Release Details
UpdatedJuly 3, 2026, 3:27 a.m.
Changelog

Changed

  • Expanded the App Store description (features list, sandbox behaviour, limitations).
  • Unified author/copyright attribution to "Hiroshi Ishizaka (ishizakahiroshi)" across info.xml, composer.json, package.json and LICENSE.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhN2MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwNjIzMDczNzAyWhcNMzYwOTI4MDczNzAyWjAbMRkwFwYD
VQQDDBBzYWZlX2h0bWxfdmlld2VyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAxGMMlgiIp7gqLruDW6Qi9hVAw1z6pTuhAMaZTUv1cvhRLyBTDhnHfgoZ
zy0ocEOSfNJJcNPDtcYg3yM5ndLvShwQEx6JJC8cgmNSlTQMQRr2iVYV31ukV1tw
0KlXBvrPYanqQs34Hyjvj7KFcY2AcFIMoFZj410msp2SgcKmRXP7TC/xqnC6IDgv
Taqy3j6TuQh2Z66ODgUwgxHwA+7XGd8r8oivMOdcRVWZhbjl6mCU5OMqoGwss+oq
7hpFJCcKas3lwMoE4eBrWHrpsuHv4Gq8iwma5rTk4T0p1S60hcLdFgBChuL2dhb9
XkuWlt6NZTct085za5/o7c1xsTlYyiIWK/BGPTkQSsX80CdVScda21debxFAsxBF
Z0r0MbvwRKB5kjEzQQPiia+RLPKVb/+USDlbaycRXZAthK6L4Vb1cgiYo+TwqRBa
p7YHJxGXnozs3WC3M6/ihKf4Yu630wJHWU5sH9HG3hz5BtmOWLDfHIUGOUP9O04m
1QA6lq+v3Mq0BMCF8H/EnEhK3z7noh24KL5vhmjc1E40RdTG/tK6L6YjvbIIeDtB
numfI3xsPZwDqqnN9PUEtdcbBGN+H93xipb9GB/dL6hBLa3Xe2RgYLPO/n43Goqe
p+fm+bgEHcQRZ1hAUzKkuCOKT2H9/QbL3TBfkpBwm+u9/udkarMCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAW0Vj6POpPcSRy1uErGomZAur80+IWV50hu6P2hEwTWsZ
XlaBWeveY/lfAbXJJAua33x1cmbw09SDja0FCneYf0kKNpyGoMyq+yDgM2NddSI1
ftVxhWO/1qlbkTAboLsuwbePtZqyfYMML/Cgl4DPaHu1Kx+IIJmj2A+iAryCetGe
jdlhwWbk+SZ6/KtyZy1wirPDQib8MWMGlv/RcJyZiWC4L8y1vAjqsmCDpn5r2qq+
0isqzdcR7kMy89PovRuHN5lDyocf/+GECyE8x+Y3zhm7kq4qc2SC33RGGT4IHsg+
6sTGnvQSrZPq66kqiFoQFTN/FP7KF7dUB6NX5OIZNg==
-----END CERTIFICATE-----
SignaturefVBl4DuXEO4qJ13HX0BQTQPTJ6DCZazoiprU2vZQhaksRZwl6gadG3Fkxbq1iGK9fIEfQKvj2gLxLzxWq+WNruBIvXTdQZm30rzQSY4sksRj7ewgDGe6libZf1Q8kfQQ6pwd0c+Wboxz+cmdZhettNKBuLNKsl2s+zIIOyMYl4x7CjP90Kl7YoZdIbgnVPeOY4X4Auti+FvrANb4JMP3uzkflg4S+E7La5DILPHFsWag2c6JivrQ6AOOluDbXlddMdMY7vwrJ8zKCzZetqCUaTBCifSuvQ6JORujThAdGm52xr4BZjQ7C8QH9laTr6Zzj1v4PQVDuLU7NRzeIH9m6euK6z4bSt2bQUY3mQ21/dvD5HI40jS9yXns17fdKRFPgsgdZdyQtOGJjlZN4+lK3anJ02a3oDtsVbQq0FrQAkb0ALB53/j1A4y2K3n4MkzhIOWuxYyXsbkeQjWO2eB6DC26tfXt6O5VOntcI7caQcKjazDZnPvyam/QRSuTL4xDgLi6KR3sbwyxbQaU6+IIeUfZkykJngV/SU1iZ8YctfudJmsXmkIFfDpVBsoQPoe64S+vPJYHJ3z/sU5J9FIcufVw8HYww1uT2Settt3U1yIIFZ33oLzfcNbeWj6gXsHBs6QG5vKsBzxeBGu+194KhNh9MAfopvtLlXRnY/C0A+c=
Signature digestsha512
Dependencies
Required Nextcloud versions >=28.0.0,<34.0.0
Minimum Integer bits32
Safe HTML Viewer 0.1.0
Release Details
UpdatedJuly 3, 2026, 3:01 a.m.
Changelog

Added

  • Initial public release of safe_html_viewer.
  • File action registration for .html / text/html files.
  • /apps/safe_html_viewer/raw/{fileId} endpoint returning HTML under strict CSP sandbox (sandbox allow-scripts allow-popups, no allow-same-origin).
  • ACL enforcement via user folder view (only accessible files are returned).
  • RedactionService with best-effort display-time redaction for:
  • Email addresses
  • Phone-like strings
  • IPv4 addresses
  • Private/localhost URLs
  • Credential query patterns (password=, token=, api_key=, ...)
  • Long opaque token-like strings
  • Redaction only affects the served preview; original file content is untouched.
  • Basic PHPUnit coverage for redaction rules.
  • Documentation: README, SECURITY, CHANGELOG, AGENTS/CLAUDE guidance files.

Security

  • Sandbox is intentionally restrictive.
  • Redaction is documented as best-effort (see README and SECURITY.md).
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhN2MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwNjIzMDczNzAyWhcNMzYwOTI4MDczNzAyWjAbMRkwFwYD
VQQDDBBzYWZlX2h0bWxfdmlld2VyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAxGMMlgiIp7gqLruDW6Qi9hVAw1z6pTuhAMaZTUv1cvhRLyBTDhnHfgoZ
zy0ocEOSfNJJcNPDtcYg3yM5ndLvShwQEx6JJC8cgmNSlTQMQRr2iVYV31ukV1tw
0KlXBvrPYanqQs34Hyjvj7KFcY2AcFIMoFZj410msp2SgcKmRXP7TC/xqnC6IDgv
Taqy3j6TuQh2Z66ODgUwgxHwA+7XGd8r8oivMOdcRVWZhbjl6mCU5OMqoGwss+oq
7hpFJCcKas3lwMoE4eBrWHrpsuHv4Gq8iwma5rTk4T0p1S60hcLdFgBChuL2dhb9
XkuWlt6NZTct085za5/o7c1xsTlYyiIWK/BGPTkQSsX80CdVScda21debxFAsxBF
Z0r0MbvwRKB5kjEzQQPiia+RLPKVb/+USDlbaycRXZAthK6L4Vb1cgiYo+TwqRBa
p7YHJxGXnozs3WC3M6/ihKf4Yu630wJHWU5sH9HG3hz5BtmOWLDfHIUGOUP9O04m
1QA6lq+v3Mq0BMCF8H/EnEhK3z7noh24KL5vhmjc1E40RdTG/tK6L6YjvbIIeDtB
numfI3xsPZwDqqnN9PUEtdcbBGN+H93xipb9GB/dL6hBLa3Xe2RgYLPO/n43Goqe
p+fm+bgEHcQRZ1hAUzKkuCOKT2H9/QbL3TBfkpBwm+u9/udkarMCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAW0Vj6POpPcSRy1uErGomZAur80+IWV50hu6P2hEwTWsZ
XlaBWeveY/lfAbXJJAua33x1cmbw09SDja0FCneYf0kKNpyGoMyq+yDgM2NddSI1
ftVxhWO/1qlbkTAboLsuwbePtZqyfYMML/Cgl4DPaHu1Kx+IIJmj2A+iAryCetGe
jdlhwWbk+SZ6/KtyZy1wirPDQib8MWMGlv/RcJyZiWC4L8y1vAjqsmCDpn5r2qq+
0isqzdcR7kMy89PovRuHN5lDyocf/+GECyE8x+Y3zhm7kq4qc2SC33RGGT4IHsg+
6sTGnvQSrZPq66kqiFoQFTN/FP7KF7dUB6NX5OIZNg==
-----END CERTIFICATE-----
SignatureLIHeXIJmSLq1g/KyD/WijCOZX+Yo9A2LHW9B/WRhd2q0GcE1Jw+4bCiax7E6m7GpIm/jLmxBi6Y6gdFtKhtCnTr5pxmnL7txji8rt0CaDMUjodZ1jIK+sym+oMRhgZlmdlwJd8V1tbvZBhTDfEzFQ0atJDuymE5IhMDyHN4703aJEQ0wEDy9c14A6mo9gW6K1Ew6YicJm83/9fgPJjoI8WpvZWtq7Oylj3HzSVqzrbVO2I5PvPCUnwkEyQ4iwo0nhFeU8aRzn0a/JPlHtfmlnPjkVXU4sHKR7HopNADqIPa000N37gofqeTP6MZ3O/dgQJkHWGRjgcPxD2LDUkn4ntaizNAK3KrMSPlormfoNyQae6Z9PZqpT+DsQr54u+0iNI88pZ2sSjl2HfNdGIYLSp4K6sPZAJRa32KzgjfgQWj8UeVSvEk9lRhXzeYdCz8PckWAdaldbQaNfs6MoigqcY1gCqZxkVOKadIsiduWLkatVSUs1zNNb8y2qyiPExV2sK16wotQbxi+Z2qqpbT1lCznZdreTHKz8jBBTBe9Bt+TzESUOq8z+04DgG254BHUq9CNYWt0FvLfwjdKzbVNud5DNGCYWBz9U/qsgynYjSGy1Uz5mkKZxCeiOVuQ660mSu1/BXqEywkFnHp0/in/rxH9P8ddw3pHj5DEs0tydqY=
Signature digestsha512
Dependencies
Required Nextcloud versions >=28.0.0,<34.0.0
Minimum Integer bits32

Nextcloud 30

Safe HTML Viewer 0.1.4
Release Details
UpdatedJuly 27, 2026, 11:48 a.m.
Changelog

Fixed

  • Closing tags written inside a <script> or <style> body were deleted from the preview. libxml's HTML parser ends a raw-text body at any </, not only at the element's own end tag, and drops the rest of it, so var t = "<button><i></i>X</button>" arrived as var t = "<button><i>X". Every DOM the script then built came out mis-nested and the layout collapsed; CSS lost content: "</td>" the same way. Raw-text bodies are now held out of the document while it is parsed and put back verbatim afterwards. Present since 0.1.0, hidden behind the non-ASCII corruption that 0.1.3 fixed.
  • A <script> body that spelled out the internal <?xml encoding="utf-8" ?> parsing prefix lost that string, because the prefix was stripped from the serialized document only after the body had been reinserted.

Added

  • NOTICES.md lists the third-party licenses that travel inside the js/main.js bundle. The list is taken from a webpack stats run, so it is what the bundle actually holds after tree shaking (17 packages) rather than the whole dependency closure (59). Regenerate with npm run notices; npm run notices:check fails when it is stale.

Changed

  • LICENSE now holds the full text of the GNU Affero General Public License, version 3. It previously contained only the "how to apply" notice and a link to the text, so no copy of the license travelled with the release tarball even though that notice says one did — and GitHub could not identify the license either. The copyright line and the definition of this app's "source code" moved to the License section of the README.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhN2MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwNjIzMDczNzAyWhcNMzYwOTI4MDczNzAyWjAbMRkwFwYD
VQQDDBBzYWZlX2h0bWxfdmlld2VyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAxGMMlgiIp7gqLruDW6Qi9hVAw1z6pTuhAMaZTUv1cvhRLyBTDhnHfgoZ
zy0ocEOSfNJJcNPDtcYg3yM5ndLvShwQEx6JJC8cgmNSlTQMQRr2iVYV31ukV1tw
0KlXBvrPYanqQs34Hyjvj7KFcY2AcFIMoFZj410msp2SgcKmRXP7TC/xqnC6IDgv
Taqy3j6TuQh2Z66ODgUwgxHwA+7XGd8r8oivMOdcRVWZhbjl6mCU5OMqoGwss+oq
7hpFJCcKas3lwMoE4eBrWHrpsuHv4Gq8iwma5rTk4T0p1S60hcLdFgBChuL2dhb9
XkuWlt6NZTct085za5/o7c1xsTlYyiIWK/BGPTkQSsX80CdVScda21debxFAsxBF
Z0r0MbvwRKB5kjEzQQPiia+RLPKVb/+USDlbaycRXZAthK6L4Vb1cgiYo+TwqRBa
p7YHJxGXnozs3WC3M6/ihKf4Yu630wJHWU5sH9HG3hz5BtmOWLDfHIUGOUP9O04m
1QA6lq+v3Mq0BMCF8H/EnEhK3z7noh24KL5vhmjc1E40RdTG/tK6L6YjvbIIeDtB
numfI3xsPZwDqqnN9PUEtdcbBGN+H93xipb9GB/dL6hBLa3Xe2RgYLPO/n43Goqe
p+fm+bgEHcQRZ1hAUzKkuCOKT2H9/QbL3TBfkpBwm+u9/udkarMCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAW0Vj6POpPcSRy1uErGomZAur80+IWV50hu6P2hEwTWsZ
XlaBWeveY/lfAbXJJAua33x1cmbw09SDja0FCneYf0kKNpyGoMyq+yDgM2NddSI1
ftVxhWO/1qlbkTAboLsuwbePtZqyfYMML/Cgl4DPaHu1Kx+IIJmj2A+iAryCetGe
jdlhwWbk+SZ6/KtyZy1wirPDQib8MWMGlv/RcJyZiWC4L8y1vAjqsmCDpn5r2qq+
0isqzdcR7kMy89PovRuHN5lDyocf/+GECyE8x+Y3zhm7kq4qc2SC33RGGT4IHsg+
6sTGnvQSrZPq66kqiFoQFTN/FP7KF7dUB6NX5OIZNg==
-----END CERTIFICATE-----
Signaturepen7RR2L7DOYaTWIXcLeLFcZ/Oc6wSIokN+buzdsKkFE9MCnvRhKFwJpAWAgQW+69q9/bo+vVM2YWcwsO4SbdU+UMs3qMAWVpRvOtL5ysv/gwI3dzwoNh4yY3ToL8Tofdmb5wSpd6oPm4T9riaK3UUCKwDAMzacEqUMfhMLv1tQocq4/7TqyTwd2WtfsgUi57rTluA+QgEVMjCnMiaJEcJAZ5w42AGQUlRSuWOYuDZQ+qXxxvLxXo5pzYMl75UyrCqzUrw+26GAhXtnK/LvZ/AD18ONQm2BrINwlkPW6kEdgwKzfW4k/xAZulXjQS6Lpr1VsKfALjE01OSQ7tMMzUvbKlapjMxdIcjsIb5Hesp98c6blRccvA/HUahf5YQVPaZRcHES/8i9+OeS96QPY2zSU/oBDM9NcEzTN14pr0aiuxxsXrrrLnIE+LQst7BraimLFNwT99//BW9HFGD3zfZ5cwFQvxzgOE+nmcZbhWcN+GpM2ZnrK/qkDbOatEHNkzZv/pN+b7+MJCioHmK3ToTThh9a+4qIYjTXte2t7ZnPldYAe9FtGsTESdRh/sqVpIzRtyzG1oQIqpaYlc6a1Mj86yMvzgMXJSFagULfs66R7jEqYpo+xExpyBjK4/ivFvEAKkJxNJTvgmaGHjS4WS3NJLBzkpJq9ePROcqwFtWU=
Signature digestsha512
Dependencies
Required Nextcloud versions >=28.0.0,<34.0.0
Minimum Integer bits32
Safe HTML Viewer 0.1.3
Release Details
UpdatedJuly 27, 2026, 9:50 a.m.
Changelog

Fixed

  • Non-ASCII content (Japanese, other non-Latin scripts, emoji) was served as decimal numeric character references. DOMDocument::saveHTML() escapes every code point

    = 0x80, and browsers do not decode those inside <script> / <style> bodies, so previews of pages that build labels in JavaScript or set CSS content rendered raw &#21517; text and broken layout. Non-ASCII runs are now placeholder-swapped around serialization, so the served preview keeps the original UTF-8.

  • ISO dates in prose were redacted as phone numbers. The phone pattern allows spaces and parentheses, so a match carried its surrounding padding and the ISO-date guard never fired: 検証資料 2026-07-17 became 検証資料[REDACTED-PHONE]. Padding is now split off before the date check and re-emitted, which also preserves the spacing around genuinely redacted phone numbers.
  • A leading UTF-8 BOM made the preview come back empty. The BOM ended up between the internal encoding declaration and the document, so parsing stopped right after it — which hit every file written by an editor that emits a BOM by default (Notepad, Excel's web export, PowerShell's ConvertTo-Html).
  • Base64 data: URI payloads were redacted as opaque secrets, blanking out inline images. Such a payload is encoded binary, so the heuristics cannot recognise a secret in it but do match it by accident; base64 data URIs are now passed through. Data URIs that are not base64 stay in scope, since those carry readable text.
  • Redaction walked only the first top-level node, so content following a <script> or <style> sibling was served unredacted.
  • The <?xml encoding="utf-8" ?> prefix used to force UTF-8 parsing leaked into previews.
  • Credential patterns (password=, token=, ...) were only matched inside query strings, and the replacement dropped the parameter name. The value is now matched as bounded ASCII, so prose in scripts without ASCII word breaks (Japanese, Chinese) is not swallowed up to the end of the text node.
  • Long-token heuristic no longer swallows a host plus path as a single secret.
  • Private/localhost URL matching required a real host boundary, so public hosts such as internal.example.com are no longer treated as private.
  • Bare IPv4 redaction no longer overrides the [REDACTED-PRIVATE-URL] label.

Changed

  • The preview endpoint now serves HTML only (.html / .htm / text/html / application/xhtml+xml) and returns 415 otherwise, rejects files over 5 MiB with 413, and maps file-access failures to 404/500 instead of surfacing an exception.
  • Content-Security-Policy is extended with frame-ancestors 'self'; base-uri 'none' alongside the existing sandbox allow-scripts allow-popups (still no allow-same-origin).
  • File action id handling accepts large numeric ids as strings instead of parseInt, and preview tabs are opened with noopener,noreferrer.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhN2MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwNjIzMDczNzAyWhcNMzYwOTI4MDczNzAyWjAbMRkwFwYD
VQQDDBBzYWZlX2h0bWxfdmlld2VyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAxGMMlgiIp7gqLruDW6Qi9hVAw1z6pTuhAMaZTUv1cvhRLyBTDhnHfgoZ
zy0ocEOSfNJJcNPDtcYg3yM5ndLvShwQEx6JJC8cgmNSlTQMQRr2iVYV31ukV1tw
0KlXBvrPYanqQs34Hyjvj7KFcY2AcFIMoFZj410msp2SgcKmRXP7TC/xqnC6IDgv
Taqy3j6TuQh2Z66ODgUwgxHwA+7XGd8r8oivMOdcRVWZhbjl6mCU5OMqoGwss+oq
7hpFJCcKas3lwMoE4eBrWHrpsuHv4Gq8iwma5rTk4T0p1S60hcLdFgBChuL2dhb9
XkuWlt6NZTct085za5/o7c1xsTlYyiIWK/BGPTkQSsX80CdVScda21debxFAsxBF
Z0r0MbvwRKB5kjEzQQPiia+RLPKVb/+USDlbaycRXZAthK6L4Vb1cgiYo+TwqRBa
p7YHJxGXnozs3WC3M6/ihKf4Yu630wJHWU5sH9HG3hz5BtmOWLDfHIUGOUP9O04m
1QA6lq+v3Mq0BMCF8H/EnEhK3z7noh24KL5vhmjc1E40RdTG/tK6L6YjvbIIeDtB
numfI3xsPZwDqqnN9PUEtdcbBGN+H93xipb9GB/dL6hBLa3Xe2RgYLPO/n43Goqe
p+fm+bgEHcQRZ1hAUzKkuCOKT2H9/QbL3TBfkpBwm+u9/udkarMCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAW0Vj6POpPcSRy1uErGomZAur80+IWV50hu6P2hEwTWsZ
XlaBWeveY/lfAbXJJAua33x1cmbw09SDja0FCneYf0kKNpyGoMyq+yDgM2NddSI1
ftVxhWO/1qlbkTAboLsuwbePtZqyfYMML/Cgl4DPaHu1Kx+IIJmj2A+iAryCetGe
jdlhwWbk+SZ6/KtyZy1wirPDQib8MWMGlv/RcJyZiWC4L8y1vAjqsmCDpn5r2qq+
0isqzdcR7kMy89PovRuHN5lDyocf/+GECyE8x+Y3zhm7kq4qc2SC33RGGT4IHsg+
6sTGnvQSrZPq66kqiFoQFTN/FP7KF7dUB6NX5OIZNg==
-----END CERTIFICATE-----
SignaturerSin+ZMVn/oSIPKmIDImyuPw6gug82xtr+w9CxHVwP4U+n+469SmAYAaG5EDbtOcBVBnkMDj6f4S6PYxriMk0Ws6jyAS291cICi0mVjRftPxgfp5RjgaLCAfTCtjMubLWwF1oW/3AbY7Dn6Y72IWk79Hx9gpLM0Rk3INFGdcL/GUCGlat80bb2heAZFy4a0a7xwXpC4FwaWkWOpAV2sVd63zia+4+4RdARfnQS7R01KUfTEAuT4Gqq46cvgcpnUQhAvxzFXzjeP8opzg+kBL0yiBdeBazwE++Fw+tvM05/M16g57JslbT9xkNWdoNiEqb/A6ug19fFy0zh2YrKZt3ixTpDolURPDr0SZXICyj7f46fmXNZIELAhOyPzIVF5XQUSVKg0pTd14QQL+NuQJpg1XKBElU7btzBa9ODDDpVpdVuUMV+3lBWV1JfQtpBNOCeMcJsndcLqYHUHfiEtQGlULeYfj1ETbYYRruBvton1ZFIpkYNUYZHYV63e1cyQSf0LqgdxiJ4/o16q0sKPEpxX35XcGT9ZVZemb+L9bPQv8l4TDSzEoEW4FHEMG3p3PbB+kYNmU2Tw4MKwEewfryU0vTtVTKhPW2wLkwByV2jIQ71/83bVZbFNbzxfxWD6+M1st9Vmz9KEideXdGwYblKhW+BqLpR/xDCc1hJkMu8A=
Signature digestsha512
Dependencies
Required Nextcloud versions >=28.0.0,<34.0.0
Minimum Integer bits32
Safe HTML Viewer 0.1.2
Release Details
UpdatedJuly 3, 2026, 3:37 a.m.
Changelog

Fixed

  • App Store description rendered raw HTML tags as text: the App Store treats info.xml description as Markdown, so the description is now written in Markdown instead of HTML.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhN2MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwNjIzMDczNzAyWhcNMzYwOTI4MDczNzAyWjAbMRkwFwYD
VQQDDBBzYWZlX2h0bWxfdmlld2VyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAxGMMlgiIp7gqLruDW6Qi9hVAw1z6pTuhAMaZTUv1cvhRLyBTDhnHfgoZ
zy0ocEOSfNJJcNPDtcYg3yM5ndLvShwQEx6JJC8cgmNSlTQMQRr2iVYV31ukV1tw
0KlXBvrPYanqQs34Hyjvj7KFcY2AcFIMoFZj410msp2SgcKmRXP7TC/xqnC6IDgv
Taqy3j6TuQh2Z66ODgUwgxHwA+7XGd8r8oivMOdcRVWZhbjl6mCU5OMqoGwss+oq
7hpFJCcKas3lwMoE4eBrWHrpsuHv4Gq8iwma5rTk4T0p1S60hcLdFgBChuL2dhb9
XkuWlt6NZTct085za5/o7c1xsTlYyiIWK/BGPTkQSsX80CdVScda21debxFAsxBF
Z0r0MbvwRKB5kjEzQQPiia+RLPKVb/+USDlbaycRXZAthK6L4Vb1cgiYo+TwqRBa
p7YHJxGXnozs3WC3M6/ihKf4Yu630wJHWU5sH9HG3hz5BtmOWLDfHIUGOUP9O04m
1QA6lq+v3Mq0BMCF8H/EnEhK3z7noh24KL5vhmjc1E40RdTG/tK6L6YjvbIIeDtB
numfI3xsPZwDqqnN9PUEtdcbBGN+H93xipb9GB/dL6hBLa3Xe2RgYLPO/n43Goqe
p+fm+bgEHcQRZ1hAUzKkuCOKT2H9/QbL3TBfkpBwm+u9/udkarMCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAW0Vj6POpPcSRy1uErGomZAur80+IWV50hu6P2hEwTWsZ
XlaBWeveY/lfAbXJJAua33x1cmbw09SDja0FCneYf0kKNpyGoMyq+yDgM2NddSI1
ftVxhWO/1qlbkTAboLsuwbePtZqyfYMML/Cgl4DPaHu1Kx+IIJmj2A+iAryCetGe
jdlhwWbk+SZ6/KtyZy1wirPDQib8MWMGlv/RcJyZiWC4L8y1vAjqsmCDpn5r2qq+
0isqzdcR7kMy89PovRuHN5lDyocf/+GECyE8x+Y3zhm7kq4qc2SC33RGGT4IHsg+
6sTGnvQSrZPq66kqiFoQFTN/FP7KF7dUB6NX5OIZNg==
-----END CERTIFICATE-----
Signaturebx/keT27YaqA8wIFCi8LoWdXOvGQ/1+9fQPdoUJv/e0Z0FViwWpolmow0juKxyzQl5aKSUqPb9AsLf1m9f8yVpFtcziSry0nPzOEufBH6gq+fc6ng1JS7naLpljunVsJX4HiAFVCF/mqaoaR9J6faXXYbHSLfFIx1eLilrWUujBulCdzS2sja60Aw7tvTigFY/xkcTCNEyOU+/QdhqYQCgPlRMGFFRxpPFhPTo7p7KqETbk5J0mr7I2g/fx6xOWtCUPju6NSmqPxbqOKHrxXDfwITxCfrFsAM530gf57rHHYF16vVXcSX2K9O7Gl/cHFeCSDBh9BpBnZzQp6dzx4jDz65BUIl+O9Bex/8rGzCj7NV7tWXjmEOtIVNj0vsn+kUmqSuvE7kui+FUVwUaHPiaV4jUeFXCOV288SBACbD8IWIU2XCD3Un8kGp//fRfvd1/avtkIL5sp4ShR5N2tAuv6F7e/Gvyci75IZvJLxmbF1fNL2NnJI4+9GYgZWNYqKZeG3Zx3gcYp63owU6HncvumewDjqyiF1H4T3ah2v2/iBKUoJftSq5BYJ9u5+3KWygC0mdSQa3ib9xpuROg7kFEjT5GUxsp95IVI+h/9l+JLg2/H9EvgaLXFXLiTSxlLo66mld0T/kzfWyDn2LdmqpH/qWsUxaOm1RSoQ56UsyQc=
Signature digestsha512
Dependencies
Required Nextcloud versions >=28.0.0,<34.0.0
Minimum Integer bits32
Safe HTML Viewer 0.1.1
Release Details
UpdatedJuly 3, 2026, 3:27 a.m.
Changelog

Changed

  • Expanded the App Store description (features list, sandbox behaviour, limitations).
  • Unified author/copyright attribution to "Hiroshi Ishizaka (ishizakahiroshi)" across info.xml, composer.json, package.json and LICENSE.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhN2MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwNjIzMDczNzAyWhcNMzYwOTI4MDczNzAyWjAbMRkwFwYD
VQQDDBBzYWZlX2h0bWxfdmlld2VyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAxGMMlgiIp7gqLruDW6Qi9hVAw1z6pTuhAMaZTUv1cvhRLyBTDhnHfgoZ
zy0ocEOSfNJJcNPDtcYg3yM5ndLvShwQEx6JJC8cgmNSlTQMQRr2iVYV31ukV1tw
0KlXBvrPYanqQs34Hyjvj7KFcY2AcFIMoFZj410msp2SgcKmRXP7TC/xqnC6IDgv
Taqy3j6TuQh2Z66ODgUwgxHwA+7XGd8r8oivMOdcRVWZhbjl6mCU5OMqoGwss+oq
7hpFJCcKas3lwMoE4eBrWHrpsuHv4Gq8iwma5rTk4T0p1S60hcLdFgBChuL2dhb9
XkuWlt6NZTct085za5/o7c1xsTlYyiIWK/BGPTkQSsX80CdVScda21debxFAsxBF
Z0r0MbvwRKB5kjEzQQPiia+RLPKVb/+USDlbaycRXZAthK6L4Vb1cgiYo+TwqRBa
p7YHJxGXnozs3WC3M6/ihKf4Yu630wJHWU5sH9HG3hz5BtmOWLDfHIUGOUP9O04m
1QA6lq+v3Mq0BMCF8H/EnEhK3z7noh24KL5vhmjc1E40RdTG/tK6L6YjvbIIeDtB
numfI3xsPZwDqqnN9PUEtdcbBGN+H93xipb9GB/dL6hBLa3Xe2RgYLPO/n43Goqe
p+fm+bgEHcQRZ1hAUzKkuCOKT2H9/QbL3TBfkpBwm+u9/udkarMCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAW0Vj6POpPcSRy1uErGomZAur80+IWV50hu6P2hEwTWsZ
XlaBWeveY/lfAbXJJAua33x1cmbw09SDja0FCneYf0kKNpyGoMyq+yDgM2NddSI1
ftVxhWO/1qlbkTAboLsuwbePtZqyfYMML/Cgl4DPaHu1Kx+IIJmj2A+iAryCetGe
jdlhwWbk+SZ6/KtyZy1wirPDQib8MWMGlv/RcJyZiWC4L8y1vAjqsmCDpn5r2qq+
0isqzdcR7kMy89PovRuHN5lDyocf/+GECyE8x+Y3zhm7kq4qc2SC33RGGT4IHsg+
6sTGnvQSrZPq66kqiFoQFTN/FP7KF7dUB6NX5OIZNg==
-----END CERTIFICATE-----
SignaturefVBl4DuXEO4qJ13HX0BQTQPTJ6DCZazoiprU2vZQhaksRZwl6gadG3Fkxbq1iGK9fIEfQKvj2gLxLzxWq+WNruBIvXTdQZm30rzQSY4sksRj7ewgDGe6libZf1Q8kfQQ6pwd0c+Wboxz+cmdZhettNKBuLNKsl2s+zIIOyMYl4x7CjP90Kl7YoZdIbgnVPeOY4X4Auti+FvrANb4JMP3uzkflg4S+E7La5DILPHFsWag2c6JivrQ6AOOluDbXlddMdMY7vwrJ8zKCzZetqCUaTBCifSuvQ6JORujThAdGm52xr4BZjQ7C8QH9laTr6Zzj1v4PQVDuLU7NRzeIH9m6euK6z4bSt2bQUY3mQ21/dvD5HI40jS9yXns17fdKRFPgsgdZdyQtOGJjlZN4+lK3anJ02a3oDtsVbQq0FrQAkb0ALB53/j1A4y2K3n4MkzhIOWuxYyXsbkeQjWO2eB6DC26tfXt6O5VOntcI7caQcKjazDZnPvyam/QRSuTL4xDgLi6KR3sbwyxbQaU6+IIeUfZkykJngV/SU1iZ8YctfudJmsXmkIFfDpVBsoQPoe64S+vPJYHJ3z/sU5J9FIcufVw8HYww1uT2Settt3U1yIIFZ33oLzfcNbeWj6gXsHBs6QG5vKsBzxeBGu+194KhNh9MAfopvtLlXRnY/C0A+c=
Signature digestsha512
Dependencies
Required Nextcloud versions >=28.0.0,<34.0.0
Minimum Integer bits32
Safe HTML Viewer 0.1.0
Release Details
UpdatedJuly 3, 2026, 3:01 a.m.
Changelog

Added

  • Initial public release of safe_html_viewer.
  • File action registration for .html / text/html files.
  • /apps/safe_html_viewer/raw/{fileId} endpoint returning HTML under strict CSP sandbox (sandbox allow-scripts allow-popups, no allow-same-origin).
  • ACL enforcement via user folder view (only accessible files are returned).
  • RedactionService with best-effort display-time redaction for:
  • Email addresses
  • Phone-like strings
  • IPv4 addresses
  • Private/localhost URLs
  • Credential query patterns (password=, token=, api_key=, ...)
  • Long opaque token-like strings
  • Redaction only affects the served preview; original file content is untouched.
  • Basic PHPUnit coverage for redaction rules.
  • Documentation: README, SECURITY, CHANGELOG, AGENTS/CLAUDE guidance files.

Security

  • Sandbox is intentionally restrictive.
  • Redaction is documented as best-effort (see README and SECURITY.md).
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhN2MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwNjIzMDczNzAyWhcNMzYwOTI4MDczNzAyWjAbMRkwFwYD
VQQDDBBzYWZlX2h0bWxfdmlld2VyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAxGMMlgiIp7gqLruDW6Qi9hVAw1z6pTuhAMaZTUv1cvhRLyBTDhnHfgoZ
zy0ocEOSfNJJcNPDtcYg3yM5ndLvShwQEx6JJC8cgmNSlTQMQRr2iVYV31ukV1tw
0KlXBvrPYanqQs34Hyjvj7KFcY2AcFIMoFZj410msp2SgcKmRXP7TC/xqnC6IDgv
Taqy3j6TuQh2Z66ODgUwgxHwA+7XGd8r8oivMOdcRVWZhbjl6mCU5OMqoGwss+oq
7hpFJCcKas3lwMoE4eBrWHrpsuHv4Gq8iwma5rTk4T0p1S60hcLdFgBChuL2dhb9
XkuWlt6NZTct085za5/o7c1xsTlYyiIWK/BGPTkQSsX80CdVScda21debxFAsxBF
Z0r0MbvwRKB5kjEzQQPiia+RLPKVb/+USDlbaycRXZAthK6L4Vb1cgiYo+TwqRBa
p7YHJxGXnozs3WC3M6/ihKf4Yu630wJHWU5sH9HG3hz5BtmOWLDfHIUGOUP9O04m
1QA6lq+v3Mq0BMCF8H/EnEhK3z7noh24KL5vhmjc1E40RdTG/tK6L6YjvbIIeDtB
numfI3xsPZwDqqnN9PUEtdcbBGN+H93xipb9GB/dL6hBLa3Xe2RgYLPO/n43Goqe
p+fm+bgEHcQRZ1hAUzKkuCOKT2H9/QbL3TBfkpBwm+u9/udkarMCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAW0Vj6POpPcSRy1uErGomZAur80+IWV50hu6P2hEwTWsZ
XlaBWeveY/lfAbXJJAua33x1cmbw09SDja0FCneYf0kKNpyGoMyq+yDgM2NddSI1
ftVxhWO/1qlbkTAboLsuwbePtZqyfYMML/Cgl4DPaHu1Kx+IIJmj2A+iAryCetGe
jdlhwWbk+SZ6/KtyZy1wirPDQib8MWMGlv/RcJyZiWC4L8y1vAjqsmCDpn5r2qq+
0isqzdcR7kMy89PovRuHN5lDyocf/+GECyE8x+Y3zhm7kq4qc2SC33RGGT4IHsg+
6sTGnvQSrZPq66kqiFoQFTN/FP7KF7dUB6NX5OIZNg==
-----END CERTIFICATE-----
SignatureLIHeXIJmSLq1g/KyD/WijCOZX+Yo9A2LHW9B/WRhd2q0GcE1Jw+4bCiax7E6m7GpIm/jLmxBi6Y6gdFtKhtCnTr5pxmnL7txji8rt0CaDMUjodZ1jIK+sym+oMRhgZlmdlwJd8V1tbvZBhTDfEzFQ0atJDuymE5IhMDyHN4703aJEQ0wEDy9c14A6mo9gW6K1Ew6YicJm83/9fgPJjoI8WpvZWtq7Oylj3HzSVqzrbVO2I5PvPCUnwkEyQ4iwo0nhFeU8aRzn0a/JPlHtfmlnPjkVXU4sHKR7HopNADqIPa000N37gofqeTP6MZ3O/dgQJkHWGRjgcPxD2LDUkn4ntaizNAK3KrMSPlormfoNyQae6Z9PZqpT+DsQr54u+0iNI88pZ2sSjl2HfNdGIYLSp4K6sPZAJRa32KzgjfgQWj8UeVSvEk9lRhXzeYdCz8PckWAdaldbQaNfs6MoigqcY1gCqZxkVOKadIsiduWLkatVSUs1zNNb8y2qyiPExV2sK16wotQbxi+Z2qqpbT1lCznZdreTHKz8jBBTBe9Bt+TzESUOq8z+04DgG254BHUq9CNYWt0FvLfwjdKzbVNud5DNGCYWBz9U/qsgynYjSGy1Uz5mkKZxCeiOVuQ660mSu1/BXqEywkFnHp0/in/rxH9P8ddw3pHj5DEs0tydqY=
Signature digestsha512
Dependencies
Required Nextcloud versions >=28.0.0,<34.0.0
Minimum Integer bits32

Nextcloud 29

Safe HTML Viewer 0.1.4
Release Details
UpdatedJuly 27, 2026, 11:48 a.m.
Changelog

Fixed

  • Closing tags written inside a <script> or <style> body were deleted from the preview. libxml's HTML parser ends a raw-text body at any </, not only at the element's own end tag, and drops the rest of it, so var t = "<button><i></i>X</button>" arrived as var t = "<button><i>X". Every DOM the script then built came out mis-nested and the layout collapsed; CSS lost content: "</td>" the same way. Raw-text bodies are now held out of the document while it is parsed and put back verbatim afterwards. Present since 0.1.0, hidden behind the non-ASCII corruption that 0.1.3 fixed.
  • A <script> body that spelled out the internal <?xml encoding="utf-8" ?> parsing prefix lost that string, because the prefix was stripped from the serialized document only after the body had been reinserted.

Added

  • NOTICES.md lists the third-party licenses that travel inside the js/main.js bundle. The list is taken from a webpack stats run, so it is what the bundle actually holds after tree shaking (17 packages) rather than the whole dependency closure (59). Regenerate with npm run notices; npm run notices:check fails when it is stale.

Changed

  • LICENSE now holds the full text of the GNU Affero General Public License, version 3. It previously contained only the "how to apply" notice and a link to the text, so no copy of the license travelled with the release tarball even though that notice says one did — and GitHub could not identify the license either. The copyright line and the definition of this app's "source code" moved to the License section of the README.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhN2MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwNjIzMDczNzAyWhcNMzYwOTI4MDczNzAyWjAbMRkwFwYD
VQQDDBBzYWZlX2h0bWxfdmlld2VyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAxGMMlgiIp7gqLruDW6Qi9hVAw1z6pTuhAMaZTUv1cvhRLyBTDhnHfgoZ
zy0ocEOSfNJJcNPDtcYg3yM5ndLvShwQEx6JJC8cgmNSlTQMQRr2iVYV31ukV1tw
0KlXBvrPYanqQs34Hyjvj7KFcY2AcFIMoFZj410msp2SgcKmRXP7TC/xqnC6IDgv
Taqy3j6TuQh2Z66ODgUwgxHwA+7XGd8r8oivMOdcRVWZhbjl6mCU5OMqoGwss+oq
7hpFJCcKas3lwMoE4eBrWHrpsuHv4Gq8iwma5rTk4T0p1S60hcLdFgBChuL2dhb9
XkuWlt6NZTct085za5/o7c1xsTlYyiIWK/BGPTkQSsX80CdVScda21debxFAsxBF
Z0r0MbvwRKB5kjEzQQPiia+RLPKVb/+USDlbaycRXZAthK6L4Vb1cgiYo+TwqRBa
p7YHJxGXnozs3WC3M6/ihKf4Yu630wJHWU5sH9HG3hz5BtmOWLDfHIUGOUP9O04m
1QA6lq+v3Mq0BMCF8H/EnEhK3z7noh24KL5vhmjc1E40RdTG/tK6L6YjvbIIeDtB
numfI3xsPZwDqqnN9PUEtdcbBGN+H93xipb9GB/dL6hBLa3Xe2RgYLPO/n43Goqe
p+fm+bgEHcQRZ1hAUzKkuCOKT2H9/QbL3TBfkpBwm+u9/udkarMCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAW0Vj6POpPcSRy1uErGomZAur80+IWV50hu6P2hEwTWsZ
XlaBWeveY/lfAbXJJAua33x1cmbw09SDja0FCneYf0kKNpyGoMyq+yDgM2NddSI1
ftVxhWO/1qlbkTAboLsuwbePtZqyfYMML/Cgl4DPaHu1Kx+IIJmj2A+iAryCetGe
jdlhwWbk+SZ6/KtyZy1wirPDQib8MWMGlv/RcJyZiWC4L8y1vAjqsmCDpn5r2qq+
0isqzdcR7kMy89PovRuHN5lDyocf/+GECyE8x+Y3zhm7kq4qc2SC33RGGT4IHsg+
6sTGnvQSrZPq66kqiFoQFTN/FP7KF7dUB6NX5OIZNg==
-----END CERTIFICATE-----
Signaturepen7RR2L7DOYaTWIXcLeLFcZ/Oc6wSIokN+buzdsKkFE9MCnvRhKFwJpAWAgQW+69q9/bo+vVM2YWcwsO4SbdU+UMs3qMAWVpRvOtL5ysv/gwI3dzwoNh4yY3ToL8Tofdmb5wSpd6oPm4T9riaK3UUCKwDAMzacEqUMfhMLv1tQocq4/7TqyTwd2WtfsgUi57rTluA+QgEVMjCnMiaJEcJAZ5w42AGQUlRSuWOYuDZQ+qXxxvLxXo5pzYMl75UyrCqzUrw+26GAhXtnK/LvZ/AD18ONQm2BrINwlkPW6kEdgwKzfW4k/xAZulXjQS6Lpr1VsKfALjE01OSQ7tMMzUvbKlapjMxdIcjsIb5Hesp98c6blRccvA/HUahf5YQVPaZRcHES/8i9+OeS96QPY2zSU/oBDM9NcEzTN14pr0aiuxxsXrrrLnIE+LQst7BraimLFNwT99//BW9HFGD3zfZ5cwFQvxzgOE+nmcZbhWcN+GpM2ZnrK/qkDbOatEHNkzZv/pN+b7+MJCioHmK3ToTThh9a+4qIYjTXte2t7ZnPldYAe9FtGsTESdRh/sqVpIzRtyzG1oQIqpaYlc6a1Mj86yMvzgMXJSFagULfs66R7jEqYpo+xExpyBjK4/ivFvEAKkJxNJTvgmaGHjS4WS3NJLBzkpJq9ePROcqwFtWU=
Signature digestsha512
Dependencies
Required Nextcloud versions >=28.0.0,<34.0.0
Minimum Integer bits32
Safe HTML Viewer 0.1.3
Release Details
UpdatedJuly 27, 2026, 9:50 a.m.
Changelog

Fixed

  • Non-ASCII content (Japanese, other non-Latin scripts, emoji) was served as decimal numeric character references. DOMDocument::saveHTML() escapes every code point

    = 0x80, and browsers do not decode those inside <script> / <style> bodies, so previews of pages that build labels in JavaScript or set CSS content rendered raw &#21517; text and broken layout. Non-ASCII runs are now placeholder-swapped around serialization, so the served preview keeps the original UTF-8.

  • ISO dates in prose were redacted as phone numbers. The phone pattern allows spaces and parentheses, so a match carried its surrounding padding and the ISO-date guard never fired: 検証資料 2026-07-17 became 検証資料[REDACTED-PHONE]. Padding is now split off before the date check and re-emitted, which also preserves the spacing around genuinely redacted phone numbers.
  • A leading UTF-8 BOM made the preview come back empty. The BOM ended up between the internal encoding declaration and the document, so parsing stopped right after it — which hit every file written by an editor that emits a BOM by default (Notepad, Excel's web export, PowerShell's ConvertTo-Html).
  • Base64 data: URI payloads were redacted as opaque secrets, blanking out inline images. Such a payload is encoded binary, so the heuristics cannot recognise a secret in it but do match it by accident; base64 data URIs are now passed through. Data URIs that are not base64 stay in scope, since those carry readable text.
  • Redaction walked only the first top-level node, so content following a <script> or <style> sibling was served unredacted.
  • The <?xml encoding="utf-8" ?> prefix used to force UTF-8 parsing leaked into previews.
  • Credential patterns (password=, token=, ...) were only matched inside query strings, and the replacement dropped the parameter name. The value is now matched as bounded ASCII, so prose in scripts without ASCII word breaks (Japanese, Chinese) is not swallowed up to the end of the text node.
  • Long-token heuristic no longer swallows a host plus path as a single secret.
  • Private/localhost URL matching required a real host boundary, so public hosts such as internal.example.com are no longer treated as private.
  • Bare IPv4 redaction no longer overrides the [REDACTED-PRIVATE-URL] label.

Changed

  • The preview endpoint now serves HTML only (.html / .htm / text/html / application/xhtml+xml) and returns 415 otherwise, rejects files over 5 MiB with 413, and maps file-access failures to 404/500 instead of surfacing an exception.
  • Content-Security-Policy is extended with frame-ancestors 'self'; base-uri 'none' alongside the existing sandbox allow-scripts allow-popups (still no allow-same-origin).
  • File action id handling accepts large numeric ids as strings instead of parseInt, and preview tabs are opened with noopener,noreferrer.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhN2MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwNjIzMDczNzAyWhcNMzYwOTI4MDczNzAyWjAbMRkwFwYD
VQQDDBBzYWZlX2h0bWxfdmlld2VyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAxGMMlgiIp7gqLruDW6Qi9hVAw1z6pTuhAMaZTUv1cvhRLyBTDhnHfgoZ
zy0ocEOSfNJJcNPDtcYg3yM5ndLvShwQEx6JJC8cgmNSlTQMQRr2iVYV31ukV1tw
0KlXBvrPYanqQs34Hyjvj7KFcY2AcFIMoFZj410msp2SgcKmRXP7TC/xqnC6IDgv
Taqy3j6TuQh2Z66ODgUwgxHwA+7XGd8r8oivMOdcRVWZhbjl6mCU5OMqoGwss+oq
7hpFJCcKas3lwMoE4eBrWHrpsuHv4Gq8iwma5rTk4T0p1S60hcLdFgBChuL2dhb9
XkuWlt6NZTct085za5/o7c1xsTlYyiIWK/BGPTkQSsX80CdVScda21debxFAsxBF
Z0r0MbvwRKB5kjEzQQPiia+RLPKVb/+USDlbaycRXZAthK6L4Vb1cgiYo+TwqRBa
p7YHJxGXnozs3WC3M6/ihKf4Yu630wJHWU5sH9HG3hz5BtmOWLDfHIUGOUP9O04m
1QA6lq+v3Mq0BMCF8H/EnEhK3z7noh24KL5vhmjc1E40RdTG/tK6L6YjvbIIeDtB
numfI3xsPZwDqqnN9PUEtdcbBGN+H93xipb9GB/dL6hBLa3Xe2RgYLPO/n43Goqe
p+fm+bgEHcQRZ1hAUzKkuCOKT2H9/QbL3TBfkpBwm+u9/udkarMCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAW0Vj6POpPcSRy1uErGomZAur80+IWV50hu6P2hEwTWsZ
XlaBWeveY/lfAbXJJAua33x1cmbw09SDja0FCneYf0kKNpyGoMyq+yDgM2NddSI1
ftVxhWO/1qlbkTAboLsuwbePtZqyfYMML/Cgl4DPaHu1Kx+IIJmj2A+iAryCetGe
jdlhwWbk+SZ6/KtyZy1wirPDQib8MWMGlv/RcJyZiWC4L8y1vAjqsmCDpn5r2qq+
0isqzdcR7kMy89PovRuHN5lDyocf/+GECyE8x+Y3zhm7kq4qc2SC33RGGT4IHsg+
6sTGnvQSrZPq66kqiFoQFTN/FP7KF7dUB6NX5OIZNg==
-----END CERTIFICATE-----
SignaturerSin+ZMVn/oSIPKmIDImyuPw6gug82xtr+w9CxHVwP4U+n+469SmAYAaG5EDbtOcBVBnkMDj6f4S6PYxriMk0Ws6jyAS291cICi0mVjRftPxgfp5RjgaLCAfTCtjMubLWwF1oW/3AbY7Dn6Y72IWk79Hx9gpLM0Rk3INFGdcL/GUCGlat80bb2heAZFy4a0a7xwXpC4FwaWkWOpAV2sVd63zia+4+4RdARfnQS7R01KUfTEAuT4Gqq46cvgcpnUQhAvxzFXzjeP8opzg+kBL0yiBdeBazwE++Fw+tvM05/M16g57JslbT9xkNWdoNiEqb/A6ug19fFy0zh2YrKZt3ixTpDolURPDr0SZXICyj7f46fmXNZIELAhOyPzIVF5XQUSVKg0pTd14QQL+NuQJpg1XKBElU7btzBa9ODDDpVpdVuUMV+3lBWV1JfQtpBNOCeMcJsndcLqYHUHfiEtQGlULeYfj1ETbYYRruBvton1ZFIpkYNUYZHYV63e1cyQSf0LqgdxiJ4/o16q0sKPEpxX35XcGT9ZVZemb+L9bPQv8l4TDSzEoEW4FHEMG3p3PbB+kYNmU2Tw4MKwEewfryU0vTtVTKhPW2wLkwByV2jIQ71/83bVZbFNbzxfxWD6+M1st9Vmz9KEideXdGwYblKhW+BqLpR/xDCc1hJkMu8A=
Signature digestsha512
Dependencies
Required Nextcloud versions >=28.0.0,<34.0.0
Minimum Integer bits32
Safe HTML Viewer 0.1.2
Release Details
UpdatedJuly 3, 2026, 3:37 a.m.
Changelog

Fixed

  • App Store description rendered raw HTML tags as text: the App Store treats info.xml description as Markdown, so the description is now written in Markdown instead of HTML.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhN2MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwNjIzMDczNzAyWhcNMzYwOTI4MDczNzAyWjAbMRkwFwYD
VQQDDBBzYWZlX2h0bWxfdmlld2VyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAxGMMlgiIp7gqLruDW6Qi9hVAw1z6pTuhAMaZTUv1cvhRLyBTDhnHfgoZ
zy0ocEOSfNJJcNPDtcYg3yM5ndLvShwQEx6JJC8cgmNSlTQMQRr2iVYV31ukV1tw
0KlXBvrPYanqQs34Hyjvj7KFcY2AcFIMoFZj410msp2SgcKmRXP7TC/xqnC6IDgv
Taqy3j6TuQh2Z66ODgUwgxHwA+7XGd8r8oivMOdcRVWZhbjl6mCU5OMqoGwss+oq
7hpFJCcKas3lwMoE4eBrWHrpsuHv4Gq8iwma5rTk4T0p1S60hcLdFgBChuL2dhb9
XkuWlt6NZTct085za5/o7c1xsTlYyiIWK/BGPTkQSsX80CdVScda21debxFAsxBF
Z0r0MbvwRKB5kjEzQQPiia+RLPKVb/+USDlbaycRXZAthK6L4Vb1cgiYo+TwqRBa
p7YHJxGXnozs3WC3M6/ihKf4Yu630wJHWU5sH9HG3hz5BtmOWLDfHIUGOUP9O04m
1QA6lq+v3Mq0BMCF8H/EnEhK3z7noh24KL5vhmjc1E40RdTG/tK6L6YjvbIIeDtB
numfI3xsPZwDqqnN9PUEtdcbBGN+H93xipb9GB/dL6hBLa3Xe2RgYLPO/n43Goqe
p+fm+bgEHcQRZ1hAUzKkuCOKT2H9/QbL3TBfkpBwm+u9/udkarMCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAW0Vj6POpPcSRy1uErGomZAur80+IWV50hu6P2hEwTWsZ
XlaBWeveY/lfAbXJJAua33x1cmbw09SDja0FCneYf0kKNpyGoMyq+yDgM2NddSI1
ftVxhWO/1qlbkTAboLsuwbePtZqyfYMML/Cgl4DPaHu1Kx+IIJmj2A+iAryCetGe
jdlhwWbk+SZ6/KtyZy1wirPDQib8MWMGlv/RcJyZiWC4L8y1vAjqsmCDpn5r2qq+
0isqzdcR7kMy89PovRuHN5lDyocf/+GECyE8x+Y3zhm7kq4qc2SC33RGGT4IHsg+
6sTGnvQSrZPq66kqiFoQFTN/FP7KF7dUB6NX5OIZNg==
-----END CERTIFICATE-----
Signaturebx/keT27YaqA8wIFCi8LoWdXOvGQ/1+9fQPdoUJv/e0Z0FViwWpolmow0juKxyzQl5aKSUqPb9AsLf1m9f8yVpFtcziSry0nPzOEufBH6gq+fc6ng1JS7naLpljunVsJX4HiAFVCF/mqaoaR9J6faXXYbHSLfFIx1eLilrWUujBulCdzS2sja60Aw7tvTigFY/xkcTCNEyOU+/QdhqYQCgPlRMGFFRxpPFhPTo7p7KqETbk5J0mr7I2g/fx6xOWtCUPju6NSmqPxbqOKHrxXDfwITxCfrFsAM530gf57rHHYF16vVXcSX2K9O7Gl/cHFeCSDBh9BpBnZzQp6dzx4jDz65BUIl+O9Bex/8rGzCj7NV7tWXjmEOtIVNj0vsn+kUmqSuvE7kui+FUVwUaHPiaV4jUeFXCOV288SBACbD8IWIU2XCD3Un8kGp//fRfvd1/avtkIL5sp4ShR5N2tAuv6F7e/Gvyci75IZvJLxmbF1fNL2NnJI4+9GYgZWNYqKZeG3Zx3gcYp63owU6HncvumewDjqyiF1H4T3ah2v2/iBKUoJftSq5BYJ9u5+3KWygC0mdSQa3ib9xpuROg7kFEjT5GUxsp95IVI+h/9l+JLg2/H9EvgaLXFXLiTSxlLo66mld0T/kzfWyDn2LdmqpH/qWsUxaOm1RSoQ56UsyQc=
Signature digestsha512
Dependencies
Required Nextcloud versions >=28.0.0,<34.0.0
Minimum Integer bits32
Safe HTML Viewer 0.1.1
Release Details
UpdatedJuly 3, 2026, 3:27 a.m.
Changelog

Changed

  • Expanded the App Store description (features list, sandbox behaviour, limitations).
  • Unified author/copyright attribution to "Hiroshi Ishizaka (ishizakahiroshi)" across info.xml, composer.json, package.json and LICENSE.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhN2MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwNjIzMDczNzAyWhcNMzYwOTI4MDczNzAyWjAbMRkwFwYD
VQQDDBBzYWZlX2h0bWxfdmlld2VyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAxGMMlgiIp7gqLruDW6Qi9hVAw1z6pTuhAMaZTUv1cvhRLyBTDhnHfgoZ
zy0ocEOSfNJJcNPDtcYg3yM5ndLvShwQEx6JJC8cgmNSlTQMQRr2iVYV31ukV1tw
0KlXBvrPYanqQs34Hyjvj7KFcY2AcFIMoFZj410msp2SgcKmRXP7TC/xqnC6IDgv
Taqy3j6TuQh2Z66ODgUwgxHwA+7XGd8r8oivMOdcRVWZhbjl6mCU5OMqoGwss+oq
7hpFJCcKas3lwMoE4eBrWHrpsuHv4Gq8iwma5rTk4T0p1S60hcLdFgBChuL2dhb9
XkuWlt6NZTct085za5/o7c1xsTlYyiIWK/BGPTkQSsX80CdVScda21debxFAsxBF
Z0r0MbvwRKB5kjEzQQPiia+RLPKVb/+USDlbaycRXZAthK6L4Vb1cgiYo+TwqRBa
p7YHJxGXnozs3WC3M6/ihKf4Yu630wJHWU5sH9HG3hz5BtmOWLDfHIUGOUP9O04m
1QA6lq+v3Mq0BMCF8H/EnEhK3z7noh24KL5vhmjc1E40RdTG/tK6L6YjvbIIeDtB
numfI3xsPZwDqqnN9PUEtdcbBGN+H93xipb9GB/dL6hBLa3Xe2RgYLPO/n43Goqe
p+fm+bgEHcQRZ1hAUzKkuCOKT2H9/QbL3TBfkpBwm+u9/udkarMCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAW0Vj6POpPcSRy1uErGomZAur80+IWV50hu6P2hEwTWsZ
XlaBWeveY/lfAbXJJAua33x1cmbw09SDja0FCneYf0kKNpyGoMyq+yDgM2NddSI1
ftVxhWO/1qlbkTAboLsuwbePtZqyfYMML/Cgl4DPaHu1Kx+IIJmj2A+iAryCetGe
jdlhwWbk+SZ6/KtyZy1wirPDQib8MWMGlv/RcJyZiWC4L8y1vAjqsmCDpn5r2qq+
0isqzdcR7kMy89PovRuHN5lDyocf/+GECyE8x+Y3zhm7kq4qc2SC33RGGT4IHsg+
6sTGnvQSrZPq66kqiFoQFTN/FP7KF7dUB6NX5OIZNg==
-----END CERTIFICATE-----
SignaturefVBl4DuXEO4qJ13HX0BQTQPTJ6DCZazoiprU2vZQhaksRZwl6gadG3Fkxbq1iGK9fIEfQKvj2gLxLzxWq+WNruBIvXTdQZm30rzQSY4sksRj7ewgDGe6libZf1Q8kfQQ6pwd0c+Wboxz+cmdZhettNKBuLNKsl2s+zIIOyMYl4x7CjP90Kl7YoZdIbgnVPeOY4X4Auti+FvrANb4JMP3uzkflg4S+E7La5DILPHFsWag2c6JivrQ6AOOluDbXlddMdMY7vwrJ8zKCzZetqCUaTBCifSuvQ6JORujThAdGm52xr4BZjQ7C8QH9laTr6Zzj1v4PQVDuLU7NRzeIH9m6euK6z4bSt2bQUY3mQ21/dvD5HI40jS9yXns17fdKRFPgsgdZdyQtOGJjlZN4+lK3anJ02a3oDtsVbQq0FrQAkb0ALB53/j1A4y2K3n4MkzhIOWuxYyXsbkeQjWO2eB6DC26tfXt6O5VOntcI7caQcKjazDZnPvyam/QRSuTL4xDgLi6KR3sbwyxbQaU6+IIeUfZkykJngV/SU1iZ8YctfudJmsXmkIFfDpVBsoQPoe64S+vPJYHJ3z/sU5J9FIcufVw8HYww1uT2Settt3U1yIIFZ33oLzfcNbeWj6gXsHBs6QG5vKsBzxeBGu+194KhNh9MAfopvtLlXRnY/C0A+c=
Signature digestsha512
Dependencies
Required Nextcloud versions >=28.0.0,<34.0.0
Minimum Integer bits32
Safe HTML Viewer 0.1.0
Release Details
UpdatedJuly 3, 2026, 3:01 a.m.
Changelog

Added

  • Initial public release of safe_html_viewer.
  • File action registration for .html / text/html files.
  • /apps/safe_html_viewer/raw/{fileId} endpoint returning HTML under strict CSP sandbox (sandbox allow-scripts allow-popups, no allow-same-origin).
  • ACL enforcement via user folder view (only accessible files are returned).
  • RedactionService with best-effort display-time redaction for:
  • Email addresses
  • Phone-like strings
  • IPv4 addresses
  • Private/localhost URLs
  • Credential query patterns (password=, token=, api_key=, ...)
  • Long opaque token-like strings
  • Redaction only affects the served preview; original file content is untouched.
  • Basic PHPUnit coverage for redaction rules.
  • Documentation: README, SECURITY, CHANGELOG, AGENTS/CLAUDE guidance files.

Security

  • Sandbox is intentionally restrictive.
  • Redaction is documented as best-effort (see README and SECURITY.md).
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhN2MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwNjIzMDczNzAyWhcNMzYwOTI4MDczNzAyWjAbMRkwFwYD
VQQDDBBzYWZlX2h0bWxfdmlld2VyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAxGMMlgiIp7gqLruDW6Qi9hVAw1z6pTuhAMaZTUv1cvhRLyBTDhnHfgoZ
zy0ocEOSfNJJcNPDtcYg3yM5ndLvShwQEx6JJC8cgmNSlTQMQRr2iVYV31ukV1tw
0KlXBvrPYanqQs34Hyjvj7KFcY2AcFIMoFZj410msp2SgcKmRXP7TC/xqnC6IDgv
Taqy3j6TuQh2Z66ODgUwgxHwA+7XGd8r8oivMOdcRVWZhbjl6mCU5OMqoGwss+oq
7hpFJCcKas3lwMoE4eBrWHrpsuHv4Gq8iwma5rTk4T0p1S60hcLdFgBChuL2dhb9
XkuWlt6NZTct085za5/o7c1xsTlYyiIWK/BGPTkQSsX80CdVScda21debxFAsxBF
Z0r0MbvwRKB5kjEzQQPiia+RLPKVb/+USDlbaycRXZAthK6L4Vb1cgiYo+TwqRBa
p7YHJxGXnozs3WC3M6/ihKf4Yu630wJHWU5sH9HG3hz5BtmOWLDfHIUGOUP9O04m
1QA6lq+v3Mq0BMCF8H/EnEhK3z7noh24KL5vhmjc1E40RdTG/tK6L6YjvbIIeDtB
numfI3xsPZwDqqnN9PUEtdcbBGN+H93xipb9GB/dL6hBLa3Xe2RgYLPO/n43Goqe
p+fm+bgEHcQRZ1hAUzKkuCOKT2H9/QbL3TBfkpBwm+u9/udkarMCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAW0Vj6POpPcSRy1uErGomZAur80+IWV50hu6P2hEwTWsZ
XlaBWeveY/lfAbXJJAua33x1cmbw09SDja0FCneYf0kKNpyGoMyq+yDgM2NddSI1
ftVxhWO/1qlbkTAboLsuwbePtZqyfYMML/Cgl4DPaHu1Kx+IIJmj2A+iAryCetGe
jdlhwWbk+SZ6/KtyZy1wirPDQib8MWMGlv/RcJyZiWC4L8y1vAjqsmCDpn5r2qq+
0isqzdcR7kMy89PovRuHN5lDyocf/+GECyE8x+Y3zhm7kq4qc2SC33RGGT4IHsg+
6sTGnvQSrZPq66kqiFoQFTN/FP7KF7dUB6NX5OIZNg==
-----END CERTIFICATE-----
SignatureLIHeXIJmSLq1g/KyD/WijCOZX+Yo9A2LHW9B/WRhd2q0GcE1Jw+4bCiax7E6m7GpIm/jLmxBi6Y6gdFtKhtCnTr5pxmnL7txji8rt0CaDMUjodZ1jIK+sym+oMRhgZlmdlwJd8V1tbvZBhTDfEzFQ0atJDuymE5IhMDyHN4703aJEQ0wEDy9c14A6mo9gW6K1Ew6YicJm83/9fgPJjoI8WpvZWtq7Oylj3HzSVqzrbVO2I5PvPCUnwkEyQ4iwo0nhFeU8aRzn0a/JPlHtfmlnPjkVXU4sHKR7HopNADqIPa000N37gofqeTP6MZ3O/dgQJkHWGRjgcPxD2LDUkn4ntaizNAK3KrMSPlormfoNyQae6Z9PZqpT+DsQr54u+0iNI88pZ2sSjl2HfNdGIYLSp4K6sPZAJRa32KzgjfgQWj8UeVSvEk9lRhXzeYdCz8PckWAdaldbQaNfs6MoigqcY1gCqZxkVOKadIsiduWLkatVSUs1zNNb8y2qyiPExV2sK16wotQbxi+Z2qqpbT1lCznZdreTHKz8jBBTBe9Bt+TzESUOq8z+04DgG254BHUq9CNYWt0FvLfwjdKzbVNud5DNGCYWBz9U/qsgynYjSGy1Uz5mkKZxCeiOVuQ660mSu1/BXqEywkFnHp0/in/rxH9P8ddw3pHj5DEs0tydqY=
Signature digestsha512
Dependencies
Required Nextcloud versions >=28.0.0,<34.0.0
Minimum Integer bits32

Nextcloud 28

Safe HTML Viewer 0.1.4
Release Details
UpdatedJuly 27, 2026, 11:48 a.m.
Changelog

Fixed

  • Closing tags written inside a <script> or <style> body were deleted from the preview. libxml's HTML parser ends a raw-text body at any </, not only at the element's own end tag, and drops the rest of it, so var t = "<button><i></i>X</button>" arrived as var t = "<button><i>X". Every DOM the script then built came out mis-nested and the layout collapsed; CSS lost content: "</td>" the same way. Raw-text bodies are now held out of the document while it is parsed and put back verbatim afterwards. Present since 0.1.0, hidden behind the non-ASCII corruption that 0.1.3 fixed.
  • A <script> body that spelled out the internal <?xml encoding="utf-8" ?> parsing prefix lost that string, because the prefix was stripped from the serialized document only after the body had been reinserted.

Added

  • NOTICES.md lists the third-party licenses that travel inside the js/main.js bundle. The list is taken from a webpack stats run, so it is what the bundle actually holds after tree shaking (17 packages) rather than the whole dependency closure (59). Regenerate with npm run notices; npm run notices:check fails when it is stale.

Changed

  • LICENSE now holds the full text of the GNU Affero General Public License, version 3. It previously contained only the "how to apply" notice and a link to the text, so no copy of the license travelled with the release tarball even though that notice says one did — and GitHub could not identify the license either. The copyright line and the definition of this app's "source code" moved to the License section of the README.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhN2MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwNjIzMDczNzAyWhcNMzYwOTI4MDczNzAyWjAbMRkwFwYD
VQQDDBBzYWZlX2h0bWxfdmlld2VyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAxGMMlgiIp7gqLruDW6Qi9hVAw1z6pTuhAMaZTUv1cvhRLyBTDhnHfgoZ
zy0ocEOSfNJJcNPDtcYg3yM5ndLvShwQEx6JJC8cgmNSlTQMQRr2iVYV31ukV1tw
0KlXBvrPYanqQs34Hyjvj7KFcY2AcFIMoFZj410msp2SgcKmRXP7TC/xqnC6IDgv
Taqy3j6TuQh2Z66ODgUwgxHwA+7XGd8r8oivMOdcRVWZhbjl6mCU5OMqoGwss+oq
7hpFJCcKas3lwMoE4eBrWHrpsuHv4Gq8iwma5rTk4T0p1S60hcLdFgBChuL2dhb9
XkuWlt6NZTct085za5/o7c1xsTlYyiIWK/BGPTkQSsX80CdVScda21debxFAsxBF
Z0r0MbvwRKB5kjEzQQPiia+RLPKVb/+USDlbaycRXZAthK6L4Vb1cgiYo+TwqRBa
p7YHJxGXnozs3WC3M6/ihKf4Yu630wJHWU5sH9HG3hz5BtmOWLDfHIUGOUP9O04m
1QA6lq+v3Mq0BMCF8H/EnEhK3z7noh24KL5vhmjc1E40RdTG/tK6L6YjvbIIeDtB
numfI3xsPZwDqqnN9PUEtdcbBGN+H93xipb9GB/dL6hBLa3Xe2RgYLPO/n43Goqe
p+fm+bgEHcQRZ1hAUzKkuCOKT2H9/QbL3TBfkpBwm+u9/udkarMCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAW0Vj6POpPcSRy1uErGomZAur80+IWV50hu6P2hEwTWsZ
XlaBWeveY/lfAbXJJAua33x1cmbw09SDja0FCneYf0kKNpyGoMyq+yDgM2NddSI1
ftVxhWO/1qlbkTAboLsuwbePtZqyfYMML/Cgl4DPaHu1Kx+IIJmj2A+iAryCetGe
jdlhwWbk+SZ6/KtyZy1wirPDQib8MWMGlv/RcJyZiWC4L8y1vAjqsmCDpn5r2qq+
0isqzdcR7kMy89PovRuHN5lDyocf/+GECyE8x+Y3zhm7kq4qc2SC33RGGT4IHsg+
6sTGnvQSrZPq66kqiFoQFTN/FP7KF7dUB6NX5OIZNg==
-----END CERTIFICATE-----
Signaturepen7RR2L7DOYaTWIXcLeLFcZ/Oc6wSIokN+buzdsKkFE9MCnvRhKFwJpAWAgQW+69q9/bo+vVM2YWcwsO4SbdU+UMs3qMAWVpRvOtL5ysv/gwI3dzwoNh4yY3ToL8Tofdmb5wSpd6oPm4T9riaK3UUCKwDAMzacEqUMfhMLv1tQocq4/7TqyTwd2WtfsgUi57rTluA+QgEVMjCnMiaJEcJAZ5w42AGQUlRSuWOYuDZQ+qXxxvLxXo5pzYMl75UyrCqzUrw+26GAhXtnK/LvZ/AD18ONQm2BrINwlkPW6kEdgwKzfW4k/xAZulXjQS6Lpr1VsKfALjE01OSQ7tMMzUvbKlapjMxdIcjsIb5Hesp98c6blRccvA/HUahf5YQVPaZRcHES/8i9+OeS96QPY2zSU/oBDM9NcEzTN14pr0aiuxxsXrrrLnIE+LQst7BraimLFNwT99//BW9HFGD3zfZ5cwFQvxzgOE+nmcZbhWcN+GpM2ZnrK/qkDbOatEHNkzZv/pN+b7+MJCioHmK3ToTThh9a+4qIYjTXte2t7ZnPldYAe9FtGsTESdRh/sqVpIzRtyzG1oQIqpaYlc6a1Mj86yMvzgMXJSFagULfs66R7jEqYpo+xExpyBjK4/ivFvEAKkJxNJTvgmaGHjS4WS3NJLBzkpJq9ePROcqwFtWU=
Signature digestsha512
Dependencies
Required Nextcloud versions >=28.0.0,<34.0.0
Minimum Integer bits32
Safe HTML Viewer 0.1.3
Release Details
UpdatedJuly 27, 2026, 9:50 a.m.
Changelog

Fixed

  • Non-ASCII content (Japanese, other non-Latin scripts, emoji) was served as decimal numeric character references. DOMDocument::saveHTML() escapes every code point

    = 0x80, and browsers do not decode those inside <script> / <style> bodies, so previews of pages that build labels in JavaScript or set CSS content rendered raw &#21517; text and broken layout. Non-ASCII runs are now placeholder-swapped around serialization, so the served preview keeps the original UTF-8.

  • ISO dates in prose were redacted as phone numbers. The phone pattern allows spaces and parentheses, so a match carried its surrounding padding and the ISO-date guard never fired: 検証資料 2026-07-17 became 検証資料[REDACTED-PHONE]. Padding is now split off before the date check and re-emitted, which also preserves the spacing around genuinely redacted phone numbers.
  • A leading UTF-8 BOM made the preview come back empty. The BOM ended up between the internal encoding declaration and the document, so parsing stopped right after it — which hit every file written by an editor that emits a BOM by default (Notepad, Excel's web export, PowerShell's ConvertTo-Html).
  • Base64 data: URI payloads were redacted as opaque secrets, blanking out inline images. Such a payload is encoded binary, so the heuristics cannot recognise a secret in it but do match it by accident; base64 data URIs are now passed through. Data URIs that are not base64 stay in scope, since those carry readable text.
  • Redaction walked only the first top-level node, so content following a <script> or <style> sibling was served unredacted.
  • The <?xml encoding="utf-8" ?> prefix used to force UTF-8 parsing leaked into previews.
  • Credential patterns (password=, token=, ...) were only matched inside query strings, and the replacement dropped the parameter name. The value is now matched as bounded ASCII, so prose in scripts without ASCII word breaks (Japanese, Chinese) is not swallowed up to the end of the text node.
  • Long-token heuristic no longer swallows a host plus path as a single secret.
  • Private/localhost URL matching required a real host boundary, so public hosts such as internal.example.com are no longer treated as private.
  • Bare IPv4 redaction no longer overrides the [REDACTED-PRIVATE-URL] label.

Changed

  • The preview endpoint now serves HTML only (.html / .htm / text/html / application/xhtml+xml) and returns 415 otherwise, rejects files over 5 MiB with 413, and maps file-access failures to 404/500 instead of surfacing an exception.
  • Content-Security-Policy is extended with frame-ancestors 'self'; base-uri 'none' alongside the existing sandbox allow-scripts allow-popups (still no allow-same-origin).
  • File action id handling accepts large numeric ids as strings instead of parseInt, and preview tabs are opened with noopener,noreferrer.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhN2MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwNjIzMDczNzAyWhcNMzYwOTI4MDczNzAyWjAbMRkwFwYD
VQQDDBBzYWZlX2h0bWxfdmlld2VyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAxGMMlgiIp7gqLruDW6Qi9hVAw1z6pTuhAMaZTUv1cvhRLyBTDhnHfgoZ
zy0ocEOSfNJJcNPDtcYg3yM5ndLvShwQEx6JJC8cgmNSlTQMQRr2iVYV31ukV1tw
0KlXBvrPYanqQs34Hyjvj7KFcY2AcFIMoFZj410msp2SgcKmRXP7TC/xqnC6IDgv
Taqy3j6TuQh2Z66ODgUwgxHwA+7XGd8r8oivMOdcRVWZhbjl6mCU5OMqoGwss+oq
7hpFJCcKas3lwMoE4eBrWHrpsuHv4Gq8iwma5rTk4T0p1S60hcLdFgBChuL2dhb9
XkuWlt6NZTct085za5/o7c1xsTlYyiIWK/BGPTkQSsX80CdVScda21debxFAsxBF
Z0r0MbvwRKB5kjEzQQPiia+RLPKVb/+USDlbaycRXZAthK6L4Vb1cgiYo+TwqRBa
p7YHJxGXnozs3WC3M6/ihKf4Yu630wJHWU5sH9HG3hz5BtmOWLDfHIUGOUP9O04m
1QA6lq+v3Mq0BMCF8H/EnEhK3z7noh24KL5vhmjc1E40RdTG/tK6L6YjvbIIeDtB
numfI3xsPZwDqqnN9PUEtdcbBGN+H93xipb9GB/dL6hBLa3Xe2RgYLPO/n43Goqe
p+fm+bgEHcQRZ1hAUzKkuCOKT2H9/QbL3TBfkpBwm+u9/udkarMCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAW0Vj6POpPcSRy1uErGomZAur80+IWV50hu6P2hEwTWsZ
XlaBWeveY/lfAbXJJAua33x1cmbw09SDja0FCneYf0kKNpyGoMyq+yDgM2NddSI1
ftVxhWO/1qlbkTAboLsuwbePtZqyfYMML/Cgl4DPaHu1Kx+IIJmj2A+iAryCetGe
jdlhwWbk+SZ6/KtyZy1wirPDQib8MWMGlv/RcJyZiWC4L8y1vAjqsmCDpn5r2qq+
0isqzdcR7kMy89PovRuHN5lDyocf/+GECyE8x+Y3zhm7kq4qc2SC33RGGT4IHsg+
6sTGnvQSrZPq66kqiFoQFTN/FP7KF7dUB6NX5OIZNg==
-----END CERTIFICATE-----
SignaturerSin+ZMVn/oSIPKmIDImyuPw6gug82xtr+w9CxHVwP4U+n+469SmAYAaG5EDbtOcBVBnkMDj6f4S6PYxriMk0Ws6jyAS291cICi0mVjRftPxgfp5RjgaLCAfTCtjMubLWwF1oW/3AbY7Dn6Y72IWk79Hx9gpLM0Rk3INFGdcL/GUCGlat80bb2heAZFy4a0a7xwXpC4FwaWkWOpAV2sVd63zia+4+4RdARfnQS7R01KUfTEAuT4Gqq46cvgcpnUQhAvxzFXzjeP8opzg+kBL0yiBdeBazwE++Fw+tvM05/M16g57JslbT9xkNWdoNiEqb/A6ug19fFy0zh2YrKZt3ixTpDolURPDr0SZXICyj7f46fmXNZIELAhOyPzIVF5XQUSVKg0pTd14QQL+NuQJpg1XKBElU7btzBa9ODDDpVpdVuUMV+3lBWV1JfQtpBNOCeMcJsndcLqYHUHfiEtQGlULeYfj1ETbYYRruBvton1ZFIpkYNUYZHYV63e1cyQSf0LqgdxiJ4/o16q0sKPEpxX35XcGT9ZVZemb+L9bPQv8l4TDSzEoEW4FHEMG3p3PbB+kYNmU2Tw4MKwEewfryU0vTtVTKhPW2wLkwByV2jIQ71/83bVZbFNbzxfxWD6+M1st9Vmz9KEideXdGwYblKhW+BqLpR/xDCc1hJkMu8A=
Signature digestsha512
Dependencies
Required Nextcloud versions >=28.0.0,<34.0.0
Minimum Integer bits32
Safe HTML Viewer 0.1.2
Release Details
UpdatedJuly 3, 2026, 3:37 a.m.
Changelog

Fixed

  • App Store description rendered raw HTML tags as text: the App Store treats info.xml description as Markdown, so the description is now written in Markdown instead of HTML.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhN2MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwNjIzMDczNzAyWhcNMzYwOTI4MDczNzAyWjAbMRkwFwYD
VQQDDBBzYWZlX2h0bWxfdmlld2VyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAxGMMlgiIp7gqLruDW6Qi9hVAw1z6pTuhAMaZTUv1cvhRLyBTDhnHfgoZ
zy0ocEOSfNJJcNPDtcYg3yM5ndLvShwQEx6JJC8cgmNSlTQMQRr2iVYV31ukV1tw
0KlXBvrPYanqQs34Hyjvj7KFcY2AcFIMoFZj410msp2SgcKmRXP7TC/xqnC6IDgv
Taqy3j6TuQh2Z66ODgUwgxHwA+7XGd8r8oivMOdcRVWZhbjl6mCU5OMqoGwss+oq
7hpFJCcKas3lwMoE4eBrWHrpsuHv4Gq8iwma5rTk4T0p1S60hcLdFgBChuL2dhb9
XkuWlt6NZTct085za5/o7c1xsTlYyiIWK/BGPTkQSsX80CdVScda21debxFAsxBF
Z0r0MbvwRKB5kjEzQQPiia+RLPKVb/+USDlbaycRXZAthK6L4Vb1cgiYo+TwqRBa
p7YHJxGXnozs3WC3M6/ihKf4Yu630wJHWU5sH9HG3hz5BtmOWLDfHIUGOUP9O04m
1QA6lq+v3Mq0BMCF8H/EnEhK3z7noh24KL5vhmjc1E40RdTG/tK6L6YjvbIIeDtB
numfI3xsPZwDqqnN9PUEtdcbBGN+H93xipb9GB/dL6hBLa3Xe2RgYLPO/n43Goqe
p+fm+bgEHcQRZ1hAUzKkuCOKT2H9/QbL3TBfkpBwm+u9/udkarMCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAW0Vj6POpPcSRy1uErGomZAur80+IWV50hu6P2hEwTWsZ
XlaBWeveY/lfAbXJJAua33x1cmbw09SDja0FCneYf0kKNpyGoMyq+yDgM2NddSI1
ftVxhWO/1qlbkTAboLsuwbePtZqyfYMML/Cgl4DPaHu1Kx+IIJmj2A+iAryCetGe
jdlhwWbk+SZ6/KtyZy1wirPDQib8MWMGlv/RcJyZiWC4L8y1vAjqsmCDpn5r2qq+
0isqzdcR7kMy89PovRuHN5lDyocf/+GECyE8x+Y3zhm7kq4qc2SC33RGGT4IHsg+
6sTGnvQSrZPq66kqiFoQFTN/FP7KF7dUB6NX5OIZNg==
-----END CERTIFICATE-----
Signaturebx/keT27YaqA8wIFCi8LoWdXOvGQ/1+9fQPdoUJv/e0Z0FViwWpolmow0juKxyzQl5aKSUqPb9AsLf1m9f8yVpFtcziSry0nPzOEufBH6gq+fc6ng1JS7naLpljunVsJX4HiAFVCF/mqaoaR9J6faXXYbHSLfFIx1eLilrWUujBulCdzS2sja60Aw7tvTigFY/xkcTCNEyOU+/QdhqYQCgPlRMGFFRxpPFhPTo7p7KqETbk5J0mr7I2g/fx6xOWtCUPju6NSmqPxbqOKHrxXDfwITxCfrFsAM530gf57rHHYF16vVXcSX2K9O7Gl/cHFeCSDBh9BpBnZzQp6dzx4jDz65BUIl+O9Bex/8rGzCj7NV7tWXjmEOtIVNj0vsn+kUmqSuvE7kui+FUVwUaHPiaV4jUeFXCOV288SBACbD8IWIU2XCD3Un8kGp//fRfvd1/avtkIL5sp4ShR5N2tAuv6F7e/Gvyci75IZvJLxmbF1fNL2NnJI4+9GYgZWNYqKZeG3Zx3gcYp63owU6HncvumewDjqyiF1H4T3ah2v2/iBKUoJftSq5BYJ9u5+3KWygC0mdSQa3ib9xpuROg7kFEjT5GUxsp95IVI+h/9l+JLg2/H9EvgaLXFXLiTSxlLo66mld0T/kzfWyDn2LdmqpH/qWsUxaOm1RSoQ56UsyQc=
Signature digestsha512
Dependencies
Required Nextcloud versions >=28.0.0,<34.0.0
Minimum Integer bits32
Safe HTML Viewer 0.1.1
Release Details
UpdatedJuly 3, 2026, 3:27 a.m.
Changelog

Changed

  • Expanded the App Store description (features list, sandbox behaviour, limitations).
  • Unified author/copyright attribution to "Hiroshi Ishizaka (ishizakahiroshi)" across info.xml, composer.json, package.json and LICENSE.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhN2MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwNjIzMDczNzAyWhcNMzYwOTI4MDczNzAyWjAbMRkwFwYD
VQQDDBBzYWZlX2h0bWxfdmlld2VyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAxGMMlgiIp7gqLruDW6Qi9hVAw1z6pTuhAMaZTUv1cvhRLyBTDhnHfgoZ
zy0ocEOSfNJJcNPDtcYg3yM5ndLvShwQEx6JJC8cgmNSlTQMQRr2iVYV31ukV1tw
0KlXBvrPYanqQs34Hyjvj7KFcY2AcFIMoFZj410msp2SgcKmRXP7TC/xqnC6IDgv
Taqy3j6TuQh2Z66ODgUwgxHwA+7XGd8r8oivMOdcRVWZhbjl6mCU5OMqoGwss+oq
7hpFJCcKas3lwMoE4eBrWHrpsuHv4Gq8iwma5rTk4T0p1S60hcLdFgBChuL2dhb9
XkuWlt6NZTct085za5/o7c1xsTlYyiIWK/BGPTkQSsX80CdVScda21debxFAsxBF
Z0r0MbvwRKB5kjEzQQPiia+RLPKVb/+USDlbaycRXZAthK6L4Vb1cgiYo+TwqRBa
p7YHJxGXnozs3WC3M6/ihKf4Yu630wJHWU5sH9HG3hz5BtmOWLDfHIUGOUP9O04m
1QA6lq+v3Mq0BMCF8H/EnEhK3z7noh24KL5vhmjc1E40RdTG/tK6L6YjvbIIeDtB
numfI3xsPZwDqqnN9PUEtdcbBGN+H93xipb9GB/dL6hBLa3Xe2RgYLPO/n43Goqe
p+fm+bgEHcQRZ1hAUzKkuCOKT2H9/QbL3TBfkpBwm+u9/udkarMCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAW0Vj6POpPcSRy1uErGomZAur80+IWV50hu6P2hEwTWsZ
XlaBWeveY/lfAbXJJAua33x1cmbw09SDja0FCneYf0kKNpyGoMyq+yDgM2NddSI1
ftVxhWO/1qlbkTAboLsuwbePtZqyfYMML/Cgl4DPaHu1Kx+IIJmj2A+iAryCetGe
jdlhwWbk+SZ6/KtyZy1wirPDQib8MWMGlv/RcJyZiWC4L8y1vAjqsmCDpn5r2qq+
0isqzdcR7kMy89PovRuHN5lDyocf/+GECyE8x+Y3zhm7kq4qc2SC33RGGT4IHsg+
6sTGnvQSrZPq66kqiFoQFTN/FP7KF7dUB6NX5OIZNg==
-----END CERTIFICATE-----
SignaturefVBl4DuXEO4qJ13HX0BQTQPTJ6DCZazoiprU2vZQhaksRZwl6gadG3Fkxbq1iGK9fIEfQKvj2gLxLzxWq+WNruBIvXTdQZm30rzQSY4sksRj7ewgDGe6libZf1Q8kfQQ6pwd0c+Wboxz+cmdZhettNKBuLNKsl2s+zIIOyMYl4x7CjP90Kl7YoZdIbgnVPeOY4X4Auti+FvrANb4JMP3uzkflg4S+E7La5DILPHFsWag2c6JivrQ6AOOluDbXlddMdMY7vwrJ8zKCzZetqCUaTBCifSuvQ6JORujThAdGm52xr4BZjQ7C8QH9laTr6Zzj1v4PQVDuLU7NRzeIH9m6euK6z4bSt2bQUY3mQ21/dvD5HI40jS9yXns17fdKRFPgsgdZdyQtOGJjlZN4+lK3anJ02a3oDtsVbQq0FrQAkb0ALB53/j1A4y2K3n4MkzhIOWuxYyXsbkeQjWO2eB6DC26tfXt6O5VOntcI7caQcKjazDZnPvyam/QRSuTL4xDgLi6KR3sbwyxbQaU6+IIeUfZkykJngV/SU1iZ8YctfudJmsXmkIFfDpVBsoQPoe64S+vPJYHJ3z/sU5J9FIcufVw8HYww1uT2Settt3U1yIIFZ33oLzfcNbeWj6gXsHBs6QG5vKsBzxeBGu+194KhNh9MAfopvtLlXRnY/C0A+c=
Signature digestsha512
Dependencies
Required Nextcloud versions >=28.0.0,<34.0.0
Minimum Integer bits32
Safe HTML Viewer 0.1.0
Release Details
UpdatedJuly 3, 2026, 3:01 a.m.
Changelog

Added

  • Initial public release of safe_html_viewer.
  • File action registration for .html / text/html files.
  • /apps/safe_html_viewer/raw/{fileId} endpoint returning HTML under strict CSP sandbox (sandbox allow-scripts allow-popups, no allow-same-origin).
  • ACL enforcement via user folder view (only accessible files are returned).
  • RedactionService with best-effort display-time redaction for:
  • Email addresses
  • Phone-like strings
  • IPv4 addresses
  • Private/localhost URLs
  • Credential query patterns (password=, token=, api_key=, ...)
  • Long opaque token-like strings
  • Redaction only affects the served preview; original file content is untouched.
  • Basic PHPUnit coverage for redaction rules.
  • Documentation: README, SECURITY, CHANGELOG, AGENTS/CLAUDE guidance files.

Security

  • Sandbox is intentionally restrictive.
  • Redaction is documented as best-effort (see README and SECURITY.md).
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIECzCCAvMCAhN2MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwNjIzMDczNzAyWhcNMzYwOTI4MDczNzAyWjAbMRkwFwYD
VQQDDBBzYWZlX2h0bWxfdmlld2VyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAxGMMlgiIp7gqLruDW6Qi9hVAw1z6pTuhAMaZTUv1cvhRLyBTDhnHfgoZ
zy0ocEOSfNJJcNPDtcYg3yM5ndLvShwQEx6JJC8cgmNSlTQMQRr2iVYV31ukV1tw
0KlXBvrPYanqQs34Hyjvj7KFcY2AcFIMoFZj410msp2SgcKmRXP7TC/xqnC6IDgv
Taqy3j6TuQh2Z66ODgUwgxHwA+7XGd8r8oivMOdcRVWZhbjl6mCU5OMqoGwss+oq
7hpFJCcKas3lwMoE4eBrWHrpsuHv4Gq8iwma5rTk4T0p1S60hcLdFgBChuL2dhb9
XkuWlt6NZTct085za5/o7c1xsTlYyiIWK/BGPTkQSsX80CdVScda21debxFAsxBF
Z0r0MbvwRKB5kjEzQQPiia+RLPKVb/+USDlbaycRXZAthK6L4Vb1cgiYo+TwqRBa
p7YHJxGXnozs3WC3M6/ihKf4Yu630wJHWU5sH9HG3hz5BtmOWLDfHIUGOUP9O04m
1QA6lq+v3Mq0BMCF8H/EnEhK3z7noh24KL5vhmjc1E40RdTG/tK6L6YjvbIIeDtB
numfI3xsPZwDqqnN9PUEtdcbBGN+H93xipb9GB/dL6hBLa3Xe2RgYLPO/n43Goqe
p+fm+bgEHcQRZ1hAUzKkuCOKT2H9/QbL3TBfkpBwm+u9/udkarMCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAW0Vj6POpPcSRy1uErGomZAur80+IWV50hu6P2hEwTWsZ
XlaBWeveY/lfAbXJJAua33x1cmbw09SDja0FCneYf0kKNpyGoMyq+yDgM2NddSI1
ftVxhWO/1qlbkTAboLsuwbePtZqyfYMML/Cgl4DPaHu1Kx+IIJmj2A+iAryCetGe
jdlhwWbk+SZ6/KtyZy1wirPDQib8MWMGlv/RcJyZiWC4L8y1vAjqsmCDpn5r2qq+
0isqzdcR7kMy89PovRuHN5lDyocf/+GECyE8x+Y3zhm7kq4qc2SC33RGGT4IHsg+
6sTGnvQSrZPq66kqiFoQFTN/FP7KF7dUB6NX5OIZNg==
-----END CERTIFICATE-----
SignatureLIHeXIJmSLq1g/KyD/WijCOZX+Yo9A2LHW9B/WRhd2q0GcE1Jw+4bCiax7E6m7GpIm/jLmxBi6Y6gdFtKhtCnTr5pxmnL7txji8rt0CaDMUjodZ1jIK+sym+oMRhgZlmdlwJd8V1tbvZBhTDfEzFQ0atJDuymE5IhMDyHN4703aJEQ0wEDy9c14A6mo9gW6K1Ew6YicJm83/9fgPJjoI8WpvZWtq7Oylj3HzSVqzrbVO2I5PvPCUnwkEyQ4iwo0nhFeU8aRzn0a/JPlHtfmlnPjkVXU4sHKR7HopNADqIPa000N37gofqeTP6MZ3O/dgQJkHWGRjgcPxD2LDUkn4ntaizNAK3KrMSPlormfoNyQae6Z9PZqpT+DsQr54u+0iNI88pZ2sSjl2HfNdGIYLSp4K6sPZAJRa32KzgjfgQWj8UeVSvEk9lRhXzeYdCz8PckWAdaldbQaNfs6MoigqcY1gCqZxkVOKadIsiduWLkatVSUs1zNNb8y2qyiPExV2sK16wotQbxi+Z2qqpbT1lCznZdreTHKz8jBBTBe9Bt+TzESUOq8z+04DgG254BHUq9CNYWt0FvLfwjdKzbVNud5DNGCYWBz9U/qsgynYjSGy1Uz5mkKZxCeiOVuQ660mSu1/BXqEywkFnHp0/in/rxH9P8ddw3pHj5DEs0tydqY=
Signature digestsha512
Dependencies
Required Nextcloud versions >=28.0.0,<34.0.0
Minimum Integer bits32