mobbdev 1.1.17 → 1.1.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/args/commands/upload_ai_blame.d.mts +28 -28
- package/dist/args/commands/upload_ai_blame.mjs +166 -105
- package/dist/index.mjs +254 -171
- package/package.json +1 -1
|
@@ -51,18 +51,26 @@ declare const PromptItemZ: z.ZodObject<{
|
|
|
51
51
|
name: string;
|
|
52
52
|
parameters: string;
|
|
53
53
|
result: string;
|
|
54
|
-
rawArguments?: string | undefined;
|
|
55
54
|
accepted?: boolean | undefined;
|
|
55
|
+
rawArguments?: string | undefined;
|
|
56
56
|
}, {
|
|
57
57
|
name: string;
|
|
58
58
|
parameters: string;
|
|
59
59
|
result: string;
|
|
60
|
-
rawArguments?: string | undefined;
|
|
61
60
|
accepted?: boolean | undefined;
|
|
61
|
+
rawArguments?: string | undefined;
|
|
62
62
|
}>>;
|
|
63
63
|
}, "strip", z.ZodTypeAny, {
|
|
64
64
|
type: "USER_PROMPT" | "AI_RESPONSE" | "TOOL_EXECUTION" | "AI_THINKING";
|
|
65
|
+
tool?: {
|
|
66
|
+
name: string;
|
|
67
|
+
parameters: string;
|
|
68
|
+
result: string;
|
|
69
|
+
accepted?: boolean | undefined;
|
|
70
|
+
rawArguments?: string | undefined;
|
|
71
|
+
} | undefined;
|
|
65
72
|
date?: Date | undefined;
|
|
73
|
+
text?: string | undefined;
|
|
66
74
|
attachedFiles?: {
|
|
67
75
|
relativePath: string;
|
|
68
76
|
startLine?: number | undefined;
|
|
@@ -71,17 +79,17 @@ declare const PromptItemZ: z.ZodObject<{
|
|
|
71
79
|
inputCount: number;
|
|
72
80
|
outputCount: number;
|
|
73
81
|
} | undefined;
|
|
74
|
-
|
|
82
|
+
}, {
|
|
83
|
+
type: "USER_PROMPT" | "AI_RESPONSE" | "TOOL_EXECUTION" | "AI_THINKING";
|
|
75
84
|
tool?: {
|
|
76
85
|
name: string;
|
|
77
86
|
parameters: string;
|
|
78
87
|
result: string;
|
|
79
|
-
rawArguments?: string | undefined;
|
|
80
88
|
accepted?: boolean | undefined;
|
|
89
|
+
rawArguments?: string | undefined;
|
|
81
90
|
} | undefined;
|
|
82
|
-
}, {
|
|
83
|
-
type: "USER_PROMPT" | "AI_RESPONSE" | "TOOL_EXECUTION" | "AI_THINKING";
|
|
84
91
|
date?: Date | undefined;
|
|
92
|
+
text?: string | undefined;
|
|
85
93
|
attachedFiles?: {
|
|
86
94
|
relativePath: string;
|
|
87
95
|
startLine?: number | undefined;
|
|
@@ -90,14 +98,6 @@ declare const PromptItemZ: z.ZodObject<{
|
|
|
90
98
|
inputCount: number;
|
|
91
99
|
outputCount: number;
|
|
92
100
|
} | undefined;
|
|
93
|
-
text?: string | undefined;
|
|
94
|
-
tool?: {
|
|
95
|
-
name: string;
|
|
96
|
-
parameters: string;
|
|
97
|
-
result: string;
|
|
98
|
-
rawArguments?: string | undefined;
|
|
99
|
-
accepted?: boolean | undefined;
|
|
100
|
-
} | undefined;
|
|
101
101
|
}>;
|
|
102
102
|
type PromptItem = z.infer<typeof PromptItemZ>;
|
|
103
103
|
declare const PromptItemArrayZ: z.ZodArray<z.ZodObject<{
|
|
@@ -134,18 +134,26 @@ declare const PromptItemArrayZ: z.ZodArray<z.ZodObject<{
|
|
|
134
134
|
name: string;
|
|
135
135
|
parameters: string;
|
|
136
136
|
result: string;
|
|
137
|
-
rawArguments?: string | undefined;
|
|
138
137
|
accepted?: boolean | undefined;
|
|
138
|
+
rawArguments?: string | undefined;
|
|
139
139
|
}, {
|
|
140
140
|
name: string;
|
|
141
141
|
parameters: string;
|
|
142
142
|
result: string;
|
|
143
|
-
rawArguments?: string | undefined;
|
|
144
143
|
accepted?: boolean | undefined;
|
|
144
|
+
rawArguments?: string | undefined;
|
|
145
145
|
}>>;
|
|
146
146
|
}, "strip", z.ZodTypeAny, {
|
|
147
147
|
type: "USER_PROMPT" | "AI_RESPONSE" | "TOOL_EXECUTION" | "AI_THINKING";
|
|
148
|
+
tool?: {
|
|
149
|
+
name: string;
|
|
150
|
+
parameters: string;
|
|
151
|
+
result: string;
|
|
152
|
+
accepted?: boolean | undefined;
|
|
153
|
+
rawArguments?: string | undefined;
|
|
154
|
+
} | undefined;
|
|
148
155
|
date?: Date | undefined;
|
|
156
|
+
text?: string | undefined;
|
|
149
157
|
attachedFiles?: {
|
|
150
158
|
relativePath: string;
|
|
151
159
|
startLine?: number | undefined;
|
|
@@ -154,17 +162,17 @@ declare const PromptItemArrayZ: z.ZodArray<z.ZodObject<{
|
|
|
154
162
|
inputCount: number;
|
|
155
163
|
outputCount: number;
|
|
156
164
|
} | undefined;
|
|
157
|
-
|
|
165
|
+
}, {
|
|
166
|
+
type: "USER_PROMPT" | "AI_RESPONSE" | "TOOL_EXECUTION" | "AI_THINKING";
|
|
158
167
|
tool?: {
|
|
159
168
|
name: string;
|
|
160
169
|
parameters: string;
|
|
161
170
|
result: string;
|
|
162
|
-
rawArguments?: string | undefined;
|
|
163
171
|
accepted?: boolean | undefined;
|
|
172
|
+
rawArguments?: string | undefined;
|
|
164
173
|
} | undefined;
|
|
165
|
-
}, {
|
|
166
|
-
type: "USER_PROMPT" | "AI_RESPONSE" | "TOOL_EXECUTION" | "AI_THINKING";
|
|
167
174
|
date?: Date | undefined;
|
|
175
|
+
text?: string | undefined;
|
|
168
176
|
attachedFiles?: {
|
|
169
177
|
relativePath: string;
|
|
170
178
|
startLine?: number | undefined;
|
|
@@ -173,14 +181,6 @@ declare const PromptItemArrayZ: z.ZodArray<z.ZodObject<{
|
|
|
173
181
|
inputCount: number;
|
|
174
182
|
outputCount: number;
|
|
175
183
|
} | undefined;
|
|
176
|
-
text?: string | undefined;
|
|
177
|
-
tool?: {
|
|
178
|
-
name: string;
|
|
179
|
-
parameters: string;
|
|
180
|
-
result: string;
|
|
181
|
-
rawArguments?: string | undefined;
|
|
182
|
-
accepted?: boolean | undefined;
|
|
183
|
-
} | undefined;
|
|
184
184
|
}>, "many">;
|
|
185
185
|
type PromptItemArray = z.infer<typeof PromptItemArrayZ>;
|
|
186
186
|
type UploadAiBlameOptions = {
|
|
@@ -1118,6 +1118,31 @@ var GetUserMvsAutoFixDocument = `
|
|
|
1118
1118
|
}
|
|
1119
1119
|
}
|
|
1120
1120
|
`;
|
|
1121
|
+
var StreamBlameAiAnalysisRequestsDocument = `
|
|
1122
|
+
subscription streamBlameAiAnalysisRequests($requestIds: [uuid!]!) {
|
|
1123
|
+
blame_ai_analysis_request(where: {id: {_in: $requestIds}}) {
|
|
1124
|
+
id
|
|
1125
|
+
state
|
|
1126
|
+
commitId
|
|
1127
|
+
organizationId
|
|
1128
|
+
createdOn
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
`;
|
|
1132
|
+
var StreamCommitBlameRequestsDocument = `
|
|
1133
|
+
subscription streamCommitBlameRequests($requestIds: [uuid!]!) {
|
|
1134
|
+
commit_blame_request(where: {id: {_in: $requestIds}}) {
|
|
1135
|
+
id
|
|
1136
|
+
state
|
|
1137
|
+
organizationId
|
|
1138
|
+
repositoryUrl
|
|
1139
|
+
commitSha
|
|
1140
|
+
createdOn
|
|
1141
|
+
completedOn
|
|
1142
|
+
error
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
`;
|
|
1121
1146
|
var defaultWrapper = (action, _operationName, _operationType, _variables) => action();
|
|
1122
1147
|
function getSdk(client, withWrapper = defaultWrapper) {
|
|
1123
1148
|
return {
|
|
@@ -1216,6 +1241,12 @@ function getSdk(client, withWrapper = defaultWrapper) {
|
|
|
1216
1241
|
},
|
|
1217
1242
|
GetUserMvsAutoFix(variables, requestHeaders, signal) {
|
|
1218
1243
|
return withWrapper((wrappedRequestHeaders) => client.request({ document: GetUserMvsAutoFixDocument, variables, requestHeaders: { ...requestHeaders, ...wrappedRequestHeaders }, signal }), "GetUserMvsAutoFix", "query", variables);
|
|
1244
|
+
},
|
|
1245
|
+
streamBlameAiAnalysisRequests(variables, requestHeaders, signal) {
|
|
1246
|
+
return withWrapper((wrappedRequestHeaders) => client.request({ document: StreamBlameAiAnalysisRequestsDocument, variables, requestHeaders: { ...requestHeaders, ...wrappedRequestHeaders }, signal }), "streamBlameAiAnalysisRequests", "subscription", variables);
|
|
1247
|
+
},
|
|
1248
|
+
streamCommitBlameRequests(variables, requestHeaders, signal) {
|
|
1249
|
+
return withWrapper((wrappedRequestHeaders) => client.request({ document: StreamCommitBlameRequestsDocument, variables, requestHeaders: { ...requestHeaders, ...wrappedRequestHeaders }, signal }), "streamCommitBlameRequests", "subscription", variables);
|
|
1219
1250
|
}
|
|
1220
1251
|
};
|
|
1221
1252
|
}
|
|
@@ -2172,6 +2203,7 @@ function getDirName() {
|
|
|
2172
2203
|
var debug = Debug("mobbdev:constants");
|
|
2173
2204
|
dotenv.config({ path: path2.join(getModuleRootDir(), ".env") });
|
|
2174
2205
|
var DEFAULT_API_URL = "https://api.mobb.ai/v1/graphql";
|
|
2206
|
+
var DEFAULT_WEB_APP_URL = "https://app.mobb.ai";
|
|
2175
2207
|
var scmFriendlyText = {
|
|
2176
2208
|
["Ado" /* Ado */]: "Azure DevOps",
|
|
2177
2209
|
["Bitbucket" /* Bitbucket */]: "Bitbucket",
|
|
@@ -2198,13 +2230,16 @@ var scannerToVulnerabilityReportVendorEnum = {
|
|
|
2198
2230
|
};
|
|
2199
2231
|
var SupportedScannersZ = z8.enum([SCANNERS.Checkmarx, SCANNERS.Snyk]);
|
|
2200
2232
|
var envVariablesSchema = z8.object({
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2233
|
+
// These have safe defaults for production - the VS Code extension passes explicit URLs
|
|
2234
|
+
WEB_APP_URL: z8.string().optional().default(DEFAULT_WEB_APP_URL),
|
|
2235
|
+
API_URL: z8.string().optional().default(DEFAULT_API_URL),
|
|
2236
|
+
// These are only needed for local development with Hasura
|
|
2237
|
+
HASURA_ACCESS_KEY: z8.string().optional().default(""),
|
|
2238
|
+
LOCAL_GRAPHQL_ENDPOINT: z8.string().optional().default(""),
|
|
2239
|
+
// Proxy settings
|
|
2205
2240
|
HTTP_PROXY: z8.string().optional().default(""),
|
|
2206
2241
|
HTTPS_PROXY: z8.string().optional().default("")
|
|
2207
|
-
})
|
|
2242
|
+
});
|
|
2208
2243
|
var envVariables = envVariablesSchema.parse(process.env);
|
|
2209
2244
|
debug("config %o", envVariables);
|
|
2210
2245
|
var WEB_APP_URL = envVariables.WEB_APP_URL;
|
|
@@ -2399,75 +2434,78 @@ function createWSClient(options) {
|
|
|
2399
2434
|
}
|
|
2400
2435
|
});
|
|
2401
2436
|
}
|
|
2402
|
-
function
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
};
|
|
2411
|
-
function cleanup() {
|
|
2437
|
+
function subscribeStream(query, variables, handlers, wsClientOptions) {
|
|
2438
|
+
let timer = null;
|
|
2439
|
+
const { timeoutInMs = SUBSCRIPTION_TIMEOUT_MS } = wsClientOptions;
|
|
2440
|
+
const client = createWSClient(wsClientOptions);
|
|
2441
|
+
let unsub = null;
|
|
2442
|
+
let settled = false;
|
|
2443
|
+
const cleanup = () => {
|
|
2444
|
+
if (unsub) {
|
|
2412
2445
|
try {
|
|
2413
|
-
|
|
2446
|
+
unsub();
|
|
2414
2447
|
} catch {
|
|
2415
2448
|
}
|
|
2416
|
-
|
|
2417
|
-
clearTimeout(timer);
|
|
2418
|
-
timer = null;
|
|
2419
|
-
}
|
|
2449
|
+
unsub = null;
|
|
2420
2450
|
}
|
|
2421
|
-
|
|
2422
|
-
|
|
2451
|
+
if (timer) {
|
|
2452
|
+
clearTimeout(timer);
|
|
2453
|
+
timer = null;
|
|
2454
|
+
}
|
|
2455
|
+
};
|
|
2456
|
+
const finalizeError = (error) => {
|
|
2457
|
+
if (settled) {
|
|
2458
|
+
return;
|
|
2459
|
+
}
|
|
2460
|
+
settled = true;
|
|
2461
|
+
cleanup();
|
|
2462
|
+
handlers.error(error);
|
|
2463
|
+
};
|
|
2464
|
+
unsub = client.subscribe(
|
|
2465
|
+
{ query, variables },
|
|
2466
|
+
{
|
|
2467
|
+
next: (payload) => {
|
|
2468
|
+
if (settled) {
|
|
2469
|
+
return;
|
|
2470
|
+
}
|
|
2471
|
+
if (!payload.data) {
|
|
2472
|
+
finalizeError(
|
|
2473
|
+
new Error(
|
|
2474
|
+
`Broken data object from graphQL subscribe: ${JSON.stringify(
|
|
2475
|
+
payload
|
|
2476
|
+
)} for query: ${query}`
|
|
2477
|
+
)
|
|
2478
|
+
);
|
|
2479
|
+
return;
|
|
2480
|
+
}
|
|
2481
|
+
handlers.next(payload.data);
|
|
2482
|
+
},
|
|
2483
|
+
error: (error) => {
|
|
2484
|
+
finalizeError(error);
|
|
2485
|
+
},
|
|
2486
|
+
complete: () => {
|
|
2423
2487
|
return;
|
|
2424
2488
|
}
|
|
2425
|
-
settled = true;
|
|
2426
|
-
cleanup();
|
|
2427
|
-
resolve(data);
|
|
2428
2489
|
}
|
|
2429
|
-
|
|
2490
|
+
);
|
|
2491
|
+
if (typeof timeoutInMs === "number") {
|
|
2492
|
+
timer = setTimeout(() => {
|
|
2493
|
+
finalizeError(
|
|
2494
|
+
new Error(
|
|
2495
|
+
`Timeout expired for graphQL subscribe query: ${query} with timeout: ${timeoutInMs}`
|
|
2496
|
+
)
|
|
2497
|
+
);
|
|
2498
|
+
}, timeoutInMs);
|
|
2499
|
+
}
|
|
2500
|
+
return {
|
|
2501
|
+
unsubscribe: () => {
|
|
2430
2502
|
if (settled) {
|
|
2431
2503
|
return;
|
|
2432
2504
|
}
|
|
2433
2505
|
settled = true;
|
|
2434
2506
|
cleanup();
|
|
2435
|
-
reject(error);
|
|
2436
2507
|
}
|
|
2437
|
-
|
|
2438
|
-
{ query, variables },
|
|
2439
|
-
{
|
|
2440
|
-
next: (data) => {
|
|
2441
|
-
if (!data.data) {
|
|
2442
|
-
finalizeReject(
|
|
2443
|
-
new Error(
|
|
2444
|
-
`Broken data object from graphQL subscribe: ${JSON.stringify(
|
|
2445
|
-
data
|
|
2446
|
-
)} for query: ${query}`
|
|
2447
|
-
)
|
|
2448
|
-
);
|
|
2449
|
-
} else {
|
|
2450
|
-
callback(finalizeResolve, finalizeReject, data.data);
|
|
2451
|
-
}
|
|
2452
|
-
},
|
|
2453
|
-
error: (error) => {
|
|
2454
|
-
finalizeReject(error);
|
|
2455
|
-
},
|
|
2456
|
-
complete: () => {
|
|
2457
|
-
return;
|
|
2458
|
-
}
|
|
2459
|
-
}
|
|
2460
|
-
);
|
|
2461
|
-
if (typeof timeoutInMs === "number") {
|
|
2462
|
-
timer = setTimeout(() => {
|
|
2463
|
-
finalizeReject(
|
|
2464
|
-
new Error(
|
|
2465
|
-
`Timeout expired for graphQL subscribe query: ${query} with timeout: ${timeoutInMs}`
|
|
2466
|
-
)
|
|
2467
|
-
);
|
|
2468
|
-
}, timeoutInMs);
|
|
2469
|
-
}
|
|
2470
|
-
});
|
|
2508
|
+
};
|
|
2471
2509
|
}
|
|
2472
2510
|
|
|
2473
2511
|
// src/features/analysis/scm/utils/index.ts
|
|
@@ -4688,10 +4726,12 @@ var GQLClient = class {
|
|
|
4688
4726
|
constructor(args) {
|
|
4689
4727
|
__publicField(this, "_client");
|
|
4690
4728
|
__publicField(this, "_clientSdk");
|
|
4729
|
+
__publicField(this, "_apiUrl");
|
|
4691
4730
|
__publicField(this, "_auth");
|
|
4692
4731
|
debug6(`init with ${args}`);
|
|
4693
4732
|
this._auth = args;
|
|
4694
|
-
this.
|
|
4733
|
+
this._apiUrl = args.apiUrl || API_URL;
|
|
4734
|
+
this._client = new GraphQLClient(this._apiUrl, {
|
|
4695
4735
|
headers: args.type === "apiKey" ? { [API_KEY_HEADER_NAME]: args.apiKey || "" } : {
|
|
4696
4736
|
Authorization: `Bearer ${args.token}`
|
|
4697
4737
|
},
|
|
@@ -4956,32 +4996,47 @@ var GQLClient = class {
|
|
|
4956
4996
|
}
|
|
4957
4997
|
async subscribeToAnalysis(params) {
|
|
4958
4998
|
const { callbackStates } = params;
|
|
4959
|
-
return
|
|
4960
|
-
|
|
4961
|
-
|
|
4962
|
-
|
|
4963
|
-
|
|
4964
|
-
|
|
4965
|
-
|
|
4966
|
-
|
|
4967
|
-
|
|
4968
|
-
|
|
4969
|
-
|
|
4970
|
-
|
|
4971
|
-
|
|
4972
|
-
|
|
4973
|
-
|
|
4974
|
-
|
|
4975
|
-
|
|
4976
|
-
|
|
4977
|
-
|
|
4978
|
-
|
|
4979
|
-
|
|
4980
|
-
|
|
4981
|
-
|
|
4982
|
-
|
|
4983
|
-
|
|
4984
|
-
|
|
4999
|
+
return new Promise(
|
|
5000
|
+
(resolve, reject) => {
|
|
5001
|
+
const subscription = subscribeStream(
|
|
5002
|
+
GetAnalysisSubscriptionDocument,
|
|
5003
|
+
params.subscribeToAnalysisParams,
|
|
5004
|
+
{
|
|
5005
|
+
next: async (data) => {
|
|
5006
|
+
if (!data.analysis?.state || data.analysis?.state === "Failed" /* Failed */) {
|
|
5007
|
+
const errorMessage = data.analysis?.failReason || `Analysis failed with id: ${data.analysis?.id}`;
|
|
5008
|
+
subscription.unsubscribe();
|
|
5009
|
+
reject(
|
|
5010
|
+
new ReportDigestError(
|
|
5011
|
+
errorMessage,
|
|
5012
|
+
data.analysis?.failReason ?? ""
|
|
5013
|
+
)
|
|
5014
|
+
);
|
|
5015
|
+
return;
|
|
5016
|
+
}
|
|
5017
|
+
if (callbackStates.includes(data.analysis?.state)) {
|
|
5018
|
+
await params.callback(data.analysis.id);
|
|
5019
|
+
subscription.unsubscribe();
|
|
5020
|
+
resolve(data);
|
|
5021
|
+
}
|
|
5022
|
+
},
|
|
5023
|
+
error: (error) => {
|
|
5024
|
+
subscription.unsubscribe();
|
|
5025
|
+
reject(error);
|
|
5026
|
+
}
|
|
5027
|
+
},
|
|
5028
|
+
this._auth.type === "apiKey" ? {
|
|
5029
|
+
apiKey: this._auth.apiKey,
|
|
5030
|
+
type: "apiKey",
|
|
5031
|
+
timeoutInMs: params.timeoutInMs,
|
|
5032
|
+
proxyAgent: getProxyAgent(this._apiUrl)
|
|
5033
|
+
} : {
|
|
5034
|
+
token: this._auth.token,
|
|
5035
|
+
type: "token",
|
|
5036
|
+
timeoutInMs: params.timeoutInMs,
|
|
5037
|
+
proxyAgent: getProxyAgent(this._apiUrl)
|
|
5038
|
+
}
|
|
5039
|
+
);
|
|
4985
5040
|
}
|
|
4986
5041
|
);
|
|
4987
5042
|
}
|
|
@@ -5065,29 +5120,37 @@ var configStore = getConfigStore();
|
|
|
5065
5120
|
var debug7 = Debug6("mobbdev:commands");
|
|
5066
5121
|
var LOGIN_MAX_WAIT = 10 * 60 * 1e3;
|
|
5067
5122
|
var LOGIN_CHECK_DELAY = 5 * 1e3;
|
|
5068
|
-
var webLoginUrl = `${WEB_APP_URL}/cli-login`;
|
|
5069
5123
|
var MOBB_LOGIN_REQUIRED_MSG = `\u{1F513} Login to Mobb is Required, you will be redirected to our login page, once the authorization is complete return to this prompt, ${chalk2.bgBlue(
|
|
5070
5124
|
"press any key to continue"
|
|
5071
5125
|
)};`;
|
|
5072
5126
|
async function getAuthenticatedGQLClient({
|
|
5073
5127
|
inputApiKey = "",
|
|
5074
|
-
isSkipPrompts = true
|
|
5128
|
+
isSkipPrompts = true,
|
|
5129
|
+
apiUrl,
|
|
5130
|
+
webAppUrl
|
|
5075
5131
|
}) {
|
|
5076
5132
|
let gqlClient = new GQLClient({
|
|
5077
5133
|
apiKey: inputApiKey || configStore.get("apiToken") || "",
|
|
5078
|
-
type: "apiKey"
|
|
5134
|
+
type: "apiKey",
|
|
5135
|
+
apiUrl
|
|
5079
5136
|
});
|
|
5080
5137
|
gqlClient = await handleMobbLogin({
|
|
5081
5138
|
inGqlClient: gqlClient,
|
|
5082
|
-
skipPrompts: isSkipPrompts
|
|
5139
|
+
skipPrompts: isSkipPrompts,
|
|
5140
|
+
apiUrl,
|
|
5141
|
+
webAppUrl
|
|
5083
5142
|
});
|
|
5084
5143
|
return gqlClient;
|
|
5085
5144
|
}
|
|
5086
5145
|
async function handleMobbLogin({
|
|
5087
5146
|
inGqlClient,
|
|
5088
5147
|
apiKey,
|
|
5089
|
-
skipPrompts
|
|
5148
|
+
skipPrompts,
|
|
5149
|
+
apiUrl,
|
|
5150
|
+
webAppUrl
|
|
5090
5151
|
}) {
|
|
5152
|
+
const resolvedWebAppUrl = webAppUrl || WEB_APP_URL;
|
|
5153
|
+
const resolvedApiUrl = apiUrl || API_URL;
|
|
5091
5154
|
const { createSpinner } = Spinner({ ci: skipPrompts });
|
|
5092
5155
|
const isConnected = await inGqlClient.verifyApiConnection();
|
|
5093
5156
|
if (!isConnected) {
|
|
@@ -5129,7 +5192,7 @@ async function handleMobbLogin({
|
|
|
5129
5192
|
const loginId = await inGqlClient.createCliLogin({
|
|
5130
5193
|
publicKey: publicKey.export({ format: "pem", type: "pkcs1" }).toString()
|
|
5131
5194
|
});
|
|
5132
|
-
const browserUrl = `${
|
|
5195
|
+
const browserUrl = `${resolvedWebAppUrl}/cli-login/${loginId}?hostname=${os.hostname()}`;
|
|
5133
5196
|
!skipPrompts && console.log(
|
|
5134
5197
|
`If the page does not open automatically, kindly access it through ${browserUrl}.`
|
|
5135
5198
|
);
|
|
@@ -5154,7 +5217,11 @@ async function handleMobbLogin({
|
|
|
5154
5217
|
});
|
|
5155
5218
|
throw new CliError();
|
|
5156
5219
|
}
|
|
5157
|
-
const newGqlClient = new GQLClient({
|
|
5220
|
+
const newGqlClient = new GQLClient({
|
|
5221
|
+
apiKey: newApiToken,
|
|
5222
|
+
type: "apiKey",
|
|
5223
|
+
apiUrl: resolvedApiUrl
|
|
5224
|
+
});
|
|
5158
5225
|
const loginSuccess = await newGqlClient.validateUserToken();
|
|
5159
5226
|
if (loginSuccess) {
|
|
5160
5227
|
debug7(`set api token ${newApiToken}`);
|
|
@@ -5242,42 +5309,36 @@ var openRedaction = new OpenRedaction({
|
|
|
5242
5309
|
"VISA_NUMBER",
|
|
5243
5310
|
"VISA_MRZ",
|
|
5244
5311
|
"TAX_ID",
|
|
5245
|
-
// Financial Data
|
|
5312
|
+
// Financial Data (removed SWIFT_BIC - too broad, matches bank code formats in variables)
|
|
5246
5313
|
"CREDIT_CARD",
|
|
5247
5314
|
"IBAN",
|
|
5248
5315
|
"BANK_ACCOUNT_UK",
|
|
5249
5316
|
"ROUTING_NUMBER_US",
|
|
5250
|
-
"SWIFT_BIC",
|
|
5251
5317
|
"CARD_TRACK1_DATA",
|
|
5252
5318
|
"CARD_TRACK2_DATA",
|
|
5253
5319
|
"CARD_EXPIRY",
|
|
5254
5320
|
"CARD_AUTH_CODE",
|
|
5255
|
-
// Cryptocurrency
|
|
5256
|
-
"BITCOIN_ADDRESS",
|
|
5321
|
+
// Cryptocurrency (removed BITCOIN_ADDRESS - too broad, matches hash-like strings)
|
|
5257
5322
|
"ETHEREUM_ADDRESS",
|
|
5258
5323
|
"LITECOIN_ADDRESS",
|
|
5259
5324
|
"CARDANO_ADDRESS",
|
|
5260
5325
|
"SOLANA_ADDRESS",
|
|
5261
5326
|
"MONERO_ADDRESS",
|
|
5262
5327
|
"RIPPLE_ADDRESS",
|
|
5263
|
-
// Medical Data
|
|
5328
|
+
// Medical Data (removed PRESCRIPTION_NUMBER - too broad, matches words containing "ription")
|
|
5264
5329
|
"NHS_NUMBER",
|
|
5265
5330
|
"MEDICAL_RECORD_NUMBER",
|
|
5266
5331
|
"AUSTRALIAN_MEDICARE",
|
|
5267
5332
|
"HEALTH_PLAN_NUMBER",
|
|
5268
|
-
"PRESCRIPTION_NUMBER",
|
|
5269
5333
|
"PATIENT_ID",
|
|
5270
|
-
// Communications
|
|
5334
|
+
// Communications (removed EMERGENCY_CONTACT, ADDRESS_PO_BOX, ZIP_CODE_US - too broad)
|
|
5271
5335
|
"PHONE_US",
|
|
5272
5336
|
"PHONE_UK",
|
|
5273
5337
|
"PHONE_UK_MOBILE",
|
|
5274
5338
|
"PHONE_INTERNATIONAL",
|
|
5275
5339
|
"PHONE_LINE_NUMBER",
|
|
5276
|
-
"EMERGENCY_CONTACT",
|
|
5277
5340
|
"ADDRESS_STREET",
|
|
5278
|
-
"ADDRESS_PO_BOX",
|
|
5279
5341
|
"POSTCODE_UK",
|
|
5280
|
-
"ZIP_CODE_US",
|
|
5281
5342
|
// Network & Technical
|
|
5282
5343
|
"IPV4",
|
|
5283
5344
|
"IPV6",
|
package/dist/index.mjs
CHANGED
|
@@ -842,16 +842,7 @@ var init_GitService = __esm({
|
|
|
842
842
|
this.git.revparse(["HEAD"]),
|
|
843
843
|
this.git.revparse(["--abbrev-ref", "HEAD"])
|
|
844
844
|
]);
|
|
845
|
-
|
|
846
|
-
if (normalizedRepoUrl.endsWith(".git")) {
|
|
847
|
-
normalizedRepoUrl = normalizedRepoUrl.slice(0, -".git".length);
|
|
848
|
-
}
|
|
849
|
-
if (normalizedRepoUrl.startsWith("git@github.com:")) {
|
|
850
|
-
normalizedRepoUrl = normalizedRepoUrl.replace(
|
|
851
|
-
"git@github.com:",
|
|
852
|
-
"https://github.com/"
|
|
853
|
-
);
|
|
854
|
-
}
|
|
845
|
+
const normalizedRepoUrl = repoUrl.value ? this.normalizeGitUrl(repoUrl.value) : "";
|
|
855
846
|
this.log("[GitService] Git repository information retrieved", "debug", {
|
|
856
847
|
repoUrl: normalizedRepoUrl,
|
|
857
848
|
hash,
|
|
@@ -1147,6 +1138,9 @@ var init_GitService = __esm({
|
|
|
1147
1138
|
}
|
|
1148
1139
|
}
|
|
1149
1140
|
}
|
|
1141
|
+
if (normalizedUrl.startsWith("https://") || normalizedUrl.startsWith("http://")) {
|
|
1142
|
+
normalizedUrl = normalizedUrl.replace(/^(https?:\/\/)([^@/]+@)/, "$1");
|
|
1143
|
+
}
|
|
1150
1144
|
return normalizedUrl;
|
|
1151
1145
|
}
|
|
1152
1146
|
/**
|
|
@@ -2377,6 +2371,31 @@ var GetUserMvsAutoFixDocument = `
|
|
|
2377
2371
|
}
|
|
2378
2372
|
}
|
|
2379
2373
|
`;
|
|
2374
|
+
var StreamBlameAiAnalysisRequestsDocument = `
|
|
2375
|
+
subscription streamBlameAiAnalysisRequests($requestIds: [uuid!]!) {
|
|
2376
|
+
blame_ai_analysis_request(where: {id: {_in: $requestIds}}) {
|
|
2377
|
+
id
|
|
2378
|
+
state
|
|
2379
|
+
commitId
|
|
2380
|
+
organizationId
|
|
2381
|
+
createdOn
|
|
2382
|
+
}
|
|
2383
|
+
}
|
|
2384
|
+
`;
|
|
2385
|
+
var StreamCommitBlameRequestsDocument = `
|
|
2386
|
+
subscription streamCommitBlameRequests($requestIds: [uuid!]!) {
|
|
2387
|
+
commit_blame_request(where: {id: {_in: $requestIds}}) {
|
|
2388
|
+
id
|
|
2389
|
+
state
|
|
2390
|
+
organizationId
|
|
2391
|
+
repositoryUrl
|
|
2392
|
+
commitSha
|
|
2393
|
+
createdOn
|
|
2394
|
+
completedOn
|
|
2395
|
+
error
|
|
2396
|
+
}
|
|
2397
|
+
}
|
|
2398
|
+
`;
|
|
2380
2399
|
var defaultWrapper = (action, _operationName, _operationType, _variables) => action();
|
|
2381
2400
|
function getSdk(client, withWrapper = defaultWrapper) {
|
|
2382
2401
|
return {
|
|
@@ -2475,6 +2494,12 @@ function getSdk(client, withWrapper = defaultWrapper) {
|
|
|
2475
2494
|
},
|
|
2476
2495
|
GetUserMvsAutoFix(variables, requestHeaders, signal) {
|
|
2477
2496
|
return withWrapper((wrappedRequestHeaders) => client.request({ document: GetUserMvsAutoFixDocument, variables, requestHeaders: { ...requestHeaders, ...wrappedRequestHeaders }, signal }), "GetUserMvsAutoFix", "query", variables);
|
|
2497
|
+
},
|
|
2498
|
+
streamBlameAiAnalysisRequests(variables, requestHeaders, signal) {
|
|
2499
|
+
return withWrapper((wrappedRequestHeaders) => client.request({ document: StreamBlameAiAnalysisRequestsDocument, variables, requestHeaders: { ...requestHeaders, ...wrappedRequestHeaders }, signal }), "streamBlameAiAnalysisRequests", "subscription", variables);
|
|
2500
|
+
},
|
|
2501
|
+
streamCommitBlameRequests(variables, requestHeaders, signal) {
|
|
2502
|
+
return withWrapper((wrappedRequestHeaders) => client.request({ document: StreamCommitBlameRequestsDocument, variables, requestHeaders: { ...requestHeaders, ...wrappedRequestHeaders }, signal }), "streamCommitBlameRequests", "subscription", variables);
|
|
2478
2503
|
}
|
|
2479
2504
|
};
|
|
2480
2505
|
}
|
|
@@ -8463,6 +8488,16 @@ function getGithubSdk(params = {}) {
|
|
|
8463
8488
|
}
|
|
8464
8489
|
|
|
8465
8490
|
// src/features/analysis/scm/github/GithubSCMLib.ts
|
|
8491
|
+
function determinePrStatus(state, isDraft) {
|
|
8492
|
+
switch (state) {
|
|
8493
|
+
case "CLOSED":
|
|
8494
|
+
return "CLOSED" /* Closed */;
|
|
8495
|
+
case "MERGED":
|
|
8496
|
+
return "MERGED" /* Merged */;
|
|
8497
|
+
case "OPEN":
|
|
8498
|
+
return isDraft ? "DRAFT" /* Draft */ : "ACTIVE" /* Active */;
|
|
8499
|
+
}
|
|
8500
|
+
}
|
|
8466
8501
|
var GithubSCMLib = class extends SCMLib {
|
|
8467
8502
|
// we don't always need a url, what's important is that we have an access token
|
|
8468
8503
|
constructor(url, accessToken, scmOrg) {
|
|
@@ -8910,12 +8945,7 @@ var GithubSCMLib = class extends SCMLib {
|
|
|
8910
8945
|
if (!pr) {
|
|
8911
8946
|
throw new Error(`Pull request #${prNumber} not found`);
|
|
8912
8947
|
}
|
|
8913
|
-
|
|
8914
|
-
if (pr.state === "CLOSED") {
|
|
8915
|
-
prStatus = pr.mergedAt ? "MERGED" /* Merged */ : "CLOSED" /* Closed */;
|
|
8916
|
-
} else if (pr.isDraft) {
|
|
8917
|
-
prStatus = "DRAFT" /* Draft */;
|
|
8918
|
-
}
|
|
8948
|
+
const prStatus = determinePrStatus(pr.state, pr.isDraft);
|
|
8919
8949
|
const firstCommit = pr.commits.nodes[0];
|
|
8920
8950
|
const firstCommitDate = firstCommit ? new Date(
|
|
8921
8951
|
firstCommit.commit.author?.date || firstCommit.commit.committedDate || pr.createdAt
|
|
@@ -10360,6 +10390,7 @@ import { z as z24 } from "zod";
|
|
|
10360
10390
|
var debug5 = Debug4("mobbdev:constants");
|
|
10361
10391
|
dotenv.config({ path: path6.join(getModuleRootDir(), ".env") });
|
|
10362
10392
|
var DEFAULT_API_URL = "https://api.mobb.ai/v1/graphql";
|
|
10393
|
+
var DEFAULT_WEB_APP_URL = "https://app.mobb.ai";
|
|
10363
10394
|
var scmFriendlyText = {
|
|
10364
10395
|
["Ado" /* Ado */]: "Azure DevOps",
|
|
10365
10396
|
["Bitbucket" /* Bitbucket */]: "Bitbucket",
|
|
@@ -10386,13 +10417,16 @@ var scannerToVulnerabilityReportVendorEnum = {
|
|
|
10386
10417
|
};
|
|
10387
10418
|
var SupportedScannersZ = z24.enum([SCANNERS.Checkmarx, SCANNERS.Snyk]);
|
|
10388
10419
|
var envVariablesSchema = z24.object({
|
|
10389
|
-
|
|
10390
|
-
|
|
10391
|
-
|
|
10392
|
-
|
|
10420
|
+
// These have safe defaults for production - the VS Code extension passes explicit URLs
|
|
10421
|
+
WEB_APP_URL: z24.string().optional().default(DEFAULT_WEB_APP_URL),
|
|
10422
|
+
API_URL: z24.string().optional().default(DEFAULT_API_URL),
|
|
10423
|
+
// These are only needed for local development with Hasura
|
|
10424
|
+
HASURA_ACCESS_KEY: z24.string().optional().default(""),
|
|
10425
|
+
LOCAL_GRAPHQL_ENDPOINT: z24.string().optional().default(""),
|
|
10426
|
+
// Proxy settings
|
|
10393
10427
|
HTTP_PROXY: z24.string().optional().default(""),
|
|
10394
10428
|
HTTPS_PROXY: z24.string().optional().default("")
|
|
10395
|
-
})
|
|
10429
|
+
});
|
|
10396
10430
|
var envVariables = envVariablesSchema.parse(process.env);
|
|
10397
10431
|
debug5("config %o", envVariables);
|
|
10398
10432
|
var mobbAscii = `
|
|
@@ -10445,9 +10479,9 @@ var errorMessages = {
|
|
|
10445
10479
|
)} is needed if you're adding an SCM token`
|
|
10446
10480
|
};
|
|
10447
10481
|
var progressMassages = {
|
|
10448
|
-
processingVulnerabilityReportSuccess: "\u2699\uFE0F Vulnerability report
|
|
10449
|
-
processingVulnerabilityReport: "\u2699\uFE0F
|
|
10450
|
-
processingVulnerabilityReportFailed: "\u2699\uFE0F Error
|
|
10482
|
+
processingVulnerabilityReportSuccess: "\u2699\uFE0F Vulnerability report processed successfully",
|
|
10483
|
+
processingVulnerabilityReport: "\u2699\uFE0F Processing vulnerability report",
|
|
10484
|
+
processingVulnerabilityReportFailed: "\u2699\uFE0F Error Processing vulnerability report"
|
|
10451
10485
|
};
|
|
10452
10486
|
var VUL_REPORT_DIGEST_TIMEOUT_MS = 1e3 * 60 * 30;
|
|
10453
10487
|
|
|
@@ -10773,75 +10807,78 @@ function createWSClient(options) {
|
|
|
10773
10807
|
}
|
|
10774
10808
|
});
|
|
10775
10809
|
}
|
|
10776
|
-
function
|
|
10777
|
-
|
|
10778
|
-
|
|
10779
|
-
|
|
10780
|
-
|
|
10781
|
-
|
|
10782
|
-
|
|
10783
|
-
|
|
10784
|
-
};
|
|
10785
|
-
function cleanup() {
|
|
10810
|
+
function subscribeStream(query, variables, handlers, wsClientOptions) {
|
|
10811
|
+
let timer = null;
|
|
10812
|
+
const { timeoutInMs = SUBSCRIPTION_TIMEOUT_MS } = wsClientOptions;
|
|
10813
|
+
const client = createWSClient(wsClientOptions);
|
|
10814
|
+
let unsub = null;
|
|
10815
|
+
let settled = false;
|
|
10816
|
+
const cleanup = () => {
|
|
10817
|
+
if (unsub) {
|
|
10786
10818
|
try {
|
|
10787
|
-
|
|
10819
|
+
unsub();
|
|
10788
10820
|
} catch {
|
|
10789
10821
|
}
|
|
10790
|
-
|
|
10791
|
-
clearTimeout(timer);
|
|
10792
|
-
timer = null;
|
|
10793
|
-
}
|
|
10822
|
+
unsub = null;
|
|
10794
10823
|
}
|
|
10795
|
-
|
|
10796
|
-
|
|
10824
|
+
if (timer) {
|
|
10825
|
+
clearTimeout(timer);
|
|
10826
|
+
timer = null;
|
|
10827
|
+
}
|
|
10828
|
+
};
|
|
10829
|
+
const finalizeError = (error) => {
|
|
10830
|
+
if (settled) {
|
|
10831
|
+
return;
|
|
10832
|
+
}
|
|
10833
|
+
settled = true;
|
|
10834
|
+
cleanup();
|
|
10835
|
+
handlers.error(error);
|
|
10836
|
+
};
|
|
10837
|
+
unsub = client.subscribe(
|
|
10838
|
+
{ query, variables },
|
|
10839
|
+
{
|
|
10840
|
+
next: (payload) => {
|
|
10841
|
+
if (settled) {
|
|
10842
|
+
return;
|
|
10843
|
+
}
|
|
10844
|
+
if (!payload.data) {
|
|
10845
|
+
finalizeError(
|
|
10846
|
+
new Error(
|
|
10847
|
+
`Broken data object from graphQL subscribe: ${JSON.stringify(
|
|
10848
|
+
payload
|
|
10849
|
+
)} for query: ${query}`
|
|
10850
|
+
)
|
|
10851
|
+
);
|
|
10852
|
+
return;
|
|
10853
|
+
}
|
|
10854
|
+
handlers.next(payload.data);
|
|
10855
|
+
},
|
|
10856
|
+
error: (error) => {
|
|
10857
|
+
finalizeError(error);
|
|
10858
|
+
},
|
|
10859
|
+
complete: () => {
|
|
10797
10860
|
return;
|
|
10798
10861
|
}
|
|
10799
|
-
settled = true;
|
|
10800
|
-
cleanup();
|
|
10801
|
-
resolve(data);
|
|
10802
10862
|
}
|
|
10803
|
-
|
|
10863
|
+
);
|
|
10864
|
+
if (typeof timeoutInMs === "number") {
|
|
10865
|
+
timer = setTimeout(() => {
|
|
10866
|
+
finalizeError(
|
|
10867
|
+
new Error(
|
|
10868
|
+
`Timeout expired for graphQL subscribe query: ${query} with timeout: ${timeoutInMs}`
|
|
10869
|
+
)
|
|
10870
|
+
);
|
|
10871
|
+
}, timeoutInMs);
|
|
10872
|
+
}
|
|
10873
|
+
return {
|
|
10874
|
+
unsubscribe: () => {
|
|
10804
10875
|
if (settled) {
|
|
10805
10876
|
return;
|
|
10806
10877
|
}
|
|
10807
10878
|
settled = true;
|
|
10808
10879
|
cleanup();
|
|
10809
|
-
reject(error);
|
|
10810
10880
|
}
|
|
10811
|
-
|
|
10812
|
-
{ query, variables },
|
|
10813
|
-
{
|
|
10814
|
-
next: (data) => {
|
|
10815
|
-
if (!data.data) {
|
|
10816
|
-
finalizeReject(
|
|
10817
|
-
new Error(
|
|
10818
|
-
`Broken data object from graphQL subscribe: ${JSON.stringify(
|
|
10819
|
-
data
|
|
10820
|
-
)} for query: ${query}`
|
|
10821
|
-
)
|
|
10822
|
-
);
|
|
10823
|
-
} else {
|
|
10824
|
-
callback(finalizeResolve, finalizeReject, data.data);
|
|
10825
|
-
}
|
|
10826
|
-
},
|
|
10827
|
-
error: (error) => {
|
|
10828
|
-
finalizeReject(error);
|
|
10829
|
-
},
|
|
10830
|
-
complete: () => {
|
|
10831
|
-
return;
|
|
10832
|
-
}
|
|
10833
|
-
}
|
|
10834
|
-
);
|
|
10835
|
-
if (typeof timeoutInMs === "number") {
|
|
10836
|
-
timer = setTimeout(() => {
|
|
10837
|
-
finalizeReject(
|
|
10838
|
-
new Error(
|
|
10839
|
-
`Timeout expired for graphQL subscribe query: ${query} with timeout: ${timeoutInMs}`
|
|
10840
|
-
)
|
|
10841
|
-
);
|
|
10842
|
-
}, timeoutInMs);
|
|
10843
|
-
}
|
|
10844
|
-
});
|
|
10881
|
+
};
|
|
10845
10882
|
}
|
|
10846
10883
|
|
|
10847
10884
|
// src/features/analysis/graphql/types.ts
|
|
@@ -10944,10 +10981,12 @@ var GQLClient = class {
|
|
|
10944
10981
|
constructor(args) {
|
|
10945
10982
|
__publicField(this, "_client");
|
|
10946
10983
|
__publicField(this, "_clientSdk");
|
|
10984
|
+
__publicField(this, "_apiUrl");
|
|
10947
10985
|
__publicField(this, "_auth");
|
|
10948
10986
|
debug6(`init with ${args}`);
|
|
10949
10987
|
this._auth = args;
|
|
10950
|
-
this.
|
|
10988
|
+
this._apiUrl = args.apiUrl || API_URL;
|
|
10989
|
+
this._client = new GraphQLClient(this._apiUrl, {
|
|
10951
10990
|
headers: args.type === "apiKey" ? { [API_KEY_HEADER_NAME]: args.apiKey || "" } : {
|
|
10952
10991
|
Authorization: `Bearer ${args.token}`
|
|
10953
10992
|
},
|
|
@@ -11212,32 +11251,47 @@ var GQLClient = class {
|
|
|
11212
11251
|
}
|
|
11213
11252
|
async subscribeToAnalysis(params) {
|
|
11214
11253
|
const { callbackStates } = params;
|
|
11215
|
-
return
|
|
11216
|
-
|
|
11217
|
-
|
|
11218
|
-
|
|
11219
|
-
|
|
11220
|
-
|
|
11221
|
-
|
|
11222
|
-
|
|
11223
|
-
|
|
11224
|
-
|
|
11225
|
-
|
|
11226
|
-
|
|
11227
|
-
|
|
11228
|
-
|
|
11229
|
-
|
|
11230
|
-
|
|
11231
|
-
|
|
11232
|
-
|
|
11233
|
-
|
|
11234
|
-
|
|
11235
|
-
|
|
11236
|
-
|
|
11237
|
-
|
|
11238
|
-
|
|
11239
|
-
|
|
11240
|
-
|
|
11254
|
+
return new Promise(
|
|
11255
|
+
(resolve, reject) => {
|
|
11256
|
+
const subscription = subscribeStream(
|
|
11257
|
+
GetAnalysisSubscriptionDocument,
|
|
11258
|
+
params.subscribeToAnalysisParams,
|
|
11259
|
+
{
|
|
11260
|
+
next: async (data) => {
|
|
11261
|
+
if (!data.analysis?.state || data.analysis?.state === "Failed" /* Failed */) {
|
|
11262
|
+
const errorMessage = data.analysis?.failReason || `Analysis failed with id: ${data.analysis?.id}`;
|
|
11263
|
+
subscription.unsubscribe();
|
|
11264
|
+
reject(
|
|
11265
|
+
new ReportDigestError(
|
|
11266
|
+
errorMessage,
|
|
11267
|
+
data.analysis?.failReason ?? ""
|
|
11268
|
+
)
|
|
11269
|
+
);
|
|
11270
|
+
return;
|
|
11271
|
+
}
|
|
11272
|
+
if (callbackStates.includes(data.analysis?.state)) {
|
|
11273
|
+
await params.callback(data.analysis.id);
|
|
11274
|
+
subscription.unsubscribe();
|
|
11275
|
+
resolve(data);
|
|
11276
|
+
}
|
|
11277
|
+
},
|
|
11278
|
+
error: (error) => {
|
|
11279
|
+
subscription.unsubscribe();
|
|
11280
|
+
reject(error);
|
|
11281
|
+
}
|
|
11282
|
+
},
|
|
11283
|
+
this._auth.type === "apiKey" ? {
|
|
11284
|
+
apiKey: this._auth.apiKey,
|
|
11285
|
+
type: "apiKey",
|
|
11286
|
+
timeoutInMs: params.timeoutInMs,
|
|
11287
|
+
proxyAgent: getProxyAgent(this._apiUrl)
|
|
11288
|
+
} : {
|
|
11289
|
+
token: this._auth.token,
|
|
11290
|
+
type: "token",
|
|
11291
|
+
timeoutInMs: params.timeoutInMs,
|
|
11292
|
+
proxyAgent: getProxyAgent(this._apiUrl)
|
|
11293
|
+
}
|
|
11294
|
+
);
|
|
11241
11295
|
}
|
|
11242
11296
|
);
|
|
11243
11297
|
}
|
|
@@ -11321,29 +11375,37 @@ var configStore = getConfigStore();
|
|
|
11321
11375
|
var debug7 = Debug6("mobbdev:commands");
|
|
11322
11376
|
var LOGIN_MAX_WAIT = 10 * 60 * 1e3;
|
|
11323
11377
|
var LOGIN_CHECK_DELAY = 5 * 1e3;
|
|
11324
|
-
var webLoginUrl = `${WEB_APP_URL}/cli-login`;
|
|
11325
11378
|
var MOBB_LOGIN_REQUIRED_MSG = `\u{1F513} Login to Mobb is Required, you will be redirected to our login page, once the authorization is complete return to this prompt, ${chalk3.bgBlue(
|
|
11326
11379
|
"press any key to continue"
|
|
11327
11380
|
)};`;
|
|
11328
11381
|
async function getAuthenticatedGQLClient({
|
|
11329
11382
|
inputApiKey = "",
|
|
11330
|
-
isSkipPrompts = true
|
|
11383
|
+
isSkipPrompts = true,
|
|
11384
|
+
apiUrl,
|
|
11385
|
+
webAppUrl
|
|
11331
11386
|
}) {
|
|
11332
11387
|
let gqlClient = new GQLClient({
|
|
11333
11388
|
apiKey: inputApiKey || configStore.get("apiToken") || "",
|
|
11334
|
-
type: "apiKey"
|
|
11389
|
+
type: "apiKey",
|
|
11390
|
+
apiUrl
|
|
11335
11391
|
});
|
|
11336
11392
|
gqlClient = await handleMobbLogin({
|
|
11337
11393
|
inGqlClient: gqlClient,
|
|
11338
|
-
skipPrompts: isSkipPrompts
|
|
11394
|
+
skipPrompts: isSkipPrompts,
|
|
11395
|
+
apiUrl,
|
|
11396
|
+
webAppUrl
|
|
11339
11397
|
});
|
|
11340
11398
|
return gqlClient;
|
|
11341
11399
|
}
|
|
11342
11400
|
async function handleMobbLogin({
|
|
11343
11401
|
inGqlClient,
|
|
11344
11402
|
apiKey,
|
|
11345
|
-
skipPrompts
|
|
11403
|
+
skipPrompts,
|
|
11404
|
+
apiUrl,
|
|
11405
|
+
webAppUrl
|
|
11346
11406
|
}) {
|
|
11407
|
+
const resolvedWebAppUrl = webAppUrl || WEB_APP_URL;
|
|
11408
|
+
const resolvedApiUrl = apiUrl || API_URL;
|
|
11347
11409
|
const { createSpinner: createSpinner5 } = Spinner({ ci: skipPrompts });
|
|
11348
11410
|
const isConnected = await inGqlClient.verifyApiConnection();
|
|
11349
11411
|
if (!isConnected) {
|
|
@@ -11385,7 +11447,7 @@ async function handleMobbLogin({
|
|
|
11385
11447
|
const loginId = await inGqlClient.createCliLogin({
|
|
11386
11448
|
publicKey: publicKey.export({ format: "pem", type: "pkcs1" }).toString()
|
|
11387
11449
|
});
|
|
11388
|
-
const browserUrl = `${
|
|
11450
|
+
const browserUrl = `${resolvedWebAppUrl}/cli-login/${loginId}?hostname=${os.hostname()}`;
|
|
11389
11451
|
!skipPrompts && console.log(
|
|
11390
11452
|
`If the page does not open automatically, kindly access it through ${browserUrl}.`
|
|
11391
11453
|
);
|
|
@@ -11410,7 +11472,11 @@ async function handleMobbLogin({
|
|
|
11410
11472
|
});
|
|
11411
11473
|
throw new CliError();
|
|
11412
11474
|
}
|
|
11413
|
-
const newGqlClient = new GQLClient({
|
|
11475
|
+
const newGqlClient = new GQLClient({
|
|
11476
|
+
apiKey: newApiToken,
|
|
11477
|
+
type: "apiKey",
|
|
11478
|
+
apiUrl: resolvedApiUrl
|
|
11479
|
+
});
|
|
11414
11480
|
const loginSuccess = await newGqlClient.validateUserToken();
|
|
11415
11481
|
if (loginSuccess) {
|
|
11416
11482
|
debug7(`set api token ${newApiToken}`);
|
|
@@ -13532,42 +13598,36 @@ var openRedaction = new OpenRedaction({
|
|
|
13532
13598
|
"VISA_NUMBER",
|
|
13533
13599
|
"VISA_MRZ",
|
|
13534
13600
|
"TAX_ID",
|
|
13535
|
-
// Financial Data
|
|
13601
|
+
// Financial Data (removed SWIFT_BIC - too broad, matches bank code formats in variables)
|
|
13536
13602
|
"CREDIT_CARD",
|
|
13537
13603
|
"IBAN",
|
|
13538
13604
|
"BANK_ACCOUNT_UK",
|
|
13539
13605
|
"ROUTING_NUMBER_US",
|
|
13540
|
-
"SWIFT_BIC",
|
|
13541
13606
|
"CARD_TRACK1_DATA",
|
|
13542
13607
|
"CARD_TRACK2_DATA",
|
|
13543
13608
|
"CARD_EXPIRY",
|
|
13544
13609
|
"CARD_AUTH_CODE",
|
|
13545
|
-
// Cryptocurrency
|
|
13546
|
-
"BITCOIN_ADDRESS",
|
|
13610
|
+
// Cryptocurrency (removed BITCOIN_ADDRESS - too broad, matches hash-like strings)
|
|
13547
13611
|
"ETHEREUM_ADDRESS",
|
|
13548
13612
|
"LITECOIN_ADDRESS",
|
|
13549
13613
|
"CARDANO_ADDRESS",
|
|
13550
13614
|
"SOLANA_ADDRESS",
|
|
13551
13615
|
"MONERO_ADDRESS",
|
|
13552
13616
|
"RIPPLE_ADDRESS",
|
|
13553
|
-
// Medical Data
|
|
13617
|
+
// Medical Data (removed PRESCRIPTION_NUMBER - too broad, matches words containing "ription")
|
|
13554
13618
|
"NHS_NUMBER",
|
|
13555
13619
|
"MEDICAL_RECORD_NUMBER",
|
|
13556
13620
|
"AUSTRALIAN_MEDICARE",
|
|
13557
13621
|
"HEALTH_PLAN_NUMBER",
|
|
13558
|
-
"PRESCRIPTION_NUMBER",
|
|
13559
13622
|
"PATIENT_ID",
|
|
13560
|
-
// Communications
|
|
13623
|
+
// Communications (removed EMERGENCY_CONTACT, ADDRESS_PO_BOX, ZIP_CODE_US - too broad)
|
|
13561
13624
|
"PHONE_US",
|
|
13562
13625
|
"PHONE_UK",
|
|
13563
13626
|
"PHONE_UK_MOBILE",
|
|
13564
13627
|
"PHONE_INTERNATIONAL",
|
|
13565
13628
|
"PHONE_LINE_NUMBER",
|
|
13566
|
-
"EMERGENCY_CONTACT",
|
|
13567
13629
|
"ADDRESS_STREET",
|
|
13568
|
-
"ADDRESS_PO_BOX",
|
|
13569
13630
|
"POSTCODE_UK",
|
|
13570
|
-
"ZIP_CODE_US",
|
|
13571
13631
|
// Network & Technical
|
|
13572
13632
|
"IPV4",
|
|
13573
13633
|
"IPV6",
|
|
@@ -14751,8 +14811,8 @@ var McpAuthService = class {
|
|
|
14751
14811
|
throw new CliLoginError("Error: createCliLogin failed");
|
|
14752
14812
|
}
|
|
14753
14813
|
logDebug(`cli login created ${loginId}`);
|
|
14754
|
-
const
|
|
14755
|
-
const browserUrl = `${
|
|
14814
|
+
const webLoginUrl = `${WEB_APP_URL}/mvs-login`;
|
|
14815
|
+
const browserUrl = `${webLoginUrl}/${loginId}?hostname=${os4.hostname()}`;
|
|
14756
14816
|
await this.openBrowser(browserUrl, isBackgoundCall);
|
|
14757
14817
|
logDebug(`waiting for login to complete`);
|
|
14758
14818
|
let newApiToken = null;
|
|
@@ -14941,54 +15001,77 @@ var McpGQLClient = class {
|
|
|
14941
15001
|
params: params.subscribeToAnalysisParams
|
|
14942
15002
|
});
|
|
14943
15003
|
const { callbackStates } = params;
|
|
14944
|
-
|
|
14945
|
-
|
|
14946
|
-
|
|
14947
|
-
|
|
14948
|
-
|
|
14949
|
-
|
|
14950
|
-
|
|
14951
|
-
|
|
14952
|
-
|
|
14953
|
-
|
|
14954
|
-
|
|
14955
|
-
|
|
14956
|
-
|
|
14957
|
-
|
|
14958
|
-
|
|
14959
|
-
|
|
14960
|
-
|
|
14961
|
-
|
|
14962
|
-
|
|
14963
|
-
|
|
14964
|
-
|
|
14965
|
-
|
|
14966
|
-
|
|
14967
|
-
|
|
14968
|
-
|
|
14969
|
-
|
|
15004
|
+
return new Promise(
|
|
15005
|
+
(resolve, reject) => {
|
|
15006
|
+
const subscription = subscribeStream(
|
|
15007
|
+
GetAnalysisSubscriptionDocument,
|
|
15008
|
+
params.subscribeToAnalysisParams,
|
|
15009
|
+
{
|
|
15010
|
+
next: async (data) => {
|
|
15011
|
+
logDebug(
|
|
15012
|
+
`[${scanContext}] GraphQL: GetAnalysis subscription data received ${data.analysis?.state}`,
|
|
15013
|
+
{ data }
|
|
15014
|
+
);
|
|
15015
|
+
if (!data.analysis?.state || data.analysis?.state === "Failed" /* Failed */) {
|
|
15016
|
+
const errorMessage = data.analysis?.failReason || `Analysis failed with id: ${data.analysis?.id}`;
|
|
15017
|
+
logError(`[${scanContext}] GraphQL: Analysis failed`, {
|
|
15018
|
+
analysisId: data.analysis?.id,
|
|
15019
|
+
state: data.analysis?.state,
|
|
15020
|
+
failReason: data.analysis?.failReason,
|
|
15021
|
+
...this.getErrorContext()
|
|
15022
|
+
});
|
|
15023
|
+
subscription.unsubscribe();
|
|
15024
|
+
reject(new Error(errorMessage));
|
|
15025
|
+
return;
|
|
15026
|
+
}
|
|
15027
|
+
if (callbackStates.includes(data.analysis?.state)) {
|
|
15028
|
+
logDebug(
|
|
15029
|
+
`[${scanContext}] GraphQL: Analysis state matches callback states: ${data.analysis.state}`,
|
|
15030
|
+
{
|
|
15031
|
+
analysisId: data.analysis.id,
|
|
15032
|
+
state: data.analysis.state,
|
|
15033
|
+
callbackStates
|
|
15034
|
+
}
|
|
15035
|
+
);
|
|
15036
|
+
await params.callback(data.analysis.id);
|
|
15037
|
+
subscription.unsubscribe();
|
|
15038
|
+
logDebug(
|
|
15039
|
+
`[${scanContext}] GraphQL: GetAnalysis subscription completed`,
|
|
15040
|
+
{
|
|
15041
|
+
analysisId: data.analysis.id,
|
|
15042
|
+
state: data.analysis.state
|
|
15043
|
+
}
|
|
15044
|
+
);
|
|
15045
|
+
resolve(data);
|
|
15046
|
+
}
|
|
15047
|
+
},
|
|
15048
|
+
error: (error) => {
|
|
15049
|
+
logError(
|
|
15050
|
+
`[${scanContext}] GraphQL: GetAnalysis subscription failed`,
|
|
15051
|
+
{
|
|
15052
|
+
error,
|
|
15053
|
+
params: params.subscribeToAnalysisParams,
|
|
15054
|
+
...this.getErrorContext()
|
|
15055
|
+
}
|
|
15056
|
+
);
|
|
15057
|
+
subscription.unsubscribe();
|
|
15058
|
+
reject(error);
|
|
14970
15059
|
}
|
|
14971
|
-
|
|
14972
|
-
|
|
14973
|
-
|
|
14974
|
-
|
|
14975
|
-
|
|
14976
|
-
|
|
14977
|
-
|
|
14978
|
-
|
|
14979
|
-
|
|
14980
|
-
|
|
14981
|
-
|
|
14982
|
-
|
|
14983
|
-
|
|
14984
|
-
timeoutInMs: params.timeoutInMs,
|
|
14985
|
-
proxyAgent: getProxyAgent2(this.apiUrl)
|
|
15060
|
+
},
|
|
15061
|
+
this._auth.type === "apiKey" ? {
|
|
15062
|
+
apiKey: this._auth.apiKey,
|
|
15063
|
+
type: "apiKey",
|
|
15064
|
+
timeoutInMs: params.timeoutInMs,
|
|
15065
|
+
proxyAgent: getProxyAgent2(this.apiUrl)
|
|
15066
|
+
} : {
|
|
15067
|
+
token: this._auth.token,
|
|
15068
|
+
type: "token",
|
|
15069
|
+
timeoutInMs: params.timeoutInMs,
|
|
15070
|
+
proxyAgent: getProxyAgent2(this.apiUrl)
|
|
15071
|
+
}
|
|
15072
|
+
);
|
|
14986
15073
|
}
|
|
14987
15074
|
);
|
|
14988
|
-
logDebug(`[${scanContext}] GraphQL: GetAnalysis subscription completed`, {
|
|
14989
|
-
result
|
|
14990
|
-
});
|
|
14991
|
-
return result;
|
|
14992
15075
|
} catch (e) {
|
|
14993
15076
|
logError(`[${scanContext}] GraphQL: GetAnalysis subscription failed`, {
|
|
14994
15077
|
error: e,
|