Skip to content

Commit 629b2da

Browse files
Copilotmtrezza
andcommitted
Add test for multi-provider authData issue
Co-authored-by: mtrezza <5673677+mtrezza@users.noreply.github.com>
1 parent eb5156c commit 629b2da

1 file changed

Lines changed: 73 additions & 0 deletions

File tree

spec/AuthenticationAdaptersV2.spec.js

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,41 @@ describe('Auth Adapter features', () => {
7676
validateAppId: () => Promise.resolve(),
7777
};
7878

79+
// Code-based adapter that requires 'code' field (like gpgames)
80+
const codeBasedAdapter = {
81+
validateAppId: () => Promise.resolve(),
82+
validateSetUp: authData => {
83+
if (!authData.code) {
84+
throw new Error('code is required.');
85+
}
86+
return Promise.resolve({ save: { id: authData.id } });
87+
},
88+
validateUpdate: authData => {
89+
if (!authData.code) {
90+
throw new Error('code is required.');
91+
}
92+
return Promise.resolve({ save: { id: authData.id } });
93+
},
94+
validateLogin: authData => {
95+
if (!authData.code) {
96+
throw new Error('code is required.');
97+
}
98+
return Promise.resolve({ save: { id: authData.id } });
99+
},
100+
afterFind: authData => {
101+
// Strip sensitive 'code' field when returning to client
102+
return { id: authData.id };
103+
},
104+
};
105+
106+
// Simple adapter that doesn't require code
107+
const simpleAdapter = {
108+
validateAppId: () => Promise.resolve(),
109+
validateSetUp: () => Promise.resolve(),
110+
validateUpdate: () => Promise.resolve(),
111+
validateLogin: () => Promise.resolve(),
112+
};
113+
79114
const headers = {
80115
'Content-Type': 'application/json',
81116
'X-Parse-Application-Id': 'test',
@@ -1302,4 +1337,42 @@ describe('Auth Adapter features', () => {
13021337
await user.fetch({ useMasterKey: true });
13031338
expect(user.get('authData')).toEqual({ adapterB: { id: 'test' } });
13041339
});
1340+
1341+
it('should handle multiple providers: add one while another remains unchanged (code-based)', async () => {
1342+
await reconfigureServer({
1343+
auth: {
1344+
codeBasedAdapter,
1345+
simpleAdapter,
1346+
},
1347+
});
1348+
1349+
// Login with code-based provider
1350+
const user = new Parse.User();
1351+
await user.save({ authData: { codeBasedAdapter: { id: 'user1', code: 'code1' } } });
1352+
const sessionToken = user.getSessionToken();
1353+
await user.fetch({ sessionToken });
1354+
1355+
// At this point, authData.codeBasedAdapter only has {id: 'user1'} due to afterFind
1356+
const current = user.get('authData') || {};
1357+
expect(current.codeBasedAdapter).toEqual({ id: 'user1' });
1358+
1359+
// Add a second provider while keeping the first unchanged
1360+
user.set('authData', {
1361+
...current,
1362+
simpleAdapter: { id: 'simple1' },
1363+
// codeBasedAdapter is NOT modified (no new code provided)
1364+
});
1365+
1366+
// This should succeed without requiring 'code' for codeBasedAdapter
1367+
await user.save(null, { sessionToken });
1368+
1369+
// Verify both providers are present
1370+
const reloaded = await new Parse.Query(Parse.User).get(user.id, {
1371+
useMasterKey: true,
1372+
});
1373+
1374+
const authData = reloaded.get('authData') || {};
1375+
expect(authData.simpleAdapter && authData.simpleAdapter.id).toBe('simple1');
1376+
expect(authData.codeBasedAdapter && authData.codeBasedAdapter.id).toBe('user1');
1377+
});
13051378
});

0 commit comments

Comments
 (0)