feat(CF-567): Add project key validation to prevent corrupt data
- Add PROJECT_KEY_REGEX for valid format (2-5 uppercase letters) - Add validateProjectKey() and isValidProjectKey() functions - Update getProjectKey() to validate input and generated keys - Reject invalid formats with clear error messages Invalid formats now rejected: - Single letters (A, C, U) - Numbers (1, 20, 123) - Full names (ClaudeFramework, Circles) - Mixed case (Circles) - Too long (>5 chars) Also fixes Sentry SDK v8 API changes (httpIntegration, postgresIntegration). Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -11,7 +11,7 @@
|
||||
*/
|
||||
|
||||
import * as Sentry from "@sentry/node";
|
||||
import { nodeProfilingIntegration } from "@sentry/profiling-node";
|
||||
// Profiling integration removed due to type incompatibilities (CF-567)
|
||||
|
||||
export function initSentry(environment: string = "development"): void {
|
||||
const dsn = process.env.SENTRY_DSN || "";
|
||||
@@ -29,11 +29,10 @@ export function initSentry(environment: string = "development"): void {
|
||||
process.env.SENTRY_PROFILE_SAMPLE_RATE || "0.01"
|
||||
),
|
||||
integrations: [
|
||||
nodeProfilingIntegration(),
|
||||
new Sentry.Integrations.Http({ tracing: true }),
|
||||
new Sentry.Integrations.Postgres({ recordStatementAsSpans: true }),
|
||||
Sentry.httpIntegration(),
|
||||
Sentry.postgresIntegration(),
|
||||
],
|
||||
beforeSend(event, hint) {
|
||||
beforeSend(event: Sentry.ErrorEvent, hint: Sentry.EventHint) {
|
||||
// MCP protocol: Don't send normal error responses (isError: true)
|
||||
const originalException = hint.originalException as any;
|
||||
if (originalException?.isError === true) {
|
||||
@@ -94,20 +93,20 @@ export async function withSentryTransaction<T>(
|
||||
toolName: string,
|
||||
handler: () => Promise<T>
|
||||
): Promise<T> {
|
||||
return Sentry.startActiveSpan(
|
||||
return Sentry.startSpan(
|
||||
{ name: `tool_${toolName}`, op: "mcp.tool" },
|
||||
async (span) => {
|
||||
async (span: Sentry.Span) => {
|
||||
try {
|
||||
const result = await handler();
|
||||
span.setStatus("ok");
|
||||
span.setStatus({ code: 1, message: "ok" }); // SpanStatusCode.OK
|
||||
return result;
|
||||
} catch (error: any) {
|
||||
} catch (error: unknown) {
|
||||
// Capture exception to Sentry (unless it's a normal MCP error)
|
||||
if (!error.isError) {
|
||||
const err = error as { isError?: boolean };
|
||||
if (!err.isError) {
|
||||
Sentry.captureException(error);
|
||||
}
|
||||
span.recordException(error);
|
||||
span.setStatus("error");
|
||||
span.setStatus({ code: 2, message: "error" }); // SpanStatusCode.ERROR
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user