Skip to content

HDNEXT-1967: port remaining v30 features to ionos-dev-v33 - #300

Merged
bromiesTM merged 7 commits into
ionos-dev-v33from
mk/dev/HDNEXT-1967-port-v30-features
Aug 4, 2026
Merged

HDNEXT-1967: port remaining v30 features to ionos-dev-v33#300
bromiesTM merged 7 commits into
ionos-dev-v33from
mk/dev/HDNEXT-1967-port-v30-features

Conversation

@printminion-co

Copy link
Copy Markdown
  • Resolves: HDNEXT-1967 — port changes from the v30 release to subsequent versions

Depends on: IONOS-Productivity/nc-richdocuments#14 — must be merged first, the apps-external/richdocuments gitlink in this PR points at its commit.

Summary

ionos-dev-v33 was rebuilt as a ground slate off vanilla v33.0.6 (HDNEXT-1604) with a hand-curated set of IONOS patches — 39 changed paths against 60 on ionos-dev-v30. Most of that difference is legitimate (patches that landed upstream in NC33), but a handful of IONOS features were lost in the reconstruction, including one runtime fatal.

Gap list derived by diffing each branch against its own vanilla base (v30.0.7..ionos-dev-v30 vs v33.0.6..ionos-dev-v33), then checking every v30-only patch against vanilla v33.0.6 to separate upstreamed from lost, plus a cherry-pick-aware comparison of all 13 submodules.

What this PR restores

Commit Gap Note
IONOS(auth) UserAgentForbidden exception class was missing entirely runtime fatal
IONOS(files-sharing) Pending-shares view gate backend was there, frontend consumer lost
IONOS(files) computed templates_enabled upstream regression
IONOS(files) admin-configurable files user-config defaults
IONOS(settings) null mail transport notice upstream branch was unreachable
IONOS(config) IONOS gitlink → 01b3f0f notify_push only with Redis
IONOS(richdocuments) gitlink → guest gating fix see linked PR

Each commit body names the original commit(s) it was ported from.

1. UserAgentForbidden — runtime fatal

lib/private/User/Session.php and ocs/v1.php both reference OC\Authentication\Exceptions\UserAgentForbidden, but the class file exists in neither this branch nor vanilla v33.0.6.

This is not theoretical: nc-config ships ionos-apps-user-agents.config.php with core.login_flow_v2.allowed_user_agents = ['/Hidrive Next/i'], so the allow-list is active on every IONOS instance. Reproduced:

Error: Class "OC\Authentication\Exceptions\UserAgentForbidden" not found at lib/private/User/Session.php#598

The request returns an empty 200 instead of the intended 403.

2. Pending shares — half-ported

LoadAdditionalListener already provides the accept_default initial state from sharing.enable_share_accept, but nothing consumed it, so Pending shares always showed. Upstream moved the file src/views/shares.tssrc/files_views/shares.ts; the gate is restored there, defaulting to false so it fails closed.

3. templates_enabled — upstream regression

Upstream 64e852c5906 replaced the computed value with a hardcoded true, removing the only way to hide Create templates folder. nc-config sets both skeletondirectory and templatedirectory to '', so the entry came back.

Restored, but using the same SERVERROOT defaults as TemplateManager::initializeTemplateDirectory() rather than v30's empty-string defaults, so an instance that configures neither value keeps upstream behaviour. For IONOS builds both are set explicitly, so the outcome is identical to v30.

4. UserConfig — deviates from v30 on purpose

v30 always used getAppValueBool(), safe because every ALLOWED_CONFIGS entry was a boolean back then. NC33 added default_view (string, files/personal), and coercing that through getAppValueBool() would return true instead of 'files' for every user without a stored preference. The fallback is therefore type-aware.

5. Mail settings — upstream branch was dead code

additional-mail.php is now just a Vue mount point, so v30's patch had nowhere to apply. The Vue view does carry the equivalent branch, but it can never fire:

<NcNoteCard v-if="smtpMode?.id === 'null'">

smtpMode resolves mail_smtpmode against smtpModeOptions, and Admin\Mail::getForm() only ever offers smtp/sendmail/qmail. With mail_smtpmode = 'null' the lookup yields undefined, the notice is skipped and the v-else form renders instead — with an empty Send mode select. Verified: smtpModeOptions ids were smtp while mail_smtpmode was null.

