mirror of
https://github.com/Sea-Haven-Industries/payments-dashboard.git
synced 2026-09-30 06:33:11 +00:00
chore: resolve open code-scanning alerts (workflow permissions + Gusto URL sanitization) (#81)
Some checks failed
Deploy / deploy (push) Has been cancelled
Some checks failed
Deploy / deploy (push) Has been cancelled
* ci: add least-privilege permissions blocks to workflow callers Resolves code scanning alerts #4 and #5 (actions/missing-workflow-permissions). Both callable workflows only need contents: read; the dependency-review callable already declares it internally, this caps the caller token to match. * enhance(email): improve detection of allowed Gusto URLs in email classification Resolves code scanning alert #2
This commit is contained in:
parent
bf235e70d7
commit
849f33a0bc
3 changed files with 26 additions and 2 deletions
3
.github/workflows/ci.yaml
vendored
3
.github/workflows/ci.yaml
vendored
|
|
@ -3,6 +3,9 @@ on:
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [main]
|
branches: [main]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
ci:
|
ci:
|
||||||
uses: Sea-Haven-Industries/.github/.github/workflows/ci-typescript-cdk.yaml@fd60e4c9041784f666ac0fdefb9bec3c7fbf5143 # main
|
uses: Sea-Haven-Industries/.github/.github/workflows/ci-typescript-cdk.yaml@fd60e4c9041784f666ac0fdefb9bec3c7fbf5143 # main
|
||||||
|
|
|
||||||
4
.github/workflows/dependency-review.yml
vendored
4
.github/workflows/dependency-review.yml
vendored
|
|
@ -1,6 +1,10 @@
|
||||||
name: Dependency Review
|
name: Dependency Review
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
review:
|
review:
|
||||||
uses: Sea-Haven-Industries/.github/.github/workflows/callable-dependency-review.yaml@fd60e4c9041784f666ac0fdefb9bec3c7fbf5143 # main
|
uses: Sea-Haven-Industries/.github/.github/workflows/callable-dependency-review.yaml@fd60e4c9041784f666ac0fdefb9bec3c7fbf5143 # main
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,24 @@ const formatCurrency = (v) =>
|
||||||
currency: "USD",
|
currency: "USD",
|
||||||
}).format(Number(v || 0));
|
}).format(Number(v || 0));
|
||||||
|
|
||||||
|
function isAllowedGustoHost(hostname) {
|
||||||
|
const h = (hostname || "").toLowerCase();
|
||||||
|
return h === "gusto.com" || h.endsWith(".gusto.com");
|
||||||
|
}
|
||||||
|
|
||||||
|
function bodyMentionsAllowedGustoUrl(text) {
|
||||||
|
const urlMatches = (text || "").match(/\bhttps?:\/\/[^\s<>"')]+/gi) || [];
|
||||||
|
for (const rawUrl of urlMatches) {
|
||||||
|
try {
|
||||||
|
const parsed = new URL(rawUrl);
|
||||||
|
if (isAllowedGustoHost(parsed.hostname)) return true;
|
||||||
|
} catch {
|
||||||
|
// Ignore malformed URLs in email text.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
function classifyEmail(from, subject, text) {
|
function classifyEmail(from, subject, text) {
|
||||||
const fromAddr = (from?.text || from || "").toLowerCase();
|
const fromAddr = (from?.text || from || "").toLowerCase();
|
||||||
const subj = (subject || "").toLowerCase();
|
const subj = (subject || "").toLowerCase();
|
||||||
|
|
@ -54,8 +72,7 @@ function classifyEmail(from, subject, text) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const strippedSubj = subj.replace(/^fwd?:\s*/i, "");
|
const strippedSubj = subj.replace(/^fwd?:\s*/i, "");
|
||||||
const body = (text || "").toLowerCase();
|
const bodyMentionsGusto = bodyMentionsAllowedGustoUrl(text || "");
|
||||||
const bodyMentionsGusto = body.includes("gusto.com");
|
|
||||||
|
|
||||||
if (bodyMentionsGusto && strippedSubj.includes("payroll confirmation")) {
|
if (bodyMentionsGusto && strippedSubj.includes("payroll confirmation")) {
|
||||||
return "employee";
|
return "employee";
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue