mobbdev 0.0.143 → 0.0.145

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.
Files changed (2) hide show
  1. package/dist/index.mjs +1114 -1074
  2. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -528,16 +528,11 @@ import fetch4 from "node-fetch";
528
528
  import open2 from "open";
529
529
  import semver from "semver";
530
530
  import tmp2 from "tmp";
531
- import { z as z11 } from "zod";
531
+ import { z as z12 } from "zod";
532
532
 
533
533
  // src/features/analysis/add_fix_comments_for_pr/add_fix_comments_for_pr.ts
534
534
  import Debug4 from "debug";
535
535
 
536
- // src/features/analysis/scm/ado.ts
537
- import querystring from "node:querystring";
538
- import * as api from "azure-devops-node-api";
539
- import { z as z2 } from "zod";
540
-
541
536
  // src/features/analysis/scm/types.ts
542
537
  var ReferenceType = /* @__PURE__ */ ((ReferenceType2) => {
543
538
  ReferenceType2["BRANCH"] = "BRANCH";
@@ -566,6 +561,35 @@ var ScmType = /* @__PURE__ */ ((ScmType2) => {
566
561
  return ScmType2;
567
562
  })(ScmType || {});
568
563
 
564
+ // src/features/analysis/scm/ado/constants.ts
565
+ var DEFUALT_ADO_ORIGIN = scmCloudUrl.Ado;
566
+
567
+ // src/features/analysis/scm/ado/utils.ts
568
+ import querystring3 from "node:querystring";
569
+ import * as api from "azure-devops-node-api";
570
+ import { z as z9 } from "zod";
571
+
572
+ // src/features/analysis/scm/env.ts
573
+ import { z as z2 } from "zod";
574
+ var EnvVariablesZod = z2.object({
575
+ GITLAB_API_TOKEN: z2.string().optional(),
576
+ BROKERED_HOSTS: z2.string().toLowerCase().transform(
577
+ (x) => x.split(",").map((url) => url.trim(), []).filter(Boolean)
578
+ ).default(""),
579
+ GITHUB_API_TOKEN: z2.string().optional(),
580
+ GIT_PROXY_HOST: z2.string().default("http://tinyproxy:8888")
581
+ });
582
+ var { GITLAB_API_TOKEN, BROKERED_HOSTS, GITHUB_API_TOKEN, GIT_PROXY_HOST } = EnvVariablesZod.parse(process.env);
583
+
584
+ // src/features/analysis/scm/scm.ts
585
+ import { z as z7 } from "zod";
586
+
587
+ // src/features/analysis/scm/bitbucket/bitbucket.ts
588
+ import querystring from "node:querystring";
589
+ import bitbucketPkg from "bitbucket";
590
+ import * as bitbucketPkgNode from "bitbucket";
591
+ import { z as z3 } from "zod";
592
+
569
593
  // src/features/analysis/scm/urlParser.ts
570
594
  function detectAdoUrl(args) {
571
595
  const { pathname, hostname, scmType } = args;
@@ -710,509 +734,519 @@ var sanityRepoURL = (scmURL) => {
710
734
  }
711
735
  };
712
736
 
713
- // src/features/analysis/scm/ado.ts
714
- function removeTrailingSlash(str) {
715
- return str.trim().replace(/\/+$/, "");
716
- }
717
- async function _getOrgsForOauthToken({ oauthToken }) {
718
- const profileZ = z2.object({
719
- displayName: z2.string(),
720
- publicAlias: z2.string().min(1),
721
- emailAddress: z2.string(),
722
- coreRevision: z2.number(),
723
- timeStamp: z2.string(),
724
- id: z2.string(),
725
- revision: z2.number()
726
- });
727
- const accountsZ = z2.object({
728
- count: z2.number(),
729
- value: z2.array(
730
- z2.object({
731
- accountId: z2.string(),
732
- accountUri: z2.string(),
733
- accountName: z2.string()
734
- })
735
- )
736
- });
737
- const profileRes = await fetch(
738
- "https://app.vssps.visualstudio.com/_apis/profile/profiles/me?api-version=6.0",
739
- {
740
- method: "GET",
741
- headers: {
742
- Authorization: `Bearer ${oauthToken}`
743
- }
744
- }
745
- );
746
- const profileJson = await profileRes.json();
747
- const profile = profileZ.parse(profileJson);
748
- const accountsRes = await fetch(
749
- `https://app.vssps.visualstudio.com/_apis/accounts?memberId=${profile.publicAlias}&api-version=6.0`,
750
- {
751
- method: "GET",
752
- headers: {
753
- Authorization: `Bearer ${oauthToken}`
754
- }
737
+ // src/features/analysis/scm/utils/get_issue_type.ts
738
+ var getIssueType = (issueType) => {
739
+ switch (issueType) {
740
+ case "SQL_Injection" /* SqlInjection */:
741
+ return "SQL Injection";
742
+ case "CMDi_relative_path_command" /* CmDiRelativePathCommand */:
743
+ return "Relative Path Command Injection";
744
+ case "CMDi" /* CmDi */:
745
+ return "Command Injection";
746
+ case "XXE" /* Xxe */:
747
+ return "XXE";
748
+ case "XSS" /* Xss */:
749
+ return "XSS";
750
+ case "PT" /* Pt */:
751
+ return "Path Traversal";
752
+ case "ZIP_SLIP" /* ZipSlip */:
753
+ return "Zip Slip";
754
+ case "INSECURE_RANDOMNESS" /* InsecureRandomness */:
755
+ return "Insecure Randomness";
756
+ case "SSRF" /* Ssrf */:
757
+ return "Server Side Request Forgery";
758
+ case "TYPE_CONFUSION" /* TypeConfusion */:
759
+ return "Type Confusion";
760
+ case "REGEX_INJECTION" /* RegexInjection */:
761
+ return "Regular Expression Injection";
762
+ case "INCOMPLETE_URL_SANITIZATION" /* IncompleteUrlSanitization */:
763
+ return "Incomplete URL Sanitization";
764
+ case "LOCALE_DEPENDENT_COMPARISON" /* LocaleDependentComparison */:
765
+ return "Locale Dependent Comparison";
766
+ case "LOG_FORGING" /* LogForging */:
767
+ return "Log Forging";
768
+ case "MISSING_CHECK_AGAINST_NULL" /* MissingCheckAgainstNull */:
769
+ return "Missing Check against Null";
770
+ case "PASSWORD_IN_COMMENT" /* PasswordInComment */:
771
+ return "Password in Comment";
772
+ case "OVERLY_BROAD_CATCH" /* OverlyBroadCatch */:
773
+ return "Poor Error Handling: Overly Broad Catch";
774
+ case "USE_OF_SYSTEM_OUTPUT_STREAM" /* UseOfSystemOutputStream */:
775
+ return "Use of System.out/System.err";
776
+ case "DANGEROUS_FUNCTION_OVERFLOW" /* DangerousFunctionOverflow */:
777
+ return "Use of dangerous function";
778
+ case "DOS_STRING_BUILDER" /* DosStringBuilder */:
779
+ return "Denial of Service: StringBuilder";
780
+ case "OPEN_REDIRECT" /* OpenRedirect */:
781
+ return "Open Redirect";
782
+ case "WEAK_XML_SCHEMA_UNBOUNDED_OCCURRENCES" /* WeakXmlSchemaUnboundedOccurrences */:
783
+ return "Weak XML Schema: Unbounded Occurrences";
784
+ case "SYSTEM_INFORMATION_LEAK" /* SystemInformationLeak */:
785
+ return "System Information Leak";
786
+ case "SYSTEM_INFORMATION_LEAK_EXTERNAL" /* SystemInformationLeakExternal */:
787
+ return "External System Information Leak";
788
+ case "HTTP_RESPONSE_SPLITTING" /* HttpResponseSplitting */:
789
+ return "HTTP response splitting";
790
+ case "HTTP_ONLY_COOKIE" /* HttpOnlyCookie */:
791
+ return "Cookie is not HttpOnly";
792
+ case "INSECURE_COOKIE" /* InsecureCookie */:
793
+ return "Insecure Cookie";
794
+ case "TRUST_BOUNDARY_VIOLATION" /* TrustBoundaryViolation */:
795
+ return "Trust Boundary Violation";
796
+ case "NULL_DEREFERENCE" /* NullDereference */:
797
+ return "Null Dereference";
798
+ case "UNSAFE_DESERIALIZATION" /* UnsafeDeserialization */:
799
+ return "Unsafe deserialization";
800
+ case "INSECURE_BINDER_CONFIGURATION" /* InsecureBinderConfiguration */:
801
+ return "Insecure Binder Configuration";
802
+ case "UNSAFE_TARGET_BLANK" /* UnsafeTargetBlank */:
803
+ return "Unsafe use of target blank";
804
+ case "IFRAME_WITHOUT_SANDBOX" /* IframeWithoutSandbox */:
805
+ return "Client use of iframe without sandbox";
806
+ case "JQUERY_DEPRECATED_SYMBOLS" /* JqueryDeprecatedSymbols */:
807
+ return "jQuery deprecated symbols";
808
+ case "MISSING_ANTIFORGERY_VALIDATION" /* MissingAntiforgeryValidation */:
809
+ return "Missing Anti-Forgery Validation";
810
+ case "GRAPHQL_DEPTH_LIMIT" /* GraphqlDepthLimit */:
811
+ return "GraphQL Depth Limit";
812
+ case "UNCHECKED_LOOP_CONDITION" /* UncheckedLoopCondition */:
813
+ return "Unchecked Loop Condition";
814
+ case "IMPROPER_RESOURCE_SHUTDOWN_OR_RELEASE" /* ImproperResourceShutdownOrRelease */:
815
+ return "Improper Resource Shutdown or Release";
816
+ case "IMPROPER_EXCEPTION_HANDLING" /* ImproperExceptionHandling */:
817
+ return "Improper Exception Handling";
818
+ case "DEFAULT_RIGHTS_IN_OBJ_DEFINITION" /* DefaultRightsInObjDefinition */:
819
+ return "Default Definer Rights in Package or Object Definition";
820
+ case "HTML_COMMENT_IN_JSP" /* HtmlCommentInJsp */:
821
+ return "HTML Comment in JSP";
822
+ case "ERROR_CONDTION_WITHOUT_ACTION" /* ErrorCondtionWithoutAction */:
823
+ return "Error Condition Without Action";
824
+ case "DEPRECATED_FUNCTION" /* DeprecatedFunction */:
825
+ return "Deprecated Function";
826
+ case "HARDCODED_SECRETS" /* HardcodedSecrets */:
827
+ return "Hardcoded Secrets";
828
+ case "PROTOTYPE_POLLUTION" /* PrototypePollution */:
829
+ return "Prototype Pollution";
830
+ case "RACE_CONDITION_FORMAT_FLAW" /* RaceConditionFormatFlaw */:
831
+ return "Race Condition Format Flaw";
832
+ case "NON_FINAL_PUBLIC_STATIC_FIELD" /* NonFinalPublicStaticField */:
833
+ return "Non-final Public Static Field";
834
+ case "MISSING_HSTS_HEADER" /* MissingHstsHeader */:
835
+ return "Missing HSTS Header";
836
+ case "DEAD_CODE_UNUSED_FIELD" /* DeadCodeUnusedField */:
837
+ return "Dead Code: Unused Field";
838
+ case "HEADER_MANIPULATION" /* HeaderManipulation */:
839
+ return "Header Manipulation";
840
+ case "MISSING_EQUALS_OR_HASHCODE" /* MissingEqualsOrHashcode */:
841
+ return "Missing equals or hashcode method";
842
+ case "WCF_MISCONFIGURATION_INSUFFICIENT_LOGGING" /* WcfMisconfigurationInsufficientLogging */:
843
+ return "WCF Misconfiguration: Insufficient Logging";
844
+ case "WCF_MISCONFIGURATION_THROTTLING_NOT_ENABLED" /* WcfMisconfigurationThrottlingNotEnabled */:
845
+ return "WCF Misconfiguration: Throttling Not Enabled";
846
+ case "USELESS_REGEXP_CHAR_ESCAPE" /* UselessRegexpCharEscape */:
847
+ return "Useless regular-expression character escape";
848
+ case "INCOMPLETE_HOSTNAME_REGEX" /* IncompleteHostnameRegex */:
849
+ return "Incomplete Hostname Regex";
850
+ case "OVERLY_LARGE_RANGE" /* OverlyLargeRange */:
851
+ return "Regex: Overly Large Range";
852
+ case "INSUFFICIENT_LOGGING" /* InsufficientLogging */:
853
+ return "Insufficient Logging of Sensitive Operations";
854
+ case "PRIVACY_VIOLATION" /* PrivacyViolation */:
855
+ return "Privacy Violation";
856
+ case "INCOMPLETE_URL_SCHEME_CHECK" /* IncompleteUrlSchemeCheck */:
857
+ return "Incomplete URL Scheme Check";
858
+ case "VALUE_NEVER_READ" /* ValueNeverRead */:
859
+ return "Value Never Read";
860
+ case "VALUE_SHADOWING" /* ValueShadowing */:
861
+ return "Value Shadowing";
862
+ default: {
863
+ return issueType ? issueType.replaceAll("_", " ") : "Other";
755
864
  }
756
- );
757
- const accountsJson = await accountsRes.json();
758
- const accounts = accountsZ.parse(accountsJson);
759
- const orgs = accounts.value.map((account) => account.accountName).filter((value, index, array) => array.indexOf(value) === index);
760
- return orgs;
761
- }
762
- function _getPublicAdoClient({ orgName }) {
763
- const orgUrl = `https://dev.azure.com/${orgName}`;
764
- const authHandler = api.getPersonalAccessTokenHandler("");
765
- authHandler.canHandleAuthentication = () => false;
766
- authHandler.prepareRequest = (_options) => {
767
- return;
768
- };
769
- const connection = new api.WebApi(orgUrl, authHandler);
770
- return connection;
771
- }
772
- function getAdoTokenType(token) {
773
- if (token.includes(".")) {
774
- return "OAUTH" /* OAUTH */;
775
865
  }
776
- return "PAT" /* PAT */;
866
+ };
867
+
868
+ // src/features/analysis/scm/utils/index.ts
869
+ function getFixUrlWithRedirect(params) {
870
+ const {
871
+ fixId,
872
+ projectId,
873
+ organizationId,
874
+ analysisId,
875
+ redirectUrl,
876
+ appBaseUrl,
877
+ commentId
878
+ } = params;
879
+ const searchParams = new URLSearchParams();
880
+ searchParams.append("commit_redirect_url", redirectUrl);
881
+ searchParams.append("comment_id", commentId.toString());
882
+ return `${getFixUrl({
883
+ appBaseUrl,
884
+ fixId,
885
+ projectId,
886
+ organizationId,
887
+ analysisId
888
+ })}?${searchParams.toString()}`;
777
889
  }
778
- async function getAdoApiClient({
779
- accessToken,
780
- tokenOrg,
781
- orgName
890
+ function getFixUrl({
891
+ appBaseUrl,
892
+ fixId,
893
+ projectId,
894
+ organizationId,
895
+ analysisId
782
896
  }) {
783
- if (!accessToken || tokenOrg && tokenOrg !== orgName) {
784
- return _getPublicAdoClient({ orgName });
897
+ return `${appBaseUrl}/organization/${organizationId}/project/${projectId}/report/${analysisId}/fix/${fixId}`;
898
+ }
899
+ function getCommitUrl(params) {
900
+ const {
901
+ fixId,
902
+ projectId,
903
+ organizationId,
904
+ analysisId,
905
+ redirectUrl,
906
+ appBaseUrl,
907
+ commentId
908
+ } = params;
909
+ const searchParams = new URLSearchParams();
910
+ searchParams.append("redirect_url", redirectUrl);
911
+ searchParams.append("comment_id", commentId.toString());
912
+ return `${getFixUrl({
913
+ appBaseUrl,
914
+ fixId,
915
+ projectId,
916
+ organizationId,
917
+ analysisId
918
+ })}/commit?${searchParams.toString()}`;
919
+ }
920
+ var userNamePattern = /^(https?:\/\/)([^@]+@)?([^/]+\/.+)$/;
921
+ var sshPattern = /^git@([\w.-]+):([\w./-]+)$/;
922
+ function normalizeUrl(repoUrl) {
923
+ let trimmedUrl = repoUrl.trim().replace(/\/+$/, "");
924
+ if (repoUrl.endsWith(".git")) {
925
+ trimmedUrl = trimmedUrl.slice(0, -".git".length);
785
926
  }
786
- const orgUrl = `https://dev.azure.com/${orgName}`;
787
- if (getAdoTokenType(accessToken) === "OAUTH" /* OAUTH */) {
788
- const connection2 = new api.WebApi(orgUrl, api.getBearerHandler(accessToken));
789
- return connection2;
927
+ const usernameMatch = trimmedUrl.match(userNamePattern);
928
+ if (usernameMatch) {
929
+ const [_all, protocol, _username, repoPath] = usernameMatch;
930
+ trimmedUrl = `${protocol}${repoPath}`;
790
931
  }
791
- const authHandler = api.getPersonalAccessTokenHandler(accessToken);
792
- const connection = new api.WebApi(orgUrl, authHandler);
793
- return connection;
794
- }
795
- async function adoValidateParams({
796
- url,
797
- accessToken,
798
- tokenOrg
799
- }) {
800
- try {
801
- if (!url && accessToken && getAdoTokenType(accessToken) === "OAUTH" /* OAUTH */) {
802
- await _getOrgsForOauthToken({ oauthToken: accessToken });
803
- return;
804
- }
805
- let org = tokenOrg;
806
- if (url) {
807
- const { owner } = parseAdoOwnerAndRepo(url);
808
- org = owner;
809
- }
810
- if (!org) {
811
- throw new InvalidRepoUrlError(`invalid ADO ORG ${org}`);
812
- }
813
- const api2 = await getAdoApiClient({
814
- accessToken,
815
- tokenOrg,
816
- orgName: org
817
- });
818
- await api2.connect();
819
- } catch (e) {
820
- const error = e;
821
- const code = error.code || error.status || error.statusCode || error.response?.status || error.response?.statusCode || error.response?.code;
822
- const description = error.description || `${e}`;
823
- if (code === 401 || code === 403 || description.includes("401") || description.includes("403")) {
824
- throw new InvalidAccessTokenError(`invalid ADO access token`);
825
- }
826
- if (code === 404 || description.includes("404") || description.includes("Not Found")) {
827
- throw new InvalidRepoUrlError(`invalid ADO repo URL ${url}`);
828
- }
829
- throw e;
830
- }
831
- }
832
- async function getAdoIsUserCollaborator({
833
- accessToken,
834
- tokenOrg,
835
- repoUrl
836
- }) {
837
- try {
838
- const { owner, repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
839
- const api2 = await getAdoApiClient({
840
- accessToken,
841
- tokenOrg,
842
- orgName: owner
843
- });
844
- const git = await api2.getGitApi();
845
- const branches = await git.getBranches(repo, projectName);
846
- if (!branches || branches.length === 0) {
847
- throw new InvalidRepoUrlError("no branches");
848
- }
849
- return true;
850
- } catch (e) {
851
- return false;
932
+ const sshMatch = trimmedUrl.match(sshPattern);
933
+ if (sshMatch) {
934
+ const [_all, hostname, reporPath] = sshMatch;
935
+ trimmedUrl = `https://${hostname}/${reporPath}`;
852
936
  }
937
+ return trimmedUrl;
853
938
  }
854
- var adoStatusNumberToEnumMap = {
855
- 1: "active" /* active */,
856
- 2: "abandoned" /* abandoned */,
857
- 3: "completed" /* completed */,
858
- 4: "all" /* all */
939
+ var isUrlHasPath = (url) => {
940
+ return new URL(url).origin !== url;
859
941
  };
860
- async function getAdoPullRequestStatus({
861
- accessToken,
862
- tokenOrg,
863
- repoUrl,
864
- prNumber
865
- }) {
866
- const { owner, repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
867
- const api2 = await getAdoApiClient({
868
- accessToken,
869
- tokenOrg,
870
- orgName: owner
871
- });
872
- const git = await api2.getGitApi();
873
- const res = await git.getPullRequest(repo, prNumber, projectName);
874
- if (!res.status || res.status < 1 || res.status > 3) {
875
- throw new Error("bad pr status for ADO");
876
- }
877
- return adoStatusNumberToEnumMap[res.status];
878
- }
879
- async function getAdoIsRemoteBranch({
880
- accessToken,
881
- tokenOrg,
882
- repoUrl,
883
- branch
884
- }) {
885
- const { owner, repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
886
- const api2 = await getAdoApiClient({
887
- accessToken,
888
- tokenOrg,
889
- orgName: owner
890
- });
891
- const git = await api2.getGitApi();
892
- try {
893
- const branchStatus = await git.getBranch(repo, branch, projectName);
894
- if (!branchStatus || !branchStatus.commit) {
895
- throw new InvalidRepoUrlError("no branch status");
896
- }
897
- return branchStatus.name === branch;
898
- } catch (e) {
899
- return false;
900
- }
942
+ function shouldValidateUrl(repoUrl) {
943
+ return repoUrl && isUrlHasPath(repoUrl);
901
944
  }
902
- async function getAdoRepoList({
903
- orgName,
904
- tokenOrg,
905
- accessToken
906
- }) {
907
- let orgs = [];
908
- if (getAdoTokenType(accessToken) === "OAUTH" /* OAUTH */) {
909
- orgs = await _getOrgsForOauthToken({ oauthToken: accessToken });
910
- }
911
- if (orgs.length === 0 && !orgName) {
912
- throw new Error(`no orgs for ADO`);
913
- } else if (orgs.length === 0 && orgName) {
914
- orgs = [orgName];
915
- }
916
- const repos = (await Promise.allSettled(
917
- orgs.map(async (org) => {
918
- const orgApi = await getAdoApiClient({
919
- accessToken,
920
- tokenOrg,
921
- orgName: org
922
- });
923
- const gitOrg = await orgApi.getGitApi();
924
- const orgRepos = await gitOrg.getRepositories();
925
- const repoInfoList = (await Promise.allSettled(
926
- orgRepos.map(async (repo) => {
927
- if (!repo.name || !repo.remoteUrl || !repo.defaultBranch) {
928
- throw new InvalidRepoUrlError("bad repo");
929
- }
930
- const branch = await gitOrg.getBranch(
931
- repo.name,
932
- repo.defaultBranch.replace(/^refs\/heads\//, ""),
933
- repo.project?.name
934
- );
935
- return {
936
- repoName: repo.name,
937
- repoUrl: repo.remoteUrl.replace(
938
- /^[hH][tT][tT][pP][sS]:\/\/[^/]+@/,
939
- "https://"
940
- ),
941
- repoOwner: org,
942
- repoIsPublic: repo.project?.visibility === 2,
943
- //2 is public in the ADO API
944
- repoLanguages: [],
945
- repoUpdatedAt: branch.commit?.committer?.date?.toDateString() || repo.project?.lastUpdateTime?.toDateString() || (/* @__PURE__ */ new Date()).toDateString()
946
- };
947
- })
948
- )).reduce((acc, res) => {
949
- if (res.status === "fulfilled") {
950
- acc.push(res.value);
951
- }
952
- return acc;
953
- }, []);
954
- return repoInfoList;
945
+
946
+ // src/features/analysis/scm/bitbucket/bitbucket.ts
947
+ var BITBUCKET_HOSTNAME = "bitbucket.org";
948
+ var TokenExpiredErrorZ = z3.object({
949
+ status: z3.number(),
950
+ error: z3.object({
951
+ type: z3.string(),
952
+ error: z3.object({
953
+ message: z3.string()
955
954
  })
956
- )).reduce((acc, res) => {
957
- if (res.status === "fulfilled") {
958
- return acc.concat(res.value);
959
- }
960
- return acc;
961
- }, []);
962
- return repos;
963
- }
964
- function getAdoPrUrl({
965
- url,
966
- prNumber
967
- }) {
968
- return `${url}/pullrequest/${prNumber}`;
969
- }
970
- function getAdoDownloadUrl({
971
- repoUrl,
972
- branch
973
- }) {
974
- const { owner, repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
975
- const url = new URL(repoUrl);
976
- const origin = url.origin.toLowerCase().endsWith(".visualstudio.com") ? "https://dev.azure.com" : url.origin.toLowerCase();
977
- return `${origin}/${owner}/${projectName}/_apis/git/repositories/${repo}/items/items?path=/&versionDescriptor[versionOptions]=0&versionDescriptor[versionType]=commit&versionDescriptor[version]=${branch}&resolveLfs=true&$format=zip&api-version=5.0&download=true`;
955
+ })
956
+ });
957
+ var BITBUCKET_ACCESS_TOKEN_URL = `https://${BITBUCKET_HOSTNAME}/site/oauth2/access_token`;
958
+ var BitbucketAuthResultZ = z3.object({
959
+ access_token: z3.string(),
960
+ token_type: z3.string(),
961
+ refresh_token: z3.string()
962
+ });
963
+ var BitbucketParseResultZ = z3.object({
964
+ organization: z3.string(),
965
+ repoName: z3.string(),
966
+ hostname: z3.literal(BITBUCKET_HOSTNAME)
967
+ });
968
+ function parseBitbucketOrganizationAndRepo(bitbucketUrl) {
969
+ const parsedGitHubUrl = normalizeUrl(bitbucketUrl);
970
+ const parsingResult = parseScmURL(parsedGitHubUrl, "Bitbucket" /* Bitbucket */);
971
+ const validatedBitbucketResult = BitbucketParseResultZ.parse(parsingResult);
972
+ return {
973
+ workspace: validatedBitbucketResult.organization,
974
+ repoSlug: validatedBitbucketResult.repoName
975
+ };
978
976
  }
979
- async function getAdoBranchList({
980
- accessToken,
981
- tokenOrg,
982
- repoUrl
983
- }) {
984
- const { owner, repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
985
- const api2 = await getAdoApiClient({
986
- accessToken,
987
- tokenOrg,
988
- orgName: owner
989
- });
990
- const git = await api2.getGitApi();
991
- try {
992
- const res = await git.getBranches(repo, projectName);
993
- res.sort((a, b) => {
994
- if (!a.commit?.committer?.date || !b.commit?.committer?.date) {
995
- return 0;
996
- }
997
- return b.commit?.committer?.date.getTime() - a.commit?.committer?.date.getTime();
998
- });
999
- return res.reduce((acc, branch) => {
1000
- if (!branch.name) {
1001
- return acc;
977
+ async function getBitbucketToken(params) {
978
+ const { bitbucketClientId, bitbucketClientSecret, authType } = params;
979
+ const res = await fetch(BITBUCKET_ACCESS_TOKEN_URL, {
980
+ method: "POST",
981
+ headers: {
982
+ "Content-Type": "application/x-www-form-urlencoded",
983
+ Authorization: "Basic " + btoa(`${bitbucketClientId}:${bitbucketClientSecret}`)
984
+ },
985
+ body: querystring.stringify(
986
+ authType === "refresh_token" ? {
987
+ grant_type: authType,
988
+ refresh_token: params.refreshToken
989
+ } : {
990
+ grant_type: authType,
991
+ code: params.code
1002
992
  }
1003
- acc.push(branch.name);
1004
- return acc;
1005
- }, []);
1006
- } catch (e) {
1007
- return [];
1008
- }
1009
- }
1010
- async function createAdoPullRequest(options) {
1011
- const { owner, repo, projectName } = parseAdoOwnerAndRepo(options.repoUrl);
1012
- const api2 = await getAdoApiClient({
1013
- accessToken: options.accessToken,
1014
- tokenOrg: options.tokenOrg,
1015
- orgName: owner
993
+ )
1016
994
  });
1017
- const git = await api2.getGitApi();
1018
- const res = await git.createPullRequest(
1019
- {
1020
- sourceRefName: `refs/heads/${options.sourceBranchName}`,
1021
- targetRefName: `refs/heads/${options.targetBranchName}`,
1022
- title: options.title,
1023
- description: options.body
1024
- },
1025
- repo,
1026
- projectName
1027
- );
1028
- return res.pullRequestId;
995
+ const authResult = await res.json();
996
+ return BitbucketAuthResultZ.parse(authResult);
1029
997
  }
1030
- async function getAdoRepoDefaultBranch({
1031
- repoUrl,
1032
- tokenOrg,
1033
- accessToken
1034
- }) {
1035
- const { owner, repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
1036
- const api2 = await getAdoApiClient({
1037
- accessToken,
1038
- tokenOrg,
1039
- orgName: owner
1040
- });
1041
- const git = await api2.getGitApi();
1042
- const getRepositoryRes = await git.getRepository(
1043
- decodeURI(repo),
1044
- projectName ? decodeURI(projectName) : void 0
1045
- );
1046
- if (!getRepositoryRes?.defaultBranch) {
1047
- throw new InvalidRepoUrlError("no default branch");
998
+ function getBitbucketIntance(params) {
999
+ const BitbucketContstructor = bitbucketPkg && "Bitbucket" in bitbucketPkg ? bitbucketPkg.Bitbucket : bitbucketPkgNode.Bitbucket;
1000
+ switch (params.authType) {
1001
+ case "public":
1002
+ return new BitbucketContstructor();
1003
+ case "token":
1004
+ return new BitbucketContstructor({ auth: { token: params.token } });
1005
+ case "basic":
1006
+ return new BitbucketContstructor({
1007
+ auth: {
1008
+ password: params.password,
1009
+ username: params.username
1010
+ }
1011
+ });
1048
1012
  }
1049
- return getRepositoryRes.defaultBranch.replace("refs/heads/", "");
1050
1013
  }
1051
- async function getAdoReferenceData({
1052
- ref,
1053
- repoUrl,
1054
- accessToken,
1055
- tokenOrg
1056
- }) {
1057
- const { owner, repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
1058
- const api2 = await getAdoApiClient({
1059
- accessToken,
1060
- tokenOrg,
1061
- orgName: owner
1062
- });
1063
- if (!projectName) {
1064
- throw new InvalidUrlPatternError("no project name");
1065
- }
1066
- const git = await api2.getGitApi();
1067
- const results = await Promise.allSettled([
1068
- (async () => {
1069
- const res = await git.getBranch(repo, ref, projectName);
1070
- if (!res.commit || !res.commit.commitId) {
1071
- throw new InvalidRepoUrlError("no commit on branch");
1072
- }
1073
- return {
1074
- sha: res.commit.commitId,
1075
- type: "BRANCH" /* BRANCH */,
1076
- date: res.commit.committer?.date || /* @__PURE__ */ new Date()
1077
- };
1078
- })(),
1079
- (async () => {
1080
- const res = await git.getCommits(
1081
- repo,
1082
- {
1083
- fromCommitId: ref,
1084
- toCommitId: ref,
1085
- $top: 1
1086
- },
1087
- projectName
1014
+ function getBitbucketSdk(params) {
1015
+ const bitbucketClient = getBitbucketIntance(params);
1016
+ return {
1017
+ getAuthType() {
1018
+ return params.authType;
1019
+ },
1020
+ async getRepos(params2) {
1021
+ const repoRes = params2?.workspaceSlug ? await getRepositoriesByWorkspace(bitbucketClient, {
1022
+ workspaceSlug: params2.workspaceSlug
1023
+ }) : await getllUsersrepositories(bitbucketClient);
1024
+ return repoRes.map((repo) => ({
1025
+ repoIsPublic: !repo.is_private,
1026
+ repoName: repo.name || "unknown repo name",
1027
+ repoOwner: repo.owner?.username || "unknown owner",
1028
+ // language can be empty string
1029
+ repoLanguages: repo.language ? [repo.language] : [],
1030
+ repoUpdatedAt: repo.updated_on ? repo.updated_on : (/* @__PURE__ */ new Date()).toISOString(),
1031
+ repoUrl: repo.links?.html?.href || ""
1032
+ }));
1033
+ },
1034
+ async getBranchList(params2) {
1035
+ const { workspace, repoSlug } = parseBitbucketOrganizationAndRepo(
1036
+ params2.repoUrl
1088
1037
  );
1089
- const commit = res[0];
1090
- if (!commit || !commit.commitId) {
1091
- throw new Error("no commit");
1092
- }
1093
- return {
1094
- sha: commit.commitId,
1095
- type: "COMMIT" /* COMMIT */,
1096
- date: commit.committer?.date || /* @__PURE__ */ new Date()
1097
- };
1098
- })(),
1099
- (async () => {
1100
- const res = await git.getRefs(repo, projectName, `tags/${ref}`);
1101
- if (!res[0] || !res[0].objectId) {
1102
- throw new Error("no tag ref");
1038
+ const res = await bitbucketClient.refs.listBranches({
1039
+ repo_slug: repoSlug,
1040
+ workspace
1041
+ });
1042
+ if (!res.data.values) {
1043
+ return [];
1103
1044
  }
1104
- let objectId = res[0].objectId;
1105
- try {
1106
- const tag = await git.getAnnotatedTag(projectName, repo, objectId);
1107
- if (tag.taggedObject?.objectId) {
1108
- objectId = tag.taggedObject.objectId;
1045
+ return res.data.values.filter((branch) => !!branch.name).map((branch) => z3.string().parse(branch.name));
1046
+ },
1047
+ async getIsUserCollaborator(params2) {
1048
+ const { repoUrl } = params2;
1049
+ const { repoSlug, workspace } = parseBitbucketOrganizationAndRepo(repoUrl);
1050
+ const fullRepoName = `${workspace}/${repoSlug}`;
1051
+ const res = await bitbucketClient.user.listPermissionsForRepos({
1052
+ q: `repository.full_name~"${fullRepoName}"`
1053
+ });
1054
+ return res.data.values?.some(
1055
+ (res2) => res2.repository?.full_name === fullRepoName
1056
+ ) ?? false;
1057
+ },
1058
+ async createPullRequest(params2) {
1059
+ const { repoSlug, workspace } = parseBitbucketOrganizationAndRepo(
1060
+ params2.repoUrl
1061
+ );
1062
+ const res = await bitbucketClient.pullrequests.create({
1063
+ repo_slug: repoSlug,
1064
+ workspace,
1065
+ _body: {
1066
+ type: "pullrequest",
1067
+ title: params2.title,
1068
+ summary: {
1069
+ raw: params2.body
1070
+ },
1071
+ source: {
1072
+ branch: {
1073
+ name: params2.sourceBranchName
1074
+ }
1075
+ },
1076
+ destination: {
1077
+ branch: {
1078
+ name: params2.targetBranchName
1079
+ }
1080
+ }
1109
1081
  }
1110
- } catch (e) {
1111
- }
1112
- const commitRes2 = await git.getCommits(
1113
- repo,
1114
- {
1115
- fromCommitId: objectId,
1116
- toCommitId: objectId,
1117
- $top: 1
1118
- },
1119
- projectName
1082
+ });
1083
+ return res.data;
1084
+ },
1085
+ async getDownloadlink(params2) {
1086
+ const { repoSlug, workspace } = parseBitbucketOrganizationAndRepo(
1087
+ params2.repoUrl
1120
1088
  );
1121
- const commit = commitRes2[0];
1122
- if (!commit) {
1123
- throw new Error("no commit");
1124
- }
1125
- return {
1126
- sha: objectId,
1089
+ const res = await bitbucketClient.downloads.list({
1090
+ repo_slug: repoSlug,
1091
+ workspace
1092
+ });
1093
+ return res.data;
1094
+ },
1095
+ async getBranch(params2) {
1096
+ const { repoSlug, workspace } = parseBitbucketOrganizationAndRepo(
1097
+ params2.repoUrl
1098
+ );
1099
+ const res = await bitbucketClient.refs.getBranch({
1100
+ name: params2.branchName,
1101
+ repo_slug: repoSlug,
1102
+ workspace
1103
+ });
1104
+ return res.data;
1105
+ },
1106
+ async getRepo(params2) {
1107
+ const { repoSlug, workspace } = parseBitbucketOrganizationAndRepo(
1108
+ params2.repoUrl
1109
+ );
1110
+ const res = await bitbucketClient.repositories.get({
1111
+ repo_slug: repoSlug,
1112
+ workspace
1113
+ });
1114
+ return res.data;
1115
+ },
1116
+ async getCommit(params2) {
1117
+ const { repoSlug, workspace } = parseBitbucketOrganizationAndRepo(
1118
+ params2.repoUrl
1119
+ );
1120
+ const res = await bitbucketClient.commits.get({
1121
+ commit: params2.commitSha,
1122
+ repo_slug: repoSlug,
1123
+ workspace
1124
+ });
1125
+ return res.data;
1126
+ },
1127
+ async getUser() {
1128
+ const res = await bitbucketClient.user.get({});
1129
+ return res.data;
1130
+ },
1131
+ async getReferenceData({
1132
+ ref,
1133
+ url
1134
+ }) {
1135
+ return Promise.allSettled([
1136
+ this.getTagRef({ repoUrl: url, tagName: ref }),
1137
+ this.getBranchRef({ repoUrl: url, branchName: ref }),
1138
+ this.getCommitRef({ repoUrl: url, commitSha: ref })
1139
+ ]).then((promisesResult) => {
1140
+ const [refPromise] = promisesResult.filter(
1141
+ (promise) => promise.status === "fulfilled"
1142
+ );
1143
+ if (!refPromise) {
1144
+ throw new RefNotFoundError(`Invalid reference ${ref} for ${url}`);
1145
+ }
1146
+ return refPromise.value;
1147
+ });
1148
+ },
1149
+ async getTagRef(params2) {
1150
+ const { tagName, repoUrl } = params2;
1151
+ const { repoSlug, workspace } = parseBitbucketOrganizationAndRepo(repoUrl);
1152
+ const tagRes = await bitbucketClient.refs.getTag({
1153
+ repo_slug: repoSlug,
1154
+ workspace,
1155
+ name: tagName
1156
+ });
1157
+ return GetRefererenceResultZ.parse({
1158
+ sha: tagRes.data.target?.hash,
1127
1159
  type: "TAG" /* TAG */,
1128
- date: commit.committer?.date || /* @__PURE__ */ new Date()
1129
- };
1130
- })()
1131
- ]);
1132
- const [branchRes, commitRes, tagRes] = results;
1133
- if (tagRes.status === "fulfilled") {
1134
- return tagRes.value;
1135
- }
1136
- if (branchRes.status === "fulfilled") {
1137
- return branchRes.value;
1138
- }
1139
- if (commitRes.status === "fulfilled") {
1140
- return commitRes.value;
1141
- }
1142
- throw new RefNotFoundError(`ref: ${ref} does not exist`);
1160
+ date: new Date(z3.string().parse(tagRes.data.target?.date))
1161
+ });
1162
+ },
1163
+ async getBranchRef(params2) {
1164
+ const getBranchRes = await this.getBranch(params2);
1165
+ return GetRefererenceResultZ.parse({
1166
+ sha: getBranchRes.target?.hash,
1167
+ type: "BRANCH" /* BRANCH */,
1168
+ date: new Date(z3.string().parse(getBranchRes.target?.date))
1169
+ });
1170
+ },
1171
+ async getCommitRef(params2) {
1172
+ const getCommitRes = await this.getCommit(params2);
1173
+ return GetRefererenceResultZ.parse({
1174
+ sha: getCommitRes.hash,
1175
+ type: "COMMIT" /* COMMIT */,
1176
+ date: new Date(z3.string().parse(getCommitRes.date))
1177
+ });
1178
+ },
1179
+ async getDownloadUrl({ url, sha }) {
1180
+ this.getReferenceData({ ref: sha, url });
1181
+ const repoRes = await this.getRepo({ repoUrl: url });
1182
+ const parsedRepoUrl = z3.string().url().parse(repoRes.links?.html?.href);
1183
+ return `${parsedRepoUrl}/get/${sha}.zip`;
1184
+ },
1185
+ async getPullRequest(params2) {
1186
+ const { repoSlug, workspace } = parseBitbucketOrganizationAndRepo(
1187
+ params2.url
1188
+ );
1189
+ const res = await bitbucketClient.pullrequests.get({
1190
+ pull_request_id: params2.prNumber,
1191
+ repo_slug: repoSlug,
1192
+ workspace
1193
+ });
1194
+ return res.data;
1195
+ }
1196
+ };
1143
1197
  }
1144
- function parseAdoOwnerAndRepo(adoUrl) {
1145
- adoUrl = removeTrailingSlash(adoUrl);
1146
- const parsingResult = parseScmURL(adoUrl, "Ado" /* Ado */);
1147
- if (!parsingResult || parsingResult.hostname !== "dev.azure.com" && !parsingResult.hostname.endsWith(".visualstudio.com")) {
1148
- throw new InvalidUrlPatternError(`invalid ADO repo URL: ${adoUrl}`);
1198
+ async function validateBitbucketParams(params) {
1199
+ const { bitbucketClient } = params;
1200
+ const authType = bitbucketClient.getAuthType();
1201
+ try {
1202
+ if (authType !== "public") {
1203
+ await bitbucketClient.getUser();
1204
+ }
1205
+ if (params.url && shouldValidateUrl(params.url)) {
1206
+ await bitbucketClient.getRepo({ repoUrl: params.url });
1207
+ }
1208
+ } catch (e) {
1209
+ const safeParseError = TokenExpiredErrorZ.safeParse(e);
1210
+ if (safeParseError.success) {
1211
+ switch (safeParseError.data.status) {
1212
+ case 401:
1213
+ throw new InvalidAccessTokenError(
1214
+ safeParseError.data.error.error.message
1215
+ );
1216
+ case 404:
1217
+ throw new InvalidRepoUrlError(safeParseError.data.error.error.message);
1218
+ }
1219
+ }
1220
+ throw e;
1149
1221
  }
1150
- const { organization, repoName, projectName, projectPath, pathElements } = parsingResult;
1151
- return {
1152
- owner: decodeURI(organization),
1153
- repo: decodeURI(repoName),
1154
- projectName: projectName ? decodeURI(projectName) : void 0,
1155
- projectPath,
1156
- pathElements
1157
- };
1158
1222
  }
1159
- async function getAdoBlameRanges() {
1160
- return [];
1223
+ async function getUsersworkspacesSlugs(bitbucketClient) {
1224
+ const res = await bitbucketClient.workspaces.getWorkspaces({});
1225
+ return res.data.values?.map((v) => z3.string().parse(v.slug));
1161
1226
  }
1162
- var ADO_ACCESS_TOKEN_URL = "https://app.vssps.visualstudio.com/oauth2/token";
1163
- var AdoAuthResultZ = z2.object({
1164
- access_token: z2.string().min(1),
1165
- token_type: z2.string().min(1),
1166
- refresh_token: z2.string().min(1)
1167
- });
1168
- async function getAdoToken({
1169
- token,
1170
- adoClientSecret,
1171
- tokenType,
1172
- redirectUri
1173
- }) {
1174
- const res = await fetch(ADO_ACCESS_TOKEN_URL, {
1175
- method: "POST",
1176
- headers: {
1177
- Accept: "application/json",
1178
- "Content-Type": "application/x-www-form-urlencoded"
1179
- },
1180
- body: querystring.stringify({
1181
- client_assertion_type: "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
1182
- client_assertion: adoClientSecret,
1183
- redirect_uri: redirectUri,
1184
- assertion: token,
1185
- grant_type: tokenType === "code" /* CODE */ ? "urn:ietf:params:oauth:grant-type:jwt-bearer" : "refresh_token"
1186
- })
1227
+ async function getllUsersrepositories(bitbucketClient) {
1228
+ const userWorspacesSlugs = await getUsersworkspacesSlugs(bitbucketClient);
1229
+ if (!userWorspacesSlugs) {
1230
+ return [];
1231
+ }
1232
+ const allWorkspaceRepos = [];
1233
+ for (const workspaceSlug of userWorspacesSlugs) {
1234
+ const repos = await bitbucketClient.repositories.list({
1235
+ workspace: workspaceSlug
1236
+ });
1237
+ if (!repos.data.values) {
1238
+ continue;
1239
+ }
1240
+ allWorkspaceRepos.push(...repos.data.values);
1241
+ }
1242
+ return allWorkspaceRepos;
1243
+ }
1244
+ async function getRepositoriesByWorkspace(bitbucketClient, { workspaceSlug }) {
1245
+ const res = await bitbucketClient.repositories.list({
1246
+ workspace: workspaceSlug
1187
1247
  });
1188
- const authResult = await res.json();
1189
- return AdoAuthResultZ.parse(authResult);
1190
- }
1191
- var AdoSdk = {
1192
- getAdoApiClient,
1193
- adoValidateParams,
1194
- getAdoIsUserCollaborator,
1195
- getAdoPullRequestStatus,
1196
- getAdoIsRemoteBranch,
1197
- getAdoRepoList,
1198
- getAdoDownloadUrl,
1199
- getAdoBranchList,
1200
- createAdoPullRequest,
1201
- getAdoRepoDefaultBranch,
1202
- getAdoReferenceData,
1203
- parseAdoOwnerAndRepo,
1204
- getAdoBlameRanges,
1205
- getAdoToken,
1206
- getAdoTokenType
1207
- };
1208
-
1209
- // src/features/analysis/scm/bitbucket/bitbucket.ts
1210
- import querystring3 from "node:querystring";
1211
- import * as bitbucketPkg from "bitbucket";
1212
- import { z as z8 } from "zod";
1213
-
1214
- // src/features/analysis/scm/scm.ts
1215
- import { z as z7 } from "zod";
1248
+ return res.data.values ?? [];
1249
+ }
1216
1250
 
1217
1251
  // src/features/analysis/scm/github/github.ts
1218
1252
  import { RequestError } from "@octokit/request-error";
@@ -1303,7 +1337,7 @@ function isGithubOnPrem(url) {
1303
1337
  function getFetch(url) {
1304
1338
  if (url && BROKERED_HOSTS.includes(new URL(url).origin)) {
1305
1339
  const dispatcher = new ProxyAgent({
1306
- uri: process.env["GIT_PROXY_HOST"] || "http://tinyproxy:8888",
1340
+ uri: GIT_PROXY_HOST,
1307
1341
  requestTls: {
1308
1342
  rejectUnauthorized: false
1309
1343
  }
@@ -1727,226 +1761,6 @@ import {
1727
1761
  } from "@gitbeaker/rest";
1728
1762
  import { ProxyAgent as ProxyAgent2 } from "undici";
1729
1763
 
1730
- // src/features/analysis/scm/env.ts
1731
- import { z as z3 } from "zod";
1732
- var EnvVariablesZod = z3.object({
1733
- GITLAB_API_TOKEN: z3.string().optional(),
1734
- BROKERED_HOSTS: z3.string().toLowerCase().transform(
1735
- (x) => x.split(",").map((url) => url.trim(), []).filter(Boolean)
1736
- ).default(""),
1737
- GITHUB_API_TOKEN: z3.string().optional()
1738
- });
1739
- var { GITLAB_API_TOKEN, BROKERED_HOSTS, GITHUB_API_TOKEN } = EnvVariablesZod.parse(process.env);
1740
-
1741
- // src/features/analysis/scm/utils/get_issue_type.ts
1742
- var getIssueType = (issueType) => {
1743
- switch (issueType) {
1744
- case "SQL_Injection" /* SqlInjection */:
1745
- return "SQL Injection";
1746
- case "CMDi_relative_path_command" /* CmDiRelativePathCommand */:
1747
- return "Relative Path Command Injection";
1748
- case "CMDi" /* CmDi */:
1749
- return "Command Injection";
1750
- case "XXE" /* Xxe */:
1751
- return "XXE";
1752
- case "XSS" /* Xss */:
1753
- return "XSS";
1754
- case "PT" /* Pt */:
1755
- return "Path Traversal";
1756
- case "ZIP_SLIP" /* ZipSlip */:
1757
- return "Zip Slip";
1758
- case "INSECURE_RANDOMNESS" /* InsecureRandomness */:
1759
- return "Insecure Randomness";
1760
- case "SSRF" /* Ssrf */:
1761
- return "Server Side Request Forgery";
1762
- case "TYPE_CONFUSION" /* TypeConfusion */:
1763
- return "Type Confusion";
1764
- case "REGEX_INJECTION" /* RegexInjection */:
1765
- return "Regular Expression Injection";
1766
- case "INCOMPLETE_URL_SANITIZATION" /* IncompleteUrlSanitization */:
1767
- return "Incomplete URL Sanitization";
1768
- case "LOCALE_DEPENDENT_COMPARISON" /* LocaleDependentComparison */:
1769
- return "Locale Dependent Comparison";
1770
- case "LOG_FORGING" /* LogForging */:
1771
- return "Log Forging";
1772
- case "MISSING_CHECK_AGAINST_NULL" /* MissingCheckAgainstNull */:
1773
- return "Missing Check against Null";
1774
- case "PASSWORD_IN_COMMENT" /* PasswordInComment */:
1775
- return "Password in Comment";
1776
- case "OVERLY_BROAD_CATCH" /* OverlyBroadCatch */:
1777
- return "Poor Error Handling: Overly Broad Catch";
1778
- case "USE_OF_SYSTEM_OUTPUT_STREAM" /* UseOfSystemOutputStream */:
1779
- return "Use of System.out/System.err";
1780
- case "DANGEROUS_FUNCTION_OVERFLOW" /* DangerousFunctionOverflow */:
1781
- return "Use of dangerous function";
1782
- case "DOS_STRING_BUILDER" /* DosStringBuilder */:
1783
- return "Denial of Service: StringBuilder";
1784
- case "OPEN_REDIRECT" /* OpenRedirect */:
1785
- return "Open Redirect";
1786
- case "WEAK_XML_SCHEMA_UNBOUNDED_OCCURRENCES" /* WeakXmlSchemaUnboundedOccurrences */:
1787
- return "Weak XML Schema: Unbounded Occurrences";
1788
- case "SYSTEM_INFORMATION_LEAK" /* SystemInformationLeak */:
1789
- return "System Information Leak";
1790
- case "SYSTEM_INFORMATION_LEAK_EXTERNAL" /* SystemInformationLeakExternal */:
1791
- return "External System Information Leak";
1792
- case "HTTP_RESPONSE_SPLITTING" /* HttpResponseSplitting */:
1793
- return "HTTP response splitting";
1794
- case "HTTP_ONLY_COOKIE" /* HttpOnlyCookie */:
1795
- return "Cookie is not HttpOnly";
1796
- case "INSECURE_COOKIE" /* InsecureCookie */:
1797
- return "Insecure Cookie";
1798
- case "TRUST_BOUNDARY_VIOLATION" /* TrustBoundaryViolation */:
1799
- return "Trust Boundary Violation";
1800
- case "NULL_DEREFERENCE" /* NullDereference */:
1801
- return "Null Dereference";
1802
- case "UNSAFE_DESERIALIZATION" /* UnsafeDeserialization */:
1803
- return "Unsafe deserialization";
1804
- case "INSECURE_BINDER_CONFIGURATION" /* InsecureBinderConfiguration */:
1805
- return "Insecure Binder Configuration";
1806
- case "UNSAFE_TARGET_BLANK" /* UnsafeTargetBlank */:
1807
- return "Unsafe use of target blank";
1808
- case "IFRAME_WITHOUT_SANDBOX" /* IframeWithoutSandbox */:
1809
- return "Client use of iframe without sandbox";
1810
- case "JQUERY_DEPRECATED_SYMBOLS" /* JqueryDeprecatedSymbols */:
1811
- return "jQuery deprecated symbols";
1812
- case "MISSING_ANTIFORGERY_VALIDATION" /* MissingAntiforgeryValidation */:
1813
- return "Missing Anti-Forgery Validation";
1814
- case "GRAPHQL_DEPTH_LIMIT" /* GraphqlDepthLimit */:
1815
- return "GraphQL Depth Limit";
1816
- case "UNCHECKED_LOOP_CONDITION" /* UncheckedLoopCondition */:
1817
- return "Unchecked Loop Condition";
1818
- case "IMPROPER_RESOURCE_SHUTDOWN_OR_RELEASE" /* ImproperResourceShutdownOrRelease */:
1819
- return "Improper Resource Shutdown or Release";
1820
- case "IMPROPER_EXCEPTION_HANDLING" /* ImproperExceptionHandling */:
1821
- return "Improper Exception Handling";
1822
- case "DEFAULT_RIGHTS_IN_OBJ_DEFINITION" /* DefaultRightsInObjDefinition */:
1823
- return "Default Definer Rights in Package or Object Definition";
1824
- case "HTML_COMMENT_IN_JSP" /* HtmlCommentInJsp */:
1825
- return "HTML Comment in JSP";
1826
- case "ERROR_CONDTION_WITHOUT_ACTION" /* ErrorCondtionWithoutAction */:
1827
- return "Error Condition Without Action";
1828
- case "DEPRECATED_FUNCTION" /* DeprecatedFunction */:
1829
- return "Deprecated Function";
1830
- case "HARDCODED_SECRETS" /* HardcodedSecrets */:
1831
- return "Hardcoded Secrets";
1832
- case "PROTOTYPE_POLLUTION" /* PrototypePollution */:
1833
- return "Prototype Pollution";
1834
- case "RACE_CONDITION_FORMAT_FLAW" /* RaceConditionFormatFlaw */:
1835
- return "Race Condition Format Flaw";
1836
- case "NON_FINAL_PUBLIC_STATIC_FIELD" /* NonFinalPublicStaticField */:
1837
- return "Non-final Public Static Field";
1838
- case "MISSING_HSTS_HEADER" /* MissingHstsHeader */:
1839
- return "Missing HSTS Header";
1840
- case "DEAD_CODE_UNUSED_FIELD" /* DeadCodeUnusedField */:
1841
- return "Dead Code: Unused Field";
1842
- case "HEADER_MANIPULATION" /* HeaderManipulation */:
1843
- return "Header Manipulation";
1844
- case "MISSING_EQUALS_OR_HASHCODE" /* MissingEqualsOrHashcode */:
1845
- return "Missing equals or hashcode method";
1846
- case "WCF_MISCONFIGURATION_INSUFFICIENT_LOGGING" /* WcfMisconfigurationInsufficientLogging */:
1847
- return "WCF Misconfiguration: Insufficient Logging";
1848
- case "WCF_MISCONFIGURATION_THROTTLING_NOT_ENABLED" /* WcfMisconfigurationThrottlingNotEnabled */:
1849
- return "WCF Misconfiguration: Throttling Not Enabled";
1850
- case "USELESS_REGEXP_CHAR_ESCAPE" /* UselessRegexpCharEscape */:
1851
- return "Useless regular-expression character escape";
1852
- case "INCOMPLETE_HOSTNAME_REGEX" /* IncompleteHostnameRegex */:
1853
- return "Incomplete Hostname Regex";
1854
- case "OVERLY_LARGE_RANGE" /* OverlyLargeRange */:
1855
- return "Regex: Overly Large Range";
1856
- case "INSUFFICIENT_LOGGING" /* InsufficientLogging */:
1857
- return "Insufficient Logging of Sensitive Operations";
1858
- case "PRIVACY_VIOLATION" /* PrivacyViolation */:
1859
- return "Privacy Violation";
1860
- case "INCOMPLETE_URL_SCHEME_CHECK" /* IncompleteUrlSchemeCheck */:
1861
- return "Incomplete URL Scheme Check";
1862
- case "VALUE_NEVER_READ" /* ValueNeverRead */:
1863
- return "Value Never Read";
1864
- case "VALUE_SHADOWING" /* ValueShadowing */:
1865
- return "Value Shadowing";
1866
- default: {
1867
- return issueType ? issueType.replaceAll("_", " ") : "Other";
1868
- }
1869
- }
1870
- };
1871
-
1872
- // src/features/analysis/scm/utils/index.ts
1873
- function getFixUrlWithRedirect(params) {
1874
- const {
1875
- fixId,
1876
- projectId,
1877
- organizationId,
1878
- analysisId,
1879
- redirectUrl,
1880
- appBaseUrl,
1881
- commentId
1882
- } = params;
1883
- const searchParams = new URLSearchParams();
1884
- searchParams.append("commit_redirect_url", redirectUrl);
1885
- searchParams.append("comment_id", commentId.toString());
1886
- return `${getFixUrl({
1887
- appBaseUrl,
1888
- fixId,
1889
- projectId,
1890
- organizationId,
1891
- analysisId
1892
- })}?${searchParams.toString()}`;
1893
- }
1894
- function getFixUrl({
1895
- appBaseUrl,
1896
- fixId,
1897
- projectId,
1898
- organizationId,
1899
- analysisId
1900
- }) {
1901
- return `${appBaseUrl}/organization/${organizationId}/project/${projectId}/report/${analysisId}/fix/${fixId}`;
1902
- }
1903
- function getCommitUrl(params) {
1904
- const {
1905
- fixId,
1906
- projectId,
1907
- organizationId,
1908
- analysisId,
1909
- redirectUrl,
1910
- appBaseUrl,
1911
- commentId
1912
- } = params;
1913
- const searchParams = new URLSearchParams();
1914
- searchParams.append("redirect_url", redirectUrl);
1915
- searchParams.append("comment_id", commentId.toString());
1916
- return `${getFixUrl({
1917
- appBaseUrl,
1918
- fixId,
1919
- projectId,
1920
- organizationId,
1921
- analysisId
1922
- })}/commit?${searchParams.toString()}`;
1923
- }
1924
- var userNamePattern = /^(https?:\/\/)([^@]+@)?([^/]+\/.+)$/;
1925
- var sshPattern = /^git@([\w.-]+):([\w./-]+)$/;
1926
- function normalizeUrl(repoUrl) {
1927
- let trimmedUrl = repoUrl.trim().replace(/\/+$/, "");
1928
- if (repoUrl.endsWith(".git")) {
1929
- trimmedUrl = trimmedUrl.slice(0, -".git".length);
1930
- }
1931
- const usernameMatch = trimmedUrl.match(userNamePattern);
1932
- if (usernameMatch) {
1933
- const [_all, protocol, _username, repoPath] = usernameMatch;
1934
- trimmedUrl = `${protocol}${repoPath}`;
1935
- }
1936
- const sshMatch = trimmedUrl.match(sshPattern);
1937
- if (sshMatch) {
1938
- const [_all, hostname, reporPath] = sshMatch;
1939
- trimmedUrl = `https://${hostname}/${reporPath}`;
1940
- }
1941
- return trimmedUrl;
1942
- }
1943
- var isUrlHasPath = (url) => {
1944
- return new URL(url).origin !== url;
1945
- };
1946
- function shouldValidateUrl(repoUrl) {
1947
- return repoUrl && isUrlHasPath(repoUrl);
1948
- }
1949
-
1950
1764
  // src/features/analysis/scm/gitlab/types.ts
1951
1765
  import { z as z4 } from "zod";
1952
1766
  var GitlabAuthResultZ = z4.object({
@@ -1956,7 +1770,7 @@ var GitlabAuthResultZ = z4.object({
1956
1770
  });
1957
1771
 
1958
1772
  // src/features/analysis/scm/gitlab/gitlab.ts
1959
- function removeTrailingSlash2(str) {
1773
+ function removeTrailingSlash(str) {
1960
1774
  return str.trim().replace(/\/+$/, "");
1961
1775
  }
1962
1776
  function getGitBeaker(options) {
@@ -2185,7 +1999,7 @@ async function getGitlabReferenceData({ ref, gitlabUrl }, options) {
2185
1999
  throw new RefNotFoundError(`ref: ${ref} does not exist`);
2186
2000
  }
2187
2001
  function parseGitlabOwnerAndRepo(gitlabUrl) {
2188
- gitlabUrl = removeTrailingSlash2(gitlabUrl);
2002
+ gitlabUrl = removeTrailingSlash(gitlabUrl);
2189
2003
  const parsingResult = parseScmURL(gitlabUrl, "GitLab" /* GitLab */);
2190
2004
  if (!parsingResult || !parsingResult.repoName) {
2191
2005
  throw new InvalidUrlPatternError(`invalid gitlab repo Url ${gitlabUrl}`);
@@ -2263,7 +2077,8 @@ var BaseSubmitToScmMessageZ = z5.object({
2263
2077
  })
2264
2078
  ),
2265
2079
  commitHash: z5.string(),
2266
- repoUrl: z5.string()
2080
+ repoUrl: z5.string(),
2081
+ extraHeaders: z5.record(z5.string(), z5.string()).default({})
2267
2082
  });
2268
2083
  var submitToScmMessageType = {
2269
2084
  commitToSameBranch: "commitToSameBranch",
@@ -2532,7 +2347,8 @@ var SCMLib = class {
2532
2347
  }
2533
2348
  const scmLibType = this.getScmLibType();
2534
2349
  if (scmLibType === "ADO" /* ADO */) {
2535
- return `https://${accessToken}@${trimmedUrl.toLowerCase().replace("https://", "")}`;
2350
+ const { host, protocol, pathname } = new URL(trimmedUrl);
2351
+ return `${protocol}//${accessToken}@${host}${pathname}`;
2536
2352
  }
2537
2353
  if (this instanceof BitbucketSCMLib) {
2538
2354
  const authData = this.getAuthData();
@@ -2580,7 +2396,7 @@ var SCMLib = class {
2580
2396
  }
2581
2397
  return this.url.split("/").at(-1) || "";
2582
2398
  }
2583
- _validateToken() {
2399
+ _validateAccessToken() {
2584
2400
  if (!this.accessToken) {
2585
2401
  console.error("no access token");
2586
2402
  throw new Error("no access token");
@@ -2626,14 +2442,12 @@ var SCMLib = class {
2626
2442
  scmLibScmTypeToScmType[z7.nativeEnum(ScmLibScmType).parse(scmType)]
2627
2443
  );
2628
2444
  }
2445
+ console.error(`error validating scm: ${scmType} `, e);
2629
2446
  }
2630
2447
  return new StubSCMLib(trimmedUrl, void 0, void 0);
2631
2448
  }
2632
2449
  _validateAccessTokenAndUrl() {
2633
- if (!this.accessToken) {
2634
- console.error("no access token");
2635
- throw new InvalidAccessTokenError("no access token");
2636
- }
2450
+ this._validateAccessToken();
2637
2451
  this._validateUrl();
2638
2452
  }
2639
2453
  _validateUrl() {
@@ -2643,45 +2457,65 @@ var SCMLib = class {
2643
2457
  }
2644
2458
  }
2645
2459
  };
2460
+ async function initAdoSdk(params) {
2461
+ const { url, accessToken, scmOrg } = params;
2462
+ const adoClientParams = await getAdoClientParams({
2463
+ tokenOrg: scmOrg,
2464
+ accessToken,
2465
+ url
2466
+ });
2467
+ return getAdoSdk(adoClientParams);
2468
+ }
2646
2469
  var AdoSCMLib = class extends SCMLib {
2470
+ constructor(url, accessToken, scmOrg) {
2471
+ super(url, accessToken, scmOrg);
2472
+ __publicField(this, "_adoSdkPromise");
2473
+ this._adoSdkPromise = initAdoSdk({ accessToken, url, scmOrg });
2474
+ }
2475
+ async getAdoSdk() {
2476
+ if (!this._adoSdkPromise) {
2477
+ console.error("ado sdk was not initialized");
2478
+ throw new InvalidAccessTokenError("ado sdk was not initialized");
2479
+ }
2480
+ return this._adoSdkPromise;
2481
+ }
2647
2482
  async createSubmitRequest(params) {
2648
2483
  this._validateAccessTokenAndUrl();
2649
2484
  const { targetBranchName, sourceBranchName, title, body } = params;
2650
- return String(
2651
- await AdoSdk.createAdoPullRequest({
2652
- title,
2653
- body,
2654
- targetBranchName,
2655
- sourceBranchName,
2656
- repoUrl: this.url,
2657
- accessToken: this.accessToken,
2658
- tokenOrg: this.scmOrg
2659
- })
2660
- );
2485
+ const adoSdk = await this.getAdoSdk();
2486
+ const pullRequestId = await adoSdk.createAdoPullRequest({
2487
+ title,
2488
+ body,
2489
+ targetBranchName,
2490
+ sourceBranchName,
2491
+ repoUrl: this.url
2492
+ });
2493
+ return String(pullRequestId);
2661
2494
  }
2662
2495
  async validateParams() {
2663
- return AdoSdk.adoValidateParams({
2496
+ return adoValidateParams({
2664
2497
  url: this.url,
2665
2498
  accessToken: this.accessToken,
2666
2499
  tokenOrg: this.scmOrg
2667
2500
  });
2668
2501
  }
2669
2502
  async getRepoList(scmOrg) {
2670
- if (!this.accessToken) {
2671
- console.error("no access token");
2672
- throw new Error("no access token");
2503
+ this._validateAccessToken();
2504
+ if (this.url && new URL(this.url).origin !== scmCloudUrl.Ado) {
2505
+ throw new Error(
2506
+ `Oauth token is not supported for ADO on prem - ${origin} `
2507
+ );
2673
2508
  }
2674
- return AdoSdk.getAdoRepoList({
2509
+ return getAdoRepoList({
2675
2510
  orgName: scmOrg,
2676
- tokenOrg: this.scmOrg,
2677
- accessToken: this.accessToken
2511
+ accessToken: this.accessToken,
2512
+ tokenOrg: this.scmOrg
2678
2513
  });
2679
2514
  }
2680
2515
  async getBranchList() {
2681
2516
  this._validateAccessTokenAndUrl();
2682
- return AdoSdk.getAdoBranchList({
2683
- accessToken: this.accessToken,
2684
- tokenOrg: this.scmOrg,
2517
+ const adoSdk = await this.getAdoSdk();
2518
+ return adoSdk.getAdoBranchList({
2685
2519
  repoUrl: this.url
2686
2520
  });
2687
2521
  }
@@ -2690,7 +2524,7 @@ var AdoSCMLib = class extends SCMLib {
2690
2524
  }
2691
2525
  getAuthHeaders() {
2692
2526
  if (this.accessToken) {
2693
- if (AdoSdk.getAdoTokenType(this.accessToken) === "OAUTH" /* OAUTH */) {
2527
+ if (getAdoTokenInfo(this.accessToken).type === "OAUTH") {
2694
2528
  return {
2695
2529
  authorization: `Bearer ${this.accessToken}`
2696
2530
  };
@@ -2704,29 +2538,26 @@ var AdoSCMLib = class extends SCMLib {
2704
2538
  }
2705
2539
  return {};
2706
2540
  }
2707
- getDownloadUrl(sha) {
2541
+ async getDownloadUrl(sha) {
2708
2542
  this._validateUrl();
2709
- return Promise.resolve(
2710
- AdoSdk.getAdoDownloadUrl({ repoUrl: this.url, branch: sha })
2711
- );
2543
+ const adoSdk = await this.getAdoSdk();
2544
+ return adoSdk.getAdoDownloadUrl({ repoUrl: this.url, branch: sha });
2712
2545
  }
2713
2546
  async _getUsernameForAuthUrl() {
2714
2547
  throw new Error("_getUsernameForAuthUrl() is not relevant for ADO");
2715
2548
  }
2716
2549
  async getIsRemoteBranch(branch) {
2717
2550
  this._validateAccessTokenAndUrl();
2718
- return AdoSdk.getAdoIsRemoteBranch({
2719
- accessToken: this.accessToken,
2720
- tokenOrg: this.scmOrg,
2551
+ const adoSdk = await this.getAdoSdk();
2552
+ return adoSdk.getAdoIsRemoteBranch({
2721
2553
  repoUrl: this.url,
2722
2554
  branch
2723
2555
  });
2724
2556
  }
2725
2557
  async getUserHasAccessToRepo() {
2726
2558
  this._validateAccessTokenAndUrl();
2727
- return AdoSdk.getAdoIsUserCollaborator({
2728
- accessToken: this.accessToken,
2729
- tokenOrg: this.scmOrg,
2559
+ const adoSdk = await this.getAdoSdk();
2560
+ return adoSdk.getAdoIsUserCollaborator({
2730
2561
  repoUrl: this.url
2731
2562
  });
2732
2563
  }
@@ -2735,46 +2566,48 @@ var AdoSCMLib = class extends SCMLib {
2735
2566
  }
2736
2567
  async getSubmitRequestStatus(scmSubmitRequestId) {
2737
2568
  this._validateAccessTokenAndUrl();
2738
- const state = await AdoSdk.getAdoPullRequestStatus({
2739
- accessToken: this.accessToken,
2740
- tokenOrg: this.scmOrg,
2569
+ const adoSdk = await this.getAdoSdk();
2570
+ const state = await adoSdk.getAdoPullRequestStatus({
2741
2571
  repoUrl: this.url,
2742
2572
  prNumber: Number(scmSubmitRequestId)
2743
2573
  });
2744
2574
  switch (state) {
2745
- case "completed" /* completed */:
2575
+ case 3 /* Completed */:
2746
2576
  return "merged";
2747
- case "active" /* active */:
2577
+ case 1 /* Active */:
2748
2578
  return "open";
2749
- case "abandoned" /* abandoned */:
2579
+ case 2 /* Abandoned */:
2750
2580
  return "closed";
2751
2581
  default:
2752
2582
  throw new Error(`unknown state ${state}`);
2753
2583
  }
2754
2584
  }
2755
2585
  async getRepoBlameRanges(_ref, _path) {
2756
- return await AdoSdk.getAdoBlameRanges();
2586
+ const adoSdk = await this.getAdoSdk();
2587
+ return await adoSdk.getAdoBlameRanges();
2757
2588
  }
2758
2589
  async getReferenceData(ref) {
2759
2590
  this._validateUrl();
2760
- return await AdoSdk.getAdoReferenceData({
2591
+ const adoSdk = await this.getAdoSdk();
2592
+ return await adoSdk.getAdoReferenceData({
2761
2593
  ref,
2762
- repoUrl: this.url,
2763
- accessToken: this.accessToken,
2764
- tokenOrg: this.scmOrg
2594
+ repoUrl: this.url
2765
2595
  });
2766
2596
  }
2767
2597
  async getRepoDefaultBranch() {
2768
2598
  this._validateUrl();
2769
- return await AdoSdk.getAdoRepoDefaultBranch({
2770
- repoUrl: this.url,
2771
- tokenOrg: this.scmOrg,
2772
- accessToken: this.accessToken
2599
+ const adoSdk = await this.getAdoSdk();
2600
+ return await adoSdk.getAdoRepoDefaultBranch({
2601
+ repoUrl: this.url
2773
2602
  });
2774
2603
  }
2775
- getPrUrl(prNumber) {
2776
- this._validateAccessTokenAndUrl();
2777
- return Promise.resolve(getAdoPrUrl({ prNumber, url: this.url }));
2604
+ async getPrUrl(prNumber) {
2605
+ this._validateUrl();
2606
+ const adoSdk = await this.getAdoSdk();
2607
+ return adoSdk.getAdoPrUrl({
2608
+ url: this.url,
2609
+ prNumber
2610
+ });
2778
2611
  }
2779
2612
  };
2780
2613
  var GitlabSCMLib = class extends SCMLib {
@@ -2937,7 +2770,7 @@ var GithubSCMLib = class extends SCMLib {
2937
2770
  return String(pullRequestResult.data.number);
2938
2771
  }
2939
2772
  async forkRepo(repoUrl) {
2940
- this._validateToken();
2773
+ this._validateAccessToken();
2941
2774
  return this.githubSdk.forkRepo({
2942
2775
  repoUrl
2943
2776
  });
@@ -3017,7 +2850,7 @@ var GithubSCMLib = class extends SCMLib {
3017
2850
  return z7.string().parse(prRes.data);
3018
2851
  }
3019
2852
  async getRepoList(_scmOrg) {
3020
- this._validateToken();
2853
+ this._validateAccessToken();
3021
2854
  return this.githubSdk.getGithubRepoList();
3022
2855
  }
3023
2856
  async getBranchList() {
@@ -3060,7 +2893,7 @@ var GithubSCMLib = class extends SCMLib {
3060
2893
  });
3061
2894
  }
3062
2895
  async getUsername() {
3063
- this._validateToken();
2896
+ this._validateAccessToken();
3064
2897
  return this.githubSdk.getGithubUsername();
3065
2898
  }
3066
2899
  async getSubmitRequestStatus(scmSubmitRequestId) {
@@ -3236,7 +3069,7 @@ var BitbucketSCMLib = class extends SCMLib {
3236
3069
  const authType = this.bitbucketSdk.getAuthType();
3237
3070
  switch (authType) {
3238
3071
  case "basic": {
3239
- this._validateToken();
3072
+ this._validateAccessToken();
3240
3073
  const { username, password } = getUserAndPassword(this.accessToken);
3241
3074
  return { username, password, authType };
3242
3075
  }
@@ -3262,7 +3095,7 @@ var BitbucketSCMLib = class extends SCMLib {
3262
3095
  });
3263
3096
  }
3264
3097
  async getRepoList(scmOrg) {
3265
- this._validateToken();
3098
+ this._validateAccessToken();
3266
3099
  return this.bitbucketSdk.getRepos({
3267
3100
  workspaceSlug: scmOrg
3268
3101
  });
@@ -3284,7 +3117,7 @@ var BitbucketSCMLib = class extends SCMLib {
3284
3117
  case "token":
3285
3118
  return { authorization: `Bearer ${this.accessToken}` };
3286
3119
  case "basic": {
3287
- this._validateToken();
3120
+ this._validateAccessToken();
3288
3121
  const { username, password } = getUserAndPassword(this.accessToken);
3289
3122
  return {
3290
3123
  authorization: `Basic ${Buffer.from(
@@ -3323,7 +3156,7 @@ var BitbucketSCMLib = class extends SCMLib {
3323
3156
  return this.bitbucketSdk.getIsUserCollaborator({ repoUrl: this.url });
3324
3157
  }
3325
3158
  async getUsername() {
3326
- this._validateToken();
3159
+ this._validateAccessToken();
3327
3160
  const res = await this.bitbucketSdk.getUser();
3328
3161
  return z7.string().parse(res.username);
3329
3162
  }
@@ -3375,309 +3208,516 @@ var BitbucketSCMLib = class extends SCMLib {
3375
3208
  }
3376
3209
  };
3377
3210
 
3378
- // src/features/analysis/scm/bitbucket/bitbucket.ts
3379
- var { Bitbucket } = bitbucketPkg;
3380
- var BITBUCKET_HOSTNAME = "bitbucket.org";
3381
- var TokenExpiredErrorZ = z8.object({
3382
- status: z8.number(),
3383
- error: z8.object({
3384
- type: z8.string(),
3385
- error: z8.object({
3386
- message: z8.string()
3387
- })
3388
- })
3211
+ // src/features/analysis/scm/ado/validation.ts
3212
+ import { z as z8 } from "zod";
3213
+ var ValidPullRequestStatusZ = z8.union([
3214
+ z8.literal(1 /* Active */),
3215
+ z8.literal(2 /* Abandoned */),
3216
+ z8.literal(3 /* Completed */)
3217
+ ]);
3218
+ var AdoAuthResultZ = z8.object({
3219
+ access_token: z8.string().min(1),
3220
+ token_type: z8.string().min(1),
3221
+ refresh_token: z8.string().min(1)
3389
3222
  });
3390
- var BITBUCKET_ACCESS_TOKEN_URL = `https://${BITBUCKET_HOSTNAME}/site/oauth2/access_token`;
3391
- var BitbucketAuthResultZ = z8.object({
3392
- access_token: z8.string(),
3393
- token_type: z8.string(),
3394
- refresh_token: z8.string()
3223
+ var profileZ = z8.object({
3224
+ displayName: z8.string(),
3225
+ publicAlias: z8.string().min(1),
3226
+ emailAddress: z8.string(),
3227
+ coreRevision: z8.number(),
3228
+ timeStamp: z8.string(),
3229
+ id: z8.string(),
3230
+ revision: z8.number()
3395
3231
  });
3396
- var BitbucketParseResultZ = z8.object({
3397
- organization: z8.string(),
3398
- repoName: z8.string(),
3399
- hostname: z8.literal(BITBUCKET_HOSTNAME)
3232
+ var accountsZ = z8.object({
3233
+ count: z8.number(),
3234
+ value: z8.array(
3235
+ z8.object({
3236
+ accountId: z8.string(),
3237
+ accountUri: z8.string(),
3238
+ accountName: z8.string()
3239
+ })
3240
+ )
3400
3241
  });
3401
- function parseBitbucketOrganizationAndRepo(bitbucketUrl) {
3402
- const parsedGitHubUrl = normalizeUrl(bitbucketUrl);
3403
- const parsingResult = parseScmURL(parsedGitHubUrl, "Bitbucket" /* Bitbucket */);
3404
- const validatedBitbucketResult = BitbucketParseResultZ.parse(parsingResult);
3405
- return {
3406
- workspace: validatedBitbucketResult.organization,
3407
- repoSlug: validatedBitbucketResult.repoName
3242
+
3243
+ // src/features/analysis/scm/ado/utils.ts
3244
+ function _getPublicAdoClient({
3245
+ orgName,
3246
+ origin: origin2
3247
+ }) {
3248
+ const orgUrl = `${origin2}/${orgName}`;
3249
+ const authHandler = api.getPersonalAccessTokenHandler("");
3250
+ authHandler.canHandleAuthentication = () => false;
3251
+ authHandler.prepareRequest = (_options) => {
3252
+ return;
3408
3253
  };
3254
+ const connection = new api.WebApi(orgUrl, authHandler);
3255
+ return connection;
3409
3256
  }
3410
- async function getBitbucketToken(params) {
3411
- const { bitbucketClientId, bitbucketClientSecret, authType } = params;
3412
- const res = await fetch(BITBUCKET_ACCESS_TOKEN_URL, {
3413
- method: "POST",
3414
- headers: {
3415
- "Content-Type": "application/x-www-form-urlencoded",
3416
- Authorization: "Basic " + btoa(`${bitbucketClientId}:${bitbucketClientSecret}`)
3417
- },
3418
- body: querystring3.stringify(
3419
- authType === "refresh_token" ? {
3420
- grant_type: authType,
3421
- refresh_token: params.refreshToken
3422
- } : {
3423
- grant_type: authType,
3424
- code: params.code
3425
- }
3426
- )
3427
- });
3428
- const authResult = await res.json();
3429
- return BitbucketAuthResultZ.parse(authResult);
3257
+ function removeTrailingSlash2(str) {
3258
+ return str.trim().replace(/\/+$/, "");
3430
3259
  }
3431
- function getBitbucketIntance(params) {
3432
- switch (params.authType) {
3433
- case "public":
3434
- return new Bitbucket();
3435
- case "token":
3436
- return new Bitbucket({ auth: { token: params.token } });
3437
- case "basic":
3438
- return new Bitbucket({
3439
- auth: {
3440
- password: params.password,
3441
- username: params.username
3442
- }
3443
- });
3260
+ function parseAdoOwnerAndRepo(adoUrl) {
3261
+ adoUrl = removeTrailingSlash2(adoUrl);
3262
+ const parsingResult = parseScmURL(adoUrl, "Ado" /* Ado */);
3263
+ if (!parsingResult) {
3264
+ throw new InvalidUrlPatternError(`
3265
+ : ${adoUrl}`);
3444
3266
  }
3445
- }
3446
- function getBitbucketSdk(params) {
3447
- const bitbucketClient = getBitbucketIntance(params);
3267
+ const {
3268
+ organization,
3269
+ repoName,
3270
+ projectName,
3271
+ projectPath,
3272
+ pathElements,
3273
+ hostname,
3274
+ protocol
3275
+ } = parsingResult;
3448
3276
  return {
3449
- getAuthType() {
3450
- return params.authType;
3451
- },
3452
- async getRepos(params2) {
3453
- const repoRes = params2?.workspaceSlug ? await getRepositoriesByWorkspace(bitbucketClient, {
3454
- workspaceSlug: params2.workspaceSlug
3455
- }) : await getllUsersrepositories(bitbucketClient);
3456
- return repoRes.map((repo) => ({
3457
- repoIsPublic: !repo.is_private,
3458
- repoName: repo.name || "unknown repo name",
3459
- repoOwner: repo.owner?.username || "unknown owner",
3460
- // language can be empty string
3461
- repoLanguages: repo.language ? [repo.language] : [],
3462
- repoUpdatedAt: repo.updated_on ? repo.updated_on : (/* @__PURE__ */ new Date()).toISOString(),
3463
- repoUrl: repo.links?.html?.href || ""
3464
- }));
3465
- },
3466
- async getBranchList(params2) {
3467
- const { workspace, repoSlug } = parseBitbucketOrganizationAndRepo(
3468
- params2.repoUrl
3469
- );
3470
- const res = await bitbucketClient.refs.listBranches({
3471
- repo_slug: repoSlug,
3472
- workspace
3473
- });
3474
- if (!res.data.values) {
3475
- return [];
3476
- }
3477
- return res.data.values.filter((branch) => !!branch.name).map((branch) => z8.string().parse(branch.name));
3478
- },
3479
- async getIsUserCollaborator(params2) {
3480
- const { repoUrl } = params2;
3481
- const { repoSlug, workspace } = parseBitbucketOrganizationAndRepo(repoUrl);
3482
- const fullRepoName = `${workspace}/${repoSlug}`;
3483
- const res = await bitbucketClient.user.listPermissionsForRepos({
3484
- q: `repository.full_name~"${fullRepoName}"`
3485
- });
3486
- return res.data.values?.some(
3487
- (res2) => res2.repository?.full_name === fullRepoName
3488
- ) ?? false;
3489
- },
3490
- async createPullRequest(params2) {
3491
- const { repoSlug, workspace } = parseBitbucketOrganizationAndRepo(
3492
- params2.repoUrl
3493
- );
3494
- const res = await bitbucketClient.pullrequests.create({
3495
- repo_slug: repoSlug,
3496
- workspace,
3497
- _body: {
3498
- type: "pullrequest",
3499
- title: params2.title,
3500
- summary: {
3501
- raw: params2.body
3502
- },
3503
- source: {
3504
- branch: {
3505
- name: params2.sourceBranchName
3506
- }
3507
- },
3508
- destination: {
3509
- branch: {
3510
- name: params2.targetBranchName
3511
- }
3512
- }
3513
- }
3514
- });
3515
- return res.data;
3516
- },
3517
- async getDownloadlink(params2) {
3518
- const { repoSlug, workspace } = parseBitbucketOrganizationAndRepo(
3519
- params2.repoUrl
3520
- );
3521
- const res = await bitbucketClient.downloads.list({
3522
- repo_slug: repoSlug,
3523
- workspace
3524
- });
3525
- return res.data;
3526
- },
3527
- async getBranch(params2) {
3528
- const { repoSlug, workspace } = parseBitbucketOrganizationAndRepo(
3529
- params2.repoUrl
3530
- );
3531
- const res = await bitbucketClient.refs.getBranch({
3532
- name: params2.branchName,
3533
- repo_slug: repoSlug,
3534
- workspace
3277
+ owner: decodeURI(organization),
3278
+ repo: decodeURI(repoName),
3279
+ projectName: projectName ? decodeURI(projectName) : void 0,
3280
+ projectPath,
3281
+ pathElements,
3282
+ origin: `${protocol}//${hostname}`
3283
+ };
3284
+ }
3285
+ async function getAdoConnectData({
3286
+ url,
3287
+ tokenOrg,
3288
+ adoTokenInfo
3289
+ }) {
3290
+ if (url && new URL(url).origin !== url) {
3291
+ const { owner, origin: origin2 } = parseAdoOwnerAndRepo(url);
3292
+ return {
3293
+ org: owner,
3294
+ origin: origin2
3295
+ };
3296
+ }
3297
+ if (!tokenOrg) {
3298
+ if (adoTokenInfo.type === "OAUTH" /* OAUTH */) {
3299
+ const [org] = await _getOrgsForOauthToken({
3300
+ oauthToken: adoTokenInfo.accessToken
3535
3301
  });
3536
- return res.data;
3537
- },
3538
- async getRepo(params2) {
3539
- const { repoSlug, workspace } = parseBitbucketOrganizationAndRepo(
3540
- params2.repoUrl
3302
+ return {
3303
+ org: z9.string().parse(org),
3304
+ origin: DEFUALT_ADO_ORIGIN
3305
+ };
3306
+ }
3307
+ throw new InvalidRepoUrlError("ADO URL is null");
3308
+ }
3309
+ return {
3310
+ org: tokenOrg,
3311
+ origin: DEFUALT_ADO_ORIGIN
3312
+ };
3313
+ }
3314
+ async function getAdoApiClient(params) {
3315
+ const { origin: origin2 = DEFUALT_ADO_ORIGIN, orgName } = params;
3316
+ if (params.tokenType === "NONE" /* NONE */ || // move to public client if the token is not associated with the PAT org
3317
+ params.tokenType === "PAT" /* PAT */ && params.patTokenOrg !== orgName) {
3318
+ return _getPublicAdoClient({ orgName, origin: origin2 });
3319
+ }
3320
+ const orgUrl = `${origin2}/${orgName}`;
3321
+ if (params.tokenType === "OAUTH" /* OAUTH */) {
3322
+ if (origin2 !== DEFUALT_ADO_ORIGIN) {
3323
+ throw new Error(
3324
+ `Oauth token is not supported for ADO on prem - ${origin2} `
3541
3325
  );
3542
- const res = await bitbucketClient.repositories.get({
3543
- repo_slug: repoSlug,
3544
- workspace
3545
- });
3546
- return res.data;
3326
+ }
3327
+ const connection2 = new api.WebApi(
3328
+ orgUrl,
3329
+ api.getBearerHandler(params.accessToken),
3330
+ {}
3331
+ );
3332
+ return connection2;
3333
+ }
3334
+ const authHandler = api.getPersonalAccessTokenHandler(params.accessToken);
3335
+ const isBroker = BROKERED_HOSTS.includes(new URL(orgUrl).origin);
3336
+ const connection = new api.WebApi(
3337
+ orgUrl,
3338
+ authHandler,
3339
+ isBroker ? {
3340
+ proxy: {
3341
+ proxyUrl: GIT_PROXY_HOST
3342
+ },
3343
+ ignoreSslError: true
3344
+ } : void 0
3345
+ );
3346
+ return connection;
3347
+ }
3348
+ function getAdoTokenInfo(token) {
3349
+ if (!token) {
3350
+ return { type: "NONE" /* NONE */ };
3351
+ }
3352
+ if (token.includes(".")) {
3353
+ return { type: "OAUTH" /* OAUTH */, accessToken: token };
3354
+ }
3355
+ return { type: "PAT" /* PAT */, accessToken: token };
3356
+ }
3357
+ async function getAdoClientParams(params) {
3358
+ const { url, accessToken, tokenOrg } = params;
3359
+ const adoTokenInfo = getAdoTokenInfo(accessToken);
3360
+ const { org, origin: origin2 } = await getAdoConnectData({
3361
+ url,
3362
+ tokenOrg,
3363
+ adoTokenInfo
3364
+ });
3365
+ switch (adoTokenInfo.type) {
3366
+ case "NONE" /* NONE */:
3367
+ return {
3368
+ tokenType: "NONE" /* NONE */,
3369
+ origin: origin2,
3370
+ orgName: org.toLowerCase()
3371
+ };
3372
+ case "OAUTH" /* OAUTH */: {
3373
+ return {
3374
+ tokenType: "OAUTH" /* OAUTH */,
3375
+ accessToken: adoTokenInfo.accessToken,
3376
+ origin: origin2,
3377
+ orgName: org.toLowerCase()
3378
+ };
3379
+ }
3380
+ case "PAT" /* PAT */: {
3381
+ return {
3382
+ tokenType: "PAT" /* PAT */,
3383
+ accessToken: adoTokenInfo.accessToken,
3384
+ patTokenOrg: z9.string().parse(tokenOrg).toLowerCase(),
3385
+ origin: origin2,
3386
+ orgName: org.toLowerCase()
3387
+ };
3388
+ }
3389
+ }
3390
+ }
3391
+ async function adoValidateParams({
3392
+ url,
3393
+ accessToken,
3394
+ tokenOrg
3395
+ }) {
3396
+ try {
3397
+ const api2 = await getAdoApiClient(
3398
+ await getAdoClientParams({ url, accessToken, tokenOrg })
3399
+ );
3400
+ await api2.connect();
3401
+ } catch (e) {
3402
+ console.log("adoValidateParams error", e);
3403
+ const error = e;
3404
+ const code = error.code || error.status || error.statusCode || error.response?.status || error.response?.statusCode || error.response?.code;
3405
+ const description = error.description || `${e}`;
3406
+ if (code === 401 || code === 403 || description.includes("401") || description.includes("403")) {
3407
+ throw new InvalidAccessTokenError(`invalid ADO access token`);
3408
+ }
3409
+ if (code === 404 || description.includes("404") || description.includes("Not Found")) {
3410
+ throw new InvalidRepoUrlError(`invalid ADO repo URL ${url}`);
3411
+ }
3412
+ throw e;
3413
+ }
3414
+ }
3415
+ async function _getOrgsForOauthToken({
3416
+ oauthToken
3417
+ }) {
3418
+ const profileRes = await fetch(
3419
+ "https://app.vssps.visualstudio.com/_apis/profile/profiles/me?api-version=6.0",
3420
+ {
3421
+ method: "GET",
3422
+ headers: {
3423
+ Authorization: `Bearer ${oauthToken}`
3424
+ }
3425
+ }
3426
+ );
3427
+ const profileJson = await profileRes.json();
3428
+ const profile = profileZ.parse(profileJson);
3429
+ const accountsRes = await fetch(
3430
+ `https://app.vssps.visualstudio.com/_apis/accounts?memberId=${profile.publicAlias}&api-version=6.0`,
3431
+ {
3432
+ method: "GET",
3433
+ headers: {
3434
+ Authorization: `Bearer ${oauthToken}`
3435
+ }
3436
+ }
3437
+ );
3438
+ const accountsJson = await accountsRes.json();
3439
+ const accounts = accountsZ.parse(accountsJson);
3440
+ const orgs = accounts.value.map((account) => account.accountName).filter((value, index, array) => array.indexOf(value) === index);
3441
+ return orgs;
3442
+ }
3443
+
3444
+ // src/features/analysis/scm/ado/ado.ts
3445
+ async function getAdoSdk(params) {
3446
+ const api2 = await getAdoApiClient(params);
3447
+ return {
3448
+ async getAdoIsUserCollaborator({ repoUrl }) {
3449
+ try {
3450
+ const { repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
3451
+ const git = await api2.getGitApi();
3452
+ const branches = await git.getBranches(repo, projectName);
3453
+ if (!branches || branches.length === 0) {
3454
+ throw new InvalidRepoUrlError("no branches");
3455
+ }
3456
+ return true;
3457
+ } catch (e) {
3458
+ return false;
3459
+ }
3547
3460
  },
3548
- async getCommit(params2) {
3549
- const { repoSlug, workspace } = parseBitbucketOrganizationAndRepo(
3550
- params2.repoUrl
3461
+ async getAdoPullRequestStatus({
3462
+ repoUrl,
3463
+ prNumber
3464
+ }) {
3465
+ const { repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
3466
+ const git = await api2.getGitApi();
3467
+ const res = await git.getPullRequest(repo, prNumber, projectName);
3468
+ const parsedPullRequestStatus = ValidPullRequestStatusZ.safeParse(
3469
+ res.status
3551
3470
  );
3552
- const res = await bitbucketClient.commits.get({
3553
- commit: params2.commitSha,
3554
- repo_slug: repoSlug,
3555
- workspace
3556
- });
3557
- return res.data;
3558
- },
3559
- async getUser() {
3560
- const res = await bitbucketClient.user.get({});
3561
- return res.data;
3471
+ if (!parsedPullRequestStatus.success) {
3472
+ throw new Error("bad pr status for ADO");
3473
+ }
3474
+ return parsedPullRequestStatus.data;
3562
3475
  },
3563
- async getReferenceData({
3564
- ref,
3565
- url
3476
+ async getAdoIsRemoteBranch({
3477
+ repoUrl,
3478
+ branch
3566
3479
  }) {
3567
- return Promise.allSettled([
3568
- this.getTagRef({ repoUrl: url, tagName: ref }),
3569
- this.getBranchRef({ repoUrl: url, branchName: ref }),
3570
- this.getCommitRef({ repoUrl: url, commitSha: ref })
3571
- ]).then((promisesResult) => {
3572
- const [refPromise] = promisesResult.filter(
3573
- (promise) => promise.status === "fulfilled"
3574
- );
3575
- if (!refPromise) {
3576
- throw new RefNotFoundError(`Invalid reference ${ref} for ${url}`);
3480
+ const { repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
3481
+ const git = await api2.getGitApi();
3482
+ try {
3483
+ const branchStatus = await git.getBranch(repo, branch, projectName);
3484
+ if (!branchStatus || !branchStatus.commit) {
3485
+ throw new InvalidRepoUrlError("no branch status");
3577
3486
  }
3578
- return refPromise.value;
3579
- });
3487
+ return branchStatus.name === branch;
3488
+ } catch (e) {
3489
+ return false;
3490
+ }
3580
3491
  },
3581
- async getTagRef(params2) {
3582
- const { tagName, repoUrl } = params2;
3583
- const { repoSlug, workspace } = parseBitbucketOrganizationAndRepo(repoUrl);
3584
- const tagRes = await bitbucketClient.refs.getTag({
3585
- repo_slug: repoSlug,
3586
- workspace,
3587
- name: tagName
3588
- });
3589
- return GetRefererenceResultZ.parse({
3590
- sha: tagRes.data.target?.hash,
3591
- type: "TAG" /* TAG */,
3592
- date: new Date(z8.string().parse(tagRes.data.target?.date))
3593
- });
3492
+ async getAdoPrUrl({ url, prNumber }) {
3493
+ const { repo, projectName } = parseAdoOwnerAndRepo(url);
3494
+ const git = await api2.getGitApi();
3495
+ const getRepositoryRes = await git.getRepository(
3496
+ decodeURI(repo),
3497
+ projectName ? decodeURI(projectName) : void 0
3498
+ );
3499
+ return `${getRepositoryRes.webUrl}/pullrequest/${prNumber}`;
3594
3500
  },
3595
- async getBranchRef(params2) {
3596
- const getBranchRes = await this.getBranch(params2);
3597
- return GetRefererenceResultZ.parse({
3598
- sha: getBranchRes.target?.hash,
3599
- type: "BRANCH" /* BRANCH */,
3600
- date: new Date(z8.string().parse(getBranchRes.target?.date))
3601
- });
3501
+ getAdoDownloadUrl({
3502
+ repoUrl,
3503
+ branch
3504
+ }) {
3505
+ const { owner, repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
3506
+ const url = new URL(repoUrl);
3507
+ const origin2 = url.origin.toLowerCase().endsWith(".visualstudio.com") ? DEFUALT_ADO_ORIGIN : url.origin.toLowerCase();
3508
+ return `${origin2}/${owner}/${projectName}/_apis/git/repositories/${repo}/items/items?path=/&versionDescriptor[versionOptions]=0&versionDescriptor[versionType]=commit&versionDescriptor[version]=${branch}&resolveLfs=true&$format=zip&api-version=5.0&download=true`;
3602
3509
  },
3603
- async getCommitRef(params2) {
3604
- const getCommitRes = await this.getCommit(params2);
3605
- return GetRefererenceResultZ.parse({
3606
- sha: getCommitRes.hash,
3607
- type: "COMMIT" /* COMMIT */,
3608
- date: new Date(z8.string().parse(getCommitRes.date))
3609
- });
3510
+ async getAdoBranchList({ repoUrl }) {
3511
+ const { repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
3512
+ const git = await api2.getGitApi();
3513
+ try {
3514
+ const res = await git.getBranches(repo, projectName);
3515
+ res.sort((a, b) => {
3516
+ if (!a.commit?.committer?.date || !b.commit?.committer?.date) {
3517
+ return 0;
3518
+ }
3519
+ return b.commit?.committer?.date.getTime() - a.commit?.committer?.date.getTime();
3520
+ });
3521
+ return res.reduce((acc, branch) => {
3522
+ if (!branch.name) {
3523
+ return acc;
3524
+ }
3525
+ acc.push(branch.name);
3526
+ return acc;
3527
+ }, []);
3528
+ } catch (e) {
3529
+ return [];
3530
+ }
3610
3531
  },
3611
- async getDownloadUrl({ url, sha }) {
3612
- this.getReferenceData({ ref: sha, url });
3613
- const repoRes = await this.getRepo({ repoUrl: url });
3614
- const parsedRepoUrl = z8.string().url().parse(repoRes.links?.html?.href);
3615
- return `${parsedRepoUrl}/get/${sha}.zip`;
3532
+ async createAdoPullRequest(options) {
3533
+ const { repoUrl, sourceBranchName, targetBranchName, title, body } = options;
3534
+ const { repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
3535
+ const git = await api2.getGitApi();
3536
+ const res = await git.createPullRequest(
3537
+ {
3538
+ sourceRefName: `refs/heads/${sourceBranchName}`,
3539
+ targetRefName: `refs/heads/${targetBranchName}`,
3540
+ title,
3541
+ description: body
3542
+ },
3543
+ repo,
3544
+ projectName
3545
+ );
3546
+ return res.pullRequestId;
3616
3547
  },
3617
- async getPullRequest(params2) {
3618
- const { repoSlug, workspace } = parseBitbucketOrganizationAndRepo(
3619
- params2.url
3548
+ async getAdoRepoDefaultBranch({
3549
+ repoUrl
3550
+ }) {
3551
+ const { repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
3552
+ const git = await api2.getGitApi();
3553
+ const getRepositoryRes = await git.getRepository(
3554
+ decodeURI(repo),
3555
+ projectName ? decodeURI(projectName) : void 0
3620
3556
  );
3621
- const res = await bitbucketClient.pullrequests.get({
3622
- pull_request_id: params2.prNumber,
3623
- repo_slug: repoSlug,
3624
- workspace
3625
- });
3626
- return res.data;
3627
- }
3628
- };
3629
- }
3630
- async function validateBitbucketParams(params) {
3631
- const { bitbucketClient } = params;
3632
- const authType = bitbucketClient.getAuthType();
3633
- try {
3634
- if (authType !== "public") {
3635
- await bitbucketClient.getUser();
3636
- }
3637
- if (params.url && shouldValidateUrl(params.url)) {
3638
- await bitbucketClient.getRepo({ repoUrl: params.url });
3639
- }
3640
- } catch (e) {
3641
- const safeParseError = TokenExpiredErrorZ.safeParse(e);
3642
- if (safeParseError.success) {
3643
- switch (safeParseError.data.status) {
3644
- case 401:
3645
- throw new InvalidAccessTokenError(
3646
- safeParseError.data.error.error.message
3557
+ if (!getRepositoryRes?.defaultBranch) {
3558
+ throw new InvalidRepoUrlError("no default branch");
3559
+ }
3560
+ return getRepositoryRes.defaultBranch.replace("refs/heads/", "");
3561
+ },
3562
+ // todo: refactor this function
3563
+ async getAdoReferenceData({
3564
+ ref,
3565
+ repoUrl
3566
+ }) {
3567
+ const { repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
3568
+ if (!projectName) {
3569
+ throw new InvalidUrlPatternError("no project name");
3570
+ }
3571
+ const git = await api2.getGitApi();
3572
+ const results = await Promise.allSettled([
3573
+ (async () => {
3574
+ const res = await git.getBranch(repo, ref, projectName);
3575
+ if (!res.commit || !res.commit.commitId) {
3576
+ throw new InvalidRepoUrlError("no commit on branch");
3577
+ }
3578
+ return {
3579
+ sha: res.commit.commitId,
3580
+ type: "BRANCH" /* BRANCH */,
3581
+ date: res.commit.committer?.date || /* @__PURE__ */ new Date()
3582
+ };
3583
+ })(),
3584
+ (async () => {
3585
+ const res = await git.getCommits(
3586
+ repo,
3587
+ {
3588
+ fromCommitId: ref,
3589
+ toCommitId: ref,
3590
+ $top: 1
3591
+ },
3592
+ projectName
3647
3593
  );
3648
- case 404:
3649
- throw new InvalidRepoUrlError(safeParseError.data.error.error.message);
3594
+ const commit = res[0];
3595
+ if (!commit || !commit.commitId) {
3596
+ throw new Error("no commit");
3597
+ }
3598
+ return {
3599
+ sha: commit.commitId,
3600
+ type: "COMMIT" /* COMMIT */,
3601
+ date: commit.committer?.date || /* @__PURE__ */ new Date()
3602
+ };
3603
+ })(),
3604
+ (async () => {
3605
+ const res = await git.getRefs(repo, projectName, `tags/${ref}`);
3606
+ if (!res[0] || !res[0].objectId) {
3607
+ throw new Error("no tag ref");
3608
+ }
3609
+ let objectId = res[0].objectId;
3610
+ try {
3611
+ const tag = await git.getAnnotatedTag(projectName, repo, objectId);
3612
+ if (tag.taggedObject?.objectId) {
3613
+ objectId = tag.taggedObject.objectId;
3614
+ }
3615
+ } catch (e) {
3616
+ }
3617
+ const commitRes2 = await git.getCommits(
3618
+ repo,
3619
+ {
3620
+ fromCommitId: objectId,
3621
+ toCommitId: objectId,
3622
+ $top: 1
3623
+ },
3624
+ projectName
3625
+ );
3626
+ const commit = commitRes2[0];
3627
+ if (!commit) {
3628
+ throw new Error("no commit");
3629
+ }
3630
+ return {
3631
+ sha: objectId,
3632
+ type: "TAG" /* TAG */,
3633
+ date: commit.committer?.date || /* @__PURE__ */ new Date()
3634
+ };
3635
+ })()
3636
+ ]);
3637
+ const [branchRes, commitRes, tagRes] = results;
3638
+ if (tagRes.status === "fulfilled") {
3639
+ return tagRes.value;
3640
+ }
3641
+ if (branchRes.status === "fulfilled") {
3642
+ return branchRes.value;
3643
+ }
3644
+ if (commitRes.status === "fulfilled") {
3645
+ return commitRes.value;
3650
3646
  }
3647
+ throw new RefNotFoundError(`ref: ${ref} does not exist`);
3648
+ },
3649
+ getAdoBlameRanges() {
3650
+ return [];
3651
3651
  }
3652
- throw e;
3653
- }
3654
- }
3655
- async function getUsersworkspacesSlugs(bitbucketClient) {
3656
- const res = await bitbucketClient.workspaces.getWorkspaces({});
3657
- return res.data.values?.map((v) => z8.string().parse(v.slug));
3652
+ };
3658
3653
  }
3659
- async function getllUsersrepositories(bitbucketClient) {
3660
- const userWorspacesSlugs = await getUsersworkspacesSlugs(bitbucketClient);
3661
- if (!userWorspacesSlugs) {
3654
+ async function getAdoRepoList({
3655
+ orgName,
3656
+ tokenOrg,
3657
+ accessToken
3658
+ }) {
3659
+ let orgs = [];
3660
+ const adoTokenInfo = getAdoTokenInfo(accessToken);
3661
+ if (adoTokenInfo.type === "NONE" /* NONE */) {
3662
3662
  return [];
3663
3663
  }
3664
- const allWorkspaceRepos = [];
3665
- for (const workspaceSlug of userWorspacesSlugs) {
3666
- const repos = await bitbucketClient.repositories.list({
3667
- workspace: workspaceSlug
3668
- });
3669
- if (!repos.data.values) {
3670
- continue;
3671
- }
3672
- allWorkspaceRepos.push(...repos.data.values);
3664
+ if (adoTokenInfo.type === "OAUTH" /* OAUTH */) {
3665
+ orgs = await _getOrgsForOauthToken({ oauthToken: accessToken });
3673
3666
  }
3674
- return allWorkspaceRepos;
3675
- }
3676
- async function getRepositoriesByWorkspace(bitbucketClient, { workspaceSlug }) {
3677
- const res = await bitbucketClient.repositories.list({
3678
- workspace: workspaceSlug
3679
- });
3680
- return res.data.values ?? [];
3667
+ if (orgs.length === 0 && !orgName) {
3668
+ throw new Error(`no orgs for ADO`);
3669
+ } else if (orgs.length === 0 && orgName) {
3670
+ orgs = [orgName];
3671
+ }
3672
+ const repos = (await Promise.allSettled(
3673
+ orgs.map(async (org) => {
3674
+ const orgApi = await getAdoApiClient({
3675
+ ...await getAdoClientParams({
3676
+ accessToken,
3677
+ tokenOrg: tokenOrg || org,
3678
+ url: void 0
3679
+ }),
3680
+ orgName: org
3681
+ });
3682
+ const gitOrg = await orgApi.getGitApi();
3683
+ const orgRepos = await gitOrg.getRepositories();
3684
+ const repoInfoList = (await Promise.allSettled(
3685
+ orgRepos.map(async (repo) => {
3686
+ if (!repo.name || !repo.remoteUrl || !repo.defaultBranch) {
3687
+ throw new InvalidRepoUrlError("bad repo");
3688
+ }
3689
+ const branch = await gitOrg.getBranch(
3690
+ repo.name,
3691
+ repo.defaultBranch.replace(/^refs\/heads\//, ""),
3692
+ repo.project?.name
3693
+ );
3694
+ return {
3695
+ repoName: repo.name,
3696
+ repoUrl: repo.remoteUrl.replace(
3697
+ /^[hH][tT][tT][pP][sS]:\/\/[^/]+@/,
3698
+ "https://"
3699
+ ),
3700
+ repoOwner: org,
3701
+ repoIsPublic: repo.project?.visibility === 2 /* Public */,
3702
+ repoLanguages: [],
3703
+ repoUpdatedAt: branch.commit?.committer?.date?.toDateString() || repo.project?.lastUpdateTime?.toDateString() || (/* @__PURE__ */ new Date()).toDateString()
3704
+ };
3705
+ })
3706
+ )).reduce((acc, res) => {
3707
+ if (res.status === "fulfilled") {
3708
+ acc.push(res.value);
3709
+ }
3710
+ return acc;
3711
+ }, []);
3712
+ return repoInfoList;
3713
+ })
3714
+ )).reduce((acc, res) => {
3715
+ if (res.status === "fulfilled") {
3716
+ return acc.concat(res.value);
3717
+ }
3718
+ return acc;
3719
+ }, []);
3720
+ return repos;
3681
3721
  }
3682
3722
 
3683
3723
  // src/features/analysis/scm/constants.ts
@@ -3686,7 +3726,7 @@ var MOBB_ICON_IMG = "https://app.mobb.ai/gh-action/Logo_Rounded_Icon.svg";
3686
3726
  // src/features/analysis/add_fix_comments_for_pr/utils.ts
3687
3727
  import Debug3 from "debug";
3688
3728
  import parseDiff2 from "parse-diff";
3689
- import { z as z9 } from "zod";
3729
+ import { z as z10 } from "zod";
3690
3730
 
3691
3731
  // src/features/analysis/utils/by_key.ts
3692
3732
  function keyBy(array, keyBy2) {
@@ -3917,7 +3957,7 @@ async function getRelevantVulenrabilitiesFromDiff(params) {
3917
3957
  });
3918
3958
  const lineAddedRanges = calculateRanges(fileNumbers);
3919
3959
  const fileFilter = {
3920
- path: z9.string().parse(file.to),
3960
+ path: z10.string().parse(file.to),
3921
3961
  ranges: lineAddedRanges.map(([startLine, endLine]) => ({
3922
3962
  endLine,
3923
3963
  startLine
@@ -4224,30 +4264,30 @@ function subscribe(query, variables, callback, wsClientOptions) {
4224
4264
  }
4225
4265
 
4226
4266
  // src/features/analysis/graphql/types.ts
4227
- import { z as z10 } from "zod";
4228
- var VulnerabilityReportIssueCodeNodeZ = z10.object({
4229
- vulnerabilityReportIssueId: z10.string(),
4230
- path: z10.string(),
4231
- startLine: z10.number(),
4232
- vulnerabilityReportIssue: z10.object({
4233
- fixId: z10.string()
4267
+ import { z as z11 } from "zod";
4268
+ var VulnerabilityReportIssueCodeNodeZ = z11.object({
4269
+ vulnerabilityReportIssueId: z11.string(),
4270
+ path: z11.string(),
4271
+ startLine: z11.number(),
4272
+ vulnerabilityReportIssue: z11.object({
4273
+ fixId: z11.string()
4234
4274
  })
4235
4275
  });
4236
- var GetVulByNodesMetadataZ = z10.object({
4237
- vulnerabilityReportIssueCodeNodes: z10.array(VulnerabilityReportIssueCodeNodeZ),
4238
- nonFixablePrVuls: z10.object({
4239
- aggregate: z10.object({
4240
- count: z10.number()
4276
+ var GetVulByNodesMetadataZ = z11.object({
4277
+ vulnerabilityReportIssueCodeNodes: z11.array(VulnerabilityReportIssueCodeNodeZ),
4278
+ nonFixablePrVuls: z11.object({
4279
+ aggregate: z11.object({
4280
+ count: z11.number()
4241
4281
  })
4242
4282
  }),
4243
- fixablePrVuls: z10.object({
4244
- aggregate: z10.object({
4245
- count: z10.number()
4283
+ fixablePrVuls: z11.object({
4284
+ aggregate: z11.object({
4285
+ count: z11.number()
4246
4286
  })
4247
4287
  }),
4248
- totalScanVulnerabilities: z10.object({
4249
- aggregate: z10.object({
4250
- count: z10.number()
4288
+ totalScanVulnerabilities: z11.object({
4289
+ aggregate: z11.object({
4290
+ count: z11.number()
4251
4291
  })
4252
4292
  })
4253
4293
  });
@@ -5148,7 +5188,7 @@ async function _scan(params, { skipPrompts = false } = {}) {
5148
5188
  spinner: mobbSpinner,
5149
5189
  submitVulnerabilityReportVariables: {
5150
5190
  fixReportId: reportUploadInfo.fixReportId,
5151
- repoUrl: z11.string().parse(repo),
5191
+ repoUrl: z12.string().parse(repo),
5152
5192
  reference,
5153
5193
  projectId,
5154
5194
  vulnerabilityReportFileName: "report.json",
@@ -5400,9 +5440,9 @@ async function _scan(params, { skipPrompts = false } = {}) {
5400
5440
  }
5401
5441
  });
5402
5442
  if (command === "review") {
5403
- const params2 = z11.object({
5404
- repo: z11.string().url(),
5405
- githubActionToken: z11.string()
5443
+ const params2 = z12.object({
5444
+ repo: z12.string().url(),
5445
+ githubActionToken: z12.string()
5406
5446
  }).parse({ repo, githubActionToken });
5407
5447
  const scm2 = await SCMLib.init({
5408
5448
  url: params2.repo,
@@ -5419,7 +5459,7 @@ async function _scan(params, { skipPrompts = false } = {}) {
5419
5459
  analysisId,
5420
5460
  gqlClient,
5421
5461
  scm: scm2,
5422
- scanner: z11.nativeEnum(SCANNERS).parse(scanner)
5462
+ scanner: z12.nativeEnum(SCANNERS).parse(scanner)
5423
5463
  });
5424
5464
  },
5425
5465
  callbackStates: ["Finished" /* Finished */]
@@ -5632,7 +5672,7 @@ var scmTokenOption = {
5632
5672
  // src/args/validation.ts
5633
5673
  import chalk6 from "chalk";
5634
5674
  import path8 from "path";
5635
- import { z as z12 } from "zod";
5675
+ import { z as z13 } from "zod";
5636
5676
  function throwRepoUrlErrorMessage({
5637
5677
  error,
5638
5678
  repoUrl,
@@ -5649,13 +5689,13 @@ Example:
5649
5689
  )}`;
5650
5690
  throw new CliError(formattedErrorMessage);
5651
5691
  }
5652
- var UrlZ = z12.string({
5692
+ var UrlZ = z13.string({
5653
5693
  invalid_type_error: "is not a valid GitHub / GitLab / ADO URL"
5654
5694
  }).refine((data) => !!sanityRepoURL(data), {
5655
5695
  message: "is not a valid GitHub / GitLab / ADO URL"
5656
5696
  });
5657
5697
  function validateOrganizationId(organizationId) {
5658
- const orgIdValidation = z12.string().uuid().nullish().safeParse(organizationId);
5698
+ const orgIdValidation = z13.string().uuid().nullish().safeParse(organizationId);
5659
5699
  if (!orgIdValidation.success) {
5660
5700
  throw new CliError(`organizationId: ${organizationId} is not a valid UUID`);
5661
5701
  }
@@ -5812,7 +5852,7 @@ async function scanHandler(args) {
5812
5852
  }
5813
5853
 
5814
5854
  // src/args/commands/token.ts
5815
- import { z as z13 } from "zod";
5855
+ import { z as z14 } from "zod";
5816
5856
  function addScmTokenBuilder(args) {
5817
5857
  return args.option("scm-type", scmTypeOption).option("url", urlOption).option("token", scmTokenOption).option("organization", scmOrgOption).option("refresh-token", scmRefreshTokenOption).option("api-key", apiKeyOption).example(
5818
5858
  "$0 add-scm-token --scm-type Ado --url https://dev.azure.com/adoorg/test/_git/repo --token abcdef0123456 --organization myOrg",
@@ -5820,7 +5860,7 @@ function addScmTokenBuilder(args) {
5820
5860
  ).help().demandOption(["url", "token"]);
5821
5861
  }
5822
5862
  function validateAddScmTokenOptions(argv) {
5823
- if (!z13.nativeEnum(ScmType).safeParse(argv.scmType).success) {
5863
+ if (!z14.nativeEnum(ScmType).safeParse(argv.scmType).success) {
5824
5864
  throw new CliError(
5825
5865
  "\nError: --scm-type must reference a valid SCM type (GitHub, GitLab, Ado, Bitbutcket)"
5826
5866
  );