Since nc-config ships mail.config.php with mail_smtpmode = 'null', this page is broken on every IONOS instance today.

Deliberately out of scope

Test backports (UserConfigTest.php, LoadAdditionalListenerTest.php, SessionTest.php user-agent cases) and the FilesListVirtual.vue folder-icon tweak (tied to the dropped FA Pro icon set, HDNEXT-1719). apps/files/js/fileactionsmenu.js needs nothing — the file no longer exists in NC33.

Already upstreamed into NC33, so no work needed: SetConfig sensitive values, MountPoint, Preview\Movie S3 guard, Mailer NullTransport, LoginFlowV2 client allow-list, SearchComposer provider filtering, Template::findTemplate core fix, all config.sample.php doc changes.

How it was verified

All in the dev container.

  • UserAgentForbidden: OCS + basic auth with a disallowed UA → 403 Client not allowed; allowed UA → 100 OK. Confirmed the failure mode without the fix, and that it works with the committed autoloader (OC\ resolves via PSR-4 — no classmap regeneration needed). Note WebDAV does not go through this path (own Sabre backend); pre-existing.
  • UserConfig: types preserved (default_view stays a string), admin-set app value becomes the default for users without a preference, a user's own preference still wins, invalid values still rejected.
  • Mail settings: initial state inspected to prove the upstream condition was unreachable; rebuilt bundle now uses the working gate.
  • richdocuments: 4 creators registered for a guest while userCanEdit() was false; new test fails without the fix; suite 89 tests, 208 assertions green.
  • phpunit: apps/files/tests/Controller/, apps/files_sharing/tests/Listener/, tests/lib/User/SessionTest.php65/65 and 32/32 green.
  • cs:check / eslint: clean on all changed files. Two cs:check findings and 14 eslint errors were left alone — verified pre-existing (the cs ones exist verbatim in pristine v33.0.6; the eslint ones are in SidebarQuota.vue / SharesMixin.js).

Compiled dist/ assets for the two frontend changes are committed alongside their sources; unrelated build drift in other bundles was deliberately excluded.

TODO

Checklist

  • Code is properly formatted
  • Tests are included — see out of scope; the richdocuments PR carries a regression test
  • Screenshots before/after for front-end changes
  • Documentation has been updated or is not required

lib/private/User/Session.php and ocs/v1.php both reference
OC\Authentication\Exceptions\UserAgentForbidden, but the class file was
never carried over when ionos-dev-v33 was rebuilt off vanilla v33.0.6.
It exists in neither this branch nor upstream, so every basic-auth
request fatals with "Class not found" as soon as
core.login_flow_v2.allowed_user_agents is configured.

Restore the file verbatim from ionos-dev-v30.

Ported from ionos-dev-v30:
  9391822 IONOS(feat): block unknown user agents
  30df636 IONOS(fix): block unknown user agents
The backend half of this feature is already on ionos-dev-v33:
LoadAdditionalListener provides the "accept_default" initial state from
the sharing.enable_share_accept system config. Nothing consumed it, so
the "Pending shares" navigation entry showed unconditionally.

Restore the frontend gate. Upstream moved the file from
apps/files_sharing/src/views/shares.ts to src/files_views/shares.ts, so
the patch is applied there; the registration is last in the function, so
an early return is enough. Default stays false so the entry fails closed.

Ported from ionos-dev-v30:
  9afff18 IONOS(files-sharing): show pending menu only if feature enabled
