feature: the credential store keeps credentials of any kind in config.json with encrypted secrets, with its routes and its dialog.
Release / release (push) Successful in 1m4s
Release / release (push) Successful in 1m4s
This commit is contained in:
1 parent
57ac5296cb
commit
b0b7a4bb7f
13 files changed
+723
-30
No files matched your search
@@ -1,25 +1,27 @@
|
||||
# Architecture Decision Records
|
||||
|
||||
## ADR-1: The toolkit is TypeScript source, linked into the applications
|
||||
## ADR-1: The source is TypeScript, linked into an application while both change
|
||||
|
||||
Status: Accepted
|
||||
|
||||
Context: manage-ui and sql-query-webui share their server helpers and web components. The
|
||||
applications run their servers with Node's type stripping and build their web code with Vite.
|
||||
The toolkit is to be published to Gitea later; until then it is developed next to them.
|
||||
They depend on the published package (ADR-2), and a change of the toolkit is tried in them before
|
||||
it is released.
|
||||
|
||||
Decision: The toolkit ships its `.ts` and `.tsx` files without a build, with three entry points:
|
||||
`./server`, `./web` and `./vite`. The applications depend on the checkout by a `file:` path, which
|
||||
npm links; Node runs the server helpers from the checkout's real path, where type stripping
|
||||
Decision: The source is `.ts` and `.tsx` files with three entry points: `./server`, `./web` and
|
||||
`./vite`. While the toolkit and an application change together, `npm link --no-save` replaces the
|
||||
installed package with the checkout, leaving `package.json` and the lock file on the published
|
||||
version; Node runs the server helpers from the checkout's real path, where type stripping
|
||||
applies, and Vite compiles the web code. The server helpers import only Node's modules at run
|
||||
time, and types of Fastify; the Vite helpers import only types of Vite, taking `loadEnv`'s answer
|
||||
from the application. The web code's React, MUI and Emotion come from the application, which
|
||||
dedupes them with `TOOLKIT_RESOLVE`. The peer dependencies are optional, as an application uses
|
||||
only some of the entry points, and are development dependencies for the toolkit's own checks.
|
||||
|
||||
Consequences: The applications need the checkout at `../sk-react-toolkit`, and their container
|
||||
builds cannot install it until it is published. Node refuses type stripping in `node_modules`,
|
||||
so the published package is compiled (ADR-2).
|
||||
Consequences: The dependency of an application never names a path; `npm ci` replaces a link
|
||||
with the published version. Node refuses type stripping in `node_modules`, so the published
|
||||
package is compiled (ADR-2).
|
||||
|
||||
## ADR-2: The published package is built in dist/ and published to Gitea by a tag
|
||||
|
||||
@@ -35,8 +37,8 @@ import extensions to `.js`, into `dist/` with declarations, and writes `dist/pac
|
||||
exports of the compiled files and declarations; the package published is `dist/`, while the
|
||||
source `package.json` stays private with exports of the source. The name is
|
||||
`@koszewscy/sk-react-toolkit`, scoped to the owner, so an application takes only this scope from
|
||||
Gitea; it imports it as `sk-react-toolkit` by an npm alias, so the switch from the checkout to the
|
||||
published package changes only the dependency. The package is built and published only by the
|
||||
Gitea; it depends on a published version and imports the package by this name, which is also the
|
||||
name `npm link` gives the checkout. The package is built and published only by the
|
||||
`Release` workflow, which follows linux-cloud-router's: it runs for each tag and on demand, with
|
||||
the secrets `CI_URL`, `CI_OWNER` and `CI_TOKEN`, and skips a version already published.
|
||||
`actions/setup-node` gives npm the registry of the package's scope and the token, so the package
|
||||
@@ -46,3 +48,27 @@ carries no registry; `release.mjs` refuses a tag `x.y.z` that is not the version
|
||||
Consequences: A release raises the version in both CHANGELOG.md and `package.json`, and a
|
||||
re-run, or a tag `x.y.z-n`, publishes nothing. The declarations of `renderApp` reference the
|
||||
declaration of the `virtual:font` module, which `build.mjs` copies into `dist/`.
|
||||
|
||||
## ADR-3: Credentials of any kind are kept in config.json, with secrets encrypted by a key of the environment
|
||||
|
||||
Status: Accepted
|
||||
|
||||
Context: sql-query-webui kept PostgreSQL connection profiles with encrypted passwords, and
|
||||
manage-ui needs a PostgreSQL connection and an Azure service principal without taking them from
|
||||
its environment. Other systems will need other kinds of credentials.
|
||||
|
||||
Decision: A credential store is a list in a key of the application's `config.json`; each entry
|
||||
has a name, a kind and the fields of its kind. The application gives the kinds as data: each field
|
||||
with its key, label, help, type (text, port, GUID or a choice), whether it is required and whether
|
||||
it is secret. The toolkit checks the entries, serves read, validate and write routes, and renders
|
||||
the dialog from the kinds, so a new kind needs no new code. Secret fields are encrypted with
|
||||
AES-256-GCM, a random 12-byte IV each, with the key the SHA-256 of `ENCRYPTION_KEY`, else of the
|
||||
content of `ENCRYPTION_KEY_FILE`. A secret is never answered: read gives null and whether it is
|
||||
kept, and a write sends null to keep it, `''` to drop it, or a new secret. The applications decide
|
||||
how a credential is used: `credentialValues` answers it with its secrets decrypted. The types the
|
||||
server and the dialog share are in `shared/credentials.ts`, exported by both entry points.
|
||||
|
||||
Consequences: Without the key no secret can be saved or used, and a changed key makes the saved
|
||||
secrets unusable until they are entered again. SHA-256 does not slow down guessing a weak key, so
|
||||
the key has to be long and random. Anyone who reaches the routes can replace credentials, as the
|
||||
applications have no authentication.
|
||||
Reference in new issue
Block a user