@openfort/cli 0.1.10 → 0.1.12

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 (2) hide show
  1. package/dist/cli.js +69 -17
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -163,20 +163,55 @@ function callbackPage(title, description, variant = "success", extraHtml = "") {
163
163
  </body>
164
164
  </html>`;
165
165
  }
166
+ function fragmentBridgePage(port) {
167
+ return `<!DOCTYPE html>
168
+ <html lang="en">
169
+ <head>
170
+ <meta charset="UTF-8">
171
+ <title>Openfort CLI - Authenticating...</title>
172
+ <style>
173
+ body { font-family: system-ui, sans-serif; display: flex; align-items: center; justify-content: center; min-height: 100vh; margin: 0; background: #fafafa; }
174
+ @media (prefers-color-scheme: dark) { body { background: #111; color: #eee; } }
175
+ p { font-size: 0.875rem; color: #888; }
176
+ </style>
177
+ </head>
178
+ <body>
179
+ <p>Completing authentication...</p>
180
+ <script>
181
+ (function() {
182
+ var hash = window.location.hash.substring(1);
183
+ if (!hash) {
184
+ document.querySelector('p').textContent = 'Authentication failed: no credentials received.';
185
+ return;
186
+ }
187
+ // Clear the fragment from the URL immediately to minimize exposure
188
+ history.replaceState(null, '', window.location.pathname);
189
+ fetch('http://localhost:${port}/callback/complete', {
190
+ method: 'POST',
191
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
192
+ body: hash
193
+ }).then(function(r) { return r.text(); }).then(function(html) {
194
+ document.open();
195
+ document.write(html);
196
+ document.close();
197
+ }).catch(function() {
198
+ document.querySelector('p').textContent = 'Failed to complete authentication. Please try again.';
199
+ });
200
+ })();
201
+ </script>
202
+ </body>
203
+ </html>`;
204
+ }
166
205
  function waitForCallback(port, state) {
167
206
  return new Promise((resolve, reject) => {
168
207
  const timeout = setTimeout(() => {
169
208
  server.close();
209
+ server.closeAllConnections();
170
210
  reject(new Error("Login timed out after 5 minutes. Please try again."));
171
211
  }, 5 * 60 * 1e3);
172
212
  const server = createServer((req, res) => {
173
213
  const url = new URL(req.url ?? "/", `http://localhost:${port}`);
174
- if (url.pathname === "/callback") {
175
- const apiKey = url.searchParams.get("api_key");
176
- const publishableKey = url.searchParams.get("publishable_key");
177
- const projectId = url.searchParams.get("project_id");
178
- const project = url.searchParams.get("project");
179
- const returnedState = url.searchParams.get("state");
214
+ if (url.pathname === "/callback" && req.method === "GET") {
180
215
  const error = url.searchParams.get("error");
181
216
  const errorDescription = url.searchParams.get("error_description");
182
217
  if (error) {
@@ -184,17 +219,32 @@ function waitForCallback(port, state) {
184
219
  res.end(callbackPage("Login failed", "Something went wrong. You can close this window.", "error"));
185
220
  clearTimeout(timeout);
186
221
  server.close();
222
+ server.closeAllConnections();
187
223
  reject(new Error(errorDescription || error));
188
224
  return;
189
225
  }
190
- if (!apiKey || returnedState !== state) {
191
- res.writeHead(400, { "Content-Type": "text/html" });
192
- res.end(callbackPage("Invalid callback", "Missing API key or state mismatch. Please try logging in again.", "error"));
193
- return;
194
- }
195
226
  res.writeHead(200, { "Content-Type": "text/html" });
196
- const skillCommand = "npx skills add openfort-xyz/agent-skills --skill openfort";
197
- const agentSkillHtml = `
227
+ res.end(fragmentBridgePage(port));
228
+ } else if (url.pathname === "/callback/complete" && req.method === "POST") {
229
+ let body = "";
230
+ req.on("data", (chunk) => {
231
+ body += chunk.toString();
232
+ });
233
+ req.on("end", () => {
234
+ const params = new URLSearchParams(body);
235
+ const apiKey = params.get("api_key");
236
+ const publishableKey = params.get("publishable_key");
237
+ const projectId = params.get("project_id");
238
+ const project = params.get("project");
239
+ const returnedState = params.get("state");
240
+ if (!apiKey || returnedState !== state) {
241
+ res.writeHead(400, { "Content-Type": "text/html" });
242
+ res.end(callbackPage("Invalid callback", "Missing API key or state mismatch. Please try logging in again.", "error"));
243
+ return;
244
+ }
245
+ res.writeHead(200, { "Content-Type": "text/html" });
246
+ const skillCommand = "npx skills add openfort-xyz/agent-skills --skill openfort";
247
+ const agentSkillHtml = `
198
248
  <div class="card-extra">
199
249
  <p class="card-extra-title">Build with AI? Add the Openfort skill:</p>
200
250
  <div class="code-block">
@@ -203,10 +253,12 @@ function waitForCallback(port, state) {
203
253
  </div>
204
254
  <a class="card-extra-link" href="https://www.openfort.io/docs/overview/building-with-cli" target="_blank" rel="noopener noreferrer">Learn more about building with the CLI</a>
205
255
  </div>`;
206
- res.end(callbackPage("Login successful!", "You can close this window and return to your terminal.", "success", agentSkillHtml));
207
- clearTimeout(timeout);
208
- server.close();
209
- resolve({ apiKey, publishableKey: publishableKey || void 0, projectId: projectId || void 0, project: project || "unknown" });
256
+ res.end(callbackPage("Login successful!", "You can close this window and return to your terminal.", "success", agentSkillHtml));
257
+ clearTimeout(timeout);
258
+ server.close();
259
+ server.closeAllConnections();
260
+ resolve({ apiKey, publishableKey: publishableKey || void 0, projectId: projectId || void 0, project: project || "unknown" });
261
+ });
210
262
  } else {
211
263
  res.writeHead(404);
212
264
  res.end();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openfort/cli",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "description": "Openfort CLI — manage wallets, policies, and transactions from the terminal.",
5
5
  "author": "Openfort (https://www.openfort.io)",
6
6
  "bugs": "https://github.com/openfort-xyz/cli/issues",