@universis/janitor 1.6.3 → 1.8.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/README.md +3 -3
- package/dist/index.d.ts +213 -7
- package/dist/index.esm.js +906 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +919 -9
- package/dist/index.js.map +1 -1
- package/package.json +38 -19
- package/src/HttpBearerStategy.js +134 -0
- package/src/HttpBearerStrategy.d.ts +4 -0
- package/src/ScopeAccessConfiguration.d.ts +23 -1
- package/src/ScopeAccessConfiguration.js +38 -8
- package/src/index.d.ts +1 -1
- package/.gitlab-ci.yml +0 -29
- package/dist/OAuth2ClientService.d.ts +0 -98
- package/dist/OAuth2ClientService.js +0 -251
- package/dist/OAuth2ClientService.js.map +0 -1
- package/dist/RateLimitService.d.ts +0 -4
- package/dist/RateLimitService.js +0 -102
- package/dist/RateLimitService.js.map +0 -1
- package/dist/RedisClientStore.d.ts +0 -5
- package/dist/RedisClientStore.js +0 -122
- package/dist/RedisClientStore.js.map +0 -1
- package/dist/RemoteAddressValidator.d.ts +0 -10
- package/dist/RemoteAddressValidator.js +0 -89
- package/dist/RemoteAddressValidator.js.map +0 -1
- package/dist/ScopeAccessConfiguration.d.ts +0 -65
- package/dist/ScopeAccessConfiguration.js +0 -160
- package/dist/ScopeAccessConfiguration.js.map +0 -1
- package/dist/SpeedLimitService.d.ts +0 -4
- package/dist/SpeedLimitService.js +0 -113
- package/dist/SpeedLimitService.js.map +0 -1
- package/dist/polyfills.js +0 -11
- package/dist/polyfills.js.map +0 -1
- package/dist/validateScope.d.ts +0 -2
- package/dist/validateScope.js +0 -23
- package/dist/validateScope.js.map +0 -1
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import { ApplicationService, ApplicationBase } from '@themost/common';
|
|
2
|
-
import { DataContext } from '@themost/data';
|
|
3
|
-
|
|
4
|
-
export declare interface OAuth2MethodOptions {
|
|
5
|
-
access_token: string;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export declare interface OAuth2AuthorizeUser {
|
|
9
|
-
client_id?: string;
|
|
10
|
-
client_secret?: string;
|
|
11
|
-
username: string;
|
|
12
|
-
password: string;
|
|
13
|
-
grant_type: string;
|
|
14
|
-
scope?: string;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export declare interface OAuth2ServiceSettings {
|
|
18
|
-
unattendedExecutionAccount?: string;
|
|
19
|
-
client_id: string;
|
|
20
|
-
client_secret?: string;
|
|
21
|
-
server_uri: string;
|
|
22
|
-
userinfo_uri?: string;
|
|
23
|
-
introspect_uri?: string;
|
|
24
|
-
admin_uri?: string;
|
|
25
|
-
well_known_configuration_uri?: string;
|
|
26
|
-
adminAccount: {
|
|
27
|
-
username: string;
|
|
28
|
-
password: string;
|
|
29
|
-
client_id: string;
|
|
30
|
-
client_secret?: string;
|
|
31
|
-
scope?: string;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export declare interface OAuth2UserProfile {
|
|
36
|
-
sub: string;
|
|
37
|
-
name: string;
|
|
38
|
-
preferred_username: string;
|
|
39
|
-
given_name: string;
|
|
40
|
-
family_name: string;
|
|
41
|
-
email: string;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export declare interface GenericUser {
|
|
45
|
-
id?: any;
|
|
46
|
-
additionalType?: string;
|
|
47
|
-
alternateName?: string;
|
|
48
|
-
description?: string;
|
|
49
|
-
givenName?: string;
|
|
50
|
-
familyName?: string;
|
|
51
|
-
image?: string;
|
|
52
|
-
name?: string;
|
|
53
|
-
url?: string;
|
|
54
|
-
dateCreated?: Date;
|
|
55
|
-
dateModified?: Date;
|
|
56
|
-
createdBy?: any;
|
|
57
|
-
modifiedBy?: any;
|
|
58
|
-
lockoutTime?: Date;
|
|
59
|
-
logonCount?: number;
|
|
60
|
-
enabled?: boolean;
|
|
61
|
-
lastLogon?: Date;
|
|
62
|
-
userCredentials?: {
|
|
63
|
-
userPassword?: string;
|
|
64
|
-
userActivated?: boolean;
|
|
65
|
-
temporary?: boolean;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export declare interface OAuth2User {
|
|
70
|
-
id?: any;
|
|
71
|
-
username?: string;
|
|
72
|
-
email?: string;
|
|
73
|
-
enabled?: boolean;
|
|
74
|
-
emailVerified?: boolean;
|
|
75
|
-
firstName?: string;
|
|
76
|
-
lastName?: string;
|
|
77
|
-
credentials?: {
|
|
78
|
-
algorithm?: string,
|
|
79
|
-
temporary?: boolean,
|
|
80
|
-
type?: string,
|
|
81
|
-
value?: string
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export declare class OAuth2ClientService extends ApplicationService {
|
|
86
|
-
get settings(): OAuth2ServiceSettings;
|
|
87
|
-
constructor(app: ApplicationBase)
|
|
88
|
-
getUserInfo(context: DataContext, token: string): Promise<OAuth2UserProfile>;
|
|
89
|
-
getTokenInfo(context: DataContext, token: string): Promise<any>;
|
|
90
|
-
getContextTokenInfo(context: DataContext): Promise<any>;
|
|
91
|
-
authorize(authorizeUser: OAuth2AuthorizeUser): Promise<{ access_token?: string, refresh_token?: string}>;
|
|
92
|
-
getUser(username: string, options: OAuth2MethodOptions): Promise<any>;
|
|
93
|
-
getUserById(user_id: any, options: OAuth2MethodOptions): Promise<any>;
|
|
94
|
-
getUserByEmail(email: string, options: OAuth2MethodOptions): Promise<any>;
|
|
95
|
-
updateUser(user: GenericUser | any, options: OAuth2MethodOptions): Promise<any>;
|
|
96
|
-
createUser(user: GenericUser | any, options: OAuth2MethodOptions): Promise<any>;
|
|
97
|
-
deleteUser(user: { id: any }, options: OAuth2MethodOptions): Promise<any>;
|
|
98
|
-
}
|
|
@@ -1,251 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.OAuth2ClientService = void 0;var _superagent = require("superagent");
|
|
2
|
-
var _url = require("url");
|
|
3
|
-
var _common = require("@themost/common");
|
|
4
|
-
|
|
5
|
-
function responseHander(resolve, reject) {
|
|
6
|
-
return function (err, response) {
|
|
7
|
-
if (err) {
|
|
8
|
-
/**
|
|
9
|
-
* @type {import('superagent').Response}
|
|
10
|
-
*/
|
|
11
|
-
const response = err.response;
|
|
12
|
-
if (response && response.headers['content-type'] === 'application/json') {
|
|
13
|
-
// get body
|
|
14
|
-
const clientError = response.body;
|
|
15
|
-
const error = new _common.HttpError(response.status);
|
|
16
|
-
return reject(Object.assign(error, {
|
|
17
|
-
clientError
|
|
18
|
-
}));
|
|
19
|
-
}
|
|
20
|
-
return reject(err);
|
|
21
|
-
}
|
|
22
|
-
if (response.status === 204 && response.headers['content-type'] === 'application/json') {
|
|
23
|
-
return resolve(null);
|
|
24
|
-
}
|
|
25
|
-
return resolve(response.body);
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* @class
|
|
31
|
-
*/
|
|
32
|
-
class OAuth2ClientService extends _common.ApplicationService {
|
|
33
|
-
/**
|
|
34
|
-
* @param {import('@themost/express').ExpressDataApplication} app
|
|
35
|
-
*/
|
|
36
|
-
constructor(app) {
|
|
37
|
-
super(app);
|
|
38
|
-
/**
|
|
39
|
-
* @name OAuth2ClientService#settings
|
|
40
|
-
* @type {{server_uri:string,token_uri?:string}}
|
|
41
|
-
*/
|
|
42
|
-
Object.defineProperty(this, 'settings', {
|
|
43
|
-
writable: false,
|
|
44
|
-
value: app.getConfiguration().getSourceAt('settings/auth'),
|
|
45
|
-
enumerable: false,
|
|
46
|
-
configurable: false
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Gets keycloak server root
|
|
52
|
-
* @returns {string}
|
|
53
|
-
*/
|
|
54
|
-
getServer() {
|
|
55
|
-
return this.settings.server_uri;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Gets keycloak server root
|
|
60
|
-
* @returns {string}
|
|
61
|
-
*/
|
|
62
|
-
getAdminRoot() {
|
|
63
|
-
return this.settings.admin_uri;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// noinspection JSUnusedGlobalSymbols
|
|
67
|
-
/**
|
|
68
|
-
* Gets user's profile by calling OAuth2 server profile endpoint
|
|
69
|
-
* @param {ExpressDataContext} context
|
|
70
|
-
* @param {string} token
|
|
71
|
-
*/
|
|
72
|
-
getUserInfo(token) {
|
|
73
|
-
return new Promise((resolve, reject) => {
|
|
74
|
-
const userinfo_uri = this.settings.userinfo_uri ? new _url.URL(this.settings.userinfo_uri, this.getServer()) : new _url.URL('me', this.getServer());
|
|
75
|
-
return new _superagent.Request('GET', userinfo_uri).
|
|
76
|
-
set({
|
|
77
|
-
'Authorization': `Bearer ${token}`,
|
|
78
|
-
'Accept': 'application/json'
|
|
79
|
-
}).
|
|
80
|
-
query({
|
|
81
|
-
'access_token': token
|
|
82
|
-
}).end(responseHander(resolve, reject));
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// noinspection JSUnusedGlobalSymbols
|
|
87
|
-
/**
|
|
88
|
-
* Gets the token info of the current context
|
|
89
|
-
* @param {ExpressDataContext} context
|
|
90
|
-
*/
|
|
91
|
-
getContextTokenInfo(context) {
|
|
92
|
-
if (context.user == null) {
|
|
93
|
-
return Promise.reject(new Error('Context user may not be null'));
|
|
94
|
-
}
|
|
95
|
-
if (context.user.authenticationType !== 'Bearer') {
|
|
96
|
-
return Promise.reject(new Error('Invalid context authentication type'));
|
|
97
|
-
}
|
|
98
|
-
if (context.user.authenticationToken == null) {
|
|
99
|
-
return Promise.reject(new Error('Context authentication data may not be null'));
|
|
100
|
-
}
|
|
101
|
-
return this.getTokenInfo(context, context.user.authenticationToken);
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Gets token info by calling OAuth2 server endpoint
|
|
105
|
-
* @param {ExpressDataContext} _context
|
|
106
|
-
* @param {string} token
|
|
107
|
-
*/
|
|
108
|
-
getTokenInfo(_context, token) {
|
|
109
|
-
return new Promise((resolve, reject) => {
|
|
110
|
-
const introspection_uri = this.settings.introspection_uri ? new _url.URL(this.settings.introspection_uri, this.getServer()) : new _url.URL('tokeninfo', this.getServer());
|
|
111
|
-
return new _superagent.Request('POST', introspection_uri).
|
|
112
|
-
auth(this.settings.client_id, this.settings.client_secret).
|
|
113
|
-
set('Accept', 'application/json').
|
|
114
|
-
type('form').
|
|
115
|
-
send({
|
|
116
|
-
'token_type_hint': 'access_token',
|
|
117
|
-
'token': token
|
|
118
|
-
}).end(responseHander(resolve, reject));
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* @param {AuthorizeUser} authorizeUser
|
|
124
|
-
*/
|
|
125
|
-
authorize(authorizeUser) {
|
|
126
|
-
const tokenURL = this.settings.token_uri ? new _url.URL(this.settings.token_uri) : new _url.URL('authorize', this.getServer());
|
|
127
|
-
return new Promise((resolve, reject) => {
|
|
128
|
-
return new _superagent.Request('POST', tokenURL).
|
|
129
|
-
type('form').
|
|
130
|
-
send(authorizeUser).end(responseHander(resolve, reject));
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Gets a user by name
|
|
136
|
-
* @param {*} user_id
|
|
137
|
-
* @param {AdminMethodOptions} options
|
|
138
|
-
*/
|
|
139
|
-
getUserById(user_id, options) {
|
|
140
|
-
return new Promise((resolve, reject) => {
|
|
141
|
-
return new _superagent.Request('GET', new _url.URL(`users/${user_id}`, this.getAdminRoot())).
|
|
142
|
-
set('Authorization', `Bearer ${options.access_token}`).
|
|
143
|
-
end(responseHander(resolve, reject));
|
|
144
|
-
});
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Gets a user by name
|
|
149
|
-
* @param {string} username
|
|
150
|
-
* @param {AdminMethodOptions} options
|
|
151
|
-
*/
|
|
152
|
-
getUser(username, options) {
|
|
153
|
-
return new Promise((resolve, reject) => {
|
|
154
|
-
return new _superagent.Request('GET', new _url.URL('users', this.getAdminRoot())).
|
|
155
|
-
set('Authorization', `Bearer ${options.access_token}`).
|
|
156
|
-
query({
|
|
157
|
-
'$filter': `name eq '${username}'`
|
|
158
|
-
}).
|
|
159
|
-
end(responseHander(resolve, reject));
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* Gets a user by email address
|
|
165
|
-
* @param {string} email
|
|
166
|
-
* @param {AdminMethodOptions} options
|
|
167
|
-
*/
|
|
168
|
-
getUserByEmail(email, options) {
|
|
169
|
-
return new Promise((resolve, reject) => {
|
|
170
|
-
return new _superagent.Request('GET', new _url.URL('users', this.getAdminRoot())).
|
|
171
|
-
set('Authorization', `Bearer ${options.access_token}`).
|
|
172
|
-
query({
|
|
173
|
-
'$filter': `alternateName eq '${email}'`
|
|
174
|
-
}).
|
|
175
|
-
end(responseHander(resolve, reject));
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Updates an existing user
|
|
181
|
-
* @param {*} user
|
|
182
|
-
* @param {AdminMethodOptions} options
|
|
183
|
-
*/
|
|
184
|
-
updateUser(user, options) {
|
|
185
|
-
return new Promise((resolve, reject) => {
|
|
186
|
-
if (user.id == null) {
|
|
187
|
-
return reject(new _common.DataError('E_IDENTIFIER', 'User may not be empty at this context.', null, 'User', 'id'));
|
|
188
|
-
}
|
|
189
|
-
const request = new _superagent.Request('PUT', new _url.URL(`users/${user.id}`, this.getAdminRoot()));
|
|
190
|
-
return request.set('Authorization', `Bearer ${options.access_token}`).
|
|
191
|
-
set('Content-Type', 'application/json').
|
|
192
|
-
send(user).
|
|
193
|
-
end(responseHander(resolve, reject));
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Creates a new user
|
|
199
|
-
* @param {*} user
|
|
200
|
-
* @param {AdminMethodOptions} options
|
|
201
|
-
*/
|
|
202
|
-
createUser(user, options) {
|
|
203
|
-
return new Promise((resolve, reject) => {
|
|
204
|
-
const request = new _superagent.Request('POST', new _url.URL('users', this.getAdminRoot()));
|
|
205
|
-
return request.set('Authorization', `Bearer ${options.access_token}`).
|
|
206
|
-
set('Content-Type', 'application/json').
|
|
207
|
-
send(Object.assign({}, user, {
|
|
208
|
-
$state: 1 // for create
|
|
209
|
-
})).
|
|
210
|
-
end(responseHander(resolve, reject));
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* Deletes a user
|
|
216
|
-
* @param {{id: any}} user
|
|
217
|
-
* @param {AdminMethodOptions} options
|
|
218
|
-
*/
|
|
219
|
-
deleteUser(user, options) {
|
|
220
|
-
return new Promise((resolve, reject) => {
|
|
221
|
-
if (user.id == null) {
|
|
222
|
-
return reject(new _common.DataError('E_IDENTIFIER', 'User may not be empty at this context.', null, 'User', 'id'));
|
|
223
|
-
}
|
|
224
|
-
const request = new _superagent.Request('DELETE', new _url.URL(`users/${user.id}`, this.getAdminRoot()));
|
|
225
|
-
return request.set('Authorization', `Bearer ${options.access_token}`).
|
|
226
|
-
end(responseHander(resolve, reject));
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
/**
|
|
231
|
-
* @param {boolean=} force
|
|
232
|
-
* @returns {*}
|
|
233
|
-
*/
|
|
234
|
-
getWellKnownConfiguration(force) {
|
|
235
|
-
if (force) {
|
|
236
|
-
this.well_known_configuration = null;
|
|
237
|
-
}
|
|
238
|
-
if (this.well_known_configuration) {
|
|
239
|
-
return Promise.resolve(this.well_known_configuration);
|
|
240
|
-
}
|
|
241
|
-
return new Promise((resolve, reject) => {
|
|
242
|
-
const well_known_configuration_uri = this.settings.well_known_configuration_uri ? new _url.URL(this.settings.well_known_configuration_uri, this.getServer()) : new _url.URL('.well-known/openid-configuration', this.getServer());
|
|
243
|
-
return new _superagent.Request('GET', well_known_configuration_uri).
|
|
244
|
-
end(responseHander(resolve, reject));
|
|
245
|
-
}).then((configuration) => {
|
|
246
|
-
this.well_known_configuration = configuration;
|
|
247
|
-
return configuration;
|
|
248
|
-
});
|
|
249
|
-
}
|
|
250
|
-
}exports.OAuth2ClientService = OAuth2ClientService;
|
|
251
|
-
//# sourceMappingURL=OAuth2ClientService.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"OAuth2ClientService.js","names":["_superagent","require","_url","_common","responseHander","resolve","reject","err","response","headers","clientError","body","error","HttpError","status","Object","assign","OAuth2ClientService","ApplicationService","constructor","app","defineProperty","writable","value","getConfiguration","getSourceAt","enumerable","configurable","getServer","settings","server_uri","getAdminRoot","admin_uri","getUserInfo","token","Promise","userinfo_uri","URL","Request","set","query","end","getContextTokenInfo","context","user","Error","authenticationType","authenticationToken","getTokenInfo","_context","introspection_uri","auth","client_id","client_secret","type","send","authorize","authorizeUser","tokenURL","token_uri","getUserById","user_id","options","access_token","getUser","username","getUserByEmail","email","updateUser","id","DataError","request","createUser","$state","deleteUser","getWellKnownConfiguration","force","well_known_configuration","well_known_configuration_uri","then","configuration","exports"],"sources":["../src/OAuth2ClientService.js"],"sourcesContent":["import {Request} from 'superagent'\nimport {URL} from 'url';\nimport {ApplicationService, DataError, HttpError} from '@themost/common';\n\nfunction responseHander(resolve, reject) {\n return function (err, response) {\n if (err) {\n /**\n * @type {import('superagent').Response}\n */\n const response = err.response\n if (response && response.headers['content-type'] === 'application/json') {\n // get body\n const clientError = response.body;\n const error = new HttpError(response.status);\n return reject(Object.assign(error, {\n clientError\n }));\n }\n return reject(err);\n }\n if (response.status === 204 && response.headers['content-type'] === 'application/json') {\n return resolve(null);\n }\n return resolve(response.body);\n };\n}\n\n/**\n * @class\n */\nclass OAuth2ClientService extends ApplicationService {\n /**\n * @param {import('@themost/express').ExpressDataApplication} app\n */\n constructor(app) {\n super(app);\n /**\n * @name OAuth2ClientService#settings\n * @type {{server_uri:string,token_uri?:string}}\n */\n Object.defineProperty(this, 'settings', {\n writable: false,\n value: app.getConfiguration().getSourceAt('settings/auth'),\n enumerable: false,\n configurable: false\n });\n }\n\n /**\n * Gets keycloak server root\n * @returns {string}\n */\n getServer() {\n return this.settings.server_uri;\n }\n\n /**\n * Gets keycloak server root\n * @returns {string}\n */\n getAdminRoot() {\n return this.settings.admin_uri;\n }\n\n // noinspection JSUnusedGlobalSymbols\n /**\n * Gets user's profile by calling OAuth2 server profile endpoint\n * @param {ExpressDataContext} context\n * @param {string} token\n */\n getUserInfo(token) {\n return new Promise((resolve, reject) => {\n const userinfo_uri = this.settings.userinfo_uri ? new URL(this.settings.userinfo_uri, this.getServer()) : new URL('me', this.getServer());\n return new Request('GET', userinfo_uri)\n .set({\n 'Authorization': `Bearer ${token}`,\n 'Accept': 'application/json'\n })\n .query({\n 'access_token':token\n }).end(responseHander(resolve, reject));\n });\n }\n\n // noinspection JSUnusedGlobalSymbols\n /**\n * Gets the token info of the current context\n * @param {ExpressDataContext} context\n */\n getContextTokenInfo(context) {\n if (context.user == null) {\n return Promise.reject(new Error('Context user may not be null'));\n }\n if (context.user.authenticationType !== 'Bearer') {\n return Promise.reject(new Error('Invalid context authentication type'));\n }\n if (context.user.authenticationToken == null) {\n return Promise.reject(new Error('Context authentication data may not be null'));\n }\n return this.getTokenInfo(context, context.user.authenticationToken);\n }\n /**\n * Gets token info by calling OAuth2 server endpoint\n * @param {ExpressDataContext} _context\n * @param {string} token\n */\n getTokenInfo(_context, token) {\n return new Promise((resolve, reject) => {\n const introspection_uri = this.settings.introspection_uri ? new URL(this.settings.introspection_uri, this.getServer()) : new URL('tokeninfo', this.getServer());\n return new Request('POST', introspection_uri)\n .auth(this.settings.client_id, this.settings.client_secret)\n .set('Accept', 'application/json')\n .type('form')\n .send({\n 'token_type_hint': 'access_token',\n 'token': token,\n }).end(responseHander(resolve, reject));\n });\n }\n\n /**\n * @param {AuthorizeUser} authorizeUser\n */\n authorize(authorizeUser) {\n const tokenURL = this.settings.token_uri ? new URL(this.settings.token_uri) : new URL('authorize', this.getServer());\n return new Promise((resolve, reject)=> {\n return new Request('POST', tokenURL)\n .type('form')\n .send(authorizeUser).end(responseHander(resolve, reject));\n });\n }\n\n /**\n * Gets a user by name\n * @param {*} user_id \n * @param {AdminMethodOptions} options \n */\n getUserById(user_id, options) {\n return new Promise((resolve, reject) => {\n return new Request('GET', new URL(`users/${user_id}`, this.getAdminRoot()))\n .set('Authorization', `Bearer ${options.access_token}`)\n .end(responseHander(resolve, reject));\n });\n }\n\n /**\n * Gets a user by name\n * @param {string} username \n * @param {AdminMethodOptions} options \n */\n getUser(username, options) {\n return new Promise((resolve, reject)=> {\n return new Request('GET', new URL('users', this.getAdminRoot()))\n .set('Authorization', `Bearer ${options.access_token}`)\n .query({\n '$filter': `name eq '${username}'`\n })\n .end(responseHander(resolve, reject));\n });\n }\n\n /**\n * Gets a user by email address\n * @param {string} email \n * @param {AdminMethodOptions} options \n */\n getUserByEmail(email, options) {\n return new Promise((resolve, reject)=> {\n return new Request('GET', new URL('users', this.getAdminRoot()))\n .set('Authorization', `Bearer ${options.access_token}`)\n .query({\n '$filter': `alternateName eq '${email}'`\n })\n .end(responseHander(resolve, reject));\n });\n }\n\n /**\n * Updates an existing user\n * @param {*} user \n * @param {AdminMethodOptions} options \n */\n updateUser(user, options) {\n return new Promise((resolve, reject)=> {\n if (user.id == null) {\n return reject(new DataError('E_IDENTIFIER', 'User may not be empty at this context.', null, 'User', 'id'));\n }\n const request = new Request('PUT', new URL(`users/${user.id}`, this.getAdminRoot()));\n return request.set('Authorization', `Bearer ${options.access_token}`)\n .set('Content-Type', 'application/json')\n .send(user)\n .end(responseHander(resolve, reject));\n });\n }\n\n /**\n * Creates a new user\n * @param {*} user \n * @param {AdminMethodOptions} options \n */\n createUser(user, options) {\n return new Promise((resolve, reject)=> {\n const request = new Request('POST', new URL('users', this.getAdminRoot()));\n return request.set('Authorization', `Bearer ${options.access_token}`)\n .set('Content-Type', 'application/json')\n .send(Object.assign({}, user, {\n $state: 1 // for create\n }))\n .end(responseHander(resolve, reject));\n });\n }\n\n /**\n * Deletes a user\n * @param {{id: any}} user \n * @param {AdminMethodOptions} options \n */\n deleteUser(user, options) {\n return new Promise((resolve, reject)=> {\n if (user.id == null) {\n return reject(new DataError('E_IDENTIFIER', 'User may not be empty at this context.', null, 'User', 'id'));\n }\n const request = new Request('DELETE', new URL(`users/${user.id}`, this.getAdminRoot()));\n return request.set('Authorization', `Bearer ${options.access_token}`)\n .end(responseHander(resolve, reject));\n });\n }\n\n /**\n * @param {boolean=} force \n * @returns {*}\n */\n getWellKnownConfiguration(force) {\n if (force) {\n this.well_known_configuration = null;\n }\n if (this.well_known_configuration) {\n return Promise.resolve(this.well_known_configuration);\n }\n return new Promise((resolve, reject) => {\n const well_known_configuration_uri = this.settings.well_known_configuration_uri ? new URL(this.settings.well_known_configuration_uri, this.getServer()) : new URL('.well-known/openid-configuration', this.getServer());\n return new Request('GET', well_known_configuration_uri)\n .end(responseHander(resolve, reject));\n }).then((configuration) => {\n this.well_known_configuration = configuration;\n return configuration;\n });\n }\n}\n\nexport {\n OAuth2ClientService\n}\n\n"],"mappings":"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"}
|
package/dist/RateLimitService.js
DELETED
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.RateLimitService = void 0;var _common = require("@themost/common");
|
|
2
|
-
var _expressRateLimit = require("express-rate-limit");
|
|
3
|
-
var _express = _interopRequireDefault(require("express"));
|
|
4
|
-
var _path = _interopRequireDefault(require("path"));function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}
|
|
5
|
-
|
|
6
|
-
class RateLimitService extends _common.ApplicationService {
|
|
7
|
-
/**
|
|
8
|
-
* @param {import('@themost/express').ExpressDataApplication} app
|
|
9
|
-
*/
|
|
10
|
-
constructor(app) {
|
|
11
|
-
super(app);
|
|
12
|
-
app.serviceRouter.subscribe((serviceRouter) => {
|
|
13
|
-
if (serviceRouter == null) {
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
try {
|
|
17
|
-
const addRouter = _express.default.Router();
|
|
18
|
-
let serviceConfiguration = app.getConfiguration().getSourceAt('settings/universis/janitor/rateLimit') || {
|
|
19
|
-
profiles: [],
|
|
20
|
-
paths: []
|
|
21
|
-
};
|
|
22
|
-
if (serviceConfiguration.extends) {
|
|
23
|
-
// get additional configuration
|
|
24
|
-
const configurationPath = app.getConfiguration().getConfigurationPath();
|
|
25
|
-
const extendsPath = _path.default.resolve(configurationPath, serviceConfiguration.extends);
|
|
26
|
-
_common.TraceUtils.log(`@universis/janitor#RateLimitService will try to extend service configuration from ${extendsPath}`);
|
|
27
|
-
serviceConfiguration = require(extendsPath);
|
|
28
|
-
}
|
|
29
|
-
const pathsArray = serviceConfiguration.paths || [];
|
|
30
|
-
const profilesArray = serviceConfiguration.profiles || [];
|
|
31
|
-
// create maps
|
|
32
|
-
const paths = new Map(pathsArray);
|
|
33
|
-
const profiles = new Map(profilesArray);
|
|
34
|
-
if (paths.size === 0) {
|
|
35
|
-
_common.TraceUtils.warn('@universis/janitor#RateLimitService is being started but the collection of paths is empty.');
|
|
36
|
-
}
|
|
37
|
-
// get proxy address forwarding option
|
|
38
|
-
let proxyAddressForwarding = app.getConfiguration().getSourceAt('settings/universis/api/proxyAddressForwarding');
|
|
39
|
-
if (typeof proxyAddressForwarding !== 'boolean') {
|
|
40
|
-
proxyAddressForwarding = false;
|
|
41
|
-
}
|
|
42
|
-
paths.forEach((value, path) => {
|
|
43
|
-
let profile;
|
|
44
|
-
// get profile
|
|
45
|
-
if (value.profile) {
|
|
46
|
-
profile = profiles.get(value.profile);
|
|
47
|
-
} else {
|
|
48
|
-
// or options defined inline
|
|
49
|
-
profile = value;
|
|
50
|
-
}
|
|
51
|
-
if (profile != null) {
|
|
52
|
-
const rateLimitOptions = Object.assign({
|
|
53
|
-
windowMs: 5 * 60 * 1000, // 5 minutes
|
|
54
|
-
limit: 50, // 50 requests
|
|
55
|
-
legacyHeaders: true // send headers
|
|
56
|
-
}, profile, {
|
|
57
|
-
keyGenerator: (req) => {
|
|
58
|
-
let remoteAddress;
|
|
59
|
-
if (proxyAddressForwarding) {
|
|
60
|
-
// get proxy headers or remote address
|
|
61
|
-
remoteAddress = req.headers['x-real-ip'] || req.headers['x-forwarded-for'] || (req.connection ? req.connection.remoteAddress : req.socket.remoteAddress);
|
|
62
|
-
} else {
|
|
63
|
-
// get remote address
|
|
64
|
-
remoteAddress = req.connection ? req.connection.remoteAddress : req.socket.remoteAddress;
|
|
65
|
-
}
|
|
66
|
-
return `${path}:${remoteAddress}`;
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
if (typeof rateLimitOptions.store === 'string') {
|
|
70
|
-
// load store
|
|
71
|
-
const store = rateLimitOptions.store.split('#');
|
|
72
|
-
let StoreClass;
|
|
73
|
-
if (store.length === 2) {
|
|
74
|
-
const storeModule = require(store[0]);
|
|
75
|
-
if (Object.prototype.hasOwnProperty.call(storeModule, store[1])) {
|
|
76
|
-
StoreClass = storeModule[store[1]];
|
|
77
|
-
rateLimitOptions.store = new StoreClass(this, rateLimitOptions);
|
|
78
|
-
} else {
|
|
79
|
-
throw new Error(`${store} cannot be found or is inaccessible`);
|
|
80
|
-
}
|
|
81
|
-
} else {
|
|
82
|
-
StoreClass = require(store[0]);
|
|
83
|
-
// create store
|
|
84
|
-
rateLimitOptions.store = new StoreClass(this, rateLimitOptions);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
addRouter.use(path, (0, _expressRateLimit.rateLimit)(rateLimitOptions));
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
if (addRouter.stack.length) {
|
|
91
|
-
serviceRouter.stack.unshift.apply(serviceRouter.stack, addRouter.stack);
|
|
92
|
-
}
|
|
93
|
-
} catch (err) {
|
|
94
|
-
_common.TraceUtils.error('An error occurred while validating rate limit configuration.');
|
|
95
|
-
_common.TraceUtils.error(err);
|
|
96
|
-
_common.TraceUtils.warn('Rate limit service is inactive due to an error occured while loading configuration.');
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
}exports.RateLimitService = RateLimitService;
|
|
102
|
-
//# sourceMappingURL=RateLimitService.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"RateLimitService.js","names":["_common","require","_expressRateLimit","_express","_interopRequireDefault","_path","obj","__esModule","default","RateLimitService","ApplicationService","constructor","app","serviceRouter","subscribe","addRouter","express","Router","serviceConfiguration","getConfiguration","getSourceAt","profiles","paths","extends","configurationPath","getConfigurationPath","extendsPath","path","resolve","TraceUtils","log","pathsArray","profilesArray","Map","size","warn","proxyAddressForwarding","forEach","value","profile","get","rateLimitOptions","Object","assign","windowMs","limit","legacyHeaders","keyGenerator","req","remoteAddress","headers","connection","socket","store","split","StoreClass","length","storeModule","prototype","hasOwnProperty","call","Error","use","rateLimit","stack","unshift","apply","err","error","exports"],"sources":["../src/RateLimitService.js"],"sourcesContent":["import { ApplicationService, TraceUtils } from '@themost/common';\nimport { rateLimit } from 'express-rate-limit';\nimport express from 'express';\nimport path from 'path';\n\nexport class RateLimitService extends ApplicationService {\n /**\n * @param {import('@themost/express').ExpressDataApplication} app \n */\n constructor(app) {\n super(app);\n app.serviceRouter.subscribe(serviceRouter => {\n if (serviceRouter == null) {\n return;\n }\n try {\n const addRouter = express.Router();\n let serviceConfiguration = app.getConfiguration().getSourceAt('settings/universis/janitor/rateLimit') || {\n profiles: [],\n paths: []\n };\n if (serviceConfiguration.extends) {\n // get additional configuration\n const configurationPath = app.getConfiguration().getConfigurationPath();\n const extendsPath = path.resolve(configurationPath, serviceConfiguration.extends);\n TraceUtils.log(`@universis/janitor#RateLimitService will try to extend service configuration from ${extendsPath}`);\n serviceConfiguration = require(extendsPath);\n }\n const pathsArray = serviceConfiguration.paths || [];\n const profilesArray = serviceConfiguration.profiles || [];\n // create maps\n const paths = new Map(pathsArray);\n const profiles = new Map(profilesArray);\n if (paths.size === 0) {\n TraceUtils.warn('@universis/janitor#RateLimitService is being started but the collection of paths is empty.');\n }\n // get proxy address forwarding option\n let proxyAddressForwarding = app.getConfiguration().getSourceAt('settings/universis/api/proxyAddressForwarding');\n if (typeof proxyAddressForwarding !== 'boolean') {\n proxyAddressForwarding = false;\n }\n paths.forEach((value, path) => {\n let profile;\n // get profile\n if (value.profile) {\n profile = profiles.get(value.profile);\n } else {\n // or options defined inline\n profile = value\n }\n if (profile != null) {\n const rateLimitOptions = Object.assign({\n windowMs: 5 * 60 * 1000, // 5 minutes\n limit: 50, // 50 requests\n legacyHeaders: true // send headers\n }, profile, {\n keyGenerator: (req) => {\n let remoteAddress;\n if (proxyAddressForwarding) {\n // get proxy headers or remote address\n remoteAddress = req.headers['x-real-ip'] || req.headers['x-forwarded-for'] || (req.connection ? req.connection.remoteAddress : req.socket.remoteAddress);\n } else {\n // get remote address\n remoteAddress = (req.connection ? req.connection.remoteAddress : req.socket.remoteAddress);\n }\n return `${path}:${remoteAddress}`;\n }\n });\n if (typeof rateLimitOptions.store === 'string') {\n // load store\n const store = rateLimitOptions.store.split('#');\n let StoreClass;\n if (store.length === 2) {\n const storeModule = require(store[0]);\n if (Object.prototype.hasOwnProperty.call(storeModule, store[1])) {\n StoreClass = storeModule[store[1]];\n rateLimitOptions.store = new StoreClass(this, rateLimitOptions);\n } else {\n throw new Error(`${store} cannot be found or is inaccessible`);\n }\n } else {\n StoreClass = require(store[0]);\n // create store\n rateLimitOptions.store = new StoreClass(this, rateLimitOptions);\n }\n }\n addRouter.use(path, rateLimit(rateLimitOptions));\n }\n });\n if (addRouter.stack.length) {\n serviceRouter.stack.unshift.apply(serviceRouter.stack, addRouter.stack);\n }\n } catch (err) {\n TraceUtils.error('An error occurred while validating rate limit configuration.');\n TraceUtils.error(err);\n TraceUtils.warn('Rate limit service is inactive due to an error occured while loading configuration.')\n }\n });\n }\n\n}"],"mappings":"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"}
|
package/dist/RedisClientStore.js
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.RedisClientStore = void 0;var _common = require("@themost/common");
|
|
2
|
-
var _rateLimitRedis = _interopRequireDefault(require("rate-limit-redis"));
|
|
3
|
-
var _ioredis = require("ioredis");
|
|
4
|
-
require("@themost/promise-sequence");function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _defineProperty(obj, key, value) {key = _toPropertyKey(key);if (key in obj) {Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true });} else {obj[key] = value;}return obj;}function _toPropertyKey(arg) {var key = _toPrimitive(arg, "string");return typeof key === "symbol" ? key : String(key);}function _toPrimitive(input, hint) {if (typeof input !== "object" || input === null) return input;var prim = input[Symbol.toPrimitive];if (prim !== undefined) {var res = prim.call(input, hint || "default");if (typeof res !== "object") return res;throw new TypeError("@@toPrimitive must return a primitive value.");}return (hint === "string" ? String : Number)(input);}
|
|
5
|
-
|
|
6
|
-
let superLoadIncrementScript;
|
|
7
|
-
let superLoadGetScript;
|
|
8
|
-
|
|
9
|
-
function noLoadGetScript() {
|
|
10
|
-
|
|
11
|
-
//
|
|
12
|
-
}
|
|
13
|
-
function noLoadIncrementScript() {
|
|
14
|
-
|
|
15
|
-
//
|
|
16
|
-
}
|
|
17
|
-
if (_rateLimitRedis.default.prototype.loadIncrementScript.name === 'loadIncrementScript') {
|
|
18
|
-
// get super method for future use
|
|
19
|
-
superLoadIncrementScript = _rateLimitRedis.default.prototype.loadIncrementScript;
|
|
20
|
-
_rateLimitRedis.default.prototype.loadIncrementScript = noLoadIncrementScript;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
if (_rateLimitRedis.default.prototype.loadGetScript.name === 'loadGetScript') {
|
|
24
|
-
// get super method
|
|
25
|
-
superLoadGetScript = _rateLimitRedis.default.prototype.loadGetScript;
|
|
26
|
-
_rateLimitRedis.default.prototype.loadGetScript = noLoadGetScript;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
class RedisClientStore extends _rateLimitRedis.default {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
*
|
|
38
|
-
* @param {import('@themost/common').ApplicationService} service
|
|
39
|
-
* @param {{windowMs: number}} options
|
|
40
|
-
*/
|
|
41
|
-
constructor(service, options) {
|
|
42
|
-
super({
|
|
43
|
-
/**
|
|
44
|
-
* @param {...string} args
|
|
45
|
-
* @returns {Promise<*>}
|
|
46
|
-
*/
|
|
47
|
-
sendCommand: function () {
|
|
48
|
-
const args = Array.from(arguments);
|
|
49
|
-
const [command] = args.splice(0, 1);
|
|
50
|
-
const self = this;
|
|
51
|
-
if (command === 'SCRIPT') {
|
|
52
|
-
const connectOptions = service.getApplication().getConfiguration().getSourceAt('settings/redis/options') || {
|
|
53
|
-
host: '127.0.0.1',
|
|
54
|
-
port: 6379
|
|
55
|
-
};
|
|
56
|
-
const client = new _ioredis.Redis(connectOptions);
|
|
57
|
-
return client.call(command, args).catch((error) => {
|
|
58
|
-
if (error instanceof TypeError && error.message === 'Invalid argument type') {
|
|
59
|
-
_common.TraceUtils.warn('RedisClientStore: Invalid argument type: ' + JSON.stringify(args));
|
|
60
|
-
}
|
|
61
|
-
return Promise.reject(error);
|
|
62
|
-
}).finally(() => {
|
|
63
|
-
if (client.isOpen) {
|
|
64
|
-
client.disconnect().catch((errDisconnect) => {
|
|
65
|
-
_common.TraceUtils.error(errDisconnect);
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
if (self.client == null) {
|
|
71
|
-
const connectOptions = service.getApplication().getConfiguration().getSourceAt('settings/redis/options') || {
|
|
72
|
-
host: '127.0.0.1',
|
|
73
|
-
port: 6379
|
|
74
|
-
};
|
|
75
|
-
self.client = new _ioredis.Redis(connectOptions);
|
|
76
|
-
}
|
|
77
|
-
if (self.client.isOpen) {
|
|
78
|
-
return self.client.call(command, args).catch((error) => {
|
|
79
|
-
if (error instanceof TypeError && error.message === 'Invalid argument type') {
|
|
80
|
-
_common.TraceUtils.warn('RedisClientStore: Invalid argument type: ' + JSON.stringify(args));
|
|
81
|
-
}
|
|
82
|
-
return Promise.reject(error);
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
// send load script commands once
|
|
86
|
-
return (() => {
|
|
87
|
-
if (self.incrementScriptSha == null) {
|
|
88
|
-
return this.postInit();
|
|
89
|
-
}
|
|
90
|
-
return Promise.resolve();
|
|
91
|
-
})().then(() => {
|
|
92
|
-
// send command
|
|
93
|
-
args[0] = self.incrementScriptSha;
|
|
94
|
-
return self.client.call(command, args).catch((error) => {
|
|
95
|
-
if (error instanceof TypeError && error.message === 'Invalid argument type') {
|
|
96
|
-
_common.TraceUtils.warn('RedisClientStore: Invalid argument type: ' + JSON.stringify(args));
|
|
97
|
-
}
|
|
98
|
-
return Promise.reject(error);
|
|
99
|
-
});
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
}); /**
|
|
103
|
-
* @type {import('redis').RedisClientType}
|
|
104
|
-
*/_defineProperty(this, "client", void 0);this.init(options);_common.TraceUtils.debug('RedisClientStore: Starting up and loading increment and get scripts.');
|
|
105
|
-
void this.postInit().then(() => {
|
|
106
|
-
_common.TraceUtils.debug('RedisClientStore: Successfully loaded increment and get scripts.');
|
|
107
|
-
}).catch((err) => {
|
|
108
|
-
_common.TraceUtils.error('RedisClientStore: Failed to load increment and get scripts.');
|
|
109
|
-
_common.TraceUtils.error(err);
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
async postInit() {
|
|
113
|
-
const [incrementScriptSha, getScriptSha] = await Promise.sequence([
|
|
114
|
-
() => superLoadIncrementScript.call(this),
|
|
115
|
-
() => superLoadGetScript.call(this)]);
|
|
116
|
-
|
|
117
|
-
this.incrementScriptSha = incrementScriptSha;
|
|
118
|
-
this.getScriptSha = getScriptSha;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
}exports.RedisClientStore = RedisClientStore;
|
|
122
|
-
//# sourceMappingURL=RedisClientStore.js.map
|