fix: audit cleanup — ReDoS guard, Telegram validation, README accuracy
- form_filler.mjs: reject regex patterns over 200 chars to mitigate ReDoS - notify.mjs: check res.ok before parsing Telegram API response - README: update project structure with new lib/apply/ modules, session.mjs, keywords.mjs; fix max_applications_per_run docs (no limit by default); clarify ATS stub status in roadmap Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
22
README.md
22
README.md
@@ -137,7 +137,7 @@ Patterns support regex:
|
|||||||
|
|
||||||
| Key | Default | Description |
|
| Key | Default | Description |
|
||||||
|-----|---------|-------------|
|
|-----|---------|-------------|
|
||||||
| `max_applications_per_run` | `50` | Cap applications per run to avoid rate limits |
|
| `max_applications_per_run` | no limit | Cap applications per run (optional, set to avoid rate limits) |
|
||||||
| `max_retries` | `2` | Times to retry a failed application before marking it permanently failed |
|
| `max_retries` | `2` | Times to retry a failed application before marking it permanently failed |
|
||||||
| `browser.provider` | `"kernel"` | `"kernel"` for stealth browsers, `"local"` for local Playwright |
|
| `browser.provider` | `"kernel"` | `"kernel"` for stealth browsers, `"local"` for local Playwright |
|
||||||
|
|
||||||
@@ -158,14 +158,26 @@ claw-apply/
|
|||||||
├── job_searcher.mjs Search agent
|
├── job_searcher.mjs Search agent
|
||||||
├── job_applier.mjs Apply agent
|
├── job_applier.mjs Apply agent
|
||||||
├── setup.mjs Setup wizard
|
├── setup.mjs Setup wizard
|
||||||
|
├── status.mjs Queue status report
|
||||||
├── lib/
|
├── lib/
|
||||||
│ ├── constants.mjs Shared constants and defaults
|
│ ├── constants.mjs Shared constants and defaults
|
||||||
│ ├── browser.mjs Kernel/Playwright browser factory
|
│ ├── browser.mjs Kernel/Playwright browser factory
|
||||||
|
│ ├── session.mjs Kernel Managed Auth session refresh
|
||||||
│ ├── form_filler.mjs Generic form filling with pattern matching
|
│ ├── form_filler.mjs Generic form filling with pattern matching
|
||||||
│ ├── linkedin.mjs LinkedIn search + Easy Apply
|
│ ├── keywords.mjs AI-generated search keywords via Claude
|
||||||
│ ├── wellfound.mjs Wellfound search + apply
|
│ ├── linkedin.mjs LinkedIn search + job classification
|
||||||
|
│ ├── wellfound.mjs Wellfound search
|
||||||
│ ├── queue.mjs Job queue and config management
|
│ ├── queue.mjs Job queue and config management
|
||||||
│ └── notify.mjs Telegram notifications with rate limiting
|
│ ├── notify.mjs Telegram notifications with rate limiting
|
||||||
|
│ └── apply/
|
||||||
|
│ ├── index.mjs Apply handler registry
|
||||||
|
│ ├── easy_apply.mjs LinkedIn Easy Apply
|
||||||
|
│ ├── wellfound.mjs Wellfound apply
|
||||||
|
│ ├── greenhouse.mjs Greenhouse ATS (stub)
|
||||||
|
│ ├── lever.mjs Lever ATS (stub)
|
||||||
|
│ ├── workday.mjs Workday ATS (stub)
|
||||||
|
│ ├── ashby.mjs Ashby ATS (stub)
|
||||||
|
│ └── jobvite.mjs Jobvite ATS (stub)
|
||||||
├── config/
|
├── config/
|
||||||
│ ├── *.example.json Templates (committed)
|
│ ├── *.example.json Templates (committed)
|
||||||
│ ├── profile.json Your info (gitignored)
|
│ ├── profile.json Your info (gitignored)
|
||||||
@@ -200,7 +212,7 @@ claw-apply/
|
|||||||
- [x] Preview mode (`--preview`)
|
- [x] Preview mode (`--preview`)
|
||||||
- [x] Configurable application caps and retry limits
|
- [x] Configurable application caps and retry limits
|
||||||
- [ ] Indeed support
|
- [ ] Indeed support
|
||||||
- [ ] External ATS support (Greenhouse, Lever)
|
- [ ] External ATS support (Greenhouse, Lever, Workday, Ashby, Jobvite — stubs ready)
|
||||||
- [ ] Job scoring and ranking
|
- [ ] Job scoring and ranking
|
||||||
- [ ] Per-job cover letter generation via LLM
|
- [ ] Per-job cover letter generation via LLM
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ export class FormFiller {
|
|||||||
// Check custom answers first (user-defined, pattern is substring or regex)
|
// Check custom answers first (user-defined, pattern is substring or regex)
|
||||||
for (const entry of this.answers) {
|
for (const entry of this.answers) {
|
||||||
try {
|
try {
|
||||||
|
if (entry.pattern.length > 200) throw new Error('pattern too long');
|
||||||
const re = new RegExp(entry.pattern, 'i');
|
const re = new RegExp(entry.pattern, 'i');
|
||||||
if (re.test(l)) return String(entry.answer);
|
if (re.test(l)) return String(entry.answer);
|
||||||
} catch {
|
} catch {
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ export async function sendTelegram(settings, message) {
|
|||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
lastSentAt = Date.now();
|
lastSentAt = Date.now();
|
||||||
|
if (!res.ok) { console.error(`[notify] Telegram HTTP error: ${res.status}`); return; }
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
if (!data.ok) console.error('[notify] Telegram error:', data.description);
|
if (!data.ok) console.error('[notify] Telegram error:', data.description);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
Reference in New Issue
Block a user