<feed xmlns='http://www.w3.org/2005/Atom'>
<title>progmaweb, branch ops/git-mirrors</title>
<subtitle>The site and account service of Progmasoft: a Next.js frontend and an ASP.NET Core API.</subtitle>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/progmaweb/'/>
<entry>
<title>Add read-only Git mirrors on git.progmasoft.com</title>
<updated>2026-11-12T20:41:27+00:00</updated>
<author>
<name>Leitwolf11</name>
</author>
<published>2026-11-12T20:41:27+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/progmaweb/commit/?id=83e0ad4586d90bf02c3a5bfeb1ab92fd90e51703'/>
<id>83e0ad4586d90bf02c3a5bfeb1ab92fd90e51703</id>
<content type='text'>
git.progmasoft.com shows the public repositories under development
(tazel, tazelish, tazel.net, catch3, progmasoft-cpp, progmaweb, website)
as read-only mirrors with cgit, and serves clones over smart HTTP, such
as git clone https://git.progmasoft.com/tazel. GitHub stays where
development happens; private and archived repositories are not mirrored.

ops/git holds what runs on the server:

- cgitrc, the header, footer and stylesheet: the look of progmasoft.com
  (its tokens, the four-tile brand with "Git" beside it, the dark
  footer), light like its default, no scripts, no rendered READMEs.
- git-mirror.sh with git-mirror.service/.timer: every ten minutes, as
  gitmirror, branches and tags only from GitHub, pruned, the default
  branch followed, repacked with a bitmap when something changed.
- fcgiwrap@cgit drop-ins: cgit and git-http-backend run as cgit with
  systemd sandboxing (no network, read-only system, exposure 0.7), on
  a socket only nginx can open.
- selinux/progmasoft_cgit.te: fcgiwrap runs in httpd_t and the two
  CGIs move into git_script_t; the module allows only that move under
  the NoNewPrivileges that the sandboxing sets.
- nginx/git.conf: HSTS, a content security policy without scripts,
  per-address request and connection limits, 403 for receive-pack and
  the dumb protocol, buffered clones, and the inline handlers of cgit's
  menus removed.

ops/README.md describes the files, the labels, and why the name is not
behind the Cloudflare proxy: through it a clone of catch3 never reached
the client.

Deployed and checked live: every page answers 200, unknown ones 404,
full clones of tazel, progmaweb and catch3 work, a push answers 403,
no SELinux denials, no console errors, no horizontal scroll at 390 px.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
git.progmasoft.com shows the public repositories under development
(tazel, tazelish, tazel.net, catch3, progmasoft-cpp, progmaweb, website)
as read-only mirrors with cgit, and serves clones over smart HTTP, such
as git clone https://git.progmasoft.com/tazel. GitHub stays where
development happens; private and archived repositories are not mirrored.

ops/git holds what runs on the server:

- cgitrc, the header, footer and stylesheet: the look of progmasoft.com
  (its tokens, the four-tile brand with "Git" beside it, the dark
  footer), light like its default, no scripts, no rendered READMEs.
- git-mirror.sh with git-mirror.service/.timer: every ten minutes, as
  gitmirror, branches and tags only from GitHub, pruned, the default
  branch followed, repacked with a bitmap when something changed.
- fcgiwrap@cgit drop-ins: cgit and git-http-backend run as cgit with
  systemd sandboxing (no network, read-only system, exposure 0.7), on
  a socket only nginx can open.
- selinux/progmasoft_cgit.te: fcgiwrap runs in httpd_t and the two
  CGIs move into git_script_t; the module allows only that move under
  the NoNewPrivileges that the sandboxing sets.
- nginx/git.conf: HSTS, a content security policy without scripts,
  per-address request and connection limits, 403 for receive-pack and
  the dumb protocol, buffered clones, and the inline handlers of cgit's
  menus removed.

ops/README.md describes the files, the labels, and why the name is not
behind the Cloudflare proxy: through it a clone of catch3 never reached
the client.

Deployed and checked live: every page answers 200, unknown ones 404,
full clones of tazel, progmaweb and catch3 work, a push answers 403,
no SELinux denials, no console errors, no horizontal scroll at 390 px.
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge pull request #61 from Progmasoft/security/cloudflare-real-ip</title>
<updated>2026-11-09T21:44:57+00:00</updated>
<author>
<name>Leitwolf</name>
</author>
<published>2026-11-09T21:44:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/progmaweb/commit/?id=80d46cbffc87da9bf2665935e563ab556c1a267d'/>
<id>80d46cbffc87da9bf2665935e563ab556c1a267d</id>
<content type='text'>
Rate-limit sign-in by visitor behind Cloudflare and stop forwarding h2c</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Rate-limit sign-in by visitor behind Cloudflare and stop forwarding h2c</pre>
</div>
</content>
</entry>
<entry>
<title>Merge remote-tracking branch 'origin/main' into security/cloudflare-real-ip</title>
<updated>2026-11-08T22:18:34+00:00</updated>
<author>
<name>Leitwolf11</name>
</author>
<published>2026-11-08T22:18:34+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/progmaweb/commit/?id=c0bafe9050161ea6ca0c49f54897f908ca16ce84'/>
<id>c0bafe9050161ea6ca0c49f54897f908ca16ce84</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge pull request #60 from Progmasoft/feature/remove-xide</title>
<updated>2026-11-08T22:17:43+00:00</updated>
<author>
<name>Leitwolf</name>
</author>
<published>2026-11-08T22:17:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/progmaweb/commit/?id=3ac256e69f10a3bb78d394c77d03a88a72261597'/>
<id>3ac256e69f10a3bb78d394c77d03a88a72261597</id>
<content type='text'>
Remove Xide and ides.progmasoft.com</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Remove Xide and ides.progmasoft.com</pre>
</div>
</content>
</entry>
<entry>
<title>Rate-limit sign-in by visitor behind Cloudflare and stop forwarding h2c</title>
<updated>2026-11-08T21:38:47+00:00</updated>
<author>
<name>Leitwolf11</name>
</author>
<published>2026-11-08T21:38:47+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/progmaweb/commit/?id=66f3cc196a9b91d471a90e021b12630100181c4a'/>
<id>66f3cc196a9b91d471a90e021b12630100181c4a</id>
<content type='text'>
Cloudflare proxies the Progmasoft hosts, so Nginx saw a Cloudflare edge as
its peer and appended that edge to X-Forwarded-For. The API takes the last
hop as the client, so the account-auth limit (12 attempts in 3 minutes) was
counted per edge: 38 failed sign-ins from one address in a row were all
answered with 401, none with 429, and unrelated visitors behind one edge
shared a bucket.

- ops/nginx/cloudflare-real-ip.conf trusts CF-Connecting-IP only from the
  published Cloudflare ranges; a direct peer keeps its own address, so the
  header cannot be forged around Cloudflare. With it installed the 13th
  failed sign-in gets 429, a forged X-Forwarded-For changes nothing, and
  another address is not affected.
- Every proxied location forwarded the client's Upgrade header with
  "Connection: upgrade" on each request. Only a WebSocket upgrade is now
  forwarded; other requests carry no Upgrade and an empty Connection.
- c8 reached glob 13 (GHSA-3g3m-2fjr-6pw4) and minimatch 10
  (GHSA-g3hv-75wg-m249) through test-exclude; both are overridden to the
  fixed majors. pnpm audit reports nothing, coverage, lint and check pass.
- The CodeQL action pins carry their exact version comment (v4.38.2).
- ops/README.md describes the address handling and no longer names a
  script that left the repository with AI Support.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Cloudflare proxies the Progmasoft hosts, so Nginx saw a Cloudflare edge as
its peer and appended that edge to X-Forwarded-For. The API takes the last
hop as the client, so the account-auth limit (12 attempts in 3 minutes) was
counted per edge: 38 failed sign-ins from one address in a row were all
answered with 401, none with 429, and unrelated visitors behind one edge
shared a bucket.

- ops/nginx/cloudflare-real-ip.conf trusts CF-Connecting-IP only from the
  published Cloudflare ranges; a direct peer keeps its own address, so the
  header cannot be forged around Cloudflare. With it installed the 13th
  failed sign-in gets 429, a forged X-Forwarded-For changes nothing, and
  another address is not affected.
- Every proxied location forwarded the client's Upgrade header with
  "Connection: upgrade" on each request. Only a WebSocket upgrade is now
  forwarded; other requests carry no Upgrade and an empty Connection.
- c8 reached glob 13 (GHSA-3g3m-2fjr-6pw4) and minimatch 10
  (GHSA-g3hv-75wg-m249) through test-exclude; both are overridden to the
  fixed majors. pnpm audit reports nothing, coverage, lint and check pass.
