Skip to content

Commit 7ba81ae

Browse files
authored
feat: add options.useMasterKey param for most RestAPI wrappers (#367)
also split utils.js to av.js/init.js/utils.js
1 parent b0536b7 commit 7ba81ae

File tree

15 files changed

+580
-559
lines changed

15 files changed

+580
-559
lines changed

src/av.js

Lines changed: 440 additions & 1 deletion
Large diffs are not rendered by default.

src/cloudfunction.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ module.exports = function(AV) {
2323
*/
2424
run: function(name, data, options) {
2525
var request = AVRequest('functions', name, null, 'POST',
26-
AV._encode(data, null, true), options && options.sessionToken);
26+
AV._encode(data, null, true), options);
2727

2828
return request.then(function(resp) {
2929
return AV._decode(null, resp).result;
@@ -43,8 +43,7 @@ module.exports = function(AV) {
4343
return Promise.reject(new Error('Can\'t pass Array as the param of rpc function in JavaScript SDK.'));
4444
}
4545

46-
return AVRequest('call', name, null, 'POST', AV._encodeObjectOrArray(data),
47-
options && options.sessionToken).then(function(resp) {
46+
return AVRequest('call', name, null, 'POST', AV._encodeObjectOrArray(data), options).then(function(resp) {
4847
return AV._decode('', resp).result;
4948
});
5049
},

src/file.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ module.exports = function(AV) {
579579
if (!this.id) {
580580
return Promise.reject(new Error('The file id is not eixsts.'));
581581
}
582-
var request = AVRequest("files", null, this.id, 'DELETE', options && options.sessionToken);
582+
var request = AVRequest("files", null, this.id, 'DELETE', null, options);
583583
return request;
584584
},
585585

src/index.js

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* The LeanCloud JavaScript SDK is freely distributable under the MIT license.
77
*/
88

9-
const AV = module.exports = require('./av');
9+
const AV = require('./av');
1010

1111
AV._ = require('underscore');
1212
AV.version = require('./version');
@@ -15,11 +15,7 @@ AV.localStorage = require('./localstorage');
1515
AV.Cache = require('./cache');
1616
AV.Error = require('./error');
1717

18-
// All internal configuration items
19-
AV._config = AV._config || {};
20-
21-
require('./utils').init(AV);
22-
18+
require('./init');
2319
require('./event')(AV);
2420
require('./geopoint')(AV);
2521
require('./acl')(AV);
@@ -36,9 +32,12 @@ require('./status')(AV);
3632
require('./search')(AV);
3733
require('./insight')(AV);
3834

35+
module.exports = AV;
36+
3937
/**
4038
* Options to controll the authentication for an operation
4139
* @typedef {Object} AuthOptions
42-
* @property {String} sessionToken Specify a user to excute the operation as.
43-
* @property {Boolean} useMasterKey Indicates whether masterKey is used for this operation. Only valid when masterKey is set.
40+
* @property {String} [sessionToken] Specify a user to excute the operation as.
41+
* @property {AV.User} [user] Specify a user to excute the operation as. The user must have _sessionToken. This option will be ignored if sessionToken option provided.
42+
* @property {Boolean} [useMasterKey] Indicates whether masterKey is used for this operation. Only valid when masterKey is set.
4443
*/

src/init.js

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
const AV = require('./av');
2+
const request = require('./request');
3+
4+
/**
5+
* Call this method first to set up authentication tokens for AV.
6+
* This method is for AV's own private use.
7+
* @param {String} applicationId Your AV Application ID.
8+
* @param {String} applicationKey Your AV Application Key
9+
*/
10+
const initialize = (appId, appKey, masterKey) => {
11+
if (AV.applicationId && appId !== AV.applicationId && appKey !== AV.applicationKey && masterKey !== AV.masterKey) {
12+
console.warn('LeanCloud SDK is already initialized, please do not reinitialize it.');
13+
}
14+
AV.applicationId = appId;
15+
AV.applicationKey = appKey;
16+
AV.masterKey = masterKey;
17+
AV._useMasterKey = false;
18+
};
19+
20+
const masterKeyWarn = () => {
21+
console.warn('MasterKey is not supposed to be used in browser.');
22+
};
23+
24+
/**
25+
* Call this method first to set up your authentication tokens for AV.
26+
* You can get your app keys from the LeanCloud dashboard on http://leancloud.cn .
27+
* @function AV.init
28+
* @param {Object} options
29+
* @param {String} options.appId application id
30+
* @param {String} options.appKey application key
31+
* @param {String} options.masterKey application master key
32+
*/
33+
34+
AV.init = (...args) => {
35+
switch (args.length) {
36+
case 1:
37+
const options = args[0];
38+
if (typeof options === 'object') {
39+
if (!AV._config.isNode && options.masterKey) {
40+
masterKeyWarn();
41+
}
42+
initialize(options.appId, options.appKey, options.masterKey);
43+
request.setServerUrlByRegion(options.region);
44+
AV._config.disableCurrentUser = options.disableCurrentUser;
45+
} else {
46+
throw new Error('AV.init(): Parameter is not correct.');
47+
}
48+
break;
49+
// 兼容旧版本的初始化方法
50+
case 2:
51+
case 3:
52+
console.warn('Please use AV.init() to replace AV.initialize(), ' +
53+
'AV.init() need an Object param, like { appId: \'YOUR_APP_ID\', appKey: \'YOUR_APP_KEY\' } . ' +
54+
'Docs: https://leancloud.cn/docs/sdk_setup-js.html');
55+
if (!AV._config.isNode && args.length === 3) {
56+
masterKeyWarn();
57+
}
58+
initialize(...args);
59+
request.setServerUrlByRegion('cn');
60+
break;
61+
}
62+
};
63+
64+
// If we're running in node.js, allow using the master key.
65+
if (AV._config.isNode) {
66+
AV.Cloud = AV.Cloud || {};
67+
/**
68+
* Switches the LeanCloud SDK to using the Master key. The Master key grants
69+
* priveleged access to the data in LeanCloud and can be used to bypass ACLs and
70+
* other restrictions that are applied to the client SDKs.
71+
* <p><strong><em>Available in Cloud Code and Node.js only.</em></strong>
72+
* </p>
73+
*/
74+
AV.Cloud.useMasterKey = function() {
75+
AV._useMasterKey = true;
76+
};
77+
}
78+
79+
// 兼容老版本的初始化方法
80+
AV.initialize = AV.init;

src/insight.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,11 @@ module.exports = function(AV) {
2727
* }
2828
* </pre></code>
2929
* sql 指定任务执行的 SQL 语句, saveAs(可选) 指定将结果保存在哪张表里,limit 最大 1000。
30+
* @param {AuthOptions} [options]
3031
* @return {Promise} A promise that will be resolved with the result
3132
* of the function.
3233
*/
33-
startJob: function(jobConfig) {
34+
startJob: function(jobConfig, options) {
3435
if(!jobConfig || !jobConfig.sql) {
3536
throw new Error('Please provide the sql to run the job.');
3637
}
@@ -39,7 +40,7 @@ module.exports = function(AV) {
3940
appId: AV.applicationId
4041
};
4142
var request = AVRequest("bigquery", 'jobs', null, 'POST',
42-
AV._encode(data, null, true));
43+
AV._encode(data, null, true), options);
4344

4445
return request.then(function(resp) {
4546
return AV._decode(null, resp).id;
@@ -106,18 +107,19 @@ module.exports = function(AV) {
106107
* results 数组表示任务结果数组,previewCount 表示可以返回的结果总数,任务的开始和截止时间
107108
* startTime、endTime 等信息。
108109
*
110+
* @param {AuthOptions} [options]
109111
* @return {Promise} A promise that will be resolved with the result
110112
* of the function.
111113
*
112114
*/
113-
find: function() {
115+
find: function(options) {
114116
var params = {
115117
skip: this._skip,
116118
limit: this._limit
117119
};
118120

119121
var request = AVRequest("bigquery", 'jobs', this.id, "GET",
120-
params);
122+
params, options);
121123
var self = this;
122124
return request.then(function(response) {
123125
if(response.error) {

src/object.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ module.exports = function(AV) {
113113
path: `/1.1/classes/${object.className}/${object.id}`,
114114
};
115115
}),
116-
}, options && options.sessionToken)
116+
}, options)
117117
).then(function(response) {
118118
_.forEach(objects, function(object, i) {
119119
if (response[i].success) {
@@ -815,14 +815,14 @@ module.exports = function(AV) {
815815
* @return {Promise} A promise that is fulfilled when the fetch
816816
* completes.
817817
*/
818-
fetch: function(fetchOptions = {}, options = {}) {
818+
fetch: function(fetchOptions = {}, options) {
819819
if (_.isArray(fetchOptions.include)) {
820820
fetchOptions.include = fetchOptions.include.join(',');
821821
}
822822

823823
var self = this;
824824
var request = AVRequest('classes', this.className, this.id, 'GET',
825-
fetchOptions, options.sessionToken);
825+
fetchOptions, options);
826826
return request.then(function(response) {
827827
self._finishFetch(self.parse(response), true);
828828
return self;
@@ -937,7 +937,7 @@ module.exports = function(AV) {
937937
}
938938
//hook makeRequest in options.
939939
var makeRequest = options._makeRequest || AVRequest;
940-
var request = makeRequest(route, className, model.id, method, json, options.sessionToken);
940+
var request = makeRequest(route, className, model.id, method, json, options);
941941

942942
request = request.then(function(resp) {
943943
var serverAttrs = model.parse(resp);
@@ -987,7 +987,7 @@ module.exports = function(AV) {
987987
}
988988

989989
var request =
990-
AVRequest('classes', this.className, this.id, 'DELETE', null, options.sessionToken);
990+
AVRequest('classes', this.className, this.id, 'DELETE', null, options);
991991
return request.then(function() {
992992
if (options.wait) {
993993
triggerDestroy();
@@ -1241,7 +1241,7 @@ module.exports = function(AV) {
12411241
}
12421242
});
12431243
var request =
1244-
AVRequest('classes', className, id, 'DELETE', null, options.sessionToken);
1244+
AVRequest('classes', className, id, 'DELETE', null, options);
12451245
return request;
12461246
};
12471247

@@ -1514,7 +1514,7 @@ module.exports = function(AV) {
15141514
};
15151515
})
15161516

1517-
}, options && options.sessionToken).then(function(response) {
1517+
}, options).then(function(response) {
15181518
var error;
15191519
AV._arrayEach(batch, function(object, i) {
15201520
if (response[i].success) {

src/push.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ module.exports = function(AV) {
2121
* @param {String} [data.cql] A CQL statement over AV.Installation that is used to match
2222
* a set of installations to push to.
2323
* @param {Date} data.data The data to send as part of the push
24-
* <ol>
24+
* @param {AuthOptions} [options]
2525
* @return {Promise}
2626
*/
27-
AV.Push.send = function(data) {
27+
AV.Push.send = function(data, options) {
2828
if (data.where) {
2929
data.where = data.where.toJSON().where;
3030
}
@@ -45,7 +45,7 @@ module.exports = function(AV) {
4545
throw new Error("Both expiration_time and expiration_time_interval can't be set");
4646
}
4747

48-
var request = AVRequest('push', null, null, 'POST', data);
48+
var request = AVRequest('push', null, null, 'POST', data, options);
4949
return request;
5050
};
5151
};

src/query.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ module.exports = function(AV) {
135135
options = pvalues;
136136
}
137137

138-
var request = AVRequest('cloudQuery', null, null, 'GET', params, options && options.sessionToken);
138+
var request = AVRequest('cloudQuery', null, null, 'GET', params, options);
139139
return request.then(function(response) {
140140
//query to process results.
141141
var query = new AV.Query(response.className);
@@ -235,7 +235,7 @@ module.exports = function(AV) {
235235
},
236236
_createRequest: function(params, options){
237237
return AVRequest('classes', this.className, null, "GET",
238-
params || this.toJSON(), options && options.sessionToken);
238+
params || this.toJSON(), options);
239239
},
240240

241241
/**

src/request.js

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ const Cache = require('./cache');
66
const AVError = require('./error');
77
const AV = require('./av');
88
const _ = require('underscore');
9+
const {
10+
getSessionToken,
11+
} = require('./utils');
912

1013
let getServerURLPromise;
1114

@@ -97,13 +100,18 @@ const ajax = (method, resourceUrl, data, headers = {}, onprogress) => {
97100
});
98101
};
99102

100-
const setHeaders = (sessionToken) => {
103+
const setHeaders = (authOptions = {}) => {
101104
const headers = {
102105
'X-LC-Id': AV.applicationId,
103106
'Content-Type': 'application/json;charset=UTF-8',
104107
};
105-
if (AV.masterKey && AV._useMasterKey) {
106-
headers['X-LC-Sign'] = sign(AV.masterKey, true);
108+
if (AV._useMasterKey || authOptions.useMasterKey) {
109+
if (AV.masterKey) {
110+
headers['X-LC-Sign'] = sign(AV.masterKey, true);
111+
} else {
112+
console.warn('masterKey is not set, fall back to use appKey');
113+
headers['X-LC-Sign'] = sign(AV.applicationKey);
114+
}
107115
} else {
108116
headers['X-LC-Sign'] = sign(AV.applicationKey);
109117
}
@@ -119,19 +127,18 @@ const setHeaders = (sessionToken) => {
119127

120128
return Promise.resolve().then(() => {
121129
// Pass the session token
130+
const sessionToken = getSessionToken(authOptions);
122131
if (sessionToken) {
123132
headers['X-LC-Session'] = sessionToken;
124-
return headers;
125133
} else if (!AV._config.disableCurrentUser) {
126134
return AV.User.currentAsync().then((currentUser) => {
127135
if (currentUser && currentUser._sessionToken) {
128136
headers['X-LC-Session'] = currentUser._sessionToken;
129137
}
130138
return headers;
131139
});
132-
} else {
133-
return headers;
134140
}
141+
return headers;
135142
});
136143
};
137144

@@ -282,7 +289,7 @@ const setServerUrlByRegion = (region = 'cn') => {
282289
* dataObject is the payload as an object, or null if there is none.
283290
* @ignore
284291
*/
285-
const AVRequest = (route, className, objectId, method, dataObject = {}, sessionToken) => {
292+
const AVRequest = (route, className, objectId, method, dataObject = {}, authOptions) => {
286293
if (!AV.applicationId) {
287294
throw new Error('You must specify your applicationId using AV.init()');
288295
}
@@ -298,7 +305,7 @@ const AVRequest = (route, className, objectId, method, dataObject = {}, sessionT
298305
}
299306
return getServerURLPromise.then(() => {
300307
const apiURL = createApiUrl(route, className, objectId, method, dataObject);
301-
return setHeaders(sessionToken).then(
308+
return setHeaders(authOptions).then(
302309
headers => ajax(method, apiURL, dataObject, headers)
303310
.then(
304311
null,

0 commit comments

Comments
 (0)