From 519c32efd70e0158743b49c1bebd1d9ad662be4e Mon Sep 17 00:00:00 2001 From: cesnimda Date: Thu, 2 Jul 2026 21:23:50 +0200 Subject: [PATCH] security: untrack DataProtection keys and runtime exports; remove dead legacy controllers - git rm --cached on committed DataProtection key XMLs (keys/, JobTrackerApi/keys/) and daily export JSON snapshots; extend .gitignore so runtime data (keys, exports, CV artifacts/exports/benchmarks) can never be committed again. - Delete root Controller/ stubs: an early prototype compiled by no project (JobTrackerApi excludes them; JobTrackerBackend globs only JobTrackerApi/Controllers). - NOTE: the removed key XMLs remain in git history; rotating DataProtection keys on the server is recommended. Co-Authored-By: Claude Fable 5 --- .gitignore | 7 ++ Controller/AttachmentsController.cs | 23 ----- Controller/CompaniesController.cs | 27 ----- Controller/CorrespondenceController.cs | 34 ------- Controller/JobApplicationsController.cs | 45 --------- .../exports/daily_export_20260325.json | 99 ------------------- .../exports/daily_export_20260326.json | 99 ------------------- ...y-9a89a42c-d2bd-4770-83fb-5930685432db.xml | 16 --- ...y-b3ca4672-1056-4ac2-ba47-0432608a4115.xml | 16 --- 9 files changed, 7 insertions(+), 359 deletions(-) delete mode 100644 Controller/AttachmentsController.cs delete mode 100644 Controller/CompaniesController.cs delete mode 100644 Controller/CorrespondenceController.cs delete mode 100644 Controller/JobApplicationsController.cs delete mode 100644 JobTrackerApi/exports/daily_export_20260325.json delete mode 100644 JobTrackerApi/exports/daily_export_20260326.json delete mode 100644 JobTrackerApi/keys/key-9a89a42c-d2bd-4770-83fb-5930685432db.xml delete mode 100644 keys/key-b3ca4672-1056-4ac2-ba47-0432608a4115.xml diff --git a/.gitignore b/.gitignore index 6d8c7e0..48d6b05 100644 --- a/.gitignore +++ b/.gitignore @@ -46,6 +46,13 @@ todo jobtracker.txt tmp/ /tmp/ +# Runtime data that must never be committed (DataProtection keys, exports, CV artifacts) +keys/ +JobTrackerApi/exports/ +JobTrackerApi/CvArtifacts/ +JobTrackerApi/CvExports/ +JobTrackerApi/CvBenchmarks/ + # Local app data *.db *.db-* diff --git a/Controller/AttachmentsController.cs b/Controller/AttachmentsController.cs deleted file mode 100644 index 30f7ecd..0000000 --- a/Controller/AttachmentsController.cs +++ /dev/null @@ -1,23 +0,0 @@ -[ApiController] -[Route("api/[controller]")] -public class AttachmentsController : ControllerBase -{ - private readonly IWebHostEnvironment _env; - public AttachmentsController(IWebHostEnvironment env) => _env = env; - - [HttpPost] - public async Task Upload([FromForm] IFormFileCollection files, [FromForm] int jobId) - { - var folder = Path.Combine(_env.ContentRootPath, "Attachments", jobId.ToString()); - Directory.CreateDirectory(folder); - - foreach (var file in files) - { - var path = Path.Combine(folder, file.FileName); - using var stream = new FileStream(path, FileMode.Create); - await file.CopyToAsync(stream); - } - - return Ok(); - } -} \ No newline at end of file diff --git a/Controller/CompaniesController.cs b/Controller/CompaniesController.cs deleted file mode 100644 index c9e6d11..0000000 --- a/Controller/CompaniesController.cs +++ /dev/null @@ -1,27 +0,0 @@ -using JobTrackerApi.Data; -using JobTrackerApi.Models; -using Microsoft.AspNetCore.Mvc; -using Microsoft.EntityFrameworkCore; - -namespace JobTrackerApi.Controllers -{ - [ApiController] - [Route("api/[controller]")] - public class CompaniesController : ControllerBase - { - private readonly JobTrackerContext _context; - public CompaniesController(JobTrackerContext context) => _context = context; - - [HttpGet] - public async Task> Get() => - await _context.Companies.Include(c => c.Jobs).ToListAsync(); - - [HttpPost] - public async Task> Post(Company company) - { - _context.Companies.Add(company); - await _context.SaveChangesAsync(); - return CreatedAtAction(nameof(Get), new { id = company.Id }, company); - } - } -} \ No newline at end of file diff --git a/Controller/CorrespondenceController.cs b/Controller/CorrespondenceController.cs deleted file mode 100644 index 79fac7f..0000000 --- a/Controller/CorrespondenceController.cs +++ /dev/null @@ -1,34 +0,0 @@ -using JobTrackerApi.Data; -using JobTrackerApi.Models; -using Microsoft.AspNetCore.Mvc; -using Microsoft.EntityFrameworkCore; - -namespace JobTrackerApi.Controllers -{ - [ApiController] - [Route("api/[controller]")] - public class CorrespondenceController : ControllerBase - { - private readonly JobTrackerContext _context; - public CorrespondenceController(JobTrackerContext context) => _context = context; - - // GET all messages for a job - [HttpGet("{jobId}")] - public async Task> GetForJob(int jobId) - { - return await _context.Correspondences - .Where(c => c.JobApplicationId == jobId) - .OrderBy(c => c.Date) - .ToListAsync(); - } - - // POST new message - [HttpPost] - public async Task> Post(Correspondence message) - { - _context.Correspondences.Add(message); - await _context.SaveChangesAsync(); - return CreatedAtAction(nameof(GetForJob), new { jobId = message.JobApplicationId }, message); - } - } -} \ No newline at end of file diff --git a/Controller/JobApplicationsController.cs b/Controller/JobApplicationsController.cs deleted file mode 100644 index 4e3b9b8..0000000 --- a/Controller/JobApplicationsController.cs +++ /dev/null @@ -1,45 +0,0 @@ -using JobTrackerApi.Data; -using JobTrackerApi.Models; -using Microsoft.AspNetCore.Mvc; -using Microsoft.EntityFrameworkCore; - -namespace JobTrackerApi.Controllers -{ - [ApiController] - [Route("api/[controller]")] - public class JobApplicationsController : ControllerBase - { - private readonly JobTrackerContext _context; - public JobApplicationsController(JobTrackerContext context) => _context = context; - - [HttpGet] - public async Task> Get() => - await _context.JobApplications.Include(j => j.Company).ToListAsync(); - - [HttpPost] - public async Task> Post(JobApplication job) - { - _context.JobApplications.Add(job); - await _context.SaveChangesAsync(); - return CreatedAtAction(nameof(Get), new { id = job.Id }, job); - } - - [HttpPut("{id}")] - public async Task Put(int id, JobApplication updatedJob) - { - var job = await _context.JobApplications.FindAsync(id); - if (job == null) return NotFound(); - - job.JobTitle = updatedJob.JobTitle; - job.Status = updatedJob.Status; - job.ResponseReceived = updatedJob.ResponseReceived; - job.ResponseDate = updatedJob.ResponseDate; - job.Notes = updatedJob.Notes; - job.CoverLetterText = updatedJob.CoverLetterText; - job.JobUrl = updatedJob.JobUrl; - await _context.SaveChangesAsync(); - - return NoContent(); - } - } -} \ No newline at end of file diff --git a/JobTrackerApi/exports/daily_export_20260325.json b/JobTrackerApi/exports/daily_export_20260325.json deleted file mode 100644 index 807f757..0000000 --- a/JobTrackerApi/exports/daily_export_20260325.json +++ /dev/null @@ -1,99 +0,0 @@ -{ - "Version": "dailyexport.v1", - "CreatedAt": "2026-03-25T02:00:00.0368687+01:00", - "Companies": [ - { - "Id": 1, - "OwnerUserId": "23dc196b-f227-4499-93fe-403d8801e21c", - "Name": "Acme Browser QA", - "Location": null, - "Source": null, - "RecruiterName": "Maria Recruiter", - "RecruiterEmail": "maria@acme.test", - "RecruiterLinkedIn": null, - "LastContactedAt": "2026-03-24T11:15:21.4772436", - "NextContactAt": "2026-03-24T00:00:00", - "PipelineStage": null - } - ], - "JobApplications": [ - { - "Id": 1, - "OwnerUserId": "23dc196b-f227-4499-93fe-403d8801e21c", - "JobTitle": "Backend Developer", - "CompanyId": 1, - "Company": null, - "Status": "Waiting", - "DateApplied": "2026-03-01T13:00:00+01:00", - "Location": null, - "Salary": null, - "NextAction": null, - "FollowUpAt": "2026-03-24T00:00:00", - "FeedbackRequestedAt": null, - "RecruiterMessageDraft": "Saved browser recruiter message", - "HasResume": true, - "HasCoverLetter": true, - "HasPortfolio": false, - "HasOtherAttachment": false, - "IsDeleted": false, - "DeletedAt": null, - "ResponseReceived": true, - "ResponseDate": null, - "Notes": "Browser-seeded notes\n\n\u003C\u003C\u003CAPPLICATION_ANSWER_DRAFT\u003E\u003E\u003E\nSaved browser application answer\n\u003C\u003C\u003CEND_APPLICATION_ANSWER_DRAFT\u003E\u003E\u003E", - "CoverLetterText": "Saved browser cover letter", - "JobUrl": "https://example.test/backend-developer", - "Description": "Need .NET APIs and strong stakeholder communication.", - "TranslatedDescription": null, - "DescriptionLanguage": null, - "Tags": "[\u0022.NET\u0022, \u0022APIs\u0022, \u0022Communication\u0022]", - "Deadline": null, - "ShortSummary": "Strong overlap in backend API delivery.", - "TailoredCvText": "Saved browser tailored CV", - "TailoredCvUpdatedAt": "2026-03-24T10:58:13.226164+01:00", - "LastReminderEmailSentAt": null, - "Messages": [], - "Attachments": [], - "Events": [], - "DaysSince": 23 - } - ], - "Correspondence": [ - { - "Id": 1, - "JobApplicationId": 1, - "From": "Company", - "Subject": "Backend Developer application update", - "Channel": "Email", - "ExternalMessageId": "browser-msg-1", - "ExternalThreadId": "browser-thread-1", - "ExternalFrom": "Maria Recruiter \u003Cmaria@acme.test\u003E", - "ExternalTo": "admin@example.com", - "Content": "We are aligning interview slots and need someone who can own the API layer.", - "Date": "2026-03-10T10:00:00+01:00" - }, - { - "Id": 2, - "JobApplicationId": 1, - "From": "Me", - "Subject": "Re: Backend Developer application update", - "Channel": "Email", - "ExternalMessageId": null, - "ExternalThreadId": null, - "ExternalFrom": null, - "ExternalTo": null, - "Content": "Hi Maria,\n\nEdited browser follow-up.\n\nThanks,\nadmin@example.com", - "Date": "2026-03-24T11:15:21.4521755" - } - ], - "Attachments": [], - "Events": [], - "Rules": { - "Id": 1, - "AppliedFollowUpDays": 14, - "AppliedGhostDays": 30, - "OfferFollowUpDays": 7, - "OfferGhostDays": 14, - "FeedbackFollowUpDays": 7, - "FeedbackGhostDays": 14 - } -} \ No newline at end of file diff --git a/JobTrackerApi/exports/daily_export_20260326.json b/JobTrackerApi/exports/daily_export_20260326.json deleted file mode 100644 index 7e9d2ab..0000000 --- a/JobTrackerApi/exports/daily_export_20260326.json +++ /dev/null @@ -1,99 +0,0 @@ -{ - "Version": "dailyexport.v1", - "CreatedAt": "2026-03-26T02:00:00.005823+01:00", - "Companies": [ - { - "Id": 1, - "OwnerUserId": "23dc196b-f227-4499-93fe-403d8801e21c", - "Name": "Acme Browser QA", - "Location": null, - "Source": null, - "RecruiterName": "Maria Recruiter", - "RecruiterEmail": "maria@acme.test", - "RecruiterLinkedIn": null, - "LastContactedAt": "2026-03-24T11:15:21.4772436", - "NextContactAt": "2026-03-24T00:00:00", - "PipelineStage": null - } - ], - "JobApplications": [ - { - "Id": 1, - "OwnerUserId": "23dc196b-f227-4499-93fe-403d8801e21c", - "JobTitle": "Backend Developer", - "CompanyId": 1, - "Company": null, - "Status": "Waiting", - "DateApplied": "2026-03-01T13:00:00+01:00", - "Location": null, - "Salary": null, - "NextAction": null, - "FollowUpAt": "2026-03-24T00:00:00", - "FeedbackRequestedAt": null, - "RecruiterMessageDraft": "Saved browser recruiter message", - "HasResume": true, - "HasCoverLetter": true, - "HasPortfolio": false, - "HasOtherAttachment": false, - "IsDeleted": false, - "DeletedAt": null, - "ResponseReceived": true, - "ResponseDate": null, - "Notes": "Browser-seeded notes\n\n\u003C\u003C\u003CAPPLICATION_ANSWER_DRAFT\u003E\u003E\u003E\nSaved browser application answer\n\u003C\u003C\u003CEND_APPLICATION_ANSWER_DRAFT\u003E\u003E\u003E", - "CoverLetterText": "Saved browser cover letter", - "JobUrl": "https://example.test/backend-developer", - "Description": "Need .NET APIs and strong stakeholder communication.", - "TranslatedDescription": null, - "DescriptionLanguage": null, - "Tags": "[\u0022.NET\u0022, \u0022APIs\u0022, \u0022Communication\u0022]", - "Deadline": null, - "ShortSummary": "Strong overlap in backend API delivery.", - "TailoredCvText": "Saved browser tailored CV", - "TailoredCvUpdatedAt": "2026-03-24T10:58:13.226164+01:00", - "LastReminderEmailSentAt": null, - "Messages": [], - "Attachments": [], - "Events": [], - "DaysSince": 24 - } - ], - "Correspondence": [ - { - "Id": 1, - "JobApplicationId": 1, - "From": "Company", - "Subject": "Backend Developer application update", - "Channel": "Email", - "ExternalMessageId": "browser-msg-1", - "ExternalThreadId": "browser-thread-1", - "ExternalFrom": "Maria Recruiter \u003Cmaria@acme.test\u003E", - "ExternalTo": "admin@example.com", - "Content": "We are aligning interview slots and need someone who can own the API layer.", - "Date": "2026-03-10T10:00:00+01:00" - }, - { - "Id": 2, - "JobApplicationId": 1, - "From": "Me", - "Subject": "Re: Backend Developer application update", - "Channel": "Email", - "ExternalMessageId": null, - "ExternalThreadId": null, - "ExternalFrom": null, - "ExternalTo": null, - "Content": "Hi Maria,\n\nEdited browser follow-up.\n\nThanks,\nadmin@example.com", - "Date": "2026-03-24T11:15:21.4521755" - } - ], - "Attachments": [], - "Events": [], - "Rules": { - "Id": 1, - "AppliedFollowUpDays": 14, - "AppliedGhostDays": 30, - "OfferFollowUpDays": 7, - "OfferGhostDays": 14, - "FeedbackFollowUpDays": 7, - "FeedbackGhostDays": 14 - } -} \ No newline at end of file diff --git a/JobTrackerApi/keys/key-9a89a42c-d2bd-4770-83fb-5930685432db.xml b/JobTrackerApi/keys/key-9a89a42c-d2bd-4770-83fb-5930685432db.xml deleted file mode 100644 index ad6c211..0000000 --- a/JobTrackerApi/keys/key-9a89a42c-d2bd-4770-83fb-5930685432db.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - 2026-03-24T09:54:28.8487759Z - 2026-03-24T09:54:28.8487759Z - 2026-06-22T09:54:28.8487759Z - - - - - - - LXbXqbpiEXn0OM6fr/TuXDBcZd83DvOInTI09PGZRr1Z20LQCD/PUKF1oo9UwC4O1VgK3wA//yxH9PPCIPzEaw== - - - - \ No newline at end of file diff --git a/keys/key-b3ca4672-1056-4ac2-ba47-0432608a4115.xml b/keys/key-b3ca4672-1056-4ac2-ba47-0432608a4115.xml deleted file mode 100644 index 4c53c94..0000000 --- a/keys/key-b3ca4672-1056-4ac2-ba47-0432608a4115.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - 2026-03-27T07:52:25.0540436Z - 2026-03-27T07:52:25.0540436Z - 2026-06-25T07:52:25.0540436Z - - - - - - - mfglwuKFrMSiWcbTVDEbPYM0eGAqlsOMHe89hNOsZUguUMMiusdx3m3ZQJvxnBCxeXte6OS+zvpZl3tIizvgHg== - - - - \ No newline at end of file