fix: Throwing error in Cloud Code Triggers afterLogin, afterLogout crashes server (#8280)
BREAKING CHANGE: Throwing an error in Cloud Code Triggers `afterLogin`, `afterLogout` returns a rejected promise; in previous releases it crashed the server if you did not handle the error on the Node.js process level; consider adapting your code if your app currently handles these errors on the Node.js process level with `process.on('unhandledRejection', ...)`
This commit is contained in:
@@ -3103,6 +3103,36 @@ describe('beforeLogin hook', () => {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('does not crash server when throwing in afterLogin hook', async () => {
|
||||||
|
const error = new Parse.Error(2000, 'afterLogin error');
|
||||||
|
const trigger = {
|
||||||
|
afterLogin() {
|
||||||
|
throw error;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const spy = spyOn(trigger, 'afterLogin').and.callThrough();
|
||||||
|
Parse.Cloud.afterLogin(trigger.afterLogin);
|
||||||
|
await Parse.User.signUp('user', 'pass');
|
||||||
|
const response = await Parse.User.logIn('user', 'pass').catch(e => e);
|
||||||
|
expect(spy).toHaveBeenCalled();
|
||||||
|
expect(response).toEqual(error);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not crash server when throwing in afterLogout hook', async () => {
|
||||||
|
const error = new Parse.Error(2000, 'afterLogout error');
|
||||||
|
const trigger = {
|
||||||
|
afterLogout() {
|
||||||
|
throw error;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const spy = spyOn(trigger, 'afterLogout').and.callThrough();
|
||||||
|
Parse.Cloud.afterLogout(trigger.afterLogout);
|
||||||
|
await Parse.User.signUp('user', 'pass');
|
||||||
|
const response = await Parse.User.logOut().catch(e => e);
|
||||||
|
expect(spy).toHaveBeenCalled();
|
||||||
|
expect(response).toEqual(error);
|
||||||
|
});
|
||||||
|
|
||||||
it('should have expected data in request', async done => {
|
it('should have expected data in request', async done => {
|
||||||
Parse.Cloud.beforeLogin(req => {
|
Parse.Cloud.beforeLogin(req => {
|
||||||
expect(req.object).toBeDefined();
|
expect(req.object).toBeDefined();
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ export class UsersRouter extends ClassesRouter {
|
|||||||
await createSession();
|
await createSession();
|
||||||
|
|
||||||
const afterLoginUser = Parse.User.fromJSON(Object.assign({ className: '_User' }, user));
|
const afterLoginUser = Parse.User.fromJSON(Object.assign({ className: '_User' }, user));
|
||||||
maybeRunTrigger(
|
await maybeRunTrigger(
|
||||||
TriggerTypes.afterLogin,
|
TriggerTypes.afterLogin,
|
||||||
{ ...req.auth, user: afterLoginUser },
|
{ ...req.auth, user: afterLoginUser },
|
||||||
afterLoginUser,
|
afterLoginUser,
|
||||||
@@ -360,11 +360,10 @@ export class UsersRouter extends ClassesRouter {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleLogOut(req) {
|
async handleLogOut(req) {
|
||||||
const success = { response: {} };
|
const success = { response: {} };
|
||||||
if (req.info && req.info.sessionToken) {
|
if (req.info && req.info.sessionToken) {
|
||||||
return rest
|
const records = await rest.find(
|
||||||
.find(
|
|
||||||
req.config,
|
req.config,
|
||||||
Auth.master(req.config),
|
Auth.master(req.config),
|
||||||
'_Session',
|
'_Session',
|
||||||
@@ -372,38 +371,26 @@ export class UsersRouter extends ClassesRouter {
|
|||||||
undefined,
|
undefined,
|
||||||
req.info.clientSDK,
|
req.info.clientSDK,
|
||||||
req.info.context
|
req.info.context
|
||||||
)
|
);
|
||||||
.then(records => {
|
|
||||||
if (records.results && records.results.length) {
|
if (records.results && records.results.length) {
|
||||||
return rest
|
await rest.del(
|
||||||
.del(
|
|
||||||
req.config,
|
req.config,
|
||||||
Auth.master(req.config),
|
Auth.master(req.config),
|
||||||
'_Session',
|
'_Session',
|
||||||
records.results[0].objectId,
|
records.results[0].objectId,
|
||||||
req.info.context
|
req.info.context
|
||||||
)
|
);
|
||||||
.then(() => {
|
await maybeRunTrigger(
|
||||||
this._runAfterLogoutTrigger(req, records.results[0]);
|
|
||||||
return Promise.resolve(success);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return Promise.resolve(success);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return Promise.resolve(success);
|
|
||||||
}
|
|
||||||
|
|
||||||
_runAfterLogoutTrigger(req, session) {
|
|
||||||
// After logout trigger
|
|
||||||
maybeRunTrigger(
|
|
||||||
TriggerTypes.afterLogout,
|
TriggerTypes.afterLogout,
|
||||||
req.auth,
|
req.auth,
|
||||||
Parse.Session.fromJSON(Object.assign({ className: '_Session' }, session)),
|
Parse.Session.fromJSON(Object.assign({ className: '_Session' }, records.results[0])),
|
||||||
null,
|
null,
|
||||||
req.config
|
req.config
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
_throwOnBadEmailConfig(req) {
|
_throwOnBadEmailConfig(req) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user