@grandlinex/kernel 1.3.0 → 1.3.2
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/cjs/classes/BaseAction.d.ts +3 -3
- package/dist/cjs/classes/BaseAction.js +13 -3
- package/dist/cjs/classes/BaseAuthProvider.d.ts +3 -2
- package/dist/cjs/classes/BaseEndpoint.d.ts +1 -1
- package/dist/cjs/classes/BaseEndpoint.js +1 -1
- package/dist/cjs/lib/index.d.ts +65 -3
- package/dist/cjs/lib/index.js +0 -6
- package/dist/cjs/modules/crypto/CryptoClient.d.ts +2 -2
- package/dist/cjs/modules/crypto/CryptoClient.js +2 -2
- package/dist/mjs/classes/BaseAction.d.ts +3 -3
- package/dist/mjs/classes/BaseAction.js +15 -5
- package/dist/mjs/classes/BaseAuthProvider.d.ts +3 -2
- package/dist/mjs/classes/BaseEndpoint.d.ts +1 -1
- package/dist/mjs/classes/BaseEndpoint.js +1 -1
- package/dist/mjs/lib/index.d.ts +65 -3
- package/dist/mjs/lib/index.js +1 -2
- package/dist/mjs/modules/crypto/CryptoClient.d.ts +2 -2
- package/dist/mjs/modules/crypto/CryptoClient.js +2 -2
- package/package.json +5 -5
- package/dist/cjs/lib/EntitySchemaExtender.d.ts +0 -11
- package/dist/cjs/lib/EntitySchemaExtender.js +0 -50
- package/dist/mjs/lib/EntitySchemaExtender.d.ts +0 -11
- package/dist/mjs/lib/EntitySchemaExtender.js +0 -47
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { CoreAction, IDataBase } from '@grandlinex/core';
|
|
1
|
+
import { CoreAction, CoreEntity, IDataBase } from '@grandlinex/core';
|
|
2
2
|
import { ActionMode, ErrorType, SSchemaEl } from '@grandlinex/swagger-mate';
|
|
3
3
|
import { IBaseAction, IBaseCache, IBaseClient, IBaseKernelModule, IBasePresenter, IKernel } from '../lib/index.js';
|
|
4
4
|
import { XActionEvent, XRequest, XResponse } from '../lib/express.js';
|
|
5
5
|
export default abstract class BaseAction<K extends IKernel = IKernel, T extends IDataBase<any, any> | null = any, P extends IBaseClient | null = any, C extends IBaseCache | null = any, E extends IBasePresenter | null = any> extends CoreAction<K, T, P, C, E> implements IBaseAction<K, T, P, C, E> {
|
|
6
6
|
mode: ActionMode;
|
|
7
7
|
forceDebug: boolean;
|
|
8
|
-
requestSchema: SSchemaEl | null;
|
|
8
|
+
requestSchema: SSchemaEl | CoreEntity | string | null;
|
|
9
9
|
constructor(chanel: string, module: IBaseKernelModule<K, T, P, C, E>);
|
|
10
10
|
abstract handler(event: XActionEvent): Promise<void>;
|
|
11
|
-
static validateSchema(error: ErrorType,
|
|
11
|
+
static validateSchema(error: ErrorType, inputSchema: SSchemaEl | CoreEntity | string, key: string, field: any, required?: boolean): void;
|
|
12
12
|
bodyValidation<A>(req: XRequest): A | ErrorType | null;
|
|
13
13
|
static sendError(res: XResponse, code: number, error: Partial<ErrorType>): void;
|
|
14
14
|
secureHandler(req: XRequest, res: XResponse, next: () => void): Promise<void>;
|
|
@@ -12,11 +12,18 @@ class BaseAction extends core_1.CoreAction {
|
|
|
12
12
|
this.forceDebug = false;
|
|
13
13
|
this.requestSchema = null;
|
|
14
14
|
}
|
|
15
|
-
static validateSchema(error,
|
|
16
|
-
|
|
15
|
+
static validateSchema(error, inputSchema, key, field, required = true) {
|
|
16
|
+
let schema;
|
|
17
|
+
if ((0, core_1.instanceOfEntity)(inputSchema)) {
|
|
18
|
+
schema = swagger_mate_1.SPathUtil.schemaFromEntity(inputSchema);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
schema = inputSchema;
|
|
22
|
+
}
|
|
23
|
+
if ((0, swagger_mate_1.isSwaggerRef)(schema) || typeof schema === 'string') {
|
|
17
24
|
error.field?.push({
|
|
18
25
|
key,
|
|
19
|
-
message: `Ref schema body validation is not supported yet`,
|
|
26
|
+
message: `Ref or string schema body validation is not supported yet`,
|
|
20
27
|
});
|
|
21
28
|
return;
|
|
22
29
|
}
|
|
@@ -132,6 +139,7 @@ class BaseAction extends core_1.CoreAction {
|
|
|
132
139
|
body = this.bodyValidation(req);
|
|
133
140
|
}
|
|
134
141
|
if ((0, swagger_mate_1.isErrorType)(body)) {
|
|
142
|
+
this.debug(body);
|
|
135
143
|
res.status(400).send(body);
|
|
136
144
|
return;
|
|
137
145
|
}
|
|
@@ -168,6 +176,7 @@ class BaseAction extends core_1.CoreAction {
|
|
|
168
176
|
body = this.bodyValidation(req);
|
|
169
177
|
}
|
|
170
178
|
if ((0, swagger_mate_1.isErrorType)(body)) {
|
|
179
|
+
this.debug(body);
|
|
171
180
|
res.status(400).send(body);
|
|
172
181
|
return;
|
|
173
182
|
}
|
|
@@ -201,6 +210,7 @@ class BaseAction extends core_1.CoreAction {
|
|
|
201
210
|
body = this.bodyValidation(req);
|
|
202
211
|
}
|
|
203
212
|
if ((0, swagger_mate_1.isErrorType)(body)) {
|
|
213
|
+
this.debug(body);
|
|
204
214
|
res.status(400).send(body);
|
|
205
215
|
return;
|
|
206
216
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as jwt from 'jsonwebtoken';
|
|
2
2
|
import { XRequest } from '../lib/express.js';
|
|
3
|
+
import { ValidationRequest } from '../lib/index.js';
|
|
3
4
|
export type JwtExtend = {
|
|
4
5
|
username: string;
|
|
5
6
|
userid: string;
|
|
@@ -11,13 +12,13 @@ export type AuthResult = {
|
|
|
11
12
|
};
|
|
12
13
|
export interface IAuthProvider<T extends JwtExtend> {
|
|
13
14
|
authorizeToken(userid: string, token: string, requestType: string): Promise<AuthResult>;
|
|
14
|
-
validateAccess(
|
|
15
|
+
validateAccess(request: ValidationRequest<T>): Promise<boolean>;
|
|
15
16
|
bearerTokenValidation(req: XRequest): Promise<JwtToken<T> | number>;
|
|
16
17
|
jwtAddData(token: JwtToken<T>, extend?: Record<string, any>): Promise<JwtToken<T>>;
|
|
17
18
|
}
|
|
18
19
|
export default abstract class BaseAuthProvider<T extends JwtExtend = JwtExtend> implements IAuthProvider<T> {
|
|
19
20
|
abstract authorizeToken(username: string, token: string, requestType: string): Promise<AuthResult>;
|
|
20
|
-
abstract validateAccess(
|
|
21
|
+
abstract validateAccess(request: ValidationRequest<T>): Promise<boolean>;
|
|
21
22
|
abstract bearerTokenValidation(req: XRequest): Promise<JwtToken<T> | number>;
|
|
22
23
|
jwtAddData(token: JwtToken<T>, extend?: Record<string, any>): Promise<JwtToken<T>>;
|
|
23
24
|
}
|
|
@@ -8,7 +8,7 @@ export default abstract class BaseEndpoint<K extends IKernel = IKernel, T extend
|
|
|
8
8
|
protected appServer: express.Express;
|
|
9
9
|
protected httpServer: http.Server;
|
|
10
10
|
protected port: number;
|
|
11
|
-
constructor(chanel: string, module: IBaseKernelModule<any
|
|
11
|
+
constructor(chanel: string, module: IBaseKernelModule<any>, port: number);
|
|
12
12
|
private setAppHeader;
|
|
13
13
|
appServerOverride(app: Express): void;
|
|
14
14
|
start(): Promise<boolean>;
|
package/dist/cjs/lib/index.d.ts
CHANGED
|
@@ -2,19 +2,81 @@ import { ICoreAction, ICoreBridge, ICoreCache, ICoreCClient, ICoreClient, ICoreE
|
|
|
2
2
|
import express from 'express';
|
|
3
3
|
import * as jwt from 'jsonwebtoken';
|
|
4
4
|
import { IAuthProvider, JwtExtend, JwtToken } from '../classes/index.js';
|
|
5
|
-
import EntitySchemaExtender from './EntitySchemaExtender.js';
|
|
6
5
|
import { XActionEvent, XRequest } from './express.js';
|
|
7
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Represents a request for validating a JWT token with optional constraints.
|
|
8
|
+
*
|
|
9
|
+
* @template T - The shape of the JWT claims, extending {@link JwtExtend}.
|
|
10
|
+
*
|
|
11
|
+
* This type includes:
|
|
12
|
+
* - **token**: the JWT token to validate.
|
|
13
|
+
* - **requestType**: an array of request type identifiers that the token must satisfy.
|
|
14
|
+
* - **required** (optional): indicates whether the token is mandatory for the request; if omitted, the token is considered required.
|
|
15
|
+
*/
|
|
16
|
+
export type ValidationRequest<T extends JwtExtend = JwtExtend> = {
|
|
17
|
+
token: JwtToken<T>;
|
|
18
|
+
requestType: string[];
|
|
19
|
+
required?: boolean;
|
|
20
|
+
};
|
|
8
21
|
export interface ICClient<T extends JwtExtend = JwtExtend> extends ICoreCClient {
|
|
22
|
+
/**
|
|
23
|
+
* Assigns the authentication provider responsible for handling authentication operations.
|
|
24
|
+
*
|
|
25
|
+
* @param provider The authentication provider to use.
|
|
26
|
+
* @return True if the provider was set successfully; otherwise, false.
|
|
27
|
+
*/
|
|
9
28
|
setAuthProvider(provider: IAuthProvider<T>): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Verifies a JWT access token and returns the decoded payload or an error code.
|
|
31
|
+
*
|
|
32
|
+
* @param token - The JWT access token string to verify.
|
|
33
|
+
* @return A promise that resolves to the decoded token payload of type {@link JwtToken<T>} if verification succeeds, or a numeric error code if verification fails.
|
|
34
|
+
*/
|
|
10
35
|
jwtVerifyAccessToken(token: string): Promise<JwtToken<T> | number>;
|
|
36
|
+
/**
|
|
37
|
+
* Decodes a JWT access token and returns its payload.
|
|
38
|
+
*
|
|
39
|
+
* @param {string} token - The JWT access token to decode.
|
|
40
|
+
* @returns {jwt.JwtPayload | null} The decoded payload if the token is valid, otherwise null.
|
|
41
|
+
*/
|
|
11
42
|
jwtDecodeAccessToken(token: string): jwt.JwtPayload | null;
|
|
43
|
+
/**
|
|
44
|
+
* Generates a signed JWT access token.
|
|
45
|
+
*
|
|
46
|
+
* @param {JwtToken<T>} data - The payload data for the token.
|
|
47
|
+
* @param {Record<string, any>} [extend] - Optional additional fields to merge into the token payload.
|
|
48
|
+
* @param {string|number} [expire] - Optional expiration time for the token, expressed in seconds or as an ISO 8601 duration string.
|
|
49
|
+
* @return {Promise<string>} A promise that resolves to the generated JWT token string.
|
|
50
|
+
*/
|
|
12
51
|
jwtGenerateAccessToken(data: JwtToken<T>, extend?: Record<string, any>, expire?: string | number): Promise<string>;
|
|
52
|
+
/**
|
|
53
|
+
* Validates an API token for a specified user and request type.
|
|
54
|
+
*
|
|
55
|
+
* @param {string} username - The username associated with the token.
|
|
56
|
+
* @param {string} token - The API token to validate.
|
|
57
|
+
* @param {string} requestType - The type of request for which the token is being validated.
|
|
58
|
+
* @returns {Promise<{ valid: boolean; userId: string | null }>} A promise that resolves to an object containing a boolean indicating whether the token is valid and the user ID if validation succeeds; otherwise, `null` is returned for the user ID.
|
|
59
|
+
*/
|
|
13
60
|
apiTokenValidation(username: string, token: string, requestType: string): Promise<{
|
|
14
61
|
valid: boolean;
|
|
15
62
|
userId: string | null;
|
|
16
63
|
}>;
|
|
17
|
-
|
|
64
|
+
/**
|
|
65
|
+
* Validates user permissions according to the supplied validation request.
|
|
66
|
+
*
|
|
67
|
+
* @param {ValidationRequest<T>} request - The request object containing the necessary
|
|
68
|
+
* data for permission evaluation, such as user identity, requested action,
|
|
69
|
+
* and contextual parameters.
|
|
70
|
+
*
|
|
71
|
+
* @return {Promise<boolean>} A promise that resolves to `true` if the permissions
|
|
72
|
+
* are valid for the specified request, otherwise resolves to `false`.
|
|
73
|
+
*/
|
|
74
|
+
permissionValidation(request: ValidationRequest<T>): Promise<boolean>;
|
|
75
|
+
/**
|
|
76
|
+
* Validates the bearer token present in the provided request.
|
|
77
|
+
* @param {XRequest} req - The HTTP request containing the Authorization header.
|
|
78
|
+
* @return {Promise<JwtToken<T> | number>} A promise that resolves to the decoded JWT payload if the token is valid, or a numeric status code (e.g., 401) if validation fails.
|
|
79
|
+
*/
|
|
18
80
|
bearerTokenValidation(req: XRequest): Promise<JwtToken<T> | number>;
|
|
19
81
|
}
|
|
20
82
|
export interface IKernel<T extends JwtExtend = JwtExtend> extends ICoreKernel<ICClient<T>> {
|
package/dist/cjs/lib/index.js
CHANGED
|
@@ -1,8 +1,2 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.EntitySchemaExtender = void 0;
|
|
7
|
-
const EntitySchemaExtender_js_1 = __importDefault(require("./EntitySchemaExtender.js"));
|
|
8
|
-
exports.EntitySchemaExtender = EntitySchemaExtender_js_1.default;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CoreCryptoClient } from '@grandlinex/core';
|
|
2
2
|
import { type StringValue } from 'ms';
|
|
3
|
-
import { ICClient, IKernel } from '../../lib/index.js';
|
|
3
|
+
import { ICClient, IKernel, ValidationRequest } from '../../lib/index.js';
|
|
4
4
|
import { IAuthProvider, JwtExtend, JwtToken } from '../../classes/index.js';
|
|
5
5
|
import { XRequest } from '../../lib/express.js';
|
|
6
6
|
export default class CryptoClient<T extends JwtExtend = JwtExtend> extends CoreCryptoClient implements ICClient<T> {
|
|
@@ -16,6 +16,6 @@ export default class CryptoClient<T extends JwtExtend = JwtExtend> extends CoreC
|
|
|
16
16
|
valid: boolean;
|
|
17
17
|
userId: string | null;
|
|
18
18
|
}>;
|
|
19
|
-
permissionValidation(
|
|
19
|
+
permissionValidation(request: ValidationRequest<T>): Promise<boolean>;
|
|
20
20
|
bearerTokenValidation(req: XRequest): Promise<JwtToken<T> | number>;
|
|
21
21
|
}
|
|
@@ -103,9 +103,9 @@ class CryptoClient extends core_1.CoreCryptoClient {
|
|
|
103
103
|
userId: null,
|
|
104
104
|
};
|
|
105
105
|
}
|
|
106
|
-
async permissionValidation(
|
|
106
|
+
async permissionValidation(request) {
|
|
107
107
|
if (this.authProvider) {
|
|
108
|
-
return this.authProvider.validateAccess(
|
|
108
|
+
return this.authProvider.validateAccess(request);
|
|
109
109
|
}
|
|
110
110
|
return false;
|
|
111
111
|
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { CoreAction, IDataBase } from '@grandlinex/core';
|
|
1
|
+
import { CoreAction, CoreEntity, IDataBase } from '@grandlinex/core';
|
|
2
2
|
import { ActionMode, ErrorType, SSchemaEl } from '@grandlinex/swagger-mate';
|
|
3
3
|
import { IBaseAction, IBaseCache, IBaseClient, IBaseKernelModule, IBasePresenter, IKernel } from '../lib/index.js';
|
|
4
4
|
import { XActionEvent, XRequest, XResponse } from '../lib/express.js';
|
|
5
5
|
export default abstract class BaseAction<K extends IKernel = IKernel, T extends IDataBase<any, any> | null = any, P extends IBaseClient | null = any, C extends IBaseCache | null = any, E extends IBasePresenter | null = any> extends CoreAction<K, T, P, C, E> implements IBaseAction<K, T, P, C, E> {
|
|
6
6
|
mode: ActionMode;
|
|
7
7
|
forceDebug: boolean;
|
|
8
|
-
requestSchema: SSchemaEl | null;
|
|
8
|
+
requestSchema: SSchemaEl | CoreEntity | string | null;
|
|
9
9
|
constructor(chanel: string, module: IBaseKernelModule<K, T, P, C, E>);
|
|
10
10
|
abstract handler(event: XActionEvent): Promise<void>;
|
|
11
|
-
static validateSchema(error: ErrorType,
|
|
11
|
+
static validateSchema(error: ErrorType, inputSchema: SSchemaEl | CoreEntity | string, key: string, field: any, required?: boolean): void;
|
|
12
12
|
bodyValidation<A>(req: XRequest): A | ErrorType | null;
|
|
13
13
|
static sendError(res: XResponse, code: number, error: Partial<ErrorType>): void;
|
|
14
14
|
secureHandler(req: XRequest, res: XResponse, next: () => void): Promise<void>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { CoreAction } from '@grandlinex/core';
|
|
2
|
-
import { ActionMode, isErrorType, isSwaggerRef, } from '@grandlinex/swagger-mate';
|
|
1
|
+
import { CoreAction, instanceOfEntity, } from '@grandlinex/core';
|
|
2
|
+
import { ActionMode, isErrorType, isSwaggerRef, SPathUtil, } from '@grandlinex/swagger-mate';
|
|
3
3
|
import { ExpressServerTiming } from './timing/index.js';
|
|
4
4
|
import { BaseUserAgent } from './BaseUserAgent.js';
|
|
5
5
|
export default class BaseAction extends CoreAction {
|
|
@@ -10,11 +10,18 @@ export default class BaseAction extends CoreAction {
|
|
|
10
10
|
this.forceDebug = false;
|
|
11
11
|
this.requestSchema = null;
|
|
12
12
|
}
|
|
13
|
-
static validateSchema(error,
|
|
14
|
-
|
|
13
|
+
static validateSchema(error, inputSchema, key, field, required = true) {
|
|
14
|
+
let schema;
|
|
15
|
+
if (instanceOfEntity(inputSchema)) {
|
|
16
|
+
schema = SPathUtil.schemaFromEntity(inputSchema);
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
schema = inputSchema;
|
|
20
|
+
}
|
|
21
|
+
if (isSwaggerRef(schema) || typeof schema === 'string') {
|
|
15
22
|
error.field?.push({
|
|
16
23
|
key,
|
|
17
|
-
message: `Ref schema body validation is not supported yet`,
|
|
24
|
+
message: `Ref or string schema body validation is not supported yet`,
|
|
18
25
|
});
|
|
19
26
|
return;
|
|
20
27
|
}
|
|
@@ -130,6 +137,7 @@ export default class BaseAction extends CoreAction {
|
|
|
130
137
|
body = this.bodyValidation(req);
|
|
131
138
|
}
|
|
132
139
|
if (isErrorType(body)) {
|
|
140
|
+
this.debug(body);
|
|
133
141
|
res.status(400).send(body);
|
|
134
142
|
return;
|
|
135
143
|
}
|
|
@@ -166,6 +174,7 @@ export default class BaseAction extends CoreAction {
|
|
|
166
174
|
body = this.bodyValidation(req);
|
|
167
175
|
}
|
|
168
176
|
if (isErrorType(body)) {
|
|
177
|
+
this.debug(body);
|
|
169
178
|
res.status(400).send(body);
|
|
170
179
|
return;
|
|
171
180
|
}
|
|
@@ -199,6 +208,7 @@ export default class BaseAction extends CoreAction {
|
|
|
199
208
|
body = this.bodyValidation(req);
|
|
200
209
|
}
|
|
201
210
|
if (isErrorType(body)) {
|
|
211
|
+
this.debug(body);
|
|
202
212
|
res.status(400).send(body);
|
|
203
213
|
return;
|
|
204
214
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as jwt from 'jsonwebtoken';
|
|
2
2
|
import { XRequest } from '../lib/express.js';
|
|
3
|
+
import { ValidationRequest } from '../lib/index.js';
|
|
3
4
|
export type JwtExtend = {
|
|
4
5
|
username: string;
|
|
5
6
|
userid: string;
|
|
@@ -11,13 +12,13 @@ export type AuthResult = {
|
|
|
11
12
|
};
|
|
12
13
|
export interface IAuthProvider<T extends JwtExtend> {
|
|
13
14
|
authorizeToken(userid: string, token: string, requestType: string): Promise<AuthResult>;
|
|
14
|
-
validateAccess(
|
|
15
|
+
validateAccess(request: ValidationRequest<T>): Promise<boolean>;
|
|
15
16
|
bearerTokenValidation(req: XRequest): Promise<JwtToken<T> | number>;
|
|
16
17
|
jwtAddData(token: JwtToken<T>, extend?: Record<string, any>): Promise<JwtToken<T>>;
|
|
17
18
|
}
|
|
18
19
|
export default abstract class BaseAuthProvider<T extends JwtExtend = JwtExtend> implements IAuthProvider<T> {
|
|
19
20
|
abstract authorizeToken(username: string, token: string, requestType: string): Promise<AuthResult>;
|
|
20
|
-
abstract validateAccess(
|
|
21
|
+
abstract validateAccess(request: ValidationRequest<T>): Promise<boolean>;
|
|
21
22
|
abstract bearerTokenValidation(req: XRequest): Promise<JwtToken<T> | number>;
|
|
22
23
|
jwtAddData(token: JwtToken<T>, extend?: Record<string, any>): Promise<JwtToken<T>>;
|
|
23
24
|
}
|
|
@@ -8,7 +8,7 @@ export default abstract class BaseEndpoint<K extends IKernel = IKernel, T extend
|
|
|
8
8
|
protected appServer: express.Express;
|
|
9
9
|
protected httpServer: http.Server;
|
|
10
10
|
protected port: number;
|
|
11
|
-
constructor(chanel: string, module: IBaseKernelModule<any
|
|
11
|
+
constructor(chanel: string, module: IBaseKernelModule<any>, port: number);
|
|
12
12
|
private setAppHeader;
|
|
13
13
|
appServerOverride(app: Express): void;
|
|
14
14
|
start(): Promise<boolean>;
|
package/dist/mjs/lib/index.d.ts
CHANGED
|
@@ -2,19 +2,81 @@ import { ICoreAction, ICoreBridge, ICoreCache, ICoreCClient, ICoreClient, ICoreE
|
|
|
2
2
|
import express from 'express';
|
|
3
3
|
import * as jwt from 'jsonwebtoken';
|
|
4
4
|
import { IAuthProvider, JwtExtend, JwtToken } from '../classes/index.js';
|
|
5
|
-
import EntitySchemaExtender from './EntitySchemaExtender.js';
|
|
6
5
|
import { XActionEvent, XRequest } from './express.js';
|
|
7
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Represents a request for validating a JWT token with optional constraints.
|
|
8
|
+
*
|
|
9
|
+
* @template T - The shape of the JWT claims, extending {@link JwtExtend}.
|
|
10
|
+
*
|
|
11
|
+
* This type includes:
|
|
12
|
+
* - **token**: the JWT token to validate.
|
|
13
|
+
* - **requestType**: an array of request type identifiers that the token must satisfy.
|
|
14
|
+
* - **required** (optional): indicates whether the token is mandatory for the request; if omitted, the token is considered required.
|
|
15
|
+
*/
|
|
16
|
+
export type ValidationRequest<T extends JwtExtend = JwtExtend> = {
|
|
17
|
+
token: JwtToken<T>;
|
|
18
|
+
requestType: string[];
|
|
19
|
+
required?: boolean;
|
|
20
|
+
};
|
|
8
21
|
export interface ICClient<T extends JwtExtend = JwtExtend> extends ICoreCClient {
|
|
22
|
+
/**
|
|
23
|
+
* Assigns the authentication provider responsible for handling authentication operations.
|
|
24
|
+
*
|
|
25
|
+
* @param provider The authentication provider to use.
|
|
26
|
+
* @return True if the provider was set successfully; otherwise, false.
|
|
27
|
+
*/
|
|
9
28
|
setAuthProvider(provider: IAuthProvider<T>): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Verifies a JWT access token and returns the decoded payload or an error code.
|
|
31
|
+
*
|
|
32
|
+
* @param token - The JWT access token string to verify.
|
|
33
|
+
* @return A promise that resolves to the decoded token payload of type {@link JwtToken<T>} if verification succeeds, or a numeric error code if verification fails.
|
|
34
|
+
*/
|
|
10
35
|
jwtVerifyAccessToken(token: string): Promise<JwtToken<T> | number>;
|
|
36
|
+
/**
|
|
37
|
+
* Decodes a JWT access token and returns its payload.
|
|
38
|
+
*
|
|
39
|
+
* @param {string} token - The JWT access token to decode.
|
|
40
|
+
* @returns {jwt.JwtPayload | null} The decoded payload if the token is valid, otherwise null.
|
|
41
|
+
*/
|
|
11
42
|
jwtDecodeAccessToken(token: string): jwt.JwtPayload | null;
|
|
43
|
+
/**
|
|
44
|
+
* Generates a signed JWT access token.
|
|
45
|
+
*
|
|
46
|
+
* @param {JwtToken<T>} data - The payload data for the token.
|
|
47
|
+
* @param {Record<string, any>} [extend] - Optional additional fields to merge into the token payload.
|
|
48
|
+
* @param {string|number} [expire] - Optional expiration time for the token, expressed in seconds or as an ISO 8601 duration string.
|
|
49
|
+
* @return {Promise<string>} A promise that resolves to the generated JWT token string.
|
|
50
|
+
*/
|
|
12
51
|
jwtGenerateAccessToken(data: JwtToken<T>, extend?: Record<string, any>, expire?: string | number): Promise<string>;
|
|
52
|
+
/**
|
|
53
|
+
* Validates an API token for a specified user and request type.
|
|
54
|
+
*
|
|
55
|
+
* @param {string} username - The username associated with the token.
|
|
56
|
+
* @param {string} token - The API token to validate.
|
|
57
|
+
* @param {string} requestType - The type of request for which the token is being validated.
|
|
58
|
+
* @returns {Promise<{ valid: boolean; userId: string | null }>} A promise that resolves to an object containing a boolean indicating whether the token is valid and the user ID if validation succeeds; otherwise, `null` is returned for the user ID.
|
|
59
|
+
*/
|
|
13
60
|
apiTokenValidation(username: string, token: string, requestType: string): Promise<{
|
|
14
61
|
valid: boolean;
|
|
15
62
|
userId: string | null;
|
|
16
63
|
}>;
|
|
17
|
-
|
|
64
|
+
/**
|
|
65
|
+
* Validates user permissions according to the supplied validation request.
|
|
66
|
+
*
|
|
67
|
+
* @param {ValidationRequest<T>} request - The request object containing the necessary
|
|
68
|
+
* data for permission evaluation, such as user identity, requested action,
|
|
69
|
+
* and contextual parameters.
|
|
70
|
+
*
|
|
71
|
+
* @return {Promise<boolean>} A promise that resolves to `true` if the permissions
|
|
72
|
+
* are valid for the specified request, otherwise resolves to `false`.
|
|
73
|
+
*/
|
|
74
|
+
permissionValidation(request: ValidationRequest<T>): Promise<boolean>;
|
|
75
|
+
/**
|
|
76
|
+
* Validates the bearer token present in the provided request.
|
|
77
|
+
* @param {XRequest} req - The HTTP request containing the Authorization header.
|
|
78
|
+
* @return {Promise<JwtToken<T> | number>} A promise that resolves to the decoded JWT payload if the token is valid, or a numeric status code (e.g., 401) if validation fails.
|
|
79
|
+
*/
|
|
18
80
|
bearerTokenValidation(req: XRequest): Promise<JwtToken<T> | number>;
|
|
19
81
|
}
|
|
20
82
|
export interface IKernel<T extends JwtExtend = JwtExtend> extends ICoreKernel<ICClient<T>> {
|
package/dist/mjs/lib/index.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export { EntitySchemaExtender };
|
|
1
|
+
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CoreCryptoClient } from '@grandlinex/core';
|
|
2
2
|
import { type StringValue } from 'ms';
|
|
3
|
-
import { ICClient, IKernel } from '../../lib/index.js';
|
|
3
|
+
import { ICClient, IKernel, ValidationRequest } from '../../lib/index.js';
|
|
4
4
|
import { IAuthProvider, JwtExtend, JwtToken } from '../../classes/index.js';
|
|
5
5
|
import { XRequest } from '../../lib/express.js';
|
|
6
6
|
export default class CryptoClient<T extends JwtExtend = JwtExtend> extends CoreCryptoClient implements ICClient<T> {
|
|
@@ -16,6 +16,6 @@ export default class CryptoClient<T extends JwtExtend = JwtExtend> extends CoreC
|
|
|
16
16
|
valid: boolean;
|
|
17
17
|
userId: string | null;
|
|
18
18
|
}>;
|
|
19
|
-
permissionValidation(
|
|
19
|
+
permissionValidation(request: ValidationRequest<T>): Promise<boolean>;
|
|
20
20
|
bearerTokenValidation(req: XRequest): Promise<JwtToken<T> | number>;
|
|
21
21
|
}
|
|
@@ -68,9 +68,9 @@ export default class CryptoClient extends CoreCryptoClient {
|
|
|
68
68
|
userId: null,
|
|
69
69
|
};
|
|
70
70
|
}
|
|
71
|
-
async permissionValidation(
|
|
71
|
+
async permissionValidation(request) {
|
|
72
72
|
if (this.authProvider) {
|
|
73
|
-
return this.authProvider.validateAccess(
|
|
73
|
+
return this.authProvider.validateAccess(request);
|
|
74
74
|
}
|
|
75
75
|
return false;
|
|
76
76
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@grandlinex/kernel",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.2",
|
|
4
4
|
"description": "GrandLineX is an out-of-the-box server framework on top of ExpressJs.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"license": "BSD-3-Clause",
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"@grandlinex/core": "1.3.1",
|
|
50
|
-
"@grandlinex/swagger-mate": "1.3.
|
|
50
|
+
"@grandlinex/swagger-mate": "1.3.3",
|
|
51
51
|
"@types/jsonwebtoken": "9.0.10",
|
|
52
52
|
"@types/ms": "2.1.0",
|
|
53
53
|
"body-parser": "2.2.1",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"express": ">=5.2.1"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
|
-
"@types/jest": "
|
|
63
|
+
"@types/jest": "30.0.0",
|
|
64
64
|
"@types/node": "22.15.20",
|
|
65
65
|
"@typescript-eslint/eslint-plugin": "7.18.0",
|
|
66
66
|
"@typescript-eslint/parser": "7.18.0",
|
|
@@ -72,10 +72,10 @@
|
|
|
72
72
|
"eslint-plugin-jest": "28.6.0",
|
|
73
73
|
"eslint-plugin-jsx-a11y": "6.9.0",
|
|
74
74
|
"eslint-plugin-prettier": "5.2.1",
|
|
75
|
-
"jest": "
|
|
75
|
+
"jest": "30.2.0",
|
|
76
76
|
"jest-junit": "16.0.0",
|
|
77
77
|
"prettier": "3.5.3",
|
|
78
|
-
"ts-jest": "29.
|
|
78
|
+
"ts-jest": "29.4.6",
|
|
79
79
|
"ts-loader": "9.5.2",
|
|
80
80
|
"ts-node": "10.9.2",
|
|
81
81
|
"typedoc": "0.28.15",
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { CoreEntity } from '@grandlinex/core';
|
|
2
|
-
import { SKey, SSchemaEl } from '@grandlinex/swagger-mate';
|
|
3
|
-
export default class EntitySchemaExtender {
|
|
4
|
-
static extendEntitySchema(entity: CoreEntity, ...options: {
|
|
5
|
-
key: string;
|
|
6
|
-
list?: boolean;
|
|
7
|
-
entity?: CoreEntity;
|
|
8
|
-
schema?: SSchemaEl;
|
|
9
|
-
required?: boolean;
|
|
10
|
-
}[]): SKey<SSchemaEl>;
|
|
11
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const core_1 = require("@grandlinex/core");
|
|
4
|
-
const swagger_mate_1 = require("@grandlinex/swagger-mate");
|
|
5
|
-
class EntitySchemaExtender {
|
|
6
|
-
static extendEntitySchema(entity, ...options) {
|
|
7
|
-
const meta = (0, core_1.getEntityMeta)(entity);
|
|
8
|
-
if (meta) {
|
|
9
|
-
const schema = swagger_mate_1.SPathUtil.schemaEntryGen(entity)[meta.name];
|
|
10
|
-
if (schema && !(0, swagger_mate_1.isSwaggerRef)(schema) && schema.properties) {
|
|
11
|
-
for (const option of options) {
|
|
12
|
-
if (option.schema) {
|
|
13
|
-
if (option.list) {
|
|
14
|
-
schema.properties[option.key] = {
|
|
15
|
-
type: 'array',
|
|
16
|
-
items: option.schema,
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
else {
|
|
20
|
-
schema.properties[option.key] = option.schema;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
else if (option.entity) {
|
|
24
|
-
const eMeta = (0, core_1.getEntityMeta)(option.entity);
|
|
25
|
-
if (eMeta) {
|
|
26
|
-
const scheme = swagger_mate_1.SPathUtil.schemaEntryGen(option.entity)[eMeta.name];
|
|
27
|
-
if (option.list) {
|
|
28
|
-
schema.properties[option.key] = {
|
|
29
|
-
type: 'array',
|
|
30
|
-
items: scheme,
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
else {
|
|
34
|
-
schema.properties[option.key] = scheme;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
if (option.required) {
|
|
39
|
-
schema.required = [...(schema.required || []), option.key];
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
return {
|
|
44
|
-
[meta.name]: schema,
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
return {};
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
exports.default = EntitySchemaExtender;
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { CoreEntity } from '@grandlinex/core';
|
|
2
|
-
import { SKey, SSchemaEl } from '@grandlinex/swagger-mate';
|
|
3
|
-
export default class EntitySchemaExtender {
|
|
4
|
-
static extendEntitySchema(entity: CoreEntity, ...options: {
|
|
5
|
-
key: string;
|
|
6
|
-
list?: boolean;
|
|
7
|
-
entity?: CoreEntity;
|
|
8
|
-
schema?: SSchemaEl;
|
|
9
|
-
required?: boolean;
|
|
10
|
-
}[]): SKey<SSchemaEl>;
|
|
11
|
-
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { getEntityMeta } from '@grandlinex/core';
|
|
2
|
-
import { isSwaggerRef, SPathUtil, } from '@grandlinex/swagger-mate';
|
|
3
|
-
export default class EntitySchemaExtender {
|
|
4
|
-
static extendEntitySchema(entity, ...options) {
|
|
5
|
-
const meta = getEntityMeta(entity);
|
|
6
|
-
if (meta) {
|
|
7
|
-
const schema = SPathUtil.schemaEntryGen(entity)[meta.name];
|
|
8
|
-
if (schema && !isSwaggerRef(schema) && schema.properties) {
|
|
9
|
-
for (const option of options) {
|
|
10
|
-
if (option.schema) {
|
|
11
|
-
if (option.list) {
|
|
12
|
-
schema.properties[option.key] = {
|
|
13
|
-
type: 'array',
|
|
14
|
-
items: option.schema,
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
else {
|
|
18
|
-
schema.properties[option.key] = option.schema;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
else if (option.entity) {
|
|
22
|
-
const eMeta = getEntityMeta(option.entity);
|
|
23
|
-
if (eMeta) {
|
|
24
|
-
const scheme = SPathUtil.schemaEntryGen(option.entity)[eMeta.name];
|
|
25
|
-
if (option.list) {
|
|
26
|
-
schema.properties[option.key] = {
|
|
27
|
-
type: 'array',
|
|
28
|
-
items: scheme,
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
else {
|
|
32
|
-
schema.properties[option.key] = scheme;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
if (option.required) {
|
|
37
|
-
schema.required = [...(schema.required || []), option.key];
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
return {
|
|
42
|
-
[meta.name]: schema,
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
return {};
|
|
46
|
-
}
|
|
47
|
-
}
|