@thzero/library_server 0.15.31 → 0.15.32

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 CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # library_server
6
6
 
7
- An opinionated library of common functionality to bootstrap a Koa based API application using MongoDb and Firebase.
7
+ An opinionated library of common functionality to bootstrap an API application using MongoDb and Firebase. Currently either Fastify or Koa can be used as the web server; Fastify will be the focus going forward due to lack of support and updates with the Koa stack.
8
8
 
9
9
  ### Installation
10
10
 
package/boot/index.js CHANGED
@@ -1,4 +1,3 @@
1
- import http from 'http';
2
1
  import {internalIpV6, internalIpV4} from '@thzero/library_server/utility/internalIp';
3
2
 
4
3
  import { createTerminus } from '@godaddy/terminus';
@@ -54,15 +53,14 @@ class BootMain {
54
53
 
55
54
  const plugins = this._determinePlugins(args);
56
55
  await await this._initPlugins(plugins);
57
-
58
- const app = await this._initApp(args, plugins);
59
-
56
+
60
57
  this.port = this._appConfig.get('port');
61
58
  this.loggerServiceI.info2(`config.port: ${this.port}`);
62
59
  this.loggerServiceI.info2(`process.env.PORT: ${process.env.PORT}`);
63
60
  this.port = process.env.PORT || this.port;
64
61
  this.loggerServiceI.info2(`selected.port: ${this.port}`);
65
- const serverHttp = http.createServer(app.callback());
62
+
63
+ const results = await this._initApp(args, plugins);
66
64
 
67
65
  function onSignal() {
68
66
  this.loggerServiceI.info2(`server is starting cleanup`);
@@ -108,10 +106,11 @@ class BootMain {
108
106
  onShutdown: onShutdown.bind(this) // [optional] called right before exiting
109
107
  };
110
108
 
111
- createTerminus(serverHttp, terminusOptions);
109
+ createTerminus(results.server, terminusOptions);
112
110
 
111
+ const self = this;
113
112
  const listen = async (port) => new Promise((resolve, reject) => {
114
- serverHttp.listen(port, (err) => {
113
+ self._initAppListen(results.app, results.server, port, (err) => {
115
114
  if (err) {
116
115
  reject(err);
117
116
  return;
@@ -121,20 +120,20 @@ class BootMain {
121
120
  });
122
121
  });
123
122
  await listen(this.port);
124
- this.address = serverHttp.address() ? serverHttp.address().address : null;
123
+ this.address = results.server.address() ? results.server.address().address : null;
125
124
  if (this.address === '::')
126
125
  this.address = await internalIpV4();
127
126
 
128
- await this._initServer(serverHttp);
127
+ await this._initServer(results.server);
129
128
 
130
129
  for (const [key, value] of this._servicesPost) {
131
130
  console.log(`services.init.post - ${key}`);
132
131
  if (value.initPost)
133
132
  await value.initPost();
134
133
  }
135
- this._initAppPost(app, args);
134
+ this._initAppPost(results.app, args);
136
135
 
137
- await this._initServerDiscovery(serverHttp);
136
+ await this._initServerDiscovery(results.server);
138
137
 
139
138
  this.loggerServiceI.info2(`Starting HTTP on: `, this.address);
140
139
  }
@@ -143,6 +142,10 @@ class BootMain {
143
142
  throw new NotImplementedError();
144
143
  }
145
144
 
145
+ _initAppListen(app, server, port, err) {
146
+ throw new NotImplementedError();
147
+ }
148
+
146
149
  async _initAppPost(app, args) {
147
150
  }
148
151
 
@@ -1,10 +1,9 @@
1
1
  import LibraryConstants from '../../constants';
2
2
  import LibraryCommonServiceConstants from '@thzero/library_common_service/constants';
3
3
 
4
- import BootPlugin from './index';
4
+ import NotImplementedError from '@thzero/library_common/errors/notImplemented';
5
5
 
6
- import homeRoute from '../../routes/home';
7
- import versionRoute from '../../routes/version';
6
+ import BootPlugin from './index';
8
7
 
9
8
  import cryptoService from '../../service/crypto';
10
9
  import versionService from '../../service/version';
@@ -31,11 +30,11 @@ class ApiBootPlugin extends BootPlugin {
31
30
  }
32
31
 
33
32
  _initRoutesHome() {
34
- return new homeRoute();
33
+ throw NotImplementedError();
35
34
  }
36
35
 
37
36
  _initRoutesVersion() {
38
- return new versionRoute();
37
+ throw NotImplementedError();
39
38
  }
40
39
 
41
40
  _initServicesCrypto() {
@@ -1,8 +1,8 @@
1
1
  import LibraryConstants from '../../constants';
2
2
 
3
- import ApiBootPlugin from './api';
3
+ import NotImplementedError from '@thzero/library_common/errors/notImplemented';
4
4
 
5
- import utilityRoute from '../../routes/utility';
5
+ import ApiBootPlugin from './api';
6
6
 
7
7
  import utilityService from '../../service/utility';
8
8
 
@@ -20,7 +20,7 @@ class FrontApiBootPlugin extends ApiBootPlugin {
20
20
  }
21
21
 
22
22
  _initRoutesUtility() {
23
- return new utilityRoute();
23
+ throw NotImplementedError();
24
24
  }
25
25
 
26
26
  _initServicesUtility() {
@@ -2,7 +2,6 @@ class BootPlugin {
2
2
  async init(config, injector) {
3
3
  this._config = config;
4
4
  this._injector = injector;
5
-
6
5
  }
7
6
 
8
7
  async initRoutes(routes) {
@@ -4,8 +4,6 @@ import NotImplementedError from '@thzero/library_common/errors/notImplemented';
4
4
 
5
5
  import BootPlugin from './index';
6
6
 
7
- import newsRoute from '../../routes/news';
8
-
9
7
  class NewsApiBootPlugin extends BootPlugin {
10
8
  async _initRoutes() {
11
9
  await super._initRoutes();
@@ -31,7 +29,7 @@ class NewsApiBootPlugin extends BootPlugin {
31
29
  }
32
30
 
33
31
  _initRoutesNews() {
34
- return new newsRoute();
32
+ throw NotImplementedError();
35
33
  }
36
34
 
37
35
  _initServicesNews() {
@@ -4,8 +4,6 @@ import NotImplementedError from '@thzero/library_common/errors/notImplemented';
4
4
 
5
5
  import BootPlugin from './index';
6
6
 
7
- import usersRoute from '../../routes/users';
8
-
9
7
  class UsersApiBootPlugin extends BootPlugin {
10
8
  async _initRoutes() {
11
9
  await super._initRoutes();
@@ -33,7 +31,7 @@ class UsersApiBootPlugin extends BootPlugin {
33
31
  }
34
32
 
35
33
  _initRoutesUsers() {
36
- return new usersRoute();
34
+ throw NotImplementedError();
37
35
  }
38
36
 
39
37
  _initServicesAuth() {
@@ -4,8 +4,6 @@ import NotImplementedError from '@thzero/library_common/errors/notImplemented';
4
4
 
5
5
  import UsersApiBootPlugin from './users';
6
6
 
7
- import plansService from '../../service/plans';
8
-
9
7
  class ExtendedUsersApiBootPlugin extends UsersApiBootPlugin {
10
8
  async _initRepositories() {
11
9
  await super._initRepositories();
@@ -25,7 +23,7 @@ class ExtendedUsersApiBootPlugin extends UsersApiBootPlugin {
25
23
  }
26
24
 
27
25
  _initServicesPlans() {
28
- return new plansService();
26
+ throw NotImplementedError();
29
27
  }
30
28
  }
31
29
 
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@thzero/library_server",
3
3
  "type": "module",
4
- "version": "0.15.31",
4
+ "version": "0.15.32",
5
5
  "version_major": 0,
6
6
  "version_minor": 15,
7
- "version_patch": 31,
8
- "version_date": "04/17/2022",
9
- "description": "An opinionated library of common functionality to bootstrap a Koa based API application using MongoDb and Firebase.",
7
+ "version_patch": 32,
8
+ "version_date": "04/18/2022",
9
+ "description": "An opinionated library of common functionality to bootstrap an API application using MongoDb and Firebase. Currently either Fastify or Koa can be used as the web server.",
10
10
  "author": "thZero",
11
11
  "license": "MIT",
12
12
  "repository": {
@@ -27,17 +27,11 @@
27
27
  },
28
28
  "dependencies": {
29
29
  "@godaddy/terminus": "^4.10.2",
30
- "@koa/cors": "^3.3.0",
31
- "@koa/router": "^10.1.1",
32
30
  "async-mutex": "^0.3.2",
33
31
  "config": "^3.3.7",
34
32
  "default-gateway": "^6.0.3",
35
33
  "easy-rbac": "^3.2.0",
36
- "ipaddr.js": "^2.0.1",
37
- "koa": "^2.13.4",
38
- "koa-body": "^4.2.0",
39
- "koa-helmet": "^6.1.0",
40
- "koa-static": "^5.0.0"
34
+ "ipaddr.js": "^2.0.1"
41
35
  },
42
36
  "devDependencies": {
43
37
  "@thzero/library_cli": "^0.15"
package/routes/index.js CHANGED
@@ -1,10 +1,9 @@
1
- import koaRouter from '@koa/router';
2
-
3
1
  class BaseRoute {
4
2
  constructor(prefix) {
5
3
  if (prefix === null || prefix === undefined)
6
4
  throw Error('Invalid prefix');
7
5
 
6
+ this.app = null;
8
7
  this._prefix = prefix;
9
8
  }
10
9
 
@@ -16,14 +15,15 @@ class BaseRoute {
16
15
  return this._router;
17
16
  }
18
17
 
19
- async init(injector, config) {
18
+ async init(injector, app, config) {
20
19
  if (!injector)
21
20
  throw Error('Invalid injector for route.');
22
21
  if (!config)
23
- throw Error('Invalid injector for route.');
22
+ throw Error('Invalid config for route.');
24
23
  if (this._prefix === null || this._prefix === undefined)
25
24
  throw Error('Invalid prefix for route.');
26
25
 
26
+ this.app = app;
27
27
  this._injector = injector;
28
28
 
29
29
  const api = config.get('api', { });
@@ -48,21 +48,17 @@ class BaseRoute {
48
48
 
49
49
  this._prefix = prefix + this._prefix;
50
50
 
51
- this._router = new koaRouter({
52
- prefix: this._prefix
53
- });
51
+ this._router = this._initializeRouter(app, config);
52
+ if (this._router === null || this._router === undefined)
53
+ throw Error('Invalid router.');
54
54
 
55
55
  this._initializeRoutes(this._router);
56
56
 
57
57
  return this._router;
58
58
  }
59
59
 
60
- _jsonResponse(ctx, json) {
61
- if (!ctx)
62
- throw Error('Invalid context for response.');
63
-
64
- ctx.type = 'application/json; charset=utf-8';
65
- ctx.body = json;
60
+ _initializeRouter(app, config) {
61
+ return null;
66
62
  }
67
63
 
68
64
  _initializeRoutes(router) {
@@ -17,12 +17,12 @@ class UsageMetricsService extends Service {
17
17
  this._repositoryUsageMetricsI = this._injector.getService(LibraryConstants.InjectorKeys.REPOSITORY_USAGE_METRIC);
18
18
  }
19
19
 
20
- async register(context, err) {
20
+ async register(usageMetrics, err) {
21
21
  try {
22
- if (!context)
22
+ if (!usageMetrics)
23
23
  return;
24
24
 
25
- const url = context.request.path;
25
+ const url = usageMetrics.url;
26
26
  if (!String.isNullOrEmpty(url)) {
27
27
  for (const ignore of this._ignore) {
28
28
  if (url === ignore)
@@ -30,16 +30,6 @@ class UsageMetricsService extends Service {
30
30
  }
31
31
  }
32
32
 
33
- const usageMetrics = {};
34
- usageMetrics.correlationId = context.correlationId;
35
- usageMetrics.href = context.request.href;
36
- usageMetrics.headers = context.request.headers;
37
- usageMetrics.host = context.request.host;
38
- usageMetrics.hostname = context.request.hostname;
39
- usageMetrics.querystring = context.request.querystring;
40
- usageMetrics.type = context.request.type;
41
- usageMetrics.token = context.request.token;
42
- usageMetrics.err = err;
43
33
  await this._repositoryUsageMetrics.register(usageMetrics);
44
34
  return this._success(usageMetrics.correlationId);
45
35
  }
package/boot/koa/index.js DELETED
@@ -1,164 +0,0 @@
1
- import Koa from 'koa';
2
- import koaCors from '@koa/cors';
3
- import koaHelmet from 'koa-helmet';
4
- import koaStatic from 'koa-static';
5
-
6
- import LibraryConstants from '../../constants';
7
- import Utility from '@thzero/library_common/utility';
8
-
9
- import TokenExpiredError from '../../errors/tokenExpired';
10
-
11
- import injector from '@thzero/library_common/utility/injector';
12
-
13
- import BootMain from '@thzero/library_server/boot';
14
-
15
- const ResponseTime = 'X-Response-Time';
16
-
17
- class KoaBootMain extends BootMain {
18
- async _initApp(args, plugins) {
19
- const app = new Koa();
20
- // https://github.com/koajs/cors
21
- app.use(koaCors({
22
- allowMethods: 'GET,POST,DELETE',
23
- maxAge : 7200,
24
- allowHeaders: `${LibraryConstants.Headers.AuthKeys.API}, ${LibraryConstants.Headers.AuthKeys.AUTH}, ${LibraryConstants.Headers.CorrelationId}, Content-Type`,
25
- credentials: true,
26
- origin: '*'
27
- }));
28
- // https://www.npmjs.com/package/koa-helmet
29
- app.use(koaHelmet());
30
-
31
- // error
32
- app.use(async (ctx, next) => {
33
- try {
34
- await next();
35
- }
36
- catch (err) {
37
- ctx.status = err.status || 500;
38
- if (err instanceof TokenExpiredError) {
39
- ctx.status = 401;
40
- ctx.response.header['WWW-Authenticate'] = 'Bearer error="invalid_token", error_description="The access token expired"'
41
- }
42
- ctx.app.emit('error', err, ctx);
43
- await this.usageMetricsServiceI.register(ctx, err).catch(() => {
44
- this.loggerServiceI.exception('KoaBootMain', 'start', err);
45
- });
46
- }
47
- });
48
-
49
- app.on('error', (err, ctx) => {
50
- this.loggerServiceI.error('KoaBootMain', 'start', 'Uncaught Exception', err);
51
- });
52
-
53
- // config
54
- app.use(async (ctx, next) => {
55
- ctx.config = this._appConfig;
56
- await next();
57
- });
58
-
59
- // correlationId
60
- app.use(async (ctx, next) => {
61
- ctx.correlationId = ctx.request.header[LibraryConstants.Headers.CorrelationId]
62
- await next();
63
- });
64
-
65
- // logger
66
- app.use(async (ctx, next) => {
67
- await next();
68
- const rt = ctx.response.get(ResponseTime);
69
- this.loggerServiceI.info2(`${ctx.method} ${ctx.url} - ${rt}`);
70
- });
71
-
72
- // x-response-time
73
- app.use(async (ctx, next) => {
74
- const start = Utility.timerStart();
75
- await next();
76
- const delta = Utility.timerStop(start, true);
77
- ctx.set(ResponseTime, delta);
78
- });
79
-
80
- app.use(koaStatic('./public'));
81
-
82
- this._initPreAuth(app);
83
-
84
- // auth-api-token
85
- app.use(async (ctx, next) => {
86
- if (ctx.originalUrl === '/favicon.ico') {
87
- await next();
88
- return;
89
- }
90
-
91
- const key = ctx.get(LibraryConstants.Headers.AuthKeys.API);
92
- // this.loggerServiceI.debug('KoaBootMain', 'start', 'auth-api-token.key', key);
93
- if (!String.isNullOrEmpty(key)) {
94
- const auth = ctx.config.get('auth');
95
- if (auth) {
96
- const apiKey = auth.apiKey;
97
- // this.loggerServiceI.debug('KoaBootMain', 'start', 'auth-api-token.apiKey', apiKey);
98
- // this.loggerServiceI.debug('KoaBootMain', 'start', 'auth-api-token.key===apiKey', (key === apiKey));
99
- if (key === apiKey) {
100
- ctx.state.apiKey = key;
101
- await next();
102
- return;
103
- }
104
- }
105
- }
106
-
107
- (async () => {
108
- await this.usageMetricsServiceI.register(ctx).catch((err) => {
109
- this.loggerServiceI.error('KoaBootMain', 'start', 'usageMetrics', err);
110
- });
111
- })();
112
-
113
- console.log('Unauthorized... auth-api-token failure');
114
- ctx.throw(401);
115
- });
116
-
117
- this._initPostAuth(app);
118
-
119
- // usage metrics
120
- app.use(async (ctx, next) => {
121
- await next();
122
- await this.usageMetricsServiceI.register(ctx).catch((err) => {
123
- this.loggerServiceI.error('KoaBootMain', 'start', 'usageMetrics', err);
124
- });
125
- });
126
-
127
- this._routes = [];
128
-
129
- this._initPreRoutes(app);
130
-
131
- for (const pluginRoute of plugins)
132
- await pluginRoute.initRoutes(this._routes);
133
-
134
- await this._initRoutes();
135
-
136
- console.log();
137
-
138
- for (const route of this._routes) {
139
- await route.init(injector, this._appConfig);
140
- app
141
- .use(route.router.routes())
142
- .use(route.router.allowedMethods());
143
-
144
- console.log([ route.id ]);
145
-
146
- for (let i = 0; i < route.router.stack.length; i++)
147
- console.log([ route.router.stack[i].path, route.router.stack[i].methods ]);
148
-
149
- console.log();
150
- }
151
-
152
- return app;
153
- }
154
-
155
- async _initAppPost(app, args) {
156
- this._initPostRoutes(app);
157
- }
158
-
159
- _initRoute(route) {
160
- this._routes.push(route);
161
- }
162
- }
163
-
164
- export default KoaBootMain;
@@ -1,67 +0,0 @@
1
- import LibraryConstants from '../constants';
2
- import LibraryCommonServiceConstants from '@thzero/library_common_service/constants';
3
-
4
- import injector from '@thzero/library_common/utility/injector';
5
-
6
- const separator = ': ';
7
-
8
- function getAuthToken(context) {
9
- if (!context)
10
- return null;
11
-
12
- const logger = injector.getService(LibraryCommonServiceConstants.InjectorKeys.SERVICE_LOGGER);
13
- const token = context.get(LibraryConstants.Headers.AuthKeys.AUTH);
14
- logger.debug('middleware', 'getAuthToken', 'token', token, context.correlationId);
15
- const split = token.split(LibraryConstants.Headers.AuthKeys.AUTH_BEARER + separator);
16
- logger.debug('middleware', 'getAuthToken', 'split', split, context.correlationId);
17
- logger.debug('middleware', 'getAuthToken', 'split.length', split.length, context.correlationId);
18
- if (split.length > 1)
19
- return split[1];
20
-
21
- logger.debug('middleware', 'getAuthToken', 'fail', null, context.correlationId);
22
- return null;
23
- }
24
-
25
- const authentication = (required) => {
26
- return async (ctx, next) => {
27
- const logger = injector.getService(LibraryCommonServiceConstants.InjectorKeys.SERVICE_LOGGER);
28
-
29
- const token = getAuthToken(ctx);
30
- logger.debug('middleware', 'authentication', 'token', token, ctx.correlationId);
31
- logger.debug('middleware', 'authentication', 'required', required, ctx.correlationId);
32
- const valid = ((required && !String.isNullOrEmpty(token)) || !required);
33
- logger.debug('middleware', 'authentication', 'valid', valid, ctx.correlationId);
34
- if (valid) {
35
- if (!String.isNullOrEmpty(token)) {
36
- const service = injector.getService(LibraryConstants.InjectorKeys.SERVICE_AUTH);
37
- const results = await service.verifyToken(ctx.correlationId, token);
38
- logger.debug('middleware', 'authentication', 'results', results, ctx.correlationId);
39
- if (!results || !results.success) {
40
- logger.warn('middleware', 'authentication', 'Unauthenticated... invalid token', null, ctx.correlationId);
41
- ctx.throw(401);
42
- return;
43
- }
44
-
45
- ctx.state.token = token;
46
- ctx.state.user = results.user;
47
- ctx.state.claims = results.claims;
48
- }
49
-
50
- await next();
51
- return;
52
- }
53
-
54
- (async () => {
55
- const usageMetrics = injector.getService(LibraryConstants.InjectorKeys.SERVICE_USAGE_METRIC);
56
- await usageMetrics.register(ctx).catch((err) => {
57
- const logger = injector.getService(LibraryCommonServiceConstants.InjectorKeys.SERVICE_LOGGER);
58
- logger.error('middleware', 'authentication', err, null, ctx.correlationId);
59
- });
60
- })();
61
-
62
- logger.warn('middleware', 'authentication', 'Unauthorized... authentication unknown', null, ctx.correlationId);
63
- ctx.throw(401);
64
- }
65
- }
66
-
67
- export default authentication;
@@ -1,180 +0,0 @@
1
- import LibraryConstants from '../constants';
2
- import LibraryCommonServiceConstants from '@thzero/library_common_service/constants';
3
-
4
- import injector from '@thzero/library_common/utility/injector';
5
-
6
- // require('../utility/string.cjs');
7
- String.isNullOrEmpty = function(value) {
8
- //return !(typeof value === 'string' && value.length > 0)
9
- return !value;
10
- }
11
-
12
- String.isString = function(value) {
13
- return (typeof value === "string" || value instanceof String);
14
- }
15
-
16
- String.trim = function(value) {
17
- if (!value || !String.isString(value))
18
- return value;
19
- return value.trim();
20
- }
21
-
22
- const logicalAnd = 'and';
23
- const logicalOr = 'or';
24
-
25
- const authorizationCheckClaims = async (ctx, success, logical, security, logger) => {
26
- if (!ctx)
27
- return false;
28
- if (!(ctx.state.claims && Array.isArray(ctx.state.claims)))
29
- return false;
30
-
31
- let result;
32
- let roleAct;
33
- let roleObj;
34
- let roleParts;
35
- for (const claim of ctx.state.claims) {
36
- logger.debug('middleware', 'authorization', 'authorization.claim', claim, ctx.correlationId);
37
-
38
- for (const role of ctx.state.roles) {
39
- logger.debug('middleware', 'authorization', 'role', role, ctx.correlationId);
40
-
41
- roleParts = role.split('.');
42
- if (roleParts && roleParts.length < 1)
43
- success = false;
44
-
45
- roleObj = roleParts[0];
46
- roleAct = roleParts.length >= 2 ? roleParts[1] : null
47
-
48
- result = await security.validate(claim, null, roleObj, roleAct);
49
- logger.debug('middleware', 'authorization', 'result', result, ctx.correlationId);
50
- if (logical === logicalOr)
51
- success = success || result;
52
- else
53
- success = success && result;
54
- }
55
- }
56
-
57
- return success;
58
- }
59
-
60
- const authorizationCheckRoles = async (ctx, success, logical, security, logger) => {
61
- if (!ctx)
62
- return false;
63
-
64
- logger.debug('middleware', 'authorizationCheckRoles', 'user', ctx.state.user, ctx.correlationId);
65
- if (!(ctx.state.user && ctx.state.user.roles && Array.isArray(ctx.state.user.roles)))
66
- return false;
67
-
68
- logger.debug('middleware', 'authorizationCheckRoles', 'logical', logical, ctx.correlationId);
69
-
70
- let result;
71
- let roleAct;
72
- let roleObj;
73
- let roleParts;
74
- for (const userRole of ctx.state.user.roles) {
75
- logger.debug('middleware', 'authorizationCheckRoles', 'userRole', userRole, ctx.correlationId);
76
-
77
- for (const role of ctx.state.roles) {
78
- logger.debug('middleware', 'authorizationCheckRoles', 'role', role, ctx.correlationId);
79
-
80
- roleParts = role.split('.');
81
- if (roleParts && roleParts.length < 1)
82
- success = false;
83
-
84
- roleObj = roleParts[0];
85
- roleAct = roleParts.length >= 2 ? roleParts[1] : null
86
-
87
- result = await security.validate(userRole, null, roleObj, roleAct);
88
- logger.debug('middleware', 'authorizationCheckRoles', 'result', result, ctx.correlationId);
89
- if (logical === logicalOr) {
90
- if (result)
91
- return result;
92
-
93
- success = false;
94
- }
95
- else
96
- success = success && result;
97
- }
98
- }
99
-
100
- return success;
101
- }
102
-
103
- const initalizeRoles = (ctx, roles, logger) => {
104
- if (Array.isArray(roles)) {
105
- // logger.debug('middleware', 'initalizeRoles', 'roles1a', roles);
106
- ctx.state.roles = roles;
107
- }
108
- else if ((typeof(roles) === 'string') || (roles instanceof String)) {
109
- // logger.debug('middleware', 'initalizeRoles', 'roles1b', roles);
110
- ctx.state.roles = roles.split(',');
111
- ctx.state.roles.map(item => item ? item.trim() : item);
112
- }
113
- }
114
-
115
- const authorization = (roles, logical) => {
116
- if (String.isNullOrEmpty(logical) || (logical !== logicalAnd) || (logical !== logicalOr))
117
- logical = logicalOr;
118
-
119
- return async (ctx, next) => {
120
- const config = injector.getService(LibraryCommonServiceConstants.InjectorKeys.SERVICE_CONFIG);
121
- const logger = injector.getService(LibraryCommonServiceConstants.InjectorKeys.SERVICE_LOGGER);
122
- const security = injector.getService(LibraryConstants.InjectorKeys.SERVICE_SECURITY);
123
-
124
- // logger.debug('token', ctx.state.token);
125
- logger.debug('middleware', 'authorization', 'user', ctx.state.user, ctx.correlationId);
126
- logger.debug('middleware', 'authorization', 'claims', ctx.state.claims, ctx.correlationId);
127
- logger.debug('middleware', 'authorization', 'roles1', roles, ctx.correlationId);
128
- ctx.state.roles = [];
129
- if (roles) {
130
- // logger.debug('authorization.roles1', roles);
131
- // logger.debug('authorization.roles1', (typeof roles));
132
- // logger.debug('authorization.roles1', Array.isArray(roles));
133
- // logger.debug('authorization.roles1', ((typeof(roles) === 'string') || (roles instanceof String)));
134
- // if (Array.isArray(roles)) {
135
- // // logger.debug('authorization.roles1a', roles);
136
- // ctx.state.roles = roles;
137
- // }
138
- // else if ((typeof(roles) === 'string') || (roles instanceof String)) {
139
- // // logger.debug('authorization.roles1b', roles);
140
- // ctx.state.roles = roles.split(',');
141
- // ctx.state.roles.map(item => item ? item.trim() : item);
142
- // }
143
- initalizeRoles(ctx, roles, logger);
144
- }
145
- logger.debug('middleware', 'authorization', 'roles2', ctx.state.roles, ctx.correlationId);
146
-
147
- let success = false; //(logical === logicalOr ? false : true);
148
- if (ctx.state.roles && Array.isArray(ctx.state.roles) && (ctx.state.roles.length > 0)) {
149
- const auth = config.get('auth');
150
- if (auth) {
151
- logger.debug('middleware', 'authorization', 'auth.claims', auth.claims, ctx.correlationId);
152
- logger.debug('middleware', 'authorization', 'auth.claims.check', auth.claims.check, ctx.correlationId);
153
- }
154
- if (auth && auth.claims && auth.claims.check)
155
- success = await authorizationCheckClaims(ctx, (logical === logicalOr ? false : true), logical, security, logger);
156
-
157
- if (!success)
158
- success = await authorizationCheckRoles(ctx, (logical === logicalOr ? false : true), logical, security, logger);
159
- }
160
-
161
- logger.debug('middleware', 'authorization', 'success', null, ctx.state.success, ctx.correlationId);
162
- if (success) {
163
- await next();
164
- return;
165
- }
166
-
167
- (async () => {
168
- const usageMetrics = injector.getService(LibraryConstants.InjectorKeys.SERVICE_USAGE_METRIC);
169
- await usageMetrics.register(ctx).catch((err) => {
170
- const logger = injector.getService(LibraryCommonServiceConstants.InjectorKeys.SERVICE_LOGGER);
171
- logger.error(null, err);
172
- });
173
- })();
174
-
175
- logger.warn('middleware', 'authorization', 'Unauthorized... authorization unknown', null, ctx.correlationId);
176
- ctx.throw(401);
177
- }
178
- }
179
-
180
- export default authorization;
@@ -1,123 +0,0 @@
1
- import koaBody from 'koa-body';
2
-
3
- import Utility from '@thzero/library_common/utility';
4
-
5
- import BaseRoute from '../index';
6
-
7
- import authentication from '../../middleware/authentication';
8
- import authorization from '../../middleware/authorization';
9
-
10
- class AdminBaseRoute extends BaseRoute {
11
- constructor(urlFragment, role, serviceKey) {
12
- if (!urlFragment)
13
- throw Error('Invalid url fragment');
14
-
15
- super(`/admin/${urlFragment}`);
16
-
17
- this._options = {
18
- role: role,
19
- serviceKey: serviceKey
20
- }
21
-
22
- // this._service = null;
23
- }
24
-
25
- async init(injector, config) {
26
- const router = await super.init(injector, config);
27
- router.service = injector.getService(this._options.serviceKey);
28
- // this._service = injector.getService(this._options.serviceKey);
29
- }
30
-
31
- _allowsCreate() {
32
- return true;
33
- }
34
-
35
- _allowsDelete() {
36
- return true;
37
- }
38
-
39
- _allowsUpdate() {
40
- return true;
41
- }
42
-
43
- _initializeRoutesCreate(router) {
44
- const self = this;
45
- router.post('/',
46
- authentication(true),
47
- authorization([ `${self._options.role}.create` ]),
48
- koaBody({
49
- text: false,
50
- }),
51
- // eslint-disable-next-line
52
- async (ctx, next) => {
53
- // const service = this._injector.getService(this._options.serviceKey);
54
- // const response = (await router.service.create(ctx.correlationId, ctx.state.user, ctx.request.body)).check(ctx);
55
- const response = (await ctx.router.service.create(ctx.correlationId, ctx.state.user, ctx.request.body)).check(ctx);
56
- this._jsonResponse(ctx, Utility.stringify(response));
57
- }
58
- );
59
- }
60
-
61
- _initializeRoutesDelete(router) {
62
- const self = this;
63
- router.delete('/:id',
64
- authentication(true),
65
- authorization([ `${self._options.role}.delete` ]),
66
- // eslint-disable-next-line
67
- async (ctx, next) => {
68
- // const service = this._injector.getService(this._options.serviceKey);
69
- // const response = (await service.delete(ctx.correlationId, ctx.state.user, ctx.params.id)).check(ctx);
70
- const response = (await ctx.router.service.delete(ctx.correlationId, ctx.state.user, ctx.params.id)).check(ctx);
71
- this._jsonResponse(ctx, Utility.stringify(response));
72
- }
73
- );
74
- }
75
-
76
- _initializeRoutesUpdate(router) {
77
- const self = this;
78
- router.post('/:id',
79
- authentication(true),
80
- authorization([ `${self._options.role}.update` ]),
81
- koaBody({
82
- text: false,
83
- }),
84
- // eslint-disable-next-line
85
- async (ctx, next) => {
86
- // const service = this._injector.getService(this._options.serviceKey);
87
- // const response = (await service.update(ctx.correlationId, ctx.state.user, ctx.params.id, ctx.request.body)).check(ctx);
88
- const response = (await ctx.router.service.update(ctx.correlationId, ctx.state.user, ctx.params.id, ctx.request.body)).check(ctx);
89
- this._jsonResponse(ctx, Utility.stringify(response));
90
- }
91
- );
92
- }
93
-
94
- _initializeRoutes(router) {
95
- if (this._allowsDelete)
96
- this._initializeRoutesDelete(router);
97
-
98
- router.post('/search',
99
- authentication(true),
100
- authorization([ `${this._options.role}.search` ]),
101
- koaBody({
102
- text: false,
103
- }),
104
- // eslint-disable-next-line
105
- async (ctx, next) => {
106
- // const service = this._injector.getService(this._options.serviceKey);
107
- // const response = (await service.search(ctx.correlationId, ctx.state.user, ctx.request.body)).check(ctx);
108
- const response = (await ctx.router.service.search(ctx.correlationId, ctx.state.user, ctx.request.body)).check(ctx);
109
- this._jsonResponse(ctx, Utility.stringify(response));
110
- }
111
- );
112
-
113
- if (this._allowsUpdate())
114
- this._initializeRoutesUpdate(router);
115
-
116
- if (this._allowsCreate())
117
- this._initializeRoutesCreate(router);
118
-
119
- return router;
120
- }
121
- }
122
-
123
- export default AdminBaseRoute;
@@ -1,22 +0,0 @@
1
- import LibraryConstants from '../../constants';
2
-
3
- import AdminRoute from './index'
4
-
5
- class NewsAdminRoute extends AdminRoute {
6
- constructor(urlFragment, role, serviceKey) {
7
- urlFragment = urlFragment ? urlFragment : 'news';
8
- role = role ? role : 'news';
9
- serviceKey = serviceKey ? serviceKey : LibraryConstants.InjectorKeys.SERVICE_ADMIN_NEWS;
10
- super(urlFragment, role, serviceKey);
11
- }
12
-
13
- get id() {
14
- return 'admin-news';
15
- }
16
-
17
- get _version() {
18
- return 'v1';
19
- }
20
- }
21
-
22
- export default NewsAdminRoute;
@@ -1,26 +0,0 @@
1
- import LibraryConstants from '../../constants';
2
-
3
- import AdminRoute from './index'
4
-
5
- class UsersAdminRoute extends AdminRoute {
6
- constructor(urlFragment, role, serviceKey) {
7
- urlFragment = urlFragment ? urlFragment : 'users';
8
- role = role ? role : 'users';
9
- serviceKey = serviceKey ? serviceKey : LibraryConstants.InjectorKeys.SERVICE_ADMIN_USERS;
10
- super(urlFragment, role, serviceKey);
11
- }
12
-
13
- get id() {
14
- return 'admin-users';
15
- }
16
-
17
- _allowsCreate() {
18
- return false;
19
- }
20
-
21
- get _version() {
22
- return 'v1';
23
- }
24
- }
25
-
26
- export default UsersAdminRoute;
@@ -1,40 +0,0 @@
1
- import LibraryConstants from '../constants';
2
-
3
- import Utility from '@thzero/library_common/utility';
4
-
5
- import BaseRoute from './index';
6
-
7
- import authentication from '../middleware/authentication';
8
-
9
- class BaseNewsRoute extends BaseRoute {
10
- constructor(prefix, version) {
11
- super(prefix ? prefix : '/news');
12
-
13
- // this._serviceNews = null;
14
- }
15
-
16
- async init(injector, config) {
17
- const router = await super.init(injector, config);
18
- router.serviceNews = injector.getService(LibraryConstants.InjectorKeys.SERVICE_NEWS);
19
- // this._serviceNews = injector.getService(LibraryConstants.InjectorKeys.SERVICE_NEWS);
20
- }
21
-
22
- get id() {
23
- return 'news';
24
- }
25
-
26
- _initializeRoutes(router) {
27
- router.get('/latest/:date',
28
- authentication(false),
29
- // eslint-disable-next-line
30
- async (ctx, next) => {
31
- // const service = this._injector.getService(LibraryConstants.InjectorKeys.SERVICE_NEWS);
32
- // const response = (await service.latest(ctx.correlationId, ctx.state.user, parseInt(ctx.params.date))).check(ctx);
33
- const response = (await ctx.router.serviceNews.latest(ctx.correlationId, ctx.state.user, parseInt(ctx.params.date))).check(ctx);
34
- this._jsonResponse(ctx, Utility.stringify(response));
35
- }
36
- );
37
- }
38
- }
39
-
40
- export default BaseNewsRoute;
@@ -1,123 +0,0 @@
1
- import koaBody from 'koa-body';
2
-
3
- import LibraryConstants from '../constants';
4
-
5
- import Utility from '@thzero/library_common/utility';
6
-
7
- import BaseRoute from './index';
8
-
9
- import authentication from '../middleware/authentication';
10
- import authorization from '../middleware/authorization';
11
-
12
- class BaseUsersRoute extends BaseRoute {
13
- constructor(prefix, version) {
14
- super(prefix ? prefix : '/users');
15
-
16
- // this._serviceUsers = null;
17
- }
18
-
19
- async init(injector, config) {
20
- const router = await super.init(injector, config);
21
- router.serviceUsers = injector.getService(LibraryConstants.InjectorKeys.SERVICE_USERS);
22
- // this._serviceUsers = injector.getService(LibraryConstants.InjectorKeys.SERVICE_USERS);
23
- }
24
-
25
- get id() {
26
- return 'users';
27
- }
28
-
29
- _initializeRoutes(router) {
30
- this._initializeRoutesGamerById(router);
31
- this._initializeRoutesGamerByTag(router);
32
- this._initializeRoutesRefreshSettings(router);
33
- this._initializeRoutesUpdate(router);
34
- this._initializeRoutesUpdateSettings(router);
35
- }
36
-
37
- _initializeRoutesGamerById(router) {
38
- return router.get('/gamerId/:gamerId',
39
- authentication(false),
40
- // authorization('user'),
41
- koaBody({
42
- text: false,
43
- }),
44
- // eslint-disable-next-line
45
- async (ctx, next) => {
46
- // const service = this._injector.getService(LibraryConstants.InjectorKeys.SERVICE_USERS);
47
- // const response = (await service.fetchByGamerId(ctx.correlationId, ctx.params.gamerId)).check(ctx);
48
- const response = (await ctx.router.serviceUsers.fetchByGamerId(ctx.correlationId, ctx.params.gamerId)).check(ctx);
49
- this._jsonResponse(ctx, Utility.stringify(response));
50
- }
51
- );
52
- }
53
-
54
- _initializeRoutesGamerByTag(router) {
55
- return router.get('/gamerTag/:gamerTag',
56
- authentication(false),
57
- // authorization('user'),
58
- koaBody({
59
- text: false,
60
- }),
61
- // eslint-disable-next-line
62
- async (ctx, next) => {
63
- // const service = this._injector.getService(LibraryConstants.InjectorKeys.SERVICE_USERS);
64
- // const response = (await service.fetchByGamerTag(ctx.correlationId, ctx.params.gamerTag)).check(ctx);
65
- const response = (await ctx.router.serviceUsers.fetchByGamerTag(ctx.correlationId, ctx.params.gamerTag)).check(ctx);
66
- this._jsonResponse(ctx, Utility.stringify(response));
67
- }
68
- );
69
- }
70
-
71
- _initializeRoutesRefreshSettings(router) {
72
- return router.post('/refresh/settings',
73
- authentication(true),
74
- authorization('user'),
75
- koaBody({
76
- text: false,
77
- }),
78
- // eslint-disable-next-line
79
- async (ctx, next) => {
80
- // const service = this._injector.getService(LibraryConstants.InjectorKeys.SERVICE_USERS);
81
- // const response = (await service.refreshSettings(ctx.correlationId, ctx.request.body)).check(ctx);
82
- const response = (await ctx.router.serviceUsers.refreshSettings(ctx.correlationId, ctx.request.body)).check(ctx);
83
- this._jsonResponse(ctx, Utility.stringify(response));
84
- }
85
- );
86
- }
87
-
88
- _initializeRoutesUpdate(router) {
89
- return router.post('/update',
90
- authentication(true),
91
- authorization('user'),
92
- koaBody({
93
- text: false,
94
- }),
95
- // eslint-disable-next-line
96
- async (ctx, next) => {
97
- // const service = this._injector.getService(LibraryConstants.InjectorKeys.SERVICE_USERS);
98
- // const response = (await service.update(ctx.correlationId, ctx.request.body)).check(ctx);
99
- const response = (await ctx.router.serviceUsers.update(ctx.correlationId, ctx.request.body)).check(ctx);
100
- this._jsonResponse(ctx, Utility.stringify(response));
101
- }
102
- );
103
- }
104
-
105
- _initializeRoutesUpdateSettings(router) {
106
- return router.post('/update/settings',
107
- authentication(true),
108
- authorization('user'),
109
- koaBody({
110
- text: false,
111
- }),
112
- // eslint-disable-next-line
113
- async (ctx, next) => {
114
- // const service = this._injector.getService(LibraryConstants.InjectorKeys.SERVICE_USERS);
115
- // const response = (await service.updateSettings(ctx.correlationId, ctx.request.body)).check(ctx);
116
- const response = (await ctx.router.serviceUsers.updateSettings(ctx.correlationId, ctx.request.body)).check(ctx);
117
- this._jsonResponse(ctx, Utility.stringify(response));
118
- }
119
- );
120
- }
121
- }
122
-
123
- export default BaseUsersRoute;
package/routes/home.js DELETED
@@ -1,28 +0,0 @@
1
- import BaseRoute from './index';
2
-
3
- class HomeRoute extends BaseRoute {
4
- constructor(prefix) {
5
- super(prefix ? prefix : '');
6
- }
7
-
8
- get id() {
9
- return 'home';
10
- }
11
-
12
- _initializeRoutes(router) {
13
- // eslint-disable-next-line
14
- router.get('/', (ctx, next) => {
15
- ctx.status = 404;
16
- });
17
- }
18
-
19
- get _ignoreApi() {
20
- return true;
21
- }
22
-
23
- get _version() {
24
- return '';
25
- }
26
- }
27
-
28
- export default HomeRoute;
package/routes/news.js DELETED
@@ -1,6 +0,0 @@
1
- import BaseNewsRoute from './baseNews';
2
-
3
- class NewsRoute extends BaseNewsRoute {
4
- }
5
-
6
- export default NewsRoute;
package/routes/plans.js DELETED
@@ -1,41 +0,0 @@
1
- import LibraryConstants from '../constants';
2
-
3
- import Utility from '@thzero/library_common/utility';
4
-
5
- import BaseRoute from './index';
6
-
7
- class PlansRoute extends BaseRoute {
8
- constructor(prefix) {
9
- super(prefix ? prefix : '/plans');
10
-
11
- // this._servicePlans = null;
12
- }
13
-
14
- async init(injector, config) {
15
- const router = await super.init(injector, config);
16
- router.servicePlans = injector.getService(LibraryConstants.InjectorKeys.SERVICE_PLANS);
17
- // this._servicePlans = injector.getService(LibraryConstants.InjectorKeys.SERVICE_PLANS);
18
- }
19
-
20
- get id() {
21
- return 'plans';
22
- }
23
-
24
- _initializeRoutes(router) {
25
- router.get('/',
26
- // eslint-disable-next-line
27
- async (ctx, next) => {
28
- // const service = this._injector.getService(LibraryConstants.InjectorKeys.SERVICE_PLANS);
29
- // const response = (await service.servicePlans.listing(ctx.correlationId)).check(ctx);
30
- const response = (await ctx.router.servicePlans.listing(ctx.correlationId)).check(ctx);
31
- this._jsonResponse(ctx, Utility.stringify(response));
32
- }
33
- );
34
- }
35
-
36
- get _version() {
37
- return 'v1';
38
- }
39
- }
40
-
41
- export default PlansRoute;
package/routes/users.js DELETED
@@ -1,6 +0,0 @@
1
- import BaseUsersRoute from './baseUsers';
2
-
3
- class UsersRoute extends BaseUsersRoute {
4
- }
5
-
6
- export default UsersRoute;
package/routes/utility.js DELETED
@@ -1,51 +0,0 @@
1
- import koaBody from 'koa-body';
2
-
3
- import LibraryConstants from '../constants';
4
-
5
- import Utility from '@thzero/library_common/utility';
6
-
7
- import BaseRoute from './index';
8
-
9
- import authentication from '../middleware/authentication';
10
- // import authorization from '../middleware/authorization';
11
-
12
- class UtilityRoute extends BaseRoute {
13
- constructor(prefix) {
14
- super(prefix ? prefix : '/utility');
15
-
16
- // this._serviceUtility = null;
17
- }
18
-
19
- async init(injector, config) {
20
- const router = await super.init(injector, config);
21
- router.serviceUtility = injector.getService(LibraryConstants.InjectorKeys.SERVICE_UTILITY);
22
- // this._serviceUtility = injector.getService(LibraryConstants.InjectorKeys.SERVICE_UTILITY);
23
- }
24
-
25
- get id() {
26
- return 'utility';
27
- }
28
-
29
- _initializeRoutes(router) {
30
- router.post('/logger',
31
- authentication(false),
32
- // authorization('utility'),
33
- // eslint-disable-next-line,
34
- koaBody({
35
- text: false,
36
- }),
37
- async (ctx, next) => {
38
- // const service = this._injector.getService(LibraryConstants.InjectorKeys.SERVICE_UTILITY);
39
- // const response = (await service.logger(ctx.correlationId, ctx.request.body)).check(ctx);
40
- const response = (await ctx.router.serviceUtility.logger(ctx.correlationId, ctx.request.body)).check(ctx);
41
- this._jsonResponse(ctx, Utility.stringify(response));
42
- }
43
- );
44
- }
45
-
46
- get _version() {
47
- return 'v1';
48
- }
49
- }
50
-
51
- export default UtilityRoute;
package/routes/version.js DELETED
@@ -1,41 +0,0 @@
1
- import LibraryConstants from '../constants';
2
-
3
- import Utility from '@thzero/library_common/utility';
4
-
5
- import BaseRoute from './index';
6
-
7
- class VersionRoute extends BaseRoute {
8
- constructor(prefix) {
9
- super(prefix ? prefix : '');
10
-
11
- // this._serviceVersion = null;
12
- }
13
-
14
- async init(injector, config) {
15
- const router = await super.init(injector, config);
16
- router.serviceVersion = injector.getService(LibraryConstants.InjectorKeys.SERVICE_VERSION);
17
- // this._serviceVersion = injector.getService(LibraryConstants.InjectorKeys.SERVICE_VERSION);
18
- }
19
-
20
- get id() {
21
- return 'version';
22
- }
23
-
24
- _initializeRoutes(router) {
25
- router.get('/version',
26
- // eslint-disable-next-line
27
- async (ctx, next) => {
28
- // const service = this._injector.getService(LibraryConstants.InjectorKeys.SERVICE_VERSION);
29
- // const response = (await service.version(ctx.correlationId)).check(ctx);
30
- const response = (await ctx.router.serviceVersion.version(ctx.correlationId)).check(ctx);
31
- this._jsonResponse(ctx, Utility.stringify(response));
32
- }
33
- );
34
- }
35
-
36
- get _version() {
37
- return 'v1';
38
- }
39
- }
40
-
41
- export default VersionRoute;