hatchkit 0.2.3 → 0.2.5

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/dist/config.d.ts CHANGED
@@ -112,8 +112,8 @@ export interface GoogleSearchConsoleMeta extends ProviderStatus {
112
112
  /** Scopes granted to the stored refresh token. Non-sensitive; useful
113
113
  * in status/doctor output when a user authorized only one API. */
114
114
  scopes?: string[];
115
- /** `hatchkit-pkce` uses Hatchkit's shipped public desktop OAuth client.
116
- * `byo-client` is the legacy/user-owned Google Cloud OAuth client path. */
115
+ /** `hatchkit-pkce` uses a Hatchkit OAuth client supplied through env vars.
116
+ * `byo-client` is the user-owned Google Cloud OAuth client path. */
117
117
  oauthMode?: "hatchkit-pkce" | "byo-client";
118
118
  }
119
119
  export interface StripeMeta extends ProviderStatus {
@@ -291,6 +291,7 @@ export declare function ensurePlausible(): Promise<PlausibleConfig>;
291
291
  export declare function getPlausibleConfig(): Promise<PlausibleConfig | null>;
292
292
  export declare function ensureResend(): Promise<ResendConfig>;
293
293
  export declare function getResendConfig(): Promise<ResendConfig | null>;
294
+ export declare function extractGoogleOAuthCodeFromCallbackUrl(rawUrl: string, expectedState: string): string;
294
295
  export declare function refreshGoogleSearchConsoleAccessToken(cfg: GoogleSearchConsoleConfig): Promise<string>;
295
296
  export declare function ensureGoogleSearchConsole(): Promise<GoogleSearchConsoleConfig>;
296
297
  export declare function getGoogleSearchConsoleConfig(): Promise<GoogleSearchConsoleConfig | null>;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,OAAO,IAAI,MAAM,MAAM,CAAC;AAcxB;;;;;;;;;;;;8DAY8D;AAC9D,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,MAAM,GAAG,IAAI,CAaf;AAeD;;;;;;;;;;;gBAWgB;AAChB,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CA0EvE;AAmBD;;sDAEsD;AACtD,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAkBxE;AAuBD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,YAAY,GAAG,cAAc,CAAC;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAID,MAAM,WAAW,WAAY,SAAQ,cAAc;IACjD,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChE;AAED,MAAM,WAAW,WAAY,SAAQ,cAAc;CAAG;AAEtD,MAAM,WAAW,OAAQ,SAAQ,cAAc;IAC7C;;;;yDAIqD;IACrD,QAAQ,EAAE,YAAY,CAAC;IACvB;;;qEAGiE;IACjE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;+EAE2E;IAC3E,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,cAAe,SAAQ,cAAc;IACpD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAgB,SAAQ,cAAc;IACrD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,aAAc,SAAQ,cAAc;IACnD,GAAG,EAAE,MAAM,CAAC;IACZ,uEAAuE;IACvE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;6BACyB;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAc,SAAQ,cAAc;IACnD,iEAAiE;IACjE,GAAG,EAAE,MAAM,CAAC;IACZ;;;sDAGkD;IAClD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;2DACuD;IACvD,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,aAAc,SAAQ,cAAc;IACnD,qEAAqE;IACrE,GAAG,EAAE,MAAM,CAAC;IACZ,wEAAwE;IACxE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAW,SAAQ,cAAc;IAChD,mFAAmF;IACnF,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,uBAAwB,SAAQ,cAAc;IAC7D;uEACmE;IACnE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB;yEACqE;IACrE,SAAS,CAAC,EAAE,eAAe,GAAG,YAAY,CAAC;CAC5C;AAED,MAAM,WAAW,UAAW,SAAQ,cAAc;IAChD;;;mEAG+D;IAC/D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;6CAEyC;IACzC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,QAAS,SAAQ,cAAc;IAC9C;;;;;oEAKgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAKD,MAAM,WAAW,aAAc,SAAQ,WAAW;IAChD,KAAK,EAAE,MAAM,CAAC;CACf;AACD,MAAM,WAAW,aAAc,SAAQ,WAAW;IAChD,KAAK,EAAE,MAAM,CAAC;CACf;AACD,MAAM,WAAW,SAAU,SAAQ,OAAO;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;2EACuE;IACvE,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AACD,MAAM,WAAW,gBAAiB,SAAQ,cAAc;IACtD,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AACD,MAAM,WAAW,iBAAkB,SAAQ,eAAe;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,eAAgB,SAAQ,aAAa;IACpD,KAAK,EAAE,MAAM,CAAC;CACf;AACD,MAAM,WAAW,eAAgB,SAAQ,aAAa;IACpD,oDAAoD;IACpD,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AACD,MAAM,WAAW,eAAgB,SAAQ,aAAa;IACpD,MAAM,EAAE,MAAM,CAAC;CAChB;AACD,MAAM,WAAW,YAAa,SAAQ,UAAU;IAC9C,MAAM,EAAE,MAAM,CAAC;CAChB;AACD,MAAM,WAAW,yBAA0B,SAAQ,uBAAuB;IACxE,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;CACtB;AACD,MAAM,WAAW,YAAa,SAAQ,UAAU;IAC9C;;kCAE8B;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;qBAEiB;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AACD,MAAM,WAAW,UAAW,SAAQ,QAAQ;IAC1C;mEAC+D;IAC/D,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE;QACT,MAAM,EAAE,cAAc,CAAC;QACvB,OAAO,CAAC,EAAE,WAAW,CAAC;QACtB,OAAO,CAAC,EAAE,WAAW,CAAC;QACtB,GAAG,CAAC,EAAE,OAAO,CAAC;QACd,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QACnC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;QACrC,SAAS,CAAC,EAAE,aAAa,CAAC;QAC1B,SAAS,CAAC,EAAE,aAAa,CAAC;QAC1B,SAAS,CAAC,EAAE,aAAa,CAAC;QAC1B,MAAM,CAAC,EAAE,UAAU,CAAC;QACpB,mBAAmB,CAAC,EAAE,uBAAuB,CAAC;QAC9C,MAAM,CAAC,EAAE,UAAU,CAAC;QACpB,IAAI,CAAC,EAAE,QAAQ,CAAC;KACjB,CAAC;IACF,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC3C;yEACqE;IACrE,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB;;sDAEkD;IAClD,QAAQ,CAAC,EAAE;QACT;;uDAE+C;QAC/C,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;CACH;AAyDD;;eAEe;AACf,wBAAgB,QAAQ,oBAEvB;AAED,wBAAgB,SAAS,IAAI,SAAS,CAErC;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED;qDACqD;AACrD,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAGjD;AA4BD,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAqBlD;AAMD,wBAAsB,aAAa,IAAI,OAAO,CAAC,aAAa,CAAC,CAmE5D;AAED;gEACgE;AAChE,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAOtE;AAMD,wBAAsB,aAAa,IAAI,OAAO,CAAC,aAAa,CAAC,CAkC5D;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAG9D;AAED,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAMtE;AAMD,wBAAsB,SAAS,IAAI,OAAO,CAAC,SAAS,CAAC,CA0FpD;AAMD;;4CAE4C;AAC5C,wBAAgB,yBAAyB,IAAI,MAAM,GAAG,IAAI,CAGzD;AAED,4CAA4C;AAC5C,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAG7D;AAED;;mEAEmE;AACnE,wBAAsB,4BAA4B,IAAI,OAAO,CAAC,MAAM,CAAC,CAmBpE;AAED;;;;;;;;;GASG;AACH,wBAAsB,+BAA+B,IAAI,OAAO,CAAC;IAC/D,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,CAeD;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAgB9D;AAMD,wBAAsB,QAAQ,CAAC,QAAQ,EAAE,SAAS,GAAG,KAAK,GAAG,IAAI,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA8K5F;AAED,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAqBpF;AAMD,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,GAAG,WAAW,GAChD,OAAO,CAAC,iBAAiB,CAAC,CA6C5B;AAED,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAMtF;AAMD,wBAAgB,YAAY,IAAI,MAAM,EAAE,CAEvC;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAOlD;AAED;8DAC8D;AAC9D,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAIrD;AAMD,wBAAgB,aAAa,IAAI,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAE9D;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,IAAI,CAE3E;AAMD,wBAAsB,eAAe,IAAI,OAAO,CAAC,eAAe,CAAC,CA+ChE;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAM1E;AAMD,wBAAsB,eAAe,IAAI,OAAO,CAAC,eAAe,CAAC,CAqFhE;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAO1E;AAMD,wBAAsB,eAAe,IAAI,OAAO,CAAC,eAAe,CAAC,CAgDhE;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAM1E;AAMD,wBAAsB,YAAY,IAAI,OAAO,CAAC,YAAY,CAAC,CAgC1D;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAMpE;AAoED,wBAAgB,qCAAqC,CACnD,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,GACpB,MAAM,CAoBR;AAgOD,wBAAsB,qCAAqC,CACzD,GAAG,EAAE,yBAAyB,GAC7B,OAAO,CAAC,MAAM,CAAC,CAmCjB;AAED,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,yBAAyB,CAAC,CAqGpF;AAED,wBAAsB,4BAA4B,IAAI,OAAO,CAAC,yBAAyB,GAAG,IAAI,CAAC,CA2B9F;AAwGD,wBAAsB,YAAY,IAAI,OAAO,CAAC,YAAY,CAAC,CAwF1D;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAOpE;AAyBD,wBAAsB,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC,CAyDtD;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAMhE;AAMD,wBAAsB,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC,CAGnD;AA0BD,KAAK,sBAAsB,GACvB,SAAS,GACT,SAAS,GACT,KAAK,GACL,WAAW,GACX,WAAW,GACX,WAAW,GACX,QAAQ,GACR,gBAAgB,GAChB,QAAQ,GACR,MAAM,GACN,MAAM,SAAS,GAAG,KAAK,GAAG,IAAI,EAAE,GAChC,OAAO,OAAO,GAAG,QAAQ,GAAG,IAAI,GAAG,WAAW,EAAE,CAAC;AAErD;;2DAE2D;AAC3D,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CA6ErF;AAkND,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAuEnD"}
package/dist/config.js CHANGED
@@ -160,6 +160,23 @@ export async function confirmPastedSecret(label) {
160
160
  return value;
161
161
  }
162
162
  }
