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
|
@@ -1,3 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.AuthController = void 0;
|
|
1
30
|
/*
|
|
2
31
|
* Kuzzle, a backend software, self-hostable and ready to use
|
|
3
32
|
* to power modern apps
|
|
@@ -18,683 +47,469 @@
|
|
|
18
47
|
* See the License for the specific language governing permissions and
|
|
19
48
|
* limitations under the License.
|
|
20
49
|
*/
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
const
|
|
31
|
-
const
|
|
32
|
-
const
|
|
33
|
-
const
|
|
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
|
-
"logout",
|
|
63
|
-
"refreshToken",
|
|
64
|
-
"searchApiKeys",
|
|
65
|
-
"updateMyCredentials",
|
|
66
|
-
"updateSelf",
|
|
67
|
-
"validateMyCredentials",
|
|
68
|
-
]);
|
|
69
|
-
|
|
70
|
-
this.anonymousId = null;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Controller initialization: we need the anonymous user identifier for the
|
|
75
|
-
* "isAuthenticated" assertion
|
|
76
|
-
*
|
|
77
|
-
* @returns {Promise}
|
|
78
|
-
*/
|
|
79
|
-
async init() {
|
|
80
|
-
const anonymous = await global.kuzzle.ask(
|
|
81
|
-
"core:security:user:anonymous:get"
|
|
82
|
-
);
|
|
83
|
-
this.anonymousId = anonymous._id;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Checks if an API action can be executed by the current user
|
|
88
|
-
*/
|
|
89
|
-
async checkRights(request) {
|
|
90
|
-
const requestPayload = request.getBody();
|
|
91
|
-
|
|
92
|
-
if (typeof requestPayload.controller !== "string") {
|
|
93
|
-
throw kerror.get("api", "assert", "missing_argument", "body.controller");
|
|
50
|
+
const http_1 = require("http");
|
|
51
|
+
const cookie_1 = __importDefault(require("cookie"));
|
|
52
|
+
const bluebird_1 = __importDefault(require("bluebird"));
|
|
53
|
+
const lodash_1 = require("lodash");
|
|
54
|
+
const errors_1 = require("../../kerror/errors");
|
|
55
|
+
const request_1 = require("../request");
|
|
56
|
+
const kerror = __importStar(require("../../kerror"));
|
|
57
|
+
const safeObject_1 = require("../../util/safeObject");
|
|
58
|
+
const baseController_1 = require("./baseController");
|
|
59
|
+
const formatProcessing_1 = __importDefault(require("../../core/auth/formatProcessing"));
|
|
60
|
+
const user_1 = require("../../model/security/user");
|
|
61
|
+
const apiKey_1 = __importDefault(require("../../model/storage/apiKey"));
|
|
62
|
+
const securityController_1 = __importDefault(require("./securityController"));
|
|
63
|
+
class AuthController extends baseController_1.NativeController {
|
|
64
|
+
/**
|
|
65
|
+
* @param {Kuzzle} kuzzle
|
|
66
|
+
* @constructor
|
|
67
|
+
*/
|
|
68
|
+
constructor() {
|
|
69
|
+
super([
|
|
70
|
+
"checkRights",
|
|
71
|
+
"checkToken",
|
|
72
|
+
"createApiKey",
|
|
73
|
+
"createMyCredentials",
|
|
74
|
+
"createToken",
|
|
75
|
+
"credentialsExist",
|
|
76
|
+
"deleteApiKey",
|
|
77
|
+
"deleteMyCredentials",
|
|
78
|
+
"getCurrentUser",
|
|
79
|
+
"getMyCredentials",
|
|
80
|
+
"getMyRights",
|
|
81
|
+
"getStrategies",
|
|
82
|
+
"login",
|
|
83
|
+
"logout",
|
|
84
|
+
"refreshToken",
|
|
85
|
+
"searchApiKeys",
|
|
86
|
+
"updateMyCredentials",
|
|
87
|
+
"updateSelf",
|
|
88
|
+
"validateMyCredentials",
|
|
89
|
+
]);
|
|
90
|
+
this.anonymousId = null;
|
|
94
91
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
92
|
+
/**
|
|
93
|
+
* Controller initialization: we need the anonymous user identifier for the
|
|
94
|
+
* "isAuthenticated" assertion
|
|
95
|
+
*
|
|
96
|
+
* @returns {Promise}
|
|
97
|
+
*/
|
|
98
|
+
async init() {
|
|
99
|
+
const anonymous = await global.kuzzle.ask("core:security:user:anonymous:get");
|
|
100
|
+
this.anonymousId = anonymous._id;
|
|
98
101
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
*/
|
|
115
|
-
async createApiKey(request) {
|
|
116
|
-
const expiresIn = request.input.args.expiresIn || -1;
|
|
117
|
-
const refresh = request.getRefresh("wait_for");
|
|
118
|
-
const apiKeyId = request.getId({ ifMissing: "generate" });
|
|
119
|
-
const description = request.getBodyString("description");
|
|
120
|
-
|
|
121
|
-
const user = request.context.user;
|
|
122
|
-
|
|
123
|
-
const apiKey = await ApiKey.create(user, expiresIn, description, {
|
|
124
|
-
apiKeyId,
|
|
125
|
-
creatorId: user._id,
|
|
126
|
-
refresh,
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
return apiKey.serialize({ includeToken: true });
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Search in the user API keys
|
|
134
|
-
*/
|
|
135
|
-
async searchApiKeys(request) {
|
|
136
|
-
let query = request.getBody({});
|
|
137
|
-
const { from, size } = request.getSearchParams();
|
|
138
|
-
const lang = request.getLangParam();
|
|
139
|
-
|
|
140
|
-
const user = request.context.user;
|
|
141
|
-
|
|
142
|
-
if (lang === "koncorde") {
|
|
143
|
-
query = await this.translateKoncorde(query);
|
|
102
|
+
async createToken(request) {
|
|
103
|
+
const singleUse = request.getBoolean("singleUse");
|
|
104
|
+
if (`${request.input.args.expiresIn}` === "-1") {
|
|
105
|
+
throw kerror.get("security", "token", "invalid_expiration", "expiresIn", "cannot be infinite");
|
|
106
|
+
}
|
|
107
|
+
const token = await this.ask("core:security:token:create", request.getUser(), {
|
|
108
|
+
expiresIn: request.input.args.expiresIn,
|
|
109
|
+
singleUse,
|
|
110
|
+
});
|
|
111
|
+
return {
|
|
112
|
+
expiresAt: token.expiresAt,
|
|
113
|
+
singleUse: token.singleUse,
|
|
114
|
+
token: token.jwt,
|
|
115
|
+
ttl: token.ttl,
|
|
116
|
+
};
|
|
144
117
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* Deletes an API key
|
|
165
|
-
*/
|
|
166
|
-
async deleteApiKey(request) {
|
|
167
|
-
const apiKeyId = request.getId();
|
|
168
|
-
const refresh = request.getRefresh();
|
|
169
|
-
|
|
170
|
-
const apiKey = await ApiKey.load(request.context.user._id, apiKeyId);
|
|
171
|
-
|
|
172
|
-
await apiKey.delete({ refresh });
|
|
173
|
-
|
|
174
|
-
return { _id: apiKeyId };
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Logs the current user out
|
|
179
|
-
*
|
|
180
|
-
* @param {KuzzleRequest} request
|
|
181
|
-
* @returns {Promise<object>}
|
|
182
|
-
*/
|
|
183
|
-
async logout(request) {
|
|
184
|
-
if (
|
|
185
|
-
!global.kuzzle.config.http.cookieAuthentication ||
|
|
186
|
-
!request.getBoolean("cookieAuth")
|
|
187
|
-
) {
|
|
188
|
-
this.assertIsAuthenticated(request);
|
|
118
|
+
/**
|
|
119
|
+
* Checks if an API action can be executed by the current user
|
|
120
|
+
*/
|
|
121
|
+
async checkRights(request) {
|
|
122
|
+
const requestPayload = request.getBody();
|
|
123
|
+
if (typeof requestPayload.controller !== "string") {
|
|
124
|
+
throw kerror.get("api", "assert", "missing_argument", "body.controller");
|
|
125
|
+
}
|
|
126
|
+
if (typeof requestPayload.action !== "string") {
|
|
127
|
+
throw kerror.get("api", "assert", "missing_argument", "body.action");
|
|
128
|
+
}
|
|
129
|
+
const user = request.context.user;
|
|
130
|
+
const allowed = await user.isActionAllowed(new request_1.KuzzleRequest(requestPayload));
|
|
131
|
+
return {
|
|
132
|
+
allowed,
|
|
133
|
+
};
|
|
189
134
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
request.
|
|
199
|
-
request.context.
|
|
200
|
-
|
|
135
|
+
/**
|
|
136
|
+
* Creates a new API key for the user
|
|
137
|
+
* @param {KuzzleRequest} request
|
|
138
|
+
*/
|
|
139
|
+
async createApiKey(request) {
|
|
140
|
+
const expiresIn = request.input.args.expiresIn || -1;
|
|
141
|
+
const refresh = request.getRefresh("wait_for");
|
|
142
|
+
const apiKeyId = request.getId({ ifMissing: "generate" });
|
|
143
|
+
const description = request.getBodyString("description");
|
|
144
|
+
const user = request.context.user;
|
|
145
|
+
const apiKey = await apiKey_1.default.create(user, expiresIn, description, {
|
|
146
|
+
apiKeyId,
|
|
147
|
+
creatorId: user._id,
|
|
148
|
+
refresh,
|
|
149
|
+
});
|
|
150
|
+
return apiKey.serialize({ includeToken: true });
|
|
201
151
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
152
|
+
/**
|
|
153
|
+
* Search in the user API keys
|
|
154
|
+
*/
|
|
155
|
+
async searchApiKeys(request) {
|
|
156
|
+
let query = request.getBody({});
|
|
157
|
+
const { from, size } = request.getSearchParams();
|
|
158
|
+
const lang = request.getLangParam();
|
|
159
|
+
const user = request.context.user;
|
|
160
|
+
if (lang === "koncorde") {
|
|
161
|
+
query = await this.translateKoncorde(query);
|
|
162
|
+
}
|
|
163
|
+
const searchBody = {
|
|
164
|
+
query: {
|
|
165
|
+
bool: {
|
|
166
|
+
filter: { bool: { must: { term: { userId: user._id } } } },
|
|
167
|
+
must: (0, lodash_1.isEmpty)(query) ? { match_all: {} } : query,
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
const apiKeys = await apiKey_1.default.search(searchBody, { from, size });
|
|
172
|
+
return {
|
|
173
|
+
hits: apiKeys.map((apiKey) => apiKey.serialize()),
|
|
174
|
+
total: apiKeys.length,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Deletes an API key
|
|
179
|
+
*/
|
|
180
|
+
async deleteApiKey(request) {
|
|
181
|
+
const apiKeyId = request.getId();
|
|
182
|
+
const refresh = request.getRefresh();
|
|
183
|
+
const apiKey = await apiKey_1.default.load(request.context.user._id, apiKeyId);
|
|
184
|
+
await apiKey.delete({ refresh });
|
|
185
|
+
return { _id: apiKeyId };
|
|
219
186
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
187
|
+
/**
|
|
188
|
+
* Logs the current user out
|
|
189
|
+
*
|
|
190
|
+
* @param {KuzzleRequest} request
|
|
191
|
+
* @returns {Promise<object>}
|
|
192
|
+
*/
|
|
193
|
+
async logout(request) {
|
|
194
|
+
if (!global.kuzzle.config.http.cookieAuthentication ||
|
|
195
|
+
!request.getBoolean("cookieAuth")) {
|
|
196
|
+
this.assertIsAuthenticated(request);
|
|
197
|
+
}
|
|
198
|
+
if (global.kuzzle.config.internal.notifiableProtocols.includes(request.context.connection.protocol)) {
|
|
199
|
+
// Unlink connection so the connection will not be notified when the token expires.
|
|
200
|
+
global.kuzzle.tokenManager.unlink(request.context.token, request.context.connection.id);
|
|
201
|
+
}
|
|
202
|
+
if (request.context.user._id !== this.anonymousId) {
|
|
203
|
+
if (request.getBoolean("global")) {
|
|
204
|
+
await global.kuzzle.ask("core:security:token:deleteByKuid", request.getKuid(), { keepApiKeys: true });
|
|
205
|
+
}
|
|
206
|
+
else if (request.context.token &&
|
|
207
|
+
request.context.token.type !== "apiKey") {
|
|
208
|
+
await global.kuzzle.ask("core:security:token:delete", request.context.token);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
if (global.kuzzle.config.http.cookieAuthentication &&
|
|
212
|
+
request.getBoolean("cookieAuth")) {
|
|
213
|
+
request.response.configure({
|
|
214
|
+
headers: {
|
|
215
|
+
"Set-Cookie": cookie_1.default.serialize("authToken", null, {
|
|
216
|
+
httpOnly: true,
|
|
217
|
+
path: "/",
|
|
218
|
+
sameSite: "strict",
|
|
219
|
+
}),
|
|
220
|
+
},
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
return { acknowledged: true };
|
|
224
|
+
}
|
|
225
|
+
// Used to send the Token using different ways when in cookieAuth mode. (DRY)
|
|
226
|
+
async _sendToken(token, request) {
|
|
227
|
+
// Only if the support of Browser Cookie as Authentication Token is enabled
|
|
228
|
+
// otherwise we should send a normal response because
|
|
229
|
+
// even if the SDK / Browser can handle the cookie,
|
|
230
|
+
// Kuzzle would not be capable of doing anything with it
|
|
231
|
+
if (global.kuzzle.config.http.cookieAuthentication &&
|
|
232
|
+
request.getBoolean("cookieAuth")) {
|
|
233
|
+
// Here we are not sending auth token when cookieAuth is set to true
|
|
234
|
+
// This allow us to detect if kuzzle does support cookie as auth token directly from the SDK
|
|
235
|
+
// or that the version of kuzzle doesn't support the feature Browser Cookie as Authentication Token
|
|
236
|
+
request.response.configure({
|
|
237
|
+
headers: {
|
|
238
|
+
"Set-Cookie": cookie_1.default.serialize("authToken", token.jwt, {
|
|
239
|
+
expires: new Date(token.expiresAt),
|
|
240
|
+
httpOnly: true,
|
|
241
|
+
path: "/",
|
|
242
|
+
sameSite: "strict",
|
|
243
|
+
}),
|
|
244
|
+
},
|
|
245
|
+
});
|
|
246
|
+
return {
|
|
247
|
+
_id: token.userId,
|
|
248
|
+
expiresAt: token.expiresAt,
|
|
249
|
+
ttl: token.ttl,
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
return {
|
|
253
|
+
_id: token.userId,
|
|
254
|
+
expiresAt: token.expiresAt,
|
|
255
|
+
jwt: token.jwt,
|
|
256
|
+
ttl: token.ttl,
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Attempts a login with request informations against the provided strategy;
|
|
261
|
+
* local is used if strategy is not provided.
|
|
262
|
+
*
|
|
263
|
+
* @param {KuzzleRequest} request
|
|
264
|
+
* @returns {Promise<Token>}
|
|
265
|
+
*/
|
|
266
|
+
async login(request) {
|
|
267
|
+
const strategy = request.getString("strategy");
|
|
268
|
+
const passportRequest = new http_1.IncomingMessage(null);
|
|
269
|
+
// Even in http, the url and the method are not pushed back to the request object
|
|
270
|
+
// set some arbitrary values to get a pseudo-valid object.
|
|
271
|
+
passportRequest.url = `/login?strategy=${strategy}`;
|
|
272
|
+
passportRequest.method = "POST";
|
|
273
|
+
passportRequest.httpVersion = "1.1";
|
|
274
|
+
passportRequest.httpVersionMajor = 1;
|
|
275
|
+
passportRequest.httpVersionMinor = 1;
|
|
276
|
+
passportRequest.body = request.input.body;
|
|
277
|
+
passportRequest.query = request.input.args;
|
|
278
|
+
passportRequest.headers = Object.assign({}, request.input.headers);
|
|
279
|
+
for (const h of Object.keys(passportRequest.headers)) {
|
|
280
|
+
passportRequest.rawHeaders.push(h);
|
|
281
|
+
passportRequest.rawHeaders.push(passportRequest.headers[h]);
|
|
282
|
+
}
|
|
283
|
+
passportRequest.original = request;
|
|
284
|
+
if (!(0, safeObject_1.has)(global.kuzzle.pluginsManager.strategies, strategy)) {
|
|
285
|
+
throw kerror.get("security", "credentials", "unknown_strategy", strategy);
|
|
286
|
+
}
|
|
287
|
+
const content = await global.kuzzle.passport.authenticate(passportRequest, strategy);
|
|
288
|
+
// do not trigger the "auth:strategyAutenticated" pipe if the result is
|
|
289
|
+
// not a User object, i.e. if we are a intermediate step of a multi-step
|
|
290
|
+
// authentication strategy
|
|
291
|
+
// (example: first redirection call for oAuth strategies)
|
|
292
|
+
const authResponse = !(content instanceof user_1.User)
|
|
293
|
+
? { content, strategy }
|
|
294
|
+
: await this.pipe("auth:strategyAuthenticated", { content, strategy });
|
|
295
|
+
if (!(authResponse.content instanceof user_1.User)) {
|
|
296
|
+
request.response.configure({
|
|
297
|
+
headers: authResponse.content.headers,
|
|
298
|
+
status: authResponse.content.statusCode || 200,
|
|
299
|
+
});
|
|
300
|
+
return authResponse.content;
|
|
301
|
+
}
|
|
302
|
+
const options = {};
|
|
303
|
+
if (request.input.args.expiresIn) {
|
|
304
|
+
options.expiresIn = request.input.args.expiresIn;
|
|
305
|
+
}
|
|
306
|
+
const existingToken = global.kuzzle.tokenManager.getConnectedUserToken(authResponse.content._id, request.context.connection.id);
|
|
307
|
+
/**
|
|
308
|
+
* If a previous token from the same User is linked to this connection
|
|
309
|
+
* and the token is either an API Key or an infinite duration token
|
|
310
|
+
* we dont need to create a new token or refresh anything, just send back the exact same token
|
|
311
|
+
* to avoid breaking changes.
|
|
312
|
+
*/
|
|
313
|
+
if (existingToken &&
|
|
314
|
+
(existingToken.type === "apiKey" || existingToken.ttl < 0)) {
|
|
315
|
+
return this._sendToken(existingToken, request);
|
|
316
|
+
}
|
|
317
|
+
const token = await this.ask("core:security:token:create", authResponse.content, options);
|
|
318
|
+
if (existingToken) {
|
|
319
|
+
global.kuzzle.tokenManager.refresh(existingToken, token);
|
|
320
|
+
}
|
|
321
|
+
if (global.kuzzle.config.internal.notifiableProtocols.includes(request.context.connection.protocol)) {
|
|
322
|
+
// Link the connection with the token, this way the connection can be notified when the token has expired.
|
|
323
|
+
global.kuzzle.tokenManager.link(token, request.context.connection.id);
|
|
324
|
+
}
|
|
325
|
+
return this._sendToken(token, request);
|
|
234
326
|
}
|
|
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
|
-
return {
|
|
265
|
-
_id: token.userId,
|
|
266
|
-
expiresAt: token.expiresAt,
|
|
267
|
-
ttl: token.ttl,
|
|
268
|
-
};
|
|
327
|
+
/**
|
|
328
|
+
* Returns the user identified by the given jwt token
|
|
329
|
+
*
|
|
330
|
+
* @param {KuzzleRequest} request
|
|
331
|
+
* @returns {Promise<Object>}
|
|
332
|
+
*/
|
|
333
|
+
getCurrentUser(request) {
|
|
334
|
+
const userId = request.context.token.userId, formattedUser = formatProcessing_1.default.serializeUser(request.context.user), promises = [];
|
|
335
|
+
if (this.anonymousId === userId) {
|
|
336
|
+
promises.push(bluebird_1.default.resolve([]));
|
|
337
|
+
}
|
|
338
|
+
else {
|
|
339
|
+
for (const strategy of global.kuzzle.pluginsManager.listStrategies()) {
|
|
340
|
+
const existsMethod = global.kuzzle.pluginsManager.getStrategyMethod(strategy, "exists");
|
|
341
|
+
promises.push(existsMethod(request, userId, strategy)
|
|
342
|
+
.then((exists) => (exists ? strategy : null))
|
|
343
|
+
.catch((err) => wrapPluginError(err)));
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
return bluebird_1.default.all(promises).then((strategies) => {
|
|
347
|
+
if (strategies.length > 0) {
|
|
348
|
+
formattedUser.strategies = strategies.filter((item) => item !== null);
|
|
349
|
+
}
|
|
350
|
+
return formattedUser;
|
|
351
|
+
});
|
|
269
352
|
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
* local is used if strategy is not provided.
|
|
282
|
-
*
|
|
283
|
-
* @param {KuzzleRequest} request
|
|
284
|
-
* @returns {Promise<Token>}
|
|
285
|
-
*/
|
|
286
|
-
async login(request) {
|
|
287
|
-
const strategy = request.getString("strategy");
|
|
288
|
-
const passportRequest = new IncomingMessage();
|
|
289
|
-
|
|
290
|
-
// Even in http, the url and the method are not pushed back to the request object
|
|
291
|
-
// set some arbitrary values to get a pseudo-valid object.
|
|
292
|
-
passportRequest.url = `/login?strategy=${strategy}`;
|
|
293
|
-
passportRequest.method = "POST";
|
|
294
|
-
passportRequest.httpVersion = "1.1";
|
|
295
|
-
passportRequest.httpVersionMajor = 1;
|
|
296
|
-
passportRequest.httpVersionMinor = 1;
|
|
297
|
-
passportRequest.body = request.input.body;
|
|
298
|
-
passportRequest.query = request.input.args;
|
|
299
|
-
passportRequest.headers = Object.assign({}, request.input.headers);
|
|
300
|
-
|
|
301
|
-
for (const h of Object.keys(passportRequest.headers)) {
|
|
302
|
-
passportRequest.rawHeaders.push(h);
|
|
303
|
-
passportRequest.rawHeaders.push(passportRequest.headers[h]);
|
|
353
|
+
/**
|
|
354
|
+
* Returns the rights of the user identified by the given jwt token
|
|
355
|
+
*
|
|
356
|
+
* @param {KuzzleRequest} request
|
|
357
|
+
* @returns {Promise<object>}
|
|
358
|
+
*/
|
|
359
|
+
getMyRights(request) {
|
|
360
|
+
return request.context.user
|
|
361
|
+
.getRights(global.kuzzle)
|
|
362
|
+
.then((rights) => Object.keys(rights).reduce((array, item) => array.concat(rights[item]), []))
|
|
363
|
+
.then((rights) => ({ hits: rights, total: rights.length }));
|
|
304
364
|
}
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
365
|
+
/**
|
|
366
|
+
* Checks the validity of a token.
|
|
367
|
+
*
|
|
368
|
+
* @param {KuzzleRequest} request
|
|
369
|
+
* @returns {Promise<object>}
|
|
370
|
+
*/
|
|
371
|
+
async checkToken(request) {
|
|
372
|
+
let token = "";
|
|
373
|
+
if (global.kuzzle.config.http.cookieAuthentication &&
|
|
374
|
+
request.getBoolean("cookieAuth")) {
|
|
375
|
+
token = request.input.jwt;
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
token = request.getBodyString("token", "") || null;
|
|
379
|
+
}
|
|
380
|
+
try {
|
|
381
|
+
const { expiresAt = -1, userId } = await this.ask("core:security:token:verify", token);
|
|
382
|
+
return { expiresAt, kuid: userId, valid: true };
|
|
383
|
+
}
|
|
384
|
+
catch (error) {
|
|
385
|
+
if (error.status === 401) {
|
|
386
|
+
return { state: error.message, valid: false };
|
|
387
|
+
}
|
|
388
|
+
throw error;
|
|
389
|
+
}
|
|
309
390
|
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
});
|
|
329
|
-
|
|
330
|
-
return authResponse.content;
|
|
391
|
+
/**
|
|
392
|
+
* Updates the current user if it is not anonymous
|
|
393
|
+
*
|
|
394
|
+
* @param {KuzzleRequest} request
|
|
395
|
+
* @returns {Promise<object>}
|
|
396
|
+
*/
|
|
397
|
+
async updateSelf(request) {
|
|
398
|
+
this.assertIsAuthenticated(request);
|
|
399
|
+
this.assertBodyHasNotAttributes(request, "_id", "profileIds");
|
|
400
|
+
const userId = request.getKuid();
|
|
401
|
+
const body = request.getBody();
|
|
402
|
+
const user = await this.ask("core:security:user:update", userId, null, body, {
|
|
403
|
+
refresh: request.getRefresh("wait_for"),
|
|
404
|
+
retryOnConflict: request.getInteger("retryOnConflict", 10),
|
|
405
|
+
userId,
|
|
406
|
+
});
|
|
407
|
+
global.kuzzle.log.info(`[SECURITY] ${securityController_1.default.userOrSdk(userId)} applied action "${request.input.action}" on user "${userId}."`);
|
|
408
|
+
return formatProcessing_1.default.serializeUser(user);
|
|
331
409
|
}
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
410
|
+
/**
|
|
411
|
+
* List authentication strategies
|
|
412
|
+
*
|
|
413
|
+
* @returns {Promise.<string[]>}
|
|
414
|
+
*/
|
|
415
|
+
getStrategies() {
|
|
416
|
+
return bluebird_1.default.resolve(global.kuzzle.pluginsManager.listStrategies());
|
|
336
417
|
}
|
|
337
|
-
|
|
338
|
-
const existingToken = global.kuzzle.tokenManager.getConnectedUserToken(
|
|
339
|
-
authResponse.content._id,
|
|
340
|
-
request.context.connection.id
|
|
341
|
-
);
|
|
342
|
-
|
|
343
418
|
/**
|
|
344
|
-
*
|
|
345
|
-
*
|
|
346
|
-
* we dont need to create a new token or refresh anything, just send back the exact same token
|
|
347
|
-
* to avoid breaking changes.
|
|
419
|
+
* @param {KuzzleRequest} request
|
|
420
|
+
* @returns {Promise.<Object>}
|
|
348
421
|
*/
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
422
|
+
createMyCredentials(request) {
|
|
423
|
+
this.assertIsAuthenticated(request);
|
|
424
|
+
const userId = request.getKuid(), strategy = request.getString("strategy"), credentials = request.getBody();
|
|
425
|
+
this.assertIsStrategyRegistered(strategy);
|
|
426
|
+
const createMethod = global.kuzzle.pluginsManager.getStrategyMethod(strategy, "create"), validateMethod = global.kuzzle.pluginsManager.getStrategyMethod(strategy, "validate");
|
|
427
|
+
return validateMethod(request, credentials, userId, strategy, false)
|
|
428
|
+
.then(() => createMethod(request, credentials, userId, strategy))
|
|
429
|
+
.catch((err) => wrapPluginError(err));
|
|
354
430
|
}
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
431
|
+
/**
|
|
432
|
+
* @param {KuzzleRequest} request
|
|
433
|
+
* @returns {Promise.<Object>}
|
|
434
|
+
*/
|
|
435
|
+
updateMyCredentials(request) {
|
|
436
|
+
this.assertIsAuthenticated(request);
|
|
437
|
+
const userId = request.getKuid(), strategy = request.getString("strategy"), credentials = request.getBody();
|
|
438
|
+
this.assertIsStrategyRegistered(strategy);
|
|
439
|
+
const updateMethod = global.kuzzle.pluginsManager.getStrategyMethod(request.input.args.strategy, "update"), validateMethod = global.kuzzle.pluginsManager.getStrategyMethod(request.input.args.strategy, "validate");
|
|
440
|
+
return validateMethod(request, credentials, userId, strategy, true)
|
|
441
|
+
.then(() => updateMethod(request, credentials, userId, strategy))
|
|
442
|
+
.catch((err) => wrapPluginError(err));
|
|
364
443
|
}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
444
|
+
/**
|
|
445
|
+
* @param {KuzzleRequest} request
|
|
446
|
+
* @returns {Promise.<Object>}
|
|
447
|
+
*/
|
|
448
|
+
credentialsExist(request) {
|
|
449
|
+
this.assertIsAuthenticated(request);
|
|
450
|
+
const userId = request.getKuid(), strategy = request.getString("strategy");
|
|
451
|
+
this.assertIsStrategyRegistered(strategy);
|
|
452
|
+
const existsMethod = global.kuzzle.pluginsManager.getStrategyMethod(strategy, "exists");
|
|
453
|
+
return existsMethod(request, userId, strategy).catch((err) => wrapPluginError(err));
|
|
373
454
|
}
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
getCurrentUser(request) {
|
|
385
|
-
const userId = request.context.token.userId,
|
|
386
|
-
formattedUser = formatProcessing.serializeUser(request.context.user),
|
|
387
|
-
promises = [];
|
|
388
|
-
|
|
389
|
-
if (this.anonymousId === userId) {
|
|
390
|
-
promises.push(Bluebird.resolve([]));
|
|
391
|
-
} else {
|
|
392
|
-
for (const strategy of global.kuzzle.pluginsManager.listStrategies()) {
|
|
393
|
-
const existsMethod = global.kuzzle.pluginsManager.getStrategyMethod(
|
|
394
|
-
strategy,
|
|
395
|
-
"exists"
|
|
396
|
-
);
|
|
397
|
-
|
|
398
|
-
promises.push(
|
|
399
|
-
existsMethod(request, userId, strategy)
|
|
400
|
-
.then((exists) => (exists ? strategy : null))
|
|
401
|
-
.catch((err) => wrapPluginError(err))
|
|
402
|
-
);
|
|
403
|
-
}
|
|
455
|
+
/**
|
|
456
|
+
* @param {KuzzleRequest} request
|
|
457
|
+
* @returns {Promise.<Object>}
|
|
458
|
+
*/
|
|
459
|
+
validateMyCredentials(request) {
|
|
460
|
+
this.assertIsAuthenticated(request);
|
|
461
|
+
const userId = request.getKuid(), strategy = request.getString("strategy"), credentials = request.getBody();
|
|
462
|
+
this.assertIsStrategyRegistered(strategy);
|
|
463
|
+
const validateMethod = global.kuzzle.pluginsManager.getStrategyMethod(strategy, "validate");
|
|
464
|
+
return validateMethod(request, credentials, userId, strategy, false).catch((err) => wrapPluginError(err));
|
|
404
465
|
}
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
*
|
|
418
|
-
* @param {KuzzleRequest} request
|
|
419
|
-
* @returns {Promise<object>}
|
|
420
|
-
*/
|
|
421
|
-
getMyRights(request) {
|
|
422
|
-
return request.context.user
|
|
423
|
-
.getRights(global.kuzzle)
|
|
424
|
-
.then((rights) =>
|
|
425
|
-
Object.keys(rights).reduce(
|
|
426
|
-
(array, item) => array.concat(rights[item]),
|
|
427
|
-
[]
|
|
428
|
-
)
|
|
429
|
-
)
|
|
430
|
-
.then((rights) => ({ hits: rights, total: rights.length }));
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
/**
|
|
434
|
-
* Checks the validity of a token.
|
|
435
|
-
*
|
|
436
|
-
* @param {KuzzleRequest} request
|
|
437
|
-
* @returns {Promise<object>}
|
|
438
|
-
*/
|
|
439
|
-
async checkToken(request) {
|
|
440
|
-
let token = "";
|
|
441
|
-
|
|
442
|
-
if (
|
|
443
|
-
global.kuzzle.config.http.cookieAuthentication &&
|
|
444
|
-
request.getBoolean("cookieAuth")
|
|
445
|
-
) {
|
|
446
|
-
token = request.input.jwt;
|
|
447
|
-
} else {
|
|
448
|
-
token = request.getBodyString("token", "") || null;
|
|
466
|
+
/**
|
|
467
|
+
* @param {KuzzleRequest} request
|
|
468
|
+
* @returns {Promise.<Object>}
|
|
469
|
+
*/
|
|
470
|
+
deleteMyCredentials(request) {
|
|
471
|
+
this.assertIsAuthenticated(request);
|
|
472
|
+
const userId = request.getKuid(), strategy = request.getString("strategy");
|
|
473
|
+
this.assertIsStrategyRegistered(strategy);
|
|
474
|
+
const deleteMethod = global.kuzzle.pluginsManager.getStrategyMethod(strategy, "delete");
|
|
475
|
+
return deleteMethod(request, userId, strategy)
|
|
476
|
+
.then(() => ({ acknowledged: true }))
|
|
477
|
+
.catch((err) => wrapPluginError(err));
|
|
449
478
|
}
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
throw error;
|
|
479
|
+
/**
|
|
480
|
+
* @param {KuzzleRequest} request
|
|
481
|
+
* @returns {Promise.<Object>}
|
|
482
|
+
*/
|
|
483
|
+
getMyCredentials(request) {
|
|
484
|
+
this.assertIsAuthenticated(request);
|
|
485
|
+
const userId = request.getKuid(), strategy = request.getString("strategy");
|
|
486
|
+
this.assertIsStrategyRegistered(strategy);
|
|
487
|
+
if (!global.kuzzle.pluginsManager.hasStrategyMethod(strategy, "getInfo")) {
|
|
488
|
+
return bluebird_1.default.resolve({});
|
|
489
|
+
}
|
|
490
|
+
const getInfoMethod = global.kuzzle.pluginsManager.getStrategyMethod(strategy, "getInfo");
|
|
491
|
+
return getInfoMethod(request, userId, strategy).catch((err) => wrapPluginError(err));
|
|
464
492
|
}
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
*/
|
|
473
|
-
async updateSelf(request) {
|
|
474
|
-
this.assertIsAuthenticated(request);
|
|
475
|
-
this.assertBodyHasNotAttributes(request, "_id", "profileIds");
|
|
476
|
-
|
|
477
|
-
const userId = request.getKuid();
|
|
478
|
-
const body = request.getBody();
|
|
479
|
-
|
|
480
|
-
const user = await this.ask(
|
|
481
|
-
"core:security:user:update",
|
|
482
|
-
userId,
|
|
483
|
-
null,
|
|
484
|
-
body,
|
|
485
|
-
{
|
|
486
|
-
refresh: request.getRefresh("wait_for"),
|
|
487
|
-
retryOnConflict: request.getInteger("retryOnConflict", 10),
|
|
488
|
-
userId,
|
|
489
|
-
}
|
|
490
|
-
);
|
|
491
|
-
|
|
492
|
-
global.kuzzle.log.info(
|
|
493
|
-
`[SECURITY] ${SecurityController.userOrSdk(userId)} applied action "${
|
|
494
|
-
request.input.action
|
|
495
|
-
}" on user "${userId}."`
|
|
496
|
-
);
|
|
497
|
-
|
|
498
|
-
return formatProcessing.serializeUser(user);
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
/**
|
|
502
|
-
* List authentication strategies
|
|
503
|
-
*
|
|
504
|
-
* @returns {Promise.<string[]>}
|
|
505
|
-
*/
|
|
506
|
-
getStrategies() {
|
|
507
|
-
return Bluebird.resolve(global.kuzzle.pluginsManager.listStrategies());
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
/**
|
|
511
|
-
* @param {KuzzleRequest} request
|
|
512
|
-
* @returns {Promise.<Object>}
|
|
513
|
-
*/
|
|
514
|
-
createMyCredentials(request) {
|
|
515
|
-
this.assertIsAuthenticated(request);
|
|
516
|
-
|
|
517
|
-
const userId = request.getKuid(),
|
|
518
|
-
strategy = request.getString("strategy"),
|
|
519
|
-
credentials = request.getBody();
|
|
520
|
-
|
|
521
|
-
this.assertIsStrategyRegistered(strategy);
|
|
522
|
-
|
|
523
|
-
const createMethod = global.kuzzle.pluginsManager.getStrategyMethod(
|
|
524
|
-
strategy,
|
|
525
|
-
"create"
|
|
526
|
-
),
|
|
527
|
-
validateMethod = global.kuzzle.pluginsManager.getStrategyMethod(
|
|
528
|
-
strategy,
|
|
529
|
-
"validate"
|
|
530
|
-
);
|
|
531
|
-
|
|
532
|
-
return validateMethod(request, credentials, userId, strategy, false)
|
|
533
|
-
.then(() => createMethod(request, credentials, userId, strategy))
|
|
534
|
-
.catch((err) => wrapPluginError(err));
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
/**
|
|
538
|
-
* @param {KuzzleRequest} request
|
|
539
|
-
* @returns {Promise.<Object>}
|
|
540
|
-
*/
|
|
541
|
-
updateMyCredentials(request) {
|
|
542
|
-
this.assertIsAuthenticated(request);
|
|
543
|
-
|
|
544
|
-
const userId = request.getKuid(),
|
|
545
|
-
strategy = request.getString("strategy"),
|
|
546
|
-
credentials = request.getBody();
|
|
547
|
-
|
|
548
|
-
this.assertIsStrategyRegistered(strategy);
|
|
549
|
-
|
|
550
|
-
const updateMethod = global.kuzzle.pluginsManager.getStrategyMethod(
|
|
551
|
-
request.input.args.strategy,
|
|
552
|
-
"update"
|
|
553
|
-
),
|
|
554
|
-
validateMethod = global.kuzzle.pluginsManager.getStrategyMethod(
|
|
555
|
-
request.input.args.strategy,
|
|
556
|
-
"validate"
|
|
557
|
-
);
|
|
558
|
-
|
|
559
|
-
return validateMethod(request, credentials, userId, strategy, true)
|
|
560
|
-
.then(() => updateMethod(request, credentials, userId, strategy))
|
|
561
|
-
.catch((err) => wrapPluginError(err));
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
/**
|
|
565
|
-
* @param {KuzzleRequest} request
|
|
566
|
-
* @returns {Promise.<Object>}
|
|
567
|
-
*/
|
|
568
|
-
credentialsExist(request) {
|
|
569
|
-
this.assertIsAuthenticated(request);
|
|
570
|
-
|
|
571
|
-
const userId = request.getKuid(),
|
|
572
|
-
strategy = request.getString("strategy");
|
|
573
|
-
|
|
574
|
-
this.assertIsStrategyRegistered(strategy);
|
|
575
|
-
|
|
576
|
-
const existsMethod = global.kuzzle.pluginsManager.getStrategyMethod(
|
|
577
|
-
strategy,
|
|
578
|
-
"exists"
|
|
579
|
-
);
|
|
580
|
-
|
|
581
|
-
return existsMethod(request, userId, strategy).catch((err) =>
|
|
582
|
-
wrapPluginError(err)
|
|
583
|
-
);
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
/**
|
|
587
|
-
* @param {KuzzleRequest} request
|
|
588
|
-
* @returns {Promise.<Object>}
|
|
589
|
-
*/
|
|
590
|
-
validateMyCredentials(request) {
|
|
591
|
-
this.assertIsAuthenticated(request);
|
|
592
|
-
|
|
593
|
-
const userId = request.getKuid(),
|
|
594
|
-
strategy = request.getString("strategy"),
|
|
595
|
-
credentials = request.getBody();
|
|
596
|
-
|
|
597
|
-
this.assertIsStrategyRegistered(strategy);
|
|
598
|
-
|
|
599
|
-
const validateMethod = global.kuzzle.pluginsManager.getStrategyMethod(
|
|
600
|
-
strategy,
|
|
601
|
-
"validate"
|
|
602
|
-
);
|
|
603
|
-
|
|
604
|
-
return validateMethod(request, credentials, userId, strategy, false).catch(
|
|
605
|
-
(err) => wrapPluginError(err)
|
|
606
|
-
);
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
/**
|
|
610
|
-
* @param {KuzzleRequest} request
|
|
611
|
-
* @returns {Promise.<Object>}
|
|
612
|
-
*/
|
|
613
|
-
deleteMyCredentials(request) {
|
|
614
|
-
this.assertIsAuthenticated(request);
|
|
615
|
-
|
|
616
|
-
const userId = request.getKuid(),
|
|
617
|
-
strategy = request.getString("strategy");
|
|
618
|
-
|
|
619
|
-
this.assertIsStrategyRegistered(strategy);
|
|
620
|
-
|
|
621
|
-
const deleteMethod = global.kuzzle.pluginsManager.getStrategyMethod(
|
|
622
|
-
strategy,
|
|
623
|
-
"delete"
|
|
624
|
-
);
|
|
625
|
-
|
|
626
|
-
return deleteMethod(request, userId, strategy)
|
|
627
|
-
.then(() => ({ acknowledged: true }))
|
|
628
|
-
.catch((err) => wrapPluginError(err));
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
/**
|
|
632
|
-
* @param {KuzzleRequest} request
|
|
633
|
-
* @returns {Promise.<Object>}
|
|
634
|
-
*/
|
|
635
|
-
getMyCredentials(request) {
|
|
636
|
-
this.assertIsAuthenticated(request);
|
|
637
|
-
|
|
638
|
-
const userId = request.getKuid(),
|
|
639
|
-
strategy = request.getString("strategy");
|
|
640
|
-
|
|
641
|
-
this.assertIsStrategyRegistered(strategy);
|
|
642
|
-
|
|
643
|
-
if (!global.kuzzle.pluginsManager.hasStrategyMethod(strategy, "getInfo")) {
|
|
644
|
-
return Bluebird.resolve({});
|
|
493
|
+
/**
|
|
494
|
+
* @param {KuzzleRequest} request
|
|
495
|
+
*/
|
|
496
|
+
async refreshToken(request) {
|
|
497
|
+
this.assertIsAuthenticated(request);
|
|
498
|
+
const token = await this.ask("core:security:token:refresh", request.context.user, request.context.token, request.input.args.expiresIn);
|
|
499
|
+
return this._sendToken(token, request);
|
|
645
500
|
}
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
);
|
|
651
|
-
|
|
652
|
-
return getInfoMethod(request, userId, strategy).catch((err) =>
|
|
653
|
-
wrapPluginError(err)
|
|
654
|
-
);
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
/**
|
|
658
|
-
* @param {KuzzleRequest} request
|
|
659
|
-
*/
|
|
660
|
-
async refreshToken(request) {
|
|
661
|
-
this.assertIsAuthenticated(request);
|
|
662
|
-
|
|
663
|
-
const token = await this.ask(
|
|
664
|
-
"core:security:token:refresh",
|
|
665
|
-
request.context.user,
|
|
666
|
-
request.context.token,
|
|
667
|
-
request.input.args.expiresIn
|
|
668
|
-
);
|
|
669
|
-
|
|
670
|
-
return this._sendToken(token, request);
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
assertIsAuthenticated(request) {
|
|
674
|
-
if (request.context.user._id === this.anonymousId) {
|
|
675
|
-
throw kerror.get(
|
|
676
|
-
"security",
|
|
677
|
-
"rights",
|
|
678
|
-
"unauthorized",
|
|
679
|
-
request.input.controller,
|
|
680
|
-
request.input.action
|
|
681
|
-
);
|
|
501
|
+
assertIsAuthenticated(request) {
|
|
502
|
+
if (request.context.user._id === this.anonymousId) {
|
|
503
|
+
throw kerror.get("security", "rights", "unauthorized", request.input.controller, request.input.action);
|
|
504
|
+
}
|
|
682
505
|
}
|
|
683
|
-
}
|
|
684
506
|
}
|
|
685
|
-
|
|
507
|
+
exports.AuthController = AuthController;
|
|
686
508
|
function wrapPluginError(error) {
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
"runtime",
|
|
692
|
-
"unexpected_error",
|
|
693
|
-
error.message
|
|
694
|
-
);
|
|
695
|
-
}
|
|
696
|
-
|
|
697
|
-
throw error;
|
|
509
|
+
if (!(error instanceof errors_1.KuzzleError)) {
|
|
510
|
+
throw kerror.getFrom(error, "plugin", "runtime", "unexpected_error", error.message);
|
|
511
|
+
}
|
|
512
|
+
throw error;
|
|
698
513
|
}
|
|
699
|
-
|
|
700
514
|
module.exports = AuthController;
|
|
515
|
+
//# sourceMappingURL=authController.js.map
|