schalli
819d50a222
feat(cert-manager): cert role badges + ZIP download in split view
...
- API: detectCertRole() classifies certs as root/intermediate/end-entity
via basicConstraints.cA + self-signed check (subject.hash === issuer.hash)
- API: SplitEntry gains certRole field; filenames now reflect role
(root-ca.pem, intermediate-1.pem, cert.pem)
- Web: SplitTab shows colour-coded role badge per cert
(red=Root-CA, amber=Zwischen-CA, blue=Zertifikat)
- Web: "Alle als ZIP herunterladen" button via fflate (client-side)
- i18n: add certRole labels + downloadZip action key (de + en)
- i18n: add missing accentColor* and deleteAvatar* keys (de + en)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-07-02 10:40:39 +02:00
schalli
7da1c19b31
fix(db): add migration for User.accentColor column
...
Tessera CI/CD / Lint & Type Check (push) Successful in 45s
Tessera CI/CD / Tests (push) Successful in 44s
Tessera CI/CD / Build & Publish Images (push) Successful in 24s
Column was added to schema but migration was missing, causing
PrismaClientKnownRequestError P2022 on prod API startup.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-07-02 10:25:43 +02:00
schalli
384b2409a2
fix(tests): add noCompactor mock + fix note-widget event simulation
...
Tessera CI/CD / Lint & Type Check (push) Successful in 42s
Tessera CI/CD / Tests (push) Successful in 46s
Tessera CI/CD / Build & Publish Images (push) Successful in 4m3s
- dashboard-grid.test: add noCompactor to react-grid-layout mock
- note-widget.test: enable edit mode before typing (onChange is undefined
when isEditing=false), replace native dispatchEvent with fireEvent.change
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-07-02 10:15:17 +02:00
schalli
745bd66266
fix(web): exclude test files from tsconfig to fix type-check
...
Tessera CI/CD / Lint & Type Check (push) Successful in 44s
Tessera CI/CD / Tests (push) Failing after 41s
Tessera CI/CD / Build & Publish Images (push) Has been skipped
Test matcher types (toBeInTheDocument etc.) from @testing-library/jest-dom
were not globally visible to tsc because module augmentations from setup.ts
don't propagate across unconnected files in the same compilation. Excluding
test files from the main tsconfig is the standard Next.js + Vitest pattern.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-07-02 09:59:35 +02:00
schalli
85bd9dfb1e
fix(module-loader): register cert-manager in MODULE_REGISTRY
...
Tessera CI/CD / Lint & Type Check (push) Failing after 46s
Tessera CI/CD / Tests (push) Has been skipped
Tessera CI/CD / Build & Publish Images (push) Has been skipped
cert-manager was seeded and activated in the DB but missing from the
frontend whitelist, causing the dynamic route to always show "module
not found".
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-07-02 09:10:56 +02:00
schalli
73e107414b
chore: gitignore playwright-mcp and research cache dirs
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-07-02 08:58:05 +02:00
schalli
610b649bdf
chore: remove handoff and continue-here files (phase 9 complete)
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-07-02 08:57:52 +02:00
schalli
2869da83c0
chore: planning artifacts + mcp.json update
...
- .mcp.json: Playwright MCP config
- 08-UAT.md: Phase 8 UAT results
- quick task summaries: 260630 user-settings, 260701 calendar domain
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-07-02 08:57:44 +02:00
schalli
c8f3361816
fix(dashboard): noCompactor + note edit/preview toggle + widget border
...
Tessera CI/CD / Tests (push) Has been cancelled
Tessera CI/CD / Build & Publish Images (push) Has been cancelled
Tessera CI/CD / Lint & Type Check (push) Has been cancelled
- dashboard-grid: add noCompactor to prevent auto-compaction on drag
- note-widget: edit/preview toggle button (pencil icon), isEditing state,
hideToolbar in preview mode
- widget-wrapper: border-primary/20 accent border
- dashboard-store: console.error on widget add/remove/layout-save failures
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-07-02 08:57:37 +02:00
schalli
be3680d0df
feat(user-settings): avatar delete + accent color
...
- DELETE /users/me/avatar endpoint with file cleanup
- PATCH /users/me/accent-color with hex validation (#rrggbb)
- auth.service.ts: include accentColor in user select
- AccountSettingsForm: delete-avatar button + accent color picker/save/reset
- auth-actions.ts: deleteAvatarAction + updateAccentColorAction
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-07-02 08:57:31 +02:00
schalli
cc95395889
docs(state): mark phase 9 complete — milestone v1.0 done
...
All 9 phases complete, 40/40 plans executed, UAT 8/8 passed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-07-02 08:46:32 +02:00
schalli
2ddd8473dc
test(09): complete UAT — 8/8 passed (automated Playwright)
...
All cert-manager features verified:
- Module navigation & 4-tab structure
- Inspect PEM (full grid: CN, SANs, expiry, fingerprints)
- Wrong PFX password → user-friendly error
- Split fullchain.pem → per-cert downloads
- Convert PEM→DER (openssl-verified)
- Convert PEM→PFX + password field (openssl-verified)
- Merge 2 PEMs → chain.pem (2 cert blocks)
- Merge 2 certs → bundle.pfx + password (openssl-verified)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-07-02 08:46:07 +02:00
schalli
c673faa40d
wip: phase-09 paused after UAT blocker (docker rebuild needed)
2026-07-02 08:23:17 +02:00
schalli
daff82ea76
docs(09-06): complete merge-pfx plan — final plan of phase 09
Tessera CI/CD / Tests (push) Has been cancelled
Tessera CI/CD / Build & Publish Images (push) Has been cancelled
Tessera CI/CD / Lint & Type Check (push) Has been cancelled
2026-07-02 07:55:54 +02:00
schalli
8b15a0099f
feat(09-06): MergeTab multi-file UI + PFX convert option + render tests
...
- actions.ts: mergeCertsAction(files, outputFormat, password?) builds FormData with
multiple file fields; delegates to postForm('merge', ...) (T-09-02/T-09-04)
- MergeTab.tsx: multi-file state (local), file input (multiple), output selector
(pem|pfx), Zusammenfuehren button disabled when < 2 files (data-testid for tests),
onOutputFormatChange callback to page.tsx for shared PasswordField visibility
- ConvertTab.tsx: gains pfx option + onTargetFormatChange callback (same pattern)
- page.tsx: lifts mergeOutputFormat + convertOutputFormat state; showPassword now
also true when active tab's output format is 'pfx'; passes callbacks to tabs
- cert-manager.test.tsx: 5 new tests — MergeTab disabled/enabled by file count,
shared PasswordField appears on pfx output, downloadBase64 called on success;
ConvertTab pfx option present; all 19/19 web tests green
- All production cert-manager files type-clean (pre-existing test type issues unchanged)
2026-07-02 07:52:52 +02:00
schalli
6326064ad3
feat(09-06): GREEN — implement mergeCerts + PFX-create + convertCert pfx output
...
- CertManagerService.mergeCerts: parse all files via detectFormat/parsePemChain/toForgeBuffer,
concatenate PEM chain or build PKCS12 via toPkcs12Asn1
- Open Question 1 resolved: toPkcs12Asn1(null, certs, password) works in node-forge 1.4.0
(null private key accepted — cert-only PFX without fallback needed)
- PFX output requires non-empty password → BadRequestException if missing (T-09-02)
- All forge calls in try/catch → BadRequestException; password never logged (T-09-02)
- bytesToHex→Buffer.from(hex,'hex')→base64 for binary safety (Pitfall 1 avoidance)
- convertCert gains pfx output target (reuses same null-key toPkcs12Asn1 pattern)
- FORMAT_MIME extended with pfx: 'application/x-pkcs12'
- NotImplementedException import removed (no longer used)
- 27/27 API cert-manager tests green; tsc --noEmit exits 0
2026-07-02 07:49:42 +02:00
schalli
f43e92c49f
test(09-06): RED — failing mergeCerts spec (PEM chain + password-PFX round-trip)
...
- 4 new mergeCerts tests: PEM chain 2 blocks, PFX round-trip with password,
missing PFX password → BadRequestException, garbage input → BadRequestException
- Controller enforces 2-file minimum; service tests use 1-2 files directly
- All 4 fail against NotImplementedException stub (RED confirmed)
- Prior 23 tests remain green
2026-07-02 07:47:28 +02:00
schalli
db7a85cc4c
docs(09-05): complete convert-vertical-slice plan
2026-07-02 07:41:34 +02:00
schalli
f89d6566b2
feat(09-05): implement ConvertTab + convertCertAction + render tests
...
Tessera CI/CD / Tests (push) Has been cancelled
Tessera CI/CD / Build & Publish Images (push) Has been cancelled
Tessera CI/CD / Lint & Type Check (push) Has been cancelled
- Add FileResponse interface to actions.ts
- Add convertCertAction(input, targetFormat): builds FormData with
file/pemText/password + targetFormat, calls postForm convert endpoint
- Implement ConvertTab: native select for pem/der/p7b targetFormat,
Konvertieren button with loading swap, error classification, empty state
- On success: calls downloadBase64(filename, content, mimeType)
- 3 new ConvertTab tests: format selector options, downloadBase64 invoked
on success, text-destructive error on format rejection
- All 14 web cert-manager tests green
2026-07-02 07:39:41 +02:00
schalli
59694642dd
feat(09-05): implement convertCert + wire POST /convert (GREEN)
...
- Add FileResponse interface and FORMAT_MIME map to service
- Implement convertCert: parses any input format (PEM/DER/PFX/P7B) via
same logic as parseCert; serializes to pem/der/p7b targetFormat
- DER output uses bytesToHex→Buffer.from(hex,'hex') to avoid utf-8
corruption (Pitfall 1 / T-09-06)
- P7B output: pkcs7.createSignedData + pem.encode (PEM-wrapped PKCS7)
- Wrap all forge ops in try/catch → BadRequestException (T-09-01)
- Controller: add @Body('pemText') + reject when neither file nor pemText
- Fix: re-add NotImplementedException import for mergeCerts stub
- All 23 API cert-manager tests green (including 4 new convertCert)
2026-07-02 07:37:41 +02:00
schalli
37db58b816
test(09-05): add failing convertCert spec (RED)
...
- PEM→DER round-trip identity test (re-parses DER base64 → verify CN)
- DER→PEM round-trip identity test (re-parses PEM base64 → verify CN)
- PEM→P7B: asserts mimeType + P7B contains ≥1 cert
- malformed input: expects BadRequestException
- All 4 fail against NotImplementedException stub (RED confirmed)
2026-07-02 07:35:51 +02:00
schalli
a1da5d9083
docs(09-04): complete split-slice plan
2026-07-02 07:17:46 +02:00
schalli
33b1bc3172
feat(09-04): SplitTab UI + splitCertsAction + render tests
...
- actions.ts: export SplitEntry + SplitResponse interfaces; add splitCertsAction(file) → POST /split
- SplitTab.tsx: Aufteilen button (disabled without file); per-cert download list (bg-secondary rows)
each row: subject.cn, validity.notAfter, Herunterladen button → downloadBase64
empty state / error state (text-destructive) matching InspectTab pattern
- cert-manager.test.tsx: 2 new SplitTab tests (success: 2 download buttons; error: text-destructive)
- All 11 cert-manager web tests green; production files type-clean
2026-07-02 07:16:18 +02:00
schalli
2c4ada347c
feat(09-04): GREEN — implement splitCerts + SplitResponse interface
...
Tessera CI/CD / Tests (push) Has been cancelled
Tessera CI/CD / Build & Publish Images (push) Has been cancelled
Tessera CI/CD / Lint & Type Check (push) Has been cancelled
- Export SplitEntry + SplitResponse interfaces
- splitCerts: PEM chain path via parsePemChain; P7B path via messageFromPem (PEM) or messageFromAsn1 (DER)
- Each cert entry: index, filename cert-N.pem, content base64 PEM, subject.cn, validity.notAfter
- BadRequestException on malformed input / unsupported format (T-09-01)
- POST /split already wired in controller with 5MB file limit (T-09-03, T-09-04)
- All 19 API tests green; type-check clean
2026-07-02 07:14:22 +02:00
schalli
eec66311a7
test(09-04): RED — failing splitCerts spec (fullchain PEM, P7B bundle, malformed)
...
- splitCerts fullchain PEM: expects count 2, two single-PEM-block certs with correct CN
- splitCerts P7B PEM bundle: expects at least one cert in result
- splitCerts malformed input: expects BadRequestException
- All three tests FAIL against NotImplementedException stub (RED confirmed)
- All 16 prior tests still pass
2026-07-02 07:12:37 +02:00
schalli
da676705d9
docs(09-03): complete inspect-slice plan
2026-07-01 23:57:54 +02:00
schalli
64a8e725e7
feat(09-03): InspectTab UI + inspectCertAction + render tests
...
- Added inspectCertAction to actions.ts (JSON path for pemText, multipart path for file)
- Added CertDetails interface to actions.ts (mirrors API response shape)
- Implemented InspectTab: Analysieren button, loading state, grid-cols-2 result grid
- InspectTab handles wrong-password error (t('error.wrongPassword')) and generic error
- Added 2 new InspectTab tests: success grid (subject CN + SHA-256) and error (text-destructive)
- Fixed setup.ts: explicit expect.extend(matchers) for vitest@4.x compatibility
(Rule 1: @testing-library/jest-dom/vitest not extending global expect in vitest 4)
- Fixed existing test: getByText -> getAllByText for 'Analysieren' (now appears in tab nav + button)
- 9/9 cert-manager tests pass
2026-07-01 23:55:41 +02:00
schalli
ba994635e8
feat(09-03): GREEN — implement parseCert + export CertDetails interface
...
- Implemented CertManagerService.parseCert for PEM/DER/PFX/P7B inputs
- Exported CertDetails interface (subject, issuer, validity, san, keyType, keyBits, serialNumber, signatureAlgorithm, fingerprint, pemPreview)
- PFX with wrong password → BadRequestException (T-09-02: never logged, never echoed)
- All forge operations wrapped in try/catch → BadRequestException (T-09-01)
- buildReverseOids() converts OID → human-readable algorithm name
- P7B handles both PEM-wrapped and binary DER (RESEARCH Pitfall 4)
- Controller already wired correctly from Plan 01 (fileSize 5MB, pemText, file, password)
- All 16 cert-manager tests pass (16/16)
2026-07-01 23:41:03 +02:00
schalli
7c2e506a2e
test(09-03): RED — failing parseCert spec (PEM/DER/PFX/wrong-password/malformed)
...
Tessera CI/CD / Tests (push) Has been cancelled
Tessera CI/CD / Build & Publish Images (push) Has been cancelled
Tessera CI/CD / Lint & Type Check (push) Has been cancelled
- Added parseCert describe block with 5 failing tests
- Covers PEM input, DER input, PFX+correct-password, PFX+wrong-password (BadRequestException), malformed input (BadRequestException)
- Existing 11 helper tests still pass
- Fixtures built via node-forge (RSA-1024, DER from asn1.toDer, PFX via toPkcs12Asn1)
2026-07-01 23:39:39 +02:00
schalli
b1aa1d0d2d
wip: phase 09 paused after wave 1 (2/6 plans done)
2026-07-01 23:27:53 +02:00
schalli
76d1a31583
docs(phase-09): update tracking after wave 1
2026-07-01 23:26:56 +02:00
schalli
a9cce06ca3
fix(09-02): repair i18n JSON after wave-1 merge conflict resolution
2026-07-01 23:26:55 +02:00
schalli
4fc448b1d4
merge(09-02): cert-manager web shell + i18n (resolve de/en.json conflict)
2026-07-01 23:26:12 +02:00
schalli
637f4674ca
merge(09-01): resolve app.module.ts conflict (CertManagerModule + FavoritesModule)
Tessera CI/CD / Lint & Type Check (push) Failing after 37s
Tessera CI/CD / Tests (push) Has been skipped
Tessera CI/CD / Build & Publish Images (push) Has been skipped
2026-07-01 23:25:48 +02:00
schalli
7ad4f22a75
docs(09-02): complete cert-manager frontend shell plan
2026-07-01 23:24:25 +02:00
schalli
2cb01f743d
test(09-02): add shell render tests for CertManagerPage (GREEN)
...
- 7 tests passing: title, all 4 tab labels, hidden password field, per-tab empty states
- Tests use vi.mock('next-intl') pattern per project convention (matches sidebar, VehicleTable tests)
- Validates T-09-02 threat mitigation: password field absent on initial render
2026-07-01 23:23:17 +02:00
schalli
3506d60dbe
docs(09-01): complete cert-manager API foundation plan summary
...
- SUMMARY.md with task results, deviations, stub tracking, threat scan
- Self-check: all 9 files found, 3 commits verified, 11 tests green
2026-07-01 23:22:51 +02:00
schalli
8bb5cf208d
feat(09-01): scaffold cert-manager module + shared node-forge helpers (GREEN)
...
- cert-manager.module.ts: OnModuleInit + seedCertManagerModule (CERT-06)
- cert-manager.seed.ts: slug='cert-manager', category='security-tools', isSystem=true
- cert-manager.service.ts: detectFormat, toForgeBuffer, getFingerprint, parsePemChain;
operation stubs parseCert/splitCerts/mergeCerts/convertCert throw NotImplementedException
- cert-manager.controller.ts: 4 POST routes with FileInterceptor/FilesInterceptor
(5 MB limit each), @UseModule('cert-manager') guard, BadRequestException on missing input
- dto/: ParseCertDto, MergeCertsDto, ConvertCertDto
- app.module.ts: CertManagerModule added to imports array
- All 11 Vitest tests pass; type-check clean
2026-07-01 23:21:36 +02:00
schalli
42a41f77d0
feat(09-02): build cert-manager page shell, components, and client helpers
...
- CertManagerPage: 'use client', useTranslations('certManager'), max-w-4xl layout
- Shared input card with DropZone, OR divider, PEM textarea, conditional PasswordField
- PasswordField renders null when show=false (T-09-02 threat mitigation)
- Tab nav: Analysieren / Aufteilen / Zusammenfuehren / Konvertieren
- Tab stubs: InspectTab, SplitTab, MergeTab, ConvertTab (empty state only)
- actions.ts: API_URL const, downloadBase64(atob->Blob->URL), postForm(credentials:'include')
- File/paste mutual exclusion: selecting one clears the other
- No shadcn/Radix; Tailwind utilities only; inline SVG eye icon
2026-07-01 23:20:10 +02:00
schalli
a06694f915
test(09-01): add failing spec for cert-manager seed + helpers (RED)
...
- Test: seedCertManagerModule calls seedModule with slug='cert-manager',
category='security-tools', isSystem=true
- Test: detectFormat returns pem/der/pfx/p7b based on extension + content sniff
- Test: getFingerprint returns uppercase colon-separated hex (sha1 + sha256)
- Test: parsePemChain returns array of length 2 for two concatenated PEMs
2026-07-01 23:18:08 +02:00
schalli
82a80e7634
feat(09-02): add certManager i18n namespace (de + en)
...
- Added certManager namespace to de.json with full key set (tabs, dropZone, paste, password, or, actions, emptyState, error)
- Added certManager namespace to en.json with matching key structure
- German copy matches UI-SPEC Copywriting Contract exactly
- Both files share identical key paths under certManager
2026-07-01 23:17:58 +02:00
schalli
a13a8a763f
chore(09-01): install node-forge + Vitest runner for @tessera/api
...
- Add node-forge@^1.4.0 runtime dependency (certificate crypto)
- Add @types/node-forge@^1.3.14 and vitest@^3 dev dependencies
- Create apps/api/vitest.config.ts (environment: node, passWithNoTests)
- Add test + test:watch scripts to apps/api/package.json
2026-07-01 23:17:23 +02:00
schalli
812eb06d9b
docs(09): create phase plan + resolve open questions
2026-07-01 16:28:31 +02:00
schalli
063666af3b
docs(09): create cert-manager phase plan (6 plans)
Tessera CI/CD / Lint & Type Check (push) Failing after 41s
Tessera CI/CD / Tests (push) Has been skipped
Tessera CI/CD / Build & Publish Images (push) Has been skipped
2026-07-01 16:24:31 +02:00
schalli
ad7de8de2d
docs(09): research phase 9 cert-manager module
Tessera CI/CD / Lint & Type Check (push) Failing after 43s
Tessera CI/CD / Tests (push) Has been skipped
Tessera CI/CD / Build & Publish Images (push) Has been skipped
2026-07-01 16:05:42 +02:00
schalli
6ee31a22fb
docs(09): UI design contract
2026-07-01 15:49:15 +02:00
schalli
09d5231148
docs(09): UI design contract
2026-07-01 15:47:00 +02:00
schalli
5b75b3284a
wip: phase 9 cert-manager paused at planning (UI-SPEC needed)
2026-07-01 15:43:47 +02:00
schalli
a32f5f948b
docs(09): add Phase 9 Cert Manager to roadmap + capture context
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-07-01 15:39:24 +02:00
schalli
e35276243a
fix(calendar): EWS uses NTLM auth + edit form stays open after save
...
- Replace ews-javascript-api (Basic Auth only) with httpntlm for EWS connections
- testEwsConnection uses GetFolder SOAP via NTLM
- fetchViaEws uses FindItem CalendarView SOAP via NTLM
- Edit form no longer auto-closes on save — shows "Erfolgreich gespeichert" instead
- Test button in edit mode uses saved credentials via /sources/:id/test endpoint
- Add saveSuccess i18n key (de/en)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-07-01 14:05:07 +02:00