@methiu/raigal 0.2.4 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +57 -14
- package/dist/cli.js +424 -120
- package/dist/index.d.ts +1 -0
- package/dist/index.js +372 -112
- package/dist/{json-BBZKvm0E.js → json-DxIA7CCt.js} +1 -1
- package/dist/mcp.js +39 -21
- package/dist/{sarif-Lt31Ld5t.js → sarif-Cu7Rm1Ma.js} +1 -1
- package/dist/{version-CukuIVX4.js → version-DtOeK-2T.js} +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as APP_VERSION } from "./version-
|
|
1
|
+
import { t as APP_VERSION } from "./version-DtOeK-2T.js";
|
|
2
2
|
import { i as ENGINE_INFO, n as withFindingAssessments, t as summarizeFindingAssessments } from "./finding-assessment-CGpt5YUR.js";
|
|
3
3
|
//#region src/output/json.ts
|
|
4
4
|
const buildJsonOutput = (results, scoreResult, fileCount, elapsedMs, coverage) => {
|
package/dist/mcp.js
CHANGED
|
@@ -84,7 +84,7 @@ const getActiveToken = () => {
|
|
|
84
84
|
};
|
|
85
85
|
//#endregion
|
|
86
86
|
//#region src/version.ts
|
|
87
|
-
const APP_VERSION = "0.2.
|
|
87
|
+
const APP_VERSION = "0.2.6";
|
|
88
88
|
//#endregion
|
|
89
89
|
//#region src/cloud/contract.ts
|
|
90
90
|
const Severity = z.enum(["error", "warning"]);
|
|
@@ -242,6 +242,8 @@ const requestApi = async (endpoint, options = {}) => {
|
|
|
242
242
|
};
|
|
243
243
|
if (options.token) headers.Authorization = `Bearer ${options.token}`;
|
|
244
244
|
if (options.oidcToken) headers["X-GitHub-OIDC"] = options.oidcToken;
|
|
245
|
+
const orgId = options.orgId || process.env.RAIGAL_ORG_ID;
|
|
246
|
+
if (orgId) headers["X-Raigal-Org-Id"] = orgId;
|
|
245
247
|
let body;
|
|
246
248
|
if (options.body !== void 0) {
|
|
247
249
|
headers["Content-Type"] = "application/json";
|
|
@@ -273,11 +275,12 @@ const requestApi = async (endpoint, options = {}) => {
|
|
|
273
275
|
}
|
|
274
276
|
return json;
|
|
275
277
|
};
|
|
276
|
-
const fetchEntitlementFromApi = async (token, oidcToken) => {
|
|
278
|
+
const fetchEntitlementFromApi = async (token, oidcToken, orgId) => {
|
|
277
279
|
const data = await requestApi("/v1/entitlement", {
|
|
278
280
|
method: "POST",
|
|
279
281
|
token: token || void 0,
|
|
280
|
-
oidcToken
|
|
282
|
+
oidcToken,
|
|
283
|
+
orgId
|
|
281
284
|
});
|
|
282
285
|
return EntitlementResponse.parse(data);
|
|
283
286
|
};
|
|
@@ -359,7 +362,7 @@ const verifyEntitlementJwt = (jwt, options = {}) => {
|
|
|
359
362
|
const claims = parsed.data;
|
|
360
363
|
const expectedIssuer = process.env.RAIGAL_ISSUER?.trim() || "https://app.raigal.dev";
|
|
361
364
|
if (claims.iss !== expectedIssuer) throw new JwtVerificationError(`Untrusted issuer: ${claims.iss}`, "invalid_issuer");
|
|
362
|
-
if (!isVersionAtLeast("0.2.
|
|
365
|
+
if (!isVersionAtLeast("0.2.6", claims.min_cli_version)) throw new JwtVerificationError(`CLI version ${APP_VERSION} is below required minimum ${claims.min_cli_version}. Run "raigal update" or "npm install -g @methiu/raigal@latest".`, "cli_version_unsupported");
|
|
363
366
|
const now = options.nowSeconds ?? Math.floor(Date.now() / 1e3);
|
|
364
367
|
const grace = options.allowGraceSeconds ?? 0;
|
|
365
368
|
if (now > claims.exp + grace) {
|
|
@@ -518,7 +521,9 @@ const getEntitlement = async () => {
|
|
|
518
521
|
}
|
|
519
522
|
} else oidcToken = await fetchGitHubOidcToken();
|
|
520
523
|
try {
|
|
521
|
-
const
|
|
524
|
+
const tokenToPass = activeToken?.token ?? "";
|
|
525
|
+
const orgId = process.env.RAIGAL_ORG_ID;
|
|
526
|
+
const response = await fetchEntitlementFromApi(tokenToPass, oidcToken, orgId);
|
|
522
527
|
const claims = verifyEntitlementJwt(response.entitlement, { nowSeconds: now });
|
|
523
528
|
saveCachedEntitlement(response.entitlement, response.refresh_after);
|
|
524
529
|
return {
|
|
@@ -532,7 +537,7 @@ const getEntitlement = async () => {
|
|
|
532
537
|
};
|
|
533
538
|
//#endregion
|
|
534
539
|
//#region src/cloud/owner.ts
|
|
535
|
-
const
|
|
540
|
+
const GENERIC_GIT_REMOTE_RE = /^(?:(?:git@|ssh:\/\/(?:git@)?)[^:/]+(?::(?:\d+\/)?|[:/])|https?:\/\/(?:[^@]+@)?[^/]+\/)([^/]+)\/([^/\s]+?)(?:\.git)?\s*$/;
|
|
536
541
|
const parseGitRemote = (rawUrl) => {
|
|
537
542
|
if (!rawUrl) return {
|
|
538
543
|
owner: null,
|
|
@@ -540,18 +545,19 @@ const parseGitRemote = (rawUrl) => {
|
|
|
540
545
|
hasRemote: false,
|
|
541
546
|
isGitHubRemote: false
|
|
542
547
|
};
|
|
543
|
-
const match = rawUrl.match(
|
|
548
|
+
const match = rawUrl.match(GENERIC_GIT_REMOTE_RE);
|
|
544
549
|
if (!match || !match[1] || !match[2]) return {
|
|
545
550
|
owner: null,
|
|
546
551
|
repo: null,
|
|
547
552
|
hasRemote: true,
|
|
548
553
|
isGitHubRemote: false
|
|
549
554
|
};
|
|
555
|
+
const isGitHub = rawUrl.includes("github.com");
|
|
550
556
|
return {
|
|
551
557
|
owner: match[1].toLowerCase(),
|
|
552
558
|
repo: match[2].toLowerCase(),
|
|
553
559
|
hasRemote: true,
|
|
554
|
-
isGitHubRemote:
|
|
560
|
+
isGitHubRemote: isGitHub
|
|
555
561
|
};
|
|
556
562
|
};
|
|
557
563
|
const readGitConfigRemote = (dir) => {
|
|
@@ -616,6 +622,27 @@ const detectLocalRepoOwner = (directory) => {
|
|
|
616
622
|
isGitHubRemote: true
|
|
617
623
|
};
|
|
618
624
|
}
|
|
625
|
+
const gitlabRepo = process.env.CI_PROJECT_PATH?.trim();
|
|
626
|
+
if (gitlabRepo && gitlabRepo.includes("/")) {
|
|
627
|
+
const parts = gitlabRepo.split("/");
|
|
628
|
+
const repo = parts.pop() ?? "";
|
|
629
|
+
return {
|
|
630
|
+
owner: (parts[0] ?? "").toLowerCase(),
|
|
631
|
+
repo: repo.toLowerCase(),
|
|
632
|
+
hasRemote: true,
|
|
633
|
+
isGitHubRemote: false
|
|
634
|
+
};
|
|
635
|
+
}
|
|
636
|
+
const bitbucketRepo = (process.env.BITBUCKET_REPO_FULL_NAME || process.env.BITBUCKET_REPO_SLUG)?.trim();
|
|
637
|
+
if (bitbucketRepo) {
|
|
638
|
+
const [owner = process.env.BITBUCKET_WORKSPACE || "", repo = ""] = bitbucketRepo.includes("/") ? bitbucketRepo.split("/") : [process.env.BITBUCKET_WORKSPACE || "", bitbucketRepo];
|
|
639
|
+
return {
|
|
640
|
+
owner: owner.toLowerCase(),
|
|
641
|
+
repo: repo.toLowerCase(),
|
|
642
|
+
hasRemote: true,
|
|
643
|
+
isGitHubRemote: false
|
|
644
|
+
};
|
|
645
|
+
}
|
|
619
646
|
const gitRoot = findGitRoot$1(directory);
|
|
620
647
|
if (!gitRoot) return {
|
|
621
648
|
owner: null,
|
|
@@ -627,26 +654,17 @@ const detectLocalRepoOwner = (directory) => {
|
|
|
627
654
|
if (rawUrl !== null) return parseGitRemote(rawUrl);
|
|
628
655
|
return parseGitRemote(spawnGitRemote(gitRoot));
|
|
629
656
|
};
|
|
630
|
-
const isNonGitHubCi = () => {
|
|
631
|
-
const env = process.env;
|
|
632
|
-
if (!(env.CI === "true" || env.CI === "1")) return false;
|
|
633
|
-
return Boolean(env.GITLAB_CI || env.BITBUCKET_BUILD_NUMBER || env.CIRCLECI && !env.CIRCLE_PROJECT_REPONAME?.includes("/") || env.BUILDKITE || env.TRAVIS || env.JENKINS_URL);
|
|
634
|
-
};
|
|
635
657
|
const checkOwnerAgainstAllowlist = (detected, allowedOwners, tokenKind) => {
|
|
636
|
-
if (isNonGitHubCi()) return {
|
|
637
|
-
allowed: false,
|
|
638
|
-
reason: "Non-GitHub CI environments are unsupported under organization allowlists."
|
|
639
|
-
};
|
|
640
658
|
if (!detected.hasRemote) {
|
|
641
659
|
if (tokenKind === "session") return { allowed: true };
|
|
642
660
|
return {
|
|
643
661
|
allowed: false,
|
|
644
|
-
reason: "Repository has no
|
|
662
|
+
reason: "Repository has no origin remote. CI and API key runs require an origin remote matching an allowed organization."
|
|
645
663
|
};
|
|
646
664
|
}
|
|
647
|
-
if (!detected.
|
|
665
|
+
if (!detected.owner) return {
|
|
648
666
|
allowed: false,
|
|
649
|
-
reason: "Repository remote
|
|
667
|
+
reason: "Repository remote owner could not be determined."
|
|
650
668
|
};
|
|
651
669
|
const lowerOwner = detected.owner.toLowerCase();
|
|
652
670
|
if (!allowedOwners.some((allowed) => allowed.login.toLowerCase() === lowerOwner)) {
|
|
@@ -654,7 +672,7 @@ const checkOwnerAgainstAllowlist = (detected, allowedOwners, tokenKind) => {
|
|
|
654
672
|
return {
|
|
655
673
|
allowed: false,
|
|
656
674
|
owner: lowerOwner,
|
|
657
|
-
reason: `
|
|
675
|
+
reason: `Repository owner '${detected.owner}' is not on the organization allowlist (${allowedLogins || "none"}).`
|
|
658
676
|
};
|
|
659
677
|
}
|
|
660
678
|
return {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as APP_VERSION } from "./version-
|
|
1
|
+
import { t as APP_VERSION } from "./version-DtOeK-2T.js";
|
|
2
2
|
import { n as isSecretClassRule, t as FIXED_SECRET_DIAGNOSTIC_MESSAGE } from "./mask-secrets-BXn-ZSEh.js";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
//#region src/output/sarif.ts
|