fa-mcp-sdk 0.3.16 → 0.3.18
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/01-getting-started.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 +77 -4
- package/cli-template/FA-MCP-SDK-DOC/05-ad-authorization.md +35 -16
- package/cli-template/README.md +105 -105
- package/cli-template/package.json +2 -2
- package/cli-template/prompt-example-new-MCP.md +2 -1
- package/cli-template/prompt_2026-03-17_13-53.md +15 -0
- 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 +19 -14
- 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
|
@@ -3,244 +3,244 @@
|
|
|
3
3
|
* Converted from pug templates in src/core/_ntlm_example/ntlm/views/
|
|
4
4
|
*/
|
|
5
5
|
// CSS styles from src/core/_ntlm_example/style.css
|
|
6
|
-
const ntlmStyles = `
|
|
7
|
-
body, html {
|
|
8
|
-
height: 100%;
|
|
9
|
-
margin: 0;
|
|
10
|
-
font-family: "Roboto", "-apple-system", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
.views-outer-container {
|
|
14
|
-
height: 100%;
|
|
15
|
-
display: flex;
|
|
16
|
-
justify-content: center;
|
|
17
|
-
align-items: center;
|
|
18
|
-
font-size: 14px;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
.views-auth-container {
|
|
22
|
-
text-align: center;
|
|
23
|
-
position: absolute;
|
|
24
|
-
top: calc(38vh - 130px);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
.views-auth-container svg {
|
|
28
|
-
width: 70px;
|
|
29
|
-
fill: rgba(194, 57, 52, 0.58);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
.views-auth-block {
|
|
33
|
-
border: 1px solid #d0d0d0;
|
|
34
|
-
padding: 20px;
|
|
35
|
-
display: flex;
|
|
36
|
-
flex-direction: column;
|
|
37
|
-
align-items: center;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
.views-input-group {
|
|
41
|
-
display: flex;
|
|
42
|
-
align-items: center;
|
|
43
|
-
margin-bottom: 10px;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
.views-input-group label {
|
|
47
|
-
width: 80px;
|
|
48
|
-
text-align: left;
|
|
49
|
-
margin-right: 10px;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
.views-input-group input {
|
|
53
|
-
padding: 5px;
|
|
54
|
-
width: 200px;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
.views-input-group input::placeholder {
|
|
58
|
-
color: #e5e5e5;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
input {
|
|
62
|
-
outline: none;
|
|
63
|
-
border: 1px solid #b0b0b0;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
input:focus {
|
|
67
|
-
border: 1px solid #ff5500;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
.views-button-container {
|
|
71
|
-
display: flex;
|
|
72
|
-
width: 100%;
|
|
73
|
-
flex-direction: column;
|
|
74
|
-
align-items: end;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
.views-button-container button {
|
|
78
|
-
padding: 3px;
|
|
79
|
-
width: 105px;
|
|
80
|
-
}
|
|
6
|
+
const ntlmStyles = `
|
|
7
|
+
body, html {
|
|
8
|
+
height: 100%;
|
|
9
|
+
margin: 0;
|
|
10
|
+
font-family: "Roboto", "-apple-system", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.views-outer-container {
|
|
14
|
+
height: 100%;
|
|
15
|
+
display: flex;
|
|
16
|
+
justify-content: center;
|
|
17
|
+
align-items: center;
|
|
18
|
+
font-size: 14px;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.views-auth-container {
|
|
22
|
+
text-align: center;
|
|
23
|
+
position: absolute;
|
|
24
|
+
top: calc(38vh - 130px);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.views-auth-container svg {
|
|
28
|
+
width: 70px;
|
|
29
|
+
fill: rgba(194, 57, 52, 0.58);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.views-auth-block {
|
|
33
|
+
border: 1px solid #d0d0d0;
|
|
34
|
+
padding: 20px;
|
|
35
|
+
display: flex;
|
|
36
|
+
flex-direction: column;
|
|
37
|
+
align-items: center;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.views-input-group {
|
|
41
|
+
display: flex;
|
|
42
|
+
align-items: center;
|
|
43
|
+
margin-bottom: 10px;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.views-input-group label {
|
|
47
|
+
width: 80px;
|
|
48
|
+
text-align: left;
|
|
49
|
+
margin-right: 10px;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.views-input-group input {
|
|
53
|
+
padding: 5px;
|
|
54
|
+
width: 200px;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.views-input-group input::placeholder {
|
|
58
|
+
color: #e5e5e5;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
input {
|
|
62
|
+
outline: none;
|
|
63
|
+
border: 1px solid #b0b0b0;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
input:focus {
|
|
67
|
+
border: 1px solid #ff5500;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.views-button-container {
|
|
71
|
+
display: flex;
|
|
72
|
+
width: 100%;
|
|
73
|
+
flex-direction: column;
|
|
74
|
+
align-items: end;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.views-button-container button {
|
|
78
|
+
padding: 3px;
|
|
79
|
+
width: 105px;
|
|
80
|
+
}
|
|
81
81
|
`;
|
|
82
82
|
// SVG icon from src/core/_ntlm_example/block-visitor.svg
|
|
83
|
-
const blockVisitorSvg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
|
84
|
-
<path fill="#c23934" d="M29.9 8.8V9v-.2z"/>
|
|
85
|
-
<path fill="#c23934"
|
|
86
|
-
d="M10.2 17.1c0-1.3.4-2.7 1-3.8.8-1.4 1.7-1.9 2.4-3 1.1-1.7 1.4-4.1.6-6-.7-1.9-2.5-3-4.5-2.9S6 2.7 5.4 4.6c-.8 2-.5 4.5 1.2 6.1.7.7 1.3 1.7 1 2.6-.4 1-1.5 1.4-2.2 1.7-1.8.8-4 1.9-4.4 4.1-.4 1.7.8 3.5 2.7 3.5h7.9c.4 0 .6-.4.4-.7-1.2-1.4-1.8-3.1-1.8-4.8zm11.3-3.9c-2.2-2.2-5.7-2.2-7.9 0s-2.2 5.6 0 7.8 5.7 2.2 7.9 0 2.1-5.7 0-7.8zm-6.6 1.2c1.3-1.2 3.1-1.4 4.5-.5l-5 5.1c-.9-1.5-.7-3.3.5-4.6zm5.3 5.3c-1.3 1.2-3.1 1.4-4.6.6l5.1-5.1c.9 1.4.7 3.3-.5 4.5z"/>
|
|
83
|
+
const blockVisitorSvg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
|
84
|
+
<path fill="#c23934" d="M29.9 8.8V9v-.2z"/>
|
|
85
|
+
<path fill="#c23934"
|
|
86
|
+
d="M10.2 17.1c0-1.3.4-2.7 1-3.8.8-1.4 1.7-1.9 2.4-3 1.1-1.7 1.4-4.1.6-6-.7-1.9-2.5-3-4.5-2.9S6 2.7 5.4 4.6c-.8 2-.5 4.5 1.2 6.1.7.7 1.3 1.7 1 2.6-.4 1-1.5 1.4-2.2 1.7-1.8.8-4 1.9-4.4 4.1-.4 1.7.8 3.5 2.7 3.5h7.9c.4 0 .6-.4.4-.7-1.2-1.4-1.8-3.1-1.8-4.8zm11.3-3.9c-2.2-2.2-5.7-2.2-7.9 0s-2.2 5.6 0 7.8 5.7 2.2 7.9 0 2.1-5.7 0-7.8zm-6.6 1.2c1.3-1.2 3.1-1.4 4.5-.5l-5 5.1c-.9-1.5-.7-3.3.5-4.6zm5.3 5.3c-1.3 1.2-3.1 1.4-4.6.6l5.1-5.1c.9 1.4.7 3.3-.5 4.5z"/>
|
|
87
87
|
</svg>`;
|
|
88
88
|
/**
|
|
89
89
|
* Basic login page template
|
|
90
90
|
*/
|
|
91
|
-
export const getLoginPageHTML = (username = '') => `<!DOCTYPE html>
|
|
92
|
-
<html>
|
|
93
|
-
<head>
|
|
94
|
-
<meta charset="UTF-8">
|
|
95
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
96
|
-
<title>Sign in</title>
|
|
97
|
-
<style>${ntlmStyles}</style>
|
|
98
|
-
</head>
|
|
99
|
-
<body>
|
|
100
|
-
<script>
|
|
101
|
-
const username = '${username}';
|
|
102
|
-
function authenticate() {
|
|
103
|
-
const wl = window.location;
|
|
104
|
-
const login = document.getElementById('login').value;
|
|
105
|
-
const password = document.getElementById('password').value;
|
|
106
|
-
|
|
107
|
-
// Special handling for NTLM authentication
|
|
108
|
-
// The @ symbol in passwords breaks URL construction, so we need proper URL encoding
|
|
109
|
-
try {
|
|
110
|
-
// Properly encode the credentials for URL
|
|
111
|
-
const encodedLogin = encodeURIComponent(login);
|
|
112
|
-
const encodedPassword = encodeURIComponent(password);
|
|
113
|
-
|
|
114
|
-
console.log('Attempting authentication with:', { login: encodedLogin, passwordLength: password.length });
|
|
115
|
-
|
|
116
|
-
// Navigate with properly encoded credentials
|
|
117
|
-
window.location.href = wl.protocol + '//' + encodedLogin + ':' + encodedPassword + '@' + wl.hostname + ':' + wl.port;
|
|
118
|
-
} catch (error) {
|
|
119
|
-
console.error('Authentication error:', error);
|
|
120
|
-
alert('Authentication failed: ' + error.message);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// For testing: add direct NTLM trigger function
|
|
125
|
-
function triggerNTLM() {
|
|
126
|
-
// This will trigger the browser's native NTLM authentication dialog
|
|
127
|
-
const wl = window.location;
|
|
128
|
-
window.location.href = wl.origin + '/';
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// Add additional button for testing
|
|
132
|
-
document.addEventListener('DOMContentLoaded', function() {
|
|
133
|
-
const buttonContainer = document.querySelector('.views-button-container');
|
|
134
|
-
if (buttonContainer) {
|
|
135
|
-
const ntlmButton = document.createElement('button');
|
|
136
|
-
ntlmButton.type = 'button';
|
|
137
|
-
ntlmButton.textContent = 'Trigger NTLM Dialog';
|
|
138
|
-
ntlmButton.style.marginTop = '10px';
|
|
139
|
-
ntlmButton.onclick = triggerNTLM;
|
|
140
|
-
buttonContainer.appendChild(ntlmButton);
|
|
141
|
-
}
|
|
142
|
-
});
|
|
143
|
-
</script>
|
|
144
|
-
<div class="views-outer-container">
|
|
145
|
-
<div class="views-auth-container">
|
|
146
|
-
<div class="views-auth-block">
|
|
147
|
-
<div class="views-input-group">
|
|
148
|
-
<label for="login">Login:</label>
|
|
149
|
-
<input type="text" id="login" value="${username}">
|
|
150
|
-
</div>
|
|
151
|
-
<div class="views-input-group">
|
|
152
|
-
<label for="password">Password:</label>
|
|
153
|
-
<input type="password" id="password">
|
|
154
|
-
</div>
|
|
155
|
-
<div class="views-button-container">
|
|
156
|
-
<button type="button" onclick="authenticate()">Sign in</button>
|
|
157
|
-
</div>
|
|
158
|
-
</div>
|
|
159
|
-
</div>
|
|
160
|
-
</div>
|
|
161
|
-
</body>
|
|
91
|
+
export const getLoginPageHTML = (username = '') => `<!DOCTYPE html>
|
|
92
|
+
<html>
|
|
93
|
+
<head>
|
|
94
|
+
<meta charset="UTF-8">
|
|
95
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
96
|
+
<title>Sign in</title>
|
|
97
|
+
<style>${ntlmStyles}</style>
|
|
98
|
+
</head>
|
|
99
|
+
<body>
|
|
100
|
+
<script>
|
|
101
|
+
const username = '${username}';
|
|
102
|
+
function authenticate() {
|
|
103
|
+
const wl = window.location;
|
|
104
|
+
const login = document.getElementById('login').value;
|
|
105
|
+
const password = document.getElementById('password').value;
|
|
106
|
+
|
|
107
|
+
// Special handling for NTLM authentication
|
|
108
|
+
// The @ symbol in passwords breaks URL construction, so we need proper URL encoding
|
|
109
|
+
try {
|
|
110
|
+
// Properly encode the credentials for URL
|
|
111
|
+
const encodedLogin = encodeURIComponent(login);
|
|
112
|
+
const encodedPassword = encodeURIComponent(password);
|
|
113
|
+
|
|
114
|
+
console.log('Attempting authentication with:', { login: encodedLogin, passwordLength: password.length });
|
|
115
|
+
|
|
116
|
+
// Navigate with properly encoded credentials
|
|
117
|
+
window.location.href = wl.protocol + '//' + encodedLogin + ':' + encodedPassword + '@' + wl.hostname + ':' + wl.port;
|
|
118
|
+
} catch (error) {
|
|
119
|
+
console.error('Authentication error:', error);
|
|
120
|
+
alert('Authentication failed: ' + error.message);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// For testing: add direct NTLM trigger function
|
|
125
|
+
function triggerNTLM() {
|
|
126
|
+
// This will trigger the browser's native NTLM authentication dialog
|
|
127
|
+
const wl = window.location;
|
|
128
|
+
window.location.href = wl.origin + '/';
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Add additional button for testing
|
|
132
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
133
|
+
const buttonContainer = document.querySelector('.views-button-container');
|
|
134
|
+
if (buttonContainer) {
|
|
135
|
+
const ntlmButton = document.createElement('button');
|
|
136
|
+
ntlmButton.type = 'button';
|
|
137
|
+
ntlmButton.textContent = 'Trigger NTLM Dialog';
|
|
138
|
+
ntlmButton.style.marginTop = '10px';
|
|
139
|
+
ntlmButton.onclick = triggerNTLM;
|
|
140
|
+
buttonContainer.appendChild(ntlmButton);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
</script>
|
|
144
|
+
<div class="views-outer-container">
|
|
145
|
+
<div class="views-auth-container">
|
|
146
|
+
<div class="views-auth-block">
|
|
147
|
+
<div class="views-input-group">
|
|
148
|
+
<label for="login">Login:</label>
|
|
149
|
+
<input type="text" id="login" value="${username}">
|
|
150
|
+
</div>
|
|
151
|
+
<div class="views-input-group">
|
|
152
|
+
<label for="password">Password:</label>
|
|
153
|
+
<input type="password" id="password">
|
|
154
|
+
</div>
|
|
155
|
+
<div class="views-button-container">
|
|
156
|
+
<button type="button" onclick="authenticate()">Sign in</button>
|
|
157
|
+
</div>
|
|
158
|
+
</div>
|
|
159
|
+
</div>
|
|
160
|
+
</div>
|
|
161
|
+
</body>
|
|
162
162
|
</html>`;
|
|
163
163
|
/**
|
|
164
164
|
* Not authenticated page template (wrong login/password)
|
|
165
165
|
*/
|
|
166
|
-
export const getNotAuthenticatedPageHTML = (title = 'NOT AUTHENTICATED', protocol = '', hostname = '', username = '') => `<!DOCTYPE html>
|
|
167
|
-
<html>
|
|
168
|
-
<head>
|
|
169
|
-
<meta charset="UTF-8">
|
|
170
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
171
|
-
<title>${title}</title>
|
|
172
|
-
<style>${ntlmStyles}</style>
|
|
173
|
-
</head>
|
|
174
|
-
<body>
|
|
175
|
-
<script>
|
|
176
|
-
const username = '${username}';
|
|
177
|
-
function authenticate() {
|
|
178
|
-
const protocol = '${protocol}';
|
|
179
|
-
const hostname = '${hostname}';
|
|
180
|
-
const login = document.getElementById('login').value;
|
|
181
|
-
const password = document.getElementById('password').value;
|
|
182
|
-
window.location.href = protocol + '://' + login + ':' + password + '@' + hostname;
|
|
183
|
-
}
|
|
184
|
-
</script>
|
|
185
|
-
<div class="views-outer-container">
|
|
186
|
-
<div class="views-auth-container">
|
|
187
|
-
${blockVisitorSvg}
|
|
188
|
-
<p>Wrong login or password</p>
|
|
189
|
-
<div class="views-auth-block">
|
|
190
|
-
<div class="views-input-group">
|
|
191
|
-
<label for="login">Login:</label>
|
|
192
|
-
<input type="text" id="login" value="${username}">
|
|
193
|
-
</div>
|
|
194
|
-
<div class="views-input-group">
|
|
195
|
-
<label for="password">Password:</label>
|
|
196
|
-
<input type="password" id="password">
|
|
197
|
-
</div>
|
|
198
|
-
<div class="views-button-container">
|
|
199
|
-
<button type="button" onclick="authenticate()">Sign in</button>
|
|
200
|
-
</div>
|
|
201
|
-
</div>
|
|
202
|
-
</div>
|
|
203
|
-
</div>
|
|
204
|
-
</body>
|
|
166
|
+
export const getNotAuthenticatedPageHTML = (title = 'NOT AUTHENTICATED', protocol = '', hostname = '', username = '') => `<!DOCTYPE html>
|
|
167
|
+
<html>
|
|
168
|
+
<head>
|
|
169
|
+
<meta charset="UTF-8">
|
|
170
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
171
|
+
<title>${title}</title>
|
|
172
|
+
<style>${ntlmStyles}</style>
|
|
173
|
+
</head>
|
|
174
|
+
<body>
|
|
175
|
+
<script>
|
|
176
|
+
const username = '${username}';
|
|
177
|
+
function authenticate() {
|
|
178
|
+
const protocol = '${protocol}';
|
|
179
|
+
const hostname = '${hostname}';
|
|
180
|
+
const login = document.getElementById('login').value;
|
|
181
|
+
const password = document.getElementById('password').value;
|
|
182
|
+
window.location.href = protocol + '://' + login + ':' + password + '@' + hostname;
|
|
183
|
+
}
|
|
184
|
+
</script>
|
|
185
|
+
<div class="views-outer-container">
|
|
186
|
+
<div class="views-auth-container">
|
|
187
|
+
${blockVisitorSvg}
|
|
188
|
+
<p>Wrong login or password</p>
|
|
189
|
+
<div class="views-auth-block">
|
|
190
|
+
<div class="views-input-group">
|
|
191
|
+
<label for="login">Login:</label>
|
|
192
|
+
<input type="text" id="login" value="${username}">
|
|
193
|
+
</div>
|
|
194
|
+
<div class="views-input-group">
|
|
195
|
+
<label for="password">Password:</label>
|
|
196
|
+
<input type="password" id="password">
|
|
197
|
+
</div>
|
|
198
|
+
<div class="views-button-container">
|
|
199
|
+
<button type="button" onclick="authenticate()">Sign in</button>
|
|
200
|
+
</div>
|
|
201
|
+
</div>
|
|
202
|
+
</div>
|
|
203
|
+
</div>
|
|
204
|
+
</body>
|
|
205
205
|
</html>`;
|
|
206
206
|
/**
|
|
207
207
|
* Not authorized page template (user doesn't have access)
|
|
208
208
|
*/
|
|
209
|
-
export const getNotAuthorizedPageHTML = (title = 'NOT AUTHORIZED', username = '') => `<!DOCTYPE html>
|
|
210
|
-
<html>
|
|
211
|
-
<head>
|
|
212
|
-
<meta charset="UTF-8">
|
|
213
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
214
|
-
<title>${title}</title>
|
|
215
|
-
<style>${ntlmStyles}</style>
|
|
216
|
-
</head>
|
|
217
|
-
<body>
|
|
218
|
-
<div class="views-outer-container">
|
|
219
|
-
<div class="views-auth-container">
|
|
220
|
-
${blockVisitorSvg}
|
|
221
|
-
<p>No access for "${username}"</p>
|
|
222
|
-
</div>
|
|
223
|
-
</div>
|
|
224
|
-
</body>
|
|
209
|
+
export const getNotAuthorizedPageHTML = (title = 'NOT AUTHORIZED', username = '') => `<!DOCTYPE html>
|
|
210
|
+
<html>
|
|
211
|
+
<head>
|
|
212
|
+
<meta charset="UTF-8">
|
|
213
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
214
|
+
<title>${title}</title>
|
|
215
|
+
<style>${ntlmStyles}</style>
|
|
216
|
+
</head>
|
|
217
|
+
<body>
|
|
218
|
+
<div class="views-outer-container">
|
|
219
|
+
<div class="views-auth-container">
|
|
220
|
+
${blockVisitorSvg}
|
|
221
|
+
<p>No access for "${username}"</p>
|
|
222
|
+
</div>
|
|
223
|
+
</div>
|
|
224
|
+
</body>
|
|
225
225
|
</html>`;
|
|
226
226
|
/**
|
|
227
227
|
* 404 page template
|
|
228
228
|
*/
|
|
229
|
-
export const get404PageHTML = () => `<!DOCTYPE html>
|
|
230
|
-
<html>
|
|
231
|
-
<head>
|
|
232
|
-
<meta charset="UTF-8">
|
|
233
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
234
|
-
<title>404 - Page Not Found</title>
|
|
235
|
-
<style>${ntlmStyles}</style>
|
|
236
|
-
</head>
|
|
237
|
-
<body>
|
|
238
|
-
<div class="views-outer-container">
|
|
239
|
-
<div class="views-auth-container">
|
|
240
|
-
${blockVisitorSvg}
|
|
241
|
-
<p>404 - Page Not Found</p>
|
|
242
|
-
</div>
|
|
243
|
-
</div>
|
|
244
|
-
</body>
|
|
229
|
+
export const get404PageHTML = () => `<!DOCTYPE html>
|
|
230
|
+
<html>
|
|
231
|
+
<head>
|
|
232
|
+
<meta charset="UTF-8">
|
|
233
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
234
|
+
<title>404 - Page Not Found</title>
|
|
235
|
+
<style>${ntlmStyles}</style>
|
|
236
|
+
</head>
|
|
237
|
+
<body>
|
|
238
|
+
<div class="views-outer-container">
|
|
239
|
+
<div class="views-auth-container">
|
|
240
|
+
${blockVisitorSvg}
|
|
241
|
+
<p>404 - Page Not Found</p>
|
|
242
|
+
</div>
|
|
243
|
+
</div>
|
|
244
|
+
</body>
|
|
245
245
|
</html>`;
|
|
246
246
|
//# sourceMappingURL=ntlm-templates.js.map
|
|
@@ -75,6 +75,15 @@
|
|
|
75
75
|
</div>
|
|
76
76
|
</div>
|
|
77
77
|
</div>
|
|
78
|
+
<div class="form-group">
|
|
79
|
+
<label for="tokenIp">Allowed IP addresses (optional):</label>
|
|
80
|
+
<input type="text" id="tokenIp" name="ip"
|
|
81
|
+
placeholder="e.g. 192.168.1.100, 10.0.0.0/24; 172.16.0.0/12">
|
|
82
|
+
<small style="color: #6b778c; margin-top: 4px; display: block;">
|
|
83
|
+
Comma, semicolon or space separated. Supports CIDR notation.
|
|
84
|
+
Leave empty to allow any IP.
|
|
85
|
+
</small>
|
|
86
|
+
</div>
|
|
78
87
|
<div class="form-group">
|
|
79
88
|
<label>Additional data (key-value):</label>
|
|
80
89
|
<div id="keyValuePairs"></div>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
|
2
|
-
<path fill="currentColor" d="M2 0h8.8a1 1 0 0 1 0 2.2H3.2v19.6h7.6a1 1 0 0 1 0 2.2H2.1A1 1 0 0 1 1 23V1a1 1 0 0 1 1-1"/>
|
|
3
|
-
<path fill="currentColor" d="M16.6 8.4 19 11H6.5a1 1 0 0 0 0 2.2H19l-2.5 2.5A1 1 0 1 0 18 17l4.4-4.3a1 1 0 0 0 0-1.6L18.1 7a1 1 0 1 0-1.5 1.5"/>
|
|
4
|
-
</svg>
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
|
2
|
+
<path fill="currentColor" d="M2 0h8.8a1 1 0 0 1 0 2.2H3.2v19.6h7.6a1 1 0 0 1 0 2.2H2.1A1 1 0 0 1 1 23V1a1 1 0 0 1 1-1"/>
|
|
3
|
+
<path fill="currentColor" d="M16.6 8.4 19 11H6.5a1 1 0 0 0 0 2.2H19l-2.5 2.5A1 1 0 1 0 18 17l4.4-4.3a1 1 0 0 0 0-1.6L18.1 7a1 1 0 1 0-1.5 1.5"/>
|
|
4
|
+
</svg>
|
|
@@ -367,6 +367,11 @@ document.getElementById('generateForm').addEventListener('submit', async (e) =>
|
|
|
367
367
|
}
|
|
368
368
|
}
|
|
369
369
|
|
|
370
|
+
const ipValue = document.getElementById('tokenIp').value.trim();
|
|
371
|
+
if (ipValue) {
|
|
372
|
+
payload.ip = ipValue;
|
|
373
|
+
}
|
|
374
|
+
|
|
370
375
|
const requestData = {
|
|
371
376
|
user: formData.get('user'),
|
|
372
377
|
timeValue: parseInt(formData.get('timeValue')),
|
|
@@ -435,7 +440,7 @@ document.getElementById('validateForm').addEventListener('submit', async (e) =>
|
|
|
435
440
|
|
|
436
441
|
if (result.success) {
|
|
437
442
|
const remainingTime = result.payload.expire - Date.now();
|
|
438
|
-
const payloadKeys = Object.keys(result.payload).filter((k) => !/^(user|expire|iat|service)$/.test(k));
|
|
443
|
+
const payloadKeys = Object.keys(result.payload).filter((k) => !/^(user|expire|iat|service|ip)$/.test(k));
|
|
439
444
|
|
|
440
445
|
let payloadHtml = '';
|
|
441
446
|
if (payloadKeys.length > 0) {
|
|
@@ -455,6 +460,7 @@ document.getElementById('validateForm').addEventListener('submit', async (e) =>
|
|
|
455
460
|
<h4>Token Information:</h4>
|
|
456
461
|
<p><strong>User:</strong> ${result.payload.user}</p>
|
|
457
462
|
${result.payload.service ? `<p><strong>Service:</strong> ${result.payload.service}</p>` : ''}
|
|
463
|
+
${result.payload.ip ? `<p><strong>Allowed IPs:</strong> ${result.payload.ip}</p>` : ''}
|
|
458
464
|
<p><strong>Issued at:</strong> ${issuedAtTime}</p>
|
|
459
465
|
<p><strong>Time remaining:</strong> ${formatTime(remainingTime)}</p>
|
|
460
466
|
<p><strong>Expires:</strong> ${new Date(result.payload.expire).toLocaleString('ru-RU')}</p>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
|
2
|
-
<path fill="currentColor"
|
|
3
|
-
d="M24 20.5v1.1c0 1.3-1.1 2.4-2.4 2.4H2.4A2.45 2.45 0 0 1 0 21.6v-1.1c0-2.9 3.4-4.7 6.6-6.1l.3-.15c.25-.1.5-.1.75.05a7.75 7.75 0 0 0 8.6 0 .8.8 0 0 1 .75-.05l.3.15c3.3 1.4 6.7 3.15 6.7 6.1zM12 0c3.3 0 5.95 2.95 5.95 6.6 0 3.65-2.65 6.6-5.95 6.6-3.3 0-5.95-2.95-5.95-6.6C6.05 2.95 8.7 0 12 0Z"/>
|
|
4
|
-
</svg>
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
|
2
|
+
<path fill="currentColor"
|
|
3
|
+
d="M24 20.5v1.1c0 1.3-1.1 2.4-2.4 2.4H2.4A2.45 2.45 0 0 1 0 21.6v-1.1c0-2.9 3.4-4.7 6.6-6.1l.3-.15c.25-.1.5-.1.75.05a7.75 7.75 0 0 0 8.6 0 .8.8 0 0 1 .75-.05l.3.15c3.3 1.4 6.7 3.15 6.7 6.1zM12 0c3.3 0 5.95 2.95 5.95 6.6 0 3.65-2.65 6.6-5.95 6.6-3.3 0-5.95-2.95-5.95-6.6C6.05 2.95 8.7 0 12 0Z"/>
|
|
4
|
+
</svg>
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fa-mcp-sdk",
|
|
3
3
|
"productName": "FA MCP SDK",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.18",
|
|
5
5
|
"description": "Core infrastructure and templates for building Model Context Protocol (MCP) servers with TypeScript",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/core/index.js",
|