[DRAFT] S-M features - #851
Conversation
# Conflicts: # documentation/release-notes/13.x.x/13.38.0/README.md # frontend/projects/valtimo/admin-settings/src/lib/constants/feature-toggle.constants.ts
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughSummary by CodeRabbit
WalkthroughThe backend Zaaktype DTO now exposes begin and end validity dates, with tests covering ISO date serialization and nullable end dates. Frontend zaaktype models and templates display validity ranges and translated open-ended dates. A new Form.io feature toggle is defined, localized, and documented. FormioComponent now switches between localStorage-based and in-memory token readiness and conditionally persists tokens. 🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 4d5c305c-8e76-4f2e-8599-733668422248
📒 Files selected for processing (12)
backend/zgw/catalogi-api/src/main/kotlin/com/ritense/catalogiapi/web/rest/result/ZaaktypeDto.ktbackend/zgw/catalogi-api/src/test/kotlin/com/ritense/catalogiapi/BaseTest.ktbackend/zgw/catalogi-api/src/test/kotlin/com/ritense/catalogiapi/web/rest/CatalogiResourceTest.ktdocumentation/release-notes/13.x.x/13.39.0/README.mdfrontend/projects/valtimo/admin-settings/src/lib/constants/feature-toggle.constants.tsfrontend/projects/valtimo/components/src/lib/components/form-io/components/form-io/form-io.component.htmlfrontend/projects/valtimo/components/src/lib/components/form-io/components/form-io/form-io.component.tsfrontend/projects/valtimo/resource/src/lib/models/open-zaak.model.tsfrontend/projects/valtimo/shared/assets/core/en.jsonfrontend/projects/valtimo/shared/assets/core/nl.jsonfrontend/projects/valtimo/shared/src/lib/models/config.tsfrontend/projects/valtimo/zgw/src/lib/modules/zaken-api/components/zaken-api-zaaktype-link/zaken-api-zaaktype-link.component.html
| if (this._storeTokenInLocalStorage) { | ||
| Formio.setUser(jwtDecode(token)); | ||
| Formio.setToken(token); | ||
| this.localStorageService.setTokenInLocalStorage(token); | ||
| } else { | ||
| // Feature toggle 'disableFormioTokenInLocalStorage': keep the token in memory only, since | ||
| // Formio.setToken/setUser would persist it (and the decoded user) to localStorage where any | ||
| // script could read it. Our APIs authenticate via the Keycloak token on the HTTP interceptor. | ||
| (Formio as unknown as {token: string}).token = token; | ||
| this._inMemoryTokenSet$.next(true); | ||
| } |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== locate file =="
git ls-files | rg 'frontend/projects/valtimo/components/src/lib/components/form-io/components/form-io/form-io\.component\.ts$' || true
echo "== file header and relevant lines =="
if [ -f frontend/projects/valtimo/components/src/lib/components/form-io/components/form-io/form-io.component.ts ]; then
sed -n '1,40p' frontend/projects/valtimo/components/src/lib/components/form-io/components/form-io/form-io.component.ts
echo "== lines 230-285 =="
sed -n '230,285p' frontend/projects/valtimo/components/src/lib/components/form-io/components/form-io/form-io.component.ts
fi
echo "== search clearToken methods/formioToken usages =="
rg -n "clearTokenFromLocalStorage|setTokenInLocalStorage|formioToken|disableFormioTokenInLocalStorage|Formio\.setToken|Formio\.setUser|token" frontend/projects/valtimo/components/src/lib/components/form-io frontend/projects/valtimo -g '!**/node_modules/**' | head -n 200
echo "== file count and license headers quick check for related files =="
git ls-files 'frontend/projects/valtimo/components/src/lib/components/form-io/**/*.ts' | while read -r f; do
first=$(sed -n '1,2p' "$f")
case "$first" in
'/*'|'<!--') echo "OK $f: $first" ;;
*) echo "HEADER_MISSING_OR_DIFFERENT $f: $first" ;;
esac
doneRepository: valtimo-platform/valtimo
Length of output: 41976
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== form-io local storage service =="
cat -n frontend/projects/valtimo/components/src/lib/components/form-io/services/form-io-local-storage.service.ts
echo "== form-io component relevant lifecycle and setToggle config =="
sed -n '70,105p' frontend/projects/valtimo/components/src/lib/components/form-io/components/form-io/form-io.component.ts
echo "== lines 110-160 =="
sed -n '110,160p' frontend/projects/valtimo/components/src/lib/components/form-io/components/form-io/form-io.component.ts
echo "== lines 190-275 =="
sed -n '190,275p' frontend/projects/valtimo/components/src/lib/components/form-io/components/form-io/form-io.component.ts
echo "== lines 295-335 =="
sed -n '295,335p' frontend/projects/valtimo/components/src/lib/components/form-io/components$form-io/form-io.component.ts
echo "== lock/package references to `@formio/angular` version =="
fd -a 'package-(lock|json)$' frontend | while read -r f; do
if rg -q '"`@formio/angular`"' "$f"; then
echo "--- $f"
php -r "echo file_get_contents('$f');" 2>/dev/null | rg -n '"`@formio/angular`"|"`@formio/angular/tree`"' -A2 -B2 || true
fi
done
echo "== read-only behavioral model of localStorage persistence path =="
python3 - <<'PY'
from pathlib import Path
import re
for path in [
Path("frontend/projects/valtimo/components/src/lib/components/form-io/components/form-io/form-io.component.ts"),
Path("frontend/projects/valtimo/components/src/lib/components/form-io/services/form-io-local-storage.service.ts"),
]:
text = path.read_text()
print(f"== {path} ==")
print("clearTokenFromLocalStorage references:", text.count("clearTokenFromLocalStorage"), "calls:", bool(re.search(r"\.clearTokenFromLocalStorage\s*\(", text)))
print("setInitialToken calls setToken:", bool(re.search(r"this\.setToken\s*\(", text)))
print("feature toggle branch lines:")
for i, line in enumerate(text.splitlines(), 1):
if "disableFormioTokenInLocalStorage" in line or "disableFormioTokenInLocalStorage" in line:
print(f"{i}: {line.strip()}")
PY
echo "== all local-storage clear methods =="
rg -n "clearTokenFromLocalStorage|localStorage\.removeItem|removeItem\(" frontend/projects/valtimo/components/src/lib -g '*.ts'Repository: valtimo-platform/valtimo
Length of output: 8682
🌐 Web query:
Form.io JavaScript SDK Formio.setToken localStorage Formio.setUser documentation
💡 Result:
In the Form.io JavaScript SDK, the Formio.setToken and Formio.setUser methods are used to manage authentication and user state within the browser's local storage [1][2][3]. Formio.setToken(token) The Formio.setToken method is used to set or remove the JSON Web Token (JWT) within the browser's local storage [1][2]. - Usage: Passing a valid JWT token string will store it in local storage [1][2]. If an empty value is provided, the token will be deleted from local storage [1][2]. - Storage: By default, the token is stored in a local storage variable named formioToken [1][4]. - Customization: You can change the storage prefix by setting a custom namespace in the SDK configuration (e.g., setting the namespace to 'test' will store the token as 'testToken') [1][2]. Formio.setUser(user, opts) The Formio.setUser method is used to set the current user object within the application cache [3]. - Parameters: - user: A JSON object containing the user metadata you wish to set [3]. - opts: Optional configuration options [3]. - Purpose: This method allows you to manually update the cached user information used by the SDK, typically after authentication or when refreshing user details [3]. Related Methods - Formio.getToken: Retrieves the current JWT token from local storage [1][2]. - formio.currentUser: Retrieves the current user's metadata and information based on the JWT token stored in local storage [1][2]. For manual authentication setup (such as SSO integrations), you can also interact directly with local storage by setting the formioToken key, though using the SDK methods is the standard programmatic approach [4].
Citations:
- 1: https://help.form.io/developers/javascript-development/javascript-sdk
- 2: https://help.form.io/dev/javascript-sdk
- 3: https://formio.github.io/core/docs/classes/sdk_formio.formio.html
- 4: https://help.form.io/dev/authentication-and-authorization
Clear legacy Form.io storage before entering memory-only mode.
With disableFormioTokenInLocalStorage enabled, setInitialToken() assigns Formio.token without clearing formioToken. A prior legacy run can therefore leave an old auth JWT in localStorage; clear it before assigning the in-memory token, and clear any Form.io user state as well so the no-persistence guarantee holds.
Proposed fix
} else {
+ this.localStorageService.clearTokenFromLocalStorage();
// Feature toggle 'disableFormioTokenInLocalStorage': keep the token in memory only, since📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (this._storeTokenInLocalStorage) { | |
| Formio.setUser(jwtDecode(token)); | |
| Formio.setToken(token); | |
| this.localStorageService.setTokenInLocalStorage(token); | |
| } else { | |
| // Feature toggle 'disableFormioTokenInLocalStorage': keep the token in memory only, since | |
| // Formio.setToken/setUser would persist it (and the decoded user) to localStorage where any | |
| // script could read it. Our APIs authenticate via the Keycloak token on the HTTP interceptor. | |
| (Formio as unknown as {token: string}).token = token; | |
| this._inMemoryTokenSet$.next(true); | |
| } | |
| if (this._storeTokenInLocalStorage) { | |
| Formio.setUser(jwtDecode(token)); | |
| Formio.setToken(token); | |
| this.localStorageService.setTokenInLocalStorage(token); | |
| } else { | |
| this.localStorageService.clearTokenFromLocalStorage(); | |
| // Feature toggle 'disableFormioTokenInLocalStorage': keep the token in memory only, since | |
| // Formio.setToken/setUser would persist it (and the decoded user) to localStorage where any | |
| // script could read it. Our APIs authenticate via the Keycloak token on the HTTP interceptor. | |
| (Formio as unknown as {token: string}).token = token; | |
| this._inMemoryTokenSet$.next(true); | |
| } |
Source: MCP tools
| beginGeldigheid?: string; | ||
| eindeGeldigheid?: string; |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== file header and relevant model snippet =="
wc -l frontend/projects/valtimo/resource/src/lib/models/open-zaak.model.ts || true
sed -n '1,80p' frontend/projects/valtimo/resource/src/lib/models/open-zaak.model.ts || true
echo
echo "== search for eindeGeldigheid usages =="
rg -n "eindeGeldigheid|beginGeldigheid" frontend || true
echo
echo "== relevant DTO/backend tests if present =="
rg -n "eindeGeldigheid|beginGeldigheid|ZaakType" . --glob '!node_modules' --glob '!dist' --glob '!build' | head -200 || trueRepository: valtimo-platform/valtimo
Length of output: 36160
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== TypeScript strict null settings and project config =="
fd -a 'tsconfig.*json' . | sed 's#^\./##' | sort
for f in frontend/tsconfig.*.json frontend/tsconfig.tsbuildinfo frontend/tsconfig.json frontend/tsconfig.base.json frontend/projects/valtimo/resource/tsconfig*.json; do
if [ -f "$f" ]; then
echo "--- $f ---"
python3 - <<'PY' "$f"
import json, sys
p=sys.argv[1]
try:
with open(p, encoding='utf-8') as fh: v=json.load(fh)
except Exception as e:
print("ERROR:", repr(e))
raise SystemExit
print(json.dumps({k:v.get(k) for k in ['compilerOptions','references','extends'] if k in v}, indent=2, ensure_ascii=False))
PY
fi
done
echo
echo "== exact backend serializer/model references for ZaakType validity fields =="
rg -n "eindeGeldigheid|beginGeldigheid|ZaakType" backend/zgw/zaken-api/src/main backend/zgw/catalogi-api/src/main -g '*.kt' | head -200 || true
echo
echo "== create-zaak config component relevant template snippets =="
sed -n '160,190p;280,330p' frontend/projects/valtimo/plugin/src/lib/plugins/zaken-api/components/create-zaak/create-zaak-configuration.component.ts || true
sed -n '40,80p' frontend/projects/valtimo/plugin/src/lib/plugins/zaken-api/components/create-zaak/create-zaak-configuration.component.html || trueRepository: valtimo-platform/valtimo
Length of output: 50380
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== Backend DTO serialization context for ZaakType validity fields =="
rg -n "class ZaaktypeDto|data class ZaaktypeDto|fun of\\(.*Zaaktype|eindeGeldigheid|beginGeldigheid" backend/zgw/catalogi-api/src/main/kotlin/com/ritense/catalogiapi -g '*.kt' | sed -n '1,220p'
echo
echo "== Frontend templates around ZaakType date formatting =="
sed -n '20,38p' frontend/projects/valtimo/zgw/src/lib/modules/zaken-api/components/zaken-api-zaaktype-link/zaken-api-zaaktype-link.component.html
sed -n '120,134p' frontend/projects/valtimo/zgw/src/lib/modules/zaken-api/components/zaken-api-zaaktype-link/zaken-api-zaaktype-link.component.htmlRepository: valtimo-platform/valtimo
Length of output: 4416
Model nullable validity dates as string | null.
ZaaktypeDto.endeGeldigheid is nullable, so the frontend API payload can contain null. Type beginGeldigheid / eindeGeldigheid as string | null | undefined to represent both omitted and JSON null; if the field is always present, use string | null instead.
Describe the changes
Link to the related Github issue:
generiekzaakafhandelcomponent/gzac-issues#137
generiekzaakafhandelcomponent/gzac-issues#495
Specify the code branch location: story/s-m-feautres
Relevant comments:
Breaking changes
Documentation
New features or changes that have been introduced have been documented.
Tests
Unit tests have been added that cover these changes
Integration tests have been added that cover these changes
Describe the testing steps
Security
The Secure by Design principle has been applied to these changes
Added or changed REST API endpoints have authentication and authorization in place
Valtimo access control checks have been implemented
Dependencies
Newly added dependencies do not introduce known vulnerabilities/CVE's and are in line with the Valtimo license