- js/index.js: the occ-command ajax call used the wrong jQuery .fail()
signature ((response, code) instead of (jqXHR, textStatus,
errorThrown)), so any failure printed the literal string
"[object Object]" instead of a useful message.
- js/index.js: the initial bootstrap call that builds the terminal had
no .fail() handler at all - a failure there (expired session/CSRF
token, network error, rejected admin check) left #app-content
permanently blank with zero diagnostic information. This is exactly
what made today's NC34 debugging session harder than it needed to
be; now it shows the actual HTTP status/reason in the page.
- OccController.php: translated a leftover Dutch comment (missed by
the earlier Russian->English pass since it wasn't Russian), and
documented why requireAdmin() is intentional defense-in-depth rather
than a misunderstanding of the framework: verified against
Nextcloud's own SecurityMiddleware source that any controller method
without @NoAdminRequired already rejects non-admins by default, so
this check (and the original "security fix" commit that added it)
was addressing a non-issue for THIS controller specifically.
DbController's equivalent check is still genuinely load-bearing -
that controller originally shipped with @PublicPage, which does
bypass the default protection - so it gets a note explaining the
distinction instead.
- README: added compatibility matrix rows for 0.4.0 (app id rename to
extended_occweb) and 0.4.1 (these fixes), both verified on NC 34.0.4.
Deferred to when a test instance exists (tracked, not fixed here): no
documented migration path from the old occweb id to extended_occweb
for existing installs, OccController's constructor doing expensive
work before the (redundant) admin check runs, and js/jquery.js loading
unconditionally on NC30-33 where core still provides jQuery.
Version bump to 0.4.1.
Nextcloud's app id "occweb" is effectively unavailable for a new store
listing: the original Adphi/occweb still owns that App Store slot
(stale, v0.2.3), and el-choco/occweb_v2 has since published a
same-lineage rewrite under its own id. Rather than fight over the
"occweb" name, publish this fork under its own id, matching the
<name> this app has always had: "Extended OCC Web".
Renames every place the literal app id is used: info.xml <id> and the
auto-generated navigation <route>, script()/style() registrations in
templates/index.php, the TemplateResponse app name in
OccController::index(), the /apps/... base URL in js/index.js, and the
'app' log context tag in DbController.php. The GitHub repo name and
its <website>/<bugs>/<repository>/<screenshot> links are unaffected -
those identify the repo, not the Nextcloud app.
Docs (README, INSTALL-AIO.md, install.sh) updated to clone into and
reference an "extended_occweb" directory, since Nextcloud requires the
app folder name to match its id - a plain `git clone` of this repo no
longer produces a correctly-named install directory on its own.
Version bump to 0.4.0 given the scope (breaking change for anyone who
already deployed under the old "occweb" id - requires disable+remove
of the old app and a fresh enable under the new id, not an in-place
upgrade).
query() runs arbitrary admin SQL (including DELETE/UPDATE) and was
exempted from CSRF protection — a leftover from the original upstream
code, which had this alongside @PublicPage (no auth at all) before our
admin-check hardening. The client already goes through the standard
$.ajax() flow that auto-attaches Nextcloud's CSRF token, exactly like
OccController::cmd() does without any such exemption, so removing it
has no functional cost.
Also bump nextcloud max-version to 36 to match nc01's current core
version, now that AIO auto-updates the core nightly.
Version bump to 0.3.4.
Covers OccOutput.php, DbController.php and js/index.js: docblocks,
inline comments, the forbidden-construct labels shown to admins in
error responses, and the SQL template descriptions shown in the
terminal (delete-user, list-user, rename-user).
- New 'rename-user' template (templates / template rename-user <old> <new>):
best-effort uid rename across core tables (oc_users, oc_preferences,
oc_group_user, oc_group_admin, oc_ldap_user_mapping, oc_share, oc_mounts,
oc_storages). Explicitly NOT a supported Nextcloud operation - the
generated script carries an in-line warning (as leading SQL comments)
that app-specific tables (Talk, Calendar, Contacts, Mail, 2FA/WebAuthn...)
are not covered and that the data directory must be renamed on disk
manually, followed by occ files:scan --all. Documented the same caveat
in both READMEs.
- Hardened the round-2 transaction wrapping: beginTransaction()/commit()/
rollBack() are now wrapped in try/catch. PostgreSQL (our backend) has
fully transactional DDL so this wasn't actually broken here, but
Nextcloud also supports MySQL/MariaDB via the same IDBConnection, where
DDL implicitly commits - on that backend a DDL statement in the batch
would make a later commit()/rollBack() throw 'no active transaction'
and previously that exception was unhandled (HTTP 500 instead of a
clean JSON response). Now: if rollBack() itself fails after an error,
we report rollbackFailed+warning instead of falsely claiming rolledBack,
since earlier statements in that batch may already be permanently
applied. If commit() fails with nothing to commit (already
auto-committed), that's logged only, since the effects are already
durably persisted.
- removeAllComments() strips -- and /* */ comments before checking
FORBIDDEN_PATTERNS, closing a bypass where a comment inserted between
a function name and '(' hid it from the regex (e.g. pg_read_file/**/(...)).
- UPDATE now requires confirm=true just like DELETE (deleteCount/updateCount).
- Batches run inside a single DB transaction; a failing statement rolls back
everything already applied in that batch instead of leaving partial writes.
- splitStatements() (PHP and JS) now tracks a single quoteChar instead of a
bool, handling both '...' strings and "..." quoted identifiers symmetrically.
- Frontend TEMPLATES no longer rely on SET/current_setting: the escaped uid
is inlined into every statement, so partial copy/paste still works.
- renderTable() renders NULL as [NULL] instead of an empty string, so it's
no longer visually identical to an empty string value.
- Added MAX_SQL_BYTES (1MB) request size limit, returned as HTTP 413.
- Added a 120s client-side AJAX timeout with a distinct timeout message,
so a hung request doesn't leave the terminal paused indefinitely.