@hapiboo/module-auth 1.0.0
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/dist/index.d.ts +19 -0
- package/dist/index.js +35 -0
- package/dist/models/credential.d.ts +43 -0
- package/dist/models/credential.js +221 -0
- package/dist/models/index.d.ts +4 -0
- package/dist/models/index.js +11 -0
- package/dist/models/naming.d.ts +50 -0
- package/dist/models/naming.js +53 -0
- package/dist/models/role.d.ts +28 -0
- package/dist/models/role.js +133 -0
- package/dist/models/user.d.ts +25 -0
- package/dist/models/user.js +97 -0
- package/dist/router/access.d.ts +1 -0
- package/dist/router/access.js +17 -0
- package/dist/router/controller.d.ts +58 -0
- package/dist/router/controller.js +111 -0
- package/dist/router/index.d.ts +1 -0
- package/dist/router/index.js +10 -0
- package/dist/router/init.d.ts +1 -0
- package/dist/router/init.js +11 -0
- package/dist/router/password.d.ts +1 -0
- package/dist/router/password.js +24 -0
- package/dist/router/profile.d.ts +1 -0
- package/dist/router/profile.js +15 -0
- package/dist/router/user.d.ts +1 -0
- package/dist/router/user.js +17 -0
- package/dist/service/authentication.d.ts +51 -0
- package/dist/service/authentication.js +569 -0
- package/dist/service/authorization.d.ts +38 -0
- package/dist/service/authorization.js +247 -0
- package/dist/service/repository.d.ts +44 -0
- package/dist/service/repository.js +201 -0
- package/dist/service/security.d.ts +46 -0
- package/dist/service/security.js +198 -0
- package/dist/service/settings.d.ts +45 -0
- package/dist/service/settings.js +90 -0
- package/package.json +41 -0
|
@@ -0,0 +1,569 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.authenticationService = void 0;
|
|
4
|
+
const uuid_1 = require("uuid");
|
|
5
|
+
const core_1 = require("@hapiboo/core");
|
|
6
|
+
const repository_1 = require("./repository");
|
|
7
|
+
const settings_1 = require("./settings");
|
|
8
|
+
const security_1 = require("./security");
|
|
9
|
+
const models_1 = require("../models");
|
|
10
|
+
const authorization_1 = require("./authorization");
|
|
11
|
+
var helper;
|
|
12
|
+
(function (helper) {
|
|
13
|
+
let tokens;
|
|
14
|
+
(function (tokens) {
|
|
15
|
+
function getJwt(user_id, account_id, is_admin, data, refreshCode) {
|
|
16
|
+
const refreshToken = security_1.securityService.token.refresh(user_id, refreshCode, 720);
|
|
17
|
+
const token = security_1.securityService.token.data(user_id, account_id, is_admin, 24, data);
|
|
18
|
+
return { token: token, refreshToken: refreshToken };
|
|
19
|
+
}
|
|
20
|
+
tokens.getJwt = getJwt;
|
|
21
|
+
function generateWithRefreshIfNeeded(credential, user, payload, confirmData) {
|
|
22
|
+
return core_1.promise.createPromise((resolve, reject) => {
|
|
23
|
+
if (credential.refreshCode === '' && credential.setRefreshCode((0, uuid_1.v4)())) {
|
|
24
|
+
core_1.promise.check(repository_1.repository.credential.update(credential), reject)
|
|
25
|
+
.then(() => {
|
|
26
|
+
if (confirmData) {
|
|
27
|
+
core_1.promise.checkVoid(repository_1.repository.user.update(user.confirm()), reject)
|
|
28
|
+
.then(() => {
|
|
29
|
+
resolve(getJwt(user.id, user.account_id, user.type === 'admin', payload, credential.refreshCode));
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
resolve(getJwt(user.id, user.account_id, user.type === 'admin', payload, credential.refreshCode));
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
if (confirmData) {
|
|
39
|
+
core_1.promise.check(repository_1.repository.credential.update(credential), reject)
|
|
40
|
+
.then(() => {
|
|
41
|
+
core_1.promise.checkVoid(repository_1.repository.user.update(user.confirm()), reject)
|
|
42
|
+
.then(() => {
|
|
43
|
+
resolve(getJwt(user.id, user.account_id, user.type === 'admin', payload, credential.refreshCode));
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
resolve(getJwt(user.id, user.account_id, user.type === 'admin', payload, credential.refreshCode));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
function generate(user, credential, confirmData) {
|
|
54
|
+
return core_1.promise.createPromise((resolve, reject) => {
|
|
55
|
+
if (user.type === 'standard' && user.account_id !== '') {
|
|
56
|
+
core_1.promise.check(settings_1.authSettings.getTokenPayload(user), reject)
|
|
57
|
+
.then((payload) => {
|
|
58
|
+
core_1.promise.resolve(generateWithRefreshIfNeeded(credential, user, payload, confirmData), resolve, reject);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
core_1.promise.resolve(generateWithRefreshIfNeeded(credential, user, undefined, confirmData), resolve, reject);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
tokens.generate = generate;
|
|
67
|
+
function generateFull(credential, confirmData) {
|
|
68
|
+
return core_1.promise.createDelayedPromise((resolve, reject) => {
|
|
69
|
+
core_1.promise.check(repository_1.repository.user.getById(credential.user_id), reject)
|
|
70
|
+
.then((user) => {
|
|
71
|
+
core_1.promise.resolve(generate(user, credential, confirmData), resolve, reject);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
tokens.generateFull = generateFull;
|
|
76
|
+
})(tokens = helper.tokens || (helper.tokens = {}));
|
|
77
|
+
let users;
|
|
78
|
+
(function (users) {
|
|
79
|
+
function registerPassword(display, email, credentialName, password, admin, isInvited, account_id, baseUrl) {
|
|
80
|
+
return core_1.promise.createPromise((resolve, reject) => {
|
|
81
|
+
//we need to find out if credentialName is not used
|
|
82
|
+
core_1.promise.check(searchPassword(credentialName, true), reject)
|
|
83
|
+
.then((value) => {
|
|
84
|
+
if (value.found) {
|
|
85
|
+
reject(core_1.ResponseError.getMessageResponse(409, 'credential name already registered'));
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
if (display && email && credentialName) {
|
|
89
|
+
//let's create actual user data
|
|
90
|
+
const user_id = (0, uuid_1.v4)();
|
|
91
|
+
let confirm = (0, uuid_1.v4)().substring(0, 6).toUpperCase();
|
|
92
|
+
let invite = undefined;
|
|
93
|
+
if (isInvited) {
|
|
94
|
+
confirm = undefined;
|
|
95
|
+
invite = (0, uuid_1.v4)().substring(0, 6).toUpperCase();
|
|
96
|
+
password = '';
|
|
97
|
+
}
|
|
98
|
+
core_1.promise.check(repository_1.repository.credential.create(new models_1.Credential().createPassword((0, uuid_1.v4)(), credentialName, user_id, 'pending', password, confirm, invite)), reject)
|
|
99
|
+
.then((cred) => {
|
|
100
|
+
//now, create user
|
|
101
|
+
core_1.promise.check(repository_1.repository.user.create(new models_1.User().create(user_id, account_id, admin ? 'admin' : 'standard', 'created', display, email)), reject)
|
|
102
|
+
.then((dataItem) => {
|
|
103
|
+
//and send the code to confirm
|
|
104
|
+
emails.confirm(email, display, isInvited, isInvited ? cred.invite : cred.confirmation, baseUrl)
|
|
105
|
+
.then(() => {
|
|
106
|
+
resolve({ user: dataItem, credentials: cred });
|
|
107
|
+
}).catch((reason) => {
|
|
108
|
+
console.error(reason.message);
|
|
109
|
+
//in case of error, we need to remove all created data
|
|
110
|
+
repository_1.repository.user.remove(dataItem.id)
|
|
111
|
+
.then(() => {
|
|
112
|
+
repository_1.repository.credential.remove(cred.id)
|
|
113
|
+
.then(() => {
|
|
114
|
+
reject(reason);
|
|
115
|
+
}).catch((reasonCred) => {
|
|
116
|
+
//we have 2 errors, and needs to combine them
|
|
117
|
+
reject(core_1.ResponseError.getCollectionResponse([reason, reasonCred]));
|
|
118
|
+
});
|
|
119
|
+
}).catch((reasonUser) => {
|
|
120
|
+
//despite error, let's try to clean up other data
|
|
121
|
+
repository_1.repository.credential.remove(cred.id)
|
|
122
|
+
.then(() => {
|
|
123
|
+
//we have 2 errors, and needs to combine them
|
|
124
|
+
reject(core_1.ResponseError.getCollectionResponse([reason, reasonUser]));
|
|
125
|
+
}).catch((reasonCred) => {
|
|
126
|
+
//we have 3 errors, and needs to combine them
|
|
127
|
+
reject(core_1.ResponseError.getCollectionResponse([reason, reasonUser, reasonCred]));
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
reject(core_1.ResponseError.getMessageResponse(400, 'data is not valid'));
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
users.registerPassword = registerPassword;
|
|
142
|
+
function searchPassword(credential_name, includeAll) {
|
|
143
|
+
return core_1.promise.createPromise((resolve, reject) => {
|
|
144
|
+
core_1.promise.check(repository_1.repository.credential.filter(credential_name, undefined, undefined, undefined, undefined, 'password'), reject)
|
|
145
|
+
.then((data) => {
|
|
146
|
+
if (data && data.length === 1) {
|
|
147
|
+
const credential = data[0];
|
|
148
|
+
if (credential.status === 'active' || includeAll) {
|
|
149
|
+
core_1.promise.check(repository_1.repository.user.getById(credential.user_id), reject)
|
|
150
|
+
.then((user) => {
|
|
151
|
+
resolve({ found: true, credential, user });
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
resolve({ found: false });
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
resolve({ found: false });
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
users.searchPassword = searchPassword;
|
|
165
|
+
})(users = helper.users || (helper.users = {}));
|
|
166
|
+
let emails;
|
|
167
|
+
(function (emails) {
|
|
168
|
+
function url(host, path) {
|
|
169
|
+
if (host != '') {
|
|
170
|
+
if (host.endsWith('/')) {
|
|
171
|
+
if (path.startsWith('/')) {
|
|
172
|
+
return host + path.substring(1);
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
return host + path;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
if (path.startsWith('/')) {
|
|
180
|
+
return host + path;
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
return host + '/' + path;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
return path;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
function confirm(emailAddress, displayName, isInvited, code, baseUrl) {
|
|
192
|
+
return core_1.promise.createVoidPromise((resolve, reject) => {
|
|
193
|
+
const link = isInvited ? { url: url(baseUrl, 'invitation/?code=' + code), title: 'Confirm Invitation' } : { url: url(baseUrl, 'confirm/?code=' + code), title: 'Confirm Account' };
|
|
194
|
+
core_1.promise.resolveVoid(settings_1.authSettings.sendConfirmation(emailAddress, displayName, isInvited, link), resolve, reject);
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
emails.confirm = confirm;
|
|
198
|
+
function recover(emailAddress, code, baseUrl) {
|
|
199
|
+
return core_1.promise.createVoidPromise((resolve, reject) => {
|
|
200
|
+
const link = { url: url(baseUrl, 'recover/?code=' + code), title: 'Reset Password' };
|
|
201
|
+
core_1.promise.resolveVoid(settings_1.authSettings.sendRecover(emailAddress, link), resolve, reject);
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
emails.recover = recover;
|
|
205
|
+
})(emails = helper.emails || (helper.emails = {}));
|
|
206
|
+
})(helper || (helper = {}));
|
|
207
|
+
var authenticationService;
|
|
208
|
+
(function (authenticationService) {
|
|
209
|
+
let general;
|
|
210
|
+
(function (general) {
|
|
211
|
+
function initData(baseURL) {
|
|
212
|
+
return core_1.promise.createDelayedPromise((resolve, reject) => {
|
|
213
|
+
core_1.promise.check(repository_1.repository.user.count(), reject)
|
|
214
|
+
.then((count) => {
|
|
215
|
+
if (count === 0) {
|
|
216
|
+
core_1.promise.resolve(admin.invite(settings_1.authSettings.firstAdmin.email, settings_1.authSettings.firstAdmin.email, settings_1.authSettings.firstAdmin.name, baseURL), resolve, reject);
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
resolve({ id: '' });
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
general.initData = initData;
|
|
225
|
+
function get(user_id) {
|
|
226
|
+
return repository_1.repository.user.getById(user_id);
|
|
227
|
+
}
|
|
228
|
+
general.get = get;
|
|
229
|
+
})(general = authenticationService.general || (authenticationService.general = {}));
|
|
230
|
+
let me;
|
|
231
|
+
(function (me) {
|
|
232
|
+
function get(user_id) {
|
|
233
|
+
return core_1.promise.createPromise((resolve, reject) => {
|
|
234
|
+
core_1.promise.check(repository_1.repository.user.getById(user_id), reject)
|
|
235
|
+
.then((data) => {
|
|
236
|
+
if (!data) {
|
|
237
|
+
reject(core_1.ResponseError.getMessageResponse(404, 'user not found'));
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
core_1.promise.check(authorization_1.authorizationService.access.getForUser(data.id), reject)
|
|
241
|
+
.then((roles) => {
|
|
242
|
+
const permission_ids = roles.map((item) => { return item.permission_id; });
|
|
243
|
+
resolve({ id: data.id, email: data.profile.email, name: data.profile.display, account_id: data.account_id, admin: data.type === 'admin', permissions: permission_ids });
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
me.get = get;
|
|
250
|
+
function update(user_id, name) {
|
|
251
|
+
return core_1.promise.createPromise((resolve, reject) => {
|
|
252
|
+
core_1.promise.check(repository_1.repository.user.getById(user_id), reject)
|
|
253
|
+
.then((data) => {
|
|
254
|
+
if (!data) {
|
|
255
|
+
reject(core_1.ResponseError.getMessageResponse(404, 'user not found'));
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
core_1.promise.resolve(repository_1.repository.user.update(new models_1.User().clone(data).updateName(name)), resolve, reject);
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
me.update = update;
|
|
264
|
+
function passwordLogin(name, password) {
|
|
265
|
+
return core_1.promise.createDelayedPromise((resolve, reject) => {
|
|
266
|
+
core_1.promise.check(helper.users.searchPassword(name.toLowerCase(), false), reject)
|
|
267
|
+
.then((value) => {
|
|
268
|
+
if (!value.found || !value.credential || !value.user) {
|
|
269
|
+
reject(core_1.ResponseError.getMessageResponse(400, 'email or password is not correct'));
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
if (value.credential.checkPasswordCorrectness(password)) {
|
|
273
|
+
core_1.promise.resolve(helper.tokens.generate(value.user, value.credential, false), resolve, reject);
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
reject(core_1.ResponseError.getMessageResponse(400, 'user or password is not correct'));
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
me.passwordLogin = passwordLogin;
|
|
283
|
+
function changePassword(user_id, credentialName, oldPassword, newPassword) {
|
|
284
|
+
return core_1.promise.createDelayedPromise((resolve, reject) => {
|
|
285
|
+
//get login
|
|
286
|
+
core_1.promise.check(repository_1.repository.credential.filter(credentialName, user_id, undefined, undefined, undefined, 'password'), reject)
|
|
287
|
+
.then((credentials) => {
|
|
288
|
+
if (credentials.length === 1) {
|
|
289
|
+
const model = credentials[0];
|
|
290
|
+
//check & change password
|
|
291
|
+
if (!model.changePassword(oldPassword, newPassword)) {
|
|
292
|
+
reject(core_1.ResponseError.getMessageResponse(406, 'incorrect password'));
|
|
293
|
+
}
|
|
294
|
+
else {
|
|
295
|
+
core_1.promise.check(repository_1.repository.user.getById(model.user_id), reject)
|
|
296
|
+
.then((user) => {
|
|
297
|
+
core_1.promise.check(helper.tokens.generate(user, model, false), reject)
|
|
298
|
+
.then((tokens) => {
|
|
299
|
+
core_1.promise.checkVoid(settings_1.authSettings.sendAfterPasswordChanged(user.profile.email), reject)
|
|
300
|
+
.then(() => {
|
|
301
|
+
resolve(tokens);
|
|
302
|
+
});
|
|
303
|
+
});
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
reject(core_1.ResponseError.getMessageResponse(403, 'incorrect parameters'));
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
me.changePassword = changePassword;
|
|
314
|
+
function refreshTokenLogin(user_id, refreshCode) {
|
|
315
|
+
return core_1.promise.createDelayedPromise((resolve, reject) => {
|
|
316
|
+
core_1.promise.check(repository_1.repository.credential.filter(undefined, user_id, undefined, undefined, undefined, 'password'), reject)
|
|
317
|
+
.then((credentials) => {
|
|
318
|
+
if (credentials.length === 1) {
|
|
319
|
+
const model = credentials[0];
|
|
320
|
+
if (model.refreshCode === refreshCode) {
|
|
321
|
+
core_1.promise.resolve(helper.tokens.generateFull(model, false), resolve, reject);
|
|
322
|
+
}
|
|
323
|
+
else {
|
|
324
|
+
reject(core_1.ResponseError.getMessageResponse(403, 'incorrect token'));
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
reject(core_1.ResponseError.getMessageResponse(403, 'incorrect parameters'));
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
me.refreshTokenLogin = refreshTokenLogin;
|
|
334
|
+
})(me = authenticationService.me || (authenticationService.me = {}));
|
|
335
|
+
let admin;
|
|
336
|
+
(function (admin) {
|
|
337
|
+
function invite(name, emailAddress, displayName, baseURL) {
|
|
338
|
+
return core_1.promise.createDelayedPromise((resolve, reject) => {
|
|
339
|
+
emailAddress = emailAddress.toLowerCase();
|
|
340
|
+
core_1.promise.check(helper.users.registerPassword(displayName, emailAddress, name, '', true, true, undefined, baseURL), reject)
|
|
341
|
+
.then((data) => {
|
|
342
|
+
resolve({ id: data.user.id });
|
|
343
|
+
});
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
admin.invite = invite;
|
|
347
|
+
function remove(id, currentUserId) {
|
|
348
|
+
return core_1.promise.createDelayedVoidPromise((resolve, reject) => {
|
|
349
|
+
if (id === currentUserId) {
|
|
350
|
+
reject(core_1.ResponseError.getMessageResponse(400, 'cannot remove own user'));
|
|
351
|
+
}
|
|
352
|
+
else {
|
|
353
|
+
core_1.promise.check(repository_1.repository.user.getById(id), reject)
|
|
354
|
+
.then((user) => {
|
|
355
|
+
if (user.type !== 'admin' || user.account_id) {
|
|
356
|
+
reject(core_1.ResponseError.getMessageResponse(404, 'cannot remove non-admin user'));
|
|
357
|
+
}
|
|
358
|
+
else {
|
|
359
|
+
//user is ok to remove - removing User object
|
|
360
|
+
core_1.promise.checkVoid(repository_1.repository.user.remove(user.id), reject)
|
|
361
|
+
.then(() => {
|
|
362
|
+
//now remove all associated credentials
|
|
363
|
+
core_1.promise.check(repository_1.repository.credential.filter(undefined, user.id, undefined, undefined, undefined, undefined), reject)
|
|
364
|
+
.then((credentials) => {
|
|
365
|
+
core_1.promise.resolveVoid(core_1.promise.all(credentials.map((credential) => {
|
|
366
|
+
return repository_1.repository.credential.remove(credential.id);
|
|
367
|
+
})), resolve, reject);
|
|
368
|
+
});
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
admin.remove = remove;
|
|
376
|
+
function getAll() {
|
|
377
|
+
return repository_1.repository.user.filter(undefined, 'admin', undefined);
|
|
378
|
+
}
|
|
379
|
+
admin.getAll = getAll;
|
|
380
|
+
})(admin = authenticationService.admin || (authenticationService.admin = {}));
|
|
381
|
+
let user;
|
|
382
|
+
(function (user_1) {
|
|
383
|
+
function registerPassword(credentialName, userDisplayName, userEmailAddress, password, account_name, account_email, baseUrl) {
|
|
384
|
+
return core_1.promise.createDelayedPromise((resolve, reject) => {
|
|
385
|
+
const account_id = (0, uuid_1.v4)();
|
|
386
|
+
userEmailAddress = userEmailAddress.toLowerCase();
|
|
387
|
+
core_1.promise.check(helper.users.registerPassword(userDisplayName, userEmailAddress, credentialName, password, false, false, account_id, baseUrl), reject)
|
|
388
|
+
.then((data) => {
|
|
389
|
+
core_1.promise.check(settings_1.authSettings.afterRegistration(account_id, data.user.id, account_name, account_email), reject)
|
|
390
|
+
.then((afterData) => {
|
|
391
|
+
resolve({ user: data.user.id, account: afterData.id });
|
|
392
|
+
});
|
|
393
|
+
});
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
user_1.registerPassword = registerPassword;
|
|
397
|
+
function invite(account_id, credentialName, displayName, emailAddress, baseUrl) {
|
|
398
|
+
return core_1.promise.createDelayedPromise((resolve, reject) => {
|
|
399
|
+
emailAddress = emailAddress.toLowerCase();
|
|
400
|
+
core_1.promise.check(helper.users.registerPassword(displayName, emailAddress, credentialName, '', false, true, account_id, baseUrl), reject)
|
|
401
|
+
.then((data) => {
|
|
402
|
+
resolve({ id: data.user.id });
|
|
403
|
+
});
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
user_1.invite = invite;
|
|
407
|
+
function updatePayload(user_id, account_id, payload) {
|
|
408
|
+
return helper.tokens.getJwt(user_id, account_id, false, payload, (0, uuid_1.v4)()).token;
|
|
409
|
+
}
|
|
410
|
+
user_1.updatePayload = updatePayload;
|
|
411
|
+
function remove(user_id, currentUserId, account_id) {
|
|
412
|
+
return core_1.promise.createDelayedVoidPromise((resolve, reject) => {
|
|
413
|
+
if (user_id === currentUserId) {
|
|
414
|
+
reject(core_1.ResponseError.getMessageResponse(400, 'cannot remove own user'));
|
|
415
|
+
}
|
|
416
|
+
else {
|
|
417
|
+
core_1.promise.check(repository_1.repository.user.getById(user_id), reject)
|
|
418
|
+
.then((user) => {
|
|
419
|
+
if (user.type !== 'standard' || user.account_id === undefined || user.account_id !== account_id) {
|
|
420
|
+
reject(core_1.ResponseError.getMessageResponse(404, 'cannot remove user'));
|
|
421
|
+
}
|
|
422
|
+
else {
|
|
423
|
+
//user is ok to remove - removing User object
|
|
424
|
+
core_1.promise.checkVoid(repository_1.repository.user.remove(user.id), reject)
|
|
425
|
+
.then(() => {
|
|
426
|
+
//now is the time to remove all permissions and roles
|
|
427
|
+
core_1.promise.checkVoid(authorization_1.authorizationService.access.removeAllForUser(user.id), reject)
|
|
428
|
+
.then(() => {
|
|
429
|
+
//now remove all associated credentials
|
|
430
|
+
core_1.promise.check(repository_1.repository.credential.filter(undefined, user.id, undefined, undefined, undefined, undefined), reject)
|
|
431
|
+
.then((credentials) => {
|
|
432
|
+
core_1.promise.resolveVoid(core_1.promise.all(credentials.map((credential) => {
|
|
433
|
+
return repository_1.repository.credential.remove(credential.id);
|
|
434
|
+
})), resolve, reject);
|
|
435
|
+
});
|
|
436
|
+
});
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
user_1.remove = remove;
|
|
444
|
+
function getForAccount(account_id) {
|
|
445
|
+
return repository_1.repository.user.filter(undefined, 'standard', account_id);
|
|
446
|
+
}
|
|
447
|
+
user_1.getForAccount = getForAccount;
|
|
448
|
+
})(user = authenticationService.user || (authenticationService.user = {}));
|
|
449
|
+
let actions;
|
|
450
|
+
(function (actions) {
|
|
451
|
+
function resendConfirmation(user_id, baseUrl) {
|
|
452
|
+
return core_1.promise.createDelayedVoidPromise((resolve, reject) => {
|
|
453
|
+
core_1.promise.check(repository_1.repository.user.getById(user_id), reject)
|
|
454
|
+
.then((user) => {
|
|
455
|
+
if (user.status === 'created') {
|
|
456
|
+
core_1.promise.check(repository_1.repository.credential.filter(undefined, user_id, undefined, undefined, undefined, 'password'), reject)
|
|
457
|
+
.then((credentials) => {
|
|
458
|
+
if (credentials.length !== 1) {
|
|
459
|
+
reject(core_1.ResponseError.getMessageResponse(422, 'user not found'));
|
|
460
|
+
}
|
|
461
|
+
else {
|
|
462
|
+
const credential = credentials[0];
|
|
463
|
+
if (credential.status !== 'pending') {
|
|
464
|
+
reject(core_1.ResponseError.getMessageResponse(422, 'user already confirmed'));
|
|
465
|
+
}
|
|
466
|
+
else {
|
|
467
|
+
core_1.promise.resolveVoid(helper.emails.confirm(user.profile.email, user.profile.display, credential.invite != '', credential.invite != '' ? credential.invite : credential.confirmation, baseUrl), resolve, reject);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
})
|
|
471
|
+
.catch((error) => {
|
|
472
|
+
reject(error);
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
});
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
actions.resendConfirmation = resendConfirmation;
|
|
479
|
+
function confirmRegistration(code, password) {
|
|
480
|
+
return core_1.promise.createDelayedPromise((resolve, reject) => {
|
|
481
|
+
core_1.promise.check(repository_1.repository.credential.filter(undefined, undefined, code, undefined, undefined, 'password'), reject)
|
|
482
|
+
.then((models) => {
|
|
483
|
+
if (models.length === 1) {
|
|
484
|
+
const model = models.pop();
|
|
485
|
+
if (model.status !== 'pending') {
|
|
486
|
+
reject(core_1.ResponseError.getMessageResponse(422, 'login already confirmed'));
|
|
487
|
+
}
|
|
488
|
+
else if (model.checkConfirmed(code, password)) {
|
|
489
|
+
core_1.promise.resolve(helper.tokens.generateFull(model, true), resolve, reject);
|
|
490
|
+
}
|
|
491
|
+
else {
|
|
492
|
+
reject(core_1.ResponseError.getMessageResponse(422, 'incorrect confirmation data'));
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
else {
|
|
496
|
+
reject(core_1.ResponseError.getMessageResponse(422, 'incorrect confirmation data'));
|
|
497
|
+
}
|
|
498
|
+
});
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
actions.confirmRegistration = confirmRegistration;
|
|
502
|
+
function confirmInvitation(code, password) {
|
|
503
|
+
return core_1.promise.createDelayedPromise((resolve, reject) => {
|
|
504
|
+
core_1.promise.check(repository_1.repository.credential.filter(undefined, undefined, undefined, undefined, code, 'password'), reject)
|
|
505
|
+
.then((models) => {
|
|
506
|
+
if (models.length === 1) {
|
|
507
|
+
const model = models.pop();
|
|
508
|
+
if (model.status !== 'pending') {
|
|
509
|
+
reject(core_1.ResponseError.getMessageResponse(422, 'invite already confirmed'));
|
|
510
|
+
}
|
|
511
|
+
else if (model.checkInvite(code, password)) {
|
|
512
|
+
core_1.promise.resolve(helper.tokens.generateFull(model, true), resolve, reject);
|
|
513
|
+
}
|
|
514
|
+
else {
|
|
515
|
+
reject(core_1.ResponseError.getMessageResponse(422, 'incorrect invitation data'));
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
else {
|
|
519
|
+
reject(core_1.ResponseError.getMessageResponse(422, 'incorrect invitation data'));
|
|
520
|
+
}
|
|
521
|
+
});
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
actions.confirmInvitation = confirmInvitation;
|
|
525
|
+
function recoverPassword(recovery, password) {
|
|
526
|
+
return core_1.promise.createDelayedPromise((resolve, reject) => {
|
|
527
|
+
core_1.promise.check(repository_1.repository.credential.filter(undefined, undefined, undefined, recovery, undefined, 'password'), reject)
|
|
528
|
+
.then((models) => {
|
|
529
|
+
if (models.length === 1) {
|
|
530
|
+
const model = models.pop();
|
|
531
|
+
if (model.status === 'revoked') {
|
|
532
|
+
reject(core_1.ResponseError.getMessageResponse(422, 'cannot recover password for revoked credential'));
|
|
533
|
+
}
|
|
534
|
+
else if (model.checkRecovery(recovery, password)) {
|
|
535
|
+
core_1.promise.resolve(helper.tokens.generateFull(model, true), resolve, reject);
|
|
536
|
+
}
|
|
537
|
+
else {
|
|
538
|
+
reject(core_1.ResponseError.getMessageResponse(422, 'recovery code is not correct'));
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
else {
|
|
542
|
+
reject(core_1.ResponseError.getMessageResponse(422, 'recovery code is not correct'));
|
|
543
|
+
}
|
|
544
|
+
});
|
|
545
|
+
});
|
|
546
|
+
}
|
|
547
|
+
actions.recoverPassword = recoverPassword;
|
|
548
|
+
function forgotPassword(credentialName, baseUrl) {
|
|
549
|
+
return core_1.promise.createDelayedVoidPromise((resolve, reject) => {
|
|
550
|
+
//find credential
|
|
551
|
+
core_1.promise.check(helper.users.searchPassword(credentialName, false), reject)
|
|
552
|
+
.then((value) => {
|
|
553
|
+
if (!value.found) {
|
|
554
|
+
reject(core_1.ResponseError.getMessageResponse(404, 'user not found'));
|
|
555
|
+
}
|
|
556
|
+
else {
|
|
557
|
+
//create recovery code
|
|
558
|
+
value.credential.recovery = (0, uuid_1.v4)().substring(0, 8).toUpperCase();
|
|
559
|
+
core_1.promise.check(repository_1.repository.credential.update(value.credential), reject)
|
|
560
|
+
.then(() => {
|
|
561
|
+
core_1.promise.resolveVoid(helper.emails.recover(value.user.profile.email, value.credential.recovery, baseUrl), resolve, reject);
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
});
|
|
565
|
+
});
|
|
566
|
+
}
|
|
567
|
+
actions.forgotPassword = forgotPassword;
|
|
568
|
+
})(actions = authenticationService.actions || (authenticationService.actions = {}));
|
|
569
|
+
})(authenticationService || (exports.authenticationService = authenticationService = {}));
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { NextFunction, Response } from 'express';
|
|
2
|
+
import { IResponsePromise, IResponsePromiseVoid } from '@hapiboo/core';
|
|
3
|
+
import { Permission, Role, UserAccess } from '../models';
|
|
4
|
+
import { IFluxRequest } from './security';
|
|
5
|
+
export declare namespace authorizationService {
|
|
6
|
+
namespace permission {
|
|
7
|
+
function create(name: string): IResponsePromise<Permission>;
|
|
8
|
+
function edit(id: string, name: string): IResponsePromise<Permission>;
|
|
9
|
+
function all(): IResponsePromise<Permission[]>;
|
|
10
|
+
}
|
|
11
|
+
namespace role {
|
|
12
|
+
function create(name: string, description: string, lucide_icon: string, permissions: string[]): IResponsePromise<Role>;
|
|
13
|
+
function edit(id: string, name: string, description: string, lucide_icon: string, permissions: string[]): IResponsePromise<Role>;
|
|
14
|
+
function all(): IResponsePromise<Role[]>;
|
|
15
|
+
}
|
|
16
|
+
namespace access {
|
|
17
|
+
namespace byRole {
|
|
18
|
+
function assign(account_id: string, user_id: string, role_id: string): IResponsePromise<UserAccess[]>;
|
|
19
|
+
function assignList(account_id: string, user_id: string, role_ids: string[]): IResponsePromise<UserAccess[]>;
|
|
20
|
+
function remove(account_id: string, user_id: string): IResponsePromiseVoid;
|
|
21
|
+
}
|
|
22
|
+
namespace byPermission {
|
|
23
|
+
function assign(_user_id: string, _permission_id: string): void;
|
|
24
|
+
function assignList(_user_id: string, _permission_id: string[]): void;
|
|
25
|
+
function remove(_account_id: string, _user_id: string): IResponsePromiseVoid;
|
|
26
|
+
}
|
|
27
|
+
function removeAllForUser(user_id: string): IResponsePromiseVoid;
|
|
28
|
+
function getForAccount(account_id: string): IResponsePromise<UserAccess[]>;
|
|
29
|
+
function getForUser(user_id: string): IResponsePromise<UserAccess[]>;
|
|
30
|
+
function split(user_access: UserAccess[]): {
|
|
31
|
+
roles: UserAccess[];
|
|
32
|
+
permissions: UserAccess[];
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
namespace middleware {
|
|
36
|
+
function permission(permission_id: string): (request: IFluxRequest, response: Response, next: NextFunction) => void;
|
|
37
|
+
}
|
|
38
|
+
}
|