@modular-rest/server 1.11.14 → 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.
- package/dist/application.d.ts +29 -0
- package/dist/application.js +217 -0
- package/dist/class/cms_trigger.d.ts +52 -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 +90 -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 +113 -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/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 +412 -0
- package/dist/services/data_provider/service.d.ts +132 -0
- package/dist/services/data_provider/service.js +253 -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 +68 -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 +632 -0
- package/package.json +3 -3
- package/src/application.ts +1 -1
- package/src/class/cms_trigger.ts +8 -14
- package/src/class/database_trigger.ts +10 -4
- package/src/class/user.ts +1 -1
- package/src/services/data_provider/router.ts +293 -0
- package/src/services/data_provider/service.ts +2 -1
- package/src/services/functions/router.ts +3 -2
- package/src/services/user_manager/db.ts +5 -5
- package/src/services/user_manager/service.ts +20 -15
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Setup options interface for initializing required services
|
|
3
|
+
* @interface SetupOptions
|
|
4
|
+
* @property {Object} [keypair] - JWT keypair configuration
|
|
5
|
+
* @property {string} keypair.private - Private key for JWT signing
|
|
6
|
+
* @property {string} keypair.public - Public key for JWT verification
|
|
7
|
+
* @property {Object} adminUser - Admin user configuration
|
|
8
|
+
* @property {string} adminUser.email - Admin user email address
|
|
9
|
+
* @property {string} adminUser.password - Admin user password
|
|
10
|
+
* @property {string} [uploadDirectory] - Directory for file uploads
|
|
11
|
+
*/
|
|
12
|
+
interface SetupOptions {
|
|
13
|
+
keypair?: {
|
|
14
|
+
private: string;
|
|
15
|
+
public: string;
|
|
16
|
+
};
|
|
17
|
+
adminUser: {
|
|
18
|
+
email: string;
|
|
19
|
+
password: string;
|
|
20
|
+
};
|
|
21
|
+
uploadDirectory?: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Sets up required services for the application to run
|
|
25
|
+
* @function setup
|
|
26
|
+
* @param {SetupOptions} options - Setup configuration options
|
|
27
|
+
* @returns {Promise<void>} A promise that resolves when setup is complete
|
|
28
|
+
* @throws {Error} If admin user configuration is missing or if setup fails
|
|
29
|
+
* @description
|
|
30
|
+
* This function performs the following setup operations:
|
|
31
|
+
* 1. Configures JWT with provided or generated keypair
|
|
32
|
+
* 2. Creates default system users (admin and anonymous)
|
|
33
|
+
* 3. Configures file upload directory if specified
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* // Setup with custom keypair
|
|
38
|
+
* await setup({
|
|
39
|
+
* keypair: {
|
|
40
|
+
* private: 'your-private-key',
|
|
41
|
+
* public: 'your-public-key'
|
|
42
|
+
* },
|
|
43
|
+
* adminUser: {
|
|
44
|
+
* email: 'admin@example.com',
|
|
45
|
+
* password: 'secure-password'
|
|
46
|
+
* },
|
|
47
|
+
* uploadDirectory: './uploads'
|
|
48
|
+
* });
|
|
49
|
+
*
|
|
50
|
+
* // Setup with auto-generated keypair
|
|
51
|
+
* await setup({
|
|
52
|
+
* adminUser: {
|
|
53
|
+
* email: 'admin@example.com',
|
|
54
|
+
* password: 'secure-password'
|
|
55
|
+
* }
|
|
56
|
+
* });
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export declare function setup({ keypair, adminUser, uploadDirectory }: SetupOptions): Promise<void>;
|
|
60
|
+
export {};
|
|
@@ -0,0 +1,108 @@
|
|
|
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.setup = setup;
|
|
40
|
+
const DataInsertion = __importStar(require("./data_insertion"));
|
|
41
|
+
const JWT = __importStar(require("../services/jwt/service"));
|
|
42
|
+
const FileService = __importStar(require("../services/file/service"));
|
|
43
|
+
const keypair_1 = __importDefault(require("keypair"));
|
|
44
|
+
/**
|
|
45
|
+
* Sets up required services for the application to run
|
|
46
|
+
* @function setup
|
|
47
|
+
* @param {SetupOptions} options - Setup configuration options
|
|
48
|
+
* @returns {Promise<void>} A promise that resolves when setup is complete
|
|
49
|
+
* @throws {Error} If admin user configuration is missing or if setup fails
|
|
50
|
+
* @description
|
|
51
|
+
* This function performs the following setup operations:
|
|
52
|
+
* 1. Configures JWT with provided or generated keypair
|
|
53
|
+
* 2. Creates default system users (admin and anonymous)
|
|
54
|
+
* 3. Configures file upload directory if specified
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```typescript
|
|
58
|
+
* // Setup with custom keypair
|
|
59
|
+
* await setup({
|
|
60
|
+
* keypair: {
|
|
61
|
+
* private: 'your-private-key',
|
|
62
|
+
* public: 'your-public-key'
|
|
63
|
+
* },
|
|
64
|
+
* adminUser: {
|
|
65
|
+
* email: 'admin@example.com',
|
|
66
|
+
* password: 'secure-password'
|
|
67
|
+
* },
|
|
68
|
+
* uploadDirectory: './uploads'
|
|
69
|
+
* });
|
|
70
|
+
*
|
|
71
|
+
* // Setup with auto-generated keypair
|
|
72
|
+
* await setup({
|
|
73
|
+
* adminUser: {
|
|
74
|
+
* email: 'admin@example.com',
|
|
75
|
+
* password: 'secure-password'
|
|
76
|
+
* }
|
|
77
|
+
* });
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
async function setup({ keypair, adminUser, uploadDirectory }) {
|
|
81
|
+
/**
|
|
82
|
+
* Json web Token
|
|
83
|
+
*
|
|
84
|
+
* Setup private and public keys for JWT module
|
|
85
|
+
*/
|
|
86
|
+
let keyPairToUse = keypair;
|
|
87
|
+
if (!keyPairToUse) {
|
|
88
|
+
// generate new keypair
|
|
89
|
+
keyPairToUse = (0, keypair_1.default)();
|
|
90
|
+
}
|
|
91
|
+
JWT.main.setKies(keyPairToUse.private, keyPairToUse.public);
|
|
92
|
+
if (!adminUser) {
|
|
93
|
+
throw new Error('Admin user is not supported in TypeScript version');
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Data Insertion
|
|
97
|
+
*
|
|
98
|
+
* Insert admin user
|
|
99
|
+
* for the first time
|
|
100
|
+
*/
|
|
101
|
+
await DataInsertion.createAdminUser(adminUser);
|
|
102
|
+
/**
|
|
103
|
+
* File Service
|
|
104
|
+
*/
|
|
105
|
+
if (uploadDirectory) {
|
|
106
|
+
FileService.main.setUploadDirectory(uploadDirectory);
|
|
107
|
+
}
|
|
108
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { createRest } from './application';
|
|
2
|
+
import { Schema } from 'mongoose';
|
|
3
|
+
import * as paginator from './class/paginator';
|
|
4
|
+
import * as reply from './class/reply';
|
|
5
|
+
import { validator } from './class/validator';
|
|
6
|
+
import { getCollection } from './services/data_provider/service';
|
|
7
|
+
import { defineFunction } from './services/functions/service';
|
|
8
|
+
import TypeCasters from './services/data_provider/typeCasters';
|
|
9
|
+
import { main as userManager } from './services/user_manager/service';
|
|
10
|
+
import { main as fileService } from './services/file/service';
|
|
11
|
+
import { CollectionDefinition, defineCollection } from './class/collection_definition';
|
|
12
|
+
import { schemas } from './class/db_schemas';
|
|
13
|
+
import DatabaseTrigger from './class/database_trigger';
|
|
14
|
+
import CmsTrigger from './class/cms_trigger';
|
|
15
|
+
import { AccessDefinition, Permission, PermissionTypes, PermissionGroup, AccessTypes } from './class/security';
|
|
16
|
+
import * as middleware from './middlewares';
|
|
17
|
+
/**
|
|
18
|
+
* @description Creates a new REST API instance
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* const rest = createRest();
|
|
22
|
+
* ```
|
|
23
|
+
* @returns A new REST API instance
|
|
24
|
+
*/
|
|
25
|
+
export { createRest };
|
|
26
|
+
export { CollectionDefinition, defineCollection };
|
|
27
|
+
/**
|
|
28
|
+
* @description Provides predefined database schemas
|
|
29
|
+
* @example
|
|
30
|
+
* ```typescript
|
|
31
|
+
* const userSchema = new Schema({
|
|
32
|
+
* name: String,
|
|
33
|
+
* avatar: Schemas.file
|
|
34
|
+
* });
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export { schemas };
|
|
38
|
+
/**
|
|
39
|
+
* @description Mongoose Schema class for defining data models
|
|
40
|
+
*/
|
|
41
|
+
export { Schema };
|
|
42
|
+
/**
|
|
43
|
+
* @description Handles database triggers and events
|
|
44
|
+
* @example
|
|
45
|
+
* ```typescript
|
|
46
|
+
* const trigger = new DatabaseTrigger('insert-one', (data) => {
|
|
47
|
+
* // Handle insert event
|
|
48
|
+
* });
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export { DatabaseTrigger };
|
|
52
|
+
/**
|
|
53
|
+
* @description Handles CMS triggers and events
|
|
54
|
+
*/
|
|
55
|
+
export { CmsTrigger };
|
|
56
|
+
/**
|
|
57
|
+
* @description Security and access control definitions
|
|
58
|
+
* @example
|
|
59
|
+
* ```typescript
|
|
60
|
+
* const permission = new Permission({
|
|
61
|
+
* type: 'user_access',
|
|
62
|
+
* read: true,
|
|
63
|
+
* write: true
|
|
64
|
+
* });
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export { AccessDefinition, Permission, PermissionTypes, PermissionGroup, AccessTypes };
|
|
68
|
+
/**
|
|
69
|
+
* @description Defines custom functions for the API
|
|
70
|
+
* @example
|
|
71
|
+
* ```typescript
|
|
72
|
+
* defineFunction('sendEmail', async (data) => {
|
|
73
|
+
* // Send email logic
|
|
74
|
+
* });
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
export { defineFunction };
|
|
78
|
+
/**
|
|
79
|
+
* @description Type casting utilities for data transformation
|
|
80
|
+
*/
|
|
81
|
+
export { TypeCasters };
|
|
82
|
+
/**
|
|
83
|
+
* @description Input validation utilities
|
|
84
|
+
*/
|
|
85
|
+
export { validator };
|
|
86
|
+
/**
|
|
87
|
+
* @description Response handling utilities
|
|
88
|
+
*/
|
|
89
|
+
export { reply };
|
|
90
|
+
/**
|
|
91
|
+
* @description Pagination utilities
|
|
92
|
+
*/
|
|
93
|
+
export { paginator };
|
|
94
|
+
/**
|
|
95
|
+
* @description Database collection access utilities
|
|
96
|
+
*/
|
|
97
|
+
export { getCollection };
|
|
98
|
+
/**
|
|
99
|
+
* @description File handling utilities
|
|
100
|
+
* @example
|
|
101
|
+
* ```typescript
|
|
102
|
+
* const file = await fileService.getFile('fileId');
|
|
103
|
+
* const link = fileService.getFileLink('fileId');
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
export { fileService };
|
|
107
|
+
/**
|
|
108
|
+
* @description Middleware utilities
|
|
109
|
+
*/
|
|
110
|
+
export { middleware };
|
|
111
|
+
/**
|
|
112
|
+
* @description User management utilities
|
|
113
|
+
* @example
|
|
114
|
+
* ```typescript
|
|
115
|
+
* const user = await userManager.getUserById('userId');
|
|
116
|
+
* ```
|
|
117
|
+
*/
|
|
118
|
+
export { userManager };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Context, Next } from 'koa';
|
|
2
|
+
/**
|
|
3
|
+
* Authentication middleware that secures routes by validating user tokens and managing access control.
|
|
4
|
+
*
|
|
5
|
+
* This middleware performs several key functions:
|
|
6
|
+
* 1. Validates that the incoming request contains an authorization token in the header
|
|
7
|
+
* 2. Verifies the token is valid by checking against the user management service
|
|
8
|
+
* 3. Retrieves the associated user object if the token is valid
|
|
9
|
+
* 4. Attaches the authenticated {@link User} object on ctx.state.user for use in subsequent middleware/routes
|
|
10
|
+
* 5. Throws appropriate HTTP errors (401, 412) if authentication fails
|
|
11
|
+
*
|
|
12
|
+
* The middleware integrates with the permission system to enable role-based access control.
|
|
13
|
+
* The attached user object provides methods like hasPermission() to check specific permissions.
|
|
14
|
+
*
|
|
15
|
+
* Common usage patterns:
|
|
16
|
+
* - Protecting sensitive API endpoints
|
|
17
|
+
* - Implementing role-based access control
|
|
18
|
+
* - Getting the current authenticated user
|
|
19
|
+
* - Validating user permissions before allowing actions
|
|
20
|
+
*
|
|
21
|
+
* @throws {Error} 401 - If no authorization header is present
|
|
22
|
+
* @throws {Error} 412 - If token validation fails
|
|
23
|
+
* @param ctx - Koa Context object containing request/response data
|
|
24
|
+
* @param next - Function to invoke next middleware
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* // Inside the router.ts file
|
|
29
|
+
* import { auth } from '@modular-rest/server';
|
|
30
|
+
* import { Router } from 'koa-router';
|
|
31
|
+
*
|
|
32
|
+
* const name = 'flowers';
|
|
33
|
+
*
|
|
34
|
+
* const flowerRouter = new Router();
|
|
35
|
+
*
|
|
36
|
+
* flowerRouter.get('/list', auth, (ctx) => {
|
|
37
|
+
* // Get the authenticated user
|
|
38
|
+
* const user = ctx.state.user;
|
|
39
|
+
*
|
|
40
|
+
* // Then you can check the user's role and permission
|
|
41
|
+
* if(user.hasPermission('get_flower')) {
|
|
42
|
+
* ctx.body = 'This is a list of flowers: Rose, Lily, Tulip';
|
|
43
|
+
* } else {
|
|
44
|
+
* ctx.status = 403;
|
|
45
|
+
* ctx.body = 'You are not authorized to access this resource';
|
|
46
|
+
* }
|
|
47
|
+
* });
|
|
48
|
+
*
|
|
49
|
+
* module.exports.name = name;
|
|
50
|
+
* module.exports.main = flowerRouter;
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export declare function auth(ctx: Context, next: Next): Promise<void>;
|
|
@@ -0,0 +1,106 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.auth = auth;
|
|
37
|
+
const validator_1 = require("./class/validator");
|
|
38
|
+
const userManager = __importStar(require("./services/user_manager/service"));
|
|
39
|
+
/**
|
|
40
|
+
* Authentication middleware that secures routes by validating user tokens and managing access control.
|
|
41
|
+
*
|
|
42
|
+
* This middleware performs several key functions:
|
|
43
|
+
* 1. Validates that the incoming request contains an authorization token in the header
|
|
44
|
+
* 2. Verifies the token is valid by checking against the user management service
|
|
45
|
+
* 3. Retrieves the associated user object if the token is valid
|
|
46
|
+
* 4. Attaches the authenticated {@link User} object on ctx.state.user for use in subsequent middleware/routes
|
|
47
|
+
* 5. Throws appropriate HTTP errors (401, 412) if authentication fails
|
|
48
|
+
*
|
|
49
|
+
* The middleware integrates with the permission system to enable role-based access control.
|
|
50
|
+
* The attached user object provides methods like hasPermission() to check specific permissions.
|
|
51
|
+
*
|
|
52
|
+
* Common usage patterns:
|
|
53
|
+
* - Protecting sensitive API endpoints
|
|
54
|
+
* - Implementing role-based access control
|
|
55
|
+
* - Getting the current authenticated user
|
|
56
|
+
* - Validating user permissions before allowing actions
|
|
57
|
+
*
|
|
58
|
+
* @throws {Error} 401 - If no authorization header is present
|
|
59
|
+
* @throws {Error} 412 - If token validation fails
|
|
60
|
+
* @param ctx - Koa Context object containing request/response data
|
|
61
|
+
* @param next - Function to invoke next middleware
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```typescript
|
|
65
|
+
* // Inside the router.ts file
|
|
66
|
+
* import { auth } from '@modular-rest/server';
|
|
67
|
+
* import { Router } from 'koa-router';
|
|
68
|
+
*
|
|
69
|
+
* const name = 'flowers';
|
|
70
|
+
*
|
|
71
|
+
* const flowerRouter = new Router();
|
|
72
|
+
*
|
|
73
|
+
* flowerRouter.get('/list', auth, (ctx) => {
|
|
74
|
+
* // Get the authenticated user
|
|
75
|
+
* const user = ctx.state.user;
|
|
76
|
+
*
|
|
77
|
+
* // Then you can check the user's role and permission
|
|
78
|
+
* if(user.hasPermission('get_flower')) {
|
|
79
|
+
* ctx.body = 'This is a list of flowers: Rose, Lily, Tulip';
|
|
80
|
+
* } else {
|
|
81
|
+
* ctx.status = 403;
|
|
82
|
+
* ctx.body = 'You are not authorized to access this resource';
|
|
83
|
+
* }
|
|
84
|
+
* });
|
|
85
|
+
*
|
|
86
|
+
* module.exports.name = name;
|
|
87
|
+
* module.exports.main = flowerRouter;
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
async function auth(ctx, next) {
|
|
91
|
+
const headers = ctx.header;
|
|
92
|
+
const headersValidated = (0, validator_1.validator)(headers, 'authorization');
|
|
93
|
+
if (!headersValidated.isValid)
|
|
94
|
+
ctx.throw(401, 'authentication is required');
|
|
95
|
+
const token = headers.authorization;
|
|
96
|
+
await userManager.main
|
|
97
|
+
.getUserByToken(token)
|
|
98
|
+
.then(async (user) => {
|
|
99
|
+
ctx.state.user = user;
|
|
100
|
+
await next();
|
|
101
|
+
})
|
|
102
|
+
.catch(err => {
|
|
103
|
+
console.log(err);
|
|
104
|
+
ctx.throw(err.status || 412, err.message);
|
|
105
|
+
});
|
|
106
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|