fa-mcp-sdk 0.4.93 → 0.4.96
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/cli-template/.claude/skills/readme-generator/reference/satellite-templates.md +1 -1
- package/cli-template/.claude/skills/upgrade-sdk/SKILL.md +554 -0
- package/cli-template/CLAUDE.md +1 -1
- package/cli-template/FA-MCP-SDK-DOC/03-configuration.md +9 -5
- package/cli-template/FA-MCP-SDK-DOC/04-authentication.md +4 -4
- package/cli-template/FA-MCP-SDK-DOC/08-agent-tester-and-headless-api.md +1 -1
- package/cli-template/package.json +1 -1
- package/config/_local.yaml +13 -6
- package/config/custom-environment-variables.yaml +1 -0
- package/config/default.yaml +14 -6
- package/dist/core/_types_/config.d.ts +1 -0
- package/dist/core/_types_/config.d.ts.map +1 -1
- package/dist/core/auth/admin-auth.d.ts.map +1 -1
- package/dist/core/auth/admin-auth.js +9 -10
- package/dist/core/auth/admin-auth.js.map +1 -1
- package/dist/core/auth/jwt.d.ts +18 -9
- package/dist/core/auth/jwt.d.ts.map +1 -1
- package/dist/core/auth/jwt.js +185 -51
- package/dist/core/auth/jwt.js.map +1 -1
- package/dist/core/auth/multi-auth.d.ts +4 -2
- package/dist/core/auth/multi-auth.d.ts.map +1 -1
- package/dist/core/auth/multi-auth.js +43 -31
- package/dist/core/auth/multi-auth.js.map +1 -1
- package/dist/core/auth/revocation.d.ts +1 -0
- package/dist/core/auth/revocation.d.ts.map +1 -1
- package/dist/core/auth/revocation.js +9 -2
- package/dist/core/auth/revocation.js.map +1 -1
- package/dist/core/auth/types.d.ts +5 -0
- package/dist/core/auth/types.d.ts.map +1 -1
- package/package.json +6 -2
- package/scripts/generate-jwt.js +61 -35
- package/scripts/update-sdk.js +16 -0
- package/cli-template/.claude/skills/upgrade-guide/SKILL.md +0 -456
|
@@ -34,10 +34,7 @@ export const getTokenFromHttpHeader = (req) => {
|
|
|
34
34
|
if (scheme.toLowerCase() === 'basic') {
|
|
35
35
|
return { scheme: 'basic', credentials };
|
|
36
36
|
}
|
|
37
|
-
|
|
38
|
-
return { scheme: 'jwtToken', credentials };
|
|
39
|
-
}
|
|
40
|
-
return { scheme: 'permanentServerTokens', credentials };
|
|
37
|
+
return { scheme: 'bearer', credentials, looksLikeJwt: jwtTokenRE.test(credentials) };
|
|
41
38
|
};
|
|
42
39
|
/**
|
|
43
40
|
* Gets custom auth validator from global context.
|
|
@@ -150,54 +147,69 @@ export async function checkMultiAuth(req) {
|
|
|
150
147
|
// fall through to standard auth
|
|
151
148
|
}
|
|
152
149
|
}
|
|
153
|
-
const { scheme
|
|
150
|
+
const { scheme, credentials } = getTokenFromHttpHeader(req);
|
|
154
151
|
if (!credentials) {
|
|
155
152
|
return { success: false, error: `${E_PFX}credentials not provided` };
|
|
156
153
|
}
|
|
157
|
-
if (!
|
|
158
|
-
return { success: false, error: `${E_PFX}Cannot detect auth
|
|
154
|
+
if (!scheme) {
|
|
155
|
+
return { success: false, error: `${E_PFX}Cannot detect auth scheme from Authorization header` };
|
|
159
156
|
}
|
|
160
157
|
logger.debug(`Checking auth types: ${configuredTypes}`);
|
|
161
|
-
if (!configuredSet.has(authType)) {
|
|
162
|
-
return { success: false, error: `${E_PFX}Detected in Authorisation header auth type ${authType} not configured` };
|
|
163
|
-
}
|
|
164
158
|
let errorResult = undefined;
|
|
165
159
|
try {
|
|
166
|
-
|
|
167
|
-
|
|
160
|
+
if (scheme === 'basic') {
|
|
161
|
+
if (!configuredSet.has('basic')) {
|
|
162
|
+
return {
|
|
163
|
+
success: false,
|
|
164
|
+
error: `${E_PFX}Detected Basic auth in Authorization header, but 'basic' is not configured`,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
const result = checkBasicAuth(credentials);
|
|
168
|
+
if (result.success) {
|
|
169
|
+
return { ...result, authType: 'basic', payload: { user: result.username } };
|
|
170
|
+
}
|
|
171
|
+
errorResult = { ...result, authType: 'basic' };
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
// Bearer / non-Basic: try permanent tokens first (O(1)), then JWT.
|
|
175
|
+
// Permanent tokens can contain dots, so we never classify purely by shape.
|
|
176
|
+
let permError;
|
|
177
|
+
let jwtErrorResult;
|
|
178
|
+
if (configuredSet.has('permanentServerTokens')) {
|
|
168
179
|
const { errorReason } = checkPermanentToken(credentials);
|
|
169
180
|
if (!errorReason) {
|
|
170
|
-
return { success: true, authType };
|
|
181
|
+
return { success: true, authType: 'permanentServerTokens' };
|
|
171
182
|
}
|
|
172
|
-
|
|
173
|
-
break;
|
|
183
|
+
permError = errorReason;
|
|
174
184
|
}
|
|
175
|
-
|
|
176
|
-
const result = checkBasicAuth(credentials);
|
|
177
|
-
if (result.success) {
|
|
178
|
-
// For basic auth, create payload with user property
|
|
179
|
-
return { ...result, authType, payload: { user: result.username } };
|
|
180
|
-
}
|
|
181
|
-
errorResult = { ...result, authType };
|
|
182
|
-
break;
|
|
183
|
-
}
|
|
184
|
-
case 'jwtToken': {
|
|
185
|
+
if (configuredSet.has('jwtToken')) {
|
|
185
186
|
const xff = req.headers['x-forwarded-for'];
|
|
186
187
|
const xffStr = (Array.isArray(xff) ? (xff[0] ?? '') : (xff ?? '')).split(',').shift() ?? '';
|
|
187
188
|
const clientIp = req.ip ?? (xffStr.trim() || (req.socket?.remoteAddress ?? ''));
|
|
188
189
|
const { errorReason, payload, isTokenDecrypted } = checkJwtToken({ token: credentials, clientIp });
|
|
189
190
|
if (!errorReason) {
|
|
190
|
-
return { success: true, authType, payload };
|
|
191
|
+
return { success: true, authType: 'jwtToken', payload };
|
|
191
192
|
}
|
|
192
|
-
|
|
193
|
-
|
|
193
|
+
jwtErrorResult = { success: false, error: `${E_PFX}${errorReason}`, authType: 'jwtToken', isTokenDecrypted };
|
|
194
|
+
}
|
|
195
|
+
// Prefer the JWT-specific error (it's more informative for malformed/expired JWTs).
|
|
196
|
+
// Fall back to the permanent token error if JWT wasn't configured/attempted.
|
|
197
|
+
if (jwtErrorResult) {
|
|
198
|
+
errorResult = jwtErrorResult;
|
|
199
|
+
}
|
|
200
|
+
else if (permError) {
|
|
201
|
+
errorResult = { success: false, authType: 'permanentServerTokens', error: `${E_PFX}${permError}` };
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
errorResult = {
|
|
205
|
+
success: false,
|
|
206
|
+
error: `${E_PFX}No bearer auth method is configured (need permanentServerTokens or jwtToken)`,
|
|
207
|
+
};
|
|
194
208
|
}
|
|
195
|
-
default:
|
|
196
|
-
errorResult = { success: false, error: `${E_PFX}Unknown auth type: ${authType}` };
|
|
197
209
|
}
|
|
198
210
|
}
|
|
199
211
|
catch (error) {
|
|
200
|
-
logger.warn(`Auth
|
|
212
|
+
logger.warn(`Auth scheme ${scheme} failed with exception:`, error instanceof Error ? E_PFX + error.message : 'Unknown error');
|
|
201
213
|
}
|
|
202
214
|
return (errorResult || {
|
|
203
215
|
success: false,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multi-auth.js","sourceRoot":"","sources":["../../../src/core/auth/multi-auth.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAE1C;;GAEG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAE,MAAM,IAAI,GAAG,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,UAAU,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAC5F,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAGrD,MAAM,MAAM,GAAG,GAAG,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;AAEvE,MAAM,EACJ,OAAO,EAAE,WAAW,EACpB,qBAAqB,EAAE,EAAE,EACzB,KAAK,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,EAAE,EACxD,QAAQ,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,GAC9B,GAAG,SAAS,CAAC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC;AAEpC;;GAEG;AACH,MAAM,SAAS,GAAG;IAChB,qBAAqB,EAAE,CAAC,EAAE,iBAAiB;IAC3C,KAAK,EAAE,CAAC,EAAE,kBAAkB;IAC5B,QAAQ,EAAE,CAAC,EAAE,oCAAoC;IACjD,MAAM,EAAE,CAAC;CACV,CAAC;
|
|
1
|
+
{"version":3,"file":"multi-auth.js","sourceRoot":"","sources":["../../../src/core/auth/multi-auth.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAE1C;;GAEG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAE,MAAM,IAAI,GAAG,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,UAAU,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAC5F,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAGrD,MAAM,MAAM,GAAG,GAAG,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;AAEvE,MAAM,EACJ,OAAO,EAAE,WAAW,EACpB,qBAAqB,EAAE,EAAE,EACzB,KAAK,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,EAAE,EACxD,QAAQ,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,GAC9B,GAAG,SAAS,CAAC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC;AAEpC;;GAEG;AACH,MAAM,SAAS,GAAG;IAChB,qBAAqB,EAAE,CAAC,EAAE,iBAAiB;IAC3C,KAAK,EAAE,CAAC,EAAE,kBAAkB;IAC5B,QAAQ,EAAE,CAAC,EAAE,oCAAoC;IACjD,MAAM,EAAE,CAAC;CACV,CAAC;AAIF,MAAM,QAAQ,GAAG,iBAAiB,CAAC;AACnC,MAAM,CAAC,MAAM,sBAAsB,GAAG,CACpC,GAAY,EAC2D,EAAE;IACzE,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IAC1C,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,MAAM,GAAW,EAAE,CAAC;IACxB,IAAI,WAAW,GAAW,CAAC,CAAC;IAC5B,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QACrB,CAAC,MAAM,GAAG,EAAE,EAAE,WAAW,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClD,CAAC;IACD,IAAI,MAAM,CAAC,WAAW,EAAE,KAAK,OAAO,EAAE,CAAC;QACrC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;IAC1C,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;AACvF,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,IAAI,gBAAwD,CAAC;AAE7D,SAAS,sBAAsB;IAC7B,IAAI,gBAAgB,KAAK,SAAS,EAAE,CAAC;QACnC,OAAO,gBAAgB,IAAI,SAAS,CAAC;IACvC,CAAC;IACD,MAAM,WAAW,GAAG,MAAM,CAAC,oBAAoB,CAAC;IAChD,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,4DAA4D;QAC5D,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,EAAE,GAAG,WAAW,CAAC,mBAAmB,CAAC;IAC3C,gBAAgB,GAAG,OAAO,EAAE,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACxD,OAAO,gBAAgB,IAAI,SAAS,CAAC;AACvC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB;IACrC,MAAM,UAAU,GAAe,EAAE,CAAC;IAClC,MAAM,MAAM,GAA6B,EAAE,CAAC;IAC5C,MAAM,MAAM,GAAwB,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,IAAI,GAAG,EAAE,EAAE,eAAe,EAAE,EAAE,EAAE,CAAC;IAE1G,IAAI,WAAW,EAAE,CAAC;QAChB,8BAA8B;QAC9B,IAAI,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5C,UAAU,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QAC3C,CAAC;QAED,kBAAkB;QAClB,IAAI,UAAU,EAAE,MAAM,EAAE,CAAC;YACvB,IAAI,UAAU,CAAC,MAAM,GAAG,sBAAsB,EAAE,CAAC;gBAC/C,MAAM,CAAC,QAAQ,GAAG;oBAChB,oCAAoC,UAAU,CAAC,MAAM,4BAA4B,sBAAsB,aAAa;iBACrH,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC;QAED,mBAAmB;QACnB,IAAI,SAAS,IAAI,SAAS,EAAE,CAAC;YAC3B,MAAM,IAAI,GAAG,EAAE,CAAC;YAChB,0DAA0D;YAC1D,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;YAChC,CAAC;YACD,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;YAChC,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACjB,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC3B,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC;YACtB,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,sBAAsB,EAAE,EAAE,CAAC;QAC7B,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC5B,CAAC;IAED,MAAM,CAAC,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3E,MAAM,CAAC,aAAa,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAClD,MAAM,CAAC,eAAe,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,IAAI,iBAAkD,CAAC;AAEvD,SAAS,oBAAoB;IAC3B,IAAI,iBAAiB,EAAE,CAAC;QACtB,OAAO,iBAAiB,CAAC;IAC3B,CAAC;IACD,MAAM,MAAM,GAAG,uBAAuB,EAAE,CAAC;IACzC,IAAI,MAAM,CAAC,oBAAoB,EAAE,CAAC;QAChC,iBAAiB,GAAG,MAAM,CAAC;IAC7B,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,KAAK,GAAG,YAAY,CAAC;AAE3B;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAY;IAC/C,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,eAAe,EAAE,GAAG,oBAAoB,EAAE,CAAC;IAC9E,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;QACvB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,KAAK,sCAAsC,EAAE,CAAC;IACnF,CAAC;IAED,yFAAyF;IACzF,MAAM,eAAe,GAAG,sBAAsB,EAAE,CAAC;IACjD,IAAI,eAAe,EAAE,CAAC;QACpB,MAAM,4BAA4B,GAAG,EAAE,GAAG,GAAG,EAAE,OAAO,EAAE,gBAAgB,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,CAAC;QAC9F,IAAI,CAAC;YACH,MAAM,YAAY,GAAG,MAAM,eAAe,CAAC,4BAA4B,CAAC,CAAC;YACzE,IAAI,YAAY,CAAC,OAAO,EAAE,CAAC;gBACzB,OAAO,YAAY,CAAC;YACtB,CAAC;YACD,iDAAiD;QACnD,CAAC;QAAC,OAAO,KAAkB,EAAE,CAAC;YAC5B,MAAM,CAAC,KAAK,CAAC,+BAA+B,EAAE,KAAK,CAAC,CAAC;YACrD,gCAAgC;QAClC,CAAC;IACH,CAAC;IAED,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;IAC5D,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,KAAK,0BAA0B,EAAE,CAAC;IACvE,CAAC;IACD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,KAAK,qDAAqD,EAAE,CAAC;IAClG,CAAC;IACD,MAAM,CAAC,KAAK,CAAC,wBAAwB,eAAe,EAAE,CAAC,CAAC;IAExD,IAAI,WAAW,GAA2B,SAAS,CAAC;IACpD,IAAI,CAAC;QACH,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;YACvB,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;gBAChC,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,GAAG,KAAK,4EAA4E;iBAC5F,CAAC;YACJ,CAAC;YACD,MAAM,MAAM,GAAG,cAAc,CAAC,WAAW,CAAC,CAAC;YAC3C,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,OAAO,EAAE,GAAG,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,QAAS,EAAE,EAAE,CAAC;YAC/E,CAAC;YACD,WAAW,GAAG,EAAE,GAAG,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;QACjD,CAAC;aAAM,CAAC;YACN,mEAAmE;YACnE,2EAA2E;YAC3E,IAAI,SAA6B,CAAC;YAClC,IAAI,cAAsC,CAAC;YAE3C,IAAI,aAAa,CAAC,GAAG,CAAC,uBAAuB,CAAC,EAAE,CAAC;gBAC/C,MAAM,EAAE,WAAW,EAAE,GAAG,mBAAmB,CAAC,WAAW,CAAC,CAAC;gBACzD,IAAI,CAAC,WAAW,EAAE,CAAC;oBACjB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,uBAAuB,EAAE,CAAC;gBAC9D,CAAC;gBACD,SAAS,GAAG,WAAW,CAAC;YAC1B,CAAC;YAED,IAAI,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;gBAClC,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;gBAC3C,MAAM,MAAM,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC;gBAC5F,MAAM,QAAQ,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,aAAa,IAAI,EAAE,CAAC,CAAC,CAAC;gBAChF,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,EAAE,GAAG,aAAa,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,CAAC;gBACnG,IAAI,CAAC,WAAW,EAAE,CAAC;oBACjB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC;gBAC1D,CAAC;gBACD,cAAc,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,KAAK,GAAG,WAAW,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,gBAAgB,EAAE,CAAC;YAC/G,CAAC;YAED,oFAAoF;YACpF,6EAA6E;YAC7E,IAAI,cAAc,EAAE,CAAC;gBACnB,WAAW,GAAG,cAAc,CAAC;YAC/B,CAAC;iBAAM,IAAI,SAAS,EAAE,CAAC;gBACrB,WAAW,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,uBAAuB,EAAE,KAAK,EAAE,GAAG,KAAK,GAAG,SAAS,EAAE,EAAE,CAAC;YACrG,CAAC;iBAAM,CAAC;gBACN,WAAW,GAAG;oBACZ,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,GAAG,KAAK,8EAA8E;iBAC9F,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,KAAkB,EAAE,CAAC;QAC5B,MAAM,CAAC,IAAI,CACT,eAAe,MAAM,yBAAyB,EAC9C,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CACjE,CAAC;IACJ,CAAC;IAED,OAAO,CACL,WAAW,IAAI;QACb,OAAO,EAAE,KAAK;QACd,KAAK,EAAE,GAAG,KAAK,qDAAqD,eAAe,EAAE;KACtF,CACF,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB;IAClC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,oBAAoB,EAAE,CAAC;IAEtD,MAAM,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;IAC1C,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IAClE,MAAM,CAAC,IAAI,CAAC,uBAAuB,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAE5D,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC;QAC/B,MAAM,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;QAC1C,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,EAAE;YACjD,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB;IACpC,MAAM,IAAI,GAAG,SAAS,CAAC,SAAS,EAAE,IAAI,CAAC;IAEvC,4CAA4C;IAC5C,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC;QACnB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,0DAA0D;IAC1D,MAAM,MAAM,GAAG,IAAI,CAAC,qBAAqB,CAAC;IAC1C,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/C,6BAA6B;QAC7B,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,UAAU,EAAE,CAAC;YACf,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;YAC/D,OAAO,EAAE,aAAa,EAAE,UAAU,UAAU,EAAE,EAAE,CAAC;QACnD,CAAC;IACH,CAAC;IAED,+DAA+D;IAC/D,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;IACvB,IAAI,KAAK,EAAE,QAAQ,IAAI,KAAK,EAAE,QAAQ,EAAE,CAAC;QACvC,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC1F,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;QAC5C,OAAO,EAAE,aAAa,EAAE,SAAS,WAAW,EAAE,EAAE,CAAC;IACnD,CAAC;IAED,gEAAgE;IAChE,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC;IAChC,IAAI,SAAS,EAAE,UAAU,IAAI,SAAS,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpE,MAAM,KAAK,GAAG,aAAa,CAAC,SAAS,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;QACzE,OAAO,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAC;QAC9D,OAAO,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE,CAAC;IAC9C,CAAC;IAED,sDAAsD;IACtD,OAAO,CAAC,IAAI,CAAC,uEAAuE,CAAC,CAAC;IACtF,OAAO,CAAC,IAAI,CAAC,gFAAgF,CAAC,CAAC;IAC/F,OAAO,EAAE,CAAC;AACZ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"revocation.d.ts","sourceRoot":"","sources":["../../../src/core/auth/revocation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"revocation.d.ts","sourceRoot":"","sources":["../../../src/core/auth/revocation.ts"],"names":[],"mappings":"AAmBA,eAAO,MAAM,iBAAiB,GAAI,OAAO,MAAM,KAAG,OAAgD,CAAC;AAEnG,eAAO,MAAM,YAAY,GAAI,KAAK,MAAM,KAAG,OAAuC,CAAC;AAEnF,eAAO,MAAM,aAAa,GAAI,MAAM,MAAM,KAAG,OAAwD,CAAC"}
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import { appConfig } from '../bootstrap/init-config.js';
|
|
2
2
|
import { trim } from '../utils/utils.js';
|
|
3
3
|
const revoked = appConfig.webServer?.auth?.revoked || {};
|
|
4
|
-
const
|
|
4
|
+
const entries = (Array.isArray(revoked.jwtTokens) ? revoked.jwtTokens : [])
|
|
5
|
+
.map((e) => trim(e?.token))
|
|
6
|
+
.filter(Boolean);
|
|
7
|
+
// Full-token entries (legacy `<expire>.<hex>` or full standard JWT `a.b.c`) — exact match
|
|
8
|
+
const revokedExactTokenSet = new Set(entries.filter((v) => v.includes('.')));
|
|
9
|
+
// Bare jti entries (no dots) — match by JWT id
|
|
10
|
+
const revokedJtiSet = new Set(entries.filter((v) => !v.includes('.')));
|
|
5
11
|
const revokedUsersSet = new Set((Array.isArray(revoked.users) ? revoked.users : []).map((u) => trim(u).toLowerCase()).filter(Boolean));
|
|
6
|
-
export const isJwtTokenRevoked = (token) =>
|
|
12
|
+
export const isJwtTokenRevoked = (token) => revokedExactTokenSet.has(trim(token));
|
|
13
|
+
export const isJtiRevoked = (jti) => revokedJtiSet.has(trim(jti));
|
|
7
14
|
export const isUserRevoked = (user) => revokedUsersSet.has(trim(user).toLowerCase());
|
|
8
15
|
//# sourceMappingURL=revocation.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"revocation.js","sourceRoot":"","sources":["../../../src/core/auth/revocation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAEzC,MAAM,OAAO,GAAG,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,IAAK,EAAU,CAAC;AAElE,MAAM,
|
|
1
|
+
{"version":3,"file":"revocation.js","sourceRoot":"","sources":["../../../src/core/auth/revocation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAEzC,MAAM,OAAO,GAAG,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,IAAK,EAAU,CAAC;AAElE,MAAM,OAAO,GAAa,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;KAClF,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;KAC/B,MAAM,CAAC,OAAO,CAAC,CAAC;AAEnB,0FAA0F;AAC1F,MAAM,oBAAoB,GAAgB,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAE1F,+CAA+C;AAC/C,MAAM,aAAa,GAAgB,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAEpF,MAAM,eAAe,GAAgB,IAAI,GAAG,CAC1C,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAC3G,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,KAAa,EAAW,EAAE,CAAC,oBAAoB,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;AAEnG,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,GAAW,EAAW,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAEnF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,IAAY,EAAW,EAAE,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC"}
|
|
@@ -5,6 +5,11 @@ export type TTokenType = 'permanent' | 'JWT';
|
|
|
5
5
|
export interface ITokenPayload {
|
|
6
6
|
user: string;
|
|
7
7
|
expire: number;
|
|
8
|
+
iat?: string;
|
|
9
|
+
service?: string;
|
|
10
|
+
jti?: string;
|
|
11
|
+
iss?: string;
|
|
12
|
+
ip?: string;
|
|
8
13
|
[key: string]: any;
|
|
9
14
|
}
|
|
10
15
|
export interface ICheckTokenResult {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/auth/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,UAAU,GAAG,WAAW,GAAG,KAAK,CAAC;AAE7C,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/auth/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,UAAU,GAAG,WAAW,GAAG,KAAK,CAAC;AAE7C,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,CAAC;IAEZ,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,aAAa,CAAC;IAExB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,MAAM,QAAQ,GAAG,uBAAuB,GAAG,UAAU,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEjF,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,QAAQ,EAAE,CAAC;IACvB,aAAa,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC7B,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACvC,OAAO,CAAC,EAAE,GAAG,CAAC;CACf"}
|
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.4.
|
|
4
|
+
"version": "0.4.96",
|
|
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",
|
|
@@ -46,7 +46,9 @@
|
|
|
46
46
|
"template:stdio": "node dist/template/start.js stdio",
|
|
47
47
|
"token-gen": "node dist/core/auth/token-generator/server.js",
|
|
48
48
|
"tsoa:spec": "tsoa spec",
|
|
49
|
-
"check-llm": "node dist/core/agent-tester/check-llm.js"
|
|
49
|
+
"check-llm": "node dist/core/agent-tester/check-llm.js",
|
|
50
|
+
"test:ip-check": "npm run build && node tests/ip-check.test.mjs",
|
|
51
|
+
"test:jwt": "npm run build && node tests/jwt.test.mjs"
|
|
50
52
|
},
|
|
51
53
|
"keywords": [
|
|
52
54
|
"mcp",
|
|
@@ -86,6 +88,7 @@
|
|
|
86
88
|
"fa-consul": "^1.0.7",
|
|
87
89
|
"helmet": "^8.1.0",
|
|
88
90
|
"js-yaml": "^4.1.1",
|
|
91
|
+
"jsonwebtoken": "^9.0.3",
|
|
89
92
|
"node-cache": "^5.1.2",
|
|
90
93
|
"openai": "^6.33.0",
|
|
91
94
|
"pgvector": "^0.2.1",
|
|
@@ -101,6 +104,7 @@
|
|
|
101
104
|
"@types/cors": "^2.8.19",
|
|
102
105
|
"@types/express": "^5.0.6",
|
|
103
106
|
"@types/js-yaml": "^4.0.9",
|
|
107
|
+
"@types/jsonwebtoken": "^9.0.10",
|
|
104
108
|
"@types/mssql": "^9.1.11",
|
|
105
109
|
"@types/node": "^25.5.2",
|
|
106
110
|
"@types/swagger-ui-express": "^4.1.8",
|
package/scripts/generate-jwt.js
CHANGED
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
* -s, --service-name Service name (optional). ENV: JWT_PAYLOAD_SERVICE_NAME
|
|
12
12
|
* -p, --params Extra payload "key=value;key=value" (optional). ENV: JWT_PAYLOAD_PARAMS
|
|
13
13
|
*
|
|
14
|
-
* The
|
|
14
|
+
* The signing secret is read from config: webServer.auth.jwtToken.encryptKey
|
|
15
|
+
* Token format: standard signed JWT (HS256), 3 segments header.payload.signature.
|
|
15
16
|
*/
|
|
16
17
|
|
|
17
18
|
import crypto from 'crypto';
|
|
@@ -19,6 +20,7 @@ import { readFileSync } from 'fs';
|
|
|
19
20
|
import { fileURLToPath } from 'url';
|
|
20
21
|
import { dirname, resolve } from 'path';
|
|
21
22
|
import configModule from 'config';
|
|
23
|
+
import jwt from 'jsonwebtoken';
|
|
22
24
|
|
|
23
25
|
// ── CLI argument parsing ────────────────────────────────────────────
|
|
24
26
|
|
|
@@ -81,17 +83,11 @@ if (!encryptKey || String(encryptKey).trim() === '' || encryptKey === '***') {
|
|
|
81
83
|
process.exit(1);
|
|
82
84
|
}
|
|
83
85
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
function encrypt(text) {
|
|
90
|
-
const buffer = Buffer.from(text);
|
|
91
|
-
const iv = crypto.randomBytes(16);
|
|
92
|
-
const cipher = crypto.createCipheriv(ALGORITHM, KEY, iv);
|
|
93
|
-
const encryptedBuf = Buffer.concat([iv, cipher.update(buffer), cipher.final()]);
|
|
94
|
-
return encryptedBuf.toString('hex');
|
|
86
|
+
let configuredIssuer = '';
|
|
87
|
+
try {
|
|
88
|
+
configuredIssuer = String(configModule.get('webServer.auth.jwtToken.issuer') || '').trim();
|
|
89
|
+
} catch {
|
|
90
|
+
// optional field, ignore
|
|
95
91
|
}
|
|
96
92
|
|
|
97
93
|
// ── Auto-detect service name if checkMCPName is enabled ─────────────
|
|
@@ -126,14 +122,9 @@ if (!effectiveService || !effectiveService.trim()) {
|
|
|
126
122
|
}
|
|
127
123
|
}
|
|
128
124
|
|
|
129
|
-
// ── Build payload
|
|
130
|
-
|
|
131
|
-
const payload = {};
|
|
132
|
-
payload.user = username.trim().toLowerCase();
|
|
125
|
+
// ── Build payload (private claims only) ─────────────────────────────
|
|
133
126
|
|
|
134
|
-
|
|
135
|
-
payload.service = effectiveService.trim();
|
|
136
|
-
}
|
|
127
|
+
const privateClaims = {};
|
|
137
128
|
|
|
138
129
|
// Parse extra params: "key1=value1;key2=value2"
|
|
139
130
|
if (paramsRaw && paramsRaw.trim()) {
|
|
@@ -150,32 +141,67 @@ if (paramsRaw && paramsRaw.trim()) {
|
|
|
150
141
|
console.error(`Error: empty key in param "${pair}"`);
|
|
151
142
|
process.exit(1);
|
|
152
143
|
}
|
|
153
|
-
|
|
144
|
+
// Skip reserved fields if user accidentally passes them
|
|
145
|
+
if (['user', 'expire', 'iat', 'service', 'sub', 'aud', 'exp', 'iss', 'jti'].includes(key)) {
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
privateClaims[key] = value;
|
|
154
149
|
}
|
|
155
150
|
}
|
|
156
151
|
|
|
157
|
-
const expire = Date.now() + liveTimeSec * 1000;
|
|
158
|
-
payload.expire = expire;
|
|
159
|
-
payload.iat = new Date().toISOString();
|
|
160
|
-
|
|
161
152
|
// ── Generate token ──────────────────────────────────────────────────
|
|
162
153
|
|
|
163
|
-
const
|
|
154
|
+
const normalizedUser = username.trim().toLowerCase();
|
|
155
|
+
const signOptions = {
|
|
156
|
+
algorithm: 'HS256',
|
|
157
|
+
subject: normalizedUser,
|
|
158
|
+
expiresIn: liveTimeSec,
|
|
159
|
+
jwtid: crypto.randomUUID(),
|
|
160
|
+
};
|
|
161
|
+
if (effectiveService && effectiveService.trim()) {
|
|
162
|
+
signOptions.audience = effectiveService.trim();
|
|
163
|
+
}
|
|
164
|
+
if (configuredIssuer) {
|
|
165
|
+
signOptions.issuer = configuredIssuer;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const token = jwt.sign(privateClaims, String(encryptKey), signOptions);
|
|
169
|
+
|
|
170
|
+
// ── Decode for display (normalized payload, mirrors checkJwtToken) ──
|
|
171
|
+
|
|
172
|
+
const decoded = jwt.decode(token, { json: true }) || {};
|
|
173
|
+
const expireMs = (decoded.exp || 0) * 1000;
|
|
174
|
+
const iatIso = decoded.iat ? new Date(decoded.iat * 1000).toISOString() : new Date().toISOString();
|
|
175
|
+
|
|
176
|
+
const displayPayload = { user: normalizedUser };
|
|
177
|
+
if (decoded.aud) {
|
|
178
|
+
displayPayload.service = Array.isArray(decoded.aud) ? decoded.aud[0] : decoded.aud;
|
|
179
|
+
}
|
|
180
|
+
displayPayload.expire = expireMs;
|
|
181
|
+
displayPayload.iat = iatIso;
|
|
182
|
+
if (decoded.jti) {
|
|
183
|
+
displayPayload.jti = decoded.jti;
|
|
184
|
+
}
|
|
185
|
+
if (decoded.iss) {
|
|
186
|
+
displayPayload.iss = decoded.iss;
|
|
187
|
+
}
|
|
188
|
+
for (const [k, v] of Object.entries(privateClaims)) {
|
|
189
|
+
displayPayload[k] = v;
|
|
190
|
+
}
|
|
164
191
|
|
|
165
192
|
console.log('');
|
|
166
193
|
console.log('JWT Token generated successfully');
|
|
167
194
|
console.log('─'.repeat(50));
|
|
168
|
-
console.log(` User: ${
|
|
169
|
-
if (
|
|
170
|
-
console.log(` Service: ${
|
|
195
|
+
console.log(` User: ${displayPayload.user}`);
|
|
196
|
+
if (displayPayload.service) {
|
|
197
|
+
console.log(` Service: ${displayPayload.service}`);
|
|
171
198
|
}
|
|
172
199
|
console.log(` TTL: ${ttlRaw} (${liveTimeSec} seconds)`);
|
|
173
|
-
console.log(` Expires: ${new Date(
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
.join('; ');
|
|
200
|
+
console.log(` Expires: ${new Date(expireMs).toISOString()}`);
|
|
201
|
+
console.log(` JTI: ${displayPayload.jti || ''}`);
|
|
202
|
+
const extraEntries = Object.entries(privateClaims);
|
|
203
|
+
if (extraEntries.length) {
|
|
204
|
+
const extra = extraEntries.map(([k, v]) => `${k}=${v}`).join('; ');
|
|
179
205
|
console.log(` Params: ${extra}`);
|
|
180
206
|
}
|
|
181
207
|
console.log('─'.repeat(50));
|
|
@@ -183,5 +209,5 @@ console.log('');
|
|
|
183
209
|
console.log(token);
|
|
184
210
|
console.log('');
|
|
185
211
|
console.log('__PAYLOAD_JSON__');
|
|
186
|
-
console.log(JSON.stringify({ ...
|
|
212
|
+
console.log(JSON.stringify({ ...displayPayload, ttl: ttlRaw, expire_iso: new Date(expireMs).toISOString() }));
|
|
187
213
|
console.log('__END_PAYLOAD_JSON__');
|
package/scripts/update-sdk.js
CHANGED
|
@@ -131,3 +131,19 @@ for (const { name, src, dest, preserve = [], respectPin = false } of targets) {
|
|
|
131
131
|
console.log(`${name} updated`);
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
|
+
|
|
135
|
+
const scriptsSrcDir = join(cwd, './node_modules/fa-mcp-sdk/scripts');
|
|
136
|
+
const scriptsDestDir = join(cwd, 'scripts');
|
|
137
|
+
const individualScripts = ['generate-jwt.js'];
|
|
138
|
+
|
|
139
|
+
for (const file of individualScripts) {
|
|
140
|
+
const src = join(scriptsSrcDir, file);
|
|
141
|
+
const dest = join(scriptsDestDir, file);
|
|
142
|
+
if (!existsSync(src)) {
|
|
143
|
+
console.error('Source not found:', src);
|
|
144
|
+
process.exit(1);
|
|
145
|
+
}
|
|
146
|
+
mkdirSync(dirname(dest), { recursive: true });
|
|
147
|
+
cpSync(src, dest);
|
|
148
|
+
console.log(`scripts/${file} updated`);
|
|
149
|
+
}
|