Skip to content

Commit 5b9a181

Browse files
authored
Merge pull request #402 from kuzzleio/6.1.2-proposal
Release 6.1.2 Bug fixes [ #398 ] Fix bulk return (Aschen) [ #394 ] Add default values for from/size to document:search (Aschen) [ #384 ] Fix search API: "sort" and "search_after" must be in the requests body (scottinet) Enhancements [ #390 ] Add authenticated property on Kuzzle object (Aschen) [ #395 ] Proxify kuzzle to avoid mistyping error (thomasarbona) [ #389 ] Remove usage of _meta (Aschen) [ #391 ] Add isConnected (Aschen) [ #388 ] Use BaseController class for controllers (Aschen) [ #385 ] Add Security.createRestrictedUser method (Aschen) Others [ #400 ] Fix large document search using scroll (stafyniaksacha) [ #387 ] SearchResult.next returns a new instance (Aschen)
2 parents ff49bb5 + 357ddba commit 5b9a181

37 files changed

+722
-181
lines changed

.eslintrc.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
"yoda": [2, "never"]
5252
},
5353
"parserOptions": {
54-
"ecmaVersion": 2017
54+
"ecmaVersion": 2018
5555
},
5656
"extends": "eslint:recommended"
5757
}

features/steps/collection.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ Then('the mapping of {string} should be updated', async function (collection) {
109109
const mapping = await this.kuzzle.collection.getMapping(this.index, collection);
110110

111111
should(mapping[this.index].mappings[collection]).eql({
112+
dynamic: 'true',
112113
properties: {
113114
gordon: {type: 'keyword'}
114115
}
@@ -129,7 +130,6 @@ Then('the specifications of {string} must not exist', async function (collection
129130
catch (error) {
130131
should(error.status).eql(404);
131132
}
132-
133133
});
134134

135135
Then('they should be validated', function () {

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "kuzzle-sdk",
3-
"version": "6.1.1",
3+
"version": "6.1.2",
44
"description": "Official Javascript SDK for Kuzzle",
55
"author": "The Kuzzle Team <support@kuzzle.io>",
66
"repository": {

src/Kuzzle.js

Lines changed: 44 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ const
1010
SecurityController = require('./controllers/security'),
1111
MemoryStorageController = require('./controllers/memoryStorage'),
1212
BaseController = require('./controllers/base'),
13-
uuidv4 = require('./uuidv4');
13+
uuidv4 = require('./uuidv4'),
14+
proxify = require('./proxify');
1415

1516
const
1617
events = [
@@ -87,6 +88,14 @@ class Kuzzle extends KuzzleEventEmitter {
8788
}
8889
this.queuing = false;
8990
this.replayInterval = 10;
91+
92+
this._jwt = undefined;
93+
94+
return proxify(this, {
95+
seal: true,
96+
name: 'kuzzle',
97+
exposeApi: true
98+
});
9099
}
91100

92101
get autoQueue () {
@@ -116,28 +125,6 @@ class Kuzzle extends KuzzleEventEmitter {
116125
this._autoReplay = value;
117126
}
118127

119-
get jwt () {
120-
return this._jwt;
121-
}
122-
123-
set jwt (token) {
124-
if (token === undefined || token === null) {
125-
this._jwt = undefined;
126-
}
127-
else if (typeof token === 'string') {
128-
this._jwt = token;
129-
}
130-
else if (typeof token === 'object'
131-
&& token.result
132-
&& token.result.jwt
133-
&& typeof token.result.jwt === 'string'
134-
) {
135-
this._jwt = token.result.jwt;
136-
} else {
137-
throw new Error(`Invalid token argument: ${token}`);
138-
}
139-
}
140-
141128
get host () {
142129
return this.protocol.host;
143130
}
@@ -203,6 +190,26 @@ class Kuzzle extends KuzzleEventEmitter {
203190
return this.protocol.sslConnection;
204191
}
205192

193+
get authenticated () {
194+
return this.auth.authenticationToken && !this.auth.authenticationToken.expired;
195+
}
196+
197+
get jwt () {
198+
if (!this.auth.authenticationToken) {
199+
return null;
200+
}
201+
202+
return this.auth.authenticationToken.encodedJwt;
203+
}
204+
205+
set jwt (encodedJwt) {
206+
this.auth.authenticationToken = encodedJwt;
207+
}
208+
209+
get connected () {
210+
return this.protocol.connected;
211+
}
212+
206213
/**
207214
* Emit an event to all registered listeners
208215
* An event cannot be emitted multiple times before a timeout has been reached.
@@ -238,7 +245,7 @@ class Kuzzle extends KuzzleEventEmitter {
238245
this.protocol.addListener('queryError', (err, query) => this.emit('queryError', err, query));
239246

240247
this.protocol.addListener('tokenExpired', () => {
241-
this.jwt = undefined;
248+
this.auth.authenticationToken = null;
242249
this.emit('tokenExpired');
243250
});
244251

@@ -274,16 +281,17 @@ class Kuzzle extends KuzzleEventEmitter {
274281
this.playQueue();
275282
}
276283

277-
if (this.jwt) {
278-
return this.auth.checkToken(this.jwt)
284+
if (this.auth.authenticationToken) {
285+
return this.auth.checkToken()
279286
.then(res => {
287+
280288
// shouldn't obtain an error but let's invalidate the token anyway
281289
if (!res.valid) {
282-
this.jwt = undefined;
290+
this.auth.authenticationToken = null;
283291
}
284292
})
285293
.catch(() => {
286-
this.jwt = undefined;
294+
this.auth.authenticationToken = null;
287295
})
288296
.then(() => this.emit('reconnected'));
289297
}
@@ -371,16 +379,7 @@ class Kuzzle extends KuzzleEventEmitter {
371379
request.volatile.sdkInstanceId = this.protocol.id;
372380
request.volatile.sdkVersion = this.sdkVersion;
373381

374-
/*
375-
* Do not add the token for the checkToken route, to avoid getting a token error when
376-
* a developer simply wish to verify his token
377-
*/
378-
if (this.jwt !== undefined
379-
&& !(request.controller === 'auth'
380-
&& (request.action === 'checkToken' || request.action === 'login'))
381-
) {
382-
request.jwt = this.jwt;
383-
}
382+
this.auth.authenticateRequest(request);
384383

385384
let queuable = true;
386385
if (options && options.queuable === false) {
@@ -456,20 +455,23 @@ Discarded request: ${JSON.stringify(request)}`));
456455
throw new Error('You must provide a valid accessor.');
457456
}
458457

459-
if (this[accessor]) {
458+
if (this.__proxy__ ? this.__proxy__.hasProp(accessor) : this[accessor]) {
460459
throw new Error(`There is already a controller with the accessor '${accessor}'. Please use another one.`);
461460
}
462461

463462
const controller = new ControllerClass(this);
464-
463+
465464
if (!(controller.name && controller.name.length > 0)) {
466465
throw new Error('Controllers must have a name.');
467466
}
468-
467+
469468
if (controller.kuzzle !== this) {
470469
throw new Error('You must pass the Kuzzle SDK instance to the parent constructor.');
471470
}
472-
471+
472+
if (this.__proxy__) {
473+
this.__proxy__.registerProp(accessor);
474+
}
473475
this[accessor] = controller;
474476

475477
return this;

src/controllers/auth.js

Lines changed: 53 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
const
2+
Jwt = require('../core/Jwt'),
23
BaseController = require('./base'),
34
User = require('./security/user');
45

@@ -16,6 +17,39 @@ class AuthController extends BaseController {
1617
*/
1718
constructor (kuzzle) {
1819
super(kuzzle, 'auth');
20+
21+
this._authenticationToken = null;
22+
}
23+
24+
get authenticationToken () {
25+
return this._authenticationToken;
26+
}
27+
28+
set authenticationToken (encodedJwt) {
29+
if (encodedJwt === undefined || encodedJwt === null) {
30+
this._authenticationToken = null;
31+
} else if (typeof encodedJwt === 'string') {
32+
this._authenticationToken = new Jwt(encodedJwt);
33+
} else {
34+
throw new Error(`Invalid token argument: ${encodedJwt}`);
35+
}
36+
}
37+
38+
/**
39+
* Do not add the token for the checkToken route, to avoid getting a token error when
40+
* a developer simply wish to verify his token
41+
*
42+
* @param {object} request
43+
*/
44+
authenticateRequest (request) {
45+
if (!this.authenticationToken
46+
|| (request.controller === 'auth'
47+
&& (request.action === 'checkToken' || request.action === 'login'))
48+
) {
49+
return;
50+
}
51+
52+
request.jwt = this.authenticationToken.encodedJwt;
1953
}
2054

2155
/**
@@ -25,10 +59,14 @@ class AuthController extends BaseController {
2559
* @return {Promise|*|PromiseLike<T>|Promise<T>}
2660
*/
2761
checkToken (token) {
62+
if (token === undefined && this.authenticationToken) {
63+
token = this.authenticationToken.encodedJwt;
64+
}
65+
2866
return this.query({
2967
action: 'checkToken',
30-
body: {token}
31-
}, {queuable: false})
68+
body: { token }
69+
}, { queuable: false })
3270
.then(response => response.result);
3371
}
3472

@@ -87,7 +125,7 @@ class AuthController extends BaseController {
87125
return this.query({
88126
action: 'getCurrentUser'
89127
}, options)
90-
.then(response => new User(this.kuzzle, response.result._id, response.result._source, response.result._meta));
128+
.then(response => new User(this.kuzzle, response.result._id, response.result._source));
91129
}
92130

93131
/**
@@ -144,23 +182,24 @@ class AuthController extends BaseController {
144182
throw new Error('Kuzzle.auth.login: strategy is required');
145183
}
146184

147-
const
148-
request = {
149-
strategy,
150-
expiresIn,
151-
body: credentials,
152-
action: 'login'
153-
};
185+
const request = {
186+
strategy,
187+
expiresIn,
188+
body: credentials,
189+
action: 'login'
190+
};
154191

155192
return this.query(request, {queuable: false})
156193
.then(response => {
157194
try {
158-
this.kuzzle.jwt = response.result.jwt;
195+
this._authenticationToken = new Jwt(response.result.jwt);
196+
159197
this.kuzzle.emit('loginAttempt', {success: true});
160198
}
161199
catch (err) {
162200
return Promise.reject(err);
163201
}
202+
164203
return response.result.jwt;
165204
})
166205
.catch(err => {
@@ -179,7 +218,7 @@ class AuthController extends BaseController {
179218
action: 'logout'
180219
}, {queuable: false})
181220
.then(() => {
182-
this.kuzzle.jwt = undefined;
221+
this._authenticationToken = null;
183222
});
184223
}
185224

@@ -212,7 +251,7 @@ class AuthController extends BaseController {
212251
body,
213252
action: 'updateSelf'
214253
}, options)
215-
.then(response => new User(this.kuzzle, response.result._id, response.result._source, response.result._meta));
254+
.then(response => new User(this.kuzzle, response.result._id, response.result._source));
216255
}
217256

218257
/**
@@ -246,7 +285,7 @@ class AuthController extends BaseController {
246285

247286
return this.query(query, options)
248287
.then(response => {
249-
this.kuzzle.jwt = response.result.jwt;
288+
this._authenticationToken = new Jwt(response.result.jwt);
250289

251290
return response.result;
252291
});

src/controllers/bulk.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class BulkController extends BaseController {
1212
bulkData: data
1313
}
1414
}, options)
15-
.then(response => response.result.items);
15+
.then(response => response.result);
1616
}
1717

1818
}

src/controllers/document.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,11 +361,17 @@ class DocumentController extends BaseController {
361361
body,
362362
action: 'search',
363363
};
364+
364365
for (const opt of ['from', 'size', 'scroll', 'includeTrash']) {
365366
request[opt] = options[opt];
366367
delete options[opt];
367368
}
368369

370+
request.size = request.size || 10;
371+
if (!request.scroll && !request.body.sort && !request.from) {
372+
request.from = 0;
373+
}
374+
369375
return this.query(request, options)
370376
.then(response => new DocumentSearchResult(this.kuzzle, request, options, response.result));
371377
}

src/controllers/realtime/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,10 @@ class RealTimeController extends BaseController {
111111
}
112112

113113
this.subscriptions = {};
114-
this.kuzzle.jwt = undefined;
114+
this.kuzzle.auth.authenticationToken = null;
115115

116116
const now = Date.now();
117+
117118
if ((now - this.lastExpirationTimestamp) > expirationThrottleDelay) {
118119
this.lastExpirationTimestamp = now;
119120
this.kuzzle.emit('tokenExpired');

src/controllers/searchResult/base.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class SearchResultBase {
3232
return this._kuzzle.query({
3333
controller: this._request.controller,
3434
action: this._scrollAction,
35+
scroll: this._request.scroll,
3536
scrollId: this._response.scrollId
3637
}, this._options)
3738
.then(response => this._buildNextSearchResult(response));

0 commit comments

Comments
 (0)