@thzero/library_server_fastify 0.18.15 → 0.18.16
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 +17 -17
- package/boot/index.js +386 -386
- package/boot/plugins/admin/news.js +11 -11
- package/boot/plugins/admin/users.js +11 -11
- package/boot/plugins/api.js +21 -21
- package/boot/plugins/apiFront.js +26 -26
- package/boot/plugins/news.js +11 -11
- package/boot/plugins/users.js +11 -11
- package/boot/plugins/usersExtended.js +6 -6
- package/license.md +8 -8
- package/middleware/authentication.js +94 -94
- package/middleware/authorization.js +112 -112
- package/openSource.js +80 -80
- package/package.json +41 -41
- package/plugins/apiKey.js +49 -49
- package/plugins/auth.js +126 -126
- package/plugins/responseTime.js +111 -111
- package/plugins/settings.js +12 -12
- package/plugins/usageMetrics.js +24 -24
- package/routes/admin/index.js +140 -140
- package/routes/admin/news.js +22 -22
- package/routes/admin/users.js +26 -26
- package/routes/baseNews.js +46 -46
- package/routes/baseUsers.js +180 -180
- package/routes/home.js +28 -28
- package/routes/index.js +41 -41
- package/routes/news.js +6 -6
- package/routes/plans.js +40 -40
- package/routes/usageMetrics.js +39 -39
- package/routes/users.js +6 -6
- package/routes/utility.js +80 -80
- package/routes/version.js +39 -39
package/boot/index.js
CHANGED
|
@@ -1,386 +1,386 @@
|
|
|
1
|
-
import path from 'path';
|
|
2
|
-
|
|
3
|
-
import Fastify from 'fastify';
|
|
4
|
-
// import fastifyAuth from '@fastify/auth';
|
|
5
|
-
import fastifyAuth from '../plugins/auth.js';
|
|
6
|
-
import fastifyCompression from '@fastify/compress';
|
|
7
|
-
import fastifyCors from '@fastify/cors';
|
|
8
|
-
import fastifyHelmet from '@fastify/helmet';
|
|
9
|
-
import fastifyRoutes from '@fastify/routes';
|
|
10
|
-
import fastifyStatic from '@fastify/static';
|
|
11
|
-
|
|
12
|
-
import LibraryServerConstants from '@thzero/library_server/constants.js';
|
|
13
|
-
|
|
14
|
-
import injector from '@thzero/library_common/utility/injector.js';
|
|
15
|
-
|
|
16
|
-
import BootMain from '@thzero/library_server/boot/index.js';
|
|
17
|
-
|
|
18
|
-
import pluginApiKey from '@thzero/library_server_fastify/plugins/apiKey.js';
|
|
19
|
-
import pluginResponseTime from '@thzero/library_server_fastify/plugins/responseTime.js';
|
|
20
|
-
import pluginSettings from '@thzero/library_server_fastify/plugins/settings.js';
|
|
21
|
-
import pluginUsageMetrics from '@thzero/library_server_fastify/plugins/usageMetrics.js';
|
|
22
|
-
|
|
23
|
-
import authenticationDefault from '../middleware/authentication.js';
|
|
24
|
-
import authorizationDefault from '../middleware/authorization.js';
|
|
25
|
-
|
|
26
|
-
class FastifyBootMain extends BootMain {
|
|
27
|
-
async _initApp(args, plugins) {
|
|
28
|
-
const __dirname = path.resolve();
|
|
29
|
-
|
|
30
|
-
// const serverFactory = (handler, opts) => {
|
|
31
|
-
// const server = http.createServer((req, res) => {
|
|
32
|
-
// handler(req, res)
|
|
33
|
-
// });
|
|
34
|
-
|
|
35
|
-
// return server;
|
|
36
|
-
// };
|
|
37
|
-
|
|
38
|
-
let http2 = this._appConfig.get('http2', { enabled: false });
|
|
39
|
-
const http2_enabled = http2 && http2.enabled === 'true' ? true : false;
|
|
40
|
-
this.loggerServiceI.info2(`config.http2.override: ${http2_enabled}`);
|
|
41
|
-
let https = null;
|
|
42
|
-
if (http2_enabled) {
|
|
43
|
-
let http2 = this._appConfig.get('http2', false);
|
|
44
|
-
if (!http2.key)
|
|
45
|
-
throw Error('Invalid key, required by http2');
|
|
46
|
-
if (!http2.cert)
|
|
47
|
-
throw Error('Invalid cert, required by http2');
|
|
48
|
-
https = {
|
|
49
|
-
key: http2.key,
|
|
50
|
-
cert: http2.cert
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// const fastify = Fastify({ serverFactory, logger: true });
|
|
55
|
-
const fastify = Fastify({
|
|
56
|
-
http2: http2_enabled,
|
|
57
|
-
https: https,
|
|
58
|
-
logger: true
|
|
59
|
-
});
|
|
60
|
-
const serverHttp = fastify.server;
|
|
61
|
-
|
|
62
|
-
await fastify.register(fastifyRoutes);
|
|
63
|
-
|
|
64
|
-
// // https://github.com/koajs/cors
|
|
65
|
-
// app.use(koaCors({
|
|
66
|
-
// allowMethods: 'GET,POST,DELETE',
|
|
67
|
-
// maxAge : 7200,
|
|
68
|
-
// allowHeaders: `${LibraryServerConstants.Headers.AuthKeys.API}, ${LibraryServerConstants.Headers.AuthKeys.AUTH}, ${ServerConstants.Headers.CorrelationId}, Content-Type`,
|
|
69
|
-
// credentials: true,
|
|
70
|
-
// origin: '*'
|
|
71
|
-
// }));
|
|
72
|
-
// https://github.com/fastify/fastify-cors
|
|
73
|
-
// fastify.register(fastifyCors, {
|
|
74
|
-
// allowMethods: 'GET,POST,DELETE',
|
|
75
|
-
// maxAge : 7200,
|
|
76
|
-
// allowHeaders: `${LibraryServerConstants.Headers.AuthKeys.API}, ${LibraryServerConstants.Headers.AuthKeys.AUTH}, ${ServerConstants.Headers.CorrelationId}, Content-Type`,
|
|
77
|
-
// credentials: true,
|
|
78
|
-
// origin: '*'
|
|
79
|
-
// });
|
|
80
|
-
const corsOptionsDefault = this._initCors({
|
|
81
|
-
allowHeaders: [ LibraryServerConstants.Headers.AuthKeys.API, LibraryServerConstants.Headers.AuthKeys.AUTH, LibraryServerConstants.Headers.CorrelationId, 'Content-Type' ],
|
|
82
|
-
credentials: true,
|
|
83
|
-
maxAge : 7200,
|
|
84
|
-
methods: ['GET', 'POST', 'DELETE'],
|
|
85
|
-
origin: '*'
|
|
86
|
-
});
|
|
87
|
-
await fastify.register(fastifyCors, (instance) => {
|
|
88
|
-
return (req, callback) => {
|
|
89
|
-
let corsOptions = corsOptionsDefault;
|
|
90
|
-
callback(null, corsOptions) // callback expects two parameters: error and options
|
|
91
|
-
}
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
// // https://www.npmjs.com/package/koa-helmet
|
|
95
|
-
// app.use(koaHelmet());
|
|
96
|
-
// https://github.com/fastify/fastify-helmet
|
|
97
|
-
const helmetOptions = this._initHelmet({
|
|
98
|
-
// Example disables the `contentSecurityPolicy` middleware but keeps the rest.
|
|
99
|
-
// contentSecurityPolicy: false
|
|
100
|
-
});
|
|
101
|
-
await fastify.register(
|
|
102
|
-
fastifyHelmet,
|
|
103
|
-
helmetOptions
|
|
104
|
-
);
|
|
105
|
-
|
|
106
|
-
const compressionOptions = this._initCompression({
|
|
107
|
-
global: true,
|
|
108
|
-
requestEncodings: [ 'br', 'gzip' ]
|
|
109
|
-
});
|
|
110
|
-
await fastify.register(
|
|
111
|
-
fastifyCompression,
|
|
112
|
-
compressionOptions
|
|
113
|
-
);
|
|
114
|
-
|
|
115
|
-
// // error
|
|
116
|
-
// app.use(async (ctx, next) => {
|
|
117
|
-
// try {
|
|
118
|
-
// await next();
|
|
119
|
-
// }
|
|
120
|
-
// catch (err) {
|
|
121
|
-
// ctx.status = err.status || 500;
|
|
122
|
-
// if (err instanceof TokenExpiredError) {
|
|
123
|
-
// ctx.status = 401;
|
|
124
|
-
// ctx.response.header['WWW-Authenticate'] = 'Bearer error="invalid_token", error_description="The access token expired"'
|
|
125
|
-
// }
|
|
126
|
-
// ctx.app.emit('error', err, ctx);
|
|
127
|
-
// await this.usageMetricsServiceI.register(ctx, err).catch(() => {
|
|
128
|
-
// this.loggerServiceI.exception('KoaBootMain', 'start', err);
|
|
129
|
-
// });
|
|
130
|
-
// }
|
|
131
|
-
// });
|
|
132
|
-
// await fastify.register(async (instance, opts, done) => {
|
|
133
|
-
// // try {
|
|
134
|
-
// // done();
|
|
135
|
-
// // }
|
|
136
|
-
// // catch (err) {
|
|
137
|
-
// // let status = err.status || 500;
|
|
138
|
-
// // if (err instanceof TokenExpiredError) {
|
|
139
|
-
// // status = 401;
|
|
140
|
-
// // response.header['WWW-Authenticate'] = 'Bearer error="invalid_token", error_description="The access token expired"'
|
|
141
|
-
// // }
|
|
142
|
-
// // app.emit('error', err, ctx);
|
|
143
|
-
// // await this.usageMetricsServiceI.register(ctx, err).catch(() => {
|
|
144
|
-
// // this.loggerServiceI.exception('KoaBootMain', 'start', err);
|
|
145
|
-
// // });
|
|
146
|
-
// // }
|
|
147
|
-
// });
|
|
148
|
-
|
|
149
|
-
// app.on('error', (err, ctx) => {
|
|
150
|
-
// this.loggerServiceI.error('KoaBootMain', 'start', 'Uncaught Exception', err);
|
|
151
|
-
// });
|
|
152
|
-
|
|
153
|
-
// // config
|
|
154
|
-
// app.use(async (ctx, next) => {
|
|
155
|
-
// ctx.config = this._appConfig;
|
|
156
|
-
// await next();
|
|
157
|
-
// });
|
|
158
|
-
// // correlationId
|
|
159
|
-
// app.use(async (ctx, next) => {
|
|
160
|
-
// ctx.correlationId = ctx.request.header[LibraryServerConstants.Headers.CorrelationId];
|
|
161
|
-
// await next();
|
|
162
|
-
// });
|
|
163
|
-
// fastify.register(async (instance, opts, done) => {
|
|
164
|
-
// instance.addHook('onRequest', (request, reply, next) => {
|
|
165
|
-
// request.config = this._appConfig;
|
|
166
|
-
// request.correlationId = ctx.request.header[LibraryServerConstants.Headers.CorrelationId];
|
|
167
|
-
// next();
|
|
168
|
-
// });
|
|
169
|
-
|
|
170
|
-
// done();
|
|
171
|
-
// });
|
|
172
|
-
await fastify.register(pluginSettings, {
|
|
173
|
-
config: this._appConfig
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
// // logger
|
|
177
|
-
// app.use(async (ctx, next) => {
|
|
178
|
-
// await next();
|
|
179
|
-
// const rt = ctx.response.get(ResponseTime);
|
|
180
|
-
// this.loggerServiceI.info2(`${ctx.method} ${ctx.url} - ${rt}`);
|
|
181
|
-
// });
|
|
182
|
-
|
|
183
|
-
// // x-response-time
|
|
184
|
-
// app.use(async (ctx, next) => {
|
|
185
|
-
// const start = Utility.timerStart();
|
|
186
|
-
// await next();
|
|
187
|
-
// const delta = Utility.timerStop(start, true);
|
|
188
|
-
// ctx.set(ResponseTime, delta);
|
|
189
|
-
// });
|
|
190
|
-
// https://github.com/lolo32/fastify-response-time
|
|
191
|
-
await fastify.register(pluginResponseTime, {
|
|
192
|
-
logger: this.loggerServiceI
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
// app.use(koaStatic('./public'));
|
|
196
|
-
// https://github.com/fastify/fastify-static
|
|
197
|
-
await fastify.register(fastifyStatic, {
|
|
198
|
-
root: path.join(__dirname, 'public'),
|
|
199
|
-
prefix: '/public/', // optional: default '/'
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
this._initPreAuth(fastify);
|
|
203
|
-
|
|
204
|
-
// // auth-api-token
|
|
205
|
-
// app.use(async (ctx, next) => {
|
|
206
|
-
// if (ctx.originalUrl === '/favicon.ico') {
|
|
207
|
-
// await next();
|
|
208
|
-
// return;
|
|
209
|
-
// }
|
|
210
|
-
|
|
211
|
-
// const key = ctx.get(LibraryServerConstants.Headers.AuthKeys.API);
|
|
212
|
-
// // this.loggerServiceI.debug('KoaBootMain', 'start', 'auth-api-token.key', key);
|
|
213
|
-
// if (!String.isNullOrEmpty(key)) {
|
|
214
|
-
// const auth = ctx.config.get('auth');
|
|
215
|
-
// if (auth) {
|
|
216
|
-
// const apiKey = auth.apiKey;
|
|
217
|
-
// // this.loggerServiceI.debug('KoaBootMain', 'start', 'auth-api-token.apiKey', apiKey);
|
|
218
|
-
// // this.loggerServiceI.debug('KoaBootMain', 'start', 'auth-api-token.key===apiKey', (key === apiKey));
|
|
219
|
-
// if (key === apiKey) {
|
|
220
|
-
// ctx.state.apiKey = key;
|
|
221
|
-
// await next();
|
|
222
|
-
// return;
|
|
223
|
-
// }
|
|
224
|
-
// }
|
|
225
|
-
// }
|
|
226
|
-
|
|
227
|
-
// (async () => {
|
|
228
|
-
// await this.usageMetricsServiceI.register(ctx).catch((err) => {
|
|
229
|
-
// this.loggerServiceI.error('KoaBootMain', 'start', 'usageMetrics', err);
|
|
230
|
-
// });
|
|
231
|
-
// })();
|
|
232
|
-
|
|
233
|
-
// console.log('Unauthorized... auth-api-token failure');
|
|
234
|
-
// ctx.throw(401);
|
|
235
|
-
// });
|
|
236
|
-
// fastify.register((instance, opts, done) => {
|
|
237
|
-
// instance.addHook('onRequest', (request, reply, next) => {
|
|
238
|
-
// if (request.originalUrl === '/favicon.ico') {
|
|
239
|
-
// next();
|
|
240
|
-
// return;
|
|
241
|
-
// }
|
|
242
|
-
|
|
243
|
-
// const key = request.get(LibraryServerConstants.Headers.AuthKeys.API);
|
|
244
|
-
// // this.loggerServiceI.debug('KoaBootMain', 'start', 'auth-api-token.key', key);
|
|
245
|
-
// if (!String.isNullOrEmpty(key)) {
|
|
246
|
-
// const auth = request.config.get('auth');
|
|
247
|
-
// if (auth) {
|
|
248
|
-
// const apiKey = auth.apiKey;
|
|
249
|
-
// // this.loggerServiceI.debug('KoaBootMain', 'start', 'auth-api-token.apiKey', apiKey);
|
|
250
|
-
// // this.loggerServiceI.debug('KoaBootMain', 'start', 'auth-api-token.key===apiKey', (key === apiKey));
|
|
251
|
-
// if (key === apiKey) {
|
|
252
|
-
// request.state.apiKey = key;
|
|
253
|
-
// next();
|
|
254
|
-
// return;
|
|
255
|
-
// }
|
|
256
|
-
// }
|
|
257
|
-
// }
|
|
258
|
-
|
|
259
|
-
// (async () => {
|
|
260
|
-
// await this.usageMetricsServiceI.register(ctx).catch((err) => {
|
|
261
|
-
// this.loggerServiceI.error('FastifyBootMain', 'start', 'usageMetrics', err);
|
|
262
|
-
// });
|
|
263
|
-
// })();
|
|
264
|
-
|
|
265
|
-
// console.log('Unauthorized... auth-api-token failure');
|
|
266
|
-
// request.throw(401);
|
|
267
|
-
// next();
|
|
268
|
-
// });
|
|
269
|
-
|
|
270
|
-
// done();
|
|
271
|
-
// });
|
|
272
|
-
await fastify.register(pluginApiKey, {
|
|
273
|
-
logger: this.loggerServiceI,
|
|
274
|
-
usageMetrics: this.usageMetricsServiceI
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
await fastify.register(fastifyAuth);
|
|
278
|
-
|
|
279
|
-
const capitalize = (word) => {
|
|
280
|
-
return word[0].toUpperCase() + word.slice(1).toLowerCase();
|
|
281
|
-
};
|
|
282
|
-
|
|
283
|
-
let item;
|
|
284
|
-
for (let [key, value] of this._initAuthentication(new Map()).entries()) {
|
|
285
|
-
item = value.init(injector);
|
|
286
|
-
fastify.decorate('authentication' + capitalize(key), item.callback);
|
|
287
|
-
fastify.decorate('authenticationMiddleware' + capitalize(key), item.service);
|
|
288
|
-
}
|
|
289
|
-
for (let [key, value] of this._initAuthorization(new Map()).entries()) {
|
|
290
|
-
item = value.init(injector);
|
|
291
|
-
fastify.decorate('authorization' + capitalize(key), item.callback);
|
|
292
|
-
fastify.decorate('authorizationMiddleware' + capitalize(key), item.service);
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
this._initPostAuth(fastify);
|
|
296
|
-
|
|
297
|
-
this._routes = [];
|
|
298
|
-
|
|
299
|
-
this._initPreRoutes(fastify);
|
|
300
|
-
|
|
301
|
-
console.log('----route.init-----------------------------------');
|
|
302
|
-
|
|
303
|
-
for (const pluginRoute of plugins)
|
|
304
|
-
await pluginRoute.initRoutes(this._routes);
|
|
305
|
-
|
|
306
|
-
await this._initRoutes();
|
|
307
|
-
for (const route of this._routes) {
|
|
308
|
-
console.log(route);
|
|
309
|
-
await route.init(injector, fastify, this._appConfig);
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
console.log('----route.init.complete--------------------------');
|
|
313
|
-
console.log();
|
|
314
|
-
|
|
315
|
-
console.log('----route.listing--------------------------------');
|
|
316
|
-
|
|
317
|
-
let methods;
|
|
318
|
-
for (let [key, value] of fastify.routes.entries()) {
|
|
319
|
-
methods = [];
|
|
320
|
-
for (let item of value)
|
|
321
|
-
methods.push(item.method);
|
|
322
|
-
console.log([ key, methods ]);
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
console.log('----route.listing.complete-----------------------');
|
|
326
|
-
console.log();
|
|
327
|
-
|
|
328
|
-
// // usage metrics
|
|
329
|
-
// app.use(async (ctx, next) => {
|
|
330
|
-
// await next();
|
|
331
|
-
// await this.usageMetricsServiceI.register(ctx).catch((err) => {
|
|
332
|
-
// this.loggerServiceI.error('KoaBootMain', 'start', 'usageMetrics', err);
|
|
333
|
-
// });
|
|
334
|
-
// });
|
|
335
|
-
await fastify.register(pluginUsageMetrics, {
|
|
336
|
-
logger: this.loggerServiceI,
|
|
337
|
-
usageMetrics: this.usageMetricsServiceI
|
|
338
|
-
});
|
|
339
|
-
|
|
340
|
-
return {
|
|
341
|
-
app: fastify,
|
|
342
|
-
server: serverHttp,
|
|
343
|
-
listen: fastify.listen
|
|
344
|
-
};
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
_initAuthentication(map) {
|
|
348
|
-
map.set('default', new authenticationDefault());
|
|
349
|
-
return map;
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
_initAuthorization(map) {
|
|
353
|
-
map.set('default', new authorizationDefault());
|
|
354
|
-
return map;
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
_initAppListen(app, server, address, port, err) {
|
|
358
|
-
const options = { port: port };
|
|
359
|
-
if (address)
|
|
360
|
-
options.host = address;
|
|
361
|
-
app.listen(options, err);
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
async _initAppPost(app, args) {
|
|
365
|
-
this._initPostRoutes(app);
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
_initCompression(options) {
|
|
369
|
-
return options;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
_initCors(options) {
|
|
373
|
-
// https://github.com/fastify/fastify-cors
|
|
374
|
-
return options;
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
_initHelmet(options) {
|
|
378
|
-
return options;
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
_initRoute(route) {
|
|
382
|
-
this._routes.push(route);
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
export default FastifyBootMain;
|
|
1
|
+
import path from 'path';
|
|
2
|
+
|
|
3
|
+
import Fastify from 'fastify';
|
|
4
|
+
// import fastifyAuth from '@fastify/auth';
|
|
5
|
+
import fastifyAuth from '../plugins/auth.js';
|
|
6
|
+
import fastifyCompression from '@fastify/compress';
|
|
7
|
+
import fastifyCors from '@fastify/cors';
|
|
8
|
+
import fastifyHelmet from '@fastify/helmet';
|
|
9
|
+
import fastifyRoutes from '@fastify/routes';
|
|
10
|
+
import fastifyStatic from '@fastify/static';
|
|
11
|
+
|
|
12
|
+
import LibraryServerConstants from '@thzero/library_server/constants.js';
|
|
13
|
+
|
|
14
|
+
import injector from '@thzero/library_common/utility/injector.js';
|
|
15
|
+
|
|
16
|
+
import BootMain from '@thzero/library_server/boot/index.js';
|
|
17
|
+
|
|
18
|
+
import pluginApiKey from '@thzero/library_server_fastify/plugins/apiKey.js';
|
|
19
|
+
import pluginResponseTime from '@thzero/library_server_fastify/plugins/responseTime.js';
|
|
20
|
+
import pluginSettings from '@thzero/library_server_fastify/plugins/settings.js';
|
|
21
|
+
import pluginUsageMetrics from '@thzero/library_server_fastify/plugins/usageMetrics.js';
|
|
22
|
+
|
|
23
|
+
import authenticationDefault from '../middleware/authentication.js';
|
|
24
|
+
import authorizationDefault from '../middleware/authorization.js';
|
|
25
|
+
|
|
26
|
+
class FastifyBootMain extends BootMain {
|
|
27
|
+
async _initApp(args, plugins) {
|
|
28
|
+
const __dirname = path.resolve();
|
|
29
|
+
|
|
30
|
+
// const serverFactory = (handler, opts) => {
|
|
31
|
+
// const server = http.createServer((req, res) => {
|
|
32
|
+
// handler(req, res)
|
|
33
|
+
// });
|
|
34
|
+
|
|
35
|
+
// return server;
|
|
36
|
+
// };
|
|
37
|
+
|
|
38
|
+
let http2 = this._appConfig.get('http2', { enabled: false });
|
|
39
|
+
const http2_enabled = http2 && http2.enabled === 'true' ? true : false;
|
|
40
|
+
this.loggerServiceI.info2(`config.http2.override: ${http2_enabled}`);
|
|
41
|
+
let https = null;
|
|
42
|
+
if (http2_enabled) {
|
|
43
|
+
let http2 = this._appConfig.get('http2', false);
|
|
44
|
+
if (!http2.key)
|
|
45
|
+
throw Error('Invalid key, required by http2');
|
|
46
|
+
if (!http2.cert)
|
|
47
|
+
throw Error('Invalid cert, required by http2');
|
|
48
|
+
https = {
|
|
49
|
+
key: http2.key,
|
|
50
|
+
cert: http2.cert
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// const fastify = Fastify({ serverFactory, logger: true });
|
|
55
|
+
const fastify = Fastify({
|
|
56
|
+
http2: http2_enabled,
|
|
57
|
+
https: https,
|
|
58
|
+
logger: true
|
|
59
|
+
});
|
|
60
|
+
const serverHttp = fastify.server;
|
|
61
|
+
|
|
62
|
+
await fastify.register(fastifyRoutes);
|
|
63
|
+
|
|
64
|
+
// // https://github.com/koajs/cors
|
|
65
|
+
// app.use(koaCors({
|
|
66
|
+
// allowMethods: 'GET,POST,DELETE',
|
|
67
|
+
// maxAge : 7200,
|
|
68
|
+
// allowHeaders: `${LibraryServerConstants.Headers.AuthKeys.API}, ${LibraryServerConstants.Headers.AuthKeys.AUTH}, ${ServerConstants.Headers.CorrelationId}, Content-Type`,
|
|
69
|
+
// credentials: true,
|
|
70
|
+
// origin: '*'
|
|
71
|
+
// }));
|
|
72
|
+
// https://github.com/fastify/fastify-cors
|
|
73
|
+
// fastify.register(fastifyCors, {
|
|
74
|
+
// allowMethods: 'GET,POST,DELETE',
|
|
75
|
+
// maxAge : 7200,
|
|
76
|
+
// allowHeaders: `${LibraryServerConstants.Headers.AuthKeys.API}, ${LibraryServerConstants.Headers.AuthKeys.AUTH}, ${ServerConstants.Headers.CorrelationId}, Content-Type`,
|
|
77
|
+
// credentials: true,
|
|
78
|
+
// origin: '*'
|
|
79
|
+
// });
|
|
80
|
+
const corsOptionsDefault = this._initCors({
|
|
81
|
+
allowHeaders: [ LibraryServerConstants.Headers.AuthKeys.API, LibraryServerConstants.Headers.AuthKeys.AUTH, LibraryServerConstants.Headers.CorrelationId, 'Content-Type' ],
|
|
82
|
+
credentials: true,
|
|
83
|
+
maxAge : 7200,
|
|
84
|
+
methods: ['GET', 'POST', 'DELETE'],
|
|
85
|
+
origin: '*'
|
|
86
|
+
});
|
|
87
|
+
await fastify.register(fastifyCors, (instance) => {
|
|
88
|
+
return (req, callback) => {
|
|
89
|
+
let corsOptions = corsOptionsDefault;
|
|
90
|
+
callback(null, corsOptions) // callback expects two parameters: error and options
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// // https://www.npmjs.com/package/koa-helmet
|
|
95
|
+
// app.use(koaHelmet());
|
|
96
|
+
// https://github.com/fastify/fastify-helmet
|
|
97
|
+
const helmetOptions = this._initHelmet({
|
|
98
|
+
// Example disables the `contentSecurityPolicy` middleware but keeps the rest.
|
|
99
|
+
// contentSecurityPolicy: false
|
|
100
|
+
});
|
|
101
|
+
await fastify.register(
|
|
102
|
+
fastifyHelmet,
|
|
103
|
+
helmetOptions
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
const compressionOptions = this._initCompression({
|
|
107
|
+
global: true,
|
|
108
|
+
requestEncodings: [ 'br', 'gzip' ]
|
|
109
|
+
});
|
|
110
|
+
await fastify.register(
|
|
111
|
+
fastifyCompression,
|
|
112
|
+
compressionOptions
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
// // error
|
|
116
|
+
// app.use(async (ctx, next) => {
|
|
117
|
+
// try {
|
|
118
|
+
// await next();
|
|
119
|
+
// }
|
|
120
|
+
// catch (err) {
|
|
121
|
+
// ctx.status = err.status || 500;
|
|
122
|
+
// if (err instanceof TokenExpiredError) {
|
|
123
|
+
// ctx.status = 401;
|
|
124
|
+
// ctx.response.header['WWW-Authenticate'] = 'Bearer error="invalid_token", error_description="The access token expired"'
|
|
125
|
+
// }
|
|
126
|
+
// ctx.app.emit('error', err, ctx);
|
|
127
|
+
// await this.usageMetricsServiceI.register(ctx, err).catch(() => {
|
|
128
|
+
// this.loggerServiceI.exception('KoaBootMain', 'start', err);
|
|
129
|
+
// });
|
|
130
|
+
// }
|
|
131
|
+
// });
|
|
132
|
+
// await fastify.register(async (instance, opts, done) => {
|
|
133
|
+
// // try {
|
|
134
|
+
// // done();
|
|
135
|
+
// // }
|
|
136
|
+
// // catch (err) {
|
|
137
|
+
// // let status = err.status || 500;
|
|
138
|
+
// // if (err instanceof TokenExpiredError) {
|
|
139
|
+
// // status = 401;
|
|
140
|
+
// // response.header['WWW-Authenticate'] = 'Bearer error="invalid_token", error_description="The access token expired"'
|
|
141
|
+
// // }
|
|
142
|
+
// // app.emit('error', err, ctx);
|
|
143
|
+
// // await this.usageMetricsServiceI.register(ctx, err).catch(() => {
|
|
144
|
+
// // this.loggerServiceI.exception('KoaBootMain', 'start', err);
|
|
145
|
+
// // });
|
|
146
|
+
// // }
|
|
147
|
+
// });
|
|
148
|
+
|
|
149
|
+
// app.on('error', (err, ctx) => {
|
|
150
|
+
// this.loggerServiceI.error('KoaBootMain', 'start', 'Uncaught Exception', err);
|
|
151
|
+
// });
|
|
152
|
+
|
|
153
|
+
// // config
|
|
154
|
+
// app.use(async (ctx, next) => {
|
|
155
|
+
// ctx.config = this._appConfig;
|
|
156
|
+
// await next();
|
|
157
|
+
// });
|
|
158
|
+
// // correlationId
|
|
159
|
+
// app.use(async (ctx, next) => {
|
|
160
|
+
// ctx.correlationId = ctx.request.header[LibraryServerConstants.Headers.CorrelationId];
|
|
161
|
+
// await next();
|
|
162
|
+
// });
|
|
163
|
+
// fastify.register(async (instance, opts, done) => {
|
|
164
|
+
// instance.addHook('onRequest', (request, reply, next) => {
|
|
165
|
+
// request.config = this._appConfig;
|
|
166
|
+
// request.correlationId = ctx.request.header[LibraryServerConstants.Headers.CorrelationId];
|
|
167
|
+
// next();
|
|
168
|
+
// });
|
|
169
|
+
|
|
170
|
+
// done();
|
|
171
|
+
// });
|
|
172
|
+
await fastify.register(pluginSettings, {
|
|
173
|
+
config: this._appConfig
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
// // logger
|
|
177
|
+
// app.use(async (ctx, next) => {
|
|
178
|
+
// await next();
|
|
179
|
+
// const rt = ctx.response.get(ResponseTime);
|
|
180
|
+
// this.loggerServiceI.info2(`${ctx.method} ${ctx.url} - ${rt}`);
|
|
181
|
+
// });
|
|
182
|
+
|
|
183
|
+
// // x-response-time
|
|
184
|
+
// app.use(async (ctx, next) => {
|
|
185
|
+
// const start = Utility.timerStart();
|
|
186
|
+
// await next();
|
|
187
|
+
// const delta = Utility.timerStop(start, true);
|
|
188
|
+
// ctx.set(ResponseTime, delta);
|
|
189
|
+
// });
|
|
190
|
+
// https://github.com/lolo32/fastify-response-time
|
|
191
|
+
await fastify.register(pluginResponseTime, {
|
|
192
|
+
logger: this.loggerServiceI
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
// app.use(koaStatic('./public'));
|
|
196
|
+
// https://github.com/fastify/fastify-static
|
|
197
|
+
await fastify.register(fastifyStatic, {
|
|
198
|
+
root: path.join(__dirname, 'public'),
|
|
199
|
+
prefix: '/public/', // optional: default '/'
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
this._initPreAuth(fastify);
|
|
203
|
+
|
|
204
|
+
// // auth-api-token
|
|
205
|
+
// app.use(async (ctx, next) => {
|
|
206
|
+
// if (ctx.originalUrl === '/favicon.ico') {
|
|
207
|
+
// await next();
|
|
208
|
+
// return;
|
|
209
|
+
// }
|
|
210
|
+
|
|
211
|
+
// const key = ctx.get(LibraryServerConstants.Headers.AuthKeys.API);
|
|
212
|
+
// // this.loggerServiceI.debug('KoaBootMain', 'start', 'auth-api-token.key', key);
|
|
213
|
+
// if (!String.isNullOrEmpty(key)) {
|
|
214
|
+
// const auth = ctx.config.get('auth');
|
|
215
|
+
// if (auth) {
|
|
216
|
+
// const apiKey = auth.apiKey;
|
|
217
|
+
// // this.loggerServiceI.debug('KoaBootMain', 'start', 'auth-api-token.apiKey', apiKey);
|
|
218
|
+
// // this.loggerServiceI.debug('KoaBootMain', 'start', 'auth-api-token.key===apiKey', (key === apiKey));
|
|
219
|
+
// if (key === apiKey) {
|
|
220
|
+
// ctx.state.apiKey = key;
|
|
221
|
+
// await next();
|
|
222
|
+
// return;
|
|
223
|
+
// }
|
|
224
|
+
// }
|
|
225
|
+
// }
|
|
226
|
+
|
|
227
|
+
// (async () => {
|
|
228
|
+
// await this.usageMetricsServiceI.register(ctx).catch((err) => {
|
|
229
|
+
// this.loggerServiceI.error('KoaBootMain', 'start', 'usageMetrics', err);
|
|
230
|
+
// });
|
|
231
|
+
// })();
|
|
232
|
+
|
|
233
|
+
// console.log('Unauthorized... auth-api-token failure');
|
|
234
|
+
// ctx.throw(401);
|
|
235
|
+
// });
|
|
236
|
+
// fastify.register((instance, opts, done) => {
|
|
237
|
+
// instance.addHook('onRequest', (request, reply, next) => {
|
|
238
|
+
// if (request.originalUrl === '/favicon.ico') {
|
|
239
|
+
// next();
|
|
240
|
+
// return;
|
|
241
|
+
// }
|
|
242
|
+
|
|
243
|
+
// const key = request.get(LibraryServerConstants.Headers.AuthKeys.API);
|
|
244
|
+
// // this.loggerServiceI.debug('KoaBootMain', 'start', 'auth-api-token.key', key);
|
|
245
|
+
// if (!String.isNullOrEmpty(key)) {
|
|
246
|
+
// const auth = request.config.get('auth');
|
|
247
|
+
// if (auth) {
|
|
248
|
+
// const apiKey = auth.apiKey;
|
|
249
|
+
// // this.loggerServiceI.debug('KoaBootMain', 'start', 'auth-api-token.apiKey', apiKey);
|
|
250
|
+
// // this.loggerServiceI.debug('KoaBootMain', 'start', 'auth-api-token.key===apiKey', (key === apiKey));
|
|
251
|
+
// if (key === apiKey) {
|
|
252
|
+
// request.state.apiKey = key;
|
|
253
|
+
// next();
|
|
254
|
+
// return;
|
|
255
|
+
// }
|
|
256
|
+
// }
|
|
257
|
+
// }
|
|
258
|
+
|
|
259
|
+
// (async () => {
|
|
260
|
+
// await this.usageMetricsServiceI.register(ctx).catch((err) => {
|
|
261
|
+
// this.loggerServiceI.error('FastifyBootMain', 'start', 'usageMetrics', err);
|
|
262
|
+
// });
|
|
263
|
+
// })();
|
|
264
|
+
|
|
265
|
+
// console.log('Unauthorized... auth-api-token failure');
|
|
266
|
+
// request.throw(401);
|
|
267
|
+
// next();
|
|
268
|
+
// });
|
|
269
|
+
|
|
270
|
+
// done();
|
|
271
|
+
// });
|
|
272
|
+
await fastify.register(pluginApiKey, {
|
|
273
|
+
logger: this.loggerServiceI,
|
|
274
|
+
usageMetrics: this.usageMetricsServiceI
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
await fastify.register(fastifyAuth);
|
|
278
|
+
|
|
279
|
+
const capitalize = (word) => {
|
|
280
|
+
return word[0].toUpperCase() + word.slice(1).toLowerCase();
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
let item;
|
|
284
|
+
for (let [key, value] of this._initAuthentication(new Map()).entries()) {
|
|
285
|
+
item = value.init(injector);
|
|
286
|
+
fastify.decorate('authentication' + capitalize(key), item.callback);
|
|
287
|
+
fastify.decorate('authenticationMiddleware' + capitalize(key), item.service);
|
|
288
|
+
}
|
|
289
|
+
for (let [key, value] of this._initAuthorization(new Map()).entries()) {
|
|
290
|
+
item = value.init(injector);
|
|
291
|
+
fastify.decorate('authorization' + capitalize(key), item.callback);
|
|
292
|
+
fastify.decorate('authorizationMiddleware' + capitalize(key), item.service);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
this._initPostAuth(fastify);
|
|
296
|
+
|
|
297
|
+
this._routes = [];
|
|
298
|
+
|
|
299
|
+
this._initPreRoutes(fastify);
|
|
300
|
+
|
|
301
|
+
console.log('----route.init-----------------------------------');
|
|
302
|
+
|
|
303
|
+
for (const pluginRoute of plugins)
|
|
304
|
+
await pluginRoute.initRoutes(this._routes);
|
|
305
|
+
|
|
306
|
+
await this._initRoutes();
|
|
307
|
+
for (const route of this._routes) {
|
|
308
|
+
console.log(route);
|
|
309
|
+
await route.init(injector, fastify, this._appConfig);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
console.log('----route.init.complete--------------------------');
|
|
313
|
+
console.log();
|
|
314
|
+
|
|
315
|
+
console.log('----route.listing--------------------------------');
|
|
316
|
+
|
|
317
|
+
let methods;
|
|
318
|
+
for (let [key, value] of fastify.routes.entries()) {
|
|
319
|
+
methods = [];
|
|
320
|
+
for (let item of value)
|
|
321
|
+
methods.push(item.method);
|
|
322
|
+
console.log([ key, methods ]);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
console.log('----route.listing.complete-----------------------');
|
|
326
|
+
console.log();
|
|
327
|
+
|
|
328
|
+
// // usage metrics
|
|
329
|
+
// app.use(async (ctx, next) => {
|
|
330
|
+
// await next();
|
|
331
|
+
// await this.usageMetricsServiceI.register(ctx).catch((err) => {
|
|
332
|
+
// this.loggerServiceI.error('KoaBootMain', 'start', 'usageMetrics', err);
|
|
333
|
+
// });
|
|
334
|
+
// });
|
|
335
|
+
await fastify.register(pluginUsageMetrics, {
|
|
336
|
+
logger: this.loggerServiceI,
|
|
337
|
+
usageMetrics: this.usageMetricsServiceI
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
return {
|
|
341
|
+
app: fastify,
|
|
342
|
+
server: serverHttp,
|
|
343
|
+
listen: fastify.listen
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
_initAuthentication(map) {
|
|
348
|
+
map.set('default', new authenticationDefault());
|
|
349
|
+
return map;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
_initAuthorization(map) {
|
|
353
|
+
map.set('default', new authorizationDefault());
|
|
354
|
+
return map;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
_initAppListen(app, server, address, port, err) {
|
|
358
|
+
const options = { port: port };
|
|
359
|
+
if (address)
|
|
360
|
+
options.host = address;
|
|
361
|
+
app.listen(options, err);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
async _initAppPost(app, args) {
|
|
365
|
+
this._initPostRoutes(app);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
_initCompression(options) {
|
|
369
|
+
return options;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
_initCors(options) {
|
|
373
|
+
// https://github.com/fastify/fastify-cors
|
|
374
|
+
return options;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
_initHelmet(options) {
|
|
378
|
+
return options;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
_initRoute(route) {
|
|
382
|
+
this._routes.push(route);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
export default FastifyBootMain;
|