Skip to content

Commit c136e2b

Browse files
authored
fix: Endpoint /upgradeToRevocableSession ignores _Session protectedFields (#10408)
1 parent 8b19852 commit c136e2b

File tree

2 files changed

+61
-17
lines changed

2 files changed

+61
-17
lines changed

spec/RevocableSessionsUpgrade.spec.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,4 +136,36 @@ describe_only_db('mongo')('revocable sessions', () => {
136136
done();
137137
});
138138
});
139+
140+
it('should strip protected fields from upgrade response when protectedFieldsSaveResponseExempt is false', async () => {
141+
await reconfigureServer({
142+
protectedFields: {
143+
_Session: { '*': ['createdWith', 'installationId'] },
144+
},
145+
protectedFieldsSaveResponseExempt: false,
146+
});
147+
const config = Config.get(Parse.applicationId);
148+
const user = {
149+
objectId: 'pfUser123',
150+
username: 'pfuser',
151+
password: 'pass',
152+
_session_token: 'legacySessionTokenPf',
153+
};
154+
await config.database.create('_User', user);
155+
156+
const response = await request({
157+
method: 'POST',
158+
url: Parse.serverURL + '/upgradeToRevocableSession',
159+
headers: {
160+
'X-Parse-Application-Id': Parse.applicationId,
161+
'X-Parse-Rest-API-Key': 'rest',
162+
'X-Parse-Session-Token': 'legacySessionTokenPf',
163+
'X-Parse-Installation-Id': 'test-install-id',
164+
},
165+
});
166+
expect(response.data.sessionToken).toBeDefined();
167+
expect(response.data.sessionToken.indexOf('r:')).toBe(0);
168+
expect(response.data.createdWith).toBeUndefined();
169+
expect(response.data.installationId).toBeUndefined();
170+
});
139171
});

src/Routers/SessionsRouter.js

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ export class SessionsRouter extends ClassesRouter {
5858
};
5959
}
6060

61-
handleUpdateToRevocableSession(req) {
61+
async handleUpdateToRevocableSession(req) {
6262
const config = req.config;
6363
const user = req.auth.user;
6464
// Issue #2720
@@ -74,22 +74,34 @@ export class SessionsRouter extends ClassesRouter {
7474
installationId: req.auth.installationId,
7575
});
7676

77-
return createSession()
78-
.then(() => {
79-
// delete the session token, use the db to skip beforeSave
80-
return config.database.update(
81-
'_User',
82-
{
83-
objectId: user.id,
84-
},
85-
{
86-
sessionToken: { __op: 'Delete' },
87-
}
88-
);
89-
})
90-
.then(() => {
91-
return Promise.resolve({ response: sessionData });
92-
});
77+
await createSession();
78+
// delete the session token, use the db to skip beforeSave
79+
await config.database.update(
80+
'_User',
81+
{ objectId: user.id },
82+
{ sessionToken: { __op: 'Delete' } }
83+
);
84+
// Re-fetch the session with the caller's auth context so that
85+
// protectedFields filtering applies correctly
86+
const userAuth = new Auth.Auth({
87+
config,
88+
isMaster: false,
89+
user: Parse.Object.fromJSON({ className: '_User', objectId: user.id }),
90+
installationId: req.auth.installationId,
91+
});
92+
const response = await rest.find(
93+
config,
94+
userAuth,
95+
'_Session',
96+
{ sessionToken: sessionData.sessionToken },
97+
{},
98+
req.info.clientSDK,
99+
req.info.context
100+
);
101+
if (!response.results || response.results.length === 0) {
102+
throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'Failed to load upgraded session.');
103+
}
104+
return { response: response.results[0] };
93105
}
94106

95107
mountRoutes() {

0 commit comments

Comments
 (0)