voicecc 1.1.10 → 1.1.11

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.
@@ -2,7 +2,7 @@
2
2
  * Claude Code authentication routes.
3
3
  *
4
4
  * Supports two auth flows:
5
- * 1. OAuth PKCE flow via claude.ai (recommended enables cloud MCP servers)
5
+ * 1. OAuth PKCE flow via claude.ai (recommended -- enables cloud MCP servers)
6
6
  * 2. Manual token paste via `claude setup-token` (fallback)
7
7
  *
8
8
  * - GET / -- probe auth status
@@ -25,12 +25,12 @@ const PROBE_TIMEOUT_MS = 5_000;
25
25
 
26
26
  const OAUTH_CLIENT_ID = "9d1c250a-e61b-44d9-88ed-5944d1962f5e";
27
27
  const OAUTH_AUTH_URL = "https://claude.ai/oauth/authorize";
28
- const OAUTH_TOKEN_URL = "https://claude.ai/oauth/token";
28
+ const OAUTH_TOKEN_URL = "https://platform.claude.com/v1/oauth/token";
29
29
  const OAUTH_REDIRECT_URI = "https://platform.claude.com/oauth/code/callback";
30
30
  const OAUTH_SCOPES = "org:create_api_key user:profile user:inference user:sessions:claude_code user:mcp_servers";
31
31
 
32
32
  // ============================================================================
33
- // PKCE STATE (single-user dashboard one pending flow at a time)
33
+ // PKCE STATE (single-user dashboard -- one pending flow at a time)
34
34
  // ============================================================================
35
35
 
36
36
  let pendingPkce: { codeVerifier: string; state: string; createdAt: number } | null = null;
@@ -51,25 +51,30 @@ function generatePkce(): { codeVerifier: string; codeChallenge: string } {
51
51
  return { codeVerifier, codeChallenge };
52
52
  }
53
53
 
54
- /** Exchange an authorization code for tokens using the PKCE verifier. */
55
- async function exchangeCodeForTokens(code: string, codeVerifier: string): Promise<{
54
+ /**
55
+ * Exchange an authorization code for tokens using the PKCE verifier.
56
+ * @param code - The authorization code from the OAuth callback
57
+ * @param codeVerifier - The PKCE code_verifier generated at flow start
58
+ * @param state - The OAuth state parameter (required by the token endpoint)
59
+ * @returns Token response with access_token, refresh_token, expires_in
60
+ */
61
+ async function exchangeCodeForTokens(code: string, codeVerifier: string, state: string): Promise<{
56
62
  access_token: string;
57
63
  refresh_token: string;
58
64
  expires_in: number;
59
65
  scope?: string;
60
66
  }> {
61
- const body = new URLSearchParams({
62
- grant_type: "authorization_code",
63
- code,
64
- code_verifier: codeVerifier,
65
- client_id: OAUTH_CLIENT_ID,
66
- redirect_uri: OAUTH_REDIRECT_URI,
67
- });
68
-
69
67
  const res = await fetch(OAUTH_TOKEN_URL, {
70
68
  method: "POST",
71
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
72
- body: body.toString(),
69
+ headers: { "Content-Type": "application/json" },
70
+ body: JSON.stringify({
71
+ grant_type: "authorization_code",
72
+ code,
73
+ state,
74
+ code_verifier: codeVerifier,
75
+ client_id: OAUTH_CLIENT_ID,
76
+ redirect_uri: OAUTH_REDIRECT_URI,
77
+ }),
73
78
  });
74
79
 
75
80
  if (!res.ok) {
@@ -96,7 +101,6 @@ interface AuthStatus {
96
101
  async function getAuthStatus(): Promise<AuthStatus> {
97
102
  return new Promise((resolve) => {
98
103
  execFile(CLAUDE_BIN, ["auth", "status"], { timeout: PROBE_TIMEOUT_MS }, (err, stdout, stderr) => {
99
- // Try parsing stdout first, then stderr (some versions write JSON to stderr on exit 1)
100
104
  const output = stdout?.trim() || stderr?.trim() || "";
101
105
  try {
102
106
  const json = JSON.parse(output);
@@ -140,7 +144,7 @@ export function authRoutes(): Hono {
140
144
  return c.json(await getAuthStatus());
141
145
  });
142
146
 
143
- /** Start an OAuth PKCE flow returns the authorization URL. */
147
+ /** Start an OAuth PKCE flow -- returns the authorization URL. */
144
148
  app.post("/oauth/start", async (c) => {
145
149
  const { codeVerifier, codeChallenge } = generatePkce();
146
150
  const state = base64url(randomBytes(32));
@@ -184,7 +188,7 @@ export function authRoutes(): Hono {
184
188
  }
185
189
 
186
190
  try {
187
- const tokens = await exchangeCodeForTokens(code.trim(), pendingPkce.codeVerifier);
191
+ const tokens = await exchangeCodeForTokens(code.trim(), pendingPkce.codeVerifier, pendingPkce.state);
188
192
  pendingPkce = null;
189
193
 
190
194
  const scopes = tokens.scope
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "voicecc",
3
- "version": "1.1.10",
3
+ "version": "1.1.11",
4
4
  "description": "Voice mode plugin for Claude Code -- hands-free interaction via ElevenLabs STT/TTS and VAD",
5
5
  "type": "module",
6
6
  "bin": {