@agent-relay/dashboard-server 2.0.71 → 2.0.73
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/server.js +19 -2
- package/dist/server.js.map +1 -1
- package/out/404.html +1 -1
- package/out/_next/static/chunks/285-57ccd3043914acb2.js +1 -0
- package/out/about.html +1 -1
- package/out/about.txt +1 -1
- package/out/app/onboarding.html +1 -1
- package/out/app/onboarding.txt +1 -1
- package/out/app.html +1 -1
- package/out/app.txt +2 -2
- package/out/blog/go-to-bed-wake-up-to-a-finished-product.html +1 -1
- package/out/blog/go-to-bed-wake-up-to-a-finished-product.txt +1 -1
- package/out/blog/let-them-cook-multi-agent-orchestration.html +1 -1
- package/out/blog/let-them-cook-multi-agent-orchestration.txt +1 -1
- package/out/blog.html +1 -1
- package/out/blog.txt +1 -1
- package/out/careers.html +1 -1
- package/out/careers.txt +1 -1
- package/out/changelog.html +1 -1
- package/out/changelog.txt +1 -1
- package/out/cloud/link.html +1 -1
- package/out/cloud/link.txt +1 -1
- package/out/complete-profile.html +1 -1
- package/out/complete-profile.txt +1 -1
- package/out/connect-repos.html +1 -1
- package/out/connect-repos.txt +1 -1
- package/out/contact.html +1 -1
- package/out/contact.txt +1 -1
- package/out/docs.html +1 -1
- package/out/docs.txt +1 -1
- package/out/history.html +1 -1
- package/out/history.txt +1 -1
- package/out/index.html +1 -1
- package/out/index.txt +2 -2
- package/out/login.html +1 -1
- package/out/login.txt +1 -1
- package/out/metrics.html +1 -1
- package/out/metrics.txt +1 -1
- package/out/pricing.html +1 -1
- package/out/pricing.txt +1 -1
- package/out/privacy.html +1 -1
- package/out/privacy.txt +1 -1
- package/out/providers/setup/claude.html +1 -1
- package/out/providers/setup/claude.txt +1 -1
- package/out/providers/setup/codex.html +1 -1
- package/out/providers/setup/codex.txt +1 -1
- package/out/providers/setup/cursor.html +1 -1
- package/out/providers/setup/cursor.txt +1 -1
- package/out/providers.html +1 -1
- package/out/providers.txt +1 -1
- package/out/security.html +1 -1
- package/out/security.txt +1 -1
- package/out/signup.html +1 -1
- package/out/signup.txt +1 -1
- package/out/terms.html +1 -1
- package/out/terms.txt +1 -1
- package/package.json +1 -1
- package/out/_next/static/chunks/285-52fb0aee5b6b90a6.js +0 -1
- /package/out/_next/static/{4b3iV9SX2_ON0klS0h-1g → CVQXstfbl09Ow0ERYIWu4}/_buildManifest.js +0 -0
- /package/out/_next/static/{4b3iV9SX2_ON0klS0h-1g → CVQXstfbl09Ow0ERYIWu4}/_ssgManifest.js +0 -0
package/dist/server.js
CHANGED
|
@@ -4815,10 +4815,22 @@ export async function startDashboard(portOrOptions, dataDirArg, teamDirArg, dbPa
|
|
|
4815
4815
|
const repoName = fullName.split('/').pop();
|
|
4816
4816
|
const workspaceDir = process.env.WORKSPACE_DIR || path.dirname(projectRoot || dataDir);
|
|
4817
4817
|
const targetDir = path.join(workspaceDir, repoName);
|
|
4818
|
-
//
|
|
4819
|
-
|
|
4818
|
+
// Prevent path traversal (e.g., repoName = ".." or ".")
|
|
4819
|
+
const resolvedTarget = path.resolve(targetDir);
|
|
4820
|
+
const resolvedWorkspace = path.resolve(workspaceDir);
|
|
4821
|
+
if (!resolvedTarget.startsWith(resolvedWorkspace + path.sep)) {
|
|
4822
|
+
return res.status(400).json({ success: false, error: 'Invalid path' });
|
|
4823
|
+
}
|
|
4824
|
+
// Idempotent: skip if already cloned (check for .git to avoid false positives
|
|
4825
|
+
// from empty directories left behind by previous failed clone attempts)
|
|
4826
|
+
if (fs.existsSync(path.join(targetDir, '.git'))) {
|
|
4820
4827
|
return res.json({ success: true, message: 'Already cloned', path: targetDir });
|
|
4821
4828
|
}
|
|
4829
|
+
// Clean up stale directory from a previous failed clone (no .git = incomplete)
|
|
4830
|
+
if (fs.existsSync(targetDir)) {
|
|
4831
|
+
console.log(`[api/repos/clone] Removing stale directory ${targetDir} (no .git found)`);
|
|
4832
|
+
fs.rmSync(targetDir, { recursive: true, force: true });
|
|
4833
|
+
}
|
|
4822
4834
|
// Use plain HTTPS URL - git credential helper handles authentication.
|
|
4823
4835
|
// The credential helper (git-credential-relay) fetches per-repo tokens from
|
|
4824
4836
|
// the cloud API, which correctly resolves installation tokens for private repos.
|
|
@@ -4842,6 +4854,11 @@ export async function startDashboard(portOrOptions, dataDirArg, teamDirArg, dbPa
|
|
|
4842
4854
|
catch (err) {
|
|
4843
4855
|
const safeMessage = (err.message || 'Clone failed');
|
|
4844
4856
|
console.error('[api/repos/clone] Clone failed:', safeMessage);
|
|
4857
|
+
// Clean up failed clone directory so future attempts aren't blocked
|
|
4858
|
+
try {
|
|
4859
|
+
fs.rmSync(targetDir, { recursive: true, force: true });
|
|
4860
|
+
}
|
|
4861
|
+
catch { /* ignore */ }
|
|
4845
4862
|
res.status(500).json({ success: false, error: safeMessage });
|
|
4846
4863
|
}
|
|
4847
4864
|
});
|