forked from leancloud/javascript-sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuser.js
More file actions
1121 lines (1026 loc) · 38.2 KB
/
Copy pathuser.js
File metadata and controls
1121 lines (1026 loc) · 38.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/**
* 每位工程师都有保持代码优雅的义务
* Each engineer has a duty to keep the code elegant
**/
const _ = require('underscore');
const AVError = require('./error');
const AVRequest = require('./request').request;
module.exports = function(AV) {
/**
* @class
*
* <p>A AV.User object is a local representation of a user persisted to the
* AV cloud. This class is a subclass of a AV.Object, and retains the
* same functionality of a AV.Object, but also extends it with various
* user specific methods, like authentication, signing up, and validation of
* uniqueness.</p>
*/
AV.User = AV.Object.extend("_User", /** @lends AV.User.prototype */ {
// Instance Variables
_isCurrentUser: false,
// Instance Methods
/**
* Internal method to handle special fields in a _User response.
*/
_mergeMagicFields: function(attrs) {
if (attrs.sessionToken) {
this._sessionToken = attrs.sessionToken;
delete attrs.sessionToken;
}
AV.User.__super__._mergeMagicFields.call(this, attrs);
},
/**
* Removes null values from authData (which exist temporarily for
* unlinking)
*/
_cleanupAuthData: function() {
if (!this.isCurrent()) {
return;
}
var authData = this.get('authData');
if (!authData) {
return;
}
AV._objectEach(this.get('authData'), function(value, key) {
if (!authData[key]) {
delete authData[key];
}
});
},
/**
* Synchronizes authData for all providers.
*/
_synchronizeAllAuthData: function() {
var authData = this.get('authData');
if (!authData) {
return;
}
var self = this;
AV._objectEach(this.get('authData'), function(value, key) {
self._synchronizeAuthData(key);
});
},
/**
* Synchronizes auth data for a provider (e.g. puts the access token in the
* right place to be used by the Facebook SDK).
*/
_synchronizeAuthData: function(provider) {
if (!this.isCurrent()) {
return;
}
var authType;
if (_.isString(provider)) {
authType = provider;
provider = AV.User._authProviders[authType];
} else {
authType = provider.getAuthType();
}
var authData = this.get('authData');
if (!authData || !provider) {
return;
}
var success = provider.restoreAuthentication(authData[authType]);
if (!success) {
this._unlinkFrom(provider);
}
},
_handleSaveResult: function(makeCurrent) {
// Clean up and synchronize the authData object, removing any unset values
if (makeCurrent && !AV._config.disableCurrentUser) {
this._isCurrentUser = true;
}
this._cleanupAuthData();
this._synchronizeAllAuthData();
// Don't keep the password around.
delete this._serverData.password;
this._rebuildEstimatedDataForKey("password");
this._refreshCache();
if ((makeCurrent || this.isCurrent()) && !AV._config.disableCurrentUser) {
// Some old version of leanengine-node-sdk will overwrite
// AV.User._saveCurrentUser which returns no Promise.
// So we need a Promise wrapper.
return AV.Promise.as(AV.User._saveCurrentUser(this));
} else {
return AV.Promise.as();
}
},
/**
* Unlike in the Android/iOS SDKs, logInWith is unnecessary, since you can
* call linkWith on the user (even if it doesn't exist yet on the server).
*/
_linkWith: function(provider, options) {
var authType;
if (_.isString(provider)) {
authType = provider;
provider = AV.User._authProviders[provider];
} else {
authType = provider.getAuthType();
}
if (_.has(options, 'authData')) {
var authData = this.get('authData') || {};
authData[authType] = options.authData;
this.set('authData', authData);
return this.save({'authData': authData}, filterOutCallbacks(options))
.then(function(model) {
return model._handleSaveResult(true).then(function() {
return model;
});
})._thenRunCallbacks(options);
} else {
var self = this;
var promise = new AV.Promise();
provider.authenticate({
success: function(provider, result) {
self._linkWith(provider, {
authData: result,
success: options.success,
error: options.error
}).then(function() {
promise.resolve(self);
});
},
error: function(provider, error) {
if (options.error) {
options.error(self, error);
}
promise.reject(error);
}
});
return promise;
}
},
/**
* Unlinks a user from a service.
*/
_unlinkFrom: function(provider, options) {
var authType;
if (_.isString(provider)) {
authType = provider;
provider = AV.User._authProviders[provider];
} else {
authType = provider.getAuthType();
}
var newOptions = _.clone(options);
var self = this;
newOptions.authData = null;
newOptions.success = function(model) {
self._synchronizeAuthData(provider);
if (options.success) {
options.success.apply(this, arguments);
}
};
return this._linkWith(provider, newOptions);
},
/**
* Checks whether a user is linked to a service.
*/
_isLinked: function(provider) {
var authType;
if (_.isString(provider)) {
authType = provider;
} else {
authType = provider.getAuthType();
}
var authData = this.get('authData') || {};
return !!authData[authType];
},
logOut: function() {
this._logOutWithAll();
this._isCurrentUser = false;
},
/**
* Deauthenticates all providers.
*/
_logOutWithAll: function() {
var authData = this.get('authData');
if (!authData) {
return;
}
var self = this;
AV._objectEach(this.get('authData'), function(value, key) {
self._logOutWith(key);
});
},
/**
* Deauthenticates a single provider (e.g. removing access tokens from the
* Facebook SDK).
*/
_logOutWith: function(provider) {
if (!this.isCurrent()) {
return;
}
if (_.isString(provider)) {
provider = AV.User._authProviders[provider];
}
if (provider && provider.deauthenticate) {
provider.deauthenticate();
}
},
/**
* Signs up a new user. You should call this instead of save for
* new AV.Users. This will create a new AV.User on the server, and
* also persist the session on disk so that you can access the user using
* <code>current</code>.
*
* <p>A username and password must be set before calling signUp.</p>
*
* <p>Calls options.success or options.error on completion.</p>
*
* @param {Object} attrs Extra fields to set on the new user, or null.
* @param {Object} options A Backbone-style options object.
* @return {AV.Promise} A promise that is fulfilled when the signup
* finishes.
* @see AV.User.signUp
*/
signUp: function(attrs, options) {
var error;
options = options || {};
var username = (attrs && attrs.username) || this.get("username");
if (!username || (username === "")) {
error = new AVError(
AVError.OTHER_CAUSE,
"Cannot sign up user with an empty name.");
if (options && options.error) {
options.error(this, error);
}
throw error;
}
var password = (attrs && attrs.password) || this.get("password");
if (!password || (password === "")) {
error = new AVError(
AVError.OTHER_CAUSE,
"Cannot sign up user with an empty password.");
if (options && options.error) {
options.error(this, error);
}
throw error;
}
return this.save(attrs, filterOutCallbacks(options)).then(function(model) {
return model._handleSaveResult(true).then(function() {
return model;
});
})._thenRunCallbacks(options, this);
},
/**
* Signs up a new user with mobile phone and sms code.
* You should call this instead of save for
* new AV.Users. This will create a new AV.User on the server, and
* also persist the session on disk so that you can access the user using
* <code>current</code>.
*
* <p>A username and password must be set before calling signUp.</p>
*
* <p>Calls options.success or options.error on completion.</p>
*
* @param {Object} attrs Extra fields to set on the new user, or null.
* @param {Object} options A Backbone-style options object.
* @return {AV.Promise} A promise that is fulfilled when the signup
* finishes.
* @see AV.User.signUpOrlogInWithMobilePhone
* @see AV.Cloud.requestSmsCode
*/
signUpOrlogInWithMobilePhone: function(attrs, options) {
var error;
options = options || {};
var mobilePhoneNumber = (attrs && attrs.mobilePhoneNumber) ||
this.get("mobilePhoneNumber");
if (!mobilePhoneNumber || (mobilePhoneNumber === "")) {
error = new AVError(
AVError.OTHER_CAUSE,
"Cannot sign up or login user by mobilePhoneNumber " +
"with an empty mobilePhoneNumber.");
if (options && options.error) {
options.error(this, error);
}
throw error;
}
var smsCode = (attrs && attrs.smsCode) || this.get("smsCode");
if (!smsCode || (smsCode === "")) {
error = new AVError(
AVError.OTHER_CAUSE,
"Cannot sign up or login user by mobilePhoneNumber " +
"with an empty smsCode.");
if (options && options.error) {
options.error(this, error);
}
throw error;
}
var newOptions = filterOutCallbacks(options);
newOptions._makeRequest = function(route, className, id, method, json) {
return AVRequest('usersByMobilePhone', null, null, "POST", json);
};
return this.save(attrs, newOptions).then(function(model) {
delete model.attributes.smsCode;
delete model._serverData.smsCode;
return model._handleSaveResult(true).then(function() {
return model;
});
})._thenRunCallbacks(options);
},
/**
* Logs in a AV.User. On success, this saves the session to localStorage,
* so you can retrieve the currently logged in user using
* <code>current</code>.
*
* <p>A username and password must be set before calling logIn.</p>
*
* <p>Calls options.success or options.error on completion.</p>
*
* @param {Object} options A Backbone-style options object.
* @see AV.User.logIn
* @return {AV.Promise} A promise that is fulfilled with the user when
* the login is complete.
*/
logIn: function(options) {
var model = this;
var request = AVRequest("login", null, null, "GET", this.toJSON());
return request.then(function(resp, status, xhr) {
var serverAttrs = model.parse(resp, status, xhr);
model._finishFetch(serverAttrs);
return model._handleSaveResult(true).then(function() {
if(!serverAttrs.smsCode)
delete model.attributes['smsCode'];
return model;
});
})._thenRunCallbacks(options, this);
},
/**
* @see AV.Object#save
*/
save: function(arg1, arg2, arg3) {
var i, attrs, current, options, saved;
if (_.isObject(arg1) || _.isNull(arg1) || _.isUndefined(arg1)) {
attrs = arg1;
options = arg2;
} else {
attrs = {};
attrs[arg1] = arg2;
options = arg3;
}
options = options || {};
return AV.Object.prototype.save
.call(this, attrs, filterOutCallbacks(options))
.then(function(model) {
return model._handleSaveResult(false).then(function() {
return model;
});
})._thenRunCallbacks(options);
},
/**
* Follow a user
* @since 0.3.0
* @param {} target The target user or user's objectId to follow.
* @param {Object} options An optional Backbone-like options object with
* success and error callbacks that will be invoked once the iteration
* has finished.
*/
follow: function(target, options){
if(!this.id){
throw "Please signin.";
}
if(!target){
throw "Invalid target user.";
}
var userObjectId = _.isString(target) ? target: target.id;
if(!userObjectId){
throw "Invalid target user.";
}
var route = 'users/' + this.id + '/friendship/' + userObjectId;
var request = AVRequest(route, null, null, 'POST', null, options && options.sessionToken);
return request._thenRunCallbacks(options);
},
/**
* Unfollow a user.
* @since 0.3.0
* @param {} target The target user or user's objectId to unfollow.
* @param options {Object} An optional Backbone-like options object with
* success and error callbacks that will be invoked once the iteration
* has finished.
*/
unfollow: function(target, options){
if(!this.id){
throw "Please signin.";
}
if(!target){
throw "Invalid target user.";
}
var userObjectId = _.isString(target) ? target: target.id;
if(!userObjectId){
throw "Invalid target user.";
}
var route = 'users/' + this.id + '/friendship/' + userObjectId;
var request = AVRequest(route, null, null, 'DELETE', null, options && options.sessionToken);
return request._thenRunCallbacks(options);
},
/**
*Create a follower query to query the user's followers.
* @since 0.3.0
* @see AV.User#followerQuery
*/
followerQuery: function() {
return AV.User.followerQuery(this.id);
},
/**
*Create a followee query to query the user's followees.
* @since 0.3.0
* @see AV.User#followeeQuery
*/
followeeQuery: function() {
return AV.User.followeeQuery(this.id);
},
/**
* @see AV.Object#fetch
*/
fetch: function() {
var options = null;
var fetchOptions = {};
if(arguments.length === 1) {
options = arguments[0];
} else if(arguments.length === 2) {
fetchOptions = arguments[0];
options = arguments[1];
}
return AV.Object.prototype.fetch.call(this, fetchOptions, {})
.then(function(model) {
return model._handleSaveResult(false).then(function() {
return model;
});
})._thenRunCallbacks(options);
},
/**
* Update user's new password safely based on old password.
* @param {String} oldPassword, the old password.
* @param {String} newPassword, the new password.
* @param {Object} An optional Backbone-like options object with
* success and error callbacks that will be invoked once the iteration
* has finished.
*/
updatePassword: function(oldPassword, newPassword, options) {
var route = 'users/' + this.id + '/updatePassword';
var params = {
old_password: oldPassword,
new_password: newPassword
};
var request = AVRequest(route, null, null, 'PUT', params, options && options.sessionToken);
return request._thenRunCallbacks(options, this);
},
/**
* Returns true if <code>current</code> would return this user.
* @see AV.User#current
*/
isCurrent: function() {
return this._isCurrentUser;
},
/**
* Returns get("username").
* @return {String}
* @see AV.Object#get
*/
getUsername: function() {
return this.get("username");
},
/**
* Returns get("mobilePhoneNumber").
* @return {String}
* @see AV.Object#get
*/
getMobilePhoneNumber: function(){
return this.get("mobilePhoneNumber");
},
/**
* Calls set("mobilePhoneNumber", phoneNumber, options) and returns the result.
* @param {String} mobilePhoneNumber
* @param {Object} options A Backbone-style options object.
* @return {Boolean}
* @see AV.Object.set
*/
setMobilePhoneNumber: function(phone, options) {
return this.set("mobilePhoneNumber", phone, options);
},
/**
* Calls set("username", username, options) and returns the result.
* @param {String} username
* @param {Object} options A Backbone-style options object.
* @return {Boolean}
* @see AV.Object.set
*/
setUsername: function(username, options) {
return this.set("username", username, options);
},
/**
* Calls set("password", password, options) and returns the result.
* @param {String} password
* @param {Object} options A Backbone-style options object.
* @return {Boolean}
* @see AV.Object.set
*/
setPassword: function(password, options) {
return this.set("password", password, options);
},
/**
* Returns get("email").
* @return {String}
* @see AV.Object#get
*/
getEmail: function() {
return this.get("email");
},
/**
* Calls set("email", email, options) and returns the result.
* @param {String} email
* @param {Object} options A Backbone-style options object.
* @return {Boolean}
* @see AV.Object.set
*/
setEmail: function(email, options) {
return this.set("email", email, options);
},
/**
* Checks whether this user is the current user and has been authenticated.
* @return (Boolean) whether this user is the current user and is logged in.
*/
authenticated: function() {
return !!this._sessionToken &&
(!AV._config.disableCurrentUser && AV.User.current() && AV.User.current().id === this.id);
},
getSessionToken: function() {
return this._sessionToken;
},
}, /** @lends AV.User */ {
// Class Variables
// The currently logged-in user.
_currentUser: null,
// Whether currentUser is known to match the serialized version on disk.
// This is useful for saving a localstorage check if you try to load
// _currentUser frequently while there is none stored.
_currentUserMatchesDisk: false,
// The localStorage key suffix that the current user is stored under.
_CURRENT_USER_KEY: "currentUser",
// The mapping of auth provider names to actual providers
_authProviders: {},
// Class Methods
/**
* Signs up a new user with a username (or email) and password.
* This will create a new AV.User on the server, and also persist the
* session in localStorage so that you can access the user using
* {@link #current}.
*
* <p>Calls options.success or options.error on completion.</p>
*
* @param {String} username The username (or email) to sign up with.
* @param {String} password The password to sign up with.
* @param {Object} attrs Extra fields to set on the new user.
* @param {Object} options A Backbone-style options object.
* @return {AV.Promise} A promise that is fulfilled with the user when
* the signup completes.
* @see AV.User#signUp
*/
signUp: function(username, password, attrs, options) {
attrs = attrs || {};
attrs.username = username;
attrs.password = password;
var user = AV.Object._create("_User");
return user.signUp(attrs, options);
},
/**
* Logs in a user with a username (or email) and password. On success, this
* saves the session to disk, so you can retrieve the currently logged in
* user using <code>current</code>.
*
* <p>Calls options.success or options.error on completion.</p>
*
* @param {String} username The username (or email) to log in with.
* @param {String} password The password to log in with.
* @param {Object} options A Backbone-style options object.
* @return {AV.Promise} A promise that is fulfilled with the user when
* the login completes.
* @see AV.User#logIn
*/
logIn: function(username, password, options) {
var user = AV.Object._create("_User");
user._finishFetch({ username: username, password: password });
return user.logIn(options);
},
/**
* Logs in a user with a session token. On success, this saves the session
* to disk, so you can retrieve the currently logged in user using
* <code>current</code>.
*
* <p>Calls options.success or options.error on completion.</p>
*
* @param {String} sessionToken The sessionToken to log in with.
* @param {Object} options A Backbone-style options object.
* @return {AV.Promise} A promise that is fulfilled with the user when
* the login completes.
*/
become: function(sessionToken, options) {
options = options || {};
var user = AV.Object._create("_User");
return AVRequest(
"users",
"me",
null,
"GET",
{
useMasterKey: options.useMasterKey,
session_token: sessionToken
}
).then(function(resp, status, xhr) {
var serverAttrs = user.parse(resp, status, xhr);
user._finishFetch(serverAttrs);
return user._handleSaveResult(true).then(function() {
return user;
});
})._thenRunCallbacks(options, user);
},
/**
* Logs in a user with a mobile phone number and sms code sent by
* AV.User.requestLoginSmsCode.On success, this
* saves the session to disk, so you can retrieve the currently logged in
* user using <code>current</code>.
*
* <p>Calls options.success or options.error on completion.</p>
*
* @param {String} mobilePhone The user's mobilePhoneNumber
* @param {String} smsCode The sms code sent by AV.User.requestLoginSmsCode
* @param {Object} options A Backbone-style options object.
* @return {AV.Promise} A promise that is fulfilled with the user when
* the login completes.
* @see AV.User#logIn
*/
logInWithMobilePhoneSmsCode: function(mobilePhone, smsCode, options){
var user = AV.Object._create("_User");
user._finishFetch({ mobilePhoneNumber: mobilePhone, smsCode: smsCode });
return user.logIn(options);
},
/**
* Sign up or logs in a user with a mobilePhoneNumber and smsCode.
* On success, this saves the session to disk, so you can retrieve the currently
* logged in user using <code>current</code>.
*
* <p>Calls options.success or options.error on completion.</p>
*
* @param {String} mobilePhoneNumber The user's mobilePhoneNumber.
* @param {String} smsCode The sms code sent by AV.Cloud.requestSmsCode
* @param {Object} attributes The user's other attributes such as username etc.
* @param {Object} options A Backbone-style options object.
* @return {AV.Promise} A promise that is fulfilled with the user when
* the login completes.
* @see AV.User#signUpOrlogInWithMobilePhone
* @see AV.Cloud.requestSmsCode
*/
signUpOrlogInWithMobilePhone: function(mobilePhoneNumber, smsCode, attrs, options) {
attrs = attrs || {};
attrs.mobilePhoneNumber = mobilePhoneNumber;
attrs.smsCode = smsCode;
var user = AV.Object._create("_User");
return user.signUpOrlogInWithMobilePhone(attrs, options);
},
/**
* Logs in a user with a mobile phone number and password. On success, this
* saves the session to disk, so you can retrieve the currently logged in
* user using <code>current</code>.
*
* <p>Calls options.success or options.error on completion.</p>
*
* @param {String} mobilePhone The user's mobilePhoneNumber
* @param {String} password The password to log in with.
* @param {Object} options A Backbone-style options object.
* @return {AV.Promise} A promise that is fulfilled with the user when
* the login completes.
* @see AV.User#logIn
*/
logInWithMobilePhone: function(mobilePhone, password, options){
var user = AV.Object._create("_User");
user._finishFetch({ mobilePhoneNumber: mobilePhone, password: password });
return user.logIn(options);
},
/**
* Sign up or logs in a user with a third party auth data(AccessToken).
* On success, this saves the session to disk, so you can retrieve the currently
* logged in user using <code>current</code>.
*
* @param {Object} authData The response json data returned from third party token, maybe like { openid: 'abc123', access_token: '123abc', expires_in: 1382686496 }
* @param {string} platform Available platform for sign up.
* @param {Object} [callback] An object that has an optional success function, that takes no arguments and will be called on a successful puSH. and an error function that takes a AVError and will be called if the push failed.
* @return {AV.Promise} A promise that is fulfilled with the user when
* the login completes.
* @example AV.User.signUpOrlogInWithAuthData(authData, platform).then(function(user) {
* //Access user here
* }).catch(function(error) {
* //console.error("error: ", error);
* });
* @see {@link https://leancloud.cn/docs/js_guide.html#绑定第三方平台账户}
*/
signUpOrlogInWithAuthData(authData, platform, callback) {
return AV.User._logInWith(platform, { authData })._thenRunCallbacks(callback);
},
/**
* Associate a user with a third party auth data(AccessToken).
*
* @param {AV.User} userObj A user which you want to associate.
* @param {string} platform Available platform for sign up.
* @param {Object} authData The response json data returned from third party token, maybe like { openid: 'abc123', access_token: '123abc', expires_in: 1382686496 }
* @return {AV.Promise} A promise that is fulfilled with the user when completed.
* @example AV.User.associateWithAuthData(loginUser, 'weixin', {
* openid: 'abc123',
* access_token: '123abc',
* expires_in: 1382686496
* }).then(function(user) {
* //Access user here
* }).catch(function(error) {
* //console.error("error: ", error);
* });
*/
associateWithAuthData(userObj, platform, authData) {
return userObj._linkWith(platform, { authData });
},
/**
* Logs out the currently logged in user session. This will remove the
* session from disk, log out of linked services, and future calls to
* <code>current</code> will return <code>null</code>.
*/
logOut: function() {
if (AV._config.disableCurrentUser) {
console.warn('AV.User.current() was disabled in multi-user environment, call logOut() from user object instead https://leancloud.cn/docs/leanengine-node-sdk-upgrade-1.html');
return AV.Promise.as(null);
}
if (AV.User._currentUser !== null) {
AV.User._currentUser._logOutWithAll();
AV.User._currentUser._isCurrentUser = false;
}
AV.User._currentUserMatchesDisk = true;
AV.User._currentUser = null;
return AV.localStorage.removeItemAsync(
AV._getAVPath(AV.User._CURRENT_USER_KEY));
},
/**
*Create a follower query for special user to query the user's followers.
* @param userObjectId {String} The user object id.
* @since 0.3.0
*/
followerQuery: function(userObjectId) {
if(!userObjectId || !_.isString(userObjectId)) {
throw "Invalid user object id.";
}
var query = new AV.FriendShipQuery('_Follower');
query._friendshipTag ='follower';
query.equalTo('user', AV.Object.createWithoutData('_User', userObjectId));
return query;
},
/**
*Create a followee query for special user to query the user's followees.
* @param userObjectId {String} The user object id.
* @since 0.3.0
*/
followeeQuery: function(userObjectId) {
if(!userObjectId || !_.isString(userObjectId)) {
throw "Invalid user object id.";
}
var query = new AV.FriendShipQuery('_Followee');
query._friendshipTag ='followee';
query.equalTo('user', AV.Object.createWithoutData('_User', userObjectId));
return query;
},
/**
* Requests a password reset email to be sent to the specified email address
* associated with the user account. This email allows the user to securely
* reset their password on the AV site.
*
* <p>Calls options.success or options.error on completion.</p>
*
* @param {String} email The email address associated with the user that
* forgot their password.
* @param {Object} options A Backbone-style options object.
*/
requestPasswordReset: function(email, options) {
var json = { email: email };
var request = AVRequest("requestPasswordReset", null, null, "POST",
json);
return request._thenRunCallbacks(options);
},
/**
* Requests a verify email to be sent to the specified email address
* associated with the user account. This email allows the user to securely
* verify their email address on the AV site.
*
* <p>Calls options.success or options.error on completion.</p>
*
* @param {String} email The email address associated with the user that
* doesn't verify their email address.
* @param {Object} options A Backbone-style options object.
*/
requestEmailVerify: function(email, options) {
var json = { email: email };
var request = AVRequest("requestEmailVerify", null, null, "POST",
json);
return request._thenRunCallbacks(options);
},
/**
* @Deprecated typo error, please use requestEmailVerify
*/
requestEmailVerfiy: function(email, options) {
var json = { email: email };
var request = AVRequest("requestEmailVerify", null, null, "POST",
json);
return request._thenRunCallbacks(options);
},
/**
* Requests a verify sms code to be sent to the specified mobile phone
* number associated with the user account. This sms code allows the user to
* verify their mobile phone number by calling AV.User.verifyMobilePhone
*
* <p>Calls options.success or options.error on completion.</p>
*
* @param {String} mobilePhone The mobile phone number associated with the
* user that doesn't verify their mobile phone number.
* @param {Object} options A Backbone-style options object.
*/
requestMobilePhoneVerify: function(mobilePhone, options){
var json = { mobilePhoneNumber: mobilePhone };
var request = AVRequest("requestMobilePhoneVerify", null, null, "POST",
json);
return request._thenRunCallbacks(options);
},
/**
* Requests a reset password sms code to be sent to the specified mobile phone
* number associated with the user account. This sms code allows the user to
* reset their account's password by calling AV.User.resetPasswordBySmsCode
*
* <p>Calls options.success or options.error on completion.</p>
*
* @param {String} mobilePhone The mobile phone number associated with the
* user that doesn't verify their mobile phone number.
* @param {Object} options A Backbone-style options object.
*/
requestPasswordResetBySmsCode: function(mobilePhone, options){
var json = { mobilePhoneNumber: mobilePhone };
var request = AVRequest("requestPasswordResetBySmsCode", null, null, "POST",
json);
return request._thenRunCallbacks(options);
},
/**
* Makes a call to reset user's account password by sms code and new password.
* The sms code is sent by AV.User.requestPasswordResetBySmsCode.
* @param {String} code The sms code sent by AV.User.Cloud.requestSmsCode
* @param {String} password The new password.
* @param {Object} options A Backbone-style options object
* @return {AV.Promise} A promise that will be resolved with the result
* of the function.
*/
resetPasswordBySmsCode: function(code, password, options){
var json = { password: password};
var request = AVRequest("resetPasswordBySmsCode", null, code, "PUT",
json);
return request._thenRunCallbacks(options);
},
/**
* Makes a call to verify sms code that sent by AV.User.Cloud.requestSmsCode
* If verify successfully,the user mobilePhoneVerified attribute will be true.
* @param {String} code The sms code sent by AV.User.Cloud.requestSmsCode
* @param {Object} options A Backbone-style options object
* @return {AV.Promise} A promise that will be resolved with the result
* of the function.
*/
verifyMobilePhone: function(code, options){
var request = AVRequest("verifyMobilePhone", null, code, "POST",
null);
return request._thenRunCallbacks(options);
},
/**
* Requests a logIn sms code to be sent to the specified mobile phone
* number associated with the user account. This sms code allows the user to
* login by AV.User.logInWithMobilePhoneSmsCode function.
*
* <p>Calls options.success or options.error on completion.</p>
*
* @param {String} mobilePhone The mobile phone number associated with the
* user that want to login by AV.User.logInWithMobilePhoneSmsCode
* @param {Object} options A Backbone-style options object.
*/
requestLoginSmsCode: function(mobilePhone, options){
var json = { mobilePhoneNumber: mobilePhone };
var request = AVRequest("requestLoginSmsCode", null, null, "POST",
json);
return request._thenRunCallbacks(options);
},
/**
* Retrieves the currently logged in AVUser with a valid session,
* either from memory or localStorage, if necessary.
* @return {AV.Promise} resolved with the currently logged in AV.User.
*/
currentAsync: function() {
if (AV._config.disableCurrentUser) {
console.warn('AV.User.currentAsync() was disabled in multi-user environment, access user from request instead https://leancloud.cn/docs/leanengine-node-sdk-upgrade-1.html');
return AV.Promise.as(null);
}
if (AV.User._currentUser) {
return AV.Promise.as(AV.User._currentUser);
}
if (AV.User._currentUserMatchesDisk) {
return AV.Promise.as(AV.User._currentUser);
}
return AV.localStorage.getItemAsync(
AV._getAVPath(AV.User._CURRENT_USER_KEY)