@mcp-z/oauth-google 1.0.0

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.
Files changed (89) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +93 -0
  3. package/dist/cjs/index.d.cts +16 -0
  4. package/dist/cjs/index.d.ts +16 -0
  5. package/dist/cjs/index.js +112 -0
  6. package/dist/cjs/index.js.map +1 -0
  7. package/dist/cjs/lib/dcr-router.d.cts +44 -0
  8. package/dist/cjs/lib/dcr-router.d.ts +44 -0
  9. package/dist/cjs/lib/dcr-router.js +1189 -0
  10. package/dist/cjs/lib/dcr-router.js.map +1 -0
  11. package/dist/cjs/lib/dcr-utils.d.cts +160 -0
  12. package/dist/cjs/lib/dcr-utils.d.ts +160 -0
  13. package/dist/cjs/lib/dcr-utils.js +860 -0
  14. package/dist/cjs/lib/dcr-utils.js.map +1 -0
  15. package/dist/cjs/lib/dcr-verify.d.cts +53 -0
  16. package/dist/cjs/lib/dcr-verify.d.ts +53 -0
  17. package/dist/cjs/lib/dcr-verify.js +193 -0
  18. package/dist/cjs/lib/dcr-verify.js.map +1 -0
  19. package/dist/cjs/lib/fetch-with-timeout.d.cts +14 -0
  20. package/dist/cjs/lib/fetch-with-timeout.d.ts +14 -0
  21. package/dist/cjs/lib/fetch-with-timeout.js +257 -0
  22. package/dist/cjs/lib/fetch-with-timeout.js.map +1 -0
  23. package/dist/cjs/lib/token-verifier.d.cts +44 -0
  24. package/dist/cjs/lib/token-verifier.d.ts +44 -0
  25. package/dist/cjs/lib/token-verifier.js +253 -0
  26. package/dist/cjs/lib/token-verifier.js.map +1 -0
  27. package/dist/cjs/package.json +1 -0
  28. package/dist/cjs/providers/dcr.d.cts +107 -0
  29. package/dist/cjs/providers/dcr.d.ts +107 -0
  30. package/dist/cjs/providers/dcr.js +584 -0
  31. package/dist/cjs/providers/dcr.js.map +1 -0
  32. package/dist/cjs/providers/loopback-oauth.d.cts +119 -0
  33. package/dist/cjs/providers/loopback-oauth.d.ts +119 -0
  34. package/dist/cjs/providers/loopback-oauth.js +1334 -0
  35. package/dist/cjs/providers/loopback-oauth.js.map +1 -0
  36. package/dist/cjs/providers/service-account.d.cts +131 -0
  37. package/dist/cjs/providers/service-account.d.ts +131 -0
  38. package/dist/cjs/providers/service-account.js +800 -0
  39. package/dist/cjs/providers/service-account.js.map +1 -0
  40. package/dist/cjs/schemas/index.d.cts +20 -0
  41. package/dist/cjs/schemas/index.d.ts +20 -0
  42. package/dist/cjs/schemas/index.js +37 -0
  43. package/dist/cjs/schemas/index.js.map +1 -0
  44. package/dist/cjs/setup/config.d.cts +112 -0
  45. package/dist/cjs/setup/config.d.ts +112 -0
  46. package/dist/cjs/setup/config.js +236 -0
  47. package/dist/cjs/setup/config.js.map +1 -0
  48. package/dist/cjs/types.d.cts +173 -0
  49. package/dist/cjs/types.d.ts +173 -0
  50. package/dist/cjs/types.js +16 -0
  51. package/dist/cjs/types.js.map +1 -0
  52. package/dist/esm/index.d.ts +16 -0
  53. package/dist/esm/index.js +16 -0
  54. package/dist/esm/index.js.map +1 -0
  55. package/dist/esm/lib/dcr-router.d.ts +44 -0
  56. package/dist/esm/lib/dcr-router.js +515 -0
  57. package/dist/esm/lib/dcr-router.js.map +1 -0
  58. package/dist/esm/lib/dcr-utils.d.ts +160 -0
  59. package/dist/esm/lib/dcr-utils.js +270 -0
  60. package/dist/esm/lib/dcr-utils.js.map +1 -0
  61. package/dist/esm/lib/dcr-verify.d.ts +53 -0
  62. package/dist/esm/lib/dcr-verify.js +53 -0
  63. package/dist/esm/lib/dcr-verify.js.map +1 -0
  64. package/dist/esm/lib/fetch-with-timeout.d.ts +14 -0
  65. package/dist/esm/lib/fetch-with-timeout.js +30 -0
  66. package/dist/esm/lib/fetch-with-timeout.js.map +1 -0
  67. package/dist/esm/lib/token-verifier.d.ts +44 -0
  68. package/dist/esm/lib/token-verifier.js +53 -0
  69. package/dist/esm/lib/token-verifier.js.map +1 -0
  70. package/dist/esm/package.json +1 -0
  71. package/dist/esm/providers/dcr.d.ts +107 -0
  72. package/dist/esm/providers/dcr.js +242 -0
  73. package/dist/esm/providers/dcr.js.map +1 -0
  74. package/dist/esm/providers/loopback-oauth.d.ts +119 -0
  75. package/dist/esm/providers/loopback-oauth.js +639 -0
  76. package/dist/esm/providers/loopback-oauth.js.map +1 -0
  77. package/dist/esm/providers/service-account.d.ts +131 -0
  78. package/dist/esm/providers/service-account.js +353 -0
  79. package/dist/esm/providers/service-account.js.map +1 -0
  80. package/dist/esm/schemas/index.d.ts +20 -0
  81. package/dist/esm/schemas/index.js +18 -0
  82. package/dist/esm/schemas/index.js.map +1 -0
  83. package/dist/esm/setup/config.d.ts +112 -0
  84. package/dist/esm/setup/config.js +258 -0
  85. package/dist/esm/setup/config.js.map +1 -0
  86. package/dist/esm/types.d.ts +173 -0
  87. package/dist/esm/types.js +6 -0
  88. package/dist/esm/types.js.map +1 -0
  89. package/package.json +89 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/oauth/oauth-google/src/providers/service-account.ts"],"sourcesContent":["import { promises as fs } from 'fs';\nimport { OAuth2Client } from 'google-auth-library';\nimport { importPKCS8, SignJWT } from 'jose';\nimport type { AuthContext, EnrichedExtra, Logger, OAuth2TokenStorageProvider } from '../types.ts';\n\n/**\n * Service Account Key File Structure\n * Standard Google Cloud service account JSON key format\n */\ninterface ServiceAccountKey {\n type: 'service_account';\n project_id: string;\n private_key_id: string;\n private_key: string;\n client_email: string;\n client_id: string;\n auth_uri: string;\n token_uri: string;\n auth_provider_x509_cert_url?: string;\n client_x509_cert_url?: string;\n}\n\n/**\n * Service Account Provider Configuration\n */\nexport interface ServiceAccountConfig {\n /** Path to Google Cloud service account JSON key file */\n keyFilePath: string;\n /** OAuth scopes to request (e.g., ['https://www.googleapis.com/auth/gmail.readonly']) */\n scopes: string[];\n /** Logger for auth operations */\n logger: Logger;\n}\n\n/**\n * Token Exchange Response from Google OAuth endpoint\n */\ninterface TokenResponse {\n access_token: string;\n expires_in: number;\n token_type: string;\n}\n\n/**\n * ServiceAccountProvider implements OAuth2TokenStorageProvider using Google Service Accounts\n * with JWT-based (2-legged OAuth) authentication.\n *\n * This provider:\n * - Loads service account key file from disk\n * - Generates self-signed JWTs using RS256 algorithm\n * - Exchanges JWTs for access tokens at Google's token endpoint\n * - Does NOT store tokens (regenerates on each request)\n * - Provides single static identity (no account management)\n *\n * @example\n * ```typescript\n * const provider = new ServiceAccountProvider({\n * keyFilePath: '/path/to/service-account-key.json',\n * scopes: ['https://www.googleapis.com/auth/drive.readonly'],\n * });\n *\n * // Get authenticated OAuth2Client for googleapis\n * const auth = provider.toAuth('default');\n * const drive = google.drive({ version: 'v3', auth });\n * ```\n */\nexport class ServiceAccountProvider implements OAuth2TokenStorageProvider {\n private config: ServiceAccountConfig;\n private keyFilePath: string;\n private scopes: string[];\n private keyData?: ServiceAccountKey;\n private cachedToken?: { token: string; expiry: number };\n\n constructor(config: ServiceAccountConfig) {\n this.config = config;\n this.keyFilePath = config.keyFilePath;\n this.scopes = config.scopes;\n }\n\n /**\n * Load and parse service account key file from disk\n * Validates structure and caches for subsequent calls\n */\n private async loadKeyFile(): Promise<ServiceAccountKey> {\n // Return cached key data if already loaded\n if (this.keyData) {\n return this.keyData;\n }\n\n try {\n // Read key file from disk\n const fileContent = await fs.readFile(this.keyFilePath, 'utf-8');\n\n // Parse JSON\n let keyData: unknown;\n try {\n keyData = JSON.parse(fileContent);\n } catch (parseError) {\n throw new Error(`Failed to parse service account key file as JSON: ${this.keyFilePath}\\n` + `Error: ${parseError instanceof Error ? parseError.message : String(parseError)}`);\n }\n\n // Validate structure\n this.keyData = this.validateKeyFile(keyData);\n return this.keyData;\n } catch (error) {\n // Handle file not found\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n throw new Error(`Service account key file not found: ${this.keyFilePath}\\nMake sure GOOGLE_SERVICE_ACCOUNT_KEY_FILE points to a valid file path.`);\n }\n\n // Handle permission errors\n if ((error as NodeJS.ErrnoException).code === 'EACCES') {\n throw new Error(`Permission denied reading service account key file: ${this.keyFilePath}\\nCheck file permissions (should be readable by current user).`);\n }\n\n // Re-throw other errors\n throw error;\n }\n }\n\n /**\n * Validate service account key file structure\n * Ensures all required fields are present and correctly typed\n */\n private validateKeyFile(data: unknown): ServiceAccountKey {\n if (!data || typeof data !== 'object') {\n throw new Error('Service account key file must contain a JSON object');\n }\n\n const obj = data as Record<string, unknown>;\n\n // Validate type field\n if (obj.type !== 'service_account') {\n throw new Error(`Invalid service account key file: Expected type \"service_account\", got \"${obj.type}\"\\nMake sure you downloaded a service account key, not an OAuth client credential.`);\n }\n\n // Validate required string fields\n const requiredFields: Array<keyof ServiceAccountKey> = ['project_id', 'private_key_id', 'private_key', 'client_email', 'client_id', 'auth_uri', 'token_uri'];\n\n const missingFields = requiredFields.filter((field) => typeof obj[field] !== 'string' || !obj[field]);\n\n if (missingFields.length > 0) {\n throw new Error(`Service account key file is missing required fields: ${missingFields.join(', ')}\\nMake sure you downloaded a complete service account key file from Google Cloud Console.`);\n }\n\n // Validate private key format\n const privateKey = obj.private_key as string;\n if (!privateKey.includes('BEGIN PRIVATE KEY') || !privateKey.includes('END PRIVATE KEY')) {\n throw new Error('Service account private_key field does not contain a valid PEM-formatted key.\\n' + 'Expected format: -----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----');\n }\n\n return obj as unknown as ServiceAccountKey;\n }\n\n /**\n * Generate signed JWT (JSON Web Token) for service account authentication\n * Uses RS256 algorithm with private key from key file\n */\n private async generateJWT(): Promise<string> {\n const keyData = await this.loadKeyFile();\n\n // Import private key using jose\n const privateKey = await importPKCS8(keyData.private_key, 'RS256');\n\n // Current time\n const now = Math.floor(Date.now() / 1000);\n\n // Create JWT with required claims for Google OAuth\n const jwt = await new SignJWT({\n iss: keyData.client_email, // Issuer: service account email\n scope: this.scopes.join(' '), // Scopes: space-separated\n aud: 'https://oauth2.googleapis.com/token', // Audience: token endpoint\n exp: now + 3600, // Expiration: 1 hour from now\n iat: now, // Issued at: current time\n })\n .setProtectedHeader({ alg: 'RS256', typ: 'JWT' })\n .sign(privateKey);\n\n return jwt;\n }\n\n /**\n * Exchange signed JWT for access token at Google OAuth endpoint\n * POST to https://oauth2.googleapis.com/token with grant_type=jwt-bearer\n */\n private async exchangeJWT(jwt: string): Promise<{ token: string; expiry: number }> {\n const tokenEndpoint = 'https://oauth2.googleapis.com/token';\n\n try {\n const response = await fetch(tokenEndpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: new URLSearchParams({\n grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',\n assertion: jwt,\n }),\n });\n\n // Handle non-2xx responses\n if (!response.ok) {\n const errorText = await response.text();\n let errorMessage: string;\n\n try {\n const errorJson = JSON.parse(errorText);\n errorMessage = errorJson.error_description || errorJson.error || errorText;\n } catch {\n errorMessage = errorText;\n }\n\n // 400: Invalid JWT (malformed claims, expired, etc.)\n if (response.status === 400) {\n throw new Error(`Invalid service account JWT: ${errorMessage}\\nThis usually means the JWT claims are malformed or the key file is invalid.`);\n }\n\n // 401: Unauthorized (revoked service account, wrong scopes, etc.)\n if (response.status === 401) {\n throw new Error(`Service account authentication failed: ${errorMessage}\\nThe service account may have been disabled or deleted. Check Google Cloud Console.`);\n }\n\n // Other errors\n throw new Error(`Token exchange failed (HTTP ${response.status}): ${errorMessage}`);\n }\n\n // Parse successful response\n const tokenData = (await response.json()) as TokenResponse;\n\n // Calculate expiry timestamp (token expires in ~1 hour)\n const expiry = Date.now() + (tokenData.expires_in - 60) * 1000; // Subtract 60s for safety margin\n\n return {\n token: tokenData.access_token,\n expiry,\n };\n } catch (error) {\n // Network errors\n if (error instanceof TypeError && error.message.includes('fetch')) {\n throw new Error('Network error connecting to Google OAuth endpoint. Check internet connection.');\n }\n\n // Re-throw other errors\n throw error;\n }\n }\n\n /**\n * Get access token for Google APIs\n * Generates fresh JWT and exchanges for access token on each call\n *\n * Note: accountId parameter is ignored for service accounts (service account is single static identity)\n */\n async getAccessToken(_accountId?: string): Promise<string> {\n // Check if we have a valid cached token (optional optimization)\n if (this.cachedToken && this.cachedToken.expiry > Date.now()) {\n return this.cachedToken.token;\n }\n\n try {\n // Generate JWT\n const jwt = await this.generateJWT();\n\n // Exchange for access token\n const { token, expiry } = await this.exchangeJWT(jwt);\n\n // Cache token for subsequent calls (optional optimization)\n this.cachedToken = { token, expiry };\n\n return token;\n } catch (error) {\n // Add context to errors\n throw new Error(`Failed to get service account access token: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n /**\n * Get OAuth2Client with service account credentials for googleapis\n * This is the CRITICAL method that servers use to get authenticated API clients\n *\n * Service account ONLY works with accountId='service-account' (single static identity)\n *\n @param accountId - Account identifier (must be 'service-account' or undefined)\n * @returns OAuth2Client instance with access token credentials set\n */\n toAuth(accountId?: string): OAuth2Client {\n // Service account ONLY works with 'service-account' account ID\n if (accountId !== undefined && accountId !== 'service-account') {\n throw new Error(`ServiceAccountProvider only supports accountId='service-account', got '${accountId}'. Service account uses a single static identity pattern.`);\n }\n\n // Create OAuth2Client instance (no client ID/secret needed for service accounts)\n const client = new OAuth2Client();\n\n // Override getRequestMetadataAsync to provide authentication headers for each request\n // This is the method googleapis calls to get auth headers - can be async and fetch tokens on-demand\n (\n client as OAuth2Client & {\n getRequestMetadataAsync: (url?: string) => Promise<{ headers: Headers | Map<string, string> }>;\n }\n ).getRequestMetadataAsync = async (_url?: string) => {\n try {\n // Get fresh access token (can be async, will trigger JWT generation if needed)\n const token = await this.getAccessToken();\n\n // Update client credentials for consistency (other googleapis methods might check these)\n client.credentials = {\n access_token: token,\n token_type: 'Bearer',\n };\n\n // Return headers as Headers instance for proper TypeScript types\n const headers = new Headers();\n headers.set('authorization', `Bearer ${token}`);\n return { headers };\n } catch (error) {\n this.config.logger?.error('Failed to get service account access token for API request', { error });\n throw error;\n }\n };\n\n // Override getAccessToken to support googleapis client API and direct token access\n client.getAccessToken = async () => {\n try {\n const token = await this.getAccessToken();\n return { token };\n } catch (error) {\n this.config.logger?.error('Failed to get service account access token', { error });\n throw error;\n }\n };\n\n this.config.logger?.debug(`ServiceAccountProvider: OAuth2Client created for ${accountId}`);\n return client;\n }\n\n /**\n * Get service account email address\n * Used for account registration and display\n *\n * Note: accountId parameter is ignored for service accounts\n * @returns Service account email from key file (e.g., \"service-account@project.iam.gserviceaccount.com\")\n */\n async getUserEmail(_accountId?: string): Promise<string> {\n const keyData = await this.loadKeyFile();\n return keyData.client_email;\n }\n\n /**\n * Create middleware wrapper for single-user authentication\n * This is the CRITICAL method that integrates service account auth into MCP servers\n *\n * Middleware wraps tool, resource, and prompt handlers and injects authContext into extra parameter.\n * Handlers receive OAuth2Client via extra.authContext.auth for API calls.\n *\n * @returns Object with withToolAuth, withResourceAuth, withPromptAuth methods\n *\n * @example\n * ```typescript\n * // Server registration\n * const authMiddleware = provider.authMiddleware();\n * const tools = toolFactories.map(f => f()).map(authMiddleware.withToolAuth);\n * const resources = resourceFactories.map(f => f()).map(authMiddleware.withResourceAuth);\n * const prompts = promptFactories.map(f => f()).map(authMiddleware.withPromptAuth);\n *\n * // Tool handler receives auth\n * async function handler({ id }: In, extra: EnrichedExtra) {\n * // extra.authContext.auth is OAuth2Client (from middleware)\n * const gmail = google.gmail({ version: 'v1', auth: extra.authContext.auth });\n * }\n * ```\n */\n authMiddleware() {\n // Shared wrapper logic - extracts extra parameter from specified position\n // Generic T captures the actual module type; handler is cast from unknown to callable\n const wrapAtPosition = <T extends { name: string; handler: unknown; [key: string]: unknown }>(module: T, extraPosition: number): T => {\n const originalHandler = module.handler as (...args: unknown[]) => Promise<unknown>;\n\n const wrappedHandler = async (...allArgs: unknown[]) => {\n // Extract extra from the correct position\n const extra = allArgs[extraPosition] as EnrichedExtra;\n\n try {\n // Use fixed accountId for storage isolation (like device-code pattern)\n const accountId = 'service-account';\n\n // Get service account email for logging/display\n const serviceEmail = await this.getUserEmail();\n\n // Get access token (generates JWT and exchanges if needed)\n await this.getAccessToken();\n\n // Create OAuth2Client with service account credentials\n const auth = this.toAuth(accountId);\n\n // Inject authContext and logger into extra parameter\n (extra as { authContext?: AuthContext }).authContext = {\n auth, // OAuth2Client for googleapis\n accountId, // 'service-account' (fixed, not service email)\n metadata: { serviceEmail }, // Keep email for logging/reference\n };\n (extra as { logger?: unknown }).logger = this.config.logger;\n\n // Call original handler with all args\n return await originalHandler(...allArgs);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n\n // Provide specific, actionable error messages based on error type\n if (message.includes('key file not found')) {\n throw new Error(`Service account setup error: Key file '${this.keyFilePath}' not found.\\n• Set GOOGLE_SERVICE_ACCOUNT_KEY_FILE environment variable\\n• Or ensure the file path exists and is accessible`);\n }\n if (message.includes('Forbidden') || message.includes('access_denied')) {\n throw new Error(\n 'Service account permission error: The service account does not have required permissions.\\n' + '• Ensure the service account has been granted the necessary roles\\n' + '• Check that required API scopes are enabled in Google Cloud Console\\n' + '• Verify the service account is active (not disabled)'\n );\n }\n if (message.includes('invalid_grant') || message.includes('JWT')) {\n throw new Error('Service account authentication error: Invalid credentials or expired tokens.\\n' + '• Verify your service account key file is valid and not expired\\n' + '• Check that the service account email and project match your GCP setup\\n' + '• Try regenerating the key file in Google Cloud Console');\n }\n if (message.includes('Network error') || message.includes('fetch')) {\n throw new Error('Service account connection error: Unable to reach Google authentication services.\\n' + '• Check your internet connection\\n' + '• Verify firewall/proxy settings allow HTTPS to oauth2.googleapis.com\\n' + '• Try again in a few moments (may be temporary service issue)');\n }\n // Generic fallback with original error\n throw new Error(`Service account authentication failed: ${message}`);\n }\n };\n\n return {\n ...module,\n handler: wrappedHandler,\n } as T;\n };\n\n return {\n // Use structural constraints to avoid contravariance check on handler type.\n // wrapAtPosition is now generic and returns T directly.\n withToolAuth: <T extends { name: string; config: unknown; handler: unknown }>(module: T) => wrapAtPosition(module, 1),\n withResourceAuth: <T extends { name: string; template?: unknown; config?: unknown; handler: unknown }>(module: T) => wrapAtPosition(module, 2),\n withPromptAuth: <T extends { name: string; config: unknown; handler: unknown }>(module: T) => wrapAtPosition(module, 0),\n };\n }\n}\n"],"names":["ServiceAccountProvider","config","keyFilePath","scopes","loadKeyFile","fileContent","keyData","error","fs","readFile","JSON","parse","parseError","Error","message","String","validateKeyFile","code","data","obj","type","requiredFields","missingFields","filter","field","length","join","privateKey","private_key","includes","generateJWT","now","jwt","importPKCS8","Math","floor","Date","SignJWT","iss","client_email","scope","aud","exp","iat","setProtectedHeader","alg","typ","sign","exchangeJWT","tokenEndpoint","response","errorText","errorMessage","errorJson","tokenData","expiry","fetch","method","headers","body","URLSearchParams","grant_type","assertion","ok","text","error_description","status","json","expires_in","token","access_token","TypeError","getAccessToken","_accountId","cachedToken","toAuth","accountId","undefined","client","OAuth2Client","getRequestMetadataAsync","_url","credentials","token_type","Headers","set","logger","debug","getUserEmail","authMiddleware","wrapAtPosition","module","extraPosition","originalHandler","handler","wrappedHandler","allArgs","extra","serviceEmail","auth","authContext","metadata","withToolAuth","withResourceAuth","withPromptAuth"],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { z } from 'zod';
2
+ export declare const AuthRequiredBranchSchema: z.ZodObject<{
3
+ type: z.ZodLiteral<"auth_required">;
4
+ provider: z.ZodString;
5
+ message: z.ZodString;
6
+ url: z.ZodOptional<z.ZodString>;
7
+ }, z.core.$strip>;
8
+ export type AuthRequiredBranch = z.infer<typeof AuthRequiredBranchSchema>;
9
+ export declare const AuthRequiredSchema: z.ZodObject<{
10
+ type: z.ZodLiteral<"auth_required">;
11
+ provider: z.ZodString;
12
+ message: z.ZodString;
13
+ url: z.ZodString;
14
+ flow: z.ZodOptional<z.ZodString>;
15
+ instructions: z.ZodString;
16
+ user_code: z.ZodOptional<z.ZodString>;
17
+ expires_in: z.ZodOptional<z.ZodNumber>;
18
+ accountId: z.ZodOptional<z.ZodString>;
19
+ }, z.core.$strip>;
20
+ export type AuthRequired = z.infer<typeof AuthRequiredSchema>;
@@ -0,0 +1,20 @@
1
+ import { z } from 'zod';
2
+ export declare const AuthRequiredBranchSchema: z.ZodObject<{
3
+ type: z.ZodLiteral<"auth_required">;
4
+ provider: z.ZodString;
5
+ message: z.ZodString;
6
+ url: z.ZodOptional<z.ZodString>;
7
+ }, z.core.$strip>;
8
+ export type AuthRequiredBranch = z.infer<typeof AuthRequiredBranchSchema>;
9
+ export declare const AuthRequiredSchema: z.ZodObject<{
10
+ type: z.ZodLiteral<"auth_required">;
11
+ provider: z.ZodString;
12
+ message: z.ZodString;
13
+ url: z.ZodString;
14
+ flow: z.ZodOptional<z.ZodString>;
15
+ instructions: z.ZodString;
16
+ user_code: z.ZodOptional<z.ZodString>;
17
+ expires_in: z.ZodOptional<z.ZodNumber>;
18
+ accountId: z.ZodOptional<z.ZodString>;
19
+ }, z.core.$strip>;
20
+ export type AuthRequired = z.infer<typeof AuthRequiredSchema>;
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: Object.getOwnPropertyDescriptor(all, name).get
9
+ });
10
+ }
11
+ _export(exports, {
12
+ get AuthRequiredBranchSchema () {
13
+ return AuthRequiredBranchSchema;
14
+ },
15
+ get AuthRequiredSchema () {
16
+ return AuthRequiredSchema;
17
+ }
18
+ });
19
+ var _zod = require("zod");
20
+ var AuthRequiredBranchSchema = _zod.z.object({
21
+ type: _zod.z.literal('auth_required'),
22
+ provider: _zod.z.string(),
23
+ message: _zod.z.string(),
24
+ url: _zod.z.string().optional()
25
+ });
26
+ var AuthRequiredSchema = _zod.z.object({
27
+ type: _zod.z.literal('auth_required'),
28
+ provider: _zod.z.string().describe('OAuth provider name (e.g., "google")'),
29
+ message: _zod.z.string().describe('Human-readable message explaining why auth is needed'),
30
+ url: _zod.z.string().url().describe('Authentication URL to open in browser'),
31
+ flow: _zod.z.string().optional().describe('Authentication flow type (e.g., "auth_url", "device_code")'),
32
+ instructions: _zod.z.string().describe('Clear instructions for the user'),
33
+ user_code: _zod.z.string().optional().describe('Code user must enter at verification URL (device flows only)'),
34
+ expires_in: _zod.z.number().optional().describe('Seconds until code expires (device flows only)'),
35
+ accountId: _zod.z.string().optional().describe('Account identifier (email) that requires authentication')
36
+ }).describe('Authentication required with clear actionable instructions for user');
37
+ /* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/oauth/oauth-google/src/schemas/index.ts"],"sourcesContent":["import { z } from 'zod';\n\nexport const AuthRequiredBranchSchema = z.object({\n type: z.literal('auth_required'),\n provider: z.string(),\n message: z.string(),\n url: z.string().optional(),\n});\nexport type AuthRequiredBranch = z.infer<typeof AuthRequiredBranchSchema>;\n\nexport const AuthRequiredSchema = z\n .object({\n type: z.literal('auth_required'),\n provider: z.string().describe('OAuth provider name (e.g., \"google\")'),\n message: z.string().describe('Human-readable message explaining why auth is needed'),\n url: z.string().url().describe('Authentication URL to open in browser'),\n flow: z.string().optional().describe('Authentication flow type (e.g., \"auth_url\", \"device_code\")'),\n instructions: z.string().describe('Clear instructions for the user'),\n user_code: z.string().optional().describe('Code user must enter at verification URL (device flows only)'),\n expires_in: z.number().optional().describe('Seconds until code expires (device flows only)'),\n accountId: z.string().optional().describe('Account identifier (email) that requires authentication'),\n })\n .describe('Authentication required with clear actionable instructions for user');\n\nexport type AuthRequired = z.infer<typeof AuthRequiredSchema>;\n"],"names":["AuthRequiredBranchSchema","AuthRequiredSchema","z","object","type","literal","provider","string","message","url","optional","describe","flow","instructions","user_code","expires_in","number","accountId"],"mappings":";;;;;;;;;;;QAEaA;eAAAA;;QAQAC;eAAAA;;;mBAVK;AAEX,IAAMD,2BAA2BE,MAAC,CAACC,MAAM,CAAC;IAC/CC,MAAMF,MAAC,CAACG,OAAO,CAAC;IAChBC,UAAUJ,MAAC,CAACK,MAAM;IAClBC,SAASN,MAAC,CAACK,MAAM;IACjBE,KAAKP,MAAC,CAACK,MAAM,GAAGG,QAAQ;AAC1B;AAGO,IAAMT,qBAAqBC,MAAC,CAChCC,MAAM,CAAC;IACNC,MAAMF,MAAC,CAACG,OAAO,CAAC;IAChBC,UAAUJ,MAAC,CAACK,MAAM,GAAGI,QAAQ,CAAC;IAC9BH,SAASN,MAAC,CAACK,MAAM,GAAGI,QAAQ,CAAC;IAC7BF,KAAKP,MAAC,CAACK,MAAM,GAAGE,GAAG,GAAGE,QAAQ,CAAC;IAC/BC,MAAMV,MAAC,CAACK,MAAM,GAAGG,QAAQ,GAAGC,QAAQ,CAAC;IACrCE,cAAcX,MAAC,CAACK,MAAM,GAAGI,QAAQ,CAAC;IAClCG,WAAWZ,MAAC,CAACK,MAAM,GAAGG,QAAQ,GAAGC,QAAQ,CAAC;IAC1CI,YAAYb,MAAC,CAACc,MAAM,GAAGN,QAAQ,GAAGC,QAAQ,CAAC;IAC3CM,WAAWf,MAAC,CAACK,MAAM,GAAGG,QAAQ,GAAGC,QAAQ,CAAC;AAC5C,GACCA,QAAQ,CAAC"}
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Google OAuth configuration parsing from CLI arguments and environment variables.
3
+ *
4
+ * This module provides utilities to parse Google OAuth configuration from
5
+ * CLI arguments and environment variables, following the same pattern as @mcp-z/server's
6
+ * parseConfig().
7
+ */
8
+ import type { DcrConfig, OAuthConfig } from '../types.js';
9
+ export type { DcrConfig, OAuthConfig };
10
+ /**
11
+ * Transport type for MCP servers
12
+ */
13
+ type TransportType = 'stdio' | 'http';
14
+ /**
15
+ * Parse Google OAuth configuration from CLI arguments and environment variables.
16
+ *
17
+ * CLI Arguments:
18
+ * - --auth: Auth mode ('loopback-oauth' | 'service-account' | 'dcr')
19
+ * - Default: 'loopback-oauth' (if flag is omitted)
20
+ * - --headless: Disable browser opening for OAuth flow (default: false, true in test env)
21
+ * - --redirect-uri: Override OAuth redirect URI (default: ephemeral loopback)
22
+ * - --service-account-key-file: Service account key file path (required for service-account mode)
23
+ *
24
+ * Required environment variables:
25
+ * - GOOGLE_CLIENT_ID: OAuth 2.0 client ID from Google Cloud Console
26
+ *
27
+ * Optional environment variables:
28
+ * - GOOGLE_CLIENT_SECRET: OAuth 2.0 client secret (optional for public clients)
29
+ * - AUTH_MODE: Auth mode (same format as --auth flag)
30
+ * - HEADLESS: Headless mode flag ('true' to enable)
31
+ * - REDIRECT_URI: OAuth redirect URI (overridden by --redirect-uri CLI flag)
32
+ * - GOOGLE_SERVICE_ACCOUNT_KEY_FILE: Service account key file (for service-account mode)
33
+ *
34
+ * @param args - CLI arguments array (typically process.argv)
35
+ * @param env - Environment variables object (typically process.env)
36
+ * @param transport - Optional transport type. If 'stdio' and auth mode is 'dcr', throws an error.
37
+ * @returns Parsed Google OAuth configuration
38
+ * @throws Error if required environment variables are missing, values are invalid, or DCR is used with stdio transport
39
+ *
40
+ * @example Default mode (no flags)
41
+ * ```typescript
42
+ * const config = parseConfig(process.argv, process.env);
43
+ * // { auth: 'loopback-oauth' }
44
+ * ```
45
+ *
46
+ * @example Override auth mode
47
+ * ```typescript
48
+ * parseConfig(['--auth=loopback-oauth'], process.env);
49
+ * parseConfig(['--auth=service-account'], process.env);
50
+ * parseConfig(['--auth=dcr'], process.env);
51
+ * ```
52
+ *
53
+ * @example With transport validation
54
+ * ```typescript
55
+ * parseConfig(['--auth=dcr'], process.env, 'http'); // OK
56
+ * parseConfig(['--auth=dcr'], process.env, 'stdio'); // Throws error
57
+ * ```
58
+ *
59
+ * Valid auth modes:
60
+ * - loopback-oauth (default)
61
+ * - service-account
62
+ * - dcr (HTTP transport only)
63
+ */
64
+ export declare function parseConfig(args: string[], env: Record<string, string | undefined>, transport?: TransportType): OAuthConfig;
65
+ /**
66
+ * Build production configuration from process globals.
67
+ * Entry point for production server.
68
+ */
69
+ export declare function createConfig(): OAuthConfig;
70
+ /**
71
+ * Parse DCR configuration from CLI arguments and environment variables.
72
+ *
73
+ * CLI Arguments:
74
+ * - --dcr-mode: DCR mode ('self-hosted' | 'external')
75
+ * - Default: 'self-hosted' (if flag is omitted)
76
+ * - --dcr-verify-url: External verification endpoint URL (required for external mode)
77
+ * - --dcr-store-uri: DCR client storage URI (required for self-hosted mode)
78
+ *
79
+ * Required environment variables:
80
+ * - GOOGLE_CLIENT_ID: OAuth 2.0 client ID from Google Cloud Console
81
+ *
82
+ * Optional environment variables:
83
+ * - GOOGLE_CLIENT_SECRET: OAuth 2.0 client secret (optional for public clients)
84
+ * - DCR_MODE: DCR mode (same format as --dcr-mode flag)
85
+ * - DCR_VERIFY_URL: External verification URL (same as --dcr-verify-url flag)
86
+ * - DCR_STORE_URI: DCR storage URI (same as --dcr-store-uri flag)
87
+ *
88
+ * @param args - CLI arguments array (typically process.argv)
89
+ * @param env - Environment variables object (typically process.env)
90
+ * @param scope - OAuth scopes to request (space-separated)
91
+ * @returns Parsed DCR configuration
92
+ * @throws Error if required environment variables are missing or validation fails
93
+ *
94
+ * @example Self-hosted mode
95
+ * ```typescript
96
+ * const config = parseDcrConfig(
97
+ * ['--dcr-mode=self-hosted', '--dcr-store-uri=file:///path/to/store.json'],
98
+ * process.env,
99
+ * 'https://www.googleapis.com/auth/drive.readonly'
100
+ * );
101
+ * ```
102
+ *
103
+ * @example External mode
104
+ * ```typescript
105
+ * const config = parseDcrConfig(
106
+ * ['--dcr-mode=external', '--dcr-verify-url=https://auth0.example.com/verify'],
107
+ * process.env,
108
+ * 'https://www.googleapis.com/auth/drive.readonly'
109
+ * );
110
+ * ```
111
+ */
112
+ export declare function parseDcrConfig(args: string[], env: Record<string, string | undefined>, scope: string): DcrConfig;
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Google OAuth configuration parsing from CLI arguments and environment variables.
3
+ *
4
+ * This module provides utilities to parse Google OAuth configuration from
5
+ * CLI arguments and environment variables, following the same pattern as @mcp-z/server's
6
+ * parseConfig().
7
+ */
8
+ import type { DcrConfig, OAuthConfig } from '../types.js';
9
+ export type { DcrConfig, OAuthConfig };
10
+ /**
11
+ * Transport type for MCP servers
12
+ */
13
+ type TransportType = 'stdio' | 'http';
14
+ /**
15
+ * Parse Google OAuth configuration from CLI arguments and environment variables.
16
+ *
17
+ * CLI Arguments:
18
+ * - --auth: Auth mode ('loopback-oauth' | 'service-account' | 'dcr')
19
+ * - Default: 'loopback-oauth' (if flag is omitted)
20
+ * - --headless: Disable browser opening for OAuth flow (default: false, true in test env)
21
+ * - --redirect-uri: Override OAuth redirect URI (default: ephemeral loopback)
22
+ * - --service-account-key-file: Service account key file path (required for service-account mode)
23
+ *
24
+ * Required environment variables:
25
+ * - GOOGLE_CLIENT_ID: OAuth 2.0 client ID from Google Cloud Console
26
+ *
27
+ * Optional environment variables:
28
+ * - GOOGLE_CLIENT_SECRET: OAuth 2.0 client secret (optional for public clients)
29
+ * - AUTH_MODE: Auth mode (same format as --auth flag)
30
+ * - HEADLESS: Headless mode flag ('true' to enable)
31
+ * - REDIRECT_URI: OAuth redirect URI (overridden by --redirect-uri CLI flag)
32
+ * - GOOGLE_SERVICE_ACCOUNT_KEY_FILE: Service account key file (for service-account mode)
33
+ *
34
+ * @param args - CLI arguments array (typically process.argv)
35
+ * @param env - Environment variables object (typically process.env)
36
+ * @param transport - Optional transport type. If 'stdio' and auth mode is 'dcr', throws an error.
37
+ * @returns Parsed Google OAuth configuration
38
+ * @throws Error if required environment variables are missing, values are invalid, or DCR is used with stdio transport
39
+ *
40
+ * @example Default mode (no flags)
41
+ * ```typescript
42
+ * const config = parseConfig(process.argv, process.env);
43
+ * // { auth: 'loopback-oauth' }
44
+ * ```
45
+ *
46
+ * @example Override auth mode
47
+ * ```typescript
48
+ * parseConfig(['--auth=loopback-oauth'], process.env);
49
+ * parseConfig(['--auth=service-account'], process.env);
50
+ * parseConfig(['--auth=dcr'], process.env);
51
+ * ```
52
+ *
53
+ * @example With transport validation
54
+ * ```typescript
55
+ * parseConfig(['--auth=dcr'], process.env, 'http'); // OK
56
+ * parseConfig(['--auth=dcr'], process.env, 'stdio'); // Throws error
57
+ * ```
58
+ *
59
+ * Valid auth modes:
60
+ * - loopback-oauth (default)
61
+ * - service-account
62
+ * - dcr (HTTP transport only)
63
+ */
64
+ export declare function parseConfig(args: string[], env: Record<string, string | undefined>, transport?: TransportType): OAuthConfig;
65
+ /**
66
+ * Build production configuration from process globals.
67
+ * Entry point for production server.
68
+ */
69
+ export declare function createConfig(): OAuthConfig;
70
+ /**
71
+ * Parse DCR configuration from CLI arguments and environment variables.
72
+ *
73
+ * CLI Arguments:
74
+ * - --dcr-mode: DCR mode ('self-hosted' | 'external')
75
+ * - Default: 'self-hosted' (if flag is omitted)
76
+ * - --dcr-verify-url: External verification endpoint URL (required for external mode)
77
+ * - --dcr-store-uri: DCR client storage URI (required for self-hosted mode)
78
+ *
79
+ * Required environment variables:
80
+ * - GOOGLE_CLIENT_ID: OAuth 2.0 client ID from Google Cloud Console
81
+ *
82
+ * Optional environment variables:
83
+ * - GOOGLE_CLIENT_SECRET: OAuth 2.0 client secret (optional for public clients)
84
+ * - DCR_MODE: DCR mode (same format as --dcr-mode flag)
85
+ * - DCR_VERIFY_URL: External verification URL (same as --dcr-verify-url flag)
86
+ * - DCR_STORE_URI: DCR storage URI (same as --dcr-store-uri flag)
87
+ *
88
+ * @param args - CLI arguments array (typically process.argv)
89
+ * @param env - Environment variables object (typically process.env)
90
+ * @param scope - OAuth scopes to request (space-separated)
91
+ * @returns Parsed DCR configuration
92
+ * @throws Error if required environment variables are missing or validation fails
93
+ *
94
+ * @example Self-hosted mode
95
+ * ```typescript
96
+ * const config = parseDcrConfig(
97
+ * ['--dcr-mode=self-hosted', '--dcr-store-uri=file:///path/to/store.json'],
98
+ * process.env,
99
+ * 'https://www.googleapis.com/auth/drive.readonly'
100
+ * );
101
+ * ```
102
+ *
103
+ * @example External mode
104
+ * ```typescript
105
+ * const config = parseDcrConfig(
106
+ * ['--dcr-mode=external', '--dcr-verify-url=https://auth0.example.com/verify'],
107
+ * process.env,
108
+ * 'https://www.googleapis.com/auth/drive.readonly'
109
+ * );
110
+ * ```
111
+ */
112
+ export declare function parseDcrConfig(args: string[], env: Record<string, string | undefined>, scope: string): DcrConfig;
@@ -0,0 +1,236 @@
1
+ /**
2
+ * Google OAuth configuration parsing from CLI arguments and environment variables.
3
+ *
4
+ * This module provides utilities to parse Google OAuth configuration from
5
+ * CLI arguments and environment variables, following the same pattern as @mcp-z/server's
6
+ * parseConfig().
7
+ */ "use strict";
8
+ Object.defineProperty(exports, "__esModule", {
9
+ value: true
10
+ });
11
+ function _export(target, all) {
12
+ for(var name in all)Object.defineProperty(target, name, {
13
+ enumerable: true,
14
+ get: Object.getOwnPropertyDescriptor(all, name).get
15
+ });
16
+ }
17
+ _export(exports, {
18
+ get createConfig () {
19
+ return createConfig;
20
+ },
21
+ get parseConfig () {
22
+ return parseConfig;
23
+ },
24
+ get parseDcrConfig () {
25
+ return parseDcrConfig;
26
+ }
27
+ });
28
+ var _path = require("path");
29
+ var _util = require("util");
30
+ function _define_property(obj, key, value) {
31
+ if (key in obj) {
32
+ Object.defineProperty(obj, key, {
33
+ value: value,
34
+ enumerable: true,
35
+ configurable: true,
36
+ writable: true
37
+ });
38
+ } else {
39
+ obj[key] = value;
40
+ }
41
+ return obj;
42
+ }
43
+ function _object_spread(target) {
44
+ for(var i = 1; i < arguments.length; i++){
45
+ var source = arguments[i] != null ? arguments[i] : {};
46
+ var ownKeys = Object.keys(source);
47
+ if (typeof Object.getOwnPropertySymbols === "function") {
48
+ ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
49
+ return Object.getOwnPropertyDescriptor(source, sym).enumerable;
50
+ }));
51
+ }
52
+ ownKeys.forEach(function(key) {
53
+ _define_property(target, key, source[key]);
54
+ });
55
+ }
56
+ return target;
57
+ }
58
+ function ownKeys(object, enumerableOnly) {
59
+ var keys = Object.keys(object);
60
+ if (Object.getOwnPropertySymbols) {
61
+ var symbols = Object.getOwnPropertySymbols(object);
62
+ if (enumerableOnly) {
63
+ symbols = symbols.filter(function(sym) {
64
+ return Object.getOwnPropertyDescriptor(object, sym).enumerable;
65
+ });
66
+ }
67
+ keys.push.apply(keys, symbols);
68
+ }
69
+ return keys;
70
+ }
71
+ function _object_spread_props(target, source) {
72
+ source = source != null ? source : {};
73
+ if (Object.getOwnPropertyDescriptors) {
74
+ Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
75
+ } else {
76
+ ownKeys(Object(source)).forEach(function(key) {
77
+ Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
78
+ });
79
+ }
80
+ return target;
81
+ }
82
+ /**
83
+ * Parse auth mode string into auth mode.
84
+ *
85
+ * @param value - Auth mode string ('loopback-oauth', 'service-account', or 'dcr')
86
+ * @returns Parsed auth mode
87
+ * @throws Error if value is invalid
88
+ *
89
+ * @example Valid formats
90
+ * ```typescript
91
+ * parseAuthMode('loopback-oauth') // { auth: 'loopback-oauth' }
92
+ * parseAuthMode('service-account') // { auth: 'service-account' }
93
+ * parseAuthMode('dcr') // { auth: 'dcr' }
94
+ * ```
95
+ */ function parseAuthMode(value) {
96
+ if (value !== 'loopback-oauth' && value !== 'service-account' && value !== 'dcr') {
97
+ throw new Error('Invalid --auth value: "'.concat(value, '". Valid values: loopback-oauth, service-account, dcr'));
98
+ }
99
+ return {
100
+ auth: value
101
+ };
102
+ }
103
+ function parseConfig(args, env, transport) {
104
+ var _ref;
105
+ function requiredEnv(key) {
106
+ var value = env[key];
107
+ if (!value) {
108
+ throw new Error("Environment variable ".concat(key, " is required for Google OAuth"));
109
+ }
110
+ return value;
111
+ }
112
+ // Parse CLI arguments
113
+ var values = (0, _util.parseArgs)({
114
+ args: args,
115
+ options: {
116
+ auth: {
117
+ type: 'string'
118
+ },
119
+ headless: {
120
+ type: 'boolean'
121
+ },
122
+ 'redirect-uri': {
123
+ type: 'string'
124
+ },
125
+ 'service-account-key-file': {
126
+ type: 'string'
127
+ }
128
+ },
129
+ strict: false,
130
+ allowPositionals: true
131
+ }).values;
132
+ var authArg = typeof values.auth === 'string' ? values.auth : undefined;
133
+ var envAuthMode = env.AUTH_MODE;
134
+ var mode = authArg || envAuthMode;
135
+ var auth;
136
+ if (mode) {
137
+ var parsed = parseAuthMode(mode);
138
+ auth = parsed.auth;
139
+ } else {
140
+ // DEFAULT: No flags provided, use loopback-oauth
141
+ auth = 'loopback-oauth';
142
+ }
143
+ // Validate: DCR only works with HTTP transport
144
+ if (auth === 'dcr' && transport === 'stdio') {
145
+ throw new Error('DCR authentication mode requires HTTP transport. DCR is not supported with stdio transport.');
146
+ }
147
+ var cliHeadless = typeof values.headless === 'boolean' ? values.headless : undefined;
148
+ var envHeadless = env.HEADLESS === 'true' ? true : env.HEADLESS === 'false' ? false : undefined;
149
+ var headless = (_ref = cliHeadless !== null && cliHeadless !== void 0 ? cliHeadless : envHeadless) !== null && _ref !== void 0 ? _ref : false;
150
+ var cliRedirectUri = typeof values['redirect-uri'] === 'string' ? values['redirect-uri'] : undefined;
151
+ var envRedirectUri = env.REDIRECT_URI;
152
+ var redirectUri = cliRedirectUri !== null && cliRedirectUri !== void 0 ? cliRedirectUri : envRedirectUri;
153
+ var clientId = requiredEnv('GOOGLE_CLIENT_ID');
154
+ var clientSecret = env.GOOGLE_CLIENT_SECRET;
155
+ var serviceAccountKeyFile;
156
+ if (auth === 'service-account') {
157
+ var cliKeyFile = typeof values['service-account-key-file'] === 'string' ? values['service-account-key-file'] : undefined;
158
+ serviceAccountKeyFile = cliKeyFile !== null && cliKeyFile !== void 0 ? cliKeyFile : env.GOOGLE_SERVICE_ACCOUNT_KEY_FILE;
159
+ if (!serviceAccountKeyFile) {
160
+ throw new Error('GOOGLE_SERVICE_ACCOUNT_KEY_FILE environment variable is required when using service account authentication. ' + 'Example: export GOOGLE_SERVICE_ACCOUNT_KEY_FILE=./service-account.json');
161
+ }
162
+ // Resolve relative paths now since cwd can change during execution
163
+ serviceAccountKeyFile = (0, _path.resolve)(serviceAccountKeyFile);
164
+ }
165
+ return _object_spread(_object_spread_props(_object_spread({
166
+ clientId: clientId
167
+ }, clientSecret && {
168
+ clientSecret: clientSecret
169
+ }), {
170
+ auth: auth,
171
+ headless: headless
172
+ }), redirectUri && {
173
+ redirectUri: redirectUri
174
+ }, serviceAccountKeyFile && {
175
+ serviceAccountKeyFile: serviceAccountKeyFile
176
+ });
177
+ }
178
+ function createConfig() {
179
+ return parseConfig(process.argv, process.env);
180
+ }
181
+ function parseDcrConfig(args, env, scope) {
182
+ function requiredEnv(key) {
183
+ var value = env[key];
184
+ if (!value) {
185
+ throw new Error("Environment variable ".concat(key, " is required for DCR configuration"));
186
+ }
187
+ return value;
188
+ }
189
+ var values = (0, _util.parseArgs)({
190
+ args: args,
191
+ options: {
192
+ 'dcr-mode': {
193
+ type: 'string'
194
+ },
195
+ 'dcr-verify-url': {
196
+ type: 'string'
197
+ },
198
+ 'dcr-store-uri': {
199
+ type: 'string'
200
+ }
201
+ },
202
+ strict: false,
203
+ allowPositionals: true
204
+ }).values;
205
+ var cliMode = typeof values['dcr-mode'] === 'string' ? values['dcr-mode'] : undefined;
206
+ var envMode = env.DCR_MODE;
207
+ var mode = cliMode || envMode || 'self-hosted';
208
+ if (mode !== 'self-hosted' && mode !== 'external') {
209
+ throw new Error('Invalid --dcr-mode value: "'.concat(mode, '". Valid values: self-hosted, external'));
210
+ }
211
+ var cliVerifyUrl = typeof values['dcr-verify-url'] === 'string' ? values['dcr-verify-url'] : undefined;
212
+ var envVerifyUrl = env.DCR_VERIFY_URL;
213
+ var verifyUrl = cliVerifyUrl || envVerifyUrl;
214
+ var cliStoreUri = typeof values['dcr-store-uri'] === 'string' ? values['dcr-store-uri'] : undefined;
215
+ var envStoreUri = env.DCR_STORE_URI;
216
+ var storeUri = cliStoreUri || envStoreUri;
217
+ if (mode === 'external' && !verifyUrl) {
218
+ throw new Error('DCR external mode requires --dcr-verify-url or DCR_VERIFY_URL environment variable');
219
+ }
220
+ var clientId = requiredEnv('GOOGLE_CLIENT_ID');
221
+ var clientSecret = env.GOOGLE_CLIENT_SECRET;
222
+ return _object_spread_props(_object_spread(_object_spread_props(_object_spread({
223
+ mode: mode
224
+ }, verifyUrl && {
225
+ verifyUrl: verifyUrl
226
+ }, storeUri && {
227
+ storeUri: storeUri
228
+ }), {
229
+ clientId: clientId
230
+ }), clientSecret && {
231
+ clientSecret: clientSecret
232
+ }), {
233
+ scope: scope
234
+ });
235
+ }
236
+ /* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/oauth/oauth-google/src/setup/config.ts"],"sourcesContent":["/**\n * Google OAuth configuration parsing from CLI arguments and environment variables.\n *\n * This module provides utilities to parse Google OAuth configuration from\n * CLI arguments and environment variables, following the same pattern as @mcp-z/server's\n * parseConfig().\n */\n\nimport { resolve } from 'path';\nimport { parseArgs } from 'util';\nimport type { DcrConfig, OAuthConfig } from '../types.ts';\n\n// Re-export for direct imports from config.ts\nexport type { DcrConfig, OAuthConfig };\n\n/**\n * auth mode type (from OAuthConfig)\n */\ntype AuthMode = 'loopback-oauth' | 'service-account' | 'dcr';\n\n/**\n * Parse auth mode string into auth mode.\n *\n * @param value - Auth mode string ('loopback-oauth', 'service-account', or 'dcr')\n * @returns Parsed auth mode\n * @throws Error if value is invalid\n *\n * @example Valid formats\n * ```typescript\n * parseAuthMode('loopback-oauth') // { auth: 'loopback-oauth' }\n * parseAuthMode('service-account') // { auth: 'service-account' }\n * parseAuthMode('dcr') // { auth: 'dcr' }\n * ```\n */\nfunction parseAuthMode(value: string): {\n auth: AuthMode;\n} {\n if (value !== 'loopback-oauth' && value !== 'service-account' && value !== 'dcr') {\n throw new Error(`Invalid --auth value: \"${value}\". Valid values: loopback-oauth, service-account, dcr`);\n }\n\n return {\n auth: value as AuthMode,\n };\n}\n\n/**\n * Transport type for MCP servers\n */\ntype TransportType = 'stdio' | 'http';\n\n/**\n * Parse Google OAuth configuration from CLI arguments and environment variables.\n *\n * CLI Arguments:\n * - --auth: Auth mode ('loopback-oauth' | 'service-account' | 'dcr')\n * - Default: 'loopback-oauth' (if flag is omitted)\n * - --headless: Disable browser opening for OAuth flow (default: false, true in test env)\n * - --redirect-uri: Override OAuth redirect URI (default: ephemeral loopback)\n * - --service-account-key-file: Service account key file path (required for service-account mode)\n *\n * Required environment variables:\n * - GOOGLE_CLIENT_ID: OAuth 2.0 client ID from Google Cloud Console\n *\n * Optional environment variables:\n * - GOOGLE_CLIENT_SECRET: OAuth 2.0 client secret (optional for public clients)\n * - AUTH_MODE: Auth mode (same format as --auth flag)\n * - HEADLESS: Headless mode flag ('true' to enable)\n * - REDIRECT_URI: OAuth redirect URI (overridden by --redirect-uri CLI flag)\n * - GOOGLE_SERVICE_ACCOUNT_KEY_FILE: Service account key file (for service-account mode)\n *\n * @param args - CLI arguments array (typically process.argv)\n * @param env - Environment variables object (typically process.env)\n * @param transport - Optional transport type. If 'stdio' and auth mode is 'dcr', throws an error.\n * @returns Parsed Google OAuth configuration\n * @throws Error if required environment variables are missing, values are invalid, or DCR is used with stdio transport\n *\n * @example Default mode (no flags)\n * ```typescript\n * const config = parseConfig(process.argv, process.env);\n * // { auth: 'loopback-oauth' }\n * ```\n *\n * @example Override auth mode\n * ```typescript\n * parseConfig(['--auth=loopback-oauth'], process.env);\n * parseConfig(['--auth=service-account'], process.env);\n * parseConfig(['--auth=dcr'], process.env);\n * ```\n *\n * @example With transport validation\n * ```typescript\n * parseConfig(['--auth=dcr'], process.env, 'http'); // OK\n * parseConfig(['--auth=dcr'], process.env, 'stdio'); // Throws error\n * ```\n *\n * Valid auth modes:\n * - loopback-oauth (default)\n * - service-account\n * - dcr (HTTP transport only)\n */\nexport function parseConfig(args: string[], env: Record<string, string | undefined>, transport?: TransportType): OAuthConfig {\n function requiredEnv(key: string): string {\n const value = env[key];\n if (!value) {\n throw new Error(`Environment variable ${key} is required for Google OAuth`);\n }\n return value;\n }\n\n // Parse CLI arguments\n const { values } = parseArgs({\n args,\n options: {\n auth: { type: 'string' },\n headless: { type: 'boolean' },\n 'redirect-uri': { type: 'string' },\n 'service-account-key-file': { type: 'string' },\n },\n strict: false, // Allow other arguments\n allowPositionals: true,\n });\n\n const authArg = typeof values.auth === 'string' ? values.auth : undefined;\n const envAuthMode = env.AUTH_MODE;\n const mode = authArg || envAuthMode;\n\n let auth: AuthMode;\n\n if (mode) {\n const parsed = parseAuthMode(mode);\n auth = parsed.auth;\n } else {\n // DEFAULT: No flags provided, use loopback-oauth\n auth = 'loopback-oauth';\n }\n\n // Validate: DCR only works with HTTP transport\n if (auth === 'dcr' && transport === 'stdio') {\n throw new Error('DCR authentication mode requires HTTP transport. DCR is not supported with stdio transport.');\n }\n\n const cliHeadless = typeof values.headless === 'boolean' ? values.headless : undefined;\n const envHeadless = env.HEADLESS === 'true' ? true : env.HEADLESS === 'false' ? false : undefined;\n const headless = cliHeadless ?? envHeadless ?? false;\n\n const cliRedirectUri = typeof values['redirect-uri'] === 'string' ? values['redirect-uri'] : undefined;\n const envRedirectUri = env.REDIRECT_URI;\n const redirectUri = cliRedirectUri ?? envRedirectUri;\n\n const clientId = requiredEnv('GOOGLE_CLIENT_ID');\n const clientSecret = env.GOOGLE_CLIENT_SECRET;\n\n let serviceAccountKeyFile: string | undefined;\n if (auth === 'service-account') {\n const cliKeyFile = typeof values['service-account-key-file'] === 'string' ? values['service-account-key-file'] : undefined;\n serviceAccountKeyFile = cliKeyFile ?? env.GOOGLE_SERVICE_ACCOUNT_KEY_FILE;\n\n if (!serviceAccountKeyFile) {\n throw new Error('GOOGLE_SERVICE_ACCOUNT_KEY_FILE environment variable is required when using service account authentication. ' + 'Example: export GOOGLE_SERVICE_ACCOUNT_KEY_FILE=./service-account.json');\n }\n\n // Resolve relative paths now since cwd can change during execution\n serviceAccountKeyFile = resolve(serviceAccountKeyFile);\n }\n\n return {\n clientId,\n ...(clientSecret && { clientSecret }),\n auth,\n headless,\n ...(redirectUri && { redirectUri }),\n ...(serviceAccountKeyFile && { serviceAccountKeyFile }),\n };\n}\n\n/**\n * Build production configuration from process globals.\n * Entry point for production server.\n */\nexport function createConfig(): OAuthConfig {\n return parseConfig(process.argv, process.env);\n}\n\n/**\n * Parse DCR configuration from CLI arguments and environment variables.\n *\n * CLI Arguments:\n * - --dcr-mode: DCR mode ('self-hosted' | 'external')\n * - Default: 'self-hosted' (if flag is omitted)\n * - --dcr-verify-url: External verification endpoint URL (required for external mode)\n * - --dcr-store-uri: DCR client storage URI (required for self-hosted mode)\n *\n * Required environment variables:\n * - GOOGLE_CLIENT_ID: OAuth 2.0 client ID from Google Cloud Console\n *\n * Optional environment variables:\n * - GOOGLE_CLIENT_SECRET: OAuth 2.0 client secret (optional for public clients)\n * - DCR_MODE: DCR mode (same format as --dcr-mode flag)\n * - DCR_VERIFY_URL: External verification URL (same as --dcr-verify-url flag)\n * - DCR_STORE_URI: DCR storage URI (same as --dcr-store-uri flag)\n *\n * @param args - CLI arguments array (typically process.argv)\n * @param env - Environment variables object (typically process.env)\n * @param scope - OAuth scopes to request (space-separated)\n * @returns Parsed DCR configuration\n * @throws Error if required environment variables are missing or validation fails\n *\n * @example Self-hosted mode\n * ```typescript\n * const config = parseDcrConfig(\n * ['--dcr-mode=self-hosted', '--dcr-store-uri=file:///path/to/store.json'],\n * process.env,\n * 'https://www.googleapis.com/auth/drive.readonly'\n * );\n * ```\n *\n * @example External mode\n * ```typescript\n * const config = parseDcrConfig(\n * ['--dcr-mode=external', '--dcr-verify-url=https://auth0.example.com/verify'],\n * process.env,\n * 'https://www.googleapis.com/auth/drive.readonly'\n * );\n * ```\n */\nexport function parseDcrConfig(args: string[], env: Record<string, string | undefined>, scope: string): DcrConfig {\n function requiredEnv(key: string): string {\n const value = env[key];\n if (!value) {\n throw new Error(`Environment variable ${key} is required for DCR configuration`);\n }\n return value;\n }\n\n const { values } = parseArgs({\n args,\n options: {\n 'dcr-mode': { type: 'string' },\n 'dcr-verify-url': { type: 'string' },\n 'dcr-store-uri': { type: 'string' },\n },\n strict: false,\n allowPositionals: true,\n });\n\n const cliMode = typeof values['dcr-mode'] === 'string' ? values['dcr-mode'] : undefined;\n const envMode = env.DCR_MODE;\n const mode = cliMode || envMode || 'self-hosted';\n\n if (mode !== 'self-hosted' && mode !== 'external') {\n throw new Error(`Invalid --dcr-mode value: \"${mode}\". Valid values: self-hosted, external`);\n }\n\n const cliVerifyUrl = typeof values['dcr-verify-url'] === 'string' ? values['dcr-verify-url'] : undefined;\n const envVerifyUrl = env.DCR_VERIFY_URL;\n const verifyUrl = cliVerifyUrl || envVerifyUrl;\n\n const cliStoreUri = typeof values['dcr-store-uri'] === 'string' ? values['dcr-store-uri'] : undefined;\n const envStoreUri = env.DCR_STORE_URI;\n const storeUri = cliStoreUri || envStoreUri;\n\n if (mode === 'external' && !verifyUrl) {\n throw new Error('DCR external mode requires --dcr-verify-url or DCR_VERIFY_URL environment variable');\n }\n\n const clientId = requiredEnv('GOOGLE_CLIENT_ID');\n const clientSecret = env.GOOGLE_CLIENT_SECRET;\n\n return {\n mode,\n ...(verifyUrl && { verifyUrl }),\n ...(storeUri && { storeUri }),\n clientId,\n ...(clientSecret && { clientSecret }),\n scope,\n };\n}\n"],"names":["createConfig","parseConfig","parseDcrConfig","parseAuthMode","value","Error","auth","args","env","transport","cliHeadless","requiredEnv","key","values","parseArgs","options","type","headless","strict","allowPositionals","authArg","undefined","envAuthMode","AUTH_MODE","mode","parsed","envHeadless","HEADLESS","cliRedirectUri","envRedirectUri","REDIRECT_URI","redirectUri","clientId","clientSecret","GOOGLE_CLIENT_SECRET","serviceAccountKeyFile","cliKeyFile","GOOGLE_SERVICE_ACCOUNT_KEY_FILE","resolve","process","argv","scope","cliMode","envMode","DCR_MODE","cliVerifyUrl","envVerifyUrl","DCR_VERIFY_URL","verifyUrl","cliStoreUri","envStoreUri","DCR_STORE_URI","storeUri"],"mappings":"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"}