This repository was archived by the owner on May 29, 2026. It is now read-only.
fix(security): wave-3 critical fixes#183
Merged
Merged
Conversation
C1 — ApplicationInsightsService: inject SchemaMapper, resolve schema
slugs to integer IDs via SchemaMapper::find() before passing to
AuditTrailMapper. Removes array_map('intval', ...) that converted every
slug to 0, silently zeroing all KPI dashboard values on every install.
C2 — ManifestResolverService + ApplicationsController: replace three
'application-version' string literals with
ApplicationVersionService::APPLICATION_VERSION_SCHEMA ('applicationVersion').
SchemaMapper::find() lowercases before compare, so 'applicationversion' ≠
'application-version', causing DoesNotExistException on every ?_version=
route and the diff endpoint.
C3 — RunExportJob: add ExportJobService::loadJob(), call it at the top
of executePipeline() to read the real applicationUuid/applicationVersion/
applicationSlug/license from the queued OR record. Removes hardcoded
'exported-app' / '0.1.0' context and job UUID passed as applicationUuid.
C4 — ApplicationsController::persistApplication: populate
permissions.owners = ['user:<ownerUid>'] on the cloned Application so
PermissionResolver::matchesCaller returns true and non-admin
citizen-developers are not immediately 403'd from their own clones.
Tests: update RunExportJobTest to mock loadJob with a job fixture for
all pipeline-exercising paths; add SchemaMapper mock to
ApplicationInsightsServiceTest setUp.
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.
Summary
Fixes all 4 wave-3 CRITICAL findings verified in
/tmp/triage-openbuilt.md.C1 (
ApplicationInsightsService): InjectSchemaMapper, resolve schema slugs to integer IDs viaSchemaMapper::find()before passing toAuditTrailMapper.array_map('intval', $schemaIds)converted every slug string to 0, silently zeroing all KPI dashboard values on every install.C2 (
ManifestResolverService+ApplicationsController): Replace three'application-version'string literals withApplicationVersionService::APPLICATION_VERSION_SCHEMA('applicationVersion'). SchemaMapper lowercases before compare —'applicationversion' ≠ 'application-version'— so every?_version=manifest route and the diff endpoint silently returned null (DoesNotExistException swallowed as 404).C3 (
RunExportJob+ExportJobService): AddExportJobService::loadJob(), call it at the top ofexecutePipeline()to read the realapplicationUuid/applicationVersion/applicationSlug/licensefrom the queued OR record. Old code passed$jobUuidasapplicationUuidand hardcoded'exported-app'/'0.1.0', making every export produce the same generic stub.C4 (
ApplicationsController::persistApplication): Populatepermissions.owners = ['user:<ownerUid>']on the cloned Application. Without this,PermissionResolver::matchesCallerreturned false on empty permissions, immediately 403-ing non-admin citizen-developers from their own template clones.Test plan
GET /api/apps/{slug}/manifest?_version={versionSlug}returns 200