@zxkane/quip-mcp-server
Version:
MCP server for interacting with Quip spreadsheets
159 lines • 4.88 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.AuthService = void 0;
exports.createAuthServiceFromEnv = createAuthServiceFromEnv;
/**
* Authentication for the Quip MCP Server
*/
const crypto = __importStar(require("crypto"));
const errors_1 = require("./errors");
const logger_1 = require("./logger");
/**
* Default authentication configuration
*/
const DEFAULT_AUTH_CONFIG = {
enabled: false,
apiKeyHeader: 'X-API-Key'
};
/**
* Authentication service
*/
class AuthService {
/**
* Create a new authentication service
*
* @param config Authentication configuration
*/
constructor(config = {}) {
this.config = {
...DEFAULT_AUTH_CONFIG,
...config
};
// Generate a random API key if enabled but not provided
if (this.config.enabled && !this.config.apiKey) {
this.config.apiKey = this.generateApiKey();
logger_1.logger.info(`Generated random API key: ${this.config.apiKey}`);
}
}
/**
* Check if authentication is enabled
*
* @returns True if authentication is enabled
*/
isEnabled() {
return this.config.enabled;
}
/**
* Get the API key header name
*
* @returns API key header name
*/
getApiKeyHeader() {
return this.config.apiKeyHeader;
}
/**
* Get the API key
*
* @returns API key or undefined if authentication is disabled
*/
getApiKey() {
return this.config.apiKey;
}
/**
* Authenticate a request
*
* @param headers Request headers
* @throws AuthenticationError if authentication fails
*/
authenticate(headers) {
if (!this.config.enabled) {
return;
}
const apiKey = this.getApiKeyFromHeaders(headers);
if (!apiKey) {
logger_1.logger.warn('Authentication failed: API key missing');
throw new errors_1.AuthenticationError('API key missing');
}
if (apiKey !== this.config.apiKey) {
logger_1.logger.warn('Authentication failed: Invalid API key');
throw new errors_1.AuthenticationError('Invalid API key');
}
logger_1.logger.debug('Authentication successful');
}
/**
* Get the API key from request headers
*
* @param headers Request headers
* @returns API key or undefined if not found
*/
getApiKeyFromHeaders(headers) {
const headerName = this.config.apiKeyHeader.toLowerCase();
for (const [key, value] of Object.entries(headers)) {
if (key.toLowerCase() === headerName) {
if (Array.isArray(value)) {
return value[0];
}
return value;
}
}
return undefined;
}
/**
* Generate a random API key
*
* @returns Random API key
*/
generateApiKey() {
return crypto.randomBytes(32).toString('hex');
}
}
exports.AuthService = AuthService;
/**
* Create an authentication service from environment variables
*
* @returns Authentication service
*/
function createAuthServiceFromEnv() {
const enabled = process.env.MCP_AUTH_ENABLED === 'true';
const apiKey = process.env.MCP_API_KEY;
const apiKeyHeader = process.env.MCP_API_KEY_HEADER || 'X-API-Key';
return new AuthService({
enabled,
apiKey,
apiKeyHeader
});
}
//# sourceMappingURL=auth.js.map