kuzzle 2.19.12 → 2.20.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +1 -1
- package/index.js +1 -1
- package/lib/api/controllers/authController.d.ts +164 -0
- package/lib/api/controllers/authController.js +469 -654
- package/lib/api/controllers/baseController.d.ts +74 -0
- package/lib/api/controllers/baseController.js +169 -221
- package/lib/api/controllers/documentController.js +6 -8
- package/lib/api/funnel.js +4 -1
- package/lib/api/httpRoutes.js +6 -0
- package/lib/api/openapi/openApiGenerator.js +2 -2
- package/lib/api/request/kuzzleRequest.d.ts +3 -1
- package/lib/api/request/kuzzleRequest.js +32 -0
- package/lib/core/backend/backendController.js +2 -2
- package/lib/core/backend/backendPlugin.js +2 -2
- package/lib/core/network/protocols/httpwsProtocol.js +0 -12
- package/lib/core/plugin/pluginRepository.js +1 -1
- package/lib/core/plugin/pluginsManager.js +1 -1
- package/lib/core/security/index.js +1 -1
- package/lib/core/security/profileRepository.d.ts +14 -4
- package/lib/core/security/profileRepository.js +2 -2
- package/lib/core/security/roleRepository.js +1 -1
- package/lib/core/security/tokenRepository.d.ts +73 -0
- package/lib/core/security/tokenRepository.js +359 -460
- package/lib/core/security/userRepository.js +1 -1
- package/lib/core/shared/repository.d.ts +178 -0
- package/lib/core/shared/repository.js +365 -450
- package/lib/kerror/codes/7-security.json +6 -0
- package/lib/model/security/token.d.ts +2 -0
- package/lib/model/security/token.js +1 -0
- package/lib/service/storage/elasticsearch.js +4 -0
- package/lib/util/{inflector.d.ts → Inflector.d.ts} +5 -0
- package/lib/util/{inflector.js → Inflector.js} +12 -1
- package/package.json +11 -4
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { JSONObject } from "kuzzle-sdk";
|
|
2
|
+
import { KuzzleRequest } from "../request";
|
|
3
|
+
/**
|
|
4
|
+
* Base class for all controllers
|
|
5
|
+
*/
|
|
6
|
+
export declare class BaseController {
|
|
7
|
+
protected __actions: Set<string>;
|
|
8
|
+
constructor();
|
|
9
|
+
get _actions(): Set<string>;
|
|
10
|
+
_addAction(name: any, fn: any): void;
|
|
11
|
+
/**
|
|
12
|
+
* Check if the provided action name exists within that controller.
|
|
13
|
+
* This check's purpose is to prevent actions leak by making actions exposure
|
|
14
|
+
* explicit.
|
|
15
|
+
*
|
|
16
|
+
* @param name
|
|
17
|
+
*/
|
|
18
|
+
_isAction(name: string): boolean;
|
|
19
|
+
}
|
|
20
|
+
export declare class NativeController extends BaseController {
|
|
21
|
+
protected ask: (event: string, ...args: any[]) => Promise<any>;
|
|
22
|
+
protected pipe: (event: string, ...args: any[]) => Promise<any>;
|
|
23
|
+
constructor(actions?: any[]);
|
|
24
|
+
/**
|
|
25
|
+
* Controller optional initialization method.
|
|
26
|
+
* Used to perform asynchronous initialization safely: the funnel will wait
|
|
27
|
+
* for all controllers to be initialized before accepting requests.
|
|
28
|
+
*/
|
|
29
|
+
init(): Promise<void>;
|
|
30
|
+
translateKoncorde(koncordeFilters: JSONObject): Promise<any>;
|
|
31
|
+
/**
|
|
32
|
+
* Throws if the body contain one of the specified attribute
|
|
33
|
+
*
|
|
34
|
+
* @param request
|
|
35
|
+
* @param paths
|
|
36
|
+
*/
|
|
37
|
+
assertBodyHasNotAttributes(request: KuzzleRequest, ...paths: string[]): void;
|
|
38
|
+
/**
|
|
39
|
+
* Throws if the strategy does not exists
|
|
40
|
+
*
|
|
41
|
+
* @todo move this method in some kind of "Security" class
|
|
42
|
+
*/
|
|
43
|
+
assertIsStrategyRegistered(strategy: string): void;
|
|
44
|
+
/**
|
|
45
|
+
* Throw if some target have:
|
|
46
|
+
* - missing properties
|
|
47
|
+
* - invalid types
|
|
48
|
+
* - unauthorized values
|
|
49
|
+
*
|
|
50
|
+
* @param Array of targets
|
|
51
|
+
* @param options.allowEmptyCollections
|
|
52
|
+
*/
|
|
53
|
+
assertTargetsAreValid(targets: Array<{
|
|
54
|
+
index: string;
|
|
55
|
+
collections?: string[];
|
|
56
|
+
}>, { allowEmptyCollections }?: {
|
|
57
|
+
allowEmptyCollections?: boolean;
|
|
58
|
+
}): void;
|
|
59
|
+
_hasMultiTargets(str: string): boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Throws if page size exceeed Kuzzle limits
|
|
62
|
+
*
|
|
63
|
+
* @param asked
|
|
64
|
+
* @throws
|
|
65
|
+
*/
|
|
66
|
+
assertNotExceedMaxFetch(asked: number): void;
|
|
67
|
+
/**
|
|
68
|
+
* Throws if number of documents exceeed Kuzzle limits
|
|
69
|
+
*
|
|
70
|
+
* @param asked
|
|
71
|
+
* @throws
|
|
72
|
+
*/
|
|
73
|
+
assertNotExceedMaxWrite(asked: number): void;
|
|
74
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/*
|
|
2
3
|
* Kuzzle, a backend software, self-hostable and ready to use
|
|
3
4
|
* to power modern apps
|
|
@@ -18,239 +19,186 @@
|
|
|
18
19
|
* See the License for the specific language governing permissions and
|
|
19
20
|
* limitations under the License.
|
|
20
21
|
*/
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
22
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
23
|
+
if (k2 === undefined) k2 = k;
|
|
24
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
25
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
26
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
27
|
+
}
|
|
28
|
+
Object.defineProperty(o, k2, desc);
|
|
29
|
+
}) : (function(o, m, k, k2) {
|
|
30
|
+
if (k2 === undefined) k2 = k;
|
|
31
|
+
o[k2] = m[k];
|
|
32
|
+
}));
|
|
33
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
34
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
35
|
+
}) : function(o, v) {
|
|
36
|
+
o["default"] = v;
|
|
37
|
+
});
|
|
38
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
39
|
+
if (mod && mod.__esModule) return mod;
|
|
40
|
+
var result = {};
|
|
41
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
42
|
+
__setModuleDefault(result, mod);
|
|
43
|
+
return result;
|
|
44
|
+
};
|
|
45
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
|
+
exports.NativeController = exports.BaseController = void 0;
|
|
47
|
+
const kerror = __importStar(require("../../kerror"));
|
|
48
|
+
const safeObject_1 = require("../../util/safeObject");
|
|
29
49
|
const assertionError = kerror.wrap("api", "assert");
|
|
30
|
-
|
|
31
|
-
|
|
50
|
+
/**
|
|
51
|
+
* Base class for all controllers
|
|
52
|
+
*/
|
|
32
53
|
class BaseController {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
*/
|
|
54
|
-
_isAction(name) {
|
|
55
|
-
return this.__actions.has(name);
|
|
56
|
-
}
|
|
54
|
+
constructor() {
|
|
55
|
+
this.__actions = new Set();
|
|
56
|
+
}
|
|
57
|
+
get _actions() {
|
|
58
|
+
return this.__actions;
|
|
59
|
+
}
|
|
60
|
+
_addAction(name, fn) {
|
|
61
|
+
this.__actions.add(name);
|
|
62
|
+
this[name] = fn;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Check if the provided action name exists within that controller.
|
|
66
|
+
* This check's purpose is to prevent actions leak by making actions exposure
|
|
67
|
+
* explicit.
|
|
68
|
+
*
|
|
69
|
+
* @param name
|
|
70
|
+
*/
|
|
71
|
+
_isAction(name) {
|
|
72
|
+
return this.__actions.has(name);
|
|
73
|
+
}
|
|
57
74
|
}
|
|
58
|
-
|
|
75
|
+
exports.BaseController = BaseController;
|
|
59
76
|
class NativeController extends BaseController {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
this.__actions = new Set(actions);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Controller optional initialization method.
|
|
70
|
-
* Used to perform asynchronous initialization safely: the funnel will wait
|
|
71
|
-
* for all controllers to be initialized before accepting requests.
|
|
72
|
-
*
|
|
73
|
-
* @returns {Promise}
|
|
74
|
-
*/
|
|
75
|
-
init() {
|
|
76
|
-
return Bluebird.resolve();
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
async translateKoncorde(koncordeFilters) {
|
|
80
|
-
if (Object.keys(koncordeFilters).length === 0) {
|
|
81
|
-
return {};
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
if (typeof koncordeFilters !== "object") {
|
|
85
|
-
throw assertionError.get("invalid_type", "body.query", "object");
|
|
77
|
+
constructor(actions = []) {
|
|
78
|
+
super();
|
|
79
|
+
this.ask = global.kuzzle.ask.bind(global.kuzzle);
|
|
80
|
+
this.pipe = global.kuzzle.pipe.bind(global.kuzzle);
|
|
81
|
+
this.__actions = new Set(actions);
|
|
86
82
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
throw assertionError.get(
|
|
96
|
-
"koncorde_restricted_keyword",
|
|
97
|
-
error.keyword.type,
|
|
98
|
-
error.keyword.name
|
|
99
|
-
);
|
|
83
|
+
/**
|
|
84
|
+
* Controller optional initialization method.
|
|
85
|
+
* Used to perform asynchronous initialization safely: the funnel will wait
|
|
86
|
+
* for all controllers to be initialized before accepting requests.
|
|
87
|
+
*/
|
|
88
|
+
async init() {
|
|
89
|
+
// nothing here
|
|
100
90
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
91
|
+
async translateKoncorde(koncordeFilters) {
|
|
92
|
+
if (Object.keys(koncordeFilters).length === 0) {
|
|
93
|
+
return {};
|
|
94
|
+
}
|
|
95
|
+
if (typeof koncordeFilters !== "object") {
|
|
96
|
+
throw assertionError.get("invalid_type", "body.query", "object");
|
|
97
|
+
}
|
|
98
|
+
try {
|
|
99
|
+
return await this.ask("core:storage:public:translate", koncordeFilters);
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
if (!error.keyword) {
|
|
103
|
+
throw error;
|
|
104
|
+
}
|
|
105
|
+
throw assertionError.get("koncorde_restricted_keyword", error.keyword.type, error.keyword.name);
|
|
114
106
|
}
|
|
115
|
-
}
|
|
116
107
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
108
|
+
/**
|
|
109
|
+
* Throws if the body contain one of the specified attribute
|
|
110
|
+
*
|
|
111
|
+
* @param request
|
|
112
|
+
* @param paths
|
|
113
|
+
*/
|
|
114
|
+
assertBodyHasNotAttributes(request, ...paths) {
|
|
115
|
+
if (request.input.body !== null) {
|
|
116
|
+
for (const path of paths) {
|
|
117
|
+
if ((0, safeObject_1.get)(request.input.body, path)) {
|
|
118
|
+
throw assertionError.get("forbidden_argument", `body.${path}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
128
122
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
* @param {Array<{index:string, collections?: string[]}>} targets Array of targets
|
|
138
|
-
* @param {*} options
|
|
139
|
-
*/
|
|
140
|
-
assertTargetsAreValid(targets, { allowEmptyCollections } = {}) {
|
|
141
|
-
for (let i = 0; i < targets.length; i++) {
|
|
142
|
-
const target = targets[i];
|
|
143
|
-
|
|
144
|
-
if (!target.index) {
|
|
145
|
-
throw kerror.get(
|
|
146
|
-
"api",
|
|
147
|
-
"assert",
|
|
148
|
-
"missing_argument",
|
|
149
|
-
`targets[${i}].index`
|
|
150
|
-
);
|
|
151
|
-
}
|
|
152
|
-
if (this._hasMultiTargets(target.index)) {
|
|
153
|
-
throw kerror.get(
|
|
154
|
-
"services",
|
|
155
|
-
"storage",
|
|
156
|
-
"invalid_target_format",
|
|
157
|
-
`targets[${i}].index`,
|
|
158
|
-
target.index
|
|
159
|
-
);
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
if (!allowEmptyCollections && !target.collections) {
|
|
163
|
-
throw kerror.get(
|
|
164
|
-
"api",
|
|
165
|
-
"assert",
|
|
166
|
-
"missing_argument",
|
|
167
|
-
`targets[${i}].collections`
|
|
168
|
-
);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
if (target.collections && !Array.isArray(target.collections)) {
|
|
172
|
-
throw kerror.get(
|
|
173
|
-
"api",
|
|
174
|
-
"assert",
|
|
175
|
-
"invalid_type",
|
|
176
|
-
`targets[${i}].collections`,
|
|
177
|
-
"array"
|
|
178
|
-
);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
if (!allowEmptyCollections && target.collections.length === 0) {
|
|
182
|
-
throw kerror.get(
|
|
183
|
-
"api",
|
|
184
|
-
"assert",
|
|
185
|
-
"empty_argument",
|
|
186
|
-
`targets[${i}].collections`
|
|
187
|
-
);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
if (
|
|
191
|
-
allowEmptyCollections &&
|
|
192
|
-
(!target.collections || target.collections.length === 0)
|
|
193
|
-
) {
|
|
194
|
-
continue;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
for (let j = 0; j < target.collections.length; j++) {
|
|
198
|
-
const collection = target.collections[j];
|
|
199
|
-
|
|
200
|
-
if (typeof collection !== "string") {
|
|
201
|
-
throw kerror.get(
|
|
202
|
-
"api",
|
|
203
|
-
"assert",
|
|
204
|
-
"invalid_type",
|
|
205
|
-
`targets[${i}].collections[${j}]`,
|
|
206
|
-
"string"
|
|
207
|
-
);
|
|
123
|
+
/**
|
|
124
|
+
* Throws if the strategy does not exists
|
|
125
|
+
*
|
|
126
|
+
* @todo move this method in some kind of "Security" class
|
|
127
|
+
*/
|
|
128
|
+
assertIsStrategyRegistered(strategy) {
|
|
129
|
+
if (!global.kuzzle.pluginsManager.listStrategies().includes(strategy)) {
|
|
130
|
+
throw kerror.get("security", "credentials", "unknown_strategy", strategy);
|
|
208
131
|
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Throw if some target have:
|
|
135
|
+
* - missing properties
|
|
136
|
+
* - invalid types
|
|
137
|
+
* - unauthorized values
|
|
138
|
+
*
|
|
139
|
+
* @param Array of targets
|
|
140
|
+
* @param options.allowEmptyCollections
|
|
141
|
+
*/
|
|
142
|
+
assertTargetsAreValid(targets, { allowEmptyCollections = false } = {}) {
|
|
143
|
+
for (let i = 0; i < targets.length; i++) {
|
|
144
|
+
const target = targets[i];
|
|
145
|
+
if (!target.index) {
|
|
146
|
+
throw kerror.get("api", "assert", "missing_argument", `targets[${i}].index`);
|
|
147
|
+
}
|
|
148
|
+
if (this._hasMultiTargets(target.index)) {
|
|
149
|
+
throw kerror.get("services", "storage", "invalid_target_format", `targets[${i}].index`, target.index);
|
|
150
|
+
}
|
|
151
|
+
if (!allowEmptyCollections && !target.collections) {
|
|
152
|
+
throw kerror.get("api", "assert", "missing_argument", `targets[${i}].collections`);
|
|
153
|
+
}
|
|
154
|
+
if (target.collections && !Array.isArray(target.collections)) {
|
|
155
|
+
throw kerror.get("api", "assert", "invalid_type", `targets[${i}].collections`, "array");
|
|
156
|
+
}
|
|
157
|
+
if (!allowEmptyCollections && target.collections.length === 0) {
|
|
158
|
+
throw kerror.get("api", "assert", "empty_argument", `targets[${i}].collections`);
|
|
159
|
+
}
|
|
160
|
+
if (allowEmptyCollections &&
|
|
161
|
+
(!target.collections || target.collections.length === 0)) {
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
for (let j = 0; j < target.collections.length; j++) {
|
|
165
|
+
const collection = target.collections[j];
|
|
166
|
+
if (typeof collection !== "string") {
|
|
167
|
+
throw kerror.get("api", "assert", "invalid_type", `targets[${i}].collections[${j}]`, "string");
|
|
168
|
+
}
|
|
169
|
+
if (this._hasMultiTargets(collection)) {
|
|
170
|
+
throw kerror.get("services", "storage", "invalid_target_format", `targets[${i}].collections[${j}]`, collection);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
218
173
|
}
|
|
219
|
-
}
|
|
220
174
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
if (asked > limit) {
|
|
237
|
-
throw kerror.get("services", "storage", "get_limit_exceeded");
|
|
175
|
+
_hasMultiTargets(str) {
|
|
176
|
+
return [",", "*", "+"].some((chr) => str.includes(chr)) || str === "_all";
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Throws if page size exceeed Kuzzle limits
|
|
180
|
+
*
|
|
181
|
+
* @param asked
|
|
182
|
+
* @throws
|
|
183
|
+
*/
|
|
184
|
+
assertNotExceedMaxFetch(asked) {
|
|
185
|
+
const limit = global.kuzzle.config.limits.documentsFetchCount;
|
|
186
|
+
if (asked > limit) {
|
|
187
|
+
throw kerror.get("services", "storage", "get_limit_exceeded");
|
|
188
|
+
}
|
|
238
189
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
if (asked > limit) {
|
|
251
|
-
throw kerror.get("services", "storage", "write_limit_exceeded");
|
|
190
|
+
/**
|
|
191
|
+
* Throws if number of documents exceeed Kuzzle limits
|
|
192
|
+
*
|
|
193
|
+
* @param asked
|
|
194
|
+
* @throws
|
|
195
|
+
*/
|
|
196
|
+
assertNotExceedMaxWrite(asked) {
|
|
197
|
+
const limit = global.kuzzle.config.limits.documentsWriteCount;
|
|
198
|
+
if (asked > limit) {
|
|
199
|
+
throw kerror.get("services", "storage", "write_limit_exceeded");
|
|
200
|
+
}
|
|
252
201
|
}
|
|
253
|
-
}
|
|
254
202
|
}
|
|
255
|
-
|
|
256
|
-
|
|
203
|
+
exports.NativeController = NativeController;
|
|
204
|
+
//# sourceMappingURL=baseController.js.map
|
|
@@ -232,17 +232,15 @@ class DocumentController extends NativeController {
|
|
|
232
232
|
|
|
233
233
|
async export(request) {
|
|
234
234
|
const { index, collection } = request.getIndexAndCollection();
|
|
235
|
-
const { size, scrollTTL
|
|
236
|
-
const format = request.getString("format", "jsonl");
|
|
237
|
-
const fields = request.getBodyArray("fields", []);
|
|
235
|
+
const { size, scrollTTL } = request.getSearchParams();
|
|
238
236
|
const lang = request.getLangParam();
|
|
237
|
+
const format = request.getString("format", "jsonl");
|
|
239
238
|
const separator = request.getString("separator", ",");
|
|
240
|
-
const
|
|
239
|
+
const query = request.getObjectFromBodyOrArgs("query", {});
|
|
240
|
+
const fields = request.getArrayFromBodyOrArgs("fields", []);
|
|
241
|
+
const fieldsName = request.getObjectFromBodyOrArgs("fieldsName", {});
|
|
241
242
|
|
|
242
|
-
|
|
243
|
-
// since those properties are not allowed in the searchBody
|
|
244
|
-
searchBody.fields = undefined;
|
|
245
|
-
searchBody.fieldsName = undefined;
|
|
243
|
+
const searchBody = { query };
|
|
246
244
|
|
|
247
245
|
if (request.context.connection.protocol !== "http") {
|
|
248
246
|
throw kerror.get(
|
package/lib/api/funnel.js
CHANGED
|
@@ -50,6 +50,7 @@ const kerror = require("../kerror");
|
|
|
50
50
|
const debug = require("../util/debug")("kuzzle:funnel");
|
|
51
51
|
const processError = kerror.wrap("api", "process");
|
|
52
52
|
const { has } = require("../util/safeObject");
|
|
53
|
+
const { HttpStream } = require("../types");
|
|
53
54
|
|
|
54
55
|
// Actions of the auth controller that does not necessite to verify the token
|
|
55
56
|
// when cookie auth is active
|
|
@@ -662,7 +663,9 @@ class Funnel {
|
|
|
662
663
|
) {
|
|
663
664
|
// check if the plugin response can be serialized
|
|
664
665
|
try {
|
|
665
|
-
|
|
666
|
+
if (!(responseData instanceof HttpStream)) {
|
|
667
|
+
JSON.stringify(responseData);
|
|
668
|
+
}
|
|
666
669
|
} catch (e) {
|
|
667
670
|
_request.setResult(null);
|
|
668
671
|
throw kerror.get("plugin", "controller", "unserializable_response");
|
package/lib/api/httpRoutes.js
CHANGED
|
@@ -25,7 +25,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
exports.generateOpenApi = void 0;
|
|
27
27
|
const lodash_1 = __importDefault(require("lodash"));
|
|
28
|
-
const
|
|
28
|
+
const Inflector_1 = require("../../util/Inflector");
|
|
29
29
|
const routeUrlMatch = /:([^/]*)/g;
|
|
30
30
|
/**
|
|
31
31
|
* Generate basic openApi Controller
|
|
@@ -35,7 +35,7 @@ function generateController(route, definition) {
|
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
37
37
|
if (!lodash_1.default.some(definition.tags, { name: route.controller })) {
|
|
38
|
-
const capitalizedController =
|
|
38
|
+
const capitalizedController = Inflector_1.Inflector.pascalCase(route.controller);
|
|
39
39
|
definition.tags.push({
|
|
40
40
|
description: `${capitalizedController} Controller`,
|
|
41
41
|
name: route.controller,
|
|
@@ -16,7 +16,7 @@ export declare class KuzzleRequest {
|
|
|
16
16
|
* Request external ID (specified by "requestId" or random uuid)
|
|
17
17
|
*/
|
|
18
18
|
id: string;
|
|
19
|
-
constructor(data: any, options
|
|
19
|
+
constructor(data: any, options?: any);
|
|
20
20
|
/**
|
|
21
21
|
* Request internal ID
|
|
22
22
|
*/
|
|
@@ -373,6 +373,8 @@ export declare class KuzzleRequest {
|
|
|
373
373
|
* Returns the search body query according to the http method
|
|
374
374
|
*/
|
|
375
375
|
getSearchBody(): JSONObject;
|
|
376
|
+
getObjectFromBodyOrArgs(name: string, def?: JSONObject): JSONObject;
|
|
377
|
+
getArrayFromBodyOrArgs(name: string, def?: any): JSONObject;
|
|
376
378
|
/**
|
|
377
379
|
* Returns the search params.
|
|
378
380
|
*/
|
|
@@ -726,6 +726,38 @@ class KuzzleRequest {
|
|
|
726
726
|
}
|
|
727
727
|
return this.getObject("searchBody", {});
|
|
728
728
|
}
|
|
729
|
+
getObjectFromBodyOrArgs(name, def) {
|
|
730
|
+
if (this.context.connection.protocol !== "http" ||
|
|
731
|
+
this.context.connection.misc.verb !== "GET") {
|
|
732
|
+
return this.getBodyObject(name, def);
|
|
733
|
+
}
|
|
734
|
+
const rawObject = this.getString(name, JSON.stringify(def));
|
|
735
|
+
try {
|
|
736
|
+
return JSON.parse(rawObject);
|
|
737
|
+
}
|
|
738
|
+
catch (error) {
|
|
739
|
+
if (error instanceof SyntaxError) {
|
|
740
|
+
throw assertionError.get("invalid_type", name, "JSON string");
|
|
741
|
+
}
|
|
742
|
+
throw error;
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
getArrayFromBodyOrArgs(name, def) {
|
|
746
|
+
if (this.context.connection.protocol !== "http" ||
|
|
747
|
+
this.context.connection.misc.verb !== "GET") {
|
|
748
|
+
return this.getBodyArray(name, def);
|
|
749
|
+
}
|
|
750
|
+
const rawObject = this.getString(name, JSON.stringify(def));
|
|
751
|
+
try {
|
|
752
|
+
return JSON.parse(rawObject);
|
|
753
|
+
}
|
|
754
|
+
catch (error) {
|
|
755
|
+
if (error instanceof SyntaxError) {
|
|
756
|
+
throw assertionError.get("invalid_type", name, "JSON string");
|
|
757
|
+
}
|
|
758
|
+
throw error;
|
|
759
|
+
}
|
|
760
|
+
}
|
|
729
761
|
/**
|
|
730
762
|
* Returns the search params.
|
|
731
763
|
*/
|
|
@@ -47,7 +47,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
47
47
|
};
|
|
48
48
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49
49
|
exports.BackendController = void 0;
|
|
50
|
-
const
|
|
50
|
+
const Inflector_1 = require("../../util/Inflector");
|
|
51
51
|
const kerror = __importStar(require("../../kerror"));
|
|
52
52
|
const index_1 = require("./index");
|
|
53
53
|
const plugin_1 = __importDefault(require("../plugin/plugin"));
|
|
@@ -149,7 +149,7 @@ class BackendController extends index_1.ApplicationManager {
|
|
|
149
149
|
throw runtimeError.get("already_started", "controller");
|
|
150
150
|
}
|
|
151
151
|
if (!controller.name) {
|
|
152
|
-
controller.name =
|
|
152
|
+
controller.name = Inflector_1.Inflector.kebabCase(controller.constructor.name).replace("-controller", "");
|
|
153
153
|
}
|
|
154
154
|
plugin_1.default.checkControllerDefinition(controller.name, controller.definition);
|
|
155
155
|
for (const [action, definition] of Object.entries(controller.definition.actions)) {
|
|
@@ -47,7 +47,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
47
47
|
};
|
|
48
48
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49
49
|
exports.BackendPlugin = void 0;
|
|
50
|
-
const
|
|
50
|
+
const Inflector_1 = require("../../util/Inflector");
|
|
51
51
|
const kerror = __importStar(require("../../kerror"));
|
|
52
52
|
const index_1 = require("./index");
|
|
53
53
|
const didYouMean_1 = __importDefault(require("../../util/didYouMean"));
|
|
@@ -77,7 +77,7 @@ class BackendPlugin extends index_1.ApplicationManager {
|
|
|
77
77
|
throw assertionError.get("no_name_provided");
|
|
78
78
|
}
|
|
79
79
|
const name = options.name ||
|
|
80
|
-
|
|
80
|
+
Inflector_1.Inflector.kebabCase(plugin.constructor.name.replace("Plugin", ""));
|
|
81
81
|
if (!this._application.PluginObject.checkName(name)) {
|
|
82
82
|
throw assertionError.get("invalid_plugin_name", name);
|
|
83
83
|
}
|