@modular-rest/server 1.11.13 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.nvmrc +1 -0
- package/.prettierrc.json +9 -0
- package/.releaserc.json +24 -0
- package/README.md +79 -94
- package/dist/application.d.ts +29 -0
- package/dist/application.js +217 -0
- package/dist/class/cms_trigger.d.ts +61 -0
- package/dist/class/cms_trigger.js +47 -0
- package/dist/class/collection_definition.d.ts +112 -0
- package/dist/class/collection_definition.js +87 -0
- package/dist/class/combinator.d.ts +43 -0
- package/dist/class/combinator.js +174 -0
- package/dist/class/database_trigger.d.ts +84 -0
- package/dist/class/database_trigger.js +64 -0
- package/dist/class/db_schemas.d.ts +25 -0
- package/dist/class/db_schemas.js +28 -0
- package/dist/class/directory.d.ts +20 -0
- package/dist/class/directory.js +87 -0
- package/dist/class/paginator.d.ts +31 -0
- package/dist/class/paginator.js +43 -0
- package/dist/class/reply.d.ts +29 -0
- package/dist/class/reply.js +44 -0
- package/dist/class/security.d.ts +186 -0
- package/dist/class/security.js +178 -0
- package/dist/class/trigger_operator.d.ts +92 -0
- package/dist/class/trigger_operator.js +99 -0
- package/dist/class/user.d.ts +81 -0
- package/dist/class/user.js +151 -0
- package/dist/class/validator.d.ts +19 -0
- package/dist/class/validator.js +101 -0
- package/dist/config.d.ts +112 -0
- package/dist/config.js +26 -0
- package/dist/defult-permissions.d.ts +2 -0
- package/dist/defult-permissions.js +31 -0
- package/dist/events.d.ts +23 -0
- package/dist/events.js +47 -0
- package/dist/helper/data_insertion.d.ts +38 -0
- package/dist/helper/data_insertion.js +110 -0
- package/dist/helper/presetup_services.d.ts +60 -0
- package/dist/helper/presetup_services.js +108 -0
- package/dist/index.d.ts +118 -0
- package/dist/index.js +79 -0
- package/dist/middlewares.d.ts +53 -0
- package/dist/middlewares.js +106 -0
- package/dist/play-test.d.ts +1 -0
- package/dist/play-test.js +9 -0
- package/dist/services/data_provider/router.d.ts +4 -0
- package/dist/services/data_provider/router.js +187 -0
- package/dist/services/data_provider/service.d.ts +131 -0
- package/dist/services/data_provider/service.js +252 -0
- package/dist/services/data_provider/typeCasters.d.ts +9 -0
- package/dist/services/data_provider/typeCasters.js +18 -0
- package/dist/services/file/db.d.ts +1 -0
- package/dist/services/file/db.js +31 -0
- package/dist/services/file/router.d.ts +4 -0
- package/dist/services/file/router.js +115 -0
- package/dist/services/file/service.d.ts +204 -0
- package/dist/services/file/service.js +341 -0
- package/dist/services/functions/router.d.ts +4 -0
- package/dist/services/functions/router.js +67 -0
- package/dist/services/functions/service.d.ts +132 -0
- package/dist/services/functions/service.js +159 -0
- package/dist/services/jwt/router.d.ts +4 -0
- package/dist/services/jwt/router.js +99 -0
- package/dist/services/jwt/service.d.ts +97 -0
- package/dist/services/jwt/service.js +135 -0
- package/dist/services/user_manager/db.d.ts +1 -0
- package/dist/services/user_manager/db.js +75 -0
- package/dist/services/user_manager/permissionManager.d.ts +19 -0
- package/dist/services/user_manager/permissionManager.js +42 -0
- package/dist/services/user_manager/router.d.ts +4 -0
- package/dist/services/user_manager/router.js +195 -0
- package/dist/services/user_manager/service.d.ts +317 -0
- package/dist/services/user_manager/service.js +628 -0
- package/docs/.keep +0 -0
- package/docs/system-access-type.md +26 -0
- package/package.json +58 -45
- package/src/application.ts +206 -0
- package/src/class/cms_trigger.ts +68 -0
- package/src/class/collection_definition.ts +134 -0
- package/src/class/combinator.ts +176 -0
- package/src/class/database_trigger.ts +99 -0
- package/src/class/db_schemas.ts +44 -0
- package/src/class/{directory.js → directory.ts} +40 -18
- package/src/class/paginator.ts +51 -0
- package/src/class/reply.ts +59 -0
- package/src/class/security.ts +250 -0
- package/src/class/trigger_operator.ts +142 -0
- package/src/class/user.ts +199 -0
- package/src/class/validator.ts +123 -0
- package/src/config.ts +121 -0
- package/src/defult-permissions.ts +31 -0
- package/src/events.ts +59 -0
- package/src/helper/data_insertion.ts +94 -0
- package/src/helper/presetup_services.ts +96 -0
- package/src/index.ts +146 -0
- package/src/middlewares.ts +75 -0
- package/src/play-test.ts +8 -0
- package/src/services/data_provider/router.ts +191 -0
- package/src/services/data_provider/service.ts +305 -0
- package/src/services/data_provider/typeCasters.ts +15 -0
- package/src/services/file/db.ts +29 -0
- package/src/services/file/router.ts +88 -0
- package/src/services/file/service.ts +387 -0
- package/src/services/functions/router.ts +34 -0
- package/src/services/functions/service.ts +203 -0
- package/src/services/jwt/router.ts +73 -0
- package/src/services/jwt/service.ts +139 -0
- package/src/services/user_manager/db.ts +87 -0
- package/src/services/user_manager/permissionManager.ts +49 -0
- package/src/services/user_manager/router.ts +193 -0
- package/src/services/user_manager/service.ts +698 -0
- package/tsconfig.json +16 -9
- package/typedoc.mjs +41 -0
- package/LICENSE +0 -21
- package/package-lock.json +0 -1373
- package/src/application.js +0 -239
- package/src/class/cms_trigger.js +0 -20
- package/src/class/collection_definition.js +0 -33
- package/src/class/combinator.js +0 -133
- package/src/class/database_trigger.js +0 -20
- package/src/class/db_schemas.js +0 -18
- package/src/class/paginator.js +0 -31
- package/src/class/reply.js +0 -37
- package/src/class/security.js +0 -141
- package/src/class/trigger_operator.js +0 -39
- package/src/class/user.js +0 -112
- package/src/class/validator.js +0 -91
- package/src/config.js +0 -67
- package/src/events.js +0 -15
- package/src/helper/data_insertion.js +0 -64
- package/src/helper/presetup_services.js +0 -31
- package/src/index.js +0 -66
- package/src/middlewares.js +0 -44
- package/src/services/data_provider/router.js +0 -552
- package/src/services/data_provider/service.js +0 -262
- package/src/services/data_provider/typeCasters.js +0 -10
- package/src/services/file/db.js +0 -29
- package/src/services/file/router.js +0 -92
- package/src/services/file/service.js +0 -231
- package/src/services/functions/router.js +0 -37
- package/src/services/functions/service.js +0 -74
- package/src/services/jwt/router.js +0 -82
- package/src/services/jwt/service.js +0 -37
- package/src/services/user_manager/db.js +0 -83
- package/src/services/user_manager/permissionManager.js +0 -43
- package/src/services/user_manager/router.js +0 -176
- package/src/services/user_manager/service.js +0 -377
- package/types/application.d.ts +0 -97
- package/types/class/cms_trigger.d.ts +0 -24
- package/types/class/collection_definition.d.ts +0 -36
- package/types/class/combinator.d.ts +0 -30
- package/types/class/database_trigger.d.ts +0 -28
- package/types/class/db_schemas.d.ts +0 -2
- package/types/class/directory.d.ts +0 -2
- package/types/class/paginator.d.ts +0 -8
- package/types/class/reply.d.ts +0 -8
- package/types/class/security.d.ts +0 -109
- package/types/class/trigger_operator.d.ts +0 -19
- package/types/class/user.d.ts +0 -24
- package/types/class/validator.d.ts +0 -9
- package/types/config.d.ts +0 -101
- package/types/events.d.ts +0 -7
- package/types/helper/data_insertion.d.ts +0 -4
- package/types/helper/presetup_services.d.ts +0 -5
- package/types/index.d.ts +0 -72
- package/types/middlewares.d.ts +0 -10
- package/types/services/data_provider/router.d.ts +0 -3
- package/types/services/data_provider/service.d.ts +0 -40
- package/types/services/data_provider/typeCasters.d.ts +0 -3
- package/types/services/file/db.d.ts +0 -3
- package/types/services/file/router.d.ts +0 -3
- package/types/services/file/service.d.ts +0 -81
- package/types/services/functions/router.d.ts +0 -3
- package/types/services/functions/service.d.ts +0 -23
- package/types/services/jwt/router.d.ts +0 -3
- package/types/services/jwt/service.d.ts +0 -10
- package/types/services/user_manager/db.d.ts +0 -3
- package/types/services/user_manager/permissionManager.d.ts +0 -3
- package/types/services/user_manager/router.d.ts +0 -3
- package/types/services/user_manager/service.d.ts +0 -131
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.name = void 0;
|
|
4
|
+
exports.defineFunction = defineFunction;
|
|
5
|
+
exports.runFunction = runFunction;
|
|
6
|
+
exports.addFunction = addFunction;
|
|
7
|
+
/**
|
|
8
|
+
* Service name constant
|
|
9
|
+
* @constant {string}
|
|
10
|
+
*/
|
|
11
|
+
exports.name = 'functions';
|
|
12
|
+
/**
|
|
13
|
+
* Storage for registered functions
|
|
14
|
+
* @private
|
|
15
|
+
*/
|
|
16
|
+
const functions = [];
|
|
17
|
+
/**
|
|
18
|
+
* To define a function you need to create a `functions.[js|ts]` in each module of your app and return am array called `functions`, and then define all your functions with calling the `defineFunction` method.
|
|
19
|
+
*
|
|
20
|
+
* The `defineFunction` method serves as a core utility for creating custom functions dynamically. This method allows you to specify various parameters, including the name of the function, the permissions required for access, and the corresponding logic that should be executed when the function is invoked.
|
|
21
|
+
*
|
|
22
|
+
* @summary
|
|
23
|
+
* Define a server function to be called by clients.
|
|
24
|
+
*
|
|
25
|
+
* @param {DefinedFunction} options - The function definition options. See {@link DefinedFunction} for detailed parameter descriptions.
|
|
26
|
+
* @expandType DefinedFunction
|
|
27
|
+
*
|
|
28
|
+
* @returns {Object} The defined function object which system will use to generate a router for the function, generall the client library will use the router to call the function.
|
|
29
|
+
* @throws {Error} If function name already exists, permission types are missing, or callback is invalid
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* Here is an example illustrating how to use the `defineFunction` method effectively:
|
|
33
|
+
* ```typescript
|
|
34
|
+
* // /modules/myModule/functions.ts
|
|
35
|
+
*
|
|
36
|
+
* import { defineFunction } from "@modular-rest/server";
|
|
37
|
+
*
|
|
38
|
+
* const getServerTime = defineFunction({
|
|
39
|
+
* name: "getServerTime",
|
|
40
|
+
* permissionTypes: ["anonymous_access"],
|
|
41
|
+
* callback: (params) => {
|
|
42
|
+
* // return your data only
|
|
43
|
+
* return `
|
|
44
|
+
* Welcome, ${params.username}!
|
|
45
|
+
* The current server time is ${new Date().toLocaleString()}.
|
|
46
|
+
* `;
|
|
47
|
+
*
|
|
48
|
+
* // error handling,
|
|
49
|
+
* // client gets error code 400, and the message
|
|
50
|
+
* // throw new Error('An error occurred');
|
|
51
|
+
* },
|
|
52
|
+
* });
|
|
53
|
+
*
|
|
54
|
+
* module.exports.functions = [getServerTime];
|
|
55
|
+
* ```
|
|
56
|
+
* In this example, we define a function named `getServerTime` that requires the `user` permission type to access. When the function is called, it will return a message containing the current server time and the username of the user who invoked the function.
|
|
57
|
+
*
|
|
58
|
+
* ---
|
|
59
|
+
*
|
|
60
|
+
* By utilizing the `defineFunction` method, developers are empowered to create custom functionality effortlessly within the Modular REST framework, enhancing both the versatility and security of their applications.
|
|
61
|
+
*/
|
|
62
|
+
function defineFunction(options) {
|
|
63
|
+
// Check if the function already exists
|
|
64
|
+
const existingFunction = functions.find(f => f.name === exports.name);
|
|
65
|
+
if (existingFunction) {
|
|
66
|
+
throw new Error(`Function with name ${exports.name} already exists`);
|
|
67
|
+
}
|
|
68
|
+
// Check if the permission types provided
|
|
69
|
+
if (!options.permissionTypes || !options.permissionTypes.length) {
|
|
70
|
+
throw new Error(`Permission types not provided for function ${exports.name}`);
|
|
71
|
+
}
|
|
72
|
+
// Check if the callback is a function
|
|
73
|
+
if (typeof options.callback !== 'function') {
|
|
74
|
+
throw new Error(`Callback is not a function for function ${exports.name}`);
|
|
75
|
+
}
|
|
76
|
+
// Add the function to the list of functions
|
|
77
|
+
return options;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Runs a function by name with arguments and user context
|
|
81
|
+
*
|
|
82
|
+
* @param {string} name - Name of the function to run
|
|
83
|
+
* @param {any} args - Arguments to pass to the function
|
|
84
|
+
* @param {User} user - User attempting to run the function
|
|
85
|
+
* @returns {Promise<any>} Promise resolving to function result
|
|
86
|
+
* @throws {Error} If function not found or user lacks required permissions
|
|
87
|
+
*
|
|
88
|
+
* @private
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```typescript
|
|
92
|
+
* try {
|
|
93
|
+
* const result = await runFunction('calculateTotal', {
|
|
94
|
+
* items: [
|
|
95
|
+
* { price: 10 },
|
|
96
|
+
* { price: 20 }
|
|
97
|
+
* ]
|
|
98
|
+
* }, currentUser);
|
|
99
|
+
* console.log('Total:', result); // 30
|
|
100
|
+
* } catch (error) {
|
|
101
|
+
* console.error('Function execution failed:', error);
|
|
102
|
+
* }
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
function runFunction(name, args, user) {
|
|
106
|
+
return new Promise((resolve, reject) => {
|
|
107
|
+
const func = functions.find(f => f.name === name);
|
|
108
|
+
if (!func) {
|
|
109
|
+
return reject(new Error(`Function with name ${name} not found`));
|
|
110
|
+
}
|
|
111
|
+
const hasPermission = func.permissionTypes.some(permissionType => user.hasPermission(permissionType));
|
|
112
|
+
if (!hasPermission) {
|
|
113
|
+
const userBrief = user.getBrief();
|
|
114
|
+
const userPermissions = typeof userBrief.permissionGroup === 'object' && userBrief.permissionGroup
|
|
115
|
+
? userBrief.permissionGroup.allowedAccessTypes
|
|
116
|
+
: 'none';
|
|
117
|
+
reject(new Error(`User does not have permission to run function ${name}:
|
|
118
|
+
Function permissions: ${func.permissionTypes}
|
|
119
|
+
User permissions: ${userPermissions}
|
|
120
|
+
`));
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
try {
|
|
124
|
+
resolve(func.callback(args));
|
|
125
|
+
}
|
|
126
|
+
catch (e) {
|
|
127
|
+
reject(e);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Adds a function to the registry, this method is used for internal use only,
|
|
134
|
+
* it will add all defined functions to the registry.
|
|
135
|
+
*
|
|
136
|
+
* @param {DefinedFunction} func - Function to add
|
|
137
|
+
* @throws {Error} If function name already exists
|
|
138
|
+
*
|
|
139
|
+
* @private
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* ```typescript
|
|
143
|
+
* const myFunction = defineFunction({
|
|
144
|
+
* name: 'myFunction',
|
|
145
|
+
* permissionTypes: ['user_access'],
|
|
146
|
+
* callback: (args) => args.value * 2
|
|
147
|
+
* });
|
|
148
|
+
*
|
|
149
|
+
* addFunction(myFunction);
|
|
150
|
+
* ```
|
|
151
|
+
*/
|
|
152
|
+
function addFunction(func) {
|
|
153
|
+
// Check if the function already exists
|
|
154
|
+
const existingFunction = functions.find(f => f.name === func.name);
|
|
155
|
+
if (existingFunction) {
|
|
156
|
+
throw new Error(`Function with name ${func.name} already exists`);
|
|
157
|
+
}
|
|
158
|
+
functions.push(func);
|
|
159
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.main = exports.name = void 0;
|
|
40
|
+
const koa_router_1 = __importDefault(require("koa-router"));
|
|
41
|
+
const validator_1 = require("../../class/validator");
|
|
42
|
+
const reply_1 = require("../../class/reply");
|
|
43
|
+
const service = __importStar(require("./service"));
|
|
44
|
+
const name = 'verify';
|
|
45
|
+
exports.name = name;
|
|
46
|
+
const verify = new koa_router_1.default();
|
|
47
|
+
exports.main = verify;
|
|
48
|
+
verify.post('/token', async (ctx) => {
|
|
49
|
+
const body = ctx.request.body;
|
|
50
|
+
// validate result
|
|
51
|
+
const bodyValidate = (0, validator_1.validateObject)(body, 'token');
|
|
52
|
+
// fields validation
|
|
53
|
+
if (!bodyValidate.isValid) {
|
|
54
|
+
ctx.status = 412;
|
|
55
|
+
ctx.body = (0, reply_1.create)('e', {
|
|
56
|
+
e: bodyValidate.requires,
|
|
57
|
+
});
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
await service.main
|
|
61
|
+
.verify(body.token)
|
|
62
|
+
.then(payload => (ctx.body = (0, reply_1.create)('s', { user: payload })))
|
|
63
|
+
.catch(err => {
|
|
64
|
+
ctx.status = 412;
|
|
65
|
+
ctx.body = (0, reply_1.create)('e', { e: err });
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
verify.post('/checkAccess', async (ctx) => {
|
|
69
|
+
const body = ctx.request.body;
|
|
70
|
+
// validate result
|
|
71
|
+
const bodyValidate = (0, validator_1.validateObject)(body, 'token permissionField');
|
|
72
|
+
// fields validation
|
|
73
|
+
if (!bodyValidate.isValid) {
|
|
74
|
+
ctx.status = 412;
|
|
75
|
+
ctx.body = (0, reply_1.create)('e', {
|
|
76
|
+
e: bodyValidate.requires,
|
|
77
|
+
});
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const payload = await service.main.verify(body.token).catch(err => {
|
|
81
|
+
console.log(err);
|
|
82
|
+
ctx.throw(412, err.message);
|
|
83
|
+
});
|
|
84
|
+
const userid = payload.id;
|
|
85
|
+
await global.services.userManager.main
|
|
86
|
+
.getUserById(userid)
|
|
87
|
+
.then((user) => {
|
|
88
|
+
const key = user.hasPermission(body.permissionField);
|
|
89
|
+
ctx.body = (0, reply_1.create)('s', { access: key });
|
|
90
|
+
})
|
|
91
|
+
.catch((err) => {
|
|
92
|
+
ctx.status = 412;
|
|
93
|
+
ctx.body = (0, reply_1.create)('e', { e: err });
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
verify.get('/ready', async (ctx) => {
|
|
97
|
+
// it's health check, so return success
|
|
98
|
+
ctx.body = (0, reply_1.create)('s', {});
|
|
99
|
+
});
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Service name constant
|
|
3
|
+
* @constant {string}
|
|
4
|
+
*/
|
|
5
|
+
export declare const name = "jwt";
|
|
6
|
+
/**
|
|
7
|
+
* JWT service class for handling JSON Web Token operations
|
|
8
|
+
* @class JWT
|
|
9
|
+
* @description
|
|
10
|
+
* This class provides methods for signing and verifying JSON Web Tokens using RS256 algorithm.
|
|
11
|
+
* It requires both private and public keys to be set before use.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* // Set up keys
|
|
16
|
+
* main.setKies(privateKey, publicKey);
|
|
17
|
+
*
|
|
18
|
+
* // Sign a token
|
|
19
|
+
* const token = await main.sign({ userId: '123', role: 'admin' });
|
|
20
|
+
*
|
|
21
|
+
* // Verify a token
|
|
22
|
+
* const decoded = await main.verify(token);
|
|
23
|
+
* console.log(decoded.userId); // '123'
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
declare class JWT {
|
|
27
|
+
private privateKey?;
|
|
28
|
+
private publicKey?;
|
|
29
|
+
/**
|
|
30
|
+
* Sets the private and public keys for JWT operations
|
|
31
|
+
* @param {string} privateKey - Private key for signing tokens (PEM format)
|
|
32
|
+
* @param {string} publicKey - Public key for verifying tokens (PEM format)
|
|
33
|
+
* @throws {Error} If either key is invalid
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* // Using PEM format keys
|
|
37
|
+
* const privateKey = `-----BEGIN PRIVATE KEY-----
|
|
38
|
+
* MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSnAgEAAoIBAQC9QFi67s...
|
|
39
|
+
* -----END PRIVATE KEY-----`;
|
|
40
|
+
*
|
|
41
|
+
* const publicKey = `-----BEGIN PUBLIC KEY-----
|
|
42
|
+
* MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvUBYuu7...
|
|
43
|
+
* -----END PUBLIC KEY-----`;
|
|
44
|
+
*
|
|
45
|
+
* main.setKies(privateKey, publicKey);
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
setKies(privateKey: string, publicKey: string): void;
|
|
49
|
+
/**
|
|
50
|
+
* Signs a payload and creates a JWT token using RS256 algorithm
|
|
51
|
+
* @param {Record<string, any>} payload - Data to be encoded in the token
|
|
52
|
+
* @returns {Promise<string>} A promise that resolves to the signed JWT token
|
|
53
|
+
* @throws {Error} If private key is not set or signing fails
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* // Sign a token with user data
|
|
57
|
+
* const token = await main.sign({
|
|
58
|
+
* userId: '123',
|
|
59
|
+
* role: 'admin',
|
|
60
|
+
* exp: Math.floor(Date.now() / 1000) + (60 * 60) // 1 hour expiry
|
|
61
|
+
* });
|
|
62
|
+
*
|
|
63
|
+
* // Sign a token with custom claims
|
|
64
|
+
* const token = await main.sign({
|
|
65
|
+
* sub: 'user123',
|
|
66
|
+
* iss: 'myapp.com',
|
|
67
|
+
* aud: 'myapp.com',
|
|
68
|
+
* iat: Math.floor(Date.now() / 1000)
|
|
69
|
+
* });
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
sign(payload: Record<string, any>): Promise<string>;
|
|
73
|
+
/**
|
|
74
|
+
* Verifies a JWT token and returns its decoded payload
|
|
75
|
+
* @param {string} token - JWT token to verify
|
|
76
|
+
* @returns {Promise<Record<string, any>>} A promise that resolves to the decoded payload
|
|
77
|
+
* @throws {Error} If public key is not set, token is invalid, or verification fails
|
|
78
|
+
* @example
|
|
79
|
+
* ```typescript
|
|
80
|
+
* try {
|
|
81
|
+
* const decoded = await main.verify(token);
|
|
82
|
+
* console.log('Token is valid:', decoded);
|
|
83
|
+
* // Access decoded data
|
|
84
|
+
* const { userId, role } = decoded;
|
|
85
|
+
* } catch (error) {
|
|
86
|
+
* console.error('Token verification failed:', error);
|
|
87
|
+
* }
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
verify(token: string): Promise<Record<string, any>>;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Main JWT service instance
|
|
94
|
+
* @constant {JWT}
|
|
95
|
+
*/
|
|
96
|
+
export declare const main: JWT;
|
|
97
|
+
export {};
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.main = exports.name = void 0;
|
|
7
|
+
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
|
|
8
|
+
/**
|
|
9
|
+
* Service name constant
|
|
10
|
+
* @constant {string}
|
|
11
|
+
*/
|
|
12
|
+
exports.name = 'jwt';
|
|
13
|
+
/**
|
|
14
|
+
* JWT service class for handling JSON Web Token operations
|
|
15
|
+
* @class JWT
|
|
16
|
+
* @description
|
|
17
|
+
* This class provides methods for signing and verifying JSON Web Tokens using RS256 algorithm.
|
|
18
|
+
* It requires both private and public keys to be set before use.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* // Set up keys
|
|
23
|
+
* main.setKies(privateKey, publicKey);
|
|
24
|
+
*
|
|
25
|
+
* // Sign a token
|
|
26
|
+
* const token = await main.sign({ userId: '123', role: 'admin' });
|
|
27
|
+
*
|
|
28
|
+
* // Verify a token
|
|
29
|
+
* const decoded = await main.verify(token);
|
|
30
|
+
* console.log(decoded.userId); // '123'
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
class JWT {
|
|
34
|
+
/**
|
|
35
|
+
* Sets the private and public keys for JWT operations
|
|
36
|
+
* @param {string} privateKey - Private key for signing tokens (PEM format)
|
|
37
|
+
* @param {string} publicKey - Public key for verifying tokens (PEM format)
|
|
38
|
+
* @throws {Error} If either key is invalid
|
|
39
|
+
* @example
|
|
40
|
+
* ```typescript
|
|
41
|
+
* // Using PEM format keys
|
|
42
|
+
* const privateKey = `-----BEGIN PRIVATE KEY-----
|
|
43
|
+
* MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSnAgEAAoIBAQC9QFi67s...
|
|
44
|
+
* -----END PRIVATE KEY-----`;
|
|
45
|
+
*
|
|
46
|
+
* const publicKey = `-----BEGIN PUBLIC KEY-----
|
|
47
|
+
* MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvUBYuu7...
|
|
48
|
+
* -----END PUBLIC KEY-----`;
|
|
49
|
+
*
|
|
50
|
+
* main.setKies(privateKey, publicKey);
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
setKies(privateKey, publicKey) {
|
|
54
|
+
if (!privateKey || !publicKey) {
|
|
55
|
+
throw new Error('Both private and public keys are required');
|
|
56
|
+
}
|
|
57
|
+
this.privateKey = privateKey;
|
|
58
|
+
this.publicKey = publicKey;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Signs a payload and creates a JWT token using RS256 algorithm
|
|
62
|
+
* @param {Record<string, any>} payload - Data to be encoded in the token
|
|
63
|
+
* @returns {Promise<string>} A promise that resolves to the signed JWT token
|
|
64
|
+
* @throws {Error} If private key is not set or signing fails
|
|
65
|
+
* @example
|
|
66
|
+
* ```typescript
|
|
67
|
+
* // Sign a token with user data
|
|
68
|
+
* const token = await main.sign({
|
|
69
|
+
* userId: '123',
|
|
70
|
+
* role: 'admin',
|
|
71
|
+
* exp: Math.floor(Date.now() / 1000) + (60 * 60) // 1 hour expiry
|
|
72
|
+
* });
|
|
73
|
+
*
|
|
74
|
+
* // Sign a token with custom claims
|
|
75
|
+
* const token = await main.sign({
|
|
76
|
+
* sub: 'user123',
|
|
77
|
+
* iss: 'myapp.com',
|
|
78
|
+
* aud: 'myapp.com',
|
|
79
|
+
* iat: Math.floor(Date.now() / 1000)
|
|
80
|
+
* });
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
sign(payload) {
|
|
84
|
+
return new Promise((done, reject) => {
|
|
85
|
+
const option = { algorithm: 'RS256' };
|
|
86
|
+
if (!this.privateKey) {
|
|
87
|
+
return reject(new Error('Private key is not set. Call setKies() first.'));
|
|
88
|
+
}
|
|
89
|
+
try {
|
|
90
|
+
const token = jsonwebtoken_1.default.sign(payload, this.privateKey, option);
|
|
91
|
+
done(token);
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
reject(error instanceof Error ? error.message : String(error));
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Verifies a JWT token and returns its decoded payload
|
|
100
|
+
* @param {string} token - JWT token to verify
|
|
101
|
+
* @returns {Promise<Record<string, any>>} A promise that resolves to the decoded payload
|
|
102
|
+
* @throws {Error} If public key is not set, token is invalid, or verification fails
|
|
103
|
+
* @example
|
|
104
|
+
* ```typescript
|
|
105
|
+
* try {
|
|
106
|
+
* const decoded = await main.verify(token);
|
|
107
|
+
* console.log('Token is valid:', decoded);
|
|
108
|
+
* // Access decoded data
|
|
109
|
+
* const { userId, role } = decoded;
|
|
110
|
+
* } catch (error) {
|
|
111
|
+
* console.error('Token verification failed:', error);
|
|
112
|
+
* }
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
verify(token) {
|
|
116
|
+
return new Promise((done, reject) => {
|
|
117
|
+
const option = { algorithm: 'RS256' };
|
|
118
|
+
if (!this.publicKey) {
|
|
119
|
+
return reject(new Error('Public key is not set. Call setKies() first.'));
|
|
120
|
+
}
|
|
121
|
+
try {
|
|
122
|
+
const decoded = jsonwebtoken_1.default.verify(token, this.publicKey, option);
|
|
123
|
+
done(decoded);
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
reject(error instanceof Error ? error.message : String(error));
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Main JWT service instance
|
|
133
|
+
* @constant {JWT}
|
|
134
|
+
*/
|
|
135
|
+
exports.main = new JWT();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const mongoose_1 = require("mongoose");
|
|
7
|
+
const collection_definition_1 = require("../../class/collection_definition");
|
|
8
|
+
const security_1 = require("../../class/security");
|
|
9
|
+
const config_1 = require("../../config");
|
|
10
|
+
const trigger_operator_1 = __importDefault(require("../../class/trigger_operator"));
|
|
11
|
+
const authSchema = new mongoose_1.Schema({
|
|
12
|
+
permissionGroup: String,
|
|
13
|
+
email: String,
|
|
14
|
+
phone: String,
|
|
15
|
+
password: String,
|
|
16
|
+
type: { type: String, default: 'user', enum: ['user', 'anonymous'] },
|
|
17
|
+
}, { timestamps: true });
|
|
18
|
+
authSchema.index({ email: 1 }, { unique: true });
|
|
19
|
+
authSchema.pre(['save', 'updateOne'], function (next) {
|
|
20
|
+
// Encode the password before saving
|
|
21
|
+
if (this.isModified && this.isModified('password')) {
|
|
22
|
+
this.password = Buffer.from(this.password).toString('base64');
|
|
23
|
+
}
|
|
24
|
+
next();
|
|
25
|
+
});
|
|
26
|
+
authSchema.post('save', function (doc, next) {
|
|
27
|
+
trigger_operator_1.default.call('insert-one', 'cms', 'auth', {
|
|
28
|
+
query: null,
|
|
29
|
+
queryResult: doc._doc,
|
|
30
|
+
});
|
|
31
|
+
next();
|
|
32
|
+
});
|
|
33
|
+
authSchema.post('findOneAndUpdate', function (doc, next) {
|
|
34
|
+
trigger_operator_1.default.call('update-one', 'cms', 'auth', {
|
|
35
|
+
query: null,
|
|
36
|
+
queryResult: doc._doc,
|
|
37
|
+
});
|
|
38
|
+
next();
|
|
39
|
+
});
|
|
40
|
+
authSchema.post('updateOne', function (result, next) {
|
|
41
|
+
trigger_operator_1.default.call('update-one', 'cms', 'auth', {
|
|
42
|
+
query: null,
|
|
43
|
+
queryResult: result,
|
|
44
|
+
});
|
|
45
|
+
next();
|
|
46
|
+
});
|
|
47
|
+
authSchema.post('findOneAndDelete', function (doc, next) {
|
|
48
|
+
trigger_operator_1.default.call('remove-one', 'cms', 'auth', {
|
|
49
|
+
query: null,
|
|
50
|
+
queryResult: doc._doc,
|
|
51
|
+
});
|
|
52
|
+
next();
|
|
53
|
+
});
|
|
54
|
+
authSchema.post('deleteOne', function (result, next) {
|
|
55
|
+
trigger_operator_1.default.call('remove-one', 'cms', 'auth', {
|
|
56
|
+
query: null,
|
|
57
|
+
queryResult: result,
|
|
58
|
+
});
|
|
59
|
+
next();
|
|
60
|
+
});
|
|
61
|
+
module.exports = [
|
|
62
|
+
new collection_definition_1.CollectionDefinition({
|
|
63
|
+
database: 'cms',
|
|
64
|
+
collection: 'auth',
|
|
65
|
+
schema: authSchema,
|
|
66
|
+
permissions: [
|
|
67
|
+
new security_1.Permission({
|
|
68
|
+
accessType: security_1.PermissionTypes.advanced_settings,
|
|
69
|
+
read: true,
|
|
70
|
+
write: true,
|
|
71
|
+
}),
|
|
72
|
+
],
|
|
73
|
+
triggers: config_1.config.authTriggers || [],
|
|
74
|
+
}),
|
|
75
|
+
];
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { PermissionGroup } from '../../class/security';
|
|
2
|
+
/**
|
|
3
|
+
* Get the default permission group
|
|
4
|
+
* @returns Default permission group
|
|
5
|
+
* @throws Error if default permission group not found
|
|
6
|
+
*/
|
|
7
|
+
export declare function getDefaultPermissionGroups(): PermissionGroup;
|
|
8
|
+
/**
|
|
9
|
+
* Get the anonymous permission group
|
|
10
|
+
* @returns Anonymous permission group
|
|
11
|
+
* @throws Error if anonymous permission group not found
|
|
12
|
+
*/
|
|
13
|
+
export declare function getDefaultAnonymousPermissionGroup(): PermissionGroup;
|
|
14
|
+
/**
|
|
15
|
+
* Get the administrator permission group
|
|
16
|
+
* @returns Administrator permission group
|
|
17
|
+
* @throws Error if administrator permission group not found
|
|
18
|
+
*/
|
|
19
|
+
export declare function getDefaultAdministratorPermissionGroup(): PermissionGroup;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getDefaultPermissionGroups = getDefaultPermissionGroups;
|
|
4
|
+
exports.getDefaultAnonymousPermissionGroup = getDefaultAnonymousPermissionGroup;
|
|
5
|
+
exports.getDefaultAdministratorPermissionGroup = getDefaultAdministratorPermissionGroup;
|
|
6
|
+
const config_1 = require("../../config");
|
|
7
|
+
/**
|
|
8
|
+
* Get the default permission group
|
|
9
|
+
* @returns Default permission group
|
|
10
|
+
* @throws Error if default permission group not found
|
|
11
|
+
*/
|
|
12
|
+
function getDefaultPermissionGroups() {
|
|
13
|
+
const defaultPermissionGroups = config_1.config.permissionGroups?.find(group => group.isDefault);
|
|
14
|
+
if (defaultPermissionGroups == null) {
|
|
15
|
+
throw new Error('Default permission group not found');
|
|
16
|
+
}
|
|
17
|
+
return defaultPermissionGroups;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Get the anonymous permission group
|
|
21
|
+
* @returns Anonymous permission group
|
|
22
|
+
* @throws Error if anonymous permission group not found
|
|
23
|
+
*/
|
|
24
|
+
function getDefaultAnonymousPermissionGroup() {
|
|
25
|
+
const anonymousPermission = config_1.config.permissionGroups?.find(group => group.isAnonymous);
|
|
26
|
+
if (anonymousPermission == null) {
|
|
27
|
+
throw new Error('Anonymous permission group not found');
|
|
28
|
+
}
|
|
29
|
+
return anonymousPermission;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Get the administrator permission group
|
|
33
|
+
* @returns Administrator permission group
|
|
34
|
+
* @throws Error if administrator permission group not found
|
|
35
|
+
*/
|
|
36
|
+
function getDefaultAdministratorPermissionGroup() {
|
|
37
|
+
const administratorPermission = config_1.config.permissionGroups?.find(group => group.title.toString() === 'administrator');
|
|
38
|
+
if (administratorPermission == null) {
|
|
39
|
+
throw new Error('Administrator permission group not found');
|
|
40
|
+
}
|
|
41
|
+
return administratorPermission;
|
|
42
|
+
}
|