This repository was archived by the owner on May 29, 2026. It is now read-only.
Create openregister.csr#1
Merged
Merged
Conversation
This was referenced Sep 6, 2024
WilcoLouwerse
added a commit
that referenced
this pull request
Feb 9, 2026
Update setAuthorization() methods to accept and decode JSON strings when loading entities from the database, preventing type errors during entity hydration. Fixes: "Argument #1 ($authorization) must be of type ?array, string given"
rubenvdlinde
added a commit
that referenced
this pull request
May 3, 2026
…1420) Adds four openspec changes implementing the audit's top hardcoded- functionality findings + ADR-019 + ADR-025. - openspec/changes/register-resolver-service/ (4 files, 560 lines) publishable RegisterResolverService that absorbs the `getValueString(...register/schema...)` pattern duplicated across 13 call sites in opencatalogi (5 controllers), pipelinq (8 services/jobs), and docudesk (OpenRegisterResolver). Five public methods (resolveRegisterId/SchemaId/Register/Schema/Pair), request-scoped caching, multi-tenant scoping via MultiTenancyTrait, three structured exceptions (MissingConfig / RegisterNotFound / SchemaNotFound), enumerateAppConfigs() for admin tooling. - openspec/changes/pluggable-integration-registry/ (4 files, 472 lines) Implements hydra ADR-019 — two-sided integration registry. IntegrationProvider PHP interface + IntegrationRegistry service + DI tag auto-registration; migrates the 8 built-in NC types (files/notes/tasks/calendar/mail/contacts/deck/talk) from the hardcoded `LinkedEntityService::TYPE_COLUMN_MAP`; routes external providers through OpenConnector; advertises capabilities via OCS; CI parity gate ensures backend ↔ frontend pairing. - openspec/changes/i18n-source-of-truth/ (4 files, 510 lines) Implements hydra ADR-025 (source-of-truth half). Adds `sourceLanguage` schema-property modifier + per-object override via `_translationMeta` + new `source_language` column on openregister_translations + render envelope `_meta.languageMeta` + `X-Source-Language` response header + automatic outdated-status flip on source-value change. Closes the gap from audit R4. - openspec/changes/i18n-api-language-negotiation/ (4 files, 437 lines) Implements hydra ADR-025 (API contract half). Adds `?_lang=` / `?language=` query params with explicit precedence over Accept-Language, lax fallback (no 406), and a write-side `X-Translation-Target-Language` header for scalar-body PATCH/PUT to non-default languages. Conflicting body+header → 400. References: .claude/audit-2026-05-03/research/R4-or-i18n-source-of-truth.md .claude/audit-2026-05-03/research/R5-or-api-language-negotiation.md .claude/audit-2026-05-03/04-hardcoded.md (top-10 findings #1-#10) hydra/openspec/architecture/adr-019-integration-registry.md hydra/openspec/architecture/adr-022-apps-consume-or-abstractions.md hydra/openspec/architecture/adr-025-i18n-source-of-truth.md
This was referenced May 5, 2026
rubenvdlinde
added a commit
that referenced
this pull request
May 12, 2026
…t + add BuiltIn provider tests
The ai-chat-companion-orchestrator change refactored McpToolsService from
an inline registers/schemas/objects CRUD service into a provider
aggregator: it now takes `array $providers` + relocates the CRUD logic to
lib/Mcp/BuiltIn/{Registers,Schemas,Objects}ToolProvider. The old 62-test
McpToolsServiceTest still constructed the pre-refactor signature
(RegisterService as arg #1) → 63 ArgumentCountErrors.
- McpToolsServiceTest: rewritten against the new API — listTools()
aggregation + `{appId}.` namespace enforcement (drops + warns),
callTool() routing/success-wrap/InvalidArgumentException-on-unknown/
exception-to-isError/debug-log/first-match-wins, invokeTool() flat
envelope + no-throw-on-unknown, addProvider() runtime registration.
- New tests/Unit/Mcp/BuiltIn/{Registers,Schemas,Objects}ToolProviderTest:
cover the relocated CRUD logic — getAppId(), the single namespaced
descriptor + inputSchema, each action (list/get/create/update/delete)
delegating to the mocked service, missing-param + unknown-action
throwing InvalidArgumentException; the objects provider also covers the
register+schema requirement and setRegister/setSchema scoping.
rubenvdlinde
added a commit
that referenced
this pull request
May 18, 2026
Brings development from 4 failing required CI jobs (Vue eslint, SBOM, PHPUnit ×2) to 0 failures, so the 7 open PRs that just rebased onto development can also clear quality gates. ## src/main.js — Vue eslint: `import/first` (5 errors) The xwiki-registry side-effect block was inserted between two import groups, which violates `import/first`. Moved all `import` statements above the side-effect code. No behavior change — the imports are hoisted at parse time anyway, so execution order is identical. ## package.json + package-lock.json — SBOM: `npm ls` exit 1 `@conduction/nextcloud-vue@1.0.0-beta.46` declares `@vueuse/core:^10.0.0` in its package.json, but its own internal `@nextcloud/dialogs@7.3.0` transitively requires `@vueuse/core:^14.0.0`. npm installs 14.2.1 to satisfy the transitive constraint, but that violates nc-vue's stated range, so `npm ls` exits 1 and SBOM generation fails. Added an `overrides` entry that re-declares nc-vue's `@vueuse/core` constraint as `^14.0.0`, matching what's actually installed. Other vueuse consumers (root, @nextcloud/vue, the v6.x dialogs branch) stay on their own ranges (10.x / 11.x) — npm hoists them separately. The upstream nc-vue package.json should be updated to match what its own internal deps require — flagged as a separate follow-up against the nc-vue repo (peer-dep narrowing). ## 13 test files — PHPUnit: 142 errors (constructor signature drift) Pre-existing test debt where production constructors gained args / changed types but the tests weren't updated. Same pattern as LeafProvidersMetadataTest (PR #1562). Files fixed: - `ToolRegistrationListenerTest` (3 err): ctor went 5 → 7 args, added `McpToolsService` + `LoggerInterface` mocks - `GitHubHandlerTest` (30 err): ctor switched from `IClientService` to 6 named args incl. `IClient` + `AttributionFormatter` - `TextExtractionService{Coverage,Deep,Gap}Test` (47+46+16 err): ctor gained `EmlParser $emlParser` (from PR #1504), added the mock - `ManifestServiceTest` (1 fail): production now requires explicit `x-openregister-manifest-user-fields` allowlist; added to fixture - `AnnotationNotificationDispatcherTest` (1 fail, surfaced after the above): production switched from `isDuplicate()` polling to claim-first via `record()` throwing `DuplicateDispatchException`; mock updated ## tests/bootstrap-unit.php — 22 ZipStream TypeErrors If the `forms` app is installed in the test environment, it ships ZipStream v2 (`ZipStream\Option\Archive`) in its vendor tree. PhpSpreadsheet's writer dispatcher then sees `class_exists(Archive)` returns true and picks the v2 entry point, but calls v2 methods against the v3 ZipStream that OR ships, causing `Argument #1 (\$operationMode) must be of type ZipStream\OperationMode, null given`. Bootstrap now defensively strips the forms-app ZipStream v2 vendor entries from all Composer autoloaders before any test runs. No-op in CI environments where forms isn't installed. ## lib/Db/MagicMapper.php — remove debug file_put_contents calls Two stray `file_put_contents('/tmp/or-debug.log', ...)` calls in the constructor were silently writing to disk and (more visibly) triggering "Permission denied" PHP warnings during test runs. Replaced with a logger->warning call when the static `\$constructCount > 2` guard trips. The guard itself is left in place — it covers a circular- construction case under investigation in #1564. ## Verification - ✅ `composer phpcs` → 814 files, 0 errors - ✅ `npm run lint` → 0 errors (273 warnings, pre-existing) - ✅ `npm ls --json --long --all --package-lock-only --omit=dev` → exit 0 - ✅ `phpunit -c phpunit-unit.xml` → 12,224 tests / 25,942 assertions / 0 errors / 0 failures (was 142 errors)
5 tasks
rjzondervan
added a commit
that referenced
this pull request
May 21, 2026
…-side; surface root cause on rollback (#1593) **Root cause of the operator-reported 500:** The `oc_openregister_entities` table has TWO `NOT NULL`-with-no-default columns (`category` and `updated_at`) that the existing detector flow (`EntityRecognitionHandler::findOrCreateEntity`) always populates. The new manual-entity flow only populated `detected_at`, so the insert failed at the DB layer with two consecutive `SQLSTATE[HY000] 1364 Field 'X' doesn't have a default value` errors — one per column. **Fix #1 — `category` is now server-derived, removed from the API:** - `EntityRecognitionHandler::getCategoryForType()` is now `public static` (was `private`) so producers outside the detector pipeline can derive the same mapping without taking on the handler's DI graph. - `ManualEntityService::lookupOrCreateEntity()` calls it on every new insert. Rationale: the operator UI rarely has the context to make a category decision, the detector flow already derives consistently, and exposing the field as operator-input was the original source of the bug (omitted = null = NOT NULL violation). Manual-entity rows and detector rows now share categories for identical types. - `category` removed from the request body, the service signature, the `writeAuditTrails` signature, the controller body-parsing, and the unit tests. The audit trail still records `category` in `changed.fields` — read from the entity after insert, so the persisted value is captured verbatim. - Operator-override on category is intentionally NOT exposed in v1; a follow-up if a concrete use case emerges. **Fix #2 — `updated_at` populated alongside `detected_at`:** - Same root cause class. Mirroring the detector flow's column population fixes it. **Fix #3 — operator-debuggable rollback path:** The service's `catch (Throwable $error)` block wrapped the original exception as `ManualEntityException(REASON_INTERNAL_ERROR)` without logging. Combined with the controller's `mapManualEntityException` only logging the reason code (not the previous-exception message), a 500 left no debuggable trail in `nextcloud.log` — exactly what the operator hit. Added a `LoggerInterface::error()` call inside the service's rollback handler that captures `errorType`, `error`, and `trace` of the underlying Throwable before re-wrapping. Future operator-reported 500s will have a stack-trace-level log entry keyed by reqId. **Spec + docs updates:** - `docs/Features/manual-entity-anonymisation.md` — request body shape loses the `category` line; added a note explaining the server-side derivation. - `openspec/changes/manual-entity-anonymisation/proposal.md` — example body updated; the 400 error hint updated. - `openspec/changes/manual-entity-anonymisation/design.md` — derivation rationale folded into the existing "lookup-or-create" section; the open-question on category resolved with a "not in the API at all" decision. - `openspec/changes/manual-entity-anonymisation/specs/entity-relation-grondslagen/spec.md` — Requirement updated, "Category mismatch does NOT trigger an update" scenario replaced with "New catalogue row carries the server-derived category". - `openspec validate manual-entity-anonymisation` clean. **Verification:** - PHPCS clean (4 touched files including the new logger call). - PHPStan clean on the full diff. - 44 unit tests / 145 assertions across `ManualEntityServiceTest|FileTextControllerManualEntityTest|ChunkTextMatcherTest|GdprEntityMapperTest|EntityRelationMapperTest` all green in the live `master-nextcloud-1` container. - End-to-end smoke test in the dev environment: - Empty-match POST → HTTP 200 with `message`, catalogue row created. - Match POST → HTTP 201 with `matchCount=4, matchesSkipped=2` (the 2 skipped were pre-existing detector hits at the same positions). - Idempotent re-POST → HTTP 201 with `matchCount=4, matchesSkipped=4`, `relations: []` (no duplicates). Refs: #1593
rjzondervan
added a commit
that referenced
this pull request
May 26, 2026
…-side; surface root cause on rollback (#1593) **Root cause of the operator-reported 500:** The `oc_openregister_entities` table has TWO `NOT NULL`-with-no-default columns (`category` and `updated_at`) that the existing detector flow (`EntityRecognitionHandler::findOrCreateEntity`) always populates. The new manual-entity flow only populated `detected_at`, so the insert failed at the DB layer with two consecutive `SQLSTATE[HY000] 1364 Field 'X' doesn't have a default value` errors — one per column. **Fix #1 — `category` is now server-derived, removed from the API:** - `EntityRecognitionHandler::getCategoryForType()` is now `public static` (was `private`) so producers outside the detector pipeline can derive the same mapping without taking on the handler's DI graph. - `ManualEntityService::lookupOrCreateEntity()` calls it on every new insert. Rationale: the operator UI rarely has the context to make a category decision, the detector flow already derives consistently, and exposing the field as operator-input was the original source of the bug (omitted = null = NOT NULL violation). Manual-entity rows and detector rows now share categories for identical types. - `category` removed from the request body, the service signature, the `writeAuditTrails` signature, the controller body-parsing, and the unit tests. The audit trail still records `category` in `changed.fields` — read from the entity after insert, so the persisted value is captured verbatim. - Operator-override on category is intentionally NOT exposed in v1; a follow-up if a concrete use case emerges. **Fix #2 — `updated_at` populated alongside `detected_at`:** - Same root cause class. Mirroring the detector flow's column population fixes it. **Fix #3 — operator-debuggable rollback path:** The service's `catch (Throwable $error)` block wrapped the original exception as `ManualEntityException(REASON_INTERNAL_ERROR)` without logging. Combined with the controller's `mapManualEntityException` only logging the reason code (not the previous-exception message), a 500 left no debuggable trail in `nextcloud.log` — exactly what the operator hit. Added a `LoggerInterface::error()` call inside the service's rollback handler that captures `errorType`, `error`, and `trace` of the underlying Throwable before re-wrapping. Future operator-reported 500s will have a stack-trace-level log entry keyed by reqId. **Spec + docs updates:** - `docs/Features/manual-entity-anonymisation.md` — request body shape loses the `category` line; added a note explaining the server-side derivation. - `openspec/changes/manual-entity-anonymisation/proposal.md` — example body updated; the 400 error hint updated. - `openspec/changes/manual-entity-anonymisation/design.md` — derivation rationale folded into the existing "lookup-or-create" section; the open-question on category resolved with a "not in the API at all" decision. - `openspec/changes/manual-entity-anonymisation/specs/entity-relation-grondslagen/spec.md` — Requirement updated, "Category mismatch does NOT trigger an update" scenario replaced with "New catalogue row carries the server-derived category". - `openspec validate manual-entity-anonymisation` clean. **Verification:** - PHPCS clean (4 touched files including the new logger call). - PHPStan clean on the full diff. - 44 unit tests / 145 assertions across `ManualEntityServiceTest|FileTextControllerManualEntityTest|ChunkTextMatcherTest|GdprEntityMapperTest|EntityRelationMapperTest` all green in the live `master-nextcloud-1` container. - End-to-end smoke test in the dev environment: - Empty-match POST → HTTP 200 with `message`, catalogue row created. - Match POST → HTTP 201 with `matchCount=4, matchesSkipped=2` (the 2 skipped were pre-existing detector hits at the same positions). - Idempotent re-POST → HTTP 201 with `matchCount=4, matchesSkipped=4`, `relations: []` (no duplicates). Refs: #1593
rjzondervan
added a commit
that referenced
this pull request
May 28, 2026
Bumps the ddn/sapp constraint from dev-feat/text-replacement-api#25db760 (pre-strict-review snapshot of the per-PR branch) to dev-work/text-replacement#07e5a74 — the tip of the SAPP fork's work/text-replacement integration branch after all 10 upstream-PR drafts (#1-#8 upstream-numbering / #1-#10 fork-PR numbering) were merged and strict-review remediated. What lands by switching the pin: - Filter chain dispatch with array-form /Filter (PR #5) - ASCIIHex, RunLength, ASCII85, LZW decoders + encoders (#1-#4) - ToUnicode CMap + FontEncoding for Identity-H/V composite fonts (#6) - TJ kerning-array flattening with multi-match per TJ + spec-tight numeric/hex/whitespace tokenisation (#7) - Public replace_text_in_document() API with Helvetica subset-font fallback + 12-key diagnostic surface + rejected_substitutions input validation (#8) - All chain-failure-propagation contracts (return false on every decoder failure path so downstream filters short-circuit cleanly) Preparatory for the pdf-anonymisation change which depends on the new replace_text_in_document API.
rubenvdlinde
added a commit
that referenced
this pull request
May 28, 2026
…jection allowlist) (#2008) CRITICAL #1 — RevertHandler RBAC bypass (C1): RevertHandler::revert() called findAcrossAllSources with _rbac:false and _multitenancy:false, letting any authenticated user revert any object in any tenant without permission checks. NotAuthorizedException was imported but never thrown. Fix: - Add missing constructor with AuditTrailMapper, ContainerInterface, IEventDispatcher, MagicMapper, and new PermissionHandler dependency. - Remove _rbac:false / _multitenancy:false flags — use tenant-scoped find. - After the find, call permissionHandler->hasPermission(schema, 'update', object) and throw NotAuthorizedException when denied. CRITICAL #2 — Client-supplied @self overwrites server-controlled fields (C2): Two-layer fix: Layer 1 — SaveObject::setSelfMetadata (primary): The method accepted owner from raw client $selfData and applied it to the entity before applyOwnerAttribution() ran. For logged-in REST requests, applyOwnerAttribution() overrode it; for background/system contexts with no IUserSession user, the client-supplied owner persisted. Removed the owner setter from setSelfMetadata — applyOwnerAttribution() is the sole authoritative owner setter. Layer 2 — MagicMapper::prepareObjectDataForTable (defense-in-depth): Client could inject @self.owner and @self.authorization via the @self block. Added explicit strip of owner and authorization from $metadata before the DB write. Also made the register/schema override unconditional (previously only applied when empty) to prevent identity field injection. Tests updated: SaveObjectDeepTest, SaveObjectTest, SaveObjectCoverageTest (owner-setting assertions inverted to assert null), MagicMapperTest (register/schema values changed to verify server-param override; owner column asserted null). gate output: php -l clean on all 7 files; phpstan no new errors (2 pre-existing errors in test files unchanged); phpunit 457/457 pass on modified test files. References wave-7 deep review (project_deep-review-findings-2026-05-27.md)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
certificate signing request for the nextcloud ppstore