- The CodeQL action pins carry their exact version comment (v4.38.2).
- ops/README.md describes the address handling and no longer names a
  script that left the repository with AI Support.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Remove Xide and ides.progmasoft.com</title>
<updated>2026-11-08T15:46:08+00:00</updated>
<author>
<name>Leitwolf11</name>
</author>
<published>2026-11-08T15:46:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/progmaweb/commit/?id=efa1f584205e93c292ea40b564d92a03f12ab33c'/>
<id>efa1f584205e93c292ea40b564d92a03f12ab33c</id>
<content type='text'>
Xide is no longer developed as of 2026-11-08 (Progmasoft/xide#29), so
Progmaweb stops presenting it:

- product.progmasoft.com: Xide leaves the catalog, its card and its
  detail page; /xide on the product host is a 404 like any unknown
  product. The catalog's description in every language names the Tala
  language with its tools and Catch3.
- ides.progmasoft.com served only the IDE list and the Xide page, so the
  whole site goes: the pages under app/ides, its texts in every
  language, idesRoute and its host in the proxy, and both nginx server
  blocks. The certificate of progmasoft.com no longer has to name it.

Tests: the catalog lists the remaining products and refuses xide.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Xide is no longer developed as of 2026-11-08 (Progmasoft/xide#29), so
Progmaweb stops presenting it:

- product.progmasoft.com: Xide leaves the catalog, its card and its
  detail page; /xide on the product host is a 404 like any unknown
  product. The catalog's description in every language names the Tala
  language with its tools and Catch3.
- ides.progmasoft.com served only the IDE list and the Xide page, so the
  whole site goes: the pages under app/ides, its texts in every
  language, idesRoute and its host in the proxy, and both nginx server
  blocks. The certificate of progmasoft.com no longer has to name it.

Tests: the catalog lists the remaining products and refuses xide.
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge pull request #58 from Progmasoft/feature/policies-consent</title>
<updated>2026-11-07T08:43:30+00:00</updated>
<author>
<name>Leitwolf</name>
</author>
<published>2026-11-07T08:43:30+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/progmaweb/commit/?id=d28c8c216708c3bb59773722e6235c4c8cbb2b73'/>
<id>d28c8c216708c3bb59773722e6235c4c8cbb2b73</id>
<content type='text'>
Ask for the Privacy and Security Policies at registration</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Ask for the Privacy and Security Policies at registration</pre>
</div>
</content>
</entry>
<entry>
<title>Drop AI Support from the Privacy Policy</title>
<updated>2026-11-07T08:10:20+00:00</updated>
<author>
<name>Leitwolf11</name>
</author>
<published>2026-11-07T08:10:20+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/progmaweb/commit/?id=5379c74171c0ef0d08c999ce93e2a03c37d25889'/>
<id>5379c74171c0ef0d08c999ce93e2a03c37d25889</id>
<content type='text'>
AI Support is removed and will not be published (progmaweb#59 is
closed): it used every core of the second server for each answer, and
it stated commands and names that are not in the documentation. The
policy in every language no longer lists it among the services it
covers, and the paragraph about where its questions go is gone.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
AI Support is removed and will not be published (progmaweb#59 is
closed): it used every core of the second server for each answer, and
it stated commands and names that are not in the documentation. The
policy in every language no longer lists it among the services it
covers, and the paragraph about where its questions go is gone.
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge branch 'main' into feature/policies-consent</title>
<updated>2026-11-06T14:51:08+00:00</updated>
<author>
<name>Leitwolf</name>
</author>
<published>2026-11-06T14:51:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/progmaweb/commit/?id=52047af6589b2729575523c1f4db61ea90a35d30'/>
<id>52047af6589b2729575523c1f4db61ea90a35d30</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge pull request #57 from Progmasoft/docs/tazel-net-links</title>
<updated>2026-11-06T14:49:34+00:00</updated>
<author>
<name>Leitwolf</name>
</author>
<published>2026-11-06T14:49:34+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/progmaweb/commit/?id=097fb096966117fe259bc2cd721527bbec04e57d'/>
<id>097fb096966117fe259bc2cd721527bbec04e57d</id>
<content type='text'>
Link Tazel's site at tazel.net</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Link Tazel's site at tazel.net</pre>
</div>
</content>
</entry>
</feed>
