@hanzo/browser-extension 1.7.5 → 1.7.6

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.
@@ -27,7 +27,8 @@
27
27
  function generateState() {
28
28
  return generateRandomString(32);
29
29
  }
30
- var IAM_BASE = "https://hanzo.id";
30
+ var IAM_LOGIN = "https://hanzo.id";
31
+ var IAM_API = "https://iam.hanzo.ai";
31
32
  var CLIENT_ID = "app-hanzo";
32
33
  var SCOPES = "openid profile email";
33
34
  function getRedirectUri() {
@@ -69,7 +70,7 @@
69
70
  const { codeVerifier, codeChallenge } = await generatePkceChallenge();
70
71
  const state = generateState();
71
72
  const redirectUri = getRedirectUri();
72
- const authorizeUrl = new URL(`${IAM_BASE}/login/oauth/authorize`);
73
+ const authorizeUrl = new URL(`${IAM_LOGIN}/login/oauth/authorize`);
73
74
  authorizeUrl.searchParams.set("client_id", CLIENT_ID);
74
75
  authorizeUrl.searchParams.set("response_type", "code");
75
76
  authorizeUrl.searchParams.set("redirect_uri", redirectUri);
@@ -82,28 +83,39 @@
82
83
  const returnedState = url.searchParams.get("state");
83
84
  if (returnedState !== state) throw new Error("State mismatch \u2014 possible CSRF");
84
85
  const code = url.searchParams.get("code");
85
- if (!code) {
86
- const error = url.searchParams.get("error_description") || url.searchParams.get("error") || "No authorization code";
86
+ const directToken = url.searchParams.get("access_token");
87
+ if (directToken) {
88
+ const tokens = {
89
+ access_token: directToken,
90
+ refresh_token: url.searchParams.get("refresh_token") || void 0,
91
+ token_type: "Bearer"
92
+ };
93
+ await storeTokens(tokens);
94
+ } else if (code) {
95
+ const tokenResponse = await fetch(`${IAM_API}/api/login/oauth/access_token`, {
96
+ method: "POST",
97
+ headers: { "Content-Type": "application/json" },
98
+ body: JSON.stringify({
99
+ grant_type: "authorization_code",
100
+ client_id: CLIENT_ID,
101
+ code,
102
+ redirect_uri: redirectUri,
103
+ code_verifier: codeVerifier
104
+ })
105
+ });
106
+ if (!tokenResponse.ok) {
107
+ const errText = await tokenResponse.text();
108
+ throw new Error(`Token exchange failed: ${errText}`);
109
+ }
110
+ const tokens = await tokenResponse.json();
111
+ await storeTokens(tokens);
112
+ } else {
113
+ const error = url.searchParams.get("error_description") || url.searchParams.get("error") || "No authorization code or token";
87
114
  throw new Error(error);
88
115
  }
89
- const tokenResponse = await fetch(`${IAM_BASE}/oauth/token`, {
90
- method: "POST",
91
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
92
- body: new URLSearchParams({
93
- grant_type: "authorization_code",
94
- client_id: CLIENT_ID,
95
- code,
96
- redirect_uri: redirectUri,
97
- code_verifier: codeVerifier
98
- })
99
- });
100
- if (!tokenResponse.ok) {
101
- const errText = await tokenResponse.text();
102
- throw new Error(`Token exchange failed: ${errText}`);
103
- }
104
- const tokens = await tokenResponse.json();
105
- await storeTokens(tokens);
106
- const user = await fetchUserInfo(tokens.access_token);
116
+ const { accessToken } = await getStoredTokens();
117
+ if (!accessToken) throw new Error("Login succeeded but no token was stored");
118
+ const user = await fetchUserInfo(accessToken);
107
119
  await chrome.storage.local.set({ [STORAGE_KEYS.user]: user });
108
120
  return user;
109
121
  }
@@ -167,10 +179,10 @@
167
179
  return accessToken;
168
180
  }
