<feed xmlns='http://www.w3.org/2005/Atom'>
<title>progmaweb, branch security/next-16.4.2</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>Update Next.js to 16.4.2 for an unauthenticated RCE</title>
<updated>2026-10-23T02:57:26+00:00</updated>
<author>
<name>Leitwolf11</name>
</author>
<published>2026-10-23T02:57:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/progmaweb/commit/?id=8e4f376c19a05c3a7ac73576515f4baa62ed206d'/>
<id>8e4f376c19a05c3a7ac73576515f4baa62ed206d</id>
<content type='text'>
pnpm audit reports a critical advisory for next &gt;=16.0.0 &lt;=16.4.0:
unauthenticated remote code execution through the Image Optimization
API when SVG files are used. progmasoft.com runs 16.3.8. The site sets
no images option and the optimizer refused an SVG request in a check
from outside, but the version is in the affected range, so it moves to
16.4.2, the latest patch release; eslint-config-next follows.

Verified: pnpm check, pnpm test:coverage, pnpm lint and pnpm build
pass; pnpm audit --audit-level high reports nothing beyond the one
advisory already ignored.

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>
pnpm audit reports a critical advisory for next &gt;=16.0.0 &lt;=16.4.0:
unauthenticated remote code execution through the Image Optimization
API when SVG files are used. progmasoft.com runs 16.3.8. The site sets
no images option and the optimizer refused an SVG request in a check
from outside, but the version is in the affected range, so it moves to
16.4.2, the latest patch release; eslint-config-next follows.

Verified: pnpm check, pnpm test:coverage, pnpm lint and pnpm build
pass; pnpm audit --audit-level high reports nothing beyond the one
advisory already ignored.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge pull request #41 from Progmasoft/web/bimi-logo</title>
<updated>2026-10-18T16:10:32+00:00</updated>
<author>
<name>Leitwolf</name>
</author>
<published>2026-10-18T16:10:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/progmaweb/commit/?id=46e526f91e805319e0b0b65bae8d09dc4fabfa0c'/>
<id>46e526f91e805319e0b0b65bae8d09dc4fabfa0c</id>
<content type='text'>
Serve the Progmasoft mark as a BIMI logo</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Serve the Progmasoft mark as a BIMI logo</pre>
</div>
</content>
</entry>
<entry>
<title>Serve the Progmasoft mark as a BIMI logo</title>
<updated>2026-10-18T14:40:26+00:00</updated>
<author>
<name>Leitwolf11</name>
</author>
<published>2026-10-18T14:40:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/progmaweb/commit/?id=6721ce3dccd7207d5372f30f0b5edb93157b0c1d'/>
<id>6721ce3dccd7207d5372f30f0b5edb93157b0c1d</id>
<content type='text'>
BIMI lets mail clients show a sender's logo next to messages from a
domain whose DMARC policy is enforced; progmasoft.com already publishes
p=quarantine with pct=100. The BIMI record points at an SVG on the
domain, so the site now serves one at /bimi/logo.svg.

The file is SVG Tiny Portable/Secure, as BIMI requires: version 1.2,
baseProfile tiny-ps, a title, no scripts, no external references and
no x or y on the root. It draws the same four tiles as the Brand
component, in the same colours (#3b4658, #1e7188, #7655fa, #dc7644)
and the same tile-to-gap ratio (11:2, here 132 and 24 on a 512 grid),
on a white square. The mark stays inside the circle that clients crop
the logo to.

Next.js serves files from apps/web/public before the dynamic routes;
the deployment already copies public/ next to the standalone server.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
BIMI lets mail clients show a sender's logo next to messages from a
domain whose DMARC policy is enforced; progmasoft.com already publishes
p=quarantine with pct=100. The BIMI record points at an SVG on the
domain, so the site now serves one at /bimi/logo.svg.

The file is SVG Tiny Portable/Secure, as BIMI requires: version 1.2,
baseProfile tiny-ps, a title, no scripts, no external references and
no x or y on the root. It draws the same four tiles as the Brand
component, in the same colours (#3b4658, #1e7188, #7655fa, #dc7644)
and the same tile-to-gap ratio (11:2, here 132 and 24 on a 512 grid),
on a white square. The mark stays inside the circle that clients crop
the logo to.

Next.js serves files from apps/web/public before the dynamic routes;
the deployment already copies public/ next to the standalone server.
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge pull request #40 from Progmasoft/feature/log-google-failures</title>
<updated>2026-10-16T15:46:35+00:00</updated>
<author>
<name>Leitwolf</name>
</author>
<published>2026-10-16T15:46:35+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/progmaweb/commit/?id=e3c7010328447038291712407142d1d744a5a462'/>
<id>e3c7010328447038291712407142d1d744a5a462</id>
<content type='text'>
Log why a Google callback could not finish</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Log why a Google callback could not finish</pre>
</div>
</content>
</entry>
<entry>
<title>Log why a Google callback could not finish</title>
<updated>2026-10-16T13:13:45+00:00</updated>
<author>
<name>Leitwolf11</name>
</author>
<published>2026-10-16T13:13:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/progmaweb/commit/?id=031cbf7efc5d97b28259da5b387cb3a3dbd242d5'/>
<id>031cbf7efc5d97b28259da5b387cb3a3dbd242d5</id>
<content type='text'>
A failed Google callback has returned the visitor to /login?google=failed
since the previous release, but nothing recorded why: a declined consent,
an expired or missing state cookie and a forged request all looked the
same, and the log of the service held no entry at all.

GoogleSignInFailure now handles OnRemoteFailure. It writes one warning,
event GoogleSignInFailed (id 5), with the cause: the error code Google
reported, such as access_denied, or the reason the handler refused the
callback, such as "The oauth state was missing or invalid." An error code
is written only when it is a short run of letters, digits, '_', '-' and
'.'; anything else from the query string is written as an unrecognized
error. The authorization code, the state and tokens are never logged.
The redirect is unchanged.

Four new tests cover the entry, the redirect, an unusual error value and
a refused state. The account API document describes the log entry.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
A failed Google callback has returned the visitor to /login?google=failed
since the previous release, but nothing recorded why: a declined consent,
an expired or missing state cookie and a forged request all looked the
same, and the log of the service held no entry at all.

GoogleSignInFailure now handles OnRemoteFailure. It writes one warning,
event GoogleSignInFailed (id 5), with the cause: the error code Google
reported, such as access_denied, or the reason the handler refused the
callback, such as "The oauth state was missing or invalid." An error code
is written only when it is a short run of letters, digits, '_', '-' and
'.'; anything else from the query string is written as an unrecognized
error. The authorization code, the state and tokens are never logged.
The redirect is unchanged.

Four new tests cover the entry, the redirect, an unusual error value and
a refused state. The account API document describes the log entry.
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge pull request #39 from Progmasoft/feature/thirty-day-sessions</title>
<updated>2026-10-16T04:18:36+00:00</updated>
<author>
<name>Leitwolf</name>
</author>
<published>2026-10-16T04:18:36+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/progmaweb/commit/?id=8f58831373b72dc5b60bad649a961acd0bb94aa4'/>
<id>8f58831373b72dc5b60bad649a961acd0bb94aa4</id>
<content type='text'>
Keep account sessions for 30 days</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Keep account sessions for 30 days</pre>
</div>
</content>
</entry>
<entry>
<title>Merge remote-tracking branch 'origin/main' into feature/thirty-day-sessions</title>
<updated>2026-10-16T04:16:14+00:00</updated>
<author>
<name>Leitwolf11</name>
</author>
<published>2026-10-16T04:16:14+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/progmaweb/commit/?id=235874b4e2bbf75acf2fd09ec37c3dfd480c01b7'/>
<id>235874b4e2bbf75acf2fd09ec37c3dfd480c01b7</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 #38 from Progmasoft/fix/stale-statements</title>
<updated>2026-10-16T04:15:42+00:00</updated>
<author>
<name>Leitwolf</name>
</author>
<published>2026-10-16T04:15:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/progmaweb/commit/?id=e140d6587a1a74efc205b29582dfbe9942e0f3dc'/>
<id>e140d6587a1a74efc205b29582dfbe9942e0f3dc</id>
<content type='text'>
Return a failed Google callback to sign-in and correct stale statements</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Return a failed Google callback to sign-in and correct stale statements</pre>
</div>
</content>
</entry>
<entry>
<title>Keep account sessions for 30 days</title>
<updated>2026-10-16T03:46:23+00:00</updated>
<author>
<name>Leitwolf11</name>
</author>
<published>2026-10-16T03:46:23+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/progmaweb/commit/?id=205d91185e22b9129c528296cf07d15225d82866'/>
<id>205d91185e22b9129c528296cf07d15225d82866</id>
<content type='text'>
A session of a Progmasoft Account, whether opened with a password or with
Google, lasted 12 hours from the sign-in, and the setting could not raise
it beyond 7 days. Sessions now last 30 days by default, and
AccountSessions:LifetimeHours may set anything from 1 hour up to that new
maximum of 720 hours; a value outside the range is clamped to it, as
before.

The lifetime stays fixed from the sign-in; it is not extended by use. The
production environment file sets no lifetime, so the new default applies
there once the API is deployed. Sessions opened before keep the expiry
they were given.

New tests check the 30-day default and the clamping of 0, 12, 720 and
10 000 hours. The account API document gives the new default and range.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
A session of a Progmasoft Account, whether opened with a password or with
Google, lasted 12 hours from the sign-in, and the setting could not raise
it beyond 7 days. Sessions now last 30 days by default, and
AccountSessions:LifetimeHours may set anything from 1 hour up to that new
maximum of 720 hours; a value outside the range is clamped to it, as
before.

The lifetime stays fixed from the sign-in; it is not extended by use. The
production environment file sets no lifetime, so the new default applies
there once the API is deployed. Sessions opened before keep the expiry
they were given.

New tests check the 30-day default and the clamping of 0, 12, 720 and
10 000 hours. The account API document gives the new default and range.
</pre>
</div>
</content>
</entry>
<entry>
<title>Return a failed Google callback to sign-in and correct stale statements</title>
<updated>2026-10-16T03:00:57+00:00</updated>
<author>
<name>Leitwolf11</name>
</author>
<published>2026-10-16T03:00:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/progmaweb/commit/?id=bc653270652c1ab44d2144ddd17ae49b404e7cd2'/>
<id>bc653270652c1ab44d2144ddd17ae49b404e7cd2</id>
<content type='text'>
A Google callback that could not finish ended in an unhandled 500: a
visitor who declined on Google's consent screen, a callback whose state
cookie had expired, and a direct request to the callback path all got an
empty error page. The account API document already promised a redirect
to /login?google=failed for a failed callback; the handler of the Google
scheme now does that through OnRemoteFailure. Three new tests cover a
callback without state, a declined consent and a forged state.

Three statements no longer matched the sites:

- the bug report template still named the catalog paths without the
  language and the build system; they are /langs/tala/&lt;Publisher&gt;/&lt;Name&gt;/
  and /dslplugins/tazel/&lt;Publisher&gt;/&lt;Name&gt;/;
- the operations guide placed Tala content on xsharp-lang.xyz, which only
  redirects to tala.run now;
- the architecture guide described the ViGet routing before the catalogs
  per language and build system: it now gives the rewrites of /langs/tala
  and /dslplugins/tazel, the redirects of /langs and /dslplugins, three
  indexed ViGet pages and a sitemap with the home page and both catalogs.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
A Google callback that could not finish ended in an unhandled 500: a
visitor who declined on Google's consent screen, a callback whose state
cookie had expired, and a direct request to the callback path all got an
empty error page. The account API document already promised a redirect
to /login?google=failed for a failed callback; the handler of the Google
scheme now does that through OnRemoteFailure. Three new tests cover a
callback without state, a declined consent and a forged state.

Three statements no longer matched the sites:

- the bug report template still named the catalog paths without the
  language and the build system; they are /langs/tala/&lt;Publisher&gt;/&lt;Name&gt;/
  and /dslplugins/tazel/&lt;Publisher&gt;/&lt;Name&gt;/;
- the operations guide placed Tala content on xsharp-lang.xyz, which only
  redirects to tala.run now;
- the architecture guide described the ViGet routing before the catalogs
  per language and build system: it now gives the rewrites of /langs/tala
  and /dslplugins/tazel, the redirects of /langs and /dslplugins, three
  indexed ViGet pages and a sitemap with the home page and both catalogs.
</pre>
</div>
</content>
</entry>
</feed>
