fa-mcp-sdk 0.3.16 → 0.3.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/cli-template/.claude/agents/architect.md +99 -99
- package/cli-template/.claude/agents/auditor.md +92 -92
- package/cli-template/.claude/agents/fa-mcp-sdk.md +1 -1
- package/cli-template/.claude/agents/planner.md +122 -122
- package/cli-template/.claude/agents/prd-writer.md +88 -88
- package/cli-template/.claude/agents/refactor.md +74 -74
- package/cli-template/.claude/agents/worker.md +132 -132
- package/cli-template/CLAUDE.md +1 -1
- package/cli-template/FA-MCP-SDK-DOC/03-configuration.md +3 -0
- package/cli-template/FA-MCP-SDK-DOC/04-authentication.md +41 -0
- package/cli-template/README.md +105 -105
- package/cli-template/package.json +1 -1
- package/cli-template/prompt-example-new-MCP.md +2 -1
- package/cli-template/r/TEST HTTP.xml +9 -9
- package/cli-template/r/TEST SSE.xml +5 -5
- package/cli-template/r/TEST STDIO.xml +5 -5
- package/cli-template/r/generate-token.xml +13 -13
- package/cli-template/r/lint-fix-build.xml +12 -12
- package/cli-template/r/remove-nul.xml +11 -11
- package/config/custom-environment-variables.yaml +1 -0
- package/config/default.yaml +3 -0
- package/config/development.yaml +4 -4
- package/config/production.yaml +4 -4
- package/dist/core/_types_/config.d.ts +1 -0
- package/dist/core/_types_/config.d.ts.map +1 -1
- package/dist/core/auth/ip-check.d.ts +18 -0
- package/dist/core/auth/ip-check.d.ts.map +1 -0
- package/dist/core/auth/ip-check.js +148 -0
- package/dist/core/auth/ip-check.js.map +1 -0
- package/dist/core/auth/jwt.d.ts +1 -0
- package/dist/core/auth/jwt.d.ts.map +1 -1
- package/dist/core/auth/jwt.js +15 -1
- package/dist/core/auth/jwt.js.map +1 -1
- package/dist/core/auth/multi-auth.d.ts.map +1 -1
- package/dist/core/auth/multi-auth.js +4 -1
- package/dist/core/auth/multi-auth.js.map +1 -1
- package/dist/core/auth/token-generator/ntlm/ntlm-templates.js +221 -221
- package/dist/core/web/static/token-gen/index.html +9 -0
- package/dist/core/web/static/token-gen/logout.svg +4 -4
- package/dist/core/web/static/token-gen/script.js +7 -1
- package/dist/core/web/static/token-gen/user.svg +4 -4
- package/package.json +1 -1
- package/scripts/publish.sh +78 -78
- package/scripts/update-doc.js +18 -18
- package/config/local-2.yaml +0 -20
- package/config/local.yaml +0 -101
package/cli-template/README.md
CHANGED
|
@@ -1,105 +1,105 @@
|
|
|
1
|
-
# {{project.productName}}
|
|
2
|
-
|
|
3
|
-
{{project.description}}
|
|
4
|
-
|
|
5
|
-
## Install & Run
|
|
6
|
-
|
|
7
|
-
### Quick Start
|
|
8
|
-
```bash
|
|
9
|
-
# Install
|
|
10
|
-
npm install
|
|
11
|
-
|
|
12
|
-
# Configure (copy config/local.yaml from config/_local.yaml)
|
|
13
|
-
# Add database credentials
|
|
14
|
-
|
|
15
|
-
# Build
|
|
16
|
-
npm run build
|
|
17
|
-
|
|
18
|
-
# Run (STDIO mode for Claude Desktop)
|
|
19
|
-
npm start
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
### Test Run
|
|
23
|
-
```bash
|
|
24
|
-
# Unit tests
|
|
25
|
-
npm test
|
|
26
|
-
|
|
27
|
-
# MCP protocol tests
|
|
28
|
-
npm run test:mcp # STDIO mode
|
|
29
|
-
npm run test:mcp-http # HTTP mode
|
|
30
|
-
npm run test:mcp-simple # Simple test
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
### Dual Transport System
|
|
34
|
-
|
|
35
|
-
**STDIO Mode** (default for Claude Desktop):
|
|
36
|
-
- Direct stdin/stdout communication
|
|
37
|
-
- Optimal for Claude Desktop integration
|
|
38
|
-
- No network ports required
|
|
39
|
-
|
|
40
|
-
**HTTP Mode** (web integration):
|
|
41
|
-
- HTTP server with Server-Sent Events (SSE)
|
|
42
|
-
- Home page with server status at `http://localhost:{{port}}/`
|
|
43
|
-
- Health check endpoint at `/health`
|
|
44
|
-
- Direct JSON-RPC 2.0 endpoint at `/mcp`
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
## Features
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
## MCP Tools
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
## MCP Prompts
|
|
56
|
-
|
|
57
|
-
### `agent_brief`
|
|
58
|
-
Brief description of agent capabilities for agent selection.
|
|
59
|
-
|
|
60
|
-
### `agent_prompt`
|
|
61
|
-
Complete prompt with instructions.
|
|
62
|
-
|
|
63
|
-
## MCP Resources
|
|
64
|
-
|
|
65
|
-
### `staff://agent/brief`
|
|
66
|
-
Same as `agent_brief` prompt. **MIME:** text/plain
|
|
67
|
-
|
|
68
|
-
### `staff://agent/prompt`
|
|
69
|
-
Same as `agent_prompt` prompt. **MIME:** text/plain
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
## 2. Configuration
|
|
73
|
-
|
|
74
|
-
**Option A: Configuration File**
|
|
75
|
-
|
|
76
|
-
**Option B: Environment Variables**
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
## Claude Desktop Setup
|
|
80
|
-
|
|
81
|
-
Add to `claude_desktop_config.json`:
|
|
82
|
-
|
|
83
|
-
```json
|
|
84
|
-
{
|
|
85
|
-
"mcpServers": {
|
|
86
|
-
"{{project.name}}": {
|
|
87
|
-
"command": "node",
|
|
88
|
-
"args": [
|
|
89
|
-
"<path-to-project>/mcp-staff-db/dist/src/index.js"
|
|
90
|
-
],
|
|
91
|
-
"env": {
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
## HTTP Mode Endpoints
|
|
99
|
-
|
|
100
|
-
- **/** - Home page
|
|
101
|
-
- **/health** - Health check
|
|
102
|
-
- **/sse** - Server-Sent Events
|
|
103
|
-
- **/mcp** - JSON-RPC 2.0
|
|
104
|
-
|
|
105
|
-
## Security
|
|
1
|
+
# {{project.productName}}
|
|
2
|
+
|
|
3
|
+
{{project.description}}
|
|
4
|
+
|
|
5
|
+
## Install & Run
|
|
6
|
+
|
|
7
|
+
### Quick Start
|
|
8
|
+
```bash
|
|
9
|
+
# Install
|
|
10
|
+
npm install
|
|
11
|
+
|
|
12
|
+
# Configure (copy config/local.yaml from config/_local.yaml)
|
|
13
|
+
# Add database credentials
|
|
14
|
+
|
|
15
|
+
# Build
|
|
16
|
+
npm run build
|
|
17
|
+
|
|
18
|
+
# Run (STDIO mode for Claude Desktop)
|
|
19
|
+
npm start
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Test Run
|
|
23
|
+
```bash
|
|
24
|
+
# Unit tests
|
|
25
|
+
npm test
|
|
26
|
+
|
|
27
|
+
# MCP protocol tests
|
|
28
|
+
npm run test:mcp # STDIO mode
|
|
29
|
+
npm run test:mcp-http # HTTP mode
|
|
30
|
+
npm run test:mcp-simple # Simple test
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Dual Transport System
|
|
34
|
+
|
|
35
|
+
**STDIO Mode** (default for Claude Desktop):
|
|
36
|
+
- Direct stdin/stdout communication
|
|
37
|
+
- Optimal for Claude Desktop integration
|
|
38
|
+
- No network ports required
|
|
39
|
+
|
|
40
|
+
**HTTP Mode** (web integration):
|
|
41
|
+
- HTTP server with Server-Sent Events (SSE)
|
|
42
|
+
- Home page with server status at `http://localhost:{{port}}/`
|
|
43
|
+
- Health check endpoint at `/health`
|
|
44
|
+
- Direct JSON-RPC 2.0 endpoint at `/mcp`
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
## Features
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
## MCP Tools
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
## MCP Prompts
|
|
56
|
+
|
|
57
|
+
### `agent_brief`
|
|
58
|
+
Brief description of agent capabilities for agent selection.
|
|
59
|
+
|
|
60
|
+
### `agent_prompt`
|
|
61
|
+
Complete prompt with instructions.
|
|
62
|
+
|
|
63
|
+
## MCP Resources
|
|
64
|
+
|
|
65
|
+
### `staff://agent/brief`
|
|
66
|
+
Same as `agent_brief` prompt. **MIME:** text/plain
|
|
67
|
+
|
|
68
|
+
### `staff://agent/prompt`
|
|
69
|
+
Same as `agent_prompt` prompt. **MIME:** text/plain
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
## 2. Configuration
|
|
73
|
+
|
|
74
|
+
**Option A: Configuration File**
|
|
75
|
+
|
|
76
|
+
**Option B: Environment Variables**
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
## Claude Desktop Setup
|
|
80
|
+
|
|
81
|
+
Add to `claude_desktop_config.json`:
|
|
82
|
+
|
|
83
|
+
```json
|
|
84
|
+
{
|
|
85
|
+
"mcpServers": {
|
|
86
|
+
"{{project.name}}": {
|
|
87
|
+
"command": "node",
|
|
88
|
+
"args": [
|
|
89
|
+
"<path-to-project>/mcp-staff-db/dist/src/index.js"
|
|
90
|
+
],
|
|
91
|
+
"env": {
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## HTTP Mode Endpoints
|
|
99
|
+
|
|
100
|
+
- **/** - Home page
|
|
101
|
+
- **/health** - Health check
|
|
102
|
+
- **/sse** - Server-Sent Events
|
|
103
|
+
- **/mcp** - JSON-RPC 2.0
|
|
104
|
+
|
|
105
|
+
## Security
|
|
@@ -18,7 +18,7 @@ Authorization: Bearer <appConfig.accessPoints.currencyService.token>
|
|
|
18
18
|
Example:
|
|
19
19
|
|
|
20
20
|
```http request
|
|
21
|
-
GET http://smart-trade-ml.com:
|
|
21
|
+
GET http://smart-trade-ml.com:5001/currency-service/?rate=THBRUB
|
|
22
22
|
Authorization: Bearer <appConfig.accessPoints.currencyService.token>
|
|
23
23
|
```
|
|
24
24
|
|
|
@@ -66,6 +66,7 @@ webServer:
|
|
|
66
66
|
jwtToken:
|
|
67
67
|
encryptKey: 'dbbe87db-90d0-4732-aae3-4089763ec392'
|
|
68
68
|
checkMCPName: true
|
|
69
|
+
isCheckIP: false
|
|
69
70
|
permanentServerTokens: ['psToken1']
|
|
70
71
|
|
|
71
72
|
adminAuth:
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
<component name="ProjectRunConfigurationManager">
|
|
2
|
-
<configuration
|
|
3
|
-
default="false"
|
|
4
|
-
name="TEST HTTP"
|
|
5
|
-
type="NodeJSConfigurationType"
|
|
6
|
-
path-to-js-file="tests/mcp/test-http.js" working-dir="$PROJECT_DIR$/">
|
|
7
|
-
<method v="2" />
|
|
8
|
-
</configuration>
|
|
9
|
-
</component>
|
|
1
|
+
<component name="ProjectRunConfigurationManager">
|
|
2
|
+
<configuration
|
|
3
|
+
default="false"
|
|
4
|
+
name="TEST HTTP"
|
|
5
|
+
type="NodeJSConfigurationType"
|
|
6
|
+
path-to-js-file="tests/mcp/test-http.js" working-dir="$PROJECT_DIR$/">
|
|
7
|
+
<method v="2" />
|
|
8
|
+
</configuration>
|
|
9
|
+
</component>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
<component name="ProjectRunConfigurationManager">
|
|
2
|
-
<configuration default="false" name="TEST SSE" type="NodeJSConfigurationType" path-to-js-file="tests/mcp/test-sse.js" working-dir="$PROJECT_DIR$/">
|
|
3
|
-
<method v="2" />
|
|
4
|
-
</configuration>
|
|
5
|
-
</component>
|
|
1
|
+
<component name="ProjectRunConfigurationManager">
|
|
2
|
+
<configuration default="false" name="TEST SSE" type="NodeJSConfigurationType" path-to-js-file="tests/mcp/test-sse.js" working-dir="$PROJECT_DIR$/">
|
|
3
|
+
<method v="2" />
|
|
4
|
+
</configuration>
|
|
5
|
+
</component>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
<component name="ProjectRunConfigurationManager">
|
|
2
|
-
<configuration default="false" name="TEST STDIO" type="NodeJSConfigurationType" path-to-js-file="tests/mcp/test-stdio.js" working-dir="$PROJECT_DIR$">
|
|
3
|
-
<method v="2" />
|
|
4
|
-
</configuration>
|
|
5
|
-
</component>
|
|
1
|
+
<component name="ProjectRunConfigurationManager">
|
|
2
|
+
<configuration default="false" name="TEST STDIO" type="NodeJSConfigurationType" path-to-js-file="tests/mcp/test-stdio.js" working-dir="$PROJECT_DIR$">
|
|
3
|
+
<method v="2" />
|
|
4
|
+
</configuration>
|
|
5
|
+
</component>
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
<component name="ProjectRunConfigurationManager">
|
|
2
|
-
<configuration default="false" name="generate-token" type="js.build_tools.npm" nameIsGenerated="true">
|
|
3
|
-
<package-json value="$PROJECT_DIR$/package.json" />
|
|
4
|
-
<command value="run" />
|
|
5
|
-
<scripts>
|
|
6
|
-
<script value="generate-token" />
|
|
7
|
-
</scripts>
|
|
8
|
-
<node-interpreter value="project" />
|
|
9
|
-
<envs>
|
|
10
|
-
<env name="DEBUG" value="ntlm:auth-flow,ntlm:ldap-proxy,ntlm:ldap-proxy-id" />
|
|
11
|
-
</envs>
|
|
12
|
-
<method v="2" />
|
|
13
|
-
</configuration>
|
|
1
|
+
<component name="ProjectRunConfigurationManager">
|
|
2
|
+
<configuration default="false" name="generate-token" type="js.build_tools.npm" nameIsGenerated="true">
|
|
3
|
+
<package-json value="$PROJECT_DIR$/package.json" />
|
|
4
|
+
<command value="run" />
|
|
5
|
+
<scripts>
|
|
6
|
+
<script value="generate-token" />
|
|
7
|
+
</scripts>
|
|
8
|
+
<node-interpreter value="project" />
|
|
9
|
+
<envs>
|
|
10
|
+
<env name="DEBUG" value="ntlm:auth-flow,ntlm:ldap-proxy,ntlm:ldap-proxy-id" />
|
|
11
|
+
</envs>
|
|
12
|
+
<method v="2" />
|
|
13
|
+
</configuration>
|
|
14
14
|
</component>
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
<component name="ProjectRunConfigurationManager">
|
|
2
|
-
<configuration default="false" name="lint-fix-build" type="js.build_tools.npm" nameIsGenerated="true">
|
|
3
|
-
<package-json value="$PROJECT_DIR$/package.json" />
|
|
4
|
-
<command value="run" />
|
|
5
|
-
<scripts>
|
|
6
|
-
<script value="lint-fix-build" />
|
|
7
|
-
</scripts>
|
|
8
|
-
<node-interpreter value="project" />
|
|
9
|
-
<envs />
|
|
10
|
-
<method v="2" />
|
|
11
|
-
</configuration>
|
|
12
|
-
</component>
|
|
1
|
+
<component name="ProjectRunConfigurationManager">
|
|
2
|
+
<configuration default="false" name="lint-fix-build" type="js.build_tools.npm" nameIsGenerated="true">
|
|
3
|
+
<package-json value="$PROJECT_DIR$/package.json" />
|
|
4
|
+
<command value="run" />
|
|
5
|
+
<scripts>
|
|
6
|
+
<script value="lint-fix-build" />
|
|
7
|
+
</scripts>
|
|
8
|
+
<node-interpreter value="project" />
|
|
9
|
+
<envs />
|
|
10
|
+
<method v="2" />
|
|
11
|
+
</configuration>
|
|
12
|
+
</component>
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
<component name="ProjectRunConfigurationManager">
|
|
2
|
-
<configuration
|
|
3
|
-
default="false"
|
|
4
|
-
name="remove-nul.js"
|
|
5
|
-
type="NodeJSConfigurationType"
|
|
6
|
-
nameIsGenerated="true"
|
|
7
|
-
path-to-js-file="scripts/remove-nul.js"
|
|
8
|
-
working-dir="$PROJECT_DIR$">
|
|
9
|
-
<method v="2"/>
|
|
10
|
-
</configuration>
|
|
11
|
-
</component>
|
|
1
|
+
<component name="ProjectRunConfigurationManager">
|
|
2
|
+
<configuration
|
|
3
|
+
default="false"
|
|
4
|
+
name="remove-nul.js"
|
|
5
|
+
type="NodeJSConfigurationType"
|
|
6
|
+
nameIsGenerated="true"
|
|
7
|
+
path-to-js-file="scripts/remove-nul.js"
|
|
8
|
+
working-dir="$PROJECT_DIR$">
|
|
9
|
+
<method v="2"/>
|
|
10
|
+
</configuration>
|
|
11
|
+
</component>
|
package/config/default.yaml
CHANGED
|
@@ -176,6 +176,9 @@ webServer:
|
|
|
176
176
|
encryptKey: '***'
|
|
177
177
|
# If webServer.auth.enabled and the parameter true, the service name and the service specified in the token will be checked
|
|
178
178
|
checkMCPName: true
|
|
179
|
+
# If true and JWT token contains non-empty 'ip' field,
|
|
180
|
+
# the client IP will be checked against the allowed list in the token
|
|
181
|
+
isCheckIP: false
|
|
179
182
|
|
|
180
183
|
# ========================================================================
|
|
181
184
|
# Basic Authentication - Base64 encoded username:password
|
package/config/development.yaml
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
---
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
---
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
package/config/production.yaml
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
---
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
---
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/core/_types_/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAGzD,UAAU,gBAAgB;IACxB,SAAS,EAAE;QACT,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,EAAE,CAAC;QACtB,IAAI,EAAE;YACJ,OAAO,EAAE,OAAO,CAAC;YACjB,KAAK,CAAC,EAAE;gBACN,QAAQ,EAAE,MAAM,CAAC;gBACjB,QAAQ,EAAE,MAAM,CAAC;aAClB,CAAC;YACF,QAAQ,EAAE;gBACR,UAAU,EAAE,MAAM,CAAC;gBACnB,YAAY,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/core/_types_/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAGzD,UAAU,gBAAgB;IACxB,SAAS,EAAE;QACT,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,EAAE,CAAC;QACtB,IAAI,EAAE;YACJ,OAAO,EAAE,OAAO,CAAC;YACjB,KAAK,CAAC,EAAE;gBACN,QAAQ,EAAE,MAAM,CAAC;gBACjB,QAAQ,EAAE,MAAM,CAAC;aAClB,CAAC;YACF,QAAQ,EAAE;gBACR,UAAU,EAAE,MAAM,CAAC;gBACnB,YAAY,EAAE,OAAO,CAAC;gBACtB,SAAS,EAAE,OAAO,CAAC;aACpB,CAAA;YACD,qBAAqB,EAAE,MAAM,EAAE,CAAC;SACjC,CAAC;QACF,SAAS,EAAE;YACT,OAAO,EAAE,OAAO,CAAC;YACjB,IAAI,EAAE,uBAAuB,GAAG,OAAO,GAAG,UAAU,GAAG,MAAM,CAAC;SAC/D,CAAC;KACH,CAAA;CACF;AAGD,UAAU,aAAa;IACrB,MAAM,EAAE;QACN,KAAK,EAAE,aAAa,CAAC;QACrB,aAAa,EAAE,OAAO,CAAC;QACvB,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAA;CACF;AAED,UAAU,UAAU;IAClB,GAAG,EAAE;QACH,SAAS,EAAE;YACT,WAAW,EAAE,MAAM,CAAC;YACpB,QAAQ,EAAE,MAAM,CAAC;SAClB,CAAC;QACF,YAAY,EAAE,MAAM,GAAG,mBAAmB,CAAA;QAC1C,aAAa,EAAE,OAAO,GAAG,MAAM,CAAC;KACjC,CAAA;CACF;AAED,UAAU,cAAc;IACtB,OAAO,EAAE;QACP,OAAO,CAAC,EAAE;YACR,GAAG,EAAE,MAAM,CAAC;YACZ,WAAW,EAAE,MAAM,CAAC;SACrB,EAAE,CAAC;KACL,CAAA;CACF;AAED,UAAU,kBAAkB;IAC1B,WAAW,CAAC,EAAE;QACZ,OAAO,EAAE,OAAO,CAAC;QACjB,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,CAAC,EAAE;YACP,MAAM,EAAE,MAAM,CAAC;YACf,OAAO,CAAC,EAAE,MAAM,CAAC;SAClB,CAAC;QACF,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACrC,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,CAAA;CACF;AAED,UAAU,YAAY;IACpB,KAAK,EAAE;QACL,UAAU,EAAE,GAAG,CAAC;QAChB,QAAQ,EAAE,IAAI,CAAC;KAChB,CAAA;CACF;AAED,MAAM,WAAW,SAAU,SAAQ,SAAS,EAC1C,YAAY,EACZ,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,UAAU,EACV,cAAc,EACd,kBAAkB;IAElB,YAAY,EAAE,OAAO,CAAC;IAEtB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IAEpB,YAAY,EAAE,aAAa,CAAC;IAC5B,MAAM,EAAE,eAAe,GAAG;QACxB,OAAO,EAAE;YACP,IAAI,EAAE,MAAM,CAAC;YACb,GAAG,EAAE,MAAM,CAAC;SACb,CAAC;KACH,CAAC;IACF,OAAO,EAAE;QACP,OAAO,EAAE,MAAM,CAAC;KACjB,CAAA;CACF"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IP address parsing and CIDR matching utilities for JWT IP checking.
|
|
3
|
+
* Pure TypeScript implementation — no external dependencies.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Parses IP string (comma/semicolon/space-separated) into array of trimmed non-empty entries.
|
|
7
|
+
* Each entry is either a plain IP or a CIDR notation (e.g., "10.0.0.0/24").
|
|
8
|
+
*/
|
|
9
|
+
export declare function parseIpList(ipStr: string): string[];
|
|
10
|
+
/**
|
|
11
|
+
* Checks if clientIp matches any entry in allowedIps.
|
|
12
|
+
* Supports:
|
|
13
|
+
* - Exact match (IPv4 and IPv6)
|
|
14
|
+
* - CIDR subnet match (e.g., 10.0.0.0/24)
|
|
15
|
+
* - IPv4-mapped IPv6 normalization (::ffff:x.x.x.x → x.x.x.x)
|
|
16
|
+
*/
|
|
17
|
+
export declare function isIpAllowed(clientIp: string, allowedIps: string[]): boolean;
|
|
18
|
+
//# sourceMappingURL=ip-check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ip-check.d.ts","sourceRoot":"","sources":["../../../src/core/auth/ip-check.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,wBAAgB,WAAW,CAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAQpD;AAmID;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAK5E"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IP address parsing and CIDR matching utilities for JWT IP checking.
|
|
3
|
+
* Pure TypeScript implementation — no external dependencies.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Parses IP string (comma/semicolon/space-separated) into array of trimmed non-empty entries.
|
|
7
|
+
* Each entry is either a plain IP or a CIDR notation (e.g., "10.0.0.0/24").
|
|
8
|
+
*/
|
|
9
|
+
export function parseIpList(ipStr) {
|
|
10
|
+
if (!ipStr) {
|
|
11
|
+
return [];
|
|
12
|
+
}
|
|
13
|
+
return ipStr
|
|
14
|
+
.split(/[,;\s]+/)
|
|
15
|
+
.map((s) => s.trim())
|
|
16
|
+
.filter(Boolean);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Normalizes an IP address string:
|
|
20
|
+
* - Strips IPv4-mapped IPv6 prefix (::ffff:x.x.x.x → x.x.x.x)
|
|
21
|
+
* - Trims whitespace
|
|
22
|
+
*/
|
|
23
|
+
function normalizeIp(ip) {
|
|
24
|
+
ip = ip.trim();
|
|
25
|
+
// Strip IPv4-mapped IPv6 prefix
|
|
26
|
+
const mapped = /^::ffff:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/i.exec(ip);
|
|
27
|
+
if (mapped?.[1]) {
|
|
28
|
+
return mapped[1];
|
|
29
|
+
}
|
|
30
|
+
return ip;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Parses an IPv4 address string into a 32-bit number.
|
|
34
|
+
* Returns null if the string is not a valid IPv4 address.
|
|
35
|
+
*/
|
|
36
|
+
function parseIpv4(ip) {
|
|
37
|
+
const parts = ip.split('.');
|
|
38
|
+
if (parts.length !== 4) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
let result = 0;
|
|
42
|
+
for (const part of parts) {
|
|
43
|
+
const n = Number(part);
|
|
44
|
+
if (!Number.isInteger(n) || n < 0 || n > 255) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
result = (result << 8) | n;
|
|
48
|
+
}
|
|
49
|
+
return result >>> 0; // ensure unsigned
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Parses an IPv6 address string into a BigInt (128-bit).
|
|
53
|
+
* Supports full and abbreviated (::) notation.
|
|
54
|
+
* Returns null if the string is not a valid IPv6 address.
|
|
55
|
+
*/
|
|
56
|
+
function parseIpv6(ip) {
|
|
57
|
+
// Handle IPv4-mapped IPv6
|
|
58
|
+
const v4mapped = /^::ffff:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/i.exec(ip);
|
|
59
|
+
if (v4mapped?.[1]) {
|
|
60
|
+
const v4 = parseIpv4(v4mapped[1]);
|
|
61
|
+
if (v4 === null) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
return BigInt(0xffff00000000n) | BigInt(v4);
|
|
65
|
+
}
|
|
66
|
+
const halves = ip.split('::');
|
|
67
|
+
if (halves.length > 2) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
let groups = [];
|
|
71
|
+
if (halves.length === 2) {
|
|
72
|
+
const left = halves[0] ? halves[0].split(':') : [];
|
|
73
|
+
const right = halves[1] ? halves[1].split(':') : [];
|
|
74
|
+
const missing = 8 - left.length - right.length;
|
|
75
|
+
if (missing < 0) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
groups = [...left, ...Array(missing).fill('0'), ...right];
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
groups = ip.split(':');
|
|
82
|
+
}
|
|
83
|
+
if (groups.length !== 8) {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
let result = 0n;
|
|
87
|
+
for (const group of groups) {
|
|
88
|
+
if (!/^[0-9a-fA-F]{1,4}$/.test(group)) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
result = (result << 16n) | BigInt(parseInt(group, 16));
|
|
92
|
+
}
|
|
93
|
+
return result;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Checks if a client IP matches a single allowed entry (exact IP or CIDR).
|
|
97
|
+
*/
|
|
98
|
+
function matchEntry(clientIp, entry) {
|
|
99
|
+
const cidrMatch = /^(.+)\/(\d+)$/.exec(entry);
|
|
100
|
+
if (cidrMatch?.[1] && cidrMatch[2]) {
|
|
101
|
+
const subnet = normalizeIp(cidrMatch[1]);
|
|
102
|
+
const prefixLen = Number(cidrMatch[2]);
|
|
103
|
+
const clientNorm = normalizeIp(clientIp);
|
|
104
|
+
// Try IPv4
|
|
105
|
+
const subnetV4 = parseIpv4(subnet);
|
|
106
|
+
const clientV4 = parseIpv4(clientNorm);
|
|
107
|
+
if (subnetV4 !== null && clientV4 !== null) {
|
|
108
|
+
if (prefixLen < 0 || prefixLen > 32) {
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
if (prefixLen === 0) {
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
const mask = (~0 << (32 - prefixLen)) >>> 0;
|
|
115
|
+
return (subnetV4 & mask) === (clientV4 & mask);
|
|
116
|
+
}
|
|
117
|
+
// Try IPv6
|
|
118
|
+
const subnetV6 = parseIpv6(subnet);
|
|
119
|
+
const clientV6 = parseIpv6(clientNorm);
|
|
120
|
+
if (subnetV6 !== null && clientV6 !== null) {
|
|
121
|
+
if (prefixLen < 0 || prefixLen > 128) {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
if (prefixLen === 0) {
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
const shift = BigInt(128 - prefixLen);
|
|
128
|
+
return (subnetV6 >> shift) === (clientV6 >> shift);
|
|
129
|
+
}
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
// Exact match
|
|
133
|
+
return normalizeIp(clientIp) === normalizeIp(entry);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Checks if clientIp matches any entry in allowedIps.
|
|
137
|
+
* Supports:
|
|
138
|
+
* - Exact match (IPv4 and IPv6)
|
|
139
|
+
* - CIDR subnet match (e.g., 10.0.0.0/24)
|
|
140
|
+
* - IPv4-mapped IPv6 normalization (::ffff:x.x.x.x → x.x.x.x)
|
|
141
|
+
*/
|
|
142
|
+
export function isIpAllowed(clientIp, allowedIps) {
|
|
143
|
+
if (!clientIp || !allowedIps.length) {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
return allowedIps.some((entry) => matchEntry(clientIp, entry));
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=ip-check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ip-check.js","sourceRoot":"","sources":["../../../src/core/auth/ip-check.ts"],"names":[],"mappings":"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"}
|
package/dist/core/auth/jwt.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../../src/core/auth/jwt.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAiB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../../src/core/auth/jwt.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAiB,MAAM,YAAY,CAAC;AAY9D,eAAO,MAAM,sBAAsB,IAAI,CAAC;AASxC,eAAO,MAAM,UAAU,QAAmC,CAAC;AAE3D;;GAEG;AACH,eAAO,MAAM,OAAO,GAAI,MAAM,MAAM,KAAG,MAStC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,OAAO,GAAI,cAAc,MAAM,WAW3C,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,MAAM,MAAM,EAAE,aAAa,MAAM,EAAE,UAAU,GAAG,KAAG,MAYhF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,aAAa,GAAI,KAAK;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,KAAG,iBAmFH,CAAC"}
|
package/dist/core/auth/jwt.js
CHANGED
|
@@ -3,10 +3,12 @@ import crypto from 'crypto';
|
|
|
3
3
|
import { appConfig } from '../bootstrap/init-config.js';
|
|
4
4
|
import { logger as lgr } from '../logger.js';
|
|
5
5
|
import { isObject, trim } from '../utils/utils.js';
|
|
6
|
+
import { parseIpList, isIpAllowed } from './ip-check.js';
|
|
6
7
|
import chalk from 'chalk';
|
|
7
8
|
const logger = lgr.getSubLogger({ name: chalk.cyan('token-auth') });
|
|
8
9
|
const { jwtToken } = appConfig.webServer?.auth || {};
|
|
9
10
|
const checkMCPName = jwtToken?.checkMCPName || false;
|
|
11
|
+
const isCheckIP = jwtToken?.isCheckIP || false;
|
|
10
12
|
export const MIN_ENCRYPT_KEY_LENGTH = 8;
|
|
11
13
|
const ALGORITHM = 'aes-256-ctr';
|
|
12
14
|
const KEY = crypto
|
|
@@ -68,7 +70,7 @@ export const generateToken = (user, liveTimeSec, payload) => {
|
|
|
68
70
|
* - If a user is transferred, it must match
|
|
69
71
|
*/
|
|
70
72
|
export const checkJwtToken = (arg) => {
|
|
71
|
-
let { token, expectedUser, expectedService = appConfig.name } = arg;
|
|
73
|
+
let { token, expectedUser, expectedService = appConfig.name, clientIp } = arg;
|
|
72
74
|
token = (token || '').trim();
|
|
73
75
|
if (!token) {
|
|
74
76
|
return {
|
|
@@ -130,6 +132,18 @@ export const checkJwtToken = (arg) => {
|
|
|
130
132
|
errorReason: `JWT Token expired :: on ${expiredOn} mc`,
|
|
131
133
|
};
|
|
132
134
|
}
|
|
135
|
+
// IP check (after all other validations pass)
|
|
136
|
+
if (isCheckIP && payload.ip) {
|
|
137
|
+
if (clientIp) {
|
|
138
|
+
const allowedIps = parseIpList(payload.ip);
|
|
139
|
+
if (allowedIps.length > 0 && !isIpAllowed(clientIp, allowedIps)) {
|
|
140
|
+
return {
|
|
141
|
+
isTokenDecrypted: true,
|
|
142
|
+
errorReason: `JWT Token: client IP ${clientIp} is not in the allowed list`,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
133
147
|
// OK!
|
|
134
148
|
return { payload };
|
|
135
149
|
};
|