@modular-rest/server 1.11.13 → 1.11.15

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.
Files changed (181) hide show
  1. package/.nvmrc +1 -0
  2. package/.prettierrc.json +9 -0
  3. package/.releaserc.json +24 -0
  4. package/README.md +79 -94
  5. package/dist/application.d.ts +29 -0
  6. package/dist/application.js +217 -0
  7. package/dist/class/cms_trigger.d.ts +52 -0
  8. package/dist/class/cms_trigger.js +47 -0
  9. package/dist/class/collection_definition.d.ts +112 -0
  10. package/dist/class/collection_definition.js +87 -0
  11. package/dist/class/combinator.d.ts +43 -0
  12. package/dist/class/combinator.js +174 -0
  13. package/dist/class/database_trigger.d.ts +90 -0
  14. package/dist/class/database_trigger.js +64 -0
  15. package/dist/class/db_schemas.d.ts +25 -0
  16. package/dist/class/db_schemas.js +28 -0
  17. package/dist/class/directory.d.ts +20 -0
  18. package/dist/class/directory.js +87 -0
  19. package/dist/class/paginator.d.ts +31 -0
  20. package/dist/class/paginator.js +43 -0
  21. package/dist/class/reply.d.ts +29 -0
  22. package/dist/class/reply.js +44 -0
  23. package/dist/class/security.d.ts +186 -0
  24. package/dist/class/security.js +178 -0
  25. package/dist/class/trigger_operator.d.ts +92 -0
  26. package/dist/class/trigger_operator.js +99 -0
  27. package/dist/class/user.d.ts +81 -0
  28. package/dist/class/user.js +151 -0
  29. package/dist/class/validator.d.ts +19 -0
  30. package/dist/class/validator.js +101 -0
  31. package/dist/config.d.ts +113 -0
  32. package/dist/config.js +26 -0
  33. package/dist/defult-permissions.d.ts +2 -0
  34. package/dist/defult-permissions.js +31 -0
  35. package/dist/events.d.ts +23 -0
  36. package/dist/events.js +47 -0
  37. package/dist/helper/data_insertion.d.ts +38 -0
  38. package/dist/helper/data_insertion.js +110 -0
  39. package/dist/helper/presetup_services.d.ts +60 -0
  40. package/dist/helper/presetup_services.js +108 -0
  41. package/dist/index.d.ts +118 -0
  42. package/dist/index.js +79 -0
  43. package/dist/middlewares.d.ts +53 -0
  44. package/dist/middlewares.js +106 -0
  45. package/dist/play-test.d.ts +1 -0
  46. package/dist/play-test.js +9 -0
  47. package/dist/services/data_provider/router.d.ts +4 -0
  48. package/dist/services/data_provider/router.js +412 -0
  49. package/dist/services/data_provider/service.d.ts +132 -0
  50. package/dist/services/data_provider/service.js +253 -0
  51. package/dist/services/data_provider/typeCasters.d.ts +9 -0
  52. package/dist/services/data_provider/typeCasters.js +18 -0
  53. package/dist/services/file/db.d.ts +1 -0
  54. package/dist/services/file/db.js +31 -0
  55. package/dist/services/file/router.d.ts +4 -0
  56. package/dist/services/file/router.js +115 -0
  57. package/dist/services/file/service.d.ts +204 -0
  58. package/dist/services/file/service.js +341 -0
  59. package/dist/services/functions/router.d.ts +4 -0
  60. package/dist/services/functions/router.js +68 -0
  61. package/dist/services/functions/service.d.ts +132 -0
  62. package/dist/services/functions/service.js +159 -0
  63. package/dist/services/jwt/router.d.ts +4 -0
  64. package/dist/services/jwt/router.js +99 -0
  65. package/dist/services/jwt/service.d.ts +97 -0
  66. package/dist/services/jwt/service.js +135 -0
  67. package/dist/services/user_manager/db.d.ts +1 -0
  68. package/dist/services/user_manager/db.js +75 -0
  69. package/dist/services/user_manager/permissionManager.d.ts +19 -0
  70. package/dist/services/user_manager/permissionManager.js +42 -0
  71. package/dist/services/user_manager/router.d.ts +4 -0
  72. package/dist/services/user_manager/router.js +195 -0
  73. package/dist/services/user_manager/service.d.ts +317 -0
  74. package/dist/services/user_manager/service.js +632 -0
  75. package/docs/.keep +0 -0
  76. package/docs/system-access-type.md +26 -0
  77. package/package.json +59 -46
  78. package/src/application.ts +206 -0
  79. package/src/class/cms_trigger.ts +62 -0
  80. package/src/class/collection_definition.ts +134 -0
  81. package/src/class/combinator.ts +176 -0
  82. package/src/class/database_trigger.ts +105 -0
  83. package/src/class/db_schemas.ts +44 -0
  84. package/src/class/{directory.js → directory.ts} +40 -18
  85. package/src/class/paginator.ts +51 -0
  86. package/src/class/reply.ts +59 -0
  87. package/src/class/security.ts +250 -0
  88. package/src/class/trigger_operator.ts +142 -0
  89. package/src/class/user.ts +199 -0
  90. package/src/class/validator.ts +123 -0
  91. package/src/config.ts +122 -0
  92. package/src/defult-permissions.ts +31 -0
  93. package/src/events.ts +59 -0
  94. package/src/helper/data_insertion.ts +94 -0
  95. package/src/helper/presetup_services.ts +96 -0
  96. package/src/index.ts +146 -0
  97. package/src/middlewares.ts +75 -0
  98. package/src/play-test.ts +8 -0
  99. package/src/services/data_provider/router.ts +484 -0
  100. package/src/services/data_provider/service.ts +306 -0
  101. package/src/services/data_provider/typeCasters.ts +15 -0
  102. package/src/services/file/db.ts +29 -0
  103. package/src/services/file/router.ts +88 -0
  104. package/src/services/file/service.ts +387 -0
  105. package/src/services/functions/router.ts +35 -0
  106. package/src/services/functions/service.ts +203 -0
  107. package/src/services/jwt/router.ts +73 -0
  108. package/src/services/jwt/service.ts +139 -0
  109. package/src/services/user_manager/db.ts +87 -0
  110. package/src/services/user_manager/permissionManager.ts +49 -0
  111. package/src/services/user_manager/router.ts +193 -0
  112. package/src/services/user_manager/service.ts +703 -0
  113. package/tsconfig.json +16 -9
  114. package/typedoc.mjs +41 -0
  115. package/LICENSE +0 -21
  116. package/package-lock.json +0 -1373
  117. package/src/application.js +0 -239
  118. package/src/class/cms_trigger.js +0 -20
  119. package/src/class/collection_definition.js +0 -33
  120. package/src/class/combinator.js +0 -133
  121. package/src/class/database_trigger.js +0 -20
  122. package/src/class/db_schemas.js +0 -18
  123. package/src/class/paginator.js +0 -31
  124. package/src/class/reply.js +0 -37
  125. package/src/class/security.js +0 -141
  126. package/src/class/trigger_operator.js +0 -39
  127. package/src/class/user.js +0 -112
  128. package/src/class/validator.js +0 -91
  129. package/src/config.js +0 -67
  130. package/src/events.js +0 -15
  131. package/src/helper/data_insertion.js +0 -64
  132. package/src/helper/presetup_services.js +0 -31
  133. package/src/index.js +0 -66
  134. package/src/middlewares.js +0 -44
  135. package/src/services/data_provider/router.js +0 -552
  136. package/src/services/data_provider/service.js +0 -262
  137. package/src/services/data_provider/typeCasters.js +0 -10
  138. package/src/services/file/db.js +0 -29
  139. package/src/services/file/router.js +0 -92
  140. package/src/services/file/service.js +0 -231
  141. package/src/services/functions/router.js +0 -37
  142. package/src/services/functions/service.js +0 -74
  143. package/src/services/jwt/router.js +0 -82
  144. package/src/services/jwt/service.js +0 -37
  145. package/src/services/user_manager/db.js +0 -83
  146. package/src/services/user_manager/permissionManager.js +0 -43
  147. package/src/services/user_manager/router.js +0 -176
  148. package/src/services/user_manager/service.js +0 -377
  149. package/types/application.d.ts +0 -97
  150. package/types/class/cms_trigger.d.ts +0 -24
  151. package/types/class/collection_definition.d.ts +0 -36
  152. package/types/class/combinator.d.ts +0 -30
  153. package/types/class/database_trigger.d.ts +0 -28
  154. package/types/class/db_schemas.d.ts +0 -2
  155. package/types/class/directory.d.ts +0 -2
  156. package/types/class/paginator.d.ts +0 -8
  157. package/types/class/reply.d.ts +0 -8
  158. package/types/class/security.d.ts +0 -109
  159. package/types/class/trigger_operator.d.ts +0 -19
  160. package/types/class/user.d.ts +0 -24
  161. package/types/class/validator.d.ts +0 -9
  162. package/types/config.d.ts +0 -101
  163. package/types/events.d.ts +0 -7
  164. package/types/helper/data_insertion.d.ts +0 -4
  165. package/types/helper/presetup_services.d.ts +0 -5
  166. package/types/index.d.ts +0 -72
  167. package/types/middlewares.d.ts +0 -10
  168. package/types/services/data_provider/router.d.ts +0 -3
  169. package/types/services/data_provider/service.d.ts +0 -40
  170. package/types/services/data_provider/typeCasters.d.ts +0 -3
  171. package/types/services/file/db.d.ts +0 -3
  172. package/types/services/file/router.d.ts +0 -3
  173. package/types/services/file/service.d.ts +0 -81
  174. package/types/services/functions/router.d.ts +0 -3
  175. package/types/services/functions/service.d.ts +0 -23
  176. package/types/services/jwt/router.d.ts +0 -3
  177. package/types/services/jwt/service.d.ts +0 -10
  178. package/types/services/user_manager/db.d.ts +0 -3
  179. package/types/services/user_manager/permissionManager.d.ts +0 -3
  180. package/types/services/user_manager/router.d.ts +0 -3
  181. package/types/services/user_manager/service.d.ts +0 -131