169
181
  async function refreshAccessToken(refreshToken) {
170
- const response = await fetch(`${IAM_BASE}/oauth/token`, {
182
+ const response = await fetch(`${IAM_API}/api/login/oauth/access_token`, {
171
183
  method: "POST",
172
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
173
- body: new URLSearchParams({
184
+ headers: { "Content-Type": "application/json" },
185
+ body: JSON.stringify({
174
186
  grant_type: "refresh_token",
175
187
  client_id: CLIENT_ID,
176
188
  refresh_token: refreshToken
@@ -182,7 +194,7 @@
182
194
  return tokens.access_token;
183
195
  }
184
196
  async function fetchUserInfo(accessToken) {
185
- const response = await fetch(`${IAM_BASE}/oauth/userinfo`, {
197
+ const response = await fetch(`${IAM_API}/api/userinfo`, {
186
198
  headers: { Authorization: `Bearer ${accessToken}` }
187
199
  });
188
200
  if (!response.ok) throw new Error("Failed to fetch user info");
@@ -1608,7 +1608,8 @@ async function generatePkceChallenge() {
1608
1608
  function generateState() {
1609
1609
  return generateRandomString(32);
1610
1610
  }
1611
- var IAM_BASE = "https://hanzo.id";
1611
+ var IAM_LOGIN = "https://hanzo.id";
1612
+ var IAM_API = "https://iam.hanzo.ai";
1612
1613
  var CLIENT_ID = "app-hanzo";
1613
1614
  var SCOPES = "openid profile email";
1614
1615
  function getRedirectUri() {
@@ -1650,7 +1651,7 @@ async function login() {
1650
1651
  const { codeVerifier, codeChallenge } = await generatePkceChallenge();
1651
1652
  const state = generateState();
1652
1653
  const redirectUri = getRedirectUri();
1653
- const authorizeUrl = new URL(`${IAM_BASE}/login/oauth/authorize`);
1654
+ const authorizeUrl = new URL(`${IAM_LOGIN}/login/oauth/authorize`);
1654
1655
  authorizeUrl.searchParams.set("client_id", CLIENT_ID);
1655
1656
  authorizeUrl.searchParams.set("response_type", "code");
1656
1657
  authorizeUrl.searchParams.set("redirect_uri", redirectUri);
@@ -1663,28 +1664,39 @@ async function login() {
1663
1664
  const returnedState = url.searchParams.get("state");
1664
1665
  if (returnedState !== state) throw new Error("State mismatch \u2014 possible CSRF");
1665
1666
  const code = url.searchParams.get("code");
1666
- if (!code) {
1667
- const error = url.searchParams.get("error_description") || url.searchParams.get("error") || "No authorization code";
1667
+ const directToken = url.searchParams.get("access_token");
1668
+ if (directToken) {
1669
+ const tokens = {
1670
+ access_token: directToken,
1671
+ refresh_token: url.searchParams.get("refresh_token") || void 0,
1672
+ token_type: "Bearer"
1673
+ };
1674
+ await storeTokens(tokens);
1675
+ } else if (code) {
1676
+ const tokenResponse = await fetch(`${IAM_API}/api/login/oauth/access_token`, {
1677
+ method: "POST",
1678
+ headers: { "Content-Type": "application/json" },
1679
+ body: JSON.stringify({
1680
+ grant_type: "authorization_code",
1681
+ client_id: CLIENT_ID,
1682
+ code,
1683
+ redirect_uri: redirectUri,
1684
+ code_verifier: codeVerifier
1685
+ })
1686
+ });
1687
+ if (!tokenResponse.ok) {
1688
+ const errText = await tokenResponse.text();
1689
+ throw new Error(`Token exchange failed: ${errText}`);
1690
+ }
1691
+ const tokens = await tokenResponse.json();
1692
+ await storeTokens(tokens);
1693
+ } else {
1694
+ const error = url.searchParams.get("error_description") || url.searchParams.get("error") || "No authorization code or token";
1668
1695
  throw new Error(error);
1669
1696
  }
1670
- const tokenResponse = await fetch(`${IAM_BASE}/oauth/token`, {
1671
- method: "POST",
1672
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
1673
- body: new URLSearchParams({
1674
- grant_type: "authorization_code",
1675
- client_id: CLIENT_ID,
1676
- code,
1677
- redirect_uri: redirectUri,
1678
- code_verifier: codeVerifier
1679
- })
1680
- });
1681
- if (!tokenResponse.ok) {
1682
- const errText = await tokenResponse.text();
1683
- throw new Error(`Token exchange failed: ${errText}`);
1684
- }
1685
- const tokens = await tokenResponse.json();
1686
- await storeTokens(tokens);
1687
- const user = await fetchUserInfo(tokens.access_token);
1697
+ const { accessToken } = await getStoredTokens();
1698
+ if (!accessToken) throw new Error("Login succeeded but no token was stored");
1699
+ const user = await fetchUserInfo(accessToken);
1688
1700
  await chrome.storage.local.set({ [STORAGE_KEYS.user]: user });
1689
1701
  return user;
1690
1702
  }
@@ -1749,10 +1761,10 @@ async function getValidAccessToken() {
1749
1761
  return accessToken;
1750
1762
  }
1751
1763
  async function refreshAccessToken(refreshToken) {
1752
- const response = await fetch(`${IAM_BASE}/oauth/token`, {
1764
+ const response = await fetch(`${IAM_API}/api/login/oauth/access_token`, {
1753
1765
  method: "POST",
1754
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
1755
- body: new URLSearchParams({
1766
+ headers: { "Content-Type": "application/json" },
1767
+ body: JSON.stringify({
1756
1768
  grant_type: "refresh_token",
1757
1769
  client_id: CLIENT_ID,
1758
1770
  refresh_token: refreshToken
@@ -1764,7 +1776,7 @@ async function refreshAccessToken(refreshToken) {
1764
1776
  return tokens.access_token;
1765
1777
  }
1766
1778
  async function fetchUserInfo(accessToken) {
1767
- const response = await fetch(`${IAM_BASE}/oauth/userinfo`, {
1779
+ const response = await fetch(`${IAM_API}/api/userinfo`, {
1768
1780
  headers: { Authorization: `Bearer ${accessToken}` }
1769
1781
  });
1770
1782
  if (!response.ok) throw new Error("Failed to fetch user info");
@@ -1608,7 +1608,8 @@ async function generatePkceChallenge() {
1608
1608
  function generateState() {
1609
1609
  return generateRandomString(32);
1610
1610
  }
1611
- var IAM_BASE = "https://hanzo.id";
1611
+ var IAM_LOGIN = "https://hanzo.id";
1612
+ var IAM_API = "https://iam.hanzo.ai";
1612
1613
  var CLIENT_ID = "app-hanzo";
1613
1614
  var SCOPES = "openid profile email";
1614
1615
  function getRedirectUri() {
@@ -1650,7 +1651,7 @@ async function login() {
1650
1651
  const { codeVerifier, codeChallenge } = await generatePkceChallenge();
1651
1652
  const state = generateState();
1652
1653
  const redirectUri = getRedirectUri();
1653
- const authorizeUrl = new URL(`${IAM_BASE}/login/oauth/authorize`);
1654
+ const authorizeUrl = new URL(`${IAM_LOGIN}/login/oauth/authorize`);
1654
1655
  authorizeUrl.searchParams.set("client_id", CLIENT_ID);
1655
1656
  authorizeUrl.searchParams.set("response_type", "code");
1656
1657
  authorizeUrl.searchParams.set("redirect_uri", redirectUri);
@@ -1663,28 +1664,39 @@ async function login() {
1663
1664
  const returnedState = url.searchParams.get("state");
1664
1665
  if (returnedState !== state) throw new Error("State mismatch \u2014 possible CSRF");
1665
1666
  const code = url.searchParams.get("code");
1666
- if (!code) {
1667
- const error = url.searchParams.get("error_description") || url.searchParams.get("error") || "No authorization code";
1667
+ const directToken = url.searchParams.get("access_token");
1668
+ if (directToken) {
1669
+ const tokens = {
1670
+ access_token: directToken,
1671
+ refresh_token: url.searchParams.get("refresh_token") || void 0,
1672
+ token_type: "Bearer"
1673
+ };
1674
+ await storeTokens(tokens);
1675
+ } else if (code) {
1676
+ const tokenResponse = await fetch(`${IAM_API}/api/login/oauth/access_token`, {
1677
+ method: "POST",
1678
+ headers: { "Content-Type": "application/json" },
1679
+ body: JSON.stringify({
1680
+ grant_type: "authorization_code",
1681
+ client_id: CLIENT_ID,
1682
+ code,
1683
+ redirect_uri: redirectUri,
1684
+ code_verifier: codeVerifier
1685
+ })
1686
+ });
1687
+ if (!tokenResponse.ok) {
1688
+ const errText = await tokenResponse.text();
1689
+ throw new Error(`Token exchange failed: ${errText}`);
1690
+ }
1691
+ const tokens = await tokenResponse.json();
1692
+ await storeTokens(tokens);
1693
+ } else {
1694
+ const error = url.searchParams.get("error_description") || url.searchParams.get("error") || "No authorization code or token";
1668
1695
  throw new Error(error);
1669
1696
  }
1670
- const tokenResponse = await fetch(`${IAM_BASE}/oauth/token`, {
1671
- method: "POST",
1672
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
1673
- body: new URLSearchParams({
1674
- grant_type: "authorization_code",
1675
- client_id: CLIENT_ID,
1676
- code,
1677
- redirect_uri: redirectUri,
1678
- code_verifier: codeVerifier
1679
- })
1680
- });
1681
- if (!tokenResponse.ok) {
1682
- const errText = await tokenResponse.text();
1683
- throw new Error(`Token exchange failed: ${errText}`);
1684
- }
1685
- const tokens = await tokenResponse.json();
1686
- await storeTokens(tokens);
1687
- const user = await fetchUserInfo(tokens.access_token);
1697
+ const { accessToken } = await getStoredTokens();
1698
+ if (!accessToken) throw new Error("Login succeeded but no token was stored");
1699
+ const user = await fetchUserInfo(accessToken);
1688
1700
  await chrome.storage.local.set({ [STORAGE_KEYS.user]: user });
1689
1701
  return user;
1690
1702
  }
@@ -1749,10 +1761,10 @@ async function getValidAccessToken() {
1749
1761
  return accessToken;
1750
1762
  }
1751
1763
  async function refreshAccessToken(refreshToken) {
1752
- const response = await fetch(`${IAM_BASE}/oauth/token`, {
1764
+ const response = await fetch(`${IAM_API}/api/login/oauth/access_token`, {
1753
1765
  method: "POST",
1754
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
1755
- body: new URLSearchParams({
1766
+ headers: { "Content-Type": "application/json" },
1767
+ body: JSON.stringify({
1756
1768
  grant_type: "refresh_token",
1757
1769
  client_id: CLIENT_ID,
1758
1770
  refresh_token: refreshToken
@@ -1764,7 +1776,7 @@ async function refreshAccessToken(refreshToken) {
1764
1776
  return tokens.access_token;
1765
1777
  }
1766
1778
  async function fetchUserInfo(accessToken) {
1767
- const response = await fetch(`${IAM_BASE}/oauth/userinfo`, {
1779
+ const response = await fetch(`${IAM_API}/api/userinfo`, {
1768
1780
  headers: { Authorization: `Bearer ${accessToken}` }
1769
1781
  });
1770
1782
  if (!response.ok) throw new Error("Failed to fetch user info");
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "manifest_version": 3,
3
3
  "name": "Hanzo AI",
4
- "version": "1.7.5",
4
+ "version": "1.7.6",
5
5
  "description": "AI-powered dev assistant — click-to-code navigation, source maps, WebGPU AI, and MCP integration for Claude Code.",
6
6
  "permissions": [
7
7
  "activeTab",
@@ -27,7 +27,8 @@
27
27
  function generateState() {
28
28
  return generateRandomString(32);
29
29
  }
30
- var IAM_BASE = "https://hanzo.id";
30
+ var IAM_LOGIN = "https://hanzo.id";
31
+ var IAM_API = "https://iam.hanzo.ai";
31
32
  var CLIENT_ID = "app-hanzo";
32
33
  var SCOPES = "openid profile email";
33
34
  function getRedirectUri() {
@@ -69,7 +70,7 @@
69
70
  const { codeVerifier, codeChallenge } = await generatePkceChallenge();
70
71
  const state = generateState();
71
72
  const redirectUri = getRedirectUri();
72
- const authorizeUrl = new URL(`${IAM_BASE}/login/oauth/authorize`);
73
+ const authorizeUrl = new URL(`${IAM_LOGIN}/login/oauth/authorize`);
73
74
  authorizeUrl.searchParams.set("client_id", CLIENT_ID);
74
75
  authorizeUrl.searchParams.set("response_type", "code");
75
76
  authorizeUrl.searchParams.set("redirect_uri", redirectUri);
@@ -82,28 +83,39 @@
82
83
  const returnedState = url.searchParams.get("state");
83
84
  if (returnedState !== state) throw new Error("State mismatch \u2014 possible CSRF");
84
85
  const code = url.searchParams.get("code");
85
- if (!code) {
86
- const error = url.searchParams.get("error_description") || url.searchParams.get("error") || "No authorization code";
86
+ const directToken = url.searchParams.get("access_token");
87
+ if (directToken) {
88
+ const tokens = {
89
+ access_token: directToken,
90
+ refresh_token: url.searchParams.get("refresh_token") || void 0,
91
+ token_type: "Bearer"
92
+ };
93
+ await storeTokens(tokens);
94
+ } else if (code) {
95
+ const tokenResponse = await fetch(`${IAM_API}/api/login/oauth/access_token`, {
96
+ method: "POST",
97
+ headers: { "Content-Type": "application/json" },
98
+ body: JSON.stringify({
99
+ grant_type: "authorization_code",
100
+ client_id: CLIENT_ID,
101
+ code,
102
+ redirect_uri: redirectUri,
103
+ code_verifier: codeVerifier
104
+ })
105
+ });
106
+ if (!tokenResponse.ok) {
107
+ const errText = await tokenResponse.text();
108
+ throw new Error(`Token exchange failed: ${errText}`);
109
+ }
110
+ const tokens = await tokenResponse.json();
111
+ await storeTokens(tokens);
112
+ } else {
113
+ const error = url.searchParams.get("error_description") || url.searchParams.get("error") || "No authorization code or token";
87
114
  throw new Error(error);
88
115
  }
89
- const tokenResponse = await fetch(`${IAM_BASE}/oauth/token`, {
90
- method: "POST",
91
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
92
- body: new URLSearchParams({
93
- grant_type: "authorization_code",
94
- client_id: CLIENT_ID,
95
- code,
96
- redirect_uri: redirectUri,
97
- code_verifier: codeVerifier
98
- })
99
- });
100
- if (!tokenResponse.ok) {
101
- const errText = await tokenResponse.text();
102
- throw new Error(`Token exchange failed: ${errText}`);
103
- }
104
- const tokens = await tokenResponse.json();
105
- await storeTokens(tokens);
106
- const user = await fetchUserInfo(tokens.access_token);
116
+ const { accessToken } = await getStoredTokens();
117
+ if (!accessToken) throw new Error("Login succeeded but no token was stored");
118
+ const user = await fetchUserInfo(accessToken);
107
119
  await chrome.storage.local.set({ [STORAGE_KEYS.user]: user });
108
120
  return user;
109
121
  }
@@ -167,10 +179,10 @@
167
179
  return accessToken;
168
180
  }
169
181
  async function refreshAccessToken(refreshToken) {
170
- const response = await fetch(`${IAM_BASE}/oauth/token`, {
182
+ const response = await fetch(`${IAM_API}/api/login/oauth/access_token`, {
171
183
  method: "POST",
172
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
173
- body: new URLSearchParams({
184
+ headers: { "Content-Type": "application/json" },
185
+ body: JSON.stringify({
174
186
  grant_type: "refresh_token",
175
187
  client_id: CLIENT_ID,
176
188
  refresh_token: refreshToken
@@ -182,7 +194,7 @@
182
194
  return tokens.access_token;
183
195
  }
184
196
  async function fetchUserInfo(accessToken) {
185
- const response = await fetch(`${IAM_BASE}/oauth/userinfo`, {
197
+ const response = await fetch(`${IAM_API}/api/userinfo`, {
186
198
  headers: { Authorization: `Bearer ${accessToken}` }
187
199
  });
188
200
  if (!response.ok) throw new Error("Failed to fetch user info");
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "manifest_version": 3,
3
3
  "name": "Hanzo AI",
4
- "version": "1.7.5",
4
+ "version": "1.7.6",
5
5
  "description": "AI-powered dev assistant — click-to-code navigation, source maps, WebGPU AI, and MCP integration for Claude Code.",
6
6
  "permissions": [
7
7
  "activeTab",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "manifest_version": 3,
3
3
  "name": "Hanzo AI",
4
- "version": "1.7.5",
4
+ "version": "1.7.6",
5
5
  "description": "AI-powered dev assistant — click-to-code navigation, source maps, WebGPU AI, and MCP integration for Claude Code.",
6
6
  "permissions": [
7
7
  "activeTab",
@@ -1608,7 +1608,8 @@ async function generatePkceChallenge() {
1608
1608
  function generateState() {
1609
1609
  return generateRandomString(32);
1610
1610
  }
1611
- var IAM_BASE = "https://hanzo.id";
1611
+ var IAM_LOGIN = "https://hanzo.id";
1612
+ var IAM_API = "https://iam.hanzo.ai";
1612
1613
  var CLIENT_ID = "app-hanzo";
1613
1614
  var SCOPES = "openid profile email";
1614
1615
  function getRedirectUri() {
@@ -1650,7 +1651,7 @@ async function login() {
1650
1651
  const { codeVerifier, codeChallenge } = await generatePkceChallenge();
1651
1652
  const state = generateState();
1652
1653
  const redirectUri = getRedirectUri();
1653
- const authorizeUrl = new URL(`${IAM_BASE}/login/oauth/authorize`);
1654
+ const authorizeUrl = new URL(`${IAM_LOGIN}/login/oauth/authorize`);
1654
1655
  authorizeUrl.searchParams.set("client_id", CLIENT_ID);
1655
1656
  authorizeUrl.searchParams.set("response_type", "code");
1656
1657
  authorizeUrl.searchParams.set("redirect_uri", redirectUri);
@@ -1663,28 +1664,39 @@ async function login() {
1663
1664
  const returnedState = url.searchParams.get("state");
1664
1665
  if (returnedState !== state) throw new Error("State mismatch \u2014 possible CSRF");
1665
1666
  const code = url.searchParams.get("code");
1666
- if (!code) {
1667
- const error = url.searchParams.get("error_description") || url.searchParams.get("error") || "No authorization code";
1667
+ const directToken = url.searchParams.get("access_token");
1668
+ if (directToken) {
1669
+ const tokens = {
1670
+ access_token: directToken,
1671
+ refresh_token: url.searchParams.get("refresh_token") || void 0,
1672
+ token_type: "Bearer"
1673
+ };
1674
+ await storeTokens(tokens);
1675
+ } else if (code) {
1676
+ const tokenResponse = await fetch(`${IAM_API}/api/login/oauth/access_token`, {
1677
+ method: "POST",
1678
+ headers: { "Content-Type": "application/json" },
1679
+ body: JSON.stringify({
1680
+ grant_type: "authorization_code",
1681
+ client_id: CLIENT_ID,
1682
+ code,
1683
+ redirect_uri: redirectUri,
1684
+ code_verifier: codeVerifier
1685
+ })
1686
+ });
1687
+ if (!tokenResponse.ok) {
1688
+ const errText = await tokenResponse.text();
1689
+ throw new Error(`Token exchange failed: ${errText}`);
1690
+ }
1691
+ const tokens = await tokenResponse.json();
1692
+ await storeTokens(tokens);
1693
+ } else {
1694
+ const error = url.searchParams.get("error_description") || url.searchParams.get("error") || "No authorization code or token";
1668
1695
  throw new Error(error);
1669
1696
  }
1670
- const tokenResponse = await fetch(`${IAM_BASE}/oauth/token`, {
1671
- method: "POST",
1672
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
1673
- body: new URLSearchParams({
1674
- grant_type: "authorization_code",
1675
- client_id: CLIENT_ID,
1676
- code,
1677
- redirect_uri: redirectUri,
1678
- code_verifier: codeVerifier
1679
- })
1680
- });
1681
- if (!tokenResponse.ok) {
1682
- const errText = await tokenResponse.text();
1683
- throw new Error(`Token exchange failed: ${errText}`);
1684
- }
1685
- const tokens = await tokenResponse.json();
1686
- await storeTokens(tokens);
1687
- const user = await fetchUserInfo(tokens.access_token);
1697
+ const { accessToken } = await getStoredTokens();
1698
+ if (!accessToken) throw new Error("Login succeeded but no token was stored");
1699
+ const user = await fetchUserInfo(accessToken);
1688
1700
  await chrome.storage.local.set({ [STORAGE_KEYS.user]: user });
1689
1701
  return user;
1690
1702
  }
@@ -1749,10 +1761,10 @@ async function getValidAccessToken() {
1749
1761
  return accessToken;
1750
1762
  }
1751
1763
  async function refreshAccessToken(refreshToken) {
1752
- const response = await fetch(`${IAM_BASE}/oauth/token`, {
1764
+ const response = await fetch(`${IAM_API}/api/login/oauth/access_token`, {
1753
1765
  method: "POST",
1754
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
1755
- body: new URLSearchParams({
1766
+ headers: { "Content-Type": "application/json" },
1767
+ body: JSON.stringify({
1756
1768
  grant_type: "refresh_token",
1757
1769
  client_id: CLIENT_ID,
1758
1770
  refresh_token: refreshToken
@@ -1764,7 +1776,7 @@ async function refreshAccessToken(refreshToken) {
1764
1776
  return tokens.access_token;
1765
1777
  }
1766
1778
  async function fetchUserInfo(accessToken) {
1767
- const response = await fetch(`${IAM_BASE}/oauth/userinfo`, {
1779
+ const response = await fetch(`${IAM_API}/api/userinfo`, {
1768
1780
  headers: { Authorization: `Bearer ${accessToken}` }
1769
1781
  });
1770
1782
  if (!response.ok) throw new Error("Failed to fetch user info");