@disruptorganic/mcp-google-search-console 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.
- package/.env.example +141 -0
- package/LICENSE +21 -0
- package/README.md +0 -0
- package/dist/auth/index.d.ts +3 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +2 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/oauth2.d.ts +31 -0
- package/dist/auth/oauth2.d.ts.map +1 -0
- package/dist/auth/oauth2.js +380 -0
- package/dist/auth/oauth2.js.map +1 -0
- package/dist/config/index.d.ts +36 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +87 -0
- package/dist/config/index.js.map +1 -0
- package/dist/gsc/client.d.ts +72 -0
- package/dist/gsc/client.d.ts.map +1 -0
- package/dist/gsc/client.js +243 -0
- package/dist/gsc/client.js.map +1 -0
- package/dist/gsc/index.d.ts +3 -0
- package/dist/gsc/index.d.ts.map +1 -0
- package/dist/gsc/index.js +3 -0
- package/dist/gsc/index.js.map +1 -0
- package/dist/gsc/properties.d.ts +42 -0
- package/dist/gsc/properties.d.ts.map +1 -0
- package/dist/gsc/properties.js +393 -0
- package/dist/gsc/properties.js.map +1 -0
- package/dist/gsc/queries.d.ts +73 -0
- package/dist/gsc/queries.d.ts.map +1 -0
- package/dist/gsc/queries.js +390 -0
- package/dist/gsc/queries.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +186 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/compare-date-ranges.d.ts +83 -0
- package/dist/tools/compare-date-ranges.d.ts.map +1 -0
- package/dist/tools/compare-date-ranges.js +462 -0
- package/dist/tools/compare-date-ranges.js.map +1 -0
- package/dist/tools/get-property-info.d.ts +30 -0
- package/dist/tools/get-property-info.d.ts.map +1 -0
- package/dist/tools/get-property-info.js +174 -0
- package/dist/tools/get-property-info.js.map +1 -0
- package/dist/tools/get-top-pages.d.ts +103 -0
- package/dist/tools/get-top-pages.d.ts.map +1 -0
- package/dist/tools/get-top-pages.js +254 -0
- package/dist/tools/get-top-pages.js.map +1 -0
- package/dist/tools/get-top-queries.d.ts +103 -0
- package/dist/tools/get-top-queries.d.ts.map +1 -0
- package/dist/tools/get-top-queries.js +254 -0
- package/dist/tools/get-top-queries.js.map +1 -0
- package/dist/tools/health-check.d.ts +12 -0
- package/dist/tools/health-check.d.ts.map +1 -0
- package/dist/tools/health-check.js +107 -0
- package/dist/tools/health-check.js.map +1 -0
- package/dist/tools/index.d.ts +1124 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +70 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/list-properties.d.ts +50 -0
- package/dist/tools/list-properties.d.ts.map +1 -0
- package/dist/tools/list-properties.js +234 -0
- package/dist/tools/list-properties.js.map +1 -0
- package/dist/tools/query-advanced.d.ts +109 -0
- package/dist/tools/query-advanced.d.ts.map +1 -0
- package/dist/tools/query-advanced.js +378 -0
- package/dist/tools/query-advanced.js.map +1 -0
- package/dist/tools/query-by-keyword.d.ts +115 -0
- package/dist/tools/query-by-keyword.d.ts.map +1 -0
- package/dist/tools/query-by-keyword.js +339 -0
- package/dist/tools/query-by-keyword.js.map +1 -0
- package/dist/tools/query-by-url.d.ts +116 -0
- package/dist/tools/query-by-url.d.ts.map +1 -0
- package/dist/tools/query-by-url.js +366 -0
- package/dist/tools/query-by-url.js.map +1 -0
- package/dist/utils/cache.d.ts +22 -0
- package/dist/utils/cache.d.ts.map +1 -0
- package/dist/utils/cache.js +75 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/index.d.ts +8 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +8 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +4 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +15 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/metrics.d.ts +9 -0
- package/dist/utils/metrics.d.ts.map +1 -0
- package/dist/utils/metrics.js +54 -0
- package/dist/utils/metrics.js.map +1 -0
- package/dist/utils/rate-limiter.d.ts +24 -0
- package/dist/utils/rate-limiter.d.ts.map +1 -0
- package/dist/utils/rate-limiter.js +175 -0
- package/dist/utils/rate-limiter.js.map +1 -0
- package/dist/utils/token-estimator.d.ts +33 -0
- package/dist/utils/token-estimator.d.ts.map +1 -0
- package/dist/utils/token-estimator.js +226 -0
- package/dist/utils/token-estimator.js.map +1 -0
- package/dist/utils/types.d.ts +68 -0
- package/dist/utils/types.d.ts.map +1 -0
- package/dist/utils/types.js +13 -0
- package/dist/utils/types.js.map +1 -0
- package/dist/utils/validators.d.ts +579 -0
- package/dist/utils/validators.d.ts.map +1 -0
- package/dist/utils/validators.js +358 -0
- package/dist/utils/validators.js.map +1 -0
- package/package.json +73 -0
package/.env.example
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# ============================================
|
|
2
|
+
# Google Search Console MCP Server Configuration
|
|
3
|
+
# ============================================
|
|
4
|
+
#
|
|
5
|
+
# This file is a template for setting up your environment variables.
|
|
6
|
+
# Copy this file to .env and fill in your actual values.
|
|
7
|
+
#
|
|
8
|
+
# IMPORTANT: Never commit your .env file to version control!
|
|
9
|
+
# The .gitignore file is already configured to exclude it.
|
|
10
|
+
|
|
11
|
+
# =============================================================================
|
|
12
|
+
# REQUIRED: Google OAuth2 Credentials
|
|
13
|
+
# =============================================================================
|
|
14
|
+
#
|
|
15
|
+
# These credentials are required for authenticating with the Google Search Console API.
|
|
16
|
+
#
|
|
17
|
+
# How to obtain OAuth2 credentials:
|
|
18
|
+
#
|
|
19
|
+
# 1. Go to Google Cloud Console: https://console.cloud.google.com/
|
|
20
|
+
# 2. Create a new project or select an existing one
|
|
21
|
+
# 3. Enable the Google Search Console API:
|
|
22
|
+
# - Navigate to "APIs & Services" > "Library"
|
|
23
|
+
# - Search for "Google Search Console API"
|
|
24
|
+
# - Click "Enable"
|
|
25
|
+
# 4. Create OAuth 2.0 credentials:
|
|
26
|
+
# - Navigate to "APIs & Services" > "Credentials"
|
|
27
|
+
# - Click "Create Credentials" > "OAuth client ID"
|
|
28
|
+
# - Choose "Desktop app" as the application type
|
|
29
|
+
# - Give it a name (e.g., "MCP GSC Server")
|
|
30
|
+
# - Click "Create"
|
|
31
|
+
# 5. Copy the Client ID and Client Secret from the dialog
|
|
32
|
+
#
|
|
33
|
+
# Format: The Client ID typically ends with .apps.googleusercontent.com
|
|
34
|
+
|
|
35
|
+
GSC_CLIENT_ID=123456789012-abcdefghijklmnopqrstuvwxyz123456.apps.googleusercontent.com
|
|
36
|
+
GSC_CLIENT_SECRET=GOCSPX-abcdefghijklmnopqrstuvwxyz
|
|
37
|
+
|
|
38
|
+
# =============================================================================
|
|
39
|
+
# OPTIONAL: Token Storage Configuration
|
|
40
|
+
# =============================================================================
|
|
41
|
+
#
|
|
42
|
+
# Path where OAuth2 access and refresh tokens are stored.
|
|
43
|
+
# The directory will be created automatically with secure permissions (0700).
|
|
44
|
+
#
|
|
45
|
+
# Default: ~/.mcp-gsc/tokens.json
|
|
46
|
+
#
|
|
47
|
+
# You can customize this to store tokens in a different location:
|
|
48
|
+
# GSC_TOKEN_PATH=/path/to/your/tokens.json
|
|
49
|
+
#
|
|
50
|
+
# Leave commented to use the default location.
|
|
51
|
+
|
|
52
|
+
# GSC_TOKEN_PATH=~/.mcp-gsc/tokens.json
|
|
53
|
+
|
|
54
|
+
# =============================================================================
|
|
55
|
+
# OPTIONAL: OAuth Redirect URI
|
|
56
|
+
# =============================================================================
|
|
57
|
+
#
|
|
58
|
+
# The OAuth2 redirect URI for the authentication flow.
|
|
59
|
+
#
|
|
60
|
+
# Default: urn:ietf:wg:oauth:2.0:oob
|
|
61
|
+
#
|
|
62
|
+
# The default value uses the "out-of-band" flow, which is appropriate for
|
|
63
|
+
# command-line applications. With this flow, Google displays the authorization
|
|
64
|
+
# code in the browser, and you manually paste it into the terminal.
|
|
65
|
+
#
|
|
66
|
+
# Alternative options:
|
|
67
|
+
# - http://localhost:3000/callback (for local web server flow)
|
|
68
|
+
# - Any custom redirect URI you've configured in Google Cloud Console
|
|
69
|
+
#
|
|
70
|
+
# Note: If you change this, you must also add the same URI to your OAuth2
|
|
71
|
+
# client's "Authorized redirect URIs" in Google Cloud Console.
|
|
72
|
+
#
|
|
73
|
+
# Leave commented to use the default out-of-band flow.
|
|
74
|
+
|
|
75
|
+
# GSC_REDIRECT_URI=urn:ietf:wg:oauth:2.0:oob
|
|
76
|
+
|
|
77
|
+
# =============================================================================
|
|
78
|
+
# OPTIONAL: Logging Configuration
|
|
79
|
+
# =============================================================================
|
|
80
|
+
#
|
|
81
|
+
# Set the logging verbosity level for the MCP server.
|
|
82
|
+
#
|
|
83
|
+
# Default: info
|
|
84
|
+
#
|
|
85
|
+
# Available levels:
|
|
86
|
+
# - error: Only critical errors that prevent operation
|
|
87
|
+
# - warn: Warnings and errors (potential issues)
|
|
88
|
+
# - info: General information, warnings, and errors (recommended)
|
|
89
|
+
# - debug: Verbose debugging information (for troubleshooting)
|
|
90
|
+
#
|
|
91
|
+
# Leave commented to use the default 'info' level.
|
|
92
|
+
|
|
93
|
+
# LOG_LEVEL=info
|
|
94
|
+
|
|
95
|
+
# =============================================================================
|
|
96
|
+
# OPTIONAL: Node.js Environment
|
|
97
|
+
# =============================================================================
|
|
98
|
+
#
|
|
99
|
+
# Standard Node.js environment variable.
|
|
100
|
+
# Not required by the MCP server, but may be useful for development.
|
|
101
|
+
#
|
|
102
|
+
# NODE_ENV=development
|
|
103
|
+
|
|
104
|
+
# =============================================================================
|
|
105
|
+
# Setup Instructions
|
|
106
|
+
# =============================================================================
|
|
107
|
+
#
|
|
108
|
+
# Quick Start:
|
|
109
|
+
# 1. Copy this file: cp .env.example .env
|
|
110
|
+
# 2. Edit .env and add your GSC_CLIENT_ID and GSC_CLIENT_SECRET
|
|
111
|
+
# 3. Run the test script: npm run test:auth
|
|
112
|
+
# 4. Follow the authentication flow in your browser
|
|
113
|
+
# 5. The tokens will be saved automatically
|
|
114
|
+
#
|
|
115
|
+
# First-Time Authentication Flow:
|
|
116
|
+
# When you first run the server, it will:
|
|
117
|
+
# 1. Check for existing tokens at the configured token path
|
|
118
|
+
# 2. If no tokens exist, initiate the OAuth2 device flow
|
|
119
|
+
# 3. Display a URL and code in the terminal
|
|
120
|
+
# 4. You visit the URL in your browser and enter the code
|
|
121
|
+
# 5. After authorization, tokens are saved and the server starts
|
|
122
|
+
# 6. Subsequent runs use the saved tokens (with automatic refresh)
|
|
123
|
+
#
|
|
124
|
+
# Security Best Practices:
|
|
125
|
+
# - Never commit your .env file to version control
|
|
126
|
+
# - Keep your Client Secret confidential
|
|
127
|
+
# - Store tokens in a secure location with restricted permissions
|
|
128
|
+
# - Rotate credentials if they are ever exposed
|
|
129
|
+
# - Use separate OAuth2 clients for development and production
|
|
130
|
+
#
|
|
131
|
+
# Troubleshooting:
|
|
132
|
+
# - "Configuration Error": Ensure GSC_CLIENT_ID and GSC_CLIENT_SECRET are set
|
|
133
|
+
# - "Invalid credentials": Verify your OAuth2 credentials in Google Cloud Console
|
|
134
|
+
# - "API not enabled": Enable the Google Search Console API in your project
|
|
135
|
+
# - "Token expired": The server will automatically refresh tokens if possible
|
|
136
|
+
# - "Permission denied": Check file permissions on the token storage directory
|
|
137
|
+
#
|
|
138
|
+
# For more information, see:
|
|
139
|
+
# - README.md
|
|
140
|
+
# - docs/authentication-setup.md
|
|
141
|
+
# - https://developers.google.com/webmaster-tools/v1/how-tos/authorizing
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Zac Almeida
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAmCA,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACjD,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAmCA,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { OAuth2Client } from 'google-auth-library';
|
|
2
|
+
export interface TokenData {
|
|
3
|
+
access_token: string;
|
|
4
|
+
refresh_token: string;
|
|
5
|
+
expiry_date: number;
|
|
6
|
+
scope: string;
|
|
7
|
+
token_type: string;
|
|
8
|
+
}
|
|
9
|
+
export interface TokenInfo {
|
|
10
|
+
expiresIn: number;
|
|
11
|
+
scopes: string[];
|
|
12
|
+
hasRefreshToken: boolean;
|
|
13
|
+
}
|
|
14
|
+
export declare class AuthError extends Error {
|
|
15
|
+
code: string;
|
|
16
|
+
userMessage: string;
|
|
17
|
+
recoverable: boolean;
|
|
18
|
+
constructor(message: string, code: string, userMessage: string, recoverable: boolean);
|
|
19
|
+
}
|
|
20
|
+
export declare class GSCAuth {
|
|
21
|
+
private oauth2Client;
|
|
22
|
+
constructor();
|
|
23
|
+
login(useDeviceFlow?: boolean): Promise<void>;
|
|
24
|
+
loginWithCode(code: string): Promise<void>;
|
|
25
|
+
getAuthorizationUrl(): string;
|
|
26
|
+
logout(): Promise<void>;
|
|
27
|
+
getAuthenticatedClient(): Promise<OAuth2Client>;
|
|
28
|
+
isAuthenticated(): Promise<boolean>;
|
|
29
|
+
getTokenInfo(): Promise<TokenInfo>;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=oauth2.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth2.d.ts","sourceRoot":"","sources":["../../src/auth/oauth2.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAUnD,MAAM,WAAW,SAAS;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB;AAKD,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAkBD,qBAAa,SAAU,SAAQ,KAAK;IAGzB,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,MAAM;IACnB,WAAW,EAAE,OAAO;gBAH3B,OAAO,EAAE,MAAM,EACR,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,OAAO;CAK9B;AAwaD,qBAAa,OAAO;IAClB,OAAO,CAAC,YAAY,CAAe;;IAc7B,KAAK,CAAC,aAAa,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAgDpD,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmChD,mBAAmB,IAAI,MAAM;IAavB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IASvB,sBAAsB,IAAI,OAAO,CAAC,YAAY,CAAC;IAmD/C,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAYnC,YAAY,IAAI,OAAO,CAAC,SAAS,CAAC;CAoBzC"}
|
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
import { OAuth2Client } from 'google-auth-library';
|
|
2
|
+
import * as fs from 'fs/promises';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import * as crypto from 'crypto';
|
|
5
|
+
import { logger } from '../utils/logger.js';
|
|
6
|
+
import { config } from '../config/index.js';
|
|
7
|
+
const SCOPES = ['https://www.googleapis.com/auth/webmasters.readonly'];
|
|
8
|
+
const TOKEN_REFRESH_MARGIN_MS = 5 * 60 * 1000;
|
|
9
|
+
const TOKEN_FILE = config.tokenPath;
|
|
10
|
+
const TOKEN_DIR = path.dirname(TOKEN_FILE);
|
|
11
|
+
export class AuthError extends Error {
|
|
12
|
+
constructor(message, code, userMessage, recoverable) {
|
|
13
|
+
super(message);
|
|
14
|
+
this.code = code;
|
|
15
|
+
this.userMessage = userMessage;
|
|
16
|
+
this.recoverable = recoverable;
|
|
17
|
+
this.name = 'AuthError';
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function redactToken(token) {
|
|
21
|
+
if (!token || token.length <= 8) {
|
|
22
|
+
return '***';
|
|
23
|
+
}
|
|
24
|
+
return `${token.substring(0, 8)}...`;
|
|
25
|
+
}
|
|
26
|
+
async function withRetry(fn, maxRetries = 3, baseDelay = 1000) {
|
|
27
|
+
let lastError;
|
|
28
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
29
|
+
try {
|
|
30
|
+
return await fn();
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
lastError = error;
|
|
34
|
+
if (error instanceof AuthError && !error.recoverable) {
|
|
35
|
+
throw error;
|
|
36
|
+
}
|
|
37
|
+
if (attempt === maxRetries) {
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
const delay = baseDelay * Math.pow(2, attempt);
|
|
41
|
+
logger.error('Retry attempt failed, will retry', {
|
|
42
|
+
attempt: attempt + 1,
|
|
43
|
+
maxRetries: maxRetries + 1,
|
|
44
|
+
delayMs: delay,
|
|
45
|
+
error: lastError
|
|
46
|
+
});
|
|
47
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
throw lastError;
|
|
51
|
+
}
|
|
52
|
+
async function ensureTokenDir() {
|
|
53
|
+
try {
|
|
54
|
+
await fs.mkdir(TOKEN_DIR, { recursive: true, mode: 0o700 });
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
throw new AuthError(`Failed to create token directory: ${error}`, 'TOKEN_DIR_ERROR', 'Could not create directory for storing authentication tokens. Please check file system permissions.', false);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
async function saveTokens(tokens) {
|
|
61
|
+
await ensureTokenDir();
|
|
62
|
+
try {
|
|
63
|
+
const tokenJson = JSON.stringify(tokens, null, 2);
|
|
64
|
+
await fs.writeFile(TOKEN_FILE, tokenJson, { mode: 0o600 });
|
|
65
|
+
logger.info('Tokens saved successfully', { tokenPath: TOKEN_FILE });
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
throw new AuthError(`Failed to save tokens: ${error}`, 'TOKEN_SAVE_ERROR', 'Could not save authentication tokens. Please check file system permissions.', false);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async function loadTokens() {
|
|
72
|
+
try {
|
|
73
|
+
const tokenJson = await fs.readFile(TOKEN_FILE, 'utf-8');
|
|
74
|
+
const tokens = JSON.parse(tokenJson);
|
|
75
|
+
if (!tokens.access_token || !tokens.refresh_token) {
|
|
76
|
+
logger.warn('Invalid token structure, tokens will be ignored', { tokenPath: TOKEN_FILE });
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
logger.info('Tokens loaded successfully', {
|
|
80
|
+
tokenPath: TOKEN_FILE,
|
|
81
|
+
accessToken: redactToken(tokens.access_token),
|
|
82
|
+
expiresAt: new Date(tokens.expiry_date).toISOString()
|
|
83
|
+
});
|
|
84
|
+
return tokens;
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
if (error.code === 'ENOENT') {
|
|
88
|
+
logger.info('No saved tokens found', { tokenPath: TOKEN_FILE });
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
throw new AuthError(`Failed to load tokens: ${error}`, 'TOKEN_LOAD_ERROR', 'Could not load authentication tokens. You may need to re-authenticate.', true);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
async function deleteTokens() {
|
|
95
|
+
try {
|
|
96
|
+
await fs.unlink(TOKEN_FILE);
|
|
97
|
+
logger.info('Tokens deleted successfully', { tokenPath: TOKEN_FILE });
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
if (error.code !== 'ENOENT') {
|
|
101
|
+
throw new AuthError(`Failed to delete tokens: ${error}`, 'TOKEN_DELETE_ERROR', 'Could not delete authentication tokens.', true);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
async function authenticateWithDeviceFlow(_oauth2Client) {
|
|
106
|
+
logger.info('Starting Device Flow Authentication');
|
|
107
|
+
const deviceCodeUrl = 'https://oauth2.googleapis.com/device/code';
|
|
108
|
+
const deviceCodeParams = new URLSearchParams({
|
|
109
|
+
client_id: config.clientId,
|
|
110
|
+
scope: SCOPES.join(' '),
|
|
111
|
+
});
|
|
112
|
+
let deviceCodeResponse;
|
|
113
|
+
try {
|
|
114
|
+
const response = await fetch(deviceCodeUrl, {
|
|
115
|
+
method: 'POST',
|
|
116
|
+
headers: {
|
|
117
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
118
|
+
},
|
|
119
|
+
body: deviceCodeParams.toString(),
|
|
120
|
+
});
|
|
121
|
+
if (!response.ok) {
|
|
122
|
+
throw new Error(`Device code request failed: ${response.statusText}`);
|
|
123
|
+
}
|
|
124
|
+
deviceCodeResponse = await response.json();
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
throw new AuthError(`Failed to request device code: ${error}`, 'DEVICE_CODE_REQUEST_FAILED', 'Could not initiate device flow authentication. Please check your network connection.', true);
|
|
128
|
+
}
|
|
129
|
+
const { device_code, user_code, verification_url, expires_in, interval = 5, } = deviceCodeResponse;
|
|
130
|
+
logger.info('Please complete authentication on another device', {
|
|
131
|
+
verificationUrl: verification_url,
|
|
132
|
+
userCode: user_code,
|
|
133
|
+
expiresInMinutes: Math.floor(expires_in / 60)
|
|
134
|
+
});
|
|
135
|
+
logger.info(`Step 1: Visit ${verification_url}`);
|
|
136
|
+
logger.info(`Step 2: Enter code ${user_code}`);
|
|
137
|
+
logger.info('Waiting for authorization...');
|
|
138
|
+
const tokenUrl = 'https://oauth2.googleapis.com/token';
|
|
139
|
+
const startTime = Date.now();
|
|
140
|
+
const expiryTime = startTime + (expires_in * 1000);
|
|
141
|
+
while (Date.now() < expiryTime) {
|
|
142
|
+
await new Promise(resolve => setTimeout(resolve, interval * 1000));
|
|
143
|
+
const tokenParams = new URLSearchParams({
|
|
144
|
+
client_id: config.clientId,
|
|
145
|
+
client_secret: config.clientSecret,
|
|
146
|
+
device_code: device_code,
|
|
147
|
+
grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
|
|
148
|
+
});
|
|
149
|
+
try {
|
|
150
|
+
const response = await fetch(tokenUrl, {
|
|
151
|
+
method: 'POST',
|
|
152
|
+
headers: {
|
|
153
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
154
|
+
},
|
|
155
|
+
body: tokenParams.toString(),
|
|
156
|
+
});
|
|
157
|
+
const result = await response.json();
|
|
158
|
+
if (response.ok) {
|
|
159
|
+
const tokens = {
|
|
160
|
+
access_token: result.access_token,
|
|
161
|
+
refresh_token: result.refresh_token,
|
|
162
|
+
expiry_date: Date.now() + (result.expires_in * 1000),
|
|
163
|
+
scope: result.scope,
|
|
164
|
+
token_type: result.token_type,
|
|
165
|
+
};
|
|
166
|
+
logger.info('Device Flow authorization successful');
|
|
167
|
+
return tokens;
|
|
168
|
+
}
|
|
169
|
+
if (result.error === 'authorization_pending') {
|
|
170
|
+
logger.info('Still waiting for authorization...');
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
else if (result.error === 'slow_down') {
|
|
174
|
+
logger.info('Slowing down polling rate');
|
|
175
|
+
await new Promise(resolve => setTimeout(resolve, interval * 1000));
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
else if (result.error === 'access_denied') {
|
|
179
|
+
throw new AuthError('User denied authorization', 'ACCESS_DENIED', 'Authorization was denied. Please try again if this was a mistake.', false);
|
|
180
|
+
}
|
|
181
|
+
else if (result.error === 'expired_token') {
|
|
182
|
+
throw new AuthError('Device code expired', 'EXPIRED_TOKEN', 'The device code has expired. Please restart the authentication process.', false);
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
throw new AuthError(`Unexpected error: ${result.error || 'unknown'}`, (result.error || 'unknown').toUpperCase(), `Authentication failed: ${result.error_description || result.error || 'unknown error'}`, false);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
if (error instanceof AuthError) {
|
|
190
|
+
throw error;
|
|
191
|
+
}
|
|
192
|
+
logger.error('Network error during polling, will retry', { error });
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
throw new AuthError('Device flow timeout', 'TIMEOUT', 'Authentication timed out. Please restart the authentication process.', false);
|
|
196
|
+
}
|
|
197
|
+
async function exchangeCodeForTokens(oauth2Client, code) {
|
|
198
|
+
try {
|
|
199
|
+
const { tokens } = await oauth2Client.getToken(code);
|
|
200
|
+
if (!tokens.access_token || !tokens.refresh_token) {
|
|
201
|
+
throw new Error('Invalid token response: missing access_token or refresh_token');
|
|
202
|
+
}
|
|
203
|
+
const tokenData = {
|
|
204
|
+
access_token: tokens.access_token,
|
|
205
|
+
refresh_token: tokens.refresh_token,
|
|
206
|
+
expiry_date: tokens.expiry_date || Date.now() + 3600000,
|
|
207
|
+
scope: tokens.scope || SCOPES.join(' '),
|
|
208
|
+
token_type: tokens.token_type || 'Bearer',
|
|
209
|
+
};
|
|
210
|
+
return tokenData;
|
|
211
|
+
}
|
|
212
|
+
catch (error) {
|
|
213
|
+
if (error.message?.includes('invalid_grant')) {
|
|
214
|
+
throw new AuthError('Invalid authorization code', 'INVALID_GRANT', 'The authorization code is invalid or has expired. Please try authenticating again.', false);
|
|
215
|
+
}
|
|
216
|
+
throw new AuthError(`Token exchange failed: ${error.message}`, 'TOKEN_EXCHANGE_FAILED', 'Could not exchange authorization code for tokens. Please try again.', true);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
async function refreshAccessToken(oauth2Client) {
|
|
220
|
+
try {
|
|
221
|
+
const { credentials } = await oauth2Client.refreshAccessToken();
|
|
222
|
+
if (!credentials.access_token) {
|
|
223
|
+
throw new Error('Invalid refresh response: missing access_token');
|
|
224
|
+
}
|
|
225
|
+
const existingTokens = oauth2Client.credentials;
|
|
226
|
+
const tokenData = {
|
|
227
|
+
access_token: credentials.access_token,
|
|
228
|
+
refresh_token: credentials.refresh_token || existingTokens.refresh_token || '',
|
|
229
|
+
expiry_date: credentials.expiry_date || Date.now() + 3600000,
|
|
230
|
+
scope: credentials.scope || existingTokens.scope || SCOPES.join(' '),
|
|
231
|
+
token_type: credentials.token_type || 'Bearer',
|
|
232
|
+
};
|
|
233
|
+
logger.info('Access token refreshed successfully', {
|
|
234
|
+
newToken: redactToken(tokenData.access_token),
|
|
235
|
+
expiresAt: new Date(tokenData.expiry_date).toISOString()
|
|
236
|
+
});
|
|
237
|
+
return tokenData;
|
|
238
|
+
}
|
|
239
|
+
catch (error) {
|
|
240
|
+
if (error.message?.includes('invalid_grant')) {
|
|
241
|
+
throw new AuthError('Refresh token expired or revoked', 'INVALID_GRANT', 'Your authentication has expired. Please run the login command again to re-authenticate.', false);
|
|
242
|
+
}
|
|
243
|
+
throw new AuthError(`Token refresh failed: ${error.message}`, 'TOKEN_REFRESH_FAILED', 'Could not refresh access token. You may need to re-authenticate.', true);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
function needsRefresh(tokens) {
|
|
247
|
+
const now = Date.now();
|
|
248
|
+
const expiresAt = tokens.expiry_date;
|
|
249
|
+
const timeUntilExpiry = expiresAt - now;
|
|
250
|
+
return timeUntilExpiry < TOKEN_REFRESH_MARGIN_MS;
|
|
251
|
+
}
|
|
252
|
+
export class GSCAuth {
|
|
253
|
+
constructor() {
|
|
254
|
+
this.oauth2Client = new OAuth2Client(config.clientId, config.clientSecret, config.redirectUri);
|
|
255
|
+
}
|
|
256
|
+
async login(useDeviceFlow = false) {
|
|
257
|
+
logger.info('Starting authentication', { useDeviceFlow });
|
|
258
|
+
try {
|
|
259
|
+
let tokens;
|
|
260
|
+
if (useDeviceFlow) {
|
|
261
|
+
tokens = await authenticateWithDeviceFlow(this.oauth2Client);
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
throw new AuthError('Manual code paste requires CLI integration', 'CLI_REQUIRED', 'Please use the CLI command to authenticate with code paste flow.', false);
|
|
265
|
+
}
|
|
266
|
+
await saveTokens(tokens);
|
|
267
|
+
this.oauth2Client.setCredentials({
|
|
268
|
+
access_token: tokens.access_token,
|
|
269
|
+
refresh_token: tokens.refresh_token,
|
|
270
|
+
expiry_date: tokens.expiry_date,
|
|
271
|
+
scope: tokens.scope,
|
|
272
|
+
token_type: tokens.token_type,
|
|
273
|
+
});
|
|
274
|
+
logger.info('Authentication successful');
|
|
275
|
+
}
|
|
276
|
+
catch (error) {
|
|
277
|
+
if (error instanceof AuthError) {
|
|
278
|
+
throw error;
|
|
279
|
+
}
|
|
280
|
+
throw new AuthError(`Authentication failed: ${error}`, 'AUTH_FAILED', 'Authentication failed. Please try again.', true);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
async loginWithCode(code) {
|
|
284
|
+
logger.info('Exchanging authorization code for tokens');
|
|
285
|
+
try {
|
|
286
|
+
const tokens = await exchangeCodeForTokens(this.oauth2Client, code);
|
|
287
|
+
await saveTokens(tokens);
|
|
288
|
+
this.oauth2Client.setCredentials({
|
|
289
|
+
access_token: tokens.access_token,
|
|
290
|
+
refresh_token: tokens.refresh_token,
|
|
291
|
+
expiry_date: tokens.expiry_date,
|
|
292
|
+
scope: tokens.scope,
|
|
293
|
+
token_type: tokens.token_type,
|
|
294
|
+
});
|
|
295
|
+
logger.info('Authentication successful');
|
|
296
|
+
}
|
|
297
|
+
catch (error) {
|
|
298
|
+
if (error instanceof AuthError) {
|
|
299
|
+
throw error;
|
|
300
|
+
}
|
|
301
|
+
throw new AuthError(`Code exchange failed: ${error}`, 'CODE_EXCHANGE_FAILED', 'Failed to exchange authorization code. Please try again.', true);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
getAuthorizationUrl() {
|
|
305
|
+
const state = crypto.randomUUID();
|
|
306
|
+
return this.oauth2Client.generateAuthUrl({
|
|
307
|
+
access_type: 'offline',
|
|
308
|
+
scope: SCOPES,
|
|
309
|
+
state: state,
|
|
310
|
+
prompt: 'consent',
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
async logout() {
|
|
314
|
+
await deleteTokens();
|
|
315
|
+
this.oauth2Client.setCredentials({});
|
|
316
|
+
logger.info('Logged out successfully');
|
|
317
|
+
}
|
|
318
|
+
async getAuthenticatedClient() {
|
|
319
|
+
if (!this.oauth2Client.credentials.access_token) {
|
|
320
|
+
const tokens = await loadTokens();
|
|
321
|
+
if (tokens) {
|
|
322
|
+
this.oauth2Client.setCredentials({
|
|
323
|
+
access_token: tokens.access_token,
|
|
324
|
+
refresh_token: tokens.refresh_token,
|
|
325
|
+
expiry_date: tokens.expiry_date,
|
|
326
|
+
scope: tokens.scope,
|
|
327
|
+
token_type: tokens.token_type,
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
else {
|
|
331
|
+
throw new AuthError('No authentication found', 'NOT_AUTHENTICATED', 'You are not authenticated. Please run the login command first.', false);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
const currentTokens = this.oauth2Client.credentials;
|
|
335
|
+
if (currentTokens.expiry_date && needsRefresh({
|
|
336
|
+
access_token: currentTokens.access_token || '',
|
|
337
|
+
refresh_token: currentTokens.refresh_token || '',
|
|
338
|
+
expiry_date: currentTokens.expiry_date,
|
|
339
|
+
scope: currentTokens.scope || '',
|
|
340
|
+
token_type: currentTokens.token_type || 'Bearer',
|
|
341
|
+
})) {
|
|
342
|
+
logger.info('Token expiring soon, refreshing', {
|
|
343
|
+
expiresAt: new Date(currentTokens.expiry_date).toISOString()
|
|
344
|
+
});
|
|
345
|
+
const newTokens = await withRetry(() => refreshAccessToken(this.oauth2Client));
|
|
346
|
+
await saveTokens(newTokens);
|
|
347
|
+
this.oauth2Client.setCredentials({
|
|
348
|
+
access_token: newTokens.access_token,
|
|
349
|
+
refresh_token: newTokens.refresh_token,
|
|
350
|
+
expiry_date: newTokens.expiry_date,
|
|
351
|
+
scope: newTokens.scope,
|
|
352
|
+
token_type: newTokens.token_type,
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
return this.oauth2Client;
|
|
356
|
+
}
|
|
357
|
+
async isAuthenticated() {
|
|
358
|
+
try {
|
|
359
|
+
const tokens = await loadTokens();
|
|
360
|
+
return tokens !== null && !!tokens.refresh_token;
|
|
361
|
+
}
|
|
362
|
+
catch (error) {
|
|
363
|
+
return false;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
async getTokenInfo() {
|
|
367
|
+
const tokens = await loadTokens();
|
|
368
|
+
if (!tokens) {
|
|
369
|
+
throw new AuthError('No tokens found', 'NOT_AUTHENTICATED', 'You are not authenticated.', false);
|
|
370
|
+
}
|
|
371
|
+
const expiresIn = Math.max(0, tokens.expiry_date - Date.now());
|
|
372
|
+
const scopes = tokens.scope.split(' ');
|
|
373
|
+
return {
|
|
374
|
+
expiresIn,
|
|
375
|
+
scopes,
|
|
376
|
+
hasRefreshToken: !!tokens.refresh_token,
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
//# sourceMappingURL=oauth2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth2.js","sourceRoot":"","sources":["../../src/auth/oauth2.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
declare const configSchema: z.ZodObject<{
|
|
3
|
+
clientId: z.ZodString;
|
|
4
|
+
clientSecret: z.ZodString;
|
|
5
|
+
tokenPath: z.ZodDefault<z.ZodString>;
|
|
6
|
+
redirectUri: z.ZodDefault<z.ZodString>;
|
|
7
|
+
logLevel: z.ZodDefault<z.ZodEnum<["error", "warn", "info", "debug"]>>;
|
|
8
|
+
}, "strip", z.ZodTypeAny, {
|
|
9
|
+
clientId: string;
|
|
10
|
+
clientSecret: string;
|
|
11
|
+
tokenPath: string;
|
|
12
|
+
redirectUri: string;
|
|
13
|
+
logLevel: "info" | "error" | "warn" | "debug";
|
|
14
|
+
}, {
|
|
15
|
+
clientId: string;
|
|
16
|
+
clientSecret: string;
|
|
17
|
+
tokenPath?: string | undefined;
|
|
18
|
+
redirectUri?: string | undefined;
|
|
19
|
+
logLevel?: "info" | "error" | "warn" | "debug" | undefined;
|
|
20
|
+
}>;
|
|
21
|
+
export type Config = z.infer<typeof configSchema>;
|
|
22
|
+
export declare const config: {
|
|
23
|
+
clientId: string;
|
|
24
|
+
clientSecret: string;
|
|
25
|
+
tokenPath: string;
|
|
26
|
+
redirectUri: string;
|
|
27
|
+
logLevel: "info" | "error" | "warn" | "debug";
|
|
28
|
+
};
|
|
29
|
+
export declare function getTokenDirectory(): string;
|
|
30
|
+
export declare function isDevelopment(): boolean;
|
|
31
|
+
export declare function isProduction(): boolean;
|
|
32
|
+
export declare function getEnvironment(): string;
|
|
33
|
+
export declare function getConfigSummary(): Record<string, string>;
|
|
34
|
+
export declare function logConfigSummary(): void;
|
|
35
|
+
export {};
|
|
36
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAoBxB,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;EAuDhB,CAAC;AASH,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAkFlD,eAAO,MAAM,MAAM;;;;;;CAAe,CAAC;AASnC,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAKD,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAKD,wBAAgB,YAAY,IAAI,OAAO,CAEtC;AAKD,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAUD,wBAAgB,gBAAgB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CASzD;AAKD,wBAAgB,gBAAgB,IAAI,IAAI,CAMvC"}
|