163
+ async function confirmOptionalPastedSecret(label) {
164
+ for (;;) {
165
+ const raw = await password({ message: `${label} (optional, leave blank to skip):` });
166
+ const value = sanitizePastedSecret(raw);
167
+ if (!value)
168
+ return undefined;
169
+ const preview = value.length <= 8
170
+ ? `${"*".repeat(value.length)} (${value.length} chars — looks short?)`
171
+ : `${value.slice(0, 4)}…${value.slice(-4)} (${value.length} chars)`;
172
+ const ok = await confirm({
173
+ message: `Looks like: ${chalk.cyan(preview)} — use this?`,
174
+ default: true,
175
+ });
176
+ if (ok)
177
+ return value;
178
+ }
179
+ }
163
180
  // ---------------------------------------------------------------------------
164
181
  // Config store
165
182
  // ---------------------------------------------------------------------------
@@ -1026,24 +1043,17 @@ const GOOGLE_SEARCH_CONSOLE_SCOPES = [
1026
1043
  "https://www.googleapis.com/auth/webmasters",
1027
1044
  "https://www.googleapis.com/auth/siteverification.verify_only",
1028
1045
  ];
1029
- // Public Desktop OAuth client for Hatchkit's own Google Cloud project.
1030
- // Desktop/installed clients are public clients, so these values are not
1031
- // confidential once distributed. Google still often requires the generated
1032
- // desktop client secret during token exchange and refresh.
1033
- // Until the Hatchkit project is verified, dev builds can set
1034
- // HATCHKIT_GOOGLE_SEARCH_CONSOLE_CLIENT_ID / _CLIENT_SECRET to exercise the
1035
- // packaged PKCE path.
1036
- const PACKAGED_GOOGLE_SEARCH_CONSOLE_CLIENT_ID = "932614455438-s0ih891al5pkeo4aeafekf01t6pbqd21.apps.googleusercontent.com";
1037
- const PACKAGED_GOOGLE_SEARCH_CONSOLE_CLIENT_SECRET = "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";
1046
+ const GOOGLE_OAUTH_CALLBACK_PATH = "/oauth/google/callback";
1047
+ const GOOGLE_OAUTH_CALLBACK_WAIT_MS = 120_000;
1048
+ const GOOGLE_OAUTH_TOKEN_TIMEOUT_MS = 30_000;
1049
+ const HATCHKIT_GOOGLE_SEARCH_CONSOLE_CLIENT_ID_ENV = "HATCHKIT_GOOGLE_SEARCH_CONSOLE_CLIENT_ID";
1050
+ const HATCHKIT_GOOGLE_SEARCH_CONSOLE_CLIENT_SECRET_ENV = "HATCHKIT_GOOGLE_SEARCH_CONSOLE_CLIENT_SECRET";
1038
1051
  function hatchkitGoogleSearchConsoleClientId() {
1039
- const configured = process.env.HATCHKIT_GOOGLE_SEARCH_CONSOLE_CLIENT_ID?.trim() ||
1040
- PACKAGED_GOOGLE_SEARCH_CONSOLE_CLIENT_ID.trim();
1052
+ const configured = process.env[HATCHKIT_GOOGLE_SEARCH_CONSOLE_CLIENT_ID_ENV]?.trim();
1041
1053
  return configured || null;
1042
1054
  }
