Skip to content

Commit 343e0aa

Browse files
sebadoblvaroqui
andauthored
onboarding improvements (#946)
* add `DEV_MODE=false` inline for the `build` script for the UI * add `just setup` back into the `CONTRIBUTING.md` * create a `just compose` recipe * mention `just compose` in `CONTRIBUTING.md` * update `just build-ui` to make optional building inside a container possible * remove static HTML from version control * fix some linting in UI server hooks * update `CONTRIBUTING.md` with some additional information about internals * add the dev handlers to the docs * mention E-Mail i18n * Update CONTRIBUTING.md Co-authored-by: Luc (Echow) Varoqui <48593807+lvaroqui@users.noreply.github.com> * remove section about pre-built HTML --------- Co-authored-by: Luc (Echow) Varoqui <48593807+lvaroqui@users.noreply.github.com>
1 parent a545447 commit 343e0aa

File tree

714 files changed

+177
-4182
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

714 files changed

+177
-4182
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,6 @@ src/bin/tests/test_data
1919
.npm_cache
2020
pnpm-lock.yaml
2121
pictures/
22-
heaptrack.rauthy.*
22+
heaptrack.rauthy.*
23+
static
24+
templates/html

CONTRIBUTING.md

Lines changed: 133 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,29 +33,59 @@ To work with this project, you need to have the following tools available on you
3333
- `npm`
3434
- `docker` / `podman`
3535

36+
> `npm` is not strictly necessary, but recommended to have. If you just want to build the static UI files, you can also
37+
> do it inside a container. However, if you want to do any form of development on the UI, you need `npm` to run it in
38+
> dev mode locally.
39+
3640
### Building from source
3741

38-
If you just want to build from source yourself without doing any development, all necessary files have been checked into
39-
version control to make this possible. In some environments, `just build-ui` does not work (like FreeBSD e.g.). To still
40-
be able to build from source on those systems, the pre-built static HTML has been checked into version control.
42+
If you only care about building from source and don't need any testing or development, you need to do 2 things:
43+
44+
- `just build-ui`
45+
- `cargo build --release`
46+
47+
This will build a release binary for your current platform in the simplest form. You can also build the multi arch
48+
container image. However, you cannot just use `just build` (like explained further down). You then need to do something
49+
like
50+
51+
```
52+
just build my/registry/rauthy
53+
```
54+
55+
This will build the container AND will try to `push` the image as well. If you only want a local image without pushing
56+
it, you can do
4157

4258
```
43-
cargo build --release
59+
just build my/registry/rauthy nopush
4460
```
4561

62+
which will then build the multi arch image and load it into your local container registry afterward.
63+
4664
#### CAUTION
4765

48-
If you are building from source, either for production or without rebuilding the UI, you MUST always build
49-
from a stable release tag and never from main. To not have messy PRs, the UI will only be rebuilt during releases or
50-
in special occasions.
51-
You also MUST NEVER use a build from `main` in production. The `main` branch might contain unstable database migrations.
52-
If these are applied to your production database and needed changes before the next release, it will produce a conflict
53-
that is impossible to be solved automatically. You either need to roll back and apply an older DB backup, or undo the
54-
unstable migrations manually. Just don't ever use `main` or any nightly images you might find in production.
66+
If you are building from source for production, you MUST always build from a stable release tag and never from `main`.
67+
68+
You MUST NEVER use a build from `main` or any nightly image (tag typically with `*-some_date` appended) in production.
69+
The `main` branch might contain unstable database migrations. If these are applied to your production database and
70+
needed changes before the next release, it will produce a conflict that is impossible to be solved automatically. You
71+
either need to roll back and apply an older DB backup, or undo the unstable migrations manually. Just don't ever use
72+
`main` or any nightly images you might find in production.
5573

5674
### Initial Development Setup
5775

58-
A lot of work has been put into simplifying the development setup lately. The minimum need to do is:
76+
A lot of work has been put into simplifying the development setup lately.
77+
78+
If you start inside a freshly cloned project, you first need to execute
79+
80+
```
81+
just setup
82+
```
83+
84+
which will run `npm install` for the frontend, to make all the `node_modules` available for either building the UI or
85+
running it in development mode. You only need to run this once or after a version bump, which will typically bump
86+
all dependencies and therefore needs another `npm install`.
87+
88+
After the `setup`, you need:
5989

6090
- `just backend-start`
6191
- `just build-ui`
@@ -65,11 +95,6 @@ times, if the containers are already running, but these can be ignored. You don'
6595
are only developing with `hiqlite`. If you want to save the resources, instead of `just backend-start`, you could only
6696
do `just mailcrab-start` to start the local email test server.
6797

68-
Even though pre-built static HTML files are checked into version control to make building from source possible on some
69-
systems, where the UI cannot be built, you MUST always rebuild it, when you are developing locally. This is done with
70-
`just build-ui`. The pre-built files checked into version control are usually only updated during releases to not have
71-
messy PRs all the time.
72-
7398
Rauthy is using compile-time checked templating with [askama](https://crates.io/crates/askama). If you ever see any
7499
templating related errors from `askama`, you most like just need to rebuild the UI with another `just build-ui`.
75100

@@ -141,6 +166,10 @@ If you want to test against Postgres, instead of the above `just run`, simply ex
141166
just run postgres
142167
```
143168

169+
> If you don't want to keep running your Postgres and Mailcrab containers up and running, you can instead of `just run`
170+
> also use `just compose`, which will start and stop both containers each time. Keep in mind though, that you will lose
171+
> any prior state from testing in that case (apart from Hiqlite).
172+
144173
### Default Credentials
145174

146175
When `DEV_MODE=true` (which is the default for local dev), Rauthy will do some programmatic DB migrations. For instance
@@ -184,6 +213,91 @@ rebuilt the UI, you will have the static HTML files updates, and you see the lat
184213
> not added of course because of the UI error.
185214
> You need to fix the UI error first, then rebuild it, and then the `askama` template errors will go away.
186215
216+
## Architecture and Internals
217+
218+
### DEV vs PROD mode
219+
220+
Rauthy's architecture in production is really simple, but in local development, it's a bit more involved.
221+
222+
During **local development**, you have the Rust backend, which basically is "Rauthy". It serves the whole API. In
223+
addition, you typically want to run the UI in dev mode as well, which is done via `just run ui`, like explained above.
224+
This will run NodeJS and serve the Svelte UI on port `5173`.
225+
226+
In **production**, the whole UI will be compiled into static HTML and served by the Rust backend. This means you only
227+
have this single server running doing all the work.
228+
229+
For the UI, `<template>` blocks are used to do a little bit of SSR. Some values will be injected into the HTML (in prod)
230+
before it's sent to the user. To access these `<template>` blocks, there is a dedicated Svelte component in
231+
`frontend/src/lib/Template.svelte` which will take care of this. In prod, it will simply get the information from the
232+
DOM. During local dev, it will fetch the data async from the Rust backend via the `/auth/v1/template/${id}` endpoint.
233+
This endpoint is only available when Rauthy is compiled with `debug_assertions` and not every scenario works with it
234+
like it prod. These cases are mentioned above already as well, just to keep that in mind. It's mostly about password
235+
resets.
236+
237+
Some actions and flows only work like normal, when the backend is served as static HTML from the Rust API. To work
238+
around these edge cases, Rauthy exposes dev-only endpoints in `src/api/src/dev_only/dev_handler.rs`. These are used
239+
in some situations, where you might have a chicken-and-egg problem because of non-static HTML or things like that.
240+
241+
### Database Migrations
242+
243+
DB migrations live in `migrations`. They work very similar for both DB versions with slight differences.
244+
245+
The files in both cases MUST follow a strictly ascending order with their ID to be considered valid. For `hiqlite`, the
246+
files therefore must always start with `<id>_`, while for Postgres (because of different crates under the hood), it must
247+
be `V<id>__`.
248+
249+
> The **most important part** is, that you NEVER modify already existing files that have been published in any stable
250+
> version before. These migrations will be hashed at startup and compared to the already applied hashes, and they will
251+
> `panic` if there is any difference, to never operate on a database in an unknown state.
252+
253+
### I18n
254+
255+
#### UI
256+
257+
Internationalization has been reworked a few times until it reached the current, hopefully easy to understand state:
258+
259+
For the UI, everything you need to do is to take a look at `frontend/src/i18n`. This folder will container `admin`
260+
and `common`. Translations are split into these categories, so that a normal user would never have to fetch any
261+
translations that are only necessary for the Admin UI part. Therefore, if you add anything, make sure it is done in the
262+
correct section. It is done in this way to have all the type-checked instead of the usual "fetch some JSON and interpret
263+
it"-way of doing it.
264+
265+
You can access them inside the code via already existing hooks and I always use `t` for the `common` translations, and
266+
`ta` for all `admin` translations:
267+
268+
```typescript
269+
let t = useI18n();
270+
let ta = useI18nAdmin();
271+
```
272+
273+
#### E-Mail
274+
275+
E-Mails are rendered in the backend. Translations are being handled in `src/models/src/i18n_email`. Most of these have
276+
fixed presets. But for the "New Password" and "Password Reset" E-Mail, some custom `TPL_*` env vars can be set to
277+
overwrite the defaults and customize these mails a bit more. The corresponding files, which require a bit more work
278+
when adding a whole new language, are `src/models/src/i18n_email/password_new.rs` and
279+
`[reset.rs](src/models/src/i18n_email/reset.rs)`.
280+
281+
### CSS
282+
283+
CSS is being done very straight forward. To make it short: I really hate any CSS frameworks.
284+
285+
There is `frontend/src/css/global.css` which contains a few global CSS values, that are just used in many places.
286+
287+
`frontend/src/css/theme.css` only exists to make the IDE happy and have a better DX. In reality, the themes are always
288+
(even during local dev) fetched from the backend to make them dynamically updatable and also cacheable. In
289+
`frontend/src/app.html`, you can see the `<link rel="stylesheet" href="/auth/v1/theme/{{client_id}}/{{theme_ts}}"/>` to
290+
fetch themes dynamically, depending on the `client_id`.
291+
292+
Apart from this, all components are styled locally in the `<style>` blocks with just normal CSS.
293+
294+
### UI Compilation
295+
296+
To make the static HTML compilation work and not fail in some edge cases, there is also the
297+
`frontend/src/hooks.server.js` which you might need to do something in, if you added something new that's failing now.
298+
This file is only used when the UI is served during local dev and will never be taken into account for the static HTML
299+
build or in production.
300+
187301
## Known Limitations
188302

189303
Rauthys setup is a bit complex during local development. It builds the UI into static HTML which will be used by a
@@ -257,8 +371,8 @@ just pre-pr-checks
257371
## FreeBSD
258372

259373
If you want to compile from source on FreeBSD, you may have a few limitations. Compiling the UI on FreeBSD seems to not
260-
work. That is why the `static/` html is checked into version control so it does not prevent you from building from
261-
source.
374+
work. You can use `just build-ui container` to use a `node` container to build the static UI files in that case, or run
375+
the docker command from the recipe manually, if you don't have `just` available.
262376

263377
Since FreeBSD uses some cargo mechanism at build time differently, you may also run into linking issues like e.g. for
264378
`openssl`, `sqlite` or `rocksdb`. In these situations, you should be able to fix it by installing the dependency on your

frontend/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"private": true,
55
"scripts": {
66
"dev": "DEV_MODE=true vite dev",
7-
"build": "vite build",
7+
"build": "DEV_MODE=false vite build",
88
"preview": "vite preview",
99
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
1010
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",

frontend/src/hooks.server.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// @ts-ignore
12
const isDev = process.env.DEV_MODE === 'true';
23

34
const langDefault = 'en';
@@ -31,7 +32,7 @@ export async function handle({event, resolve}) {
3132
let locale = event.cookies.get('locale');
3233
return html
3334
.replace('%lang%', locale || langDefault)
34-
.replace('{{theme_ts}}', new Date().getTime());
35+
.replace('{{theme_ts}}', new Date().getTime().toString());
3536
} else {
3637
return html.replace('%lang%', '{{lang}}');
3738
}

justfile

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ docker := `echo ${DOCKER:-docker}`
1010
map_docker_user := if docker == "podman" { "" } else { "-u $USER" }
1111
npm := `echo ${NPM:-npm}`
1212
cargo_home := `echo ${CARGO_HOME:-$HOME/.cargo}`
13+
node_image := "node:22"
1314
builder_image := "ghcr.io/sebadob/rauthy-builder"
1415
builder_tag_date := "20250505"
1516
container_mailcrab := "rauthy-mailcrab"
@@ -33,12 +34,6 @@ setup:
3334
{{ npm }} install
3435
cd ..
3536

36-
echo "Building the UI and static HTML"
37-
just build-ui
38-
39-
echo "Starting Postgres and Mailcrab containers"
40-
just backend-start
41-
4237
# start the backend containers for local dev
4338
@backend-start:
4439
just mailcrab-start || echo ">>> Mailcrab is already running - nothing to do"
@@ -175,6 +170,27 @@ run ty="hiqlite":
175170
cargo run
176171
fi
177172

173+
# runs (and stops) Postgres, Mailcrab, normal `just run` command
174+
compose ty="hiqlite":
175+
#!/usr/bin/env bash
176+
177+
just mailcrab-start
178+
179+
# In case of Postgres, the container will not be up that quickly
180+
if [[ {{ ty }} == "postgres" ]]; then
181+
just postgres-start
182+
sleep 2
183+
{{ postgres }} cargo run
184+
just postgres-stop
185+
elif [[ {{ ty }} == "ui" ]]; then
186+
cd frontend
187+
{{ npm }} run dev -- --host=0.0.0.0
188+
elif [[ {{ ty }} == "hiqlite" ]]; then
189+
cargo run
190+
fi
191+
192+
just mailcrab-stop
193+
178194
# prints out the currently set version
179195
version:
180196
#!/usr/bin/env bash
@@ -262,8 +278,8 @@ test-postgres test="": test-backend-stop postgres-stop postgres-start
262278
exit 1
263279
fi
264280

265-
# builds the frontend and exports to static html
266-
build-ui:
281+
# builds the frontend and exports to static html, the option `container` will build it inside a container
282+
build-ui where="local":
267283
#!/usr/bin/env bash
268284
set -euxo pipefail
269285

@@ -274,13 +290,21 @@ build-ui:
274290
rm -rf static/v1/*
275291
rm -rf templates/html/*
276292

277-
# build the frontend
278-
cd frontend
279-
{{ npm }} run build
280-
cd ..
293+
if [[ {{ where }} == "container" ]]; then
294+
{{ docker }} run \
295+
-v {{ invocation_directory() }}/:/work/ \
296+
-w /work/frontend \
297+
{{ map_docker_user }} \
298+
{{ node_image }} \
299+
npm run build
300+
else
301+
# build the frontend
302+
cd frontend
303+
{{ npm }} run build
304+
fi
281305

282-
git add static/v1/*
283-
git add templates/html/*
306+
# git add static/v1/*
307+
# git add templates/html/*
284308

285309
# builds the rauthy book
286310
build-docs:

static/v1/_app/immutable/assets/0.Bj1icLx7.css

Lines changed: 0 additions & 1 deletion
This file was deleted.
-1.17 KB
Binary file not shown.
-1.39 KB
Binary file not shown.

0 commit comments

Comments
 (0)