Skip to content

Commit 381fcfc

Browse files
authored
feat: Add Parse.User.loginAs (parse-community#1875)
1 parent 24c03dd commit 381fcfc

File tree

4 files changed

+130
-0
lines changed

4 files changed

+130
-0
lines changed

.eslintrc.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
"jsdoc/require-param-description": 0,
4343
"jsdoc/require-property-description": 0,
4444
"jsdoc/require-param-type": 0,
45+
"jsdoc/tag-lines": 0,
4546
"jsdoc/check-param-names": [
4647
"error",
4748
{

integration/test/ParseUserTest.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,27 @@ describe('Parse User', () => {
148148
expect(sessions[1].get('sessionToken')).toBe(installationUser.getSessionToken());
149149
});
150150

151+
it('can login with userId', async () => {
152+
Parse.User.enableUnsafeCurrentUser();
153+
154+
const user = await Parse.User.signUp('parsetest', 'parse', { code: 'red' });
155+
assert.equal(Parse.User.current(), user);
156+
await Parse.User.logOut();
157+
assert(!Parse.User.current());
158+
159+
const newUser = await Parse.User.loginAs(user.id);
160+
assert.equal(Parse.User.current(), newUser);
161+
assert(newUser);
162+
assert.equal(user.id, newUser.id);
163+
assert.equal(user.get('code'), 'red');
164+
165+
await Parse.User.logOut();
166+
assert(!Parse.User.current());
167+
await expectAsync(Parse.User.loginAs('garbage')).toBeRejectedWithError(
168+
'user not found'
169+
);
170+
});
171+
151172
it('can become a user', done => {
152173
Parse.User.enableUnsafeCurrentUser();
153174
let session = null;
@@ -782,6 +803,16 @@ describe('Parse User', () => {
782803
expect(user.doSomething()).toBe(5);
783804
});
784805

806+
it('can loginAs user with subclass static', async () => {
807+
Parse.User.enableUnsafeCurrentUser();
808+
809+
let user = await CustomUser.signUp('username', 'password');
810+
811+
user = await CustomUser.loginAs(user.id);
812+
expect(user instanceof CustomUser).toBe(true);
813+
expect(user.doSomething()).toBe(5);
814+
});
815+
785816
it('can get user (me) with subclass static', async () => {
786817
Parse.User.enableUnsafeCurrentUser();
787818

src/ParseUser.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,25 @@ class ParseUser extends ParseObject {
653653
return user.logIn(options);
654654
}
655655

656+
/**
657+
* Logs in a user with an objectId. On success, this saves the session
658+
* to disk, so you can retrieve the currently logged in user using
659+
* <code>current</code>.
660+
*
661+
* @param {string} userId The objectId for the user.
662+
* @static
663+
* @returns {Promise} A promise that is fulfilled with the user when
664+
* the login completes.
665+
*/
666+
static loginAs(userId: string) {
667+
if (!userId) {
668+
throw new ParseError(ParseError.USERNAME_MISSING, 'Cannot log in as user with an empty user id');
669+
}
670+
const controller = CoreManager.getUserController();
671+
const user = new this();
672+
return controller.loginAs(user, userId);
673+
}
674+
656675
/**
657676
* Logs in a user with a session token. On success, this saves the session
658677
* to disk, so you can retrieve the currently logged in user using
@@ -1097,6 +1116,18 @@ const DefaultController = {
10971116
);
10981117
},
10991118

1119+
loginAs(user: ParseUser, userId: string): Promise<ParseUser> {
1120+
const RESTController = CoreManager.getRESTController();
1121+
return RESTController.request('POST', 'loginAs', { userId }, { useMasterKey: true }).then(response => {
1122+
user._finishFetch(response);
1123+
user._setExisted(true);
1124+
if (!canUseCurrentUser) {
1125+
return Promise.resolve(user);
1126+
}
1127+
return DefaultController.setCurrentUser(user);
1128+
});
1129+
},
1130+
11001131
become(user: ParseUser, options: RequestOptions): Promise<ParseUser> {
11011132
const RESTController = CoreManager.getRESTController();
11021133
return RESTController.request('GET', 'users/me', {}, options).then(response => {

src/__tests__/ParseUser-test.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,73 @@ describe('ParseUser', () => {
360360
});
361361
});
362362

363+
it('does not allow loginAs without id', (done) => {
364+
try {
365+
ParseUser.loginAs(null, null);
366+
} catch (e) {
367+
expect(e.message).toBe('Cannot log in as user with an empty user id')
368+
done();
369+
}
370+
});
371+
372+
it('can login as a user with an objectId', async () => {
373+
ParseUser.disableUnsafeCurrentUser();
374+
ParseUser._clearCache();
375+
CoreManager.setRESTController({
376+
request(method, path, body, options) {
377+
expect(method).toBe('POST');
378+
expect(path).toBe('loginAs');
379+
expect(body.userId).toBe('uid4');
380+
expect(options.useMasterKey).toBe(true);
381+
382+
return Promise.resolve(
383+
{
384+
objectId: 'uid4',
385+
username: 'username',
386+
sessionToken: '123abc',
387+
},
388+
200
389+
);
390+
},
391+
ajax() {},
392+
});
393+
394+
const user = await ParseUser.loginAs('uid4');
395+
expect(user.id).toBe('uid4');
396+
expect(user.isCurrent()).toBe(false);
397+
expect(user.existed()).toBe(true);
398+
});
399+
400+
it('can loginAs a user with async storage', async () => {
401+
const currentStorage = CoreManager.getStorageController();
402+
CoreManager.setStorageController(mockAsyncStorage);
403+
ParseUser.enableUnsafeCurrentUser();
404+
ParseUser._clearCache();
405+
CoreManager.setRESTController({
406+
request(method, path, body, options) {
407+
expect(method).toBe('POST');
408+
expect(path).toBe('loginAs');
409+
expect(body.userId).toBe('uid5');
410+
expect(options.useMasterKey).toBe(true);
411+
return Promise.resolve(
412+
{
413+
objectId: 'uid5',
414+
username: 'username',
415+
sessionToken: '123abc',
416+
},
417+
200
418+
);
419+
},
420+
ajax() {},
421+
});
422+
423+
const user = await ParseUser.loginAs('uid5');
424+
expect(user.id).toBe('uid5');
425+
expect(user.isCurrent()).toBe(true);
426+
expect(user.existed()).toBe(true);
427+
CoreManager.setStorageController(currentStorage);
428+
});
429+
363430
it('can become a user with a session token', done => {
364431
ParseUser.enableUnsafeCurrentUser();
365432
ParseUser._clearCache();

0 commit comments

Comments
 (0)