OAuth credential sync and app integration enhancements#4
OAuth credential sync and app integration enhancements#4akshayutture-augment wants to merge 1 commit into
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 <52925846+alishaz-polymath@users.noreply.github.com> Co-authored-by: Omar López <zomars@me.com>
|
@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