-
Notifications
You must be signed in to change notification settings - Fork 0
OAuth credential sync and app integration enhancements #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: oauth-security-base
Are you sure you want to change the base?
Conversation
…11059) * Add credential sync .env variables * Add webhook to send app credentials * Upsert credentials when webhook called * Refresh oauth token from a specific endpoint * Pass appSlug * Add credential encryption * Move oauth helps into a folder * Create parse token response wrapper * Add OAuth helpers to apps * Clean up * Refactor `appDirName` to `appSlug` * Address feedback * Change to safe parse * Remove console.log --------- Co-authored-by: Syed Ali Shahbaz <[email protected]> Co-authored-by: Omar López <[email protected]>
|
@claude review this PR |
1 similar comment
|
@claude review this PR |
|
Claude finished @akshayutture-augment's task —— View job Code Review CompleteI've reviewed the OAuth credential sync and app integration enhancements PR. Here's my comprehensive feedback: 🔐 Security IssuesCritical: Webhook Authentication VulnerabilityFile: The webhook secret validation has a significant vulnerability: if (
req.headers[process.env.CALCOM_WEBHOOK_HEADER_NAME || "calcom-webhook-secret"] !==
process.env.CALCOM_WEBHOOK_SECRET
) {
return res.status(403).json({ message: "Invalid webhook secret" });
}Issues:
Recommendations:
Critical: Missing Input ValidationFile: The decryption happens without proper error handling: const keys = JSON.parse(
symmetricDecrypt(reqBody.keys, process.env.CALCOM_APP_CREDENTIAL_ENCRYPTION_KEY || "")
);Issues:
Recommendations: if (!process.env.CALCOM_APP_CREDENTIAL_ENCRYPTION_KEY) {
return res.status(500).json({ message: "Server configuration error" });
}
let keys;
try {
const decrypted = symmetricDecrypt(reqBody.keys, process.env.CALCOM_APP_CREDENTIAL_ENCRYPTION_KEY);
keys = JSON.parse(decrypted);
} catch (error) {
return res.status(400).json({ message: "Invalid encrypted payload" });
}Medium: Timing Attack VulnerabilityFile: The direct string comparison for webhook secret is vulnerable to timing attacks. Recommendation: Use a constant-time comparison function like 🐛 Logic IssuesBug: Incorrect Error Handling in parseRefreshTokenResponseFile: if (!refreshTokenResponse.data.refresh_token) {
refreshTokenResponse.data.refresh_token = "refresh_token";
}Issue: Setting a placeholder string
Bug: Missing Import in Salesforce CalendarServiceFile: await prisma.credential.update({The file uses Bug: Promise Not ReturnedFile: async deleteEvent(uid: string) {
const deletedEvent = await this.salesforceDeleteEvent(uid);
if (deletedEvent.success) {
Promise.resolve(); // ❌ Not returned!
} else {
Promise.reject({ calError: "Something went wrong when deleting the event in Salesforce" });
}
}Issue: Fix: async deleteEvent(uid: string) {
const deletedEvent = await this.salesforceDeleteEvent(uid);
if (deletedEvent.success) {
return;
} else {
throw new Error("Something went wrong when deleting the event in Salesforce");
}
}🔄 Consistency IssuesInconsistent refreshOAuthTokens ImplementationThe Google Calendar (packages/app-store/googlecalendar/lib/CalendarService.ts:86-93): ✅ Correctly awaits the response const res = await refreshOAuthTokens(
async () => {
const fetchTokens = await myGoogleAuth.refreshToken(googleCredentials.refresh_token);
return fetchTokens.res;
},
"google-calendar",
credential.userId
);Hubspot (packages/app-store/hubspot/lib/CalendarService.ts:177-189): const hubspotRefreshToken: HubspotToken = await refreshOAuthTokens(
async () => await hubspotClient.oauth.tokensApi.createToken(...),
"hubspot",
credential.userId
);Issue: Hubspot assumes the return type is Recommendation: Add type guards or use 🎯 Design ConcernsUnclear Feature Flag LogicFile: The logic branches based on
Issues:
Recommendations:
Weak Schema in parseRefreshTokenResponseFile: const minimumTokenResponseSchema = z.object({
access_token: z.string(),
[z.string().toString()]: z.number(),
[z.string().optional().toString()]: z.unknown().optional(),
});Issue: This schema is too permissive. Using dynamic keys like Expected behavior: The schema should be defined with explicit fields or use 📝 Code Quality IssuesMissing Error HandlingMultiple service files make network requests without comprehensive error handling: Office365 Calendar (packages/app-store/office365calendar/lib/CalendarService.ts:246-261): const response = await refreshOAuthTokens(
async () => await fetch("https://login.microsoftonline.com/common/oauth2/v2.0/token", {
// ... fetch options
}),
"office365-calendar",
credential.userId
);
const responseJson = await handleErrorsJson(response);Issue: No validation that Inconsistent Import PathsThe OAuth utility files were moved to a new
All imports were updated, but this is a good opportunity to:
✅ Positive Aspects
🔍 Testing Recommendations
📋 SummaryMust Fix Before Merge:
Should Fix:
Nice to Have:
|
|
This PR is being marked as stale due to inactivity. |
Test 8
Replicated from ai-code-review-evaluation/cal.com-greptile#8