Skip to content

Commit 309790c

Browse files
authored
Stateless UserController (#846)
* Stateless UserController * revert become, add me
1 parent e19da0e commit 309790c

File tree

4 files changed

+112
-15
lines changed

4 files changed

+112
-15
lines changed

src/CoreManager.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,8 @@ type UserController = {
121121
logIn: (user: ParseUser, options: RequestOptions) => Promise;
122122
become: (options: RequestOptions) => Promise;
123123
hydrate: (userJSON: AttributeMap) => Promise;
124-
logOut: () => Promise;
124+
logOut: (options: RequestOptions) => Promise;
125+
me: (options: RequestOptions) => Promise;
125126
requestPasswordReset: (email: string, options: RequestOptions) => Promise;
126127
updateUserOnDisk: (user: ParseUser) => Promise;
127128
upgradeToRevocableSession: (user: ParseUser, options: RequestOptions) => Promise;
@@ -378,6 +379,7 @@ module.exports = {
378379
'logIn',
379380
'become',
380381
'logOut',
382+
'me',
381383
'requestPasswordReset',
382384
'upgradeToRevocableSession',
383385
'linkWith',

src/ParseUser.js

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,25 @@ class ParseUser extends ParseObject {
651651
return controller.become(becomeOptions);
652652
}
653653

654+
/**
655+
* Retrieves a user with a session token.
656+
*
657+
* @param {String} sessionToken The sessionToken to get user with.
658+
* @param {Object} options
659+
* @static
660+
* @return {Promise} A promise that is fulfilled with the user is fetched.
661+
*/
662+
static me(sessionToken: string, options?: RequestOptions = {}) {
663+
const controller = CoreManager.getUserController();
664+
const meOptions: RequestOptions = {
665+
sessionToken: sessionToken
666+
};
667+
if (options.useMasterKey) {
668+
meOptions.useMasterKey = options.useMasterKey;
669+
}
670+
return controller.me(meOptions);
671+
}
672+
654673
/**
655674
* Logs in a user with a session token. On success, this saves the session
656675
* to disk, so you can retrieve the currently logged in user using
@@ -674,20 +693,15 @@ class ParseUser extends ParseObject {
674693
* Logs out the currently logged in user session. This will remove the
675694
* session from disk, log out of linked services, and future calls to
676695
* <code>current</code> will return <code>null</code>.
677-
696+
*
697+
* @param {Object} options
678698
* @static
679699
* @return {Promise} A promise that is resolved when the session is
680700
* destroyed on the server.
681701
*/
682-
static logOut() {
683-
if (!canUseCurrentUser) {
684-
throw new Error(
685-
'There is no current user on a node.js server environment.'
686-
);
687-
}
688-
702+
static logOut(options: RequestOptions = {}) {
689703
const controller = CoreManager.getUserController();
690-
return controller.logOut();
704+
return controller.logOut(options);
691705
}
692706

693707
/**
@@ -998,11 +1012,28 @@ const DefaultController = {
9981012
}
9991013
},
10001014

1001-
logOut(): Promise<ParseUser> {
1015+
me(options: RequestOptions): Promise<ParseUser> {
1016+
const RESTController = CoreManager.getRESTController();
1017+
return RESTController.request(
1018+
'GET', 'users/me', {}, options
1019+
).then((response) => {
1020+
const user = new ParseUser();
1021+
user._finishFetch(response);
1022+
user._setExisted(true);
1023+
return user;
1024+
});
1025+
},
1026+
1027+
logOut(options: RequestOptions): Promise<ParseUser> {
1028+
const RESTController = CoreManager.getRESTController();
1029+
if (options.sessionToken) {
1030+
return RESTController.request(
1031+
'POST', 'logout', {}, options
1032+
);
1033+
}
10021034
return DefaultController.currentUserAsync().then((currentUser) => {
10031035
const path = Storage.generatePath(CURRENT_USER_KEY);
10041036
let promise = Storage.removeItemAsync(path);
1005-
const RESTController = CoreManager.getRESTController();
10061037
if (currentUser !== null) {
10071038
const isAnonymous = AnonymousUtils.isLinked(currentUser);
10081039
const currentSession = currentUser.getSessionToken();

src/__tests__/ParseUser-test.js

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,6 @@ describe('ParseUser', () => {
137137
expect(ParseUser.become.bind(null, 'token')).toThrow(
138138
'It is not memory-safe to become a user in a server environment'
139139
);
140-
expect(ParseUser.logOut).toThrow(
141-
'There is no current user on a node.js server environment.'
142-
);
143140
});
144141

145142
it('can sign up a new user', (done) => {
@@ -675,6 +672,71 @@ describe('ParseUser', () => {
675672
});
676673
});
677674

675+
it('can retreive a user with sessionToken (me)', async () => {
676+
ParseUser.disableUnsafeCurrentUser();
677+
ParseUser._clearCache();
678+
CoreManager.setRESTController({
679+
request(method, path, body, options) {
680+
expect(method).toBe('GET');
681+
expect(path).toBe('users/me');
682+
expect(options.sessionToken).toBe('123abc');
683+
return Promise.resolve({
684+
objectId: 'uid3',
685+
username: 'username',
686+
sessionToken: '123abc'
687+
}, 200);
688+
},
689+
ajax() {}
690+
});
691+
692+
const user = await ParseUser.me('123abc');
693+
expect(user.id).toBe('uid3');
694+
expect(user.isCurrent()).toBe(false);
695+
expect(user.existed()).toBe(true);
696+
});
697+
698+
it('can retreive a user with sessionToken and masterKey(me)', async () => {
699+
ParseUser.disableUnsafeCurrentUser();
700+
ParseUser._clearCache();
701+
CoreManager.setRESTController({
702+
request(method, path, body, options) {
703+
expect(method).toBe('GET');
704+
expect(path).toBe('users/me');
705+
expect(options.sessionToken).toBe('123abc');
706+
expect(options.useMasterKey).toBe(true);
707+
return Promise.resolve({
708+
objectId: 'uid3',
709+
username: 'username',
710+
sessionToken: '123abc'
711+
}, 200);
712+
},
713+
ajax() {}
714+
});
715+
716+
const user = await ParseUser.me('123abc', { useMasterKey: true });
717+
expect(user.id).toBe('uid3');
718+
expect(user.isCurrent()).toBe(false);
719+
expect(user.existed()).toBe(true);
720+
});
721+
722+
it('can logout user with sessionToken', async () => {
723+
ParseUser.disableUnsafeCurrentUser();
724+
ParseUser._clearCache();
725+
Storage._clear();
726+
const RESTController = {
727+
request() {
728+
return Promise.resolve({}, 200);
729+
},
730+
ajax() {}
731+
};
732+
jest.spyOn(RESTController, 'request');
733+
CoreManager.setRESTController(RESTController);
734+
735+
await ParseUser.logOut({ sessionToken: '1234' });
736+
737+
expect(RESTController.request).toHaveBeenCalledWith('POST', 'logout', {}, { sessionToken: '1234' });
738+
});
739+
678740
it('can get error when recursive _linkWith call fails', (done) => {
679741
CoreManager.setRESTController({
680742
request(method, path, body) {

src/__tests__/RESTController-test.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ describe('RESTController', () => {
263263
logIn() {},
264264
become() {},
265265
logOut() {},
266+
me() {},
266267
requestPasswordReset() {},
267268
upgradeToRevocableSession() {},
268269
linkWith() {},
@@ -298,6 +299,7 @@ describe('RESTController', () => {
298299
logIn() {},
299300
become() {},
300301
logOut() {},
302+
me() {},
301303
requestPasswordReset() {},
302304
upgradeToRevocableSession() {},
303305
linkWith() {},

0 commit comments

Comments
 (0)