1043
1055
  function hatchkitGoogleSearchConsoleClientSecret() {
1044
- return (process.env.HATCHKIT_GOOGLE_SEARCH_CONSOLE_CLIENT_SECRET?.trim() ||
1045
- PACKAGED_GOOGLE_SEARCH_CONSOLE_CLIENT_SECRET.trim() ||
1046
- undefined);
1056
+ return process.env[HATCHKIT_GOOGLE_SEARCH_CONSOLE_CLIENT_SECRET_ENV]?.trim() || undefined;
1047
1057
  }
1048
1058
  const GOOGLE_SEARCH_CONSOLE_SCOPE_REQUIREMENTS = [
1049
1059
  {
@@ -1075,6 +1085,65 @@ function createPkcePair() {
1075
1085
  const challenge = base64Url(createHash("sha256").update(verifier).digest());
1076
1086
  return { verifier, challenge };
1077
1087
  }
1088
+ function sleep(ms) {
1089
+ return new Promise((resolve) => setTimeout(resolve, ms));
1090
+ }
1091
+ export function extractGoogleOAuthCodeFromCallbackUrl(rawUrl, expectedState) {
1092
+ const trimmed = rawUrl.trim();
1093
+ if (!trimmed)
1094
+ throw new Error("Redirect URL is empty.");
1095
+ let url;
1096
+ try {
1097
+ url = new URL(trimmed);
1098
+ }
1099
+ catch {
1100
+ throw new Error("Could not parse the pasted Google redirect URL.");
1101
+ }
1102
+ if (url.pathname !== GOOGLE_OAUTH_CALLBACK_PATH) {
1103
+ throw new Error(`Expected a Google redirect URL ending in ${GOOGLE_OAUTH_CALLBACK_PATH}, got ${url.pathname}.`);
1104
+ }
1105
+ const gotState = url.searchParams.get("state");
1106
+ const code = url.searchParams.get("code");
1107
+ const error = url.searchParams.get("error");
1108
+ if (gotState !== expectedState)
1109
+ throw new Error("Google OAuth state mismatch.");
1110
+ if (error || !code)
1111
+ throw new Error(`Google OAuth failed: ${error ?? "missing code"}.`);
1112
+ return code;
1113
+ }
1114
+ async function waitForGoogleOAuthCode(args) {
1115
+ const callbackResult = args.codePromise.then((code) => ({ kind: "code", code }), (error) => ({ kind: "error", error: error }));
1116
+ while (true) {
1117
+ const result = await Promise.race([
1118
+ callbackResult,
1119
+ sleep(GOOGLE_OAUTH_CALLBACK_WAIT_MS).then(() => ({ kind: "timeout" })),
1120
+ ]);
1121
+ if (result.kind === "code")
1122
+ return result.code;
1123
+ if (result.kind === "error")
1124
+ throw result.error;
1125
+ console.log(chalk.yellow("\n Still waiting for Google to redirect your browser back to the local callback server."));
1126
+ console.log(chalk.dim(` Expected callback: ${chalk.cyan(args.redirectUri)}`));
1127
+ console.log(chalk.dim(' If your browser ended on a localhost URL, a blank page, or a "site can\'t be reached" page, paste the full address below.'));
1128
+ if (!process.stdin.isTTY) {
1129
+ throw new Error("Timed out waiting for the Google OAuth callback. Re-run in an interactive terminal, or copy the final localhost redirect URL from your browser when prompted.");
1130
+ }
1131
+ const pasted = (await input({
1132
+ message: "Google redirect URL (leave blank to keep waiting):",
1133
+ })).trim();
1134
+ if (!pasted) {
1135
+ console.log(chalk.dim(" Keeping the callback server open. Finish the browser flow."));
1136
+ continue;
1137
+ }
1138
+ try {
1139
+ return extractGoogleOAuthCodeFromCallbackUrl(pasted, args.state);
1140
+ }
1141
+ catch (err) {
1142
+ console.log(chalk.yellow(` ${err.message}`));
1143
+ console.log(chalk.dim(" Try pasting the final localhost callback URL, including the code and state."));
1144
+ }
1145
+ }
1146
+ }
1078
1147
  async function exchangeGoogleCode(args) {
1079
1148
  const body = new URLSearchParams({
1080
1149
  client_id: args.clientId,
@@ -1086,18 +1155,25 @@ async function exchangeGoogleCode(args) {
1086
1155
  body.set("client_secret", args.clientSecret);
1087
1156
  if (args.codeVerifier)
1088
1157
  body.set("code_verifier", args.codeVerifier);
1089
- const res = await fetch("https://oauth2.googleapis.com/token", {
1090
- method: "POST",
1091
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
1092
- body,
1093
- });
1158
+ let res;
1159
+ try {
1160
+ res = await fetch("https://oauth2.googleapis.com/token", {
1161
+ method: "POST",
1162
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
1163
+ body,
1164
+ signal: AbortSignal.timeout(GOOGLE_OAUTH_TOKEN_TIMEOUT_MS),
1165
+ });
1166
+ }
1167
+ catch (err) {
1168
+ throw new Error(`Google OAuth token exchange failed: ${err.message}`);
1169
+ }
1094
1170
  const json = (await res.json().catch(() => null));
1095
1171
  if (!res.ok || !json?.access_token) {
1096
1172
  const msg = json?.error_description ?? json?.error ?? `HTTP ${res.status}`;
1097
1173
  if (/client_secret is missing/i.test(msg) && !args.clientSecret) {
1098
1174
  throw new Error("Google OAuth token exchange failed: client_secret is missing. " +
1099
- "Google Desktop OAuth clients can still require their generated client secret. " +
1100
- "Add a new secret for the Hatchkit Desktop client if needed, set HATCHKIT_GOOGLE_SEARCH_CONSOLE_CLIENT_SECRET, then retry.");
1175
+ "Desktop OAuth clients using PKCE normally do not require one. " +
1176
+ `Verify the OAuth client type is Desktop app, or set ${HATCHKIT_GOOGLE_SEARCH_CONSOLE_CLIENT_SECRET_ENV} / re-run setup with the optional secret as a fallback.`);
1101
1177
  }
1102
1178
  throw new Error(`Google OAuth token exchange failed: ${msg}`);
1103
1179
  }
@@ -1121,7 +1197,7 @@ async function runGoogleOAuthLoopback(args) {
1121
1197
  });
1122
1198
  const server = createServer((req, res) => {
1123
1199
  const url = new URL(req.url ?? "/", redirectUri);
1124
- if (url.pathname !== "/oauth/google/callback") {
1200
+ if (url.pathname !== GOOGLE_OAUTH_CALLBACK_PATH) {
1125
1201
  res.writeHead(404, { "Content-Type": "text/plain" });
1126
1202
  res.end("Not found");
1127
1203
  return;
@@ -1174,8 +1250,12 @@ async function runGoogleOAuthLoopback(args) {
1174
1250
  }
1175
1251
  console.log(chalk.dim("\n Open this URL in your browser, approve access, then return here:"));
1176
1252
  console.log(chalk.cyan(` ${authUrl.toString()}\n`));
1253
+ console.log(chalk.dim(` Waiting for Google to redirect your browser to ${chalk.cyan(redirectUri)}. ` +
1254
+ "If the browser cannot reach localhost, Hatchkit will ask you to paste the final redirect URL."));
1177
1255
  try {
1178
- const code = await codePromise;
1256
+ const code = await waitForGoogleOAuthCode({ codePromise, redirectUri, state });
1257
+ console.log(chalk.green(" ✓ Google OAuth callback received"));
1258
+ console.log(chalk.dim(" Exchanging authorization code for a refresh token..."));
1179
1259
  const token = await exchangeGoogleCode({
1180
1260
  clientId: args.clientId,
1181
1261
  clientSecret: args.clientSecret,
@@ -1188,6 +1268,7 @@ async function runGoogleOAuthLoopback(args) {
1188
1268
  }
1189
1269
  const scopes = token.scope?.split(/\s+/).filter(Boolean) ?? GOOGLE_SEARCH_CONSOLE_SCOPES;
1190
1270
  assertGoogleSearchConsoleScopes(scopes);
1271
+ console.log(chalk.green(" ✓ Google granted Search Console + Site Verification access"));
1191
1272
  return {
1192
1273
  refreshToken: token.refresh_token,
1193
1274
  scopes,
@@ -1205,18 +1286,25 @@ export async function refreshGoogleSearchConsoleAccessToken(cfg) {
1205
1286
  });
1206
1287
  if (cfg.clientSecret)
1207
1288
  body.set("client_secret", cfg.clientSecret);
1208
- const res = await fetch("https://oauth2.googleapis.com/token", {
1209
- method: "POST",
1210
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
1211
- body,
1212
- });
1289
+ let res;
1290
+ try {
1291
+ res = await fetch("https://oauth2.googleapis.com/token", {
1292
+ method: "POST",
1293
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
1294
+ body,
1295
+ signal: AbortSignal.timeout(GOOGLE_OAUTH_TOKEN_TIMEOUT_MS),
1296
+ });
1297
+ }
1298
+ catch (err) {
1299
+ throw new Error(`Google refresh token failed: ${err.message}`);
1300
+ }
1213
1301
  const json = (await res.json().catch(() => null));
1214
1302
  if (!res.ok || !json?.access_token) {
1215
1303
  const msg = json?.error_description ?? json?.error ?? `HTTP ${res.status}`;
1216
1304
  if (/client_secret is missing/i.test(msg) && !cfg.clientSecret) {
1217
1305
  throw new Error("Google refresh token failed: client_secret is missing. " +
1218
- "Google Desktop OAuth clients can still require their generated client secret. " +
1219
- "Set HATCHKIT_GOOGLE_SEARCH_CONSOLE_CLIENT_SECRET or rebuild Hatchkit with the packaged desktop client secret.");
1306
+ "Desktop OAuth clients using PKCE normally do not require one. " +
1307
+ `Verify the OAuth client type is Desktop app, or set ${HATCHKIT_GOOGLE_SEARCH_CONSOLE_CLIENT_SECRET_ENV} / re-run setup with the optional secret as a fallback.`);
1220
1308
  }
1221
1309
  throw new Error(`Google refresh token failed: ${msg}`);
1222
1310
  }
@@ -1228,7 +1316,7 @@ export async function ensureGoogleSearchConsole() {
1228
1316
  const existingClientSecret = await getSecret(SECRET_KEYS.googleSearchConsoleClientSecret);
1229
1317
  const existingRefreshToken = await getSecret(SECRET_KEYS.googleSearchConsoleRefreshToken);
1230
1318
  const hatchkitClientId = hatchkitGoogleSearchConsoleClientId();
1231
- const existingMode = existing?.oauthMode ?? (existingClientSecret ? "byo-client" : "hatchkit-pkce");
1319
+ const existingMode = existing?.oauthMode ?? (existingClientId ? "byo-client" : "hatchkit-pkce");
1232
1320
  if (existing?.status === "configured" && existingRefreshToken) {
1233
1321
  if (existingMode === "hatchkit-pkce" && hatchkitClientId) {
1234
1322
  return {
@@ -1239,12 +1327,12 @@ export async function ensureGoogleSearchConsole() {
1239
1327
  refreshToken: existingRefreshToken,
1240
1328
  };
1241
1329
  }
1242
- if (existingClientId && existingClientSecret) {
1330
+ if (existingClientId) {
1243
1331
  return {
1244
1332
  ...existing,
1245
1333
  oauthMode: "byo-client",
1246
1334
  clientId: existingClientId,
1247
- clientSecret: existingClientSecret,
1335
+ clientSecret: existingClientSecret ?? undefined,
1248
1336
  refreshToken: existingRefreshToken,
1249
1337
  };
1250
1338
  }
@@ -1260,22 +1348,22 @@ export async function ensureGoogleSearchConsole() {
1260
1348
  clientId = hatchkitClientId;
1261
1349
  clientSecret = hatchkitGoogleSearchConsoleClientSecret();
1262
1350
  oauthMode = "hatchkit-pkce";
1263
- console.log(chalk.dim(" Using Hatchkit's shipped Google OAuth desktop client with PKCE. No user-owned Google Cloud setup is needed."));
1351
+ console.log(chalk.dim(` Using the Google OAuth desktop client from ${HATCHKIT_GOOGLE_SEARCH_CONSOLE_CLIENT_ID_ENV} with PKCE.`));
1264
1352
  if (!clientSecret) {
1265
- console.log(chalk.yellow(" This build does not include the Google desktop client secret. If Google rejects the token exchange with `client_secret is missing`, set HATCHKIT_GOOGLE_SEARCH_CONSOLE_CLIENT_SECRET and retry."));
1353
+ console.log(chalk.yellow(` If Google rejects the token exchange with \`client_secret is missing\`, set ${HATCHKIT_GOOGLE_SEARCH_CONSOLE_CLIENT_SECRET_ENV} and retry.`));
1266
1354
  }
1267
1355
  }
1268
1356
  else {
1269
1357
  oauthMode = "byo-client";
1270
- console.log(chalk.dim(" No packaged Hatchkit Google OAuth client id is configured in this build.\n" +
1358
+ console.log(chalk.dim(" No Hatchkit Google OAuth client id is configured in this environment.\n" +
1271
1359
  " Falling back to the legacy BYO Google Cloud OAuth client setup.\n"));
1272
- tokenHint("https://console.cloud.google.com/apis/credentials", "OAuth client (Desktop app) with Search Console API + Site Verification API enabled", `Scopes: ${GOOGLE_SEARCH_CONSOLE_SCOPES.join(", ")}`);
1360
+ tokenHint("https://console.cloud.google.com/apis/credentials", "OAuth client (Desktop app) with Search Console API + Site Verification API enabled", `Scopes: ${GOOGLE_SEARCH_CONSOLE_SCOPES.join(", ")}; client secret is optional for Desktop app + PKCE`);
1273
1361
  clientId = (await input({
1274
1362
  message: "Google OAuth client ID:",
1275
1363
  default: existingClientId ?? undefined,
1276
1364
  validate: validateRequired,
1277
1365
  })).trim();
1278
- clientSecret = await confirmPastedSecret("Google OAuth client secret");
1366
+ clientSecret = await confirmOptionalPastedSecret("Google OAuth client secret");
1279
1367
  }
1280
1368
  const oauth = await runGoogleOAuthLoopback({ clientId, clientSecret });
1281
1369
  const meta = {
@@ -1289,6 +1377,8 @@ export async function ensureGoogleSearchConsole() {
1289
1377
  await setSecret(SECRET_KEYS.googleSearchConsoleClientId, clientId);
1290
1378
  if (clientSecret)
1291
1379
  await setSecret(SECRET_KEYS.googleSearchConsoleClientSecret, clientSecret);
1380
+ else
1381
+ await deleteSecret(SECRET_KEYS.googleSearchConsoleClientSecret);
1292
1382
  }
1293
1383
  else {
1294
1384
  await deleteSecret(SECRET_KEYS.googleSearchConsoleClientId);
@@ -1320,9 +1410,15 @@ export async function getGoogleSearchConsoleConfig() {
1320
1410
  refreshToken,
1321
1411
  };
1322
1412
  }
1323
- if (!clientId || !clientSecret)
1413
+ if (!clientId)
1324
1414
  return null;
1325
- return { ...meta, oauthMode: "byo-client", clientId, clientSecret, refreshToken };
1415
+ return {
1416
+ ...meta,
1417
+ oauthMode: "byo-client",
1418
+ clientId,
1419
+ clientSecret: clientSecret ?? undefined,
1420
+ refreshToken,
1421
+ };
1326
1422
  }
1327
1423
  // ---------------------------------------------------------------------------
1328
1424
  // Provider: Stripe (payments)