|
1 | 1 | const Parse = require('parse/node'); |
| 2 | +import { isDeepStrictEqual } from 'util'; |
2 | 3 | import { getRequestObject, resolveError } from './triggers'; |
3 | 4 | import { logger } from './logger'; |
4 | 5 | import { LRUCache as LRU } from 'lru-cache'; |
@@ -468,16 +469,21 @@ const hasMutatedAuthData = (authData, userAuthData) => { |
468 | 469 | return; |
469 | 470 | } |
470 | 471 |
|
471 | | - // If provider exists, check if the id has changed |
472 | | - // Only consider it mutated if the id is different |
473 | | - // This prevents re-validation when auth adapters strip fields via afterFind |
474 | | - if (providerData?.id !== userProviderAuthData?.id) { |
| 472 | + // Check if incoming data represents actual changes vs just echoing back |
| 473 | + // what afterFind returned. If incoming data is a subset of stored data |
| 474 | + // (all incoming fields match stored values), it's not mutated. |
| 475 | + // If incoming data has different values or fields not in stored data, it's mutated. |
| 476 | + // This handles the case where afterFind strips sensitive fields like 'code': |
| 477 | + // - Incoming: { id: 'x' }, Stored: { id: 'x', code: 'secret' } -> NOT mutated (subset) |
| 478 | + // - Incoming: { id: 'x', token: 'new' }, Stored: { id: 'x', token: 'old' } -> MUTATED |
| 479 | + const incomingKeys = Object.keys(providerData || {}); |
| 480 | + const hasChanges = incomingKeys.some(key => { |
| 481 | + return !isDeepStrictEqual(providerData[key], userProviderAuthData[key]); |
| 482 | + }); |
| 483 | + |
| 484 | + if (hasChanges) { |
475 | 485 | mutatedAuthData[provider] = providerData; |
476 | | - return; |
477 | 486 | } |
478 | | - |
479 | | - // If id is the same, don't treat as mutation even if other fields differ |
480 | | - // This handles the case where afterFind strips sensitive fields like 'code' |
481 | 487 | }); |
482 | 488 | const hasMutatedAuthData = Object.keys(mutatedAuthData).length !== 0; |
483 | 489 | return { hasMutatedAuthData, mutatedAuthData }; |
|
0 commit comments