/**
* @fileoverview IBM i token authentication strategy implementation.
* Validates custom IBM i bearer tokens generated by TokenManager against
* authenticated connection pools. This strategy integrates the existing
* TokenManager system with the MCP authentication framework.
* @module src/mcp-server/transports/auth/strategies/IBMiTokenStrategy
*/
import { JsonRpcErrorCode, McpError } from "@/types-global/errors.js";
import { logger, requestContextService } from "@/utils/index.js";
import { TokenManager } from "@/ibmi-mcp-server/auth/tokenManager.js";
import type { AuthInfo } from "../lib/authTypes.js";
import type { AuthStrategy } from "./authStrategy.js";
export class IBMiTokenStrategy implements AuthStrategy {
private tokenManager: TokenManager;
constructor() {
const context = requestContextService.createRequestContext({
operation: "IBMiTokenStrategy.constructor",
});
logger.debug(
context,
"Initializing IBM i token authentication strategy...",
);
this.tokenManager = TokenManager.getInstance();
logger.info(context, "IBM i token strategy initialized successfully");
}
/**
* Verifies an IBM i authentication token using the TokenManager
* @param token - The raw IBM i token string extracted from the Bearer header
* @returns A promise that resolves with AuthInfo on successful verification
* @throws {McpError} if the token is invalid, expired, or fails verification
*/
async verify(token: string): Promise<AuthInfo> {
const context = requestContextService.createRequestContext({
operation: "IBMiTokenStrategy.verify",
});
logger.debug(context, "Attempting to verify IBM i authentication token");
// Use existing TokenManager validation
const validation = this.tokenManager.validateToken(token, context);
if (!validation.valid || !validation.session) {
logger.warning(
{
...context,
tokenPrefix: token.substring(0, 10) + "...",
error: validation.error,
},
"IBM i token validation failed",
);
throw new McpError(
JsonRpcErrorCode.Unauthorized,
validation.error || "Invalid IBM i authentication token",
{
...context,
tokenPrefix: token.substring(0, 10) + "...",
},
);
}
// Convert to AuthInfo format expected by middleware
const authInfo: AuthInfo = {
token,
clientId: validation.session.credentials.user, // Use IBM i username as clientId
scopes: ["ibmi:access"], // Standard scope for IBM i access
subject: validation.session.credentials.user,
// Add IBM i specific context for YAML tools to use
ibmiToken: token,
ibmiHost: validation.session.credentials.host,
};
logger.info(
{
...context,
clientId: authInfo.clientId,
ibmiHost: validation.session.credentials.host,
scopes: authInfo.scopes,
},
"IBM i token verification successful",
);
return authInfo;
}
}