Browse Source

block localhost on repo announcements

need tor or a public domain
main
Silberengel 4 weeks ago
parent
commit
f356a34800
  1. 38
      src/routes/api/repos/[npub]/[repo]/fork/+server.ts
  2. 38
      src/routes/api/repos/[npub]/[repo]/settings/+server.ts
  3. 51
      src/routes/signup/+page.svelte

38
src/routes/api/repos/[npub]/[repo]/fork/+server.ts

@ -179,14 +179,25 @@ export const POST: RequestHandler = async ({ params, request }) => {
// Create fork announcement // Create fork announcement
const gitDomain = process.env.GIT_DOMAIN || 'localhost:6543'; const gitDomain = process.env.GIT_DOMAIN || 'localhost:6543';
const protocol = gitDomain.startsWith('localhost') ? 'http' : 'https'; const isLocalhost = gitDomain.startsWith('localhost') || gitDomain.startsWith('127.0.0.1');
const protocol = isLocalhost ? 'http' : 'https';
const forkGitUrl = `${protocol}://${gitDomain}/${userNpub}/${forkRepoName}.git`; const forkGitUrl = `${protocol}://${gitDomain}/${userNpub}/${forkRepoName}.git`;
// Get Tor .onion URL if available
const { getTorGitUrl } = await import('$lib/services/tor/hidden-service.js');
const torOnionUrl = await getTorGitUrl(userNpub, forkRepoName);
// Extract original clone URLs and earliest unique commit // Extract original clone URLs and earliest unique commit
const originalCloneUrls = originalAnnouncement.tags const originalCloneUrls = originalAnnouncement.tags
.filter(t => t[0] === 'clone') .filter(t => t[0] === 'clone')
.flatMap(t => t.slice(1)) .flatMap(t => t.slice(1))
.filter(url => url && typeof url === 'string') as string[]; .filter(url => url && typeof url === 'string')
.filter(url => {
// Exclude our domain and .onion URLs (we'll add our own if available)
if (url.includes(gitDomain)) return false;
if (url.includes('.onion')) return false;
return true;
}) as string[];
const earliestCommitTag = originalAnnouncement.tags.find(t => t[0] === 'r' && t[2] === 'euc'); const earliestCommitTag = originalAnnouncement.tags.find(t => t[0] === 'r' && t[2] === 'euc');
const earliestCommit = earliestCommitTag?.[1]; const earliestCommit = earliestCommitTag?.[1];
@ -195,12 +206,33 @@ export const POST: RequestHandler = async ({ params, request }) => {
const originalName = originalAnnouncement.tags.find(t => t[0] === 'name')?.[1] || repo; const originalName = originalAnnouncement.tags.find(t => t[0] === 'name')?.[1] || repo;
const originalDescription = originalAnnouncement.tags.find(t => t[0] === 'description')?.[1] || ''; const originalDescription = originalAnnouncement.tags.find(t => t[0] === 'description')?.[1] || '';
// Build clone URLs for fork - NEVER include localhost, only include public domain or Tor .onion
const forkCloneUrls: string[] = [];
// Add our domain URL only if it's NOT localhost (explicitly check the URL)
if (!isLocalhost && !forkGitUrl.includes('localhost') && !forkGitUrl.includes('127.0.0.1')) {
forkCloneUrls.push(forkGitUrl);
}
// Add Tor .onion URL if available
if (torOnionUrl) {
forkCloneUrls.push(torOnionUrl);
}
// Add original clone URLs
forkCloneUrls.push(...originalCloneUrls);
// Validate: If using localhost, require either Tor .onion URL or at least one other clone URL
if (isLocalhost && !torOnionUrl && originalCloneUrls.length === 0) {
return error(400, 'Cannot create fork with only localhost. The original repository must have at least one public clone URL, or you need to configure a Tor .onion address.');
}
// Build fork announcement tags // Build fork announcement tags
const tags: string[][] = [ const tags: string[][] = [
['d', forkRepoName], ['d', forkRepoName],
['name', `${originalName} (fork)`], ['name', `${originalName} (fork)`],
['description', `Fork of ${originalName}${originalDescription ? `: ${originalDescription}` : ''}`], ['description', `Fork of ${originalName}${originalDescription ? `: ${originalDescription}` : ''}`],
['clone', forkGitUrl, ...originalCloneUrls.filter(url => !url.includes(gitDomain))], ['clone', ...forkCloneUrls],
['relays', ...DEFAULT_NOSTR_RELAYS], ['relays', ...DEFAULT_NOSTR_RELAYS],
['t', 'fork'], // Mark as fork ['t', 'fork'], // Mark as fork
['a', `${KIND.REPO_ANNOUNCEMENT}:${originalOwnerPubkey}:${repo}`], // Reference to original repo ['a', `${KIND.REPO_ANNOUNCEMENT}:${originalOwnerPubkey}:${repo}`], // Reference to original repo

38
src/routes/api/repos/[npub]/[repo]/settings/+server.ts

@ -171,19 +171,43 @@ export const POST: RequestHandler = async ({ params, request }) => {
// Build updated tags // Build updated tags
const gitDomain = process.env.GIT_DOMAIN || 'localhost:6543'; const gitDomain = process.env.GIT_DOMAIN || 'localhost:6543';
const protocol = gitDomain.startsWith('localhost') ? 'http' : 'https'; const isLocalhost = gitDomain.startsWith('localhost') || gitDomain.startsWith('127.0.0.1');
const protocol = isLocalhost ? 'http' : 'https';
const gitUrl = `${protocol}://${gitDomain}/${npub}/${repo}.git`; const gitUrl = `${protocol}://${gitDomain}/${npub}/${repo}.git`;
// Get Tor .onion URL if available // Get Tor .onion URL if available
const { getTorGitUrl } = await import('$lib/services/tor/hidden-service.js'); const { getTorGitUrl } = await import('$lib/services/tor/hidden-service.js');
const torOnionUrl = await getTorGitUrl(npub, repo); const torOnionUrl = await getTorGitUrl(npub, repo);
// Build clone URLs - include regular domain and Tor .onion if available // Filter user-provided clone URLs (exclude localhost and .onion duplicates)
const cloneUrlList = [ const userCloneUrls = (cloneUrls || []).filter((url: string) => {
gitUrl, if (!url || !url.trim()) return false;
...(torOnionUrl ? [torOnionUrl] : []), // Exclude if it's our domain or already a .onion
...(cloneUrls || []).filter((url: string) => url && !url.includes(gitDomain) && !url.includes('.onion')) if (url.includes(gitDomain)) return false;
]; if (url.includes('.onion')) return false;
return true;
});
// Build clone URLs - NEVER include localhost, only include public domain or Tor .onion
const cloneUrlList: string[] = [];
// Add our domain URL only if it's NOT localhost (explicitly check the URL)
if (!isLocalhost && !gitUrl.includes('localhost') && !gitUrl.includes('127.0.0.1')) {
cloneUrlList.push(gitUrl);
}
// Add Tor .onion URL if available (always useful, even with localhost)
if (torOnionUrl) {
cloneUrlList.push(torOnionUrl);
}
// Add user-provided clone URLs
cloneUrlList.push(...userCloneUrls);
// Validate: If using localhost, require either Tor .onion URL or at least one other clone URL
if (isLocalhost && !torOnionUrl && userCloneUrls.length === 0) {
return error(400, 'Cannot update with only localhost. You need either a Tor .onion address or at least one other clone URL.');
}
const tags: string[][] = [ const tags: string[][] = [
['d', repo], ['d', repo],

51
src/routes/signup/+page.svelte

@ -879,7 +879,8 @@
// Get git domain from layout data // Get git domain from layout data
const gitDomain = $page.data.gitDomain || 'localhost:6543'; const gitDomain = $page.data.gitDomain || 'localhost:6543';
const protocol = gitDomain.startsWith('localhost') ? 'http' : 'https'; const isLocalhost = gitDomain.startsWith('localhost') || gitDomain.startsWith('127.0.0.1');
const protocol = isLocalhost ? 'http' : 'https';
const gitUrl = `${protocol}://${gitDomain}/${npub}/${dTag}.git`; const gitUrl = `${protocol}://${gitDomain}/${npub}/${dTag}.git`;
// Try to get Tor .onion address and add it to clone URLs // Try to get Tor .onion address and add it to clone URLs
@ -896,12 +897,40 @@
// Tor not available, continue without it // Tor not available, continue without it
} }
// Build clone URLs - always include our domain, and Tor .onion if available // Filter user-provided clone URLs (exclude localhost and .onion duplicates)
const allCloneUrls = [ const userCloneUrls = cloneUrls.filter(url => {
gitUrl, const trimmed = url.trim();
...(torOnionUrl ? [torOnionUrl] : []), // Add Tor .onion URL if available if (!trimmed) return false;
...cloneUrls.filter(url => url.trim() && !url.includes(gitDomain) && !url.includes('.onion')) // Exclude if it's our domain or already a .onion
]; if (trimmed.includes(gitDomain)) return false;
if (trimmed.includes('.onion')) return false;
return true;
});
// Validate: If using localhost, require either Tor .onion URL or at least one other clone URL
if (isLocalhost && !torOnionUrl && userCloneUrls.length === 0) {
error = 'Cannot publish with only localhost. You need either:\n' +
'• A Tor .onion address (configure Tor hidden service and set TOR_ONION_ADDRESS)\n' +
'• At least one other clone URL (e.g., GitHub, GitLab, or another GitRepublic instance)';
loading = false;
return;
}
// Build clone URLs - NEVER include localhost, only include public domain or Tor .onion
const allCloneUrls: string[] = [];
// Add our domain URL only if it's NOT localhost (explicitly check the URL)
if (!isLocalhost && !gitUrl.includes('localhost') && !gitUrl.includes('127.0.0.1')) {
allCloneUrls.push(gitUrl);
}
// Add Tor .onion URL if available (always useful, even with localhost)
if (torOnionUrl) {
allCloneUrls.push(torOnionUrl);
}
// Add user-provided clone URLs
allCloneUrls.push(...userCloneUrls);
// Build web URLs // Build web URLs
const allWebUrls = webUrls.filter(url => url.trim()); const allWebUrls = webUrls.filter(url => url.trim());
@ -1264,7 +1293,13 @@
<div class="form-group"> <div class="form-group">
<div class="label"> <div class="label">
Clone URLs Clone URLs
<small>{$page.data.gitDomain || 'localhost:6543'} will be added automatically, but you can add any existing ones here.</small> <small>
{#if ($page.data.gitDomain || 'localhost:6543').startsWith('localhost') || ($page.data.gitDomain || 'localhost:6543').startsWith('127.0.0.1')}
<strong>Note:</strong> Your server is using localhost, which won't work for others. You must add at least one public clone URL (e.g., GitHub, GitLab) or configure a Tor .onion address.
{:else}
{$page.data.gitDomain || 'localhost:6543'} will be added automatically, but you can add any existing ones here.
{/if}
</small>
</div> </div>
{#each cloneUrls as url, index} {#each cloneUrls as url, index}
<div class="input-group"> <div class="input-group">

Loading…
Cancel
Save