Upstream 64e852c ("only skip template initialization when both
skeletondirectory and templatedirectory are empty") replaced the computed
"templates_enabled" initial state with a hardcoded true, which removes
the only way to hide the "Create templates folder" entry from the New
menu. nc-config sets both skeletondirectory and templatedirectory to an
empty string (configs/initial-files.config.php), so the entry was back.

Restore the computed expression. Unlike ionos-dev-v30, which defaulted
both lookups to an empty string, this uses the same SERVERROOT defaults
as TemplateManager::initializeTemplateDirectory() (lib/private/Files/
Template/TemplateManager.php:320-323) so an instance that does not
configure either value keeps upstream behaviour instead of silently
losing the entry. For IONOS builds both are set explicitly, so the
outcome is identical to v30.

The frontend side (newMenu/newTemplatesFolder.ts) is already upstream and
needs no change; the TemplateManager half of 64e852c is left alone.

References:
  c7bcfbf fix: Hide "Create templates folder" option if templates are
              disabled in configuration (upstream; on ionos-dev-v30 as
              7bb09be)
  64e852c fix: only skip template initialization when both
              skeletondirectory and templatedirectory are empty (upstream
              regression this restores)
Let an admin set the instance-wide default for the files user configs via
`occ config:app:set files <key>`: getConfigs() now reads the user value
with a null default and, when the user has no explicit preference, falls
back to the app config before the shipped default. setConfig() coerces
booleans with filter_var() and validates strictly so "true"/"false"
strings from the API are stored as real booleans.

Deviation from ionos-dev-v30: v30 always used getAppValueBool(), which
was safe because every entry in ALLOWED_CONFIGS was a boolean back then.
NC33 added default_view (string, "files"/"personal"), and coercing that
through getAppValueBool() would return true instead of "files" for every
user without a stored preference. The fallback is therefore type-aware:
getAppValueBool() for boolean defaults, getAppValueString() otherwise.

Verified in the dev container: types preserved (default_view stays a
string), an admin-set app value becomes the default for users without a
preference, a users own preference still wins, and invalid values are
still rejected.

Ported from ionos-dev-v30:
  85edc56 feat(files/user-config): make configs admin-configurable
  8869c73 fix(files): strict check of default values
Upstream rewrote the admin mail settings as a Vue view, and
apps/settings/templates/settings/admin/additional-mail.php is now just a
mount point, so v30 IONOS patch has no place to apply anymore. The Vue
view does carry the equivalent branch, but it can never trigger:

  <NcNoteCard v-if="smtpMode?.id === 'null'">

smtpMode resolves mail_smtpmode against settingsAdminMail.smtpModeOptions,
and Admin\Mail::getForm() only ever offers smtp/sendmail/qmail there.
With mail_smtpmode = "null" the lookup yields undefined, the notice is
skipped and the v-else form renders instead - with an empty "Send mode"
select. Verified in the dev container: smtpModeOptions ids were "smtp"
while mail_smtpmode was "null".

Compare against the raw config value instead, which is what the v30
template did ($_["mail_smtpmode"] === "null"). This matters for IONOS
because nc-config ships mail.config.php with mail_smtpmode = "null", so
this page is broken on every IONOS instance.

Ported from ionos-dev-v30:
  83c6dc5 feat(Mailer): hide admin settings for "null" transport
Picks up the fix for the local-setup breakage described in HDNEXT-1967:
notify_push without a reachable Redis throws while its console commands
are constructed and prints that error on stdout with exit code 0, which
corrupts every occ call whose output configure.sh captures (most notably
`occ app:list --enabled --output json` piped into jq).

90800e6..01b3f0f:
  01b3f0f Merge pull request #145 from IONOS-Productivity/mk/fix/disable-notify-push-without-redis-password
  bafc421 fix(configure.sh): configure notify_push before the other apps
  e862a43 fix(configure.sh): disable notify_push unless Redis password is set
  39a31bc refactor(configure.sh): use log_info for plain status output
  f1daad5 refactor(configure.sh): use log_warning instead of inline ANSI codes
6b8957bfc..593107e1a:
  593107e1a IONOS: fix: do not offer document creation to public share visitors

Restores the ionos-dev-v30 behaviour that anonymous public share visitors
are not offered Collabora document creation. The v30 patch worked through
the legacy OCA.Files.NewFileMenu plugin, which no longer exists in the
NC33 line, so the gate now lives in RegisterTemplateFileCreatorListener.

Ported from ionos-dev-v30 richdocuments:
  f1db58f79 IONOS: fix: for shares allow document creation only for users
            that can edit
@bromiesTM
bromiesTM force-pushed the mk/dev/HDNEXT-1967-port-v30-features branch from c00ece1 to 5642dce Compare August 4, 2026 10:02
@bromiesTM
bromiesTM merged commit 93e514a into ionos-dev-v33 Aug 4, 2026
3 of 12 checks passed
@bromiesTM
bromiesTM deleted the mk/dev/HDNEXT-1967-port-v30-features branch August 4, 2026 10:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants