Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/web.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const TYPES: Record<string, string> = {
};

export const PAGE_CSP =
"default-src 'self'; script-src 'self' https://crawlproof.com; style-src 'self'; img-src 'self' data: https:; connect-src 'self' https://crawlproof.com; font-src 'self'; frame-ancestors 'none'; base-uri 'none'; form-action 'self' http://127.0.0.1:* http://localhost:*";
"default-src 'self'; script-src 'self' https://crawlproof.com; style-src 'self'; img-src 'self' data: https:; connect-src 'self' https://crawlproof.com; font-src 'self'; frame-src https://crawlproof.com; frame-ancestors 'none'; base-uri 'none'; form-action 'self' http://127.0.0.1:* http://localhost:*";

export interface WebOptions {
mailer: Mailer;
Expand Down
1 change: 1 addition & 0 deletions test/web.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ describe('pages', () => {
const res = await req('GET', '/');
expect(res.status).toBe(200);
expect(res.headers.get('content-security-policy')).toContain("script-src 'self'");
expect(res.headers.get('content-security-policy')).toContain('frame-src https://crawlproof.com');
// no-referrer makes browsers send Origin: null on same-site form posts, which breaks the consent form.
expect(res.headers.get('referrer-policy')).toBe('same-origin');
const html = await res.text();
Expand Down
2 changes: 2 additions & 0 deletions web/assets/site.css
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ section.block .sub { color: var(--fg-2); max-width: 60ch; font-size: 17px; margi
.cta-band h2 { margin: 0; color: var(--bg); }
.cta-band p { margin: 6px 0 0; color: color-mix(in srgb, var(--bg) 75%, transparent); }
.cta-band .btn.primary { background: var(--bg); color: var(--fg); border-color: var(--bg); }
.cp-ad { margin-top: 8px; margin-bottom: 24px; }
.cp-ad iframe { display: block; width: 100%; height: 40px; border: 0; }
footer.site { border-top: 1px solid var(--line); padding: 28px 0 40px; color: var(--muted); font-size: 13.5px; }
footer.site .wrap { display: flex; flex-wrap: wrap; gap: 16px; justify-content: space-between; }
footer.site a { color: var(--fg-2); text-decoration: none; margin-right: 14px; }
Expand Down
6 changes: 6 additions & 0 deletions web/docs.html
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ <h2>Self-hosting</h2>
<p>SubmitFleet is MIT-licensed. <code>npm i -g @profullstack/submitfleet</code>, then <code>submitfleet serve</code> runs the app, API, MCP and workers in one process on SQLite (or Turso). Source and issues: <a href="https://github.com/profullstack/submitfleet">github.com/profullstack/submitfleet</a>.</p>
</section>
</main>

<!-- CrawlProof sponsored line: a script-free cross-origin frame (the page CSP
forbids inline styles, which ad.js's srcdoc creative needs). text_link is
the one fluid format and carries its own "Sponsored" mark. -->
<aside class="cp-ad wrap" aria-label="Advertisement"><iframe src="https://crawlproof.com/api/ads/frame?slot=a03e3686-cb16-4b4c-bf87-c6526991b219&amp;format=text_link" title="Advertisement" height="40" loading="lazy" scrolling="no" sandbox="allow-popups allow-popups-to-escape-sandbox allow-top-navigation-by-user-activation"></iframe></aside>

<footer class="site"><div class="wrap"><span>漏 2026 Profullstack, Inc.</span><span><a href="/">Home</a><a href="https://github.com/profullstack/submitfleet">GitHub</a></span></div></footer>
</body>
</html>
5 changes: 5 additions & 0 deletions web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ <h2>What is in the catalog</h2>
</section>
</main>

<!-- CrawlProof sponsored line: a script-free cross-origin frame (the page CSP
forbids inline styles, which ad.js's srcdoc creative needs). text_link is
the one fluid format and carries its own "Sponsored" mark. -->
<aside class="cp-ad wrap" aria-label="Advertisement"><iframe src="https://crawlproof.com/api/ads/frame?slot=a03e3686-cb16-4b4c-bf87-c6526991b219&amp;format=text_link" title="Advertisement" height="40" loading="lazy" scrolling="no" sandbox="allow-popups allow-popups-to-escape-sandbox allow-top-navigation-by-user-activation"></iframe></aside>

<footer class="site">
<div class="wrap">
<span>漏 2026 Profullstack, Inc.</span>
Expand Down
Loading