@@ -0,0 +1,94 @@
1
+ import * as DataProvider from '../services/data_provider/service';
2
+ import {
3
+ getDefaultAnonymousPermissionGroup,
4
+ getDefaultAdministratorPermissionGroup,
5
+ } from '../services/user_manager/permissionManager';
6
+ import * as userManager from '../services/user_manager/service';
7
+
8
+ /**
9
+ * Admin user credentials interface
10
+ * @interface AdminCredentials
11
+ * @property {string} email - Admin user email address
12
+ * @property {string} password - Admin user password
13
+ */
14
+ interface AdminCredentials {
15
+ email: string;
16
+ password: string;
17
+ }
18
+
19
+ /**
20
+ * Creates default system users if they don't exist
21
+ * @function createAdminUser
22
+ * @param {AdminCredentials} credentials - Admin user credentials
23
+ * @returns {Promise<void>} A promise that resolves when the operation is complete
24
+ * @throws {Error} If admin credentials are invalid or if the operation fails
25
+ * @description
26
+ * This function performs the following operations:
27
+ * 1. Checks if an anonymous user exists, creates one if it doesn't
28
+ * 2. Checks if an administrator user exists, creates one if it doesn't
29
+ * 3. Uses the provided credentials for the administrator user
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * // Create default system users
34
+ * await createAdminUser({
35
+ * email: 'admin@example.com',
36
+ * password: 'secure-password'
37
+ * });
38
+ *
39
+ * // The function will:
40
+ * // 1. Create an anonymous user if it doesn't exist
41
+ * // 2. Create an admin user with the provided credentials if it doesn't exist
42
+ * // 3. Do nothing if both users already exist
43
+ * ```
44
+ */
45
+ export async function createAdminUser({ email, password }: AdminCredentials): Promise<void> {
46
+ const authModel = DataProvider.getCollection('cms', 'auth');
47
+
48
+ try {
49
+ const isAnonymousExisted = await authModel.countDocuments({ type: 'anonymous' }).exec();
50
+
51
+ const isAdministratorExisted = await authModel
52
+ .countDocuments({ type: 'user', email: email })
53
+ .exec();
54
+
55
+ if (isAnonymousExisted === 0) {
56
+ await userManager.main.registerUser({
57
+ permissionGroup: getDefaultAnonymousPermissionGroup().title,
58
+ email: '',
59
+ phone: '',
60
+ password: '',
61
+ type: 'anonymous',
62
+ });
63
+ // await new authModel({
64
+ // permission: getDefaultAnonymousPermissionGroup().title,
65
+ // email: "",
66
+ // phone: "",
67
+ // password: "",
68
+ // type: "anonymous",
69
+ // }).save();
70
+ }
71
+
72
+ if (isAdministratorExisted === 0) {
73
+ if (!email || !password) {
74
+ return Promise.reject('Invalid email or password for admin user.');
75
+ }
76
+
77
+ await userManager.main.registerUser({
78
+ permissionGroup: getDefaultAdministratorPermissionGroup().title,
79
+ email: email,
80
+ password: password,
81
+ type: 'user',
82
+ });
83
+
84
+ // await new authModel({
85
+ // permission: getDefaultAdministratorPermissionGroup().title,
86
+ // email: email,
87
+ // password: password,
88
+ // type: "user",
89
+ // }).save();
90
+ }
91
+ } catch (e) {
92
+ return Promise.reject(e);
93
+ }
94
+ }
@@ -0,0 +1,96 @@
1
+ import * as DataInsertion from './data_insertion';
2
+ import * as JWT from '../services/jwt/service';
3
+ import * as FileService from '../services/file/service';
4
+ import generateKeypair from 'keypair';
5
+
6
+ /**
7
+ * Setup options interface for initializing required services
8
+ * @interface SetupOptions
9
+ * @property {Object} [keypair] - JWT keypair configuration
10
+ * @property {string} keypair.private - Private key for JWT signing
11
+ * @property {string} keypair.public - Public key for JWT verification
12
+ * @property {Object} adminUser - Admin user configuration
13
+ * @property {string} adminUser.email - Admin user email address
14
+ * @property {string} adminUser.password - Admin user password
15
+ * @property {string} [uploadDirectory] - Directory for file uploads
16
+ */
17
+ interface SetupOptions {
18
+ keypair?: {
19
+ private: string;
20
+ public: string;
21
+ };
22
+ adminUser: {
23
+ email: string;
24
+ password: string;
25
+ };
26
+ uploadDirectory?: string;
27
+ }
28
+
29
+ /**
30
+ * Sets up required services for the application to run
31
+ * @function setup
32
+ * @param {SetupOptions} options - Setup configuration options
33
+ * @returns {Promise<void>} A promise that resolves when setup is complete
34
+ * @throws {Error} If admin user configuration is missing or if setup fails
35
+ * @description
36
+ * This function performs the following setup operations:
37
+ * 1. Configures JWT with provided or generated keypair
38
+ * 2. Creates default system users (admin and anonymous)
39
+ * 3. Configures file upload directory if specified
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * // Setup with custom keypair
44
+ * await setup({
45
+ * keypair: {
46
+ * private: 'your-private-key',
47
+ * public: 'your-public-key'
48
+ * },
49
+ * adminUser: {
50
+ * email: 'admin@example.com',
51
+ * password: 'secure-password'
52
+ * },
53
+ * uploadDirectory: './uploads'
54
+ * });
55
+ *
56
+ * // Setup with auto-generated keypair
57
+ * await setup({
58
+ * adminUser: {
59
+ * email: 'admin@example.com',
60
+ * password: 'secure-password'
61
+ * }
62
+ * });
63
+ * ```
64
+ */
65
+ export async function setup({ keypair, adminUser, uploadDirectory }: SetupOptions): Promise<void> {
66
+ /**
67
+ * Json web Token
68
+ *
69
+ * Setup private and public keys for JWT module
70
+ */
71
+ let keyPairToUse = keypair;
72
+ if (!keyPairToUse) {
73
+ // generate new keypair
74
+ keyPairToUse = generateKeypair();
75
+ }
76
+
77
+ JWT.main.setKies(keyPairToUse.private, keyPairToUse.public);
78
+
79
+ if (!adminUser) {
80
+ throw new Error('Admin user is not supported in TypeScript version');
81
+ }
82
+ /**
83
+ * Data Insertion
84
+ *
85
+ * Insert admin user
86
+ * for the first time
87
+ */
88
+ await DataInsertion.createAdminUser(adminUser);
89
+
90
+ /**
91
+ * File Service
92
+ */
93
+ if (uploadDirectory) {
94
+ FileService.main.setUploadDirectory(uploadDirectory);
95
+ }
96
+ }
package/src/index.ts ADDED
@@ -0,0 +1,146 @@
1
+ // Application
2
+ import { createRest } from './application';
3
+ import { Schema } from 'mongoose';
4
+
5
+ // Utilities
6
+ import * as paginator from './class/paginator';
7
+ import * as reply from './class/reply';
8
+ import { validator } from './class/validator';
9
+ import { getCollection } from './services/data_provider/service';
10
+ import { defineFunction } from './services/functions/service';
11
+ import TypeCasters from './services/data_provider/typeCasters';
12
+
13
+ import { main as userManager } from './services/user_manager/service';
14
+ import { main as fileService } from './services/file/service';
15
+
16
+ // Base class
17
+ import { CollectionDefinition, defineCollection } from './class/collection_definition';
18
+ import { schemas } from './class/db_schemas';
19
+ import DatabaseTrigger from './class/database_trigger';
20
+ import CmsTrigger from './class/cms_trigger';
21
+ import {
22
+ AccessDefinition,
23
+ Permission,
24
+ PermissionTypes,
25
+ PermissionGroup,
26
+ AccessTypes,
27
+ } from './class/security';
28
+ import * as middleware from './middlewares';
29
+
30
+ /**
31
+ * @description Creates a new REST API instance
32
+ * @example
33
+ * ```typescript
34
+ * const rest = createRest();
35
+ * ```
36
+ * @returns A new REST API instance
37
+ */
38
+ export { createRest };
39
+
40
+ export { CollectionDefinition, defineCollection };
41
+
42
+ /**
43
+ * @description Provides predefined database schemas
44
+ * @example
45
+ * ```typescript
46
+ * const userSchema = new Schema({
47
+ * name: String,
48
+ * avatar: Schemas.file
49
+ * });
50
+ * ```
51
+ */
52
+ export { schemas };
53
+
54
+ /**
55
+ * @description Mongoose Schema class for defining data models
56
+ */
57
+ export { Schema };
58
+
59
+ /**
60
+ * @description Handles database triggers and events
61
+ * @example
62
+ * ```typescript
63
+ * const trigger = new DatabaseTrigger('insert-one', (data) => {
64
+ * // Handle insert event
65
+ * });
66
+ * ```
67
+ */
68
+ export { DatabaseTrigger };
69
+
70
+ /**
71
+ * @description Handles CMS triggers and events
72
+ */
73
+ export { CmsTrigger };
74
+
75
+ /**
76
+ * @description Security and access control definitions
77
+ * @example
78
+ * ```typescript
79
+ * const permission = new Permission({
80
+ * type: 'user_access',
81
+ * read: true,
82
+ * write: true
83
+ * });
84
+ * ```
85
+ */
86
+ export { AccessDefinition, Permission, PermissionTypes, PermissionGroup, AccessTypes };
87
+
88
+ /**
89
+ * @description Defines custom functions for the API
90
+ * @example
91
+ * ```typescript
92
+ * defineFunction('sendEmail', async (data) => {
93
+ * // Send email logic
94
+ * });
95
+ * ```
96
+ */
97
+ export { defineFunction };
98
+
99
+ /**
100
+ * @description Type casting utilities for data transformation
101
+ */
102
+ export { TypeCasters };
103
+
104
+ /**
105
+ * @description Input validation utilities
106
+ */
107
+ export { validator };
108
+
109
+ /**
110
+ * @description Response handling utilities
111
+ */
112
+ export { reply };
113
+
114
+ /**
115
+ * @description Pagination utilities
116
+ */
117
+ export { paginator };
118
+
119
+ /**
120
+ * @description Database collection access utilities
121
+ */
122
+ export { getCollection };
123
+
124
+ /**
125
+ * @description File handling utilities
126
+ * @example
127
+ * ```typescript
128
+ * const file = await fileService.getFile('fileId');
129
+ * const link = fileService.getFileLink('fileId');
130
+ * ```
131
+ */
132
+ export { fileService };
133
+
134
+ /**
135
+ * @description Middleware utilities
136
+ */
137
+ export { middleware };
138
+
139
+ /**
140
+ * @description User management utilities
141
+ * @example
142
+ * ```typescript
143
+ * const user = await userManager.getUserById('userId');
144
+ * ```
145
+ */
146
+ export { userManager };
@@ -0,0 +1,75 @@
1
+ import { Context, Next } from 'koa';
2
+ import { validator as validateObject } from './class/validator';
3
+ import * as userManager from './services/user_manager/service';
4
+ import User from './class/user';
5
+
6
+ /**
7
+ * Authentication middleware that secures routes by validating user tokens and managing access control.
8
+ *
9
+ * This middleware performs several key functions:
10
+ * 1. Validates that the incoming request contains an authorization token in the header
11
+ * 2. Verifies the token is valid by checking against the user management service
12
+ * 3. Retrieves the associated user object if the token is valid
13
+ * 4. Attaches the authenticated {@link User} object on ctx.state.user for use in subsequent middleware/routes
14
+ * 5. Throws appropriate HTTP errors (401, 412) if authentication fails
15
+ *
16
+ * The middleware integrates with the permission system to enable role-based access control.
17
+ * The attached user object provides methods like hasPermission() to check specific permissions.
18
+ *
19
+ * Common usage patterns:
20
+ * - Protecting sensitive API endpoints
21
+ * - Implementing role-based access control
22
+ * - Getting the current authenticated user
23
+ * - Validating user permissions before allowing actions
24
+ *
25
+ * @throws {Error} 401 - If no authorization header is present
26
+ * @throws {Error} 412 - If token validation fails
27
+ * @param ctx - Koa Context object containing request/response data
28
+ * @param next - Function to invoke next middleware
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * // Inside the router.ts file
33
+ * import { auth } from '@modular-rest/server';
34
+ * import { Router } from 'koa-router';
35
+ *
36
+ * const name = 'flowers';
37
+ *
38
+ * const flowerRouter = new Router();
39
+ *
40
+ * flowerRouter.get('/list', auth, (ctx) => {
41
+ * // Get the authenticated user
42
+ * const user = ctx.state.user;
43
+ *
44
+ * // Then you can check the user's role and permission
45
+ * if(user.hasPermission('get_flower')) {
46
+ * ctx.body = 'This is a list of flowers: Rose, Lily, Tulip';
47
+ * } else {
48
+ * ctx.status = 403;
49
+ * ctx.body = 'You are not authorized to access this resource';
50
+ * }
51
+ * });
52
+ *
53
+ * module.exports.name = name;
54
+ * module.exports.main = flowerRouter;
55
+ * ```
56
+ */
57
+ export async function auth(ctx: Context, next: Next): Promise<void> {
58
+ const headers = ctx.header;
59
+ const headersValidated = validateObject(headers, 'authorization');
60
+
61
+ if (!headersValidated.isValid) ctx.throw(401, 'authentication is required');
62
+
63
+ const token = headers.authorization as string;
64
+
65
+ await userManager.main
66
+ .getUserByToken(token)
67
+ .then(async (user: User) => {
68
+ ctx.state.user = user;
69
+ await next();
70
+ })
71
+ .catch(err => {
72
+ console.log(err);
73
+ ctx.throw(err.status || 412, err.message);
74
+ });
75
+ }
@@ -0,0 +1,8 @@
1
+ import { createRest } from './application';
2
+
3
+ const app = createRest({
4
+ adminUser: {
5
+ email: 'admin@example.com',
6
+ password: 'password',
7
+ },
8
+ });