Tighten formActions guard: allowlist real exceptions and require call sites.
Also rethrow non-FormDataBoundaryError from the activity lifecycle id pre-parse.
This commit is contained in:
parent
3c162c5250
commit
98c334785e
2 changed files with 14 additions and 6 deletions
|
|
@ -1,7 +1,7 @@
|
|||
'use server'
|
||||
|
||||
import { cancelActivity, markActivityRealized } from '@/app/(campaign)/campanha/actions/activity'
|
||||
import { requiredRelationshipFormValue } from '@/lib/formData'
|
||||
import { FormDataBoundaryError, requiredRelationshipFormValue } from '@/lib/formData'
|
||||
import type { Activity } from '@/payload-types'
|
||||
import {
|
||||
runCampaignRedirectFormAction,
|
||||
|
|
@ -21,7 +21,8 @@ const setActivityLifecycleFormAction = async (
|
|||
let activityId: number
|
||||
try {
|
||||
activityId = requiredRelationshipFormValue(formData, 'id')
|
||||
} catch {
|
||||
} catch (error) {
|
||||
if (!(error instanceof FormDataBoundaryError)) throw error
|
||||
return { message: ACTIVITY_ID_MISSING_MESSAGE }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -145,6 +145,11 @@ describe('campaign formActions convention', () => {
|
|||
// by useOptimistic in ActivityTaskChecklist — not a (state, formData) ladder,
|
||||
// nothing to route through the shared wrapper.
|
||||
'src/app/(campaign)/campanha/(app)/atividades/[slug]/taskActions.ts',
|
||||
// Custom unique-violation → fieldErrors + async duplicate-title fallback
|
||||
// that links to the existing activity — policy the wrappers don't grow for.
|
||||
'src/app/(campaign)/campanha/(app)/atividades/formActions.ts',
|
||||
// Flattens field errors into message-only states for inline detail controls.
|
||||
'src/app/(campaign)/campanha/(app)/apoiadores/[id]/formActions.ts',
|
||||
])
|
||||
|
||||
it('routes every *FormActions / taskActions ladder through a shared wrapper', () => {
|
||||
|
|
@ -152,10 +157,12 @@ describe('campaign formActions convention', () => {
|
|||
.filter((file) => isGuardedActionFile(basename(file)))
|
||||
.map(repoPath)
|
||||
.filter((path) => !allowlist.has(path))
|
||||
.filter(
|
||||
(path) =>
|
||||
!/runCampaign(Redirect)?FormAction/.test(readFileSync(resolve(repoRoot, path), 'utf8')),
|
||||
)
|
||||
.filter((path) => {
|
||||
// Require a real call site — a comment naming the wrappers must not pass
|
||||
// (the documented exceptions above used to hide behind that loophole).
|
||||
const source = readFileSync(resolve(repoRoot, path), 'utf8')
|
||||
return !/\brunCampaign(Redirect)?FormAction\s*\(/.test(source)
|
||||
})
|
||||
|
||||
expect(offenders, 'wrap with runCampaignFormAction/runCampaignRedirectFormAction').toEqual([])
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in a new issue