<feed xmlns='http://www.w3.org/2005/Atom'>
<title>progmaweb/docs/ACCOUNT-API.md, branch feature/progmasoft-credentials</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>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>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>Run the account API without a Google client</title>
<updated>2026-10-03T15:46:35+00:00</updated>
<author>
<name>Leitwolf11</name>
</author>
<published>2026-10-03T15:46:35+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/progmaweb/commit/?id=ec774db15976385a6d5ea6f48d3622fe507d3843'/>
<id>ec774db15976385a6d5ea6f48d3622fe507d3843</id>
<content type='text'>
With an empty Google client identifier or secret the API answered every
request with 500, including registration, password sign-in and the status
route. The Google scheme was always registered, and the authentication
middleware initializes every remote scheme for each request; with empty
credentials the validation of the Google options threw there, before any
endpoint ran. The API could not be started locally without credentials, and
the "Google sign-in is unavailable" answer of the start endpoint was never
reached.

The Google scheme is now registered only when both values are configured.
Without it the service runs normally, the start endpoint answers 503, the
completion endpoint redirects to the failed sign-in page without a session,
and the callback path is not a route. With both values nothing changes.

The test factory passes the two values as host settings. The program makes
the decision while it registers services, and configuration sources a test
factory adds are applied only when the host is built, after that point.

New tests run the service without a Google client: the ordinary routes,
a full register, sign-out and sign-in round trip, and the three Google
paths. They failed with 500 against the previous program and pass now, also
when the environment of the test run carries Google credentials.

The guides no longer list this as a limitation or ask for placeholder
credentials.

Deploying this change restarts the API, which deletes every account while
the store is in memory.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
With an empty Google client identifier or secret the API answered every
request with 500, including registration, password sign-in and the status
route. The Google scheme was always registered, and the authentication
middleware initializes every remote scheme for each request; with empty
credentials the validation of the Google options threw there, before any
endpoint ran. The API could not be started locally without credentials, and
the "Google sign-in is unavailable" answer of the start endpoint was never
reached.

The Google scheme is now registered only when both values are configured.
Without it the service runs normally, the start endpoint answers 503, the
completion endpoint redirects to the failed sign-in page without a session,
and the callback path is not a route. With both values nothing changes.

The test factory passes the two values as host settings. The program makes
the decision while it registers services, and configuration sources a test
factory adds are applied only when the host is built, after that point.

New tests run the service without a Google client: the ordinary routes,
a full register, sign-out and sign-in round trip, and the three Google
paths. They failed with 500 against the previous program and pass now, also
when the environment of the test run carries Google credentials.

The guides no longer list this as a limitation or ask for placeholder
credentials.

Deploying this change restarts the API, which deletes every account while
the store is in memory.
</pre>
</div>
</content>
</entry>
<entry>
<title>Document the architecture, the account API, localization and limitations</title>
<updated>2026-10-03T15:18:50+00:00</updated>
<author>
<name>Leitwolf11</name>
</author>
<published>2026-10-03T15:18:50+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/progmaweb/commit/?id=ba237e5ce9f50cd9e586697417c1d636e3cd129c'/>
<id>ba237e5ce9f50cd9e586697417c1d636e3cd129c</id>
<content type='text'>
The repository had a README and two operations notes. This adds the
documents a contributor or operator needs and corrects what had gone stale.

New, under docs/:
- README.md: index of the documentation.
- ARCHITECTURE.md: the two processes, the three hosts, the host-aware
  routing rules, the account flow and the trust boundaries.
- ACCOUNT-API.md: every endpoint with its request, responses and errors,
  the field rules, the Google flow outcome by outcome, cookies, limits and
  configuration. The responses were checked against a locally running API.
- LOCALIZATION.md: the four languages, how a page picks one, the cookie,
  how Hebrew text is laid out, and how to add a language.
- DEVELOPMENT.md: requirements, local setup, checks, tests, what each CI
  workflow enforces, the audit exception and the DocFX project.
- LIMITATIONS.md: what is missing or temporary, with the consequence of
  each: the in-memory account store, unverified addresses, no mail, no
  password change, the ignored returnTo parameter, the legacy ViGet status
  route, and that the API answers 500 to everything while the Google
  settings are empty.

Updated:
- README.md: languages, a documentation section, the local API command
  with its port, and the DocFX check.
- ops/README.md: restarting the API deletes every account, how to release
  a frontend-only change without that restart, and lessons from past
  releases.
- ops/mail/README.md: a status note that the API does not send mail yet.
- The pull request template names all four languages.

No source file changes.

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>
The repository had a README and two operations notes. This adds the
documents a contributor or operator needs and corrects what had gone stale.

New, under docs/:
- README.md: index of the documentation.
- ARCHITECTURE.md: the two processes, the three hosts, the host-aware
  routing rules, the account flow and the trust boundaries.
- ACCOUNT-API.md: every endpoint with its request, responses and errors,
  the field rules, the Google flow outcome by outcome, cookies, limits and
  configuration. The responses were checked against a locally running API.
- LOCALIZATION.md: the four languages, how a page picks one, the cookie,
  how Hebrew text is laid out, and how to add a language.
- DEVELOPMENT.md: requirements, local setup, checks, tests, what each CI
  workflow enforces, the audit exception and the DocFX project.
- LIMITATIONS.md: what is missing or temporary, with the consequence of
  each: the in-memory account store, unverified addresses, no mail, no
  password change, the ignored returnTo parameter, the legacy ViGet status
  route, and that the API answers 500 to everything while the Google
  settings are empty.

Updated:
- README.md: languages, a documentation section, the local API command
  with its port, and the DocFX check.
- ops/README.md: restarting the API deletes every account, how to release
  a frontend-only change without that restart, and lessons from past
  releases.
- ops/mail/README.md: a status note that the API does not send mail yet.
- The pull request template names all four languages.

No source file changes.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</pre>
</div>
</content>
</entry>
</feed>
