fix: address all code review findings
- Extract shared permission logic into boardPermissions.ts utility - Fix DnD drag revert: add dirty flag to prevent overwrite - Wrap OAuth group sync in Prisma transaction (N+1 fix) - Add empty widgetIds validation in widget reorder API - Add invalidateAll() after guest toggle PATCH - Replace console.error with user-visible error banners - Extract WidgetCreationForm component (DraggableSection was 448 lines) - Remove unused boardId prop from DraggableSection - Always include OAuth state parameter + validate in callback - Clean up copyLink timer on component destroy - Add type-specific widget config validation in addWidget action
This commit is contained in:
@@ -26,17 +26,29 @@ export const GET: RequestHandler = async ({ url, cookies }) => {
|
||||
throw new Error('No authorization code received from OAuth provider');
|
||||
}
|
||||
|
||||
// Retrieve the code_verifier from the cookie
|
||||
// Retrieve the code_verifier and state from cookies
|
||||
const codeVerifier = cookies.get('oauth_code_verifier');
|
||||
if (!codeVerifier) {
|
||||
throw new Error('OAuth session expired. Please try logging in again.');
|
||||
}
|
||||
|
||||
// Clear the code_verifier cookie
|
||||
const expectedState = cookies.get('oauth_state');
|
||||
if (!expectedState) {
|
||||
throw new Error('OAuth session expired. Please try logging in again.');
|
||||
}
|
||||
|
||||
// Validate the state parameter matches to prevent CSRF
|
||||
const returnedState = url.searchParams.get('state');
|
||||
if (returnedState !== expectedState) {
|
||||
throw new Error('OAuth state mismatch. Possible CSRF attack. Please try logging in again.');
|
||||
}
|
||||
|
||||
// Clear the OAuth cookies
|
||||
cookies.delete('oauth_code_verifier', { path: '/' });
|
||||
cookies.delete('oauth_state', { path: '/' });
|
||||
|
||||
// Exchange the authorization code for tokens and get user info
|
||||
const userInfo = await oauthService.handleCallback(url, codeVerifier);
|
||||
const userInfo = await oauthService.handleCallback(url, codeVerifier, expectedState);
|
||||
|
||||
// Find or create local user from OAuth info
|
||||
const user = await userService.findOrCreateByOAuth({
|
||||
|
||||
Reference in New Issue
Block a user