Repository: sebadob/rauthy (language: rust)

Issue:
Issues with building from source
Running `cargo build` (or `just setup`) results in many compile errors, all related to sqlx queries:

[Build log](https://gist.github.com/gepbird/37cb986be0e57be215d8bf8b73209407)

I got the same result with 1.81.0, 1.83.0 and nightly 1.85.0 rust toolchains.

I'm in the process of packaging rauthy in [nixpkgs](https://github.com/NixOS/nixpkgs) where we prefer building packages from source.




Discussion / hints:
That's because of an incomplete or incorrect setup. The migrations are missing and therefore the compile-time checked queries throw errors.

Just `cargo build` is a bad idea anyway, because it's missing the `just build-ui`, which is not checked into version control, and the sqlx queries are not prepared. To build Rauthy, you need access to a running Postgres with applied database migrations. If you can't have one up and running, take a look at `cargo sqlx prepare`, but there is no `just` recipe or anything for that. The best idea is to take a look at `just build` and what it does.

If build setps are missing, you could run into 2 issues:
- sqlx errors all over the place if it can't connect to a Postgres or no queries have been prepared
- template errors from `askama` if the ui has not been built

Edit:

Btw you should not build from `main`, only from a stable tag, because otherwise you might end up in a situation where you might have un-resolveable conflicts with database migrations. They are not stabilized on `main`.
Thanks for the quick response!

## Summary/TLDR

My issues were:
- cargo bin directory not being in PATH, consider using `cargo sqlx ...` instead of `sqlx` commands in the justfile (tho this could be blamed on the user as even cargo warns about it when installing a tool)
- `DATABASE_URL` not being set, please write this down somewhere, like in `CONTRIBUTING.md`
- on slower machines [sleep 3](https://github.com/sebadob/rauthy/blob/c44db4b61e964e2584cb754367c5afa1f2ba81b9/justfile#L166) is too fast and the db doesn't have enough time to start up	


Getting the `cargo sqlx prepare` command working would still be the best solution, any ideas for that?
Edit: seems like `prepare` requires a live database, so later it can be compiled without a live db :(

## Details of figuring out the issues (feel free to not read it, I wrote it to clear up confusion and potentially help further contributors)

At the very first attempt, I ran `just setup`, that makes sure I have the cargo tools, the frontend is built with `just build-ui`, and the database (and mailcrab) is running in docker. After making a few system libraries available to Rauthy, the only error was with sqlx, I tried the `cargo sqlx preapre` from the error message and as you suggested:
```console
$ cargo sqlx prepare
error: failed to get package in current working directory, pass `--workspace` if running from a workspace root
```

After not thinking much and rerunning it with `--workspace` results with the sqlx errors:
```console
$ cargo sqlx prepare --workspace
    Checking h2 v0.3.26
    Checking encoding_rs v0.8.35
<similar output omitted>
    Checking rauthy-api-types v0.27.3 (/home/gep/forks/rauthy/src/api_types)                                                                                                                 
    Checking rauthy-models v0.27.3 (/home/gep/forks/rauthy/src/models)                                                                                                                       
error: set `DATABASE_URL` to use query macros online, or run `cargo sqlx prepare` to update the query cache                                                                                  
  --> src/models/src/entity/api_keys.rs:61:13                                                                                                                                                
   |                                                                                                                                                                                         
61 | /             query!(                                                                                                                                                                   
62 | |                 r#"                                                                                                                                                                   
63 | | INSERT INTO
64 | | api_keys (name, secret, created, expires, enc_key_id, access)
...  |
71 | |                 access_enc,
72 | |             )
   | |_____________^
   |
   = note: this error originates in the macro `$crate::sqlx_macros::expand_query` which comes from the expansion of the macro `query` (in Nightly builds, run with -Z macro-backtrace for mor
e info)
<similar output omitted>
```

(going into the `src/models` directory and running `cargo sqlx prepare` will repeat the sqlx errors)

I was (also) building from the v0.27.3 tag.

> To build Rauthy, you need access to a running Postgres with applied database migrations.

The database is up in docker:
```console
$ docker ps
CONTAINER ID   IMAGE                  COMMAND                  CREATED       STATUS       PORTS                                                                                  NAMES
f9ddcd288dbe   postgres:17.2-alpine   "docker-entrypoint.s…"   2 hours ago   Up 2 hours   0.0.0.0:5432->5432/tcp, :::5432->5432/tcp                                              rauthy-db-postgres
49a54b9a688b   marlonb/mailcrab       "/app/mailcrab"          2 hours ago   Up 2 hours   0.0.0.0:1025->1025/tcp, :::1025->1025/tcp, 0.0.0.0:1080->1080/tcp, :::1080->1080/tcp   rauthy-mailcrab
```

The postgresql database seems to not have any rauthy specific tables:

<details><summary>psql output</summary>

```console
$ psql -h localhost -p 5432 -d rauthy -U rauthy
Password for user rauthy: 
psql (17.2)
Type "help" for help.

rauthy=# \dt *.*
                          List of relations
       Schema       |           Name           |    Type     | Owner  
--------------------+--------------------------+-------------+--------
 information_schema | sql_features             | table       | rauthy
 information_schema | sql_implementation_info  | table       | rauthy
 information_schema | sql_parts                | table       | rauthy
 information_schema | sql_sizing               | table       | rauthy
 pg_catalog         | pg_aggregate             | table       | rauthy
 pg_catalog         | pg_am                    | table       | rauthy
 pg_catalog         | pg_amop                  | table       | rauthy
 pg_catalog         | pg_amproc                | table       | rauthy
 pg_catalog         | pg_attrdef               | table       | rauthy
 pg_catalog         | pg_attribute             | table       | rauthy
 pg_catalog         | pg_auth_members          | table       | rauthy
 pg_catalog         | pg_authid                | table       | rauthy
 pg_catalog         | pg_cast                  | table       | rauthy
 pg_catalog         | pg_class                 | table       | rauthy
 pg_catalog         | pg_collation             | table       | rauthy
 pg_catalog         | pg_constraint            | table       | rauthy
 pg_catalog         | pg_conversion            | table       | rauthy
 pg_catalog         | pg_database              | table       | rauthy
 pg_catalog         | pg_db_role_setting       | table       | rauthy
 pg_catalog         | pg_default_acl           | table       | rauthy
 pg_catalog         | pg_depend                | table       | rauthy
 pg_catalog         | pg_description           | table       | rauthy
 pg_catalog         | pg_enum                  | table       | rauthy
 pg_catalog         | pg_event_trigger         | table       | rauthy
 pg_catalog         | pg_extension             | table       | rauthy
 pg_catalog         | pg_foreign_data_wrapper  | table       | rauthy
 pg_catalog         | pg_foreign_server        | table       | rauthy
 pg_catalog         | pg_foreign_table         | table       | rauthy
 pg_catalog         | pg_index                 | table       | rauthy
 pg_catalog         | pg_inherits              | table       | rauthy
 pg_catalog         | pg_init_privs            | table       | rauthy
 pg_catalog         | pg_language              | table       | rauthy
 pg_catalog         | pg_largeobject           | table       | rauthy
 pg_catalog         | pg_largeobject_metadata  | table       | rauthy
 pg_catalog         | pg_namespace             | table       | rauthy
 pg_catalog         | pg_opclass               | table       | rauthy
 pg_catalog         | pg_operator              | table       | rauthy
 pg_catalog         | pg_opfamily              | table       | rauthy
 pg_catalog         | pg_parameter_acl         | table       | rauthy
 pg_catalog         | pg_partitioned_table     | table       | rauthy
 pg_catalog         | pg_policy                | table       | rauthy
 pg_catalog         | pg_proc                  | table       | rauthy
 pg_catalog         | pg_publication           | table       | rauthy
 pg_catalog         | pg_publication_namespace | table       | rauthy
 pg_catalog         | pg_publication_rel       | table       | rauthy
 pg_catalog         | pg_range                 | table       | rauthy
 pg_catalog         | pg_replication_origin    | table       | rauthy
 pg_catalog         | pg_rewrite               | table       | rauthy
 pg_catalog         | pg_seclabel              | table       | rauthy
 pg_catalog         | pg_sequence              | table       | rauthy
 pg_catalog         | pg_shdepend              | table       | rauthy
 pg_catalog         | pg_shdescription         | table       | rauthy
 pg_catalog         | pg_shseclabel            | table       | rauthy
 pg_catalog         | pg_statistic             | table       | rauthy
 pg_catalog         | pg_statistic_ext         | table       | rauthy
 pg_catalog         | pg_statistic_ext_data    | table       | rauthy
 pg_catalog         | pg_subscription          | table       | rauthy
 pg_catalog         | pg_subscription_rel      | table       | rauthy
 pg_catalog         | pg_tablespace            | table       | rauthy
 pg_catalog         | pg_transform             | table       | rauthy
 pg_catalog         | pg_trigger               | table       | rauthy
 pg_catalog         | pg_ts_config             | table       | rauthy
 pg_catalog         | pg_ts_config_map         | table       | rauthy
 pg_catalog         | pg_ts_dict               | table       | rauthy
 pg_catalog         | pg_ts_parser             | table       | rauthy
 pg_catalog         | pg_ts_template           | table       | rauthy
 pg_catalog         | pg_type                  | table       | rauthy
 pg_catalog         | pg_user_mapping          | table       | rauthy
 pg_toast           | pg_toast_1213            | TOAST table | rauthy
 pg_toast           | pg_toast_1247            | TOAST table | rauthy
 pg_toast           | pg_toast_1255            | TOAST table | rauthy
 pg_toast           | pg_toast_1260            | TOAST table | rauthy
 pg_toast           | pg_toast_1262            | TOAST table | rauthy
 pg_toast           | pg_toast_13445           | TOAST table | rauthy
 pg_toast           | pg_toast_13450           | TOAST table | rauthy
 pg_toast           | pg_toast_13455           | TOAST table | rauthy
 pg_toast           | pg_toast_13460           | TOAST table | rauthy
 pg_toast           | pg_toast_1417            | TOAST table | rauthy
 pg_toast           | pg_toast_1418            | TOAST table | rauthy
 pg_toast           | pg_toast_2328            | TOAST table | rauthy
 pg_toast           | pg_toast_2396            | TOAST table | rauthy
 pg_toast           | pg_toast_2600            | TOAST table | rauthy
 pg_toast           | pg_toast_2604            | TOAST table | rauthy
 pg_toast           | pg_toast_2606            | TOAST table | rauthy
 pg_toast           | pg_toast_2609            | TOAST table | rauthy
 pg_toast           | pg_toast_2612            | TOAST table | rauthy
 pg_toast           | pg_toast_2615            | TOAST table | rauthy
 pg_toast           | pg_toast_2618            | TOAST table | rauthy
 pg_toast           | pg_toast_2619            | TOAST table | rauthy
 pg_toast           | pg_toast_2620            | TOAST table | rauthy
 pg_toast           | pg_toast_2964            | TOAST table | rauthy
 pg_toast           | pg_toast_3079            | TOAST table | rauthy
 pg_toast           | pg_toast_3118            | TOAST table | rauthy
 pg_toast           | pg_toast_3256            | TOAST table | rauthy
 pg_toast           | pg_toast_3350            | TOAST table | rauthy
 pg_toast           | pg_toast_3381            | TOAST table | rauthy
 pg_toast           | pg_toast_3394            | TOAST table | rauthy
 pg_toast           | pg_toast_3429            | TOAST table | rauthy
 pg_toast           | pg_toast_3456            | TOAST table | rauthy
 pg_toast           | pg_toast_3466            | TOAST table | rauthy
 pg_toast           | pg_toast_3592            | TOAST table | rauthy
 pg_toast           | pg_toast_3596            | TOAST table | rauthy
 pg_toast           | pg_toast_3600            | TOAST table | rauthy
 pg_toast           | pg_toast_6000            | TOAST table | rauthy
 pg_toast           | pg_toast_6100            | TOAST table | rauthy
 pg_toast           | pg_toast_6106            | TOAST table | rauthy
 pg_toast           | pg_toast_6243            | TOAST table | rauthy
 pg_toast           | pg_toast_826             | TOAST table | rauthy
(108 rows)
```
</details>

After manually running `just backend-stop; just backend-start`, I noticed: `migrate-postgres: line 1: sqlx: command not found`. It's partially my fault as I haven't added the cargo bin directory to my PATH, however since it is installed I just edited the Justfile to do `cargo sqlx ...`. I'm surprised even some command failed with an exit code 127, I got exit code 0 (success) with `just backend-start`.

But the `DATABASE_URL` variable is unset:
```console
$ cargo sqlx migrate run --source migrations/postgres
error: the `--database-url` option or the `DATABASE_URL` environment variable must be provided
```

After setting it with `export DATABASE_URL="postgresql://rauthy:123SuperSafe@localhost:5432/rauthy"`, I get an error that the database hasn't booted up: `error: error returned from database: the database system is starting up`. Increasing the sleep from 3 to 10 seconds fixed it, migrations are applied and `cargo build` passes!


So it builds with a live postgresql database, but not with an sqlite, as the queries were written for only postgres, I guess I can't avoid running postgres for just building Rauthy:

[cargo build log](https://github.com/user-attachments/files/18304817/sqlite-postgres.log)

(by the way, why are there sqlite migrations if the app doesn't work with those database engines?)

Fix patch:
diff --git a/.gitignore b/.gitignore
index fc1f9f89d..90f1501d7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,5 +18,4 @@ templates/html/
 book/book
 out/
 .npm_cache
-.sqlx
 pnpm-lock.yaml
diff --git a/.sqlx/query-037a3eb8f28070ca848446024b04e30f4bd150bbe92e85a9cb1cdc482aad4d30.json b/.sqlx/query-037a3eb8f28070ca848446024b04e30f4bd150bbe92e85a9cb1cdc482aad4d30.json
new file mode 100644
index 000000000..66b65a6ae
--- /dev/null
+++ b/.sqlx/query-037a3eb8f28070ca848446024b04e30f4bd150bbe92e85a9cb1cdc482aad4d30.json
@@ -0,0 +1,42 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nSELECT auth_provider_id AS id, res, content_type, data\nFROM auth_provider_logos\nWHERE auth_provider_id = $1 AND (res = $2 OR res = $3)",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "res",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "content_type",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 3,
+        "name": "data",
+        "type_info": "Bytea"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text",
+        "Text",
+        "Text"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      false
+    ]
+  },
+  "hash": "037a3eb8f28070ca848446024b04e30f4bd150bbe92e85a9cb1cdc482aad4d30"
+}
diff --git a/.sqlx/query-03e0e1606773fcefcf325ed73225f637eb29599a4555170aa2475153e7f8043a.json b/.sqlx/query-03e0e1606773fcefcf325ed73225f637eb29599a4555170aa2475153e7f8043a.json
new file mode 100644
index 000000000..499f1e74b
--- /dev/null
+++ b/.sqlx/query-03e0e1606773fcefcf325ed73225f637eb29599a4555170aa2475153e7f8043a.json
@@ -0,0 +1,14 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "DELETE FROM devices WHERE id = $1",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "03e0e1606773fcefcf325ed73225f637eb29599a4555170aa2475153e7f8043a"
+}
diff --git a/.sqlx/query-04a136dc39ca6399e42a1069a7e06757db6f80fb488ed7c0e015cbb29e0557ca.json b/.sqlx/query-04a136dc39ca6399e42a1069a7e06757db6f80fb488ed7c0e015cbb29e0557ca.json
new file mode 100644
index 000000000..4702d036e
--- /dev/null
+++ b/.sqlx/query-04a136dc39ca6399e42a1069a7e06757db6f80fb488ed7c0e015cbb29e0557ca.json
@@ -0,0 +1,130 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM users WHERE user_expires < $1",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "email",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "given_name",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 3,
+        "name": "family_name",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 4,
+        "name": "password",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 5,
+        "name": "roles",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 6,
+        "name": "groups",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 7,
+        "name": "enabled",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 8,
+        "name": "email_verified",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 9,
+        "name": "password_expires",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 10,
+        "name": "created_at",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 11,
+        "name": "last_login",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 12,
+        "name": "last_failed_login",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 13,
+        "name": "failed_login_attempts",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 14,
+        "name": "language",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 15,
+        "name": "webauthn_user_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 16,
+        "name": "user_expires",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 17,
+        "name": "auth_provider_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 18,
+        "name": "federation_uid",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Int8"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      true,
+      true,
+      false,
+      true,
+      false,
+      false,
+      true,
+      false,
+      true,
+      true,
+      true,
+      false,
+      true,
+      true,
+      true,
+      true
+    ]
+  },
+  "hash": "04a136dc39ca6399e42a1069a7e06757db6f80fb488ed7c0e015cbb29e0557ca"
+}
diff --git a/.sqlx/query-04ff4fca8514ccab3d1599962fc287aa6e45d9aeacc28888ed11abb658505d03.json b/.sqlx/query-04ff4fca8514ccab3d1599962fc287aa6e45d9aeacc28888ed11abb658505d03.json
new file mode 100644
index 000000000..5d4bdd2ab
--- /dev/null
+++ b/.sqlx/query-04ff4fca8514ccab3d1599962fc287aa6e45d9aeacc28888ed11abb658505d03.json
@@ -0,0 +1,18 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nINSERT INTO jwks (kid, created_at, signature, enc_key_id, jwk)\nVALUES ($1, $2, $3, $4, $5)",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Int8",
+        "Varchar",
+        "Varchar",
+        "Bytea"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "04ff4fca8514ccab3d1599962fc287aa6e45d9aeacc28888ed11abb658505d03"
+}
diff --git a/.sqlx/query-0637fa9bc4aa44ce367de98c8bfa4a8762f0e4aff03f7c70611654cc49073889.json b/.sqlx/query-0637fa9bc4aa44ce367de98c8bfa4a8762f0e4aff03f7c70611654cc49073889.json
new file mode 100644
index 000000000..ff4f574ad
--- /dev/null
+++ b/.sqlx/query-0637fa9bc4aa44ce367de98c8bfa4a8762f0e4aff03f7c70611654cc49073889.json
@@ -0,0 +1,58 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM events ORDER BY timestamp DESC LIMIT $1",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "timestamp",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 2,
+        "name": "typ",
+        "type_info": "Int2"
+      },
+      {
+        "ordinal": 3,
+        "name": "level",
+        "type_info": "Int2"
+      },
+      {
+        "ordinal": 4,
+        "name": "ip",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 5,
+        "name": "data",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 6,
+        "name": "text",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Int8"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      false,
+      true,
+      true,
+      true
+    ]
+  },
+  "hash": "0637fa9bc4aa44ce367de98c8bfa4a8762f0e4aff03f7c70611654cc49073889"
+}
diff --git a/.sqlx/query-0ba48165a69eb14273647dab7bfdfea8218a0865e0b7cc037baf3971fec6ae04.json b/.sqlx/query-0ba48165a69eb14273647dab7bfdfea8218a0865e0b7cc037baf3971fec6ae04.json
new file mode 100644
index 000000000..bacf83dcf
--- /dev/null
+++ b/.sqlx/query-0ba48165a69eb14273647dab7bfdfea8218a0865e0b7cc037baf3971fec6ae04.json
@@ -0,0 +1,20 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nINSERT INTO events (id, timestamp, level, typ, ip, data, text)\nVALUES ($1, $2, $3, $4, $5, $6, $7)",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Int8",
+        "Int2",
+        "Int2",
+        "Varchar",
+        "Int8",
+        "Varchar"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "0ba48165a69eb14273647dab7bfdfea8218a0865e0b7cc037baf3971fec6ae04"
+}
diff --git a/.sqlx/query-0cbe41d7df5407eee6d7114994fa4907bb6451f57d64b0adc34e5308eb32514c.json b/.sqlx/query-0cbe41d7df5407eee6d7114994fa4907bb6451f57d64b0adc34e5308eb32514c.json
new file mode 100644
index 000000000..6c99d25da
--- /dev/null
+++ b/.sqlx/query-0cbe41d7df5407eee6d7114994fa4907bb6451f57d64b0adc34e5308eb32514c.json
@@ -0,0 +1,15 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "UPDATE refresh_tokens_devices SET exp = $1 WHERE exp > $1 AND user_id = $2",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Int8",
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "0cbe41d7df5407eee6d7114994fa4907bb6451f57d64b0adc34e5308eb32514c"
+}
diff --git a/.sqlx/query-0daa6956165b8f258a43e51cb6b2fd0e1a6cdd469858d883a2663377eb605c0a.json b/.sqlx/query-0daa6956165b8f258a43e51cb6b2fd0e1a6cdd469858d883a2663377eb605c0a.json
new file mode 100644
index 000000000..6bf157d73
--- /dev/null
+++ b/.sqlx/query-0daa6956165b8f258a43e51cb6b2fd0e1a6cdd469858d883a2663377eb605c0a.json
@@ -0,0 +1,17 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "UPDATE magic_links SET cookie = $1, exp = $2, used = $3 WHERE id = $4",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Int8",
+        "Bool",
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "0daa6956165b8f258a43e51cb6b2fd0e1a6cdd469858d883a2663377eb605c0a"
+}
diff --git a/.sqlx/query-0e654494cc4c050ba04873cced5a1beaf5c59e909b36c01b0f6b4ecdbea6d14c.json b/.sqlx/query-0e654494cc4c050ba04873cced5a1beaf5c59e909b36c01b0f6b4ecdbea6d14c.json
new file mode 100644
index 000000000..f9f185107
--- /dev/null
+++ b/.sqlx/query-0e654494cc4c050ba04873cced5a1beaf5c59e909b36c01b0f6b4ecdbea6d14c.json
@@ -0,0 +1,64 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM passkeys WHERE user_id = $1",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "user_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "name",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "passkey_user_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 3,
+        "name": "passkey",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 4,
+        "name": "credential_id",
+        "type_info": "Bytea"
+      },
+      {
+        "ordinal": 5,
+        "name": "registered",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 6,
+        "name": "last_used",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 7,
+        "name": "user_verified",
+        "type_info": "Bool"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      true
+    ]
+  },
+  "hash": "0e654494cc4c050ba04873cced5a1beaf5c59e909b36c01b0f6b4ecdbea6d14c"
+}
diff --git a/.sqlx/query-0f1c96b8d1f713855019d7ef2569e855de5f7925359644b4a8a767a23562274a.json b/.sqlx/query-0f1c96b8d1f713855019d7ef2569e855de5f7925359644b4a8a767a23562274a.json
new file mode 100644
index 000000000..23afce02c
--- /dev/null
+++ b/.sqlx/query-0f1c96b8d1f713855019d7ef2569e855de5f7925359644b4a8a767a23562274a.json
@@ -0,0 +1,14 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "DELETE FROM user_attr_values WHERE key = $1",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "0f1c96b8d1f713855019d7ef2569e855de5f7925359644b4a8a767a23562274a"
+}
diff --git a/.sqlx/query-0f964578478c4d051acf9a87f13c3ff3837a9c32cd56eea10b2f861c953d0438.json b/.sqlx/query-0f964578478c4d051acf9a87f13c3ff3837a9c32cd56eea10b2f861c953d0438.json
new file mode 100644
index 000000000..0dcad7841
--- /dev/null
+++ b/.sqlx/query-0f964578478c4d051acf9a87f13c3ff3837a9c32cd56eea10b2f861c953d0438.json
@@ -0,0 +1,17 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nINSERT INTO client_logos (client_id, res, content_type, data)\nVALUES ($1, $2, $3, $4)",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Bytea"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "0f964578478c4d051acf9a87f13c3ff3837a9c32cd56eea10b2f861c953d0438"
+}
diff --git a/.sqlx/query-10222707a2dc9b4adfb86497236447300744da9fc2b0896e8f16a88ca1d84d2e.json b/.sqlx/query-10222707a2dc9b4adfb86497236447300744da9fc2b0896e8f16a88ca1d84d2e.json
new file mode 100644
index 000000000..9b2dc028d
--- /dev/null
+++ b/.sqlx/query-10222707a2dc9b4adfb86497236447300744da9fc2b0896e8f16a88ca1d84d2e.json
@@ -0,0 +1,74 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM sessions ORDER BY exp DESC",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "csrf_token",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "user_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 3,
+        "name": "roles",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 4,
+        "name": "groups",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 5,
+        "name": "is_mfa",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 6,
+        "name": "state",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 7,
+        "name": "exp",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 8,
+        "name": "last_seen",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 9,
+        "name": "remote_ip",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": []
+    },
+    "nullable": [
+      false,
+      false,
+      true,
+      true,
+      true,
+      false,
+      false,
+      false,
+      false,
+      true
+    ]
+  },
+  "hash": "10222707a2dc9b4adfb86497236447300744da9fc2b0896e8f16a88ca1d84d2e"
+}
diff --git a/.sqlx/query-11393c919abf79fa170b844e79b54612626de7b436963d0853d7d765461b1aa3.json b/.sqlx/query-11393c919abf79fa170b844e79b54612626de7b436963d0853d7d765461b1aa3.json
new file mode 100644
index 000000000..1e8a68ccb
--- /dev/null
+++ b/.sqlx/query-11393c919abf79fa170b844e79b54612626de7b436963d0853d7d765461b1aa3.json
@@ -0,0 +1,15 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "DELETE FROM passkeys WHERE user_id = $1 AND name = $2",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Text",
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "11393c919abf79fa170b844e79b54612626de7b436963d0853d7d765461b1aa3"
+}
diff --git a/.sqlx/query-11675b0ef50a6cec3ee97b39dd65eda5614728e7394672f9ecce72ce5992696f.json b/.sqlx/query-11675b0ef50a6cec3ee97b39dd65eda5614728e7394672f9ecce72ce5992696f.json
new file mode 100644
index 000000000..d04bdc7a0
--- /dev/null
+++ b/.sqlx/query-11675b0ef50a6cec3ee97b39dd65eda5614728e7394672f9ecce72ce5992696f.json
@@ -0,0 +1,15 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "UPDATE clients_dyn SET last_used = $1 WHERE id = $2",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Int8",
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "11675b0ef50a6cec3ee97b39dd65eda5614728e7394672f9ecce72ce5992696f"
+}
diff --git a/.sqlx/query-11e96cfd8c2736f13ce55975ea910dd68640f6f14e38a4b3342d514804e3de27.json b/.sqlx/query-11e96cfd8c2736f13ce55975ea910dd68640f6f14e38a4b3342d514804e3de27.json
new file mode 100644
index 000000000..6fddc7b31
--- /dev/null
+++ b/.sqlx/query-11e96cfd8c2736f13ce55975ea910dd68640f6f14e38a4b3342d514804e3de27.json
@@ -0,0 +1,14 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "DELETE FROM sessions WHERE id = $1",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "11e96cfd8c2736f13ce55975ea910dd68640f6f14e38a4b3342d514804e3de27"
+}
diff --git a/.sqlx/query-124854aa2b1f6a82e097d86d1d1e5791e53ac2d4a54e75d7125cc4b1ca4ac9cb.json b/.sqlx/query-124854aa2b1f6a82e097d86d1d1e5791e53ac2d4a54e75d7125cc4b1ca4ac9cb.json
new file mode 100644
index 000000000..ad5084b34
--- /dev/null
+++ b/.sqlx/query-124854aa2b1f6a82e097d86d1d1e5791e53ac2d4a54e75d7125cc4b1ca4ac9cb.json
@@ -0,0 +1,28 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM roles WHERE id = $1",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "name",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": [
+      false,
+      false
+    ]
+  },
+  "hash": "124854aa2b1f6a82e097d86d1d1e5791e53ac2d4a54e75d7125cc4b1ca4ac9cb"
+}
diff --git a/.sqlx/query-13fee11f7e8bf1de4bfa28077cae3ed44b645240f0748fa9509e3f4db4072759.json b/.sqlx/query-13fee11f7e8bf1de4bfa28077cae3ed44b645240f0748fa9509e3f4db4072759.json
new file mode 100644
index 000000000..ffddec75f
--- /dev/null
+++ b/.sqlx/query-13fee11f7e8bf1de4bfa28077cae3ed44b645240f0748fa9509e3f4db4072759.json
@@ -0,0 +1,20 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nINSERT INTO\nusers_values (id, birthdate, phone, street, zip, city, country)\nVALUES ($1, $2, $3, $4, $5, $6, $7)\nON CONFLICT(id) DO UPDATE\nSET birthdate = $2, phone = $3, street = $4, zip = $5, city = $6, country = $7",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Int4",
+        "Varchar",
+        "Varchar"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "13fee11f7e8bf1de4bfa28077cae3ed44b645240f0748fa9509e3f4db4072759"
+}
diff --git a/.sqlx/query-156fe9f4e74a741cf85e5e05df8b34a8d9d054cd9aca91d0fa818b8dc8c20733.json b/.sqlx/query-156fe9f4e74a741cf85e5e05df8b34a8d9d054cd9aca91d0fa818b8dc8c20733.json
new file mode 100644
index 000000000..ba03bdc94
--- /dev/null
+++ b/.sqlx/query-156fe9f4e74a741cf85e5e05df8b34a8d9d054cd9aca91d0fa818b8dc8c20733.json
@@ -0,0 +1,14 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "DELETE FROM colors WHERE client_id = $1",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "156fe9f4e74a741cf85e5e05df8b34a8d9d054cd9aca91d0fa818b8dc8c20733"
+}
diff --git a/.sqlx/query-15a2a078631016bdbf49893b0d72f88de0ea450370064de69b21c108f5f87275.json b/.sqlx/query-15a2a078631016bdbf49893b0d72f88de0ea450370064de69b21c108f5f87275.json
new file mode 100644
index 000000000..c9311c7b6
--- /dev/null
+++ b/.sqlx/query-15a2a078631016bdbf49893b0d72f88de0ea450370064de69b21c108f5f87275.json
@@ -0,0 +1,33 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nINSERT INTO\nauth_providers (id, name, enabled, typ, issuer, authorization_endpoint, token_endpoint,\nuserinfo_endpoint, client_id, secret, scope, admin_claim_path, admin_claim_value,\nmfa_claim_path, mfa_claim_value, allow_insecure_requests, use_pkce, root_pem, client_secret_basic,\nclient_secret_post)\nVALUES\n($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20)",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar",
+        "Bool",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Bytea",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Bool",
+        "Bool",
+        "Varchar",
+        "Bool",
+        "Bool"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "15a2a078631016bdbf49893b0d72f88de0ea450370064de69b21c108f5f87275"
+}
diff --git a/.sqlx/query-16157c95c388e08aed9e0ecbf4804bbdff33426e6aca198468ae02d777d54f0d.json b/.sqlx/query-16157c95c388e08aed9e0ecbf4804bbdff33426e6aca198468ae02d777d54f0d.json
new file mode 100644
index 000000000..71872a8c4
--- /dev/null
+++ b/.sqlx/query-16157c95c388e08aed9e0ecbf4804bbdff33426e6aca198468ae02d777d54f0d.json
@@ -0,0 +1,32 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nINSERT INTO users\n(id, email, given_name, family_name, password, roles, groups, enabled, email_verified,\npassword_expires, created_at, last_login, last_failed_login, failed_login_attempts, language,\nwebauthn_user_id, user_expires, auth_provider_id, federation_uid)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19)",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Bool",
+        "Bool",
+        "Int8",
+        "Int8",
+        "Int8",
+        "Int8",
+        "Int8",
+        "Varchar",
+        "Varchar",
+        "Int8",
+        "Varchar",
+        "Varchar"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "16157c95c388e08aed9e0ecbf4804bbdff33426e6aca198468ae02d777d54f0d"
+}
diff --git a/.sqlx/query-19d826c4ec19cfa49ff7de48c392b64d75ef05321494aa62707b70d30e517d64.json b/.sqlx/query-19d826c4ec19cfa49ff7de48c392b64d75ef05321494aa62707b70d30e517d64.json
new file mode 100644
index 000000000..dc8f781e7
--- /dev/null
+++ b/.sqlx/query-19d826c4ec19cfa49ff7de48c392b64d75ef05321494aa62707b70d30e517d64.json
@@ -0,0 +1,14 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "UPDATE sessions SET exp = $1 WHERE exp > $1",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Int8"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "19d826c4ec19cfa49ff7de48c392b64d75ef05321494aa62707b70d30e517d64"
+}
diff --git a/.sqlx/query-1a9876f0cdc8875c1dc58a40d57e911e7e98c9c1c88158f0454838cd0b1414c0.json b/.sqlx/query-1a9876f0cdc8875c1dc58a40d57e911e7e98c9c1c88158f0454838cd0b1414c0.json
new file mode 100644
index 000000000..851191bb8
--- /dev/null
+++ b/.sqlx/query-1a9876f0cdc8875c1dc58a40d57e911e7e98c9c1c88158f0454838cd0b1414c0.json
@@ -0,0 +1,19 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nINSERT INTO\napi_keys (name, secret, created, expires, enc_key_id, access)\nVALUES ($1, $2, $3, $4, $5, $6)",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Bytea",
+        "Int8",
+        "Int8",
+        "Varchar",
+        "Bytea"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "1a9876f0cdc8875c1dc58a40d57e911e7e98c9c1c88158f0454838cd0b1414c0"
+}
diff --git a/.sqlx/query-1fa31f4388d7dc9bc592d451ad19ba93cfb9779a26f414ecc2358323737bc8d5.json b/.sqlx/query-1fa31f4388d7dc9bc592d451ad19ba93cfb9779a26f414ecc2358323737bc8d5.json
new file mode 100644
index 000000000..d2e196dcd
--- /dev/null
+++ b/.sqlx/query-1fa31f4388d7dc9bc592d451ad19ba93cfb9779a26f414ecc2358323737bc8d5.json
@@ -0,0 +1,17 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\n    INSERT INTO scopes (id, name, attr_include_access, attr_include_id)\n    VALUES ($1, $2, $3, $4)",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "1fa31f4388d7dc9bc592d451ad19ba93cfb9779a26f414ecc2358323737bc8d5"
+}
diff --git a/.sqlx/query-2095d507de0757267dc0c50a5bffc9c058b8185bfa09a0ff6eaaf8a6c04020e4.json b/.sqlx/query-2095d507de0757267dc0c50a5bffc9c058b8185bfa09a0ff6eaaf8a6c04020e4.json
new file mode 100644
index 000000000..d61b940e0
--- /dev/null
+++ b/.sqlx/query-2095d507de0757267dc0c50a5bffc9c058b8185bfa09a0ff6eaaf8a6c04020e4.json
@@ -0,0 +1,12 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "DELETE FROM users WHERE email IN ('init_admin@localhost.de', 'test_admin@localhost.de')",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": []
+    },
+    "nullable": []
+  },
+  "hash": "2095d507de0757267dc0c50a5bffc9c058b8185bfa09a0ff6eaaf8a6c04020e4"
+}
diff --git a/.sqlx/query-214486aa880d9439c6f9d987e98fd5949a6994e20bc9d6ff0a36ec9230a77504.json b/.sqlx/query-214486aa880d9439c6f9d987e98fd5949a6994e20bc9d6ff0a36ec9230a77504.json
new file mode 100644
index 000000000..eb6bf00e1
--- /dev/null
+++ b/.sqlx/query-214486aa880d9439c6f9d987e98fd5949a6994e20bc9d6ff0a36ec9230a77504.json
@@ -0,0 +1,15 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "INSERT INTO recent_passwords (user_id, passwords) VALUES ($1, $2)",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "214486aa880d9439c6f9d987e98fd5949a6994e20bc9d6ff0a36ec9230a77504"
+}
diff --git a/.sqlx/query-22305f8b217e5d443bb7f7a653fd8db637996eac64b79d267c86096f9f4754e5.json b/.sqlx/query-22305f8b217e5d443bb7f7a653fd8db637996eac64b79d267c86096f9f4754e5.json
new file mode 100644
index 000000000..f1ff5ec72
--- /dev/null
+++ b/.sqlx/query-22305f8b217e5d443bb7f7a653fd8db637996eac64b79d267c86096f9f4754e5.json
@@ -0,0 +1,30 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nUPDATE clients SET enabled = $1, confidential = $2, redirect_uris = $3,\npost_logout_redirect_uris = $4, allowed_origins = $5, flows_enabled = $6, access_token_alg = $7,\nid_token_alg = $8, auth_code_lifetime = $9, access_token_lifetime = $10, scopes = $11,\ndefault_scopes = $12, challenge = $13, force_mfa = $14, client_uri = $15, contacts = $16\nWHERE id = $17",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Bool",
+        "Bool",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Int4",
+        "Int4",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Bool",
+        "Varchar",
+        "Varchar",
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "22305f8b217e5d443bb7f7a653fd8db637996eac64b79d267c86096f9f4754e5"
+}
diff --git a/.sqlx/query-237b794a108dcba3977b598f8ac1c159cbf58d2d4c05b10eff9f421ee1f3c264.json b/.sqlx/query-237b794a108dcba3977b598f8ac1c159cbf58d2d4c05b10eff9f421ee1f3c264.json
new file mode 100644
index 000000000..a8643e618
--- /dev/null
+++ b/.sqlx/query-237b794a108dcba3977b598f8ac1c159cbf58d2d4c05b10eff9f421ee1f3c264.json
@@ -0,0 +1,23 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nINSERT INTO\nsessions (id, csrf_token, user_id, roles, groups, is_mfa, state, exp, last_seen, remote_ip)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)\nON CONFLICT(id) DO UPDATE\nSET user_id = $3, roles = $4, groups = $5, is_mfa = $6, state = $7, exp = $8, last_seen = $9,\nremote_ip = $10",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Bool",
+        "Varchar",
+        "Int8",
+        "Int8",
+        "Varchar"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "237b794a108dcba3977b598f8ac1c159cbf58d2d4c05b10eff9f421ee1f3c264"
+}
diff --git a/.sqlx/query-240eb4d3172d00b13a5183517551e9bb5a938f7b6baa940eab6dd3ca4f08a60f.json b/.sqlx/query-240eb4d3172d00b13a5183517551e9bb5a938f7b6baa940eab6dd3ca4f08a60f.json
new file mode 100644
index 000000000..7dc9f6aa6
--- /dev/null
+++ b/.sqlx/query-240eb4d3172d00b13a5183517551e9bb5a938f7b6baa940eab6dd3ca4f08a60f.json
@@ -0,0 +1,64 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM devices WHERE user_id = $1",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "client_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "user_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 3,
+        "name": "created",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 4,
+        "name": "access_exp",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 5,
+        "name": "refresh_exp",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 6,
+        "name": "peer_ip",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 7,
+        "name": "name",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      true,
+      false,
+      false,
+      true,
+      false,
+      false
+    ]
+  },
+  "hash": "240eb4d3172d00b13a5183517551e9bb5a938f7b6baa940eab6dd3ca4f08a60f"
+}
diff --git a/.sqlx/query-243d6ea1b927dd7ef2fc38e360b9c6aa418ba9ff4d84a6c79da9c575d0bbd875.json b/.sqlx/query-243d6ea1b927dd7ef2fc38e360b9c6aa418ba9ff4d84a6c79da9c575d0bbd875.json
new file mode 100644
index 000000000..73e466421
--- /dev/null
+++ b/.sqlx/query-243d6ea1b927dd7ef2fc38e360b9c6aa418ba9ff4d84a6c79da9c575d0bbd875.json
@@ -0,0 +1,14 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "DELETE FROM auth_providers WHERE id = $1",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "243d6ea1b927dd7ef2fc38e360b9c6aa418ba9ff4d84a6c79da9c575d0bbd875"
+}
diff --git a/.sqlx/query-2799bb888d45b55b53b66d2a219c5640421740852854ba36dbaedf7d16446f85.json b/.sqlx/query-2799bb888d45b55b53b66d2a219c5640421740852854ba36dbaedf7d16446f85.json
new file mode 100644
index 000000000..f0d59e0cb
--- /dev/null
+++ b/.sqlx/query-2799bb888d45b55b53b66d2a219c5640421740852854ba36dbaedf7d16446f85.json
@@ -0,0 +1,40 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM scopes WHERE id = $1",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "name",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "attr_include_access",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 3,
+        "name": "attr_include_id",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      true,
+      true
+    ]
+  },
+  "hash": "2799bb888d45b55b53b66d2a219c5640421740852854ba36dbaedf7d16446f85"
+}
diff --git a/.sqlx/query-28e1a6854f42c93677db574734a6cd010b821a6dc2b52060f76aca6e6f307b79.json b/.sqlx/query-28e1a6854f42c93677db574734a6cd010b821a6dc2b52060f76aca6e6f307b79.json
new file mode 100644
index 000000000..253552888
--- /dev/null
+++ b/.sqlx/query-28e1a6854f42c93677db574734a6cd010b821a6dc2b52060f76aca6e6f307b79.json
@@ -0,0 +1,19 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nINSERT INTO refresh_tokens (id, user_id, nbf, exp, scope, is_mfa)\nVALUES ($1, $2, $3, $4, $5, $6)\nON CONFLICT(id) DO UPDATE SET user_id = $2, nbf = $3, exp = $4, scope = $5",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar",
+        "Int8",
+        "Int8",
+        "Varchar",
+        "Bool"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "28e1a6854f42c93677db574734a6cd010b821a6dc2b52060f76aca6e6f307b79"
+}
diff --git a/.sqlx/query-2aa2cc335f172ceabd6165bbaa1f904345e5cf5e76885596d0ed9ce25b3408c8.json b/.sqlx/query-2aa2cc335f172ceabd6165bbaa1f904345e5cf5e76885596d0ed9ce25b3408c8.json
new file mode 100644
index 000000000..51a2ee5c7
--- /dev/null
+++ b/.sqlx/query-2aa2cc335f172ceabd6165bbaa1f904345e5cf5e76885596d0ed9ce25b3408c8.json
@@ -0,0 +1,20 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nINSERT INTO\nusers_values (id, birthdate, phone, street, zip, city, country)\nVALUES ($1, $2, $3, $4, $5, $6, $7)",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Int4",
+        "Varchar",
+        "Varchar"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "2aa2cc335f172ceabd6165bbaa1f904345e5cf5e76885596d0ed9ce25b3408c8"
+}
diff --git a/.sqlx/query-2b0c3bb4a98afdb826516d854255f30b5bb73c815f443cff7aada2bd0eb26b7d.json b/.sqlx/query-2b0c3bb4a98afdb826516d854255f30b5bb73c815f443cff7aada2bd0eb26b7d.json
new file mode 100644
index 000000000..718419942
--- /dev/null
+++ b/.sqlx/query-2b0c3bb4a98afdb826516d854255f30b5bb73c815f443cff7aada2bd0eb26b7d.json
@@ -0,0 +1,77 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM sessions WHERE user_id LIKE $1 ORDER BY exp DESC LIMIT $2",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "csrf_token",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "user_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 3,
+        "name": "roles",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 4,
+        "name": "groups",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 5,
+        "name": "is_mfa",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 6,
+        "name": "state",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 7,
+        "name": "exp",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 8,
+        "name": "last_seen",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 9,
+        "name": "remote_ip",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text",
+        "Int8"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      true,
+      true,
+      true,
+      false,
+      false,
+      false,
+      false,
+      true
+    ]
+  },
+  "hash": "2b0c3bb4a98afdb826516d854255f30b5bb73c815f443cff7aada2bd0eb26b7d"
+}
diff --git a/.sqlx/query-2b2c22855811b8ee18639f105a273abcf229349b9998b3a6357571f0a53abca6.json b/.sqlx/query-2b2c22855811b8ee18639f105a273abcf229349b9998b3a6357571f0a53abca6.json
new file mode 100644
index 000000000..f6fb4ad91
--- /dev/null
+++ b/.sqlx/query-2b2c22855811b8ee18639f105a273abcf229349b9998b3a6357571f0a53abca6.json
@@ -0,0 +1,15 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "INSERT INTO colors (client_id, data) VALUES ($1, $2)",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Bytea"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "2b2c22855811b8ee18639f105a273abcf229349b9998b3a6357571f0a53abca6"
+}
diff --git a/.sqlx/query-2ce1507126d500d74d34e9e2fc66a941a1b47579be029f2bc6248e07e077ff14.json b/.sqlx/query-2ce1507126d500d74d34e9e2fc66a941a1b47579be029f2bc6248e07e077ff14.json
new file mode 100644
index 000000000..8bf18c1eb
--- /dev/null
+++ b/.sqlx/query-2ce1507126d500d74d34e9e2fc66a941a1b47579be029f2bc6248e07e077ff14.json
@@ -0,0 +1,14 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "DELETE FROM client_logos WHERE client_id = $1",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "2ce1507126d500d74d34e9e2fc66a941a1b47579be029f2bc6248e07e077ff14"
+}
diff --git a/.sqlx/query-2d46c931ca50ed3c2f79029ae1349bb43b77eac5c32486320981a321f1caae29.json b/.sqlx/query-2d46c931ca50ed3c2f79029ae1349bb43b77eac5c32486320981a321f1caae29.json
new file mode 100644
index 000000000..b16093e16
--- /dev/null
+++ b/.sqlx/query-2d46c931ca50ed3c2f79029ae1349bb43b77eac5c32486320981a321f1caae29.json
@@ -0,0 +1,17 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nINSERT INTO scopes (id, name, attr_include_access, attr_include_id)\nVALUES ($1, $2, $3, $4)",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "2d46c931ca50ed3c2f79029ae1349bb43b77eac5c32486320981a321f1caae29"
+}
diff --git a/.sqlx/query-2fc08bf6746bea9ef7fffdfa81110dcb1bdaf62e50e4265dccaac0a084b43026.json b/.sqlx/query-2fc08bf6746bea9ef7fffdfa81110dcb1bdaf62e50e4265dccaac0a084b43026.json
new file mode 100644
index 000000000..f1096a480
--- /dev/null
+++ b/.sqlx/query-2fc08bf6746bea9ef7fffdfa81110dcb1bdaf62e50e4265dccaac0a084b43026.json
@@ -0,0 +1,28 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM user_attr_config WHERE name = $1",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "name",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "desc",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": [
+      false,
+      true
+    ]
+  },
+  "hash": "2fc08bf6746bea9ef7fffdfa81110dcb1bdaf62e50e4265dccaac0a084b43026"
+}
diff --git a/.sqlx/query-3081d25a15f1498a4280584a103b63f4c49c673f93cd7155410503628a201cbb.json b/.sqlx/query-3081d25a15f1498a4280584a103b63f4c49c673f93cd7155410503628a201cbb.json
new file mode 100644
index 000000000..30f8fb1c1
--- /dev/null
+++ b/.sqlx/query-3081d25a15f1498a4280584a103b63f4c49c673f93cd7155410503628a201cbb.json
@@ -0,0 +1,19 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nINSERT INTO themes (client_id, last_update, version, light, dark, border_radius)\nVALUES ($1, $2, $3, $4, $5, $6)\nON CONFLICT (client_id) DO UPDATE\nSET last_update = $2, version = $3, light = $4, dark = $5, border_radius = $6\n",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Int8",
+        "Int4",
+        "Bytea",
+        "Bytea",
+        "Varchar"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "3081d25a15f1498a4280584a103b63f4c49c673f93cd7155410503628a201cbb"
+}
diff --git a/.sqlx/query-31bb337b58b0b2fef82e3c8ed9005491600af57a1f64121e59df22990b1e70f1.json b/.sqlx/query-31bb337b58b0b2fef82e3c8ed9005491600af57a1f64121e59df22990b1e70f1.json
new file mode 100644
index 000000000..a0222df0a
--- /dev/null
+++ b/.sqlx/query-31bb337b58b0b2fef82e3c8ed9005491600af57a1f64121e59df22990b1e70f1.json
@@ -0,0 +1,53 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM refresh_tokens WHERE id = $1 AND exp > $2",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "user_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "nbf",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 3,
+        "name": "exp",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 4,
+        "name": "scope",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 5,
+        "name": "is_mfa",
+        "type_info": "Bool"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text",
+        "Int8"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      false,
+      true,
+      false
+    ]
+  },
+  "hash": "31bb337b58b0b2fef82e3c8ed9005491600af57a1f64121e59df22990b1e70f1"
+}
diff --git a/.sqlx/query-32e8a1b281fc416e24fc58d6efccace5e14f5efd4f005621af994e2c8e306fea.json b/.sqlx/query-32e8a1b281fc416e24fc58d6efccace5e14f5efd4f005621af994e2c8e306fea.json
new file mode 100644
index 000000000..570415347
--- /dev/null
+++ b/.sqlx/query-32e8a1b281fc416e24fc58d6efccace5e14f5efd4f005621af994e2c8e306fea.json
@@ -0,0 +1,15 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "UPDATE users SET email = $1, password = $2 WHERE email = 'admin@localhost.de'",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "32e8a1b281fc416e24fc58d6efccace5e14f5efd4f005621af994e2c8e306fea"
+}
diff --git a/.sqlx/query-33444b258ac57d932c09b20ff837f0eb4b39ada2d7faba81767b96b7774d16fc.json b/.sqlx/query-33444b258ac57d932c09b20ff837f0eb4b39ada2d7faba81767b96b7774d16fc.json
new file mode 100644
index 000000000..dd682db87
--- /dev/null
+++ b/.sqlx/query-33444b258ac57d932c09b20ff837f0eb4b39ada2d7faba81767b96b7774d16fc.json
@@ -0,0 +1,14 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "UPDATE devices SET refresh_exp = null WHERE id = $1",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "33444b258ac57d932c09b20ff837f0eb4b39ada2d7faba81767b96b7774d16fc"
+}
diff --git a/.sqlx/query-351d48d4d56a73bd899979e7af042aeb977384d557e212f9762d3cae8c422179.json b/.sqlx/query-351d48d4d56a73bd899979e7af042aeb977384d557e212f9762d3cae8c422179.json
new file mode 100644
index 000000000..9c96fdb87
--- /dev/null
+++ b/.sqlx/query-351d48d4d56a73bd899979e7af042aeb977384d557e212f9762d3cae8c422179.json
@@ -0,0 +1,44 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM clients_dyn WHERE last_used = null",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "created",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 2,
+        "name": "last_used",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 3,
+        "name": "registration_token",
+        "type_info": "Bytea"
+      },
+      {
+        "ordinal": 4,
+        "name": "token_endpoint_auth_method",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": []
+    },
+    "nullable": [
+      false,
+      false,
+      true,
+      false,
+      false
+    ]
+  },
+  "hash": "351d48d4d56a73bd899979e7af042aeb977384d557e212f9762d3cae8c422179"
+}
diff --git a/.sqlx/query-35787b7e283f7b0c0c5eb54d9aa2983e6cd7c0c9029548f1f38414e943fb26aa.json b/.sqlx/query-35787b7e283f7b0c0c5eb54d9aa2983e6cd7c0c9029548f1f38414e943fb26aa.json
new file mode 100644
index 000000000..b9cdf5a40
--- /dev/null
+++ b/.sqlx/query-35787b7e283f7b0c0c5eb54d9aa2983e6cd7c0c9029548f1f38414e943fb26aa.json
@@ -0,0 +1,18 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "INSERT INTO\n                jwks (kid, created_at, signature, enc_key_id, jwk)\n                VALUES ($1, $2, $3, $4, $5)",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Int8",
+        "Varchar",
+        "Varchar",
+        "Bytea"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "35787b7e283f7b0c0c5eb54d9aa2983e6cd7c0c9029548f1f38414e943fb26aa"
+}
diff --git a/.sqlx/query-369efd1d64f2e4cc39ac57e2f5bc9e706ba72188d7f174cff6036d0db102c22b.json b/.sqlx/query-369efd1d64f2e4cc39ac57e2f5bc9e706ba72188d7f174cff6036d0db102c22b.json
new file mode 100644
index 000000000..eec5b2727
--- /dev/null
+++ b/.sqlx/query-369efd1d64f2e4cc39ac57e2f5bc9e706ba72188d7f174cff6036d0db102c22b.json
@@ -0,0 +1,28 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM colors WHERE client_id = $1",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "client_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "data",
+        "type_info": "Bytea"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": [
+      false,
+      false
+    ]
+  },
+  "hash": "369efd1d64f2e4cc39ac57e2f5bc9e706ba72188d7f174cff6036d0db102c22b"
+}
diff --git a/.sqlx/query-385bb48006f303031b6cf6d5a68b205c11589286ff178b780cd7e9c1a203bf79.json b/.sqlx/query-385bb48006f303031b6cf6d5a68b205c11589286ff178b780cd7e9c1a203bf79.json
new file mode 100644
index 000000000..4e6427c90
--- /dev/null
+++ b/.sqlx/query-385bb48006f303031b6cf6d5a68b205c11589286ff178b780cd7e9c1a203bf79.json
@@ -0,0 +1,62 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM pg_tables WHERE tablename = 'clients' LIMIT 1",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "schemaname",
+        "type_info": "Name"
+      },
+      {
+        "ordinal": 1,
+        "name": "tablename",
+        "type_info": "Name"
+      },
+      {
+        "ordinal": 2,
+        "name": "tableowner",
+        "type_info": "Name"
+      },
+      {
+        "ordinal": 3,
+        "name": "tablespace",
+        "type_info": "Name"
+      },
+      {
+        "ordinal": 4,
+        "name": "hasindexes",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 5,
+        "name": "hasrules",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 6,
+        "name": "hastriggers",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 7,
+        "name": "rowsecurity",
+        "type_info": "Bool"
+      }
+    ],
+    "parameters": {
+      "Left": []
+    },
+    "nullable": [
+      true,
+      true,
+      true,
+      true,
+      true,
+      true,
+      true,
+      true
+    ]
+  },
+  "hash": "385bb48006f303031b6cf6d5a68b205c11589286ff178b780cd7e9c1a203bf79"
+}
diff --git a/.sqlx/query-389aaa7a60bfc78d399cbebb447c0e81eb05dce40eb59ec8c4a986634357113d.json b/.sqlx/query-389aaa7a60bfc78d399cbebb447c0e81eb05dce40eb59ec8c4a986634357113d.json
new file mode 100644
index 000000000..bfe672bb5
--- /dev/null
+++ b/.sqlx/query-389aaa7a60bfc78d399cbebb447c0e81eb05dce40eb59ec8c4a986634357113d.json
@@ -0,0 +1,58 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM magic_links WHERE id = $1",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "user_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "csrf_token",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 3,
+        "name": "cookie",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 4,
+        "name": "exp",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 5,
+        "name": "used",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 6,
+        "name": "usage",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      true,
+      false,
+      false,
+      false
+    ]
+  },
+  "hash": "389aaa7a60bfc78d399cbebb447c0e81eb05dce40eb59ec8c4a986634357113d"
+}
diff --git a/.sqlx/query-3ad7e466ae4956859619fed127a6143f2d34fd5c97d5020e6dae7453e5cbc39a.json b/.sqlx/query-3ad7e466ae4956859619fed127a6143f2d34fd5c97d5020e6dae7453e5cbc39a.json
new file mode 100644
index 000000000..2c0d740de
--- /dev/null
+++ b/.sqlx/query-3ad7e466ae4956859619fed127a6143f2d34fd5c97d5020e6dae7453e5cbc39a.json
@@ -0,0 +1,134 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM auth_providers",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "enabled",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 2,
+        "name": "name",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 3,
+        "name": "typ",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 4,
+        "name": "issuer",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 5,
+        "name": "authorization_endpoint",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 6,
+        "name": "token_endpoint",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 7,
+        "name": "userinfo_endpoint",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 8,
+        "name": "client_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 9,
+        "name": "secret",
+        "type_info": "Bytea"
+      },
+      {
+        "ordinal": 10,
+        "name": "scope",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 11,
+        "name": "admin_claim_path",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 12,
+        "name": "admin_claim_value",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 13,
+        "name": "mfa_claim_path",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 14,
+        "name": "mfa_claim_value",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 15,
+        "name": "allow_insecure_requests",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 16,
+        "name": "use_pkce",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 17,
+        "name": "root_pem",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 18,
+        "name": "client_secret_basic",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 19,
+        "name": "client_secret_post",
+        "type_info": "Bool"
+      }
+    ],
+    "parameters": {
+      "Left": []
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      true,
+      false,
+      true,
+      true,
+      true,
+      true,
+      false,
+      false,
+      true,
+      false,
+      false
+    ]
+  },
+  "hash": "3ad7e466ae4956859619fed127a6143f2d34fd5c97d5020e6dae7453e5cbc39a"
+}
diff --git a/.sqlx/query-3b1d4c9ee99e47060ba2996d008923019db899d8d3c04a2ae8196d20507953e0.json b/.sqlx/query-3b1d4c9ee99e47060ba2996d008923019db899d8d3c04a2ae8196d20507953e0.json
new file mode 100644
index 000000000..bc299e696
--- /dev/null
+++ b/.sqlx/query-3b1d4c9ee99e47060ba2996d008923019db899d8d3c04a2ae8196d20507953e0.json
@@ -0,0 +1,34 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM user_attr_values WHERE user_id = $1",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "user_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "key",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "value",
+        "type_info": "Bytea"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      false
+    ]
+  },
+  "hash": "3b1d4c9ee99e47060ba2996d008923019db899d8d3c04a2ae8196d20507953e0"
+}
diff --git a/.sqlx/query-423217b623b36610b226cd931f4bfcb048ca2793e2af0a34a5076b2596933c78.json b/.sqlx/query-423217b623b36610b226cd931f4bfcb048ca2793e2af0a34a5076b2596933c78.json
new file mode 100644
index 000000000..9b180d84d
--- /dev/null
+++ b/.sqlx/query-423217b623b36610b226cd931f4bfcb048ca2793e2af0a34a5076b2596933c78.json
@@ -0,0 +1,58 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM magic_links WHERE user_id = $1",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "user_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "csrf_token",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 3,
+        "name": "cookie",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 4,
+        "name": "exp",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 5,
+        "name": "used",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 6,
+        "name": "usage",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      true,
+      false,
+      false,
+      false
+    ]
+  },
+  "hash": "423217b623b36610b226cd931f4bfcb048ca2793e2af0a34a5076b2596933c78"
+}
diff --git a/.sqlx/query-4353622ec8d18c5ace32c3b0579638333b49de599d74787471656df6c251a7ed.json b/.sqlx/query-4353622ec8d18c5ace32c3b0579638333b49de599d74787471656df6c251a7ed.json
new file mode 100644
index 000000000..0a9b4df1a
--- /dev/null
+++ b/.sqlx/query-4353622ec8d18c5ace32c3b0579638333b49de599d74787471656df6c251a7ed.json
@@ -0,0 +1,77 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nSELECT *\nFROM sessions\nORDER BY exp DESC\nLIMIT $1\nOFFSET $2",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "csrf_token",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "user_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 3,
+        "name": "roles",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 4,
+        "name": "groups",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 5,
+        "name": "is_mfa",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 6,
+        "name": "state",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 7,
+        "name": "exp",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 8,
+        "name": "last_seen",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 9,
+        "name": "remote_ip",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Int8",
+        "Int8"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      true,
+      true,
+      true,
+      false,
+      false,
+      false,
+      false,
+      true
+    ]
+  },
+  "hash": "4353622ec8d18c5ace32c3b0579638333b49de599d74787471656df6c251a7ed"
+}
diff --git a/.sqlx/query-463e3cb3cc41990e508d9159e6e4043629edcc6761ce8ccaddfafc51523b2991.json b/.sqlx/query-463e3cb3cc41990e508d9159e6e4043629edcc6761ce8ccaddfafc51523b2991.json
new file mode 100644
index 000000000..ecfa23868
--- /dev/null
+++ b/.sqlx/query-463e3cb3cc41990e508d9159e6e4043629edcc6761ce8ccaddfafc51523b2991.json
@@ -0,0 +1,14 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "DELETE FROM roles WHERE id = $1",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "463e3cb3cc41990e508d9159e6e4043629edcc6761ce8ccaddfafc51523b2991"
+}
diff --git a/.sqlx/query-486ee0c26ef5f92b1f3464867649b80a4c8bde3ec2c2ef303480087ca7df5964.json b/.sqlx/query-486ee0c26ef5f92b1f3464867649b80a4c8bde3ec2c2ef303480087ca7df5964.json
new file mode 100644
index 000000000..cc9d8e6c0
--- /dev/null
+++ b/.sqlx/query-486ee0c26ef5f92b1f3464867649b80a4c8bde3ec2c2ef303480087ca7df5964.json
@@ -0,0 +1,77 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nSELECT *\nFROM sessions\nORDER BY exp ASC\nLIMIT $1\nOFFSET $2",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "csrf_token",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "user_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 3,
+        "name": "roles",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 4,
+        "name": "groups",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 5,
+        "name": "is_mfa",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 6,
+        "name": "state",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 7,
+        "name": "exp",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 8,
+        "name": "last_seen",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 9,
+        "name": "remote_ip",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Int8",
+        "Int8"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      true,
+      true,
+      true,
+      false,
+      false,
+      false,
+      false,
+      true
+    ]
+  },
+  "hash": "486ee0c26ef5f92b1f3464867649b80a4c8bde3ec2c2ef303480087ca7df5964"
+}
diff --git a/.sqlx/query-4996341c15f229487e85e2658724cab9e362e61d7e2132fda057451097629fd7.json b/.sqlx/query-4996341c15f229487e85e2658724cab9e362e61d7e2132fda057451097629fd7.json
new file mode 100644
index 000000000..f66ecb455
--- /dev/null
+++ b/.sqlx/query-4996341c15f229487e85e2658724cab9e362e61d7e2132fda057451097629fd7.json
@@ -0,0 +1,46 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM jwks WHERE kid = $1",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "kid",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "created_at",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 2,
+        "name": "signature",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 3,
+        "name": "enc_key_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 4,
+        "name": "jwk",
+        "type_info": "Bytea"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      false,
+      false
+    ]
+  },
+  "hash": "4996341c15f229487e85e2658724cab9e362e61d7e2132fda057451097629fd7"
+}
diff --git a/.sqlx/query-4a66675865cbc907fe1329042b56156d62749c82420b58d8c5b44d519c254945.json b/.sqlx/query-4a66675865cbc907fe1329042b56156d62749c82420b58d8c5b44d519c254945.json
new file mode 100644
index 000000000..6dc2e6b82
--- /dev/null
+++ b/.sqlx/query-4a66675865cbc907fe1329042b56156d62749c82420b58d8c5b44d519c254945.json
@@ -0,0 +1,18 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nINSERT INTO\nclients_dyn (id, created, last_used, registration_token, token_endpoint_auth_method)\nVALUES ($1, $2, $3, $4, $5)",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Int8",
+        "Int8",
+        "Bytea",
+        "Varchar"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "4a66675865cbc907fe1329042b56156d62749c82420b58d8c5b44d519c254945"
+}
diff --git a/.sqlx/query-4c04057c904a6a10e3434de73f93604a115486f45fd886f642a3fc5c71e2d929.json b/.sqlx/query-4c04057c904a6a10e3434de73f93604a115486f45fd886f642a3fc5c71e2d929.json
new file mode 100644
index 000000000..e5e5335c1
--- /dev/null
+++ b/.sqlx/query-4c04057c904a6a10e3434de73f93604a115486f45fd886f642a3fc5c71e2d929.json
@@ -0,0 +1,14 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "DELETE FROM refresh_tokens_devices WHERE id = $1",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "4c04057c904a6a10e3434de73f93604a115486f45fd886f642a3fc5c71e2d929"
+}
diff --git a/.sqlx/query-50293c2e54af11d4c2a553e29b671cef087a159c6ee7182d8ca929ecb748f3b7.json b/.sqlx/query-50293c2e54af11d4c2a553e29b671cef087a159c6ee7182d8ca929ecb748f3b7.json
new file mode 100644
index 000000000..412749b47
--- /dev/null
+++ b/.sqlx/query-50293c2e54af11d4c2a553e29b671cef087a159c6ee7182d8ca929ecb748f3b7.json
@@ -0,0 +1,14 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "DELETE FROM users WHERE id = $1",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "50293c2e54af11d4c2a553e29b671cef087a159c6ee7182d8ca929ecb748f3b7"
+}
diff --git a/.sqlx/query-51fa92c15cf8cbf6c530ef83c6bf1c5c01cdc2aa4044393dd2d1b8ac817e9b89.json b/.sqlx/query-51fa92c15cf8cbf6c530ef83c6bf1c5c01cdc2aa4044393dd2d1b8ac817e9b89.json
new file mode 100644
index 000000000..315f90b52
--- /dev/null
+++ b/.sqlx/query-51fa92c15cf8cbf6c530ef83c6bf1c5c01cdc2aa4044393dd2d1b8ac817e9b89.json
@@ -0,0 +1,16 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\n    UPDATE scopes\n    SET attr_include_access = $1, attr_include_id = $2\n    WHERE id = $3",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar",
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "51fa92c15cf8cbf6c530ef83c6bf1c5c01cdc2aa4044393dd2d1b8ac817e9b89"
+}
diff --git a/.sqlx/query-53e11cda5ecc597c03b4ca46ec126e1fc76292c565f558da2cae22c335fee0cf.json b/.sqlx/query-53e11cda5ecc597c03b4ca46ec126e1fc76292c565f558da2cae22c335fee0cf.json
new file mode 100644
index 000000000..cd4fb29db
--- /dev/null
+++ b/.sqlx/query-53e11cda5ecc597c03b4ca46ec126e1fc76292c565f558da2cae22c335fee0cf.json
@@ -0,0 +1,128 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM users ORDER BY created_at ASC",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "email",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "given_name",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 3,
+        "name": "family_name",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 4,
+        "name": "password",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 5,
+        "name": "roles",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 6,
+        "name": "groups",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 7,
+        "name": "enabled",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 8,
+        "name": "email_verified",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 9,
+        "name": "password_expires",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 10,
+        "name": "created_at",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 11,
+        "name": "last_login",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 12,
+        "name": "last_failed_login",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 13,
+        "name": "failed_login_attempts",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 14,
+        "name": "language",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 15,
+        "name": "webauthn_user_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 16,
+        "name": "user_expires",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 17,
+        "name": "auth_provider_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 18,
+        "name": "federation_uid",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": []
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      true,
+      true,
+      false,
+      true,
+      false,
+      false,
+      true,
+      false,
+      true,
+      true,
+      true,
+      false,
+      true,
+      true,
+      true,
+      true
+    ]
+  },
+  "hash": "53e11cda5ecc597c03b4ca46ec126e1fc76292c565f558da2cae22c335fee0cf"
+}
diff --git a/.sqlx/query-55c5c1e34b424899ac4a8afb9e2081e87d5703779b83922eedb7c95a3ecb7767.json b/.sqlx/query-55c5c1e34b424899ac4a8afb9e2081e87d5703779b83922eedb7c95a3ecb7767.json
new file mode 100644
index 000000000..01c272b49
--- /dev/null
+++ b/.sqlx/query-55c5c1e34b424899ac4a8afb9e2081e87d5703779b83922eedb7c95a3ecb7767.json
@@ -0,0 +1,15 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "DELETE FROM user_attr_values WHERE user_id = $1 AND key = $2",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Text",
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "55c5c1e34b424899ac4a8afb9e2081e87d5703779b83922eedb7c95a3ecb7767"
+}
diff --git a/.sqlx/query-57251ada1b28f473e85c51e63a74b4d3acea0f46d27797f95d9e81e77602f695.json b/.sqlx/query-57251ada1b28f473e85c51e63a74b4d3acea0f46d27797f95d9e81e77602f695.json
new file mode 100644
index 000000000..7dfc538f1
--- /dev/null
+++ b/.sqlx/query-57251ada1b28f473e85c51e63a74b4d3acea0f46d27797f95d9e81e77602f695.json
@@ -0,0 +1,14 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "DELETE FROM magic_links WHERE user_id = $1 AND USAGE LIKE 'email_change$%'",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "57251ada1b28f473e85c51e63a74b4d3acea0f46d27797f95d9e81e77602f695"
+}
diff --git a/.sqlx/query-57d3a0eb814e2b16418a2a07f4cb43ebe0cccab8b24f1ed8f7f2854fb71019dc.json b/.sqlx/query-57d3a0eb814e2b16418a2a07f4cb43ebe0cccab8b24f1ed8f7f2854fb71019dc.json
new file mode 100644
index 000000000..5720dd97c
--- /dev/null
+++ b/.sqlx/query-57d3a0eb814e2b16418a2a07f4cb43ebe0cccab8b24f1ed8f7f2854fb71019dc.json
@@ -0,0 +1,17 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nUPDATE scopes\nSET name = $1, attr_include_access = $2, attr_include_id = $3\nWHERE id = $4",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "57d3a0eb814e2b16418a2a07f4cb43ebe0cccab8b24f1ed8f7f2854fb71019dc"
+}
diff --git a/.sqlx/query-5899d9d79fb72e9cdcdc5e3c1483b0cc26e0bd1bd73c61aa17adca1f1c12d1c6.json b/.sqlx/query-5899d9d79fb72e9cdcdc5e3c1483b0cc26e0bd1bd73c61aa17adca1f1c12d1c6.json
new file mode 100644
index 000000000..7df081cc0
--- /dev/null
+++ b/.sqlx/query-5899d9d79fb72e9cdcdc5e3c1483b0cc26e0bd1bd73c61aa17adca1f1c12d1c6.json
@@ -0,0 +1,31 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nINSERT INTO\nauth_providers (id, enabled, name, typ, issuer, authorization_endpoint, token_endpoint,\nuserinfo_endpoint, client_id, secret, scope, admin_claim_path, admin_claim_value, mfa_claim_path,\nmfa_claim_value, allow_insecure_requests, use_pkce, root_pem)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18)",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Bool",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Bytea",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Bool",
+        "Bool",
+        "Varchar"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "5899d9d79fb72e9cdcdc5e3c1483b0cc26e0bd1bd73c61aa17adca1f1c12d1c6"
+}
diff --git a/.sqlx/query-5a4c6dc084216ae01034238e8cd252213c5143c11d83daf0fa4dab827b308753.json b/.sqlx/query-5a4c6dc084216ae01034238e8cd252213c5143c11d83daf0fa4dab827b308753.json
new file mode 100644
index 000000000..2766f1668
--- /dev/null
+++ b/.sqlx/query-5a4c6dc084216ae01034238e8cd252213c5143c11d83daf0fa4dab827b308753.json
@@ -0,0 +1,17 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nUPDATE passkeys\nSET passkey = $1, last_used = $2\nWHERE user_id = $3 AND name = $4",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Int8",
+        "Text",
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "5a4c6dc084216ae01034238e8cd252213c5143c11d83daf0fa4dab827b308753"
+}
diff --git a/.sqlx/query-5dd70008e95ab28c0000b98286244543011dbe3fe8af42fd77609ab6edbed7cf.json b/.sqlx/query-5dd70008e95ab28c0000b98286244543011dbe3fe8af42fd77609ab6edbed7cf.json
new file mode 100644
index 000000000..ec5e6f876
--- /dev/null
+++ b/.sqlx/query-5dd70008e95ab28c0000b98286244543011dbe3fe8af42fd77609ab6edbed7cf.json
@@ -0,0 +1,14 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\n    DELETE FROM devices\n    WHERE access_exp < $1\n    AND (refresh_exp IS NULL OR refresh_exp < $1)",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Int8"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "5dd70008e95ab28c0000b98286244543011dbe3fe8af42fd77609ab6edbed7cf"
+}
diff --git a/.sqlx/query-606661737a113501248d1422ea66496488aca69bf7d78349c4c8bbf835646db2.json b/.sqlx/query-606661737a113501248d1422ea66496488aca69bf7d78349c4c8bbf835646db2.json
new file mode 100644
index 000000000..3f7e6c72b
--- /dev/null
+++ b/.sqlx/query-606661737a113501248d1422ea66496488aca69bf7d78349c4c8bbf835646db2.json
@@ -0,0 +1,14 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "DELETE FROM events WHERE timestamp < $1",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Int8"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "606661737a113501248d1422ea66496488aca69bf7d78349c4c8bbf835646db2"
+}
diff --git a/.sqlx/query-61e17e84439a395594a3175b31dc14481c3ca036bc769b294689ffd9d7adef13.json b/.sqlx/query-61e17e84439a395594a3175b31dc14481c3ca036bc769b294689ffd9d7adef13.json
new file mode 100644
index 000000000..17c68a957
--- /dev/null
+++ b/.sqlx/query-61e17e84439a395594a3175b31dc14481c3ca036bc769b294689ffd9d7adef13.json
@@ -0,0 +1,15 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "UPDATE recent_passwords SET passwords = $1 WHERE user_id = $2",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "61e17e84439a395594a3175b31dc14481c3ca036bc769b294689ffd9d7adef13"
+}
diff --git a/.sqlx/query-67743e31585c022bc934cfcf30d43578964b07dfa2370e0cce5542cb0fc721f5.json b/.sqlx/query-67743e31585c022bc934cfcf30d43578964b07dfa2370e0cce5542cb0fc721f5.json
new file mode 100644
index 000000000..1c5cc3ec0
--- /dev/null
+++ b/.sqlx/query-67743e31585c022bc934cfcf30d43578964b07dfa2370e0cce5542cb0fc721f5.json
@@ -0,0 +1,15 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "UPDATE api_keys SET secret = $1 WHERE name = $2",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Bytea",
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "67743e31585c022bc934cfcf30d43578964b07dfa2370e0cce5542cb0fc721f5"
+}
diff --git a/.sqlx/query-6970add03eae90073a9044c97178dcc2e8c2916f2a5519e35bca4ec1b7cf6369.json b/.sqlx/query-6970add03eae90073a9044c97178dcc2e8c2916f2a5519e35bca4ec1b7cf6369.json
new file mode 100644
index 000000000..b5ccfdf36
--- /dev/null
+++ b/.sqlx/query-6970add03eae90073a9044c97178dcc2e8c2916f2a5519e35bca4ec1b7cf6369.json
@@ -0,0 +1,26 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM user_attr_config",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "name",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "desc",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": []
+    },
+    "nullable": [
+      false,
+      true
+    ]
+  },
+  "hash": "6970add03eae90073a9044c97178dcc2e8c2916f2a5519e35bca4ec1b7cf6369"
+}
diff --git a/.sqlx/query-6976d14d278240601142ec0fc82c4ed566679e0dd350accb33f79ebd6bba3a26.json b/.sqlx/query-6976d14d278240601142ec0fc82c4ed566679e0dd350accb33f79ebd6bba3a26.json
new file mode 100644
index 000000000..72ae75f98
--- /dev/null
+++ b/.sqlx/query-6976d14d278240601142ec0fc82c4ed566679e0dd350accb33f79ebd6bba3a26.json
@@ -0,0 +1,20 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT data FROM config WHERE id = 'db_version'",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "data",
+        "type_info": "Bytea"
+      }
+    ],
+    "parameters": {
+      "Left": []
+    },
+    "nullable": [
+      true
+    ]
+  },
+  "hash": "6976d14d278240601142ec0fc82c4ed566679e0dd350accb33f79ebd6bba3a26"
+}
diff --git a/.sqlx/query-6b535da232b3d79333a537faf6746a02054b8660e4f9f7d9b0002dd12fffd743.json b/.sqlx/query-6b535da232b3d79333a537faf6746a02054b8660e4f9f7d9b0002dd12fffd743.json
new file mode 100644
index 000000000..2ad3129f5
--- /dev/null
+++ b/.sqlx/query-6b535da232b3d79333a537faf6746a02054b8660e4f9f7d9b0002dd12fffd743.json
@@ -0,0 +1,136 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM auth_providers WHERE id = $1",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "enabled",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 2,
+        "name": "name",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 3,
+        "name": "typ",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 4,
+        "name": "issuer",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 5,
+        "name": "authorization_endpoint",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 6,
+        "name": "token_endpoint",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 7,
+        "name": "userinfo_endpoint",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 8,
+        "name": "client_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 9,
+        "name": "secret",
+        "type_info": "Bytea"
+      },
+      {
+        "ordinal": 10,
+        "name": "scope",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 11,
+        "name": "admin_claim_path",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 12,
+        "name": "admin_claim_value",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 13,
+        "name": "mfa_claim_path",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 14,
+        "name": "mfa_claim_value",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 15,
+        "name": "allow_insecure_requests",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 16,
+        "name": "use_pkce",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 17,
+        "name": "root_pem",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 18,
+        "name": "client_secret_basic",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 19,
+        "name": "client_secret_post",
+        "type_info": "Bool"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      true,
+      false,
+      true,
+      true,
+      true,
+      true,
+      false,
+      false,
+      true,
+      false,
+      false
+    ]
+  },
+  "hash": "6b535da232b3d79333a537faf6746a02054b8660e4f9f7d9b0002dd12fffd743"
+}
diff --git a/.sqlx/query-6e15f595be153045948c0b5e3d1f1a2c79147cfb2a1ef92a458e1793e69d600c.json b/.sqlx/query-6e15f595be153045948c0b5e3d1f1a2c79147cfb2a1ef92a458e1793e69d600c.json
new file mode 100644
index 000000000..0526d5a8f
--- /dev/null
+++ b/.sqlx/query-6e15f595be153045948c0b5e3d1f1a2c79147cfb2a1ef92a458e1793e69d600c.json
@@ -0,0 +1,14 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "DELETE FROM refresh_tokens WHERE id = $1",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "6e15f595be153045948c0b5e3d1f1a2c79147cfb2a1ef92a458e1793e69d600c"
+}
diff --git a/.sqlx/query-6f1201e5eb2d42328104503c873eef0f4ecade1749323d7da2f5c58ed70e088f.json b/.sqlx/query-6f1201e5eb2d42328104503c873eef0f4ecade1749323d7da2f5c58ed70e088f.json
new file mode 100644
index 000000000..dad070917
--- /dev/null
+++ b/.sqlx/query-6f1201e5eb2d42328104503c873eef0f4ecade1749323d7da2f5c58ed70e088f.json
@@ -0,0 +1,33 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nINSERT INTO clients (id, name, enabled, confidential, secret, secret_kid, redirect_uris,\npost_logout_redirect_uris, allowed_origins, flows_enabled, access_token_alg, id_token_alg,\nauth_code_lifetime, access_token_lifetime, scopes, default_scopes, challenge, force_mfa,\nclient_uri, contacts)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20)",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar",
+        "Bool",
+        "Bool",
+        "Bytea",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Int4",
+        "Int4",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Bool",
+        "Varchar",
+        "Varchar"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "6f1201e5eb2d42328104503c873eef0f4ecade1749323d7da2f5c58ed70e088f"
+}
diff --git a/.sqlx/query-71aa1997e2abc557307483f8ce79dc0c2f2e2765e2fd58167b9a948fdc598a19.json b/.sqlx/query-71aa1997e2abc557307483f8ce79dc0c2f2e2765e2fd58167b9a948fdc598a19.json
new file mode 100644
index 000000000..c29690a42
--- /dev/null
+++ b/.sqlx/query-71aa1997e2abc557307483f8ce79dc0c2f2e2765e2fd58167b9a948fdc598a19.json
@@ -0,0 +1,14 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "INSERT INTO config (id, data)\n                    VALUES ('db_version', $1)\n                    ON CONFLICT(id) DO UPDATE SET data = $1",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Bytea"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "71aa1997e2abc557307483f8ce79dc0c2f2e2765e2fd58167b9a948fdc598a19"
+}
diff --git a/.sqlx/query-7222531d12b3801147937dac42d1e0ef7a683f05871636762dff25ebf6f562da.json b/.sqlx/query-7222531d12b3801147937dac42d1e0ef7a683f05871636762dff25ebf6f562da.json
new file mode 100644
index 000000000..a5f9c6b80
--- /dev/null
+++ b/.sqlx/query-7222531d12b3801147937dac42d1e0ef7a683f05871636762dff25ebf6f562da.json
@@ -0,0 +1,28 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT id, email FROM users WHERE auth_provider_id = $1",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "email",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": [
+      false,
+      false
+    ]
+  },
+  "hash": "7222531d12b3801147937dac42d1e0ef7a683f05871636762dff25ebf6f562da"
+}
diff --git a/.sqlx/query-7541d99e248a3b2ea1de9028ce23fa53b29a99f3c452a76e2c68219cebeba3b8.json b/.sqlx/query-7541d99e248a3b2ea1de9028ce23fa53b29a99f3c452a76e2c68219cebeba3b8.json
new file mode 100644
index 000000000..86f2eed72
--- /dev/null
+++ b/.sqlx/query-7541d99e248a3b2ea1de9028ce23fa53b29a99f3c452a76e2c68219cebeba3b8.json
@@ -0,0 +1,14 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "DELETE FROM scopes WHERE id = $1",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "7541d99e248a3b2ea1de9028ce23fa53b29a99f3c452a76e2c68219cebeba3b8"
+}
diff --git a/.sqlx/query-76db4a13ef6cafdc7b58d1a92fe0a1cdcbeeec1a8e40c183e21073041f766ada.json b/.sqlx/query-76db4a13ef6cafdc7b58d1a92fe0a1cdcbeeec1a8e40c183e21073041f766ada.json
new file mode 100644
index 000000000..c4df24d32
--- /dev/null
+++ b/.sqlx/query-76db4a13ef6cafdc7b58d1a92fe0a1cdcbeeec1a8e40c183e21073041f766ada.json
@@ -0,0 +1,22 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT credential_id FROM passkeys WHERE user_id = $1",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "credential_id",
+        "type_info": "Bytea"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": [
+      false
+    ]
+  },
+  "hash": "76db4a13ef6cafdc7b58d1a92fe0a1cdcbeeec1a8e40c183e21073041f766ada"
+}
diff --git a/.sqlx/query-77b46df625319d4c6e165b071017bf20483a8945b0fdd6f7e7323365a47181ff.json b/.sqlx/query-77b46df625319d4c6e165b071017bf20483a8945b0fdd6f7e7323365a47181ff.json
new file mode 100644
index 000000000..0de41cff0
--- /dev/null
+++ b/.sqlx/query-77b46df625319d4c6e165b071017bf20483a8945b0fdd6f7e7323365a47181ff.json
@@ -0,0 +1,46 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM clients_dyn WHERE id = $1",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "created",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 2,
+        "name": "last_used",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 3,
+        "name": "registration_token",
+        "type_info": "Bytea"
+      },
+      {
+        "ordinal": 4,
+        "name": "token_endpoint_auth_method",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      true,
+      false,
+      false
+    ]
+  },
+  "hash": "77b46df625319d4c6e165b071017bf20483a8945b0fdd6f7e7323365a47181ff"
+}
diff --git a/.sqlx/query-77b7fa71315ea7d015df56bab71d78a4d5acb35bad052714237453b11cd67423.json b/.sqlx/query-77b7fa71315ea7d015df56bab71d78a4d5acb35bad052714237453b11cd67423.json
new file mode 100644
index 000000000..89ea0c30c
--- /dev/null
+++ b/.sqlx/query-77b7fa71315ea7d015df56bab71d78a4d5acb35bad052714237453b11cd67423.json
@@ -0,0 +1,14 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "DELETE FROM refresh_tokens WHERE user_id = $1",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "77b7fa71315ea7d015df56bab71d78a4d5acb35bad052714237453b11cd67423"
+}
diff --git a/.sqlx/query-7bb71b4b4829adf1f482505f65789346da4dd2d38269b17664b920592c864553.json b/.sqlx/query-7bb71b4b4829adf1f482505f65789346da4dd2d38269b17664b920592c864553.json
new file mode 100644
index 000000000..5c865323c
--- /dev/null
+++ b/.sqlx/query-7bb71b4b4829adf1f482505f65789346da4dd2d38269b17664b920592c864553.json
@@ -0,0 +1,16 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\n    INSERT INTO user_attr_values (user_id, key, value)\n    VALUES ($1, $2, $3)\n    ON CONFLICT(user_id, key) DO UPDATE SET value = $3",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar",
+        "Bytea"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "7bb71b4b4829adf1f482505f65789346da4dd2d38269b17664b920592c864553"
+}
diff --git a/.sqlx/query-7db996183478edcef00f6f399f97097cf4b3592c694423cc4fdb270f844ed555.json b/.sqlx/query-7db996183478edcef00f6f399f97097cf4b3592c694423cc4fdb270f844ed555.json
new file mode 100644
index 000000000..1f4c5d576
--- /dev/null
+++ b/.sqlx/query-7db996183478edcef00f6f399f97097cf4b3592c694423cc4fdb270f844ed555.json
@@ -0,0 +1,17 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nINSERT INTO auth_provider_logos (auth_provider_id, res, content_type, data)\nVALUES ($1, $2, $3, $4)\nON CONFLICT(auth_provider_id, res) DO UPDATE\nSET content_type = $3, data = $4",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Bytea"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "7db996183478edcef00f6f399f97097cf4b3592c694423cc4fdb270f844ed555"
+}
diff --git a/.sqlx/query-840c6f4024e8576c38b6b894291be382ce81062ee9fd23c91f267192b90f55cf.json b/.sqlx/query-840c6f4024e8576c38b6b894291be382ce81062ee9fd23c91f267192b90f55cf.json
new file mode 100644
index 000000000..1db3f8406
--- /dev/null
+++ b/.sqlx/query-840c6f4024e8576c38b6b894291be382ce81062ee9fd23c91f267192b90f55cf.json
@@ -0,0 +1,131 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM users WHERE auth_provider_id = $1 AND federation_uid = $2",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "email",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "given_name",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 3,
+        "name": "family_name",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 4,
+        "name": "password",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 5,
+        "name": "roles",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 6,
+        "name": "groups",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 7,
+        "name": "enabled",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 8,
+        "name": "email_verified",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 9,
+        "name": "password_expires",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 10,
+        "name": "created_at",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 11,
+        "name": "last_login",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 12,
+        "name": "last_failed_login",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 13,
+        "name": "failed_login_attempts",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 14,
+        "name": "language",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 15,
+        "name": "webauthn_user_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 16,
+        "name": "user_expires",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 17,
+        "name": "auth_provider_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 18,
+        "name": "federation_uid",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text",
+        "Text"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      true,
+      true,
+      false,
+      true,
+      false,
+      false,
+      true,
+      false,
+      true,
+      true,
+      true,
+      false,
+      true,
+      true,
+      true,
+      true
+    ]
+  },
+  "hash": "840c6f4024e8576c38b6b894291be382ce81062ee9fd23c91f267192b90f55cf"
+}
diff --git a/.sqlx/query-841b4b259076d6fa0b782a59e3682dc72263c7e776065678faa496b279266963.json b/.sqlx/query-841b4b259076d6fa0b782a59e3682dc72263c7e776065678faa496b279266963.json
new file mode 100644
index 000000000..5cb8236da
--- /dev/null
+++ b/.sqlx/query-841b4b259076d6fa0b782a59e3682dc72263c7e776065678faa496b279266963.json
@@ -0,0 +1,20 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT id FROM config LIMIT 1",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": []
+    },
+    "nullable": [
+      false
+    ]
+  },
+  "hash": "841b4b259076d6fa0b782a59e3682dc72263c7e776065678faa496b279266963"
+}
diff --git a/.sqlx/query-843923b9a0257cf80f1dff554e7dc8fdfc05f489328e8376513124dfb42996e3.json b/.sqlx/query-843923b9a0257cf80f1dff554e7dc8fdfc05f489328e8376513124dfb42996e3.json
new file mode 100644
index 000000000..eb4bc7a13
--- /dev/null
+++ b/.sqlx/query-843923b9a0257cf80f1dff554e7dc8fdfc05f489328e8376513124dfb42996e3.json
@@ -0,0 +1,130 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM users WHERE id = $1",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "email",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "given_name",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 3,
+        "name": "family_name",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 4,
+        "name": "password",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 5,
+        "name": "roles",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 6,
+        "name": "groups",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 7,
+        "name": "enabled",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 8,
+        "name": "email_verified",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 9,
+        "name": "password_expires",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 10,
+        "name": "created_at",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 11,
+        "name": "last_login",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 12,
+        "name": "last_failed_login",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 13,
+        "name": "failed_login_attempts",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 14,
+        "name": "language",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 15,
+        "name": "webauthn_user_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 16,
+        "name": "user_expires",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 17,
+        "name": "auth_provider_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 18,
+        "name": "federation_uid",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      true,
+      true,
+      false,
+      true,
+      false,
+      false,
+      true,
+      false,
+      true,
+      true,
+      true,
+      false,
+      true,
+      true,
+      true,
+      true
+    ]
+  },
+  "hash": "843923b9a0257cf80f1dff554e7dc8fdfc05f489328e8376513124dfb42996e3"
+}
diff --git a/.sqlx/query-84d744eede1c29a26f28f4a2d2244b0e71fe4aa05347b67d501e9c9a1da2465f.json b/.sqlx/query-84d744eede1c29a26f28f4a2d2244b0e71fe4aa05347b67d501e9c9a1da2465f.json
new file mode 100644
index 000000000..50f790175
--- /dev/null
+++ b/.sqlx/query-84d744eede1c29a26f28f4a2d2244b0e71fe4aa05347b67d501e9c9a1da2465f.json
@@ -0,0 +1,33 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\n    INSERT INTO clients (id, name, enabled, confidential, secret, secret_kid, redirect_uris,\n    post_logout_redirect_uris, allowed_origins, flows_enabled, access_token_alg, id_token_alg,\n    auth_code_lifetime, access_token_lifetime, scopes, default_scopes, challenge, force_mfa,\n    client_uri, contacts)\n    VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17,\n    $18, $19, $20)",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar",
+        "Bool",
+        "Bool",
+        "Bytea",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Int4",
+        "Int4",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Bool",
+        "Varchar",
+        "Varchar"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "84d744eede1c29a26f28f4a2d2244b0e71fe4aa05347b67d501e9c9a1da2465f"
+}
diff --git a/.sqlx/query-875ed512cffabad9d9ba237c92db5e7a6ea2f39589eebbce5c316a709d4c9566.json b/.sqlx/query-875ed512cffabad9d9ba237c92db5e7a6ea2f39589eebbce5c316a709d4c9566.json
new file mode 100644
index 000000000..1563f691a
--- /dev/null
+++ b/.sqlx/query-875ed512cffabad9d9ba237c92db5e7a6ea2f39589eebbce5c316a709d4c9566.json
@@ -0,0 +1,16 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "UPDATE sessions SET exp = $1, state = $2 WHERE id = $3",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Int8",
+        "Varchar",
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "875ed512cffabad9d9ba237c92db5e7a6ea2f39589eebbce5c316a709d4c9566"
+}
diff --git a/.sqlx/query-887631a171b771d677355932a9626f563e31fab88bf3b8fb2095585cfd5f9d3a.json b/.sqlx/query-887631a171b771d677355932a9626f563e31fab88bf3b8fb2095585cfd5f9d3a.json
new file mode 100644
index 000000000..ced35e024
--- /dev/null
+++ b/.sqlx/query-887631a171b771d677355932a9626f563e31fab88bf3b8fb2095585cfd5f9d3a.json
@@ -0,0 +1,42 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nSELECT client_id AS id, res, content_type, data\nFROM client_logos\nWHERE client_id = $1 AND (res = $2 OR res = $3)",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "res",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "content_type",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 3,
+        "name": "data",
+        "type_info": "Bytea"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text",
+        "Text",
+        "Text"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      false
+    ]
+  },
+  "hash": "887631a171b771d677355932a9626f563e31fab88bf3b8fb2095585cfd5f9d3a"
+}
diff --git a/.sqlx/query-88f26472e41c0381a8945804164c12fdc502c55c9bb4f90d64fd38d953e0d5f5.json b/.sqlx/query-88f26472e41c0381a8945804164c12fdc502c55c9bb4f90d64fd38d953e0d5f5.json
new file mode 100644
index 000000000..a370fea12
--- /dev/null
+++ b/.sqlx/query-88f26472e41c0381a8945804164c12fdc502c55c9bb4f90d64fd38d953e0d5f5.json
@@ -0,0 +1,22 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT id FROM users WHERE id = $1",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": [
+      false
+    ]
+  },
+  "hash": "88f26472e41c0381a8945804164c12fdc502c55c9bb4f90d64fd38d953e0d5f5"
+}
diff --git a/.sqlx/query-89494e523c428743705b26cac37bbad08ebf121f534362b254e72bd8ac29e3f1.json b/.sqlx/query-89494e523c428743705b26cac37bbad08ebf121f534362b254e72bd8ac29e3f1.json
new file mode 100644
index 000000000..1d64db4c2
--- /dev/null
+++ b/.sqlx/query-89494e523c428743705b26cac37bbad08ebf121f534362b254e72bd8ac29e3f1.json
@@ -0,0 +1,76 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM sessions WHERE id = $1 ORDER BY exp DESC",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "csrf_token",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "user_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 3,
+        "name": "roles",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 4,
+        "name": "groups",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 5,
+        "name": "is_mfa",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 6,
+        "name": "state",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 7,
+        "name": "exp",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 8,
+        "name": "last_seen",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 9,
+        "name": "remote_ip",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      true,
+      true,
+      true,
+      false,
+      false,
+      false,
+      false,
+      true
+    ]
+  },
+  "hash": "89494e523c428743705b26cac37bbad08ebf121f534362b254e72bd8ac29e3f1"
+}
diff --git a/.sqlx/query-8b7774eb0d57304316f84f2793b67612479d1ee29490c33d9394e89300aafe6c.json b/.sqlx/query-8b7774eb0d57304316f84f2793b67612479d1ee29490c33d9394e89300aafe6c.json
new file mode 100644
index 000000000..35c427dbd
--- /dev/null
+++ b/.sqlx/query-8b7774eb0d57304316f84f2793b67612479d1ee29490c33d9394e89300aafe6c.json
@@ -0,0 +1,16 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\n    INSERT INTO webids (user_id, custom_triples, expose_email)\n    VALUES ($1, $2, $3)\n    ON CONFLICT(user_id) DO UPDATE\n    SET custom_triples = $2, expose_email = $3",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar",
+        "Bool"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "8b7774eb0d57304316f84f2793b67612479d1ee29490c33d9394e89300aafe6c"
+}
diff --git a/.sqlx/query-8bc1a011144e7d31ef6818d9123c4d58324a75eec10e9296eb584f01220d3aaf.json b/.sqlx/query-8bc1a011144e7d31ef6818d9123c4d58324a75eec10e9296eb584f01220d3aaf.json
new file mode 100644
index 000000000..83258e20e
--- /dev/null
+++ b/.sqlx/query-8bc1a011144e7d31ef6818d9123c4d58324a75eec10e9296eb584f01220d3aaf.json
@@ -0,0 +1,50 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM api_keys",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "name",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "secret",
+        "type_info": "Bytea"
+      },
+      {
+        "ordinal": 2,
+        "name": "created",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 3,
+        "name": "expires",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 4,
+        "name": "enc_key_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 5,
+        "name": "access",
+        "type_info": "Bytea"
+      }
+    ],
+    "parameters": {
+      "Left": []
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      true,
+      false,
+      false
+    ]
+  },
+  "hash": "8bc1a011144e7d31ef6818d9123c4d58324a75eec10e9296eb584f01220d3aaf"
+}
diff --git a/.sqlx/query-8bf349f2c27914665ee96cf2895d9b95662c087d55d3ecf31564c91c1fb5b87b.json b/.sqlx/query-8bf349f2c27914665ee96cf2895d9b95662c087d55d3ecf31564c91c1fb5b87b.json
new file mode 100644
index 000000000..bdaaab005
--- /dev/null
+++ b/.sqlx/query-8bf349f2c27914665ee96cf2895d9b95662c087d55d3ecf31564c91c1fb5b87b.json
@@ -0,0 +1,64 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM passkeys WHERE user_id = $1 AND user_verified = true",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "user_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "name",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "passkey_user_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 3,
+        "name": "passkey",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 4,
+        "name": "credential_id",
+        "type_info": "Bytea"
+      },
+      {
+        "ordinal": 5,
+        "name": "registered",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 6,
+        "name": "last_used",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 7,
+        "name": "user_verified",
+        "type_info": "Bool"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      true
+    ]
+  },
+  "hash": "8bf349f2c27914665ee96cf2895d9b95662c087d55d3ecf31564c91c1fb5b87b"
+}
diff --git a/.sqlx/query-8d104b815808c9fd0a1a06fb1b5d11389671bd4eb37815e486afb7b13ead535d.json b/.sqlx/query-8d104b815808c9fd0a1a06fb1b5d11389671bd4eb37815e486afb7b13ead535d.json
new file mode 100644
index 000000000..a4dd34a2d
--- /dev/null
+++ b/.sqlx/query-8d104b815808c9fd0a1a06fb1b5d11389671bd4eb37815e486afb7b13ead535d.json
@@ -0,0 +1,19 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nINSERT INTO magic_links (id, user_id, csrf_token, exp, used, usage)\nVALUES ($1, $2, $3, $4, $5, $6)",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Int8",
+        "Bool",
+        "Varchar"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "8d104b815808c9fd0a1a06fb1b5d11389671bd4eb37815e486afb7b13ead535d"
+}
diff --git a/.sqlx/query-8e5a1c14958f0fbe1510f32486284579f371c9d6ff9db7a5b8e1cbfea78e5a90.json b/.sqlx/query-8e5a1c14958f0fbe1510f32486284579f371c9d6ff9db7a5b8e1cbfea78e5a90.json
new file mode 100644
index 000000000..a5150789b
--- /dev/null
+++ b/.sqlx/query-8e5a1c14958f0fbe1510f32486284579f371c9d6ff9db7a5b8e1cbfea78e5a90.json
@@ -0,0 +1,60 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nSELECT * FROM events\nWHERE timestamp >= $1 AND timestamp <= $2 AND level >= $3\nORDER BY timestamp DESC",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "timestamp",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 2,
+        "name": "typ",
+        "type_info": "Int2"
+      },
+      {
+        "ordinal": 3,
+        "name": "level",
+        "type_info": "Int2"
+      },
+      {
+        "ordinal": 4,
+        "name": "ip",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 5,
+        "name": "data",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 6,
+        "name": "text",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Int8",
+        "Int8",
+        "Int2"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      false,
+      true,
+      true,
+      true
+    ]
+  },
+  "hash": "8e5a1c14958f0fbe1510f32486284579f371c9d6ff9db7a5b8e1cbfea78e5a90"
+}
diff --git a/.sqlx/query-8eb839e514ee556e1544e10c219eb038b0a34ca40fa46004abc51e9b5ca3f0f0.json b/.sqlx/query-8eb839e514ee556e1544e10c219eb038b0a34ca40fa46004abc51e9b5ca3f0f0.json
new file mode 100644
index 000000000..8d9f66792
--- /dev/null
+++ b/.sqlx/query-8eb839e514ee556e1544e10c219eb038b0a34ca40fa46004abc51e9b5ca3f0f0.json
@@ -0,0 +1,17 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nINSERT INTO client_logos (client_id, res, content_type, data)\nVALUES ($1, $2, $3, $4)\nON CONFLICT(client_id, res) DO UPDATE\nSET content_type = $3, data = $4",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Bytea"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "8eb839e514ee556e1544e10c219eb038b0a34ca40fa46004abc51e9b5ca3f0f0"
+}
diff --git a/.sqlx/query-8f00172112fa13c366d5c29fe061af183ebf42b7a09b3ffa83fc7e5a05c70c62.json b/.sqlx/query-8f00172112fa13c366d5c29fe061af183ebf42b7a09b3ffa83fc7e5a05c70c62.json
new file mode 100644
index 000000000..51bfae542
--- /dev/null
+++ b/.sqlx/query-8f00172112fa13c366d5c29fe061af183ebf42b7a09b3ffa83fc7e5a05c70c62.json
@@ -0,0 +1,46 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nSELECT * FROM jwks\nWHERE signature = $1\nORDER BY created_at DESC\nLIMIT 1\n",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "kid",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "created_at",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 2,
+        "name": "signature",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 3,
+        "name": "enc_key_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 4,
+        "name": "jwk",
+        "type_info": "Bytea"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      false,
+      false
+    ]
+  },
+  "hash": "8f00172112fa13c366d5c29fe061af183ebf42b7a09b3ffa83fc7e5a05c70c62"
+}
diff --git a/.sqlx/query-8fd4b81475ac4a0f3e1f0d155ac0a39efdf0299f7a496432f69ebf529bf3226a.json b/.sqlx/query-8fd4b81475ac4a0f3e1f0d155ac0a39efdf0299f7a496432f69ebf529bf3226a.json
new file mode 100644
index 000000000..bce8beb02
--- /dev/null
+++ b/.sqlx/query-8fd4b81475ac4a0f3e1f0d155ac0a39efdf0299f7a496432f69ebf529bf3226a.json
@@ -0,0 +1,14 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "DELETE FROM user_attr_config WHERE name  = $1",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "8fd4b81475ac4a0f3e1f0d155ac0a39efdf0299f7a496432f69ebf529bf3226a"
+}
diff --git a/.sqlx/query-902b631d3527ab2f5849da095f8909f70e557e6ac7362b51d79fd9badafa1091.json b/.sqlx/query-902b631d3527ab2f5849da095f8909f70e557e6ac7362b51d79fd9badafa1091.json
new file mode 100644
index 000000000..f20710913
--- /dev/null
+++ b/.sqlx/query-902b631d3527ab2f5849da095f8909f70e557e6ac7362b51d79fd9badafa1091.json
@@ -0,0 +1,22 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nINSERT INTO\nsessions (id, csrf_token, user_id, roles, groups, is_mfa, state, exp, last_seen)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Bool",
+        "Varchar",
+        "Int8",
+        "Int8"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "902b631d3527ab2f5849da095f8909f70e557e6ac7362b51d79fd9badafa1091"
+}
diff --git a/.sqlx/query-9034de28c245ac0cd0f4c4cbab67b0aabf8dfd71fe1b7cd6989c6959ec860dff.json b/.sqlx/query-9034de28c245ac0cd0f4c4cbab67b0aabf8dfd71fe1b7cd6989c6959ec860dff.json
new file mode 100644
index 000000000..932998cb3
--- /dev/null
+++ b/.sqlx/query-9034de28c245ac0cd0f4c4cbab67b0aabf8dfd71fe1b7cd6989c6959ec860dff.json
@@ -0,0 +1,20 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT COUNT (*) count FROM users",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "count",
+        "type_info": "Int8"
+      }
+    ],
+    "parameters": {
+      "Left": []
+    },
+    "nullable": [
+      null
+    ]
+  },
+  "hash": "9034de28c245ac0cd0f4c4cbab67b0aabf8dfd71fe1b7cd6989c6959ec860dff"
+}
diff --git a/.sqlx/query-90e84e1e4c45ef1fbabe1c387f887372f45d99ac2e9d9ca467adef3e72cd8a04.json b/.sqlx/query-90e84e1e4c45ef1fbabe1c387f887372f45d99ac2e9d9ca467adef3e72cd8a04.json
new file mode 100644
index 000000000..cc74000ad
--- /dev/null
+++ b/.sqlx/query-90e84e1e4c45ef1fbabe1c387f887372f45d99ac2e9d9ca467adef3e72cd8a04.json
@@ -0,0 +1,17 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nINSERT INTO\nclients_dyn (id, created, registration_token, token_endpoint_auth_method)\nVALUES ($1, $2, $3, $4)",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Int8",
+        "Bytea",
+        "Varchar"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "90e84e1e4c45ef1fbabe1c387f887372f45d99ac2e9d9ca467adef3e72cd8a04"
+}
diff --git a/.sqlx/query-937d9832ea4437533e25c3ea8b3c7407296fdeeb5c29efa245d7326240590879.json b/.sqlx/query-937d9832ea4437533e25c3ea8b3c7407296fdeeb5c29efa245d7326240590879.json
new file mode 100644
index 000000000..4a65d3a5d
--- /dev/null
+++ b/.sqlx/query-937d9832ea4437533e25c3ea8b3c7407296fdeeb5c29efa245d7326240590879.json
@@ -0,0 +1,44 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM jwks",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "kid",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "created_at",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 2,
+        "name": "signature",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 3,
+        "name": "enc_key_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 4,
+        "name": "jwk",
+        "type_info": "Bytea"
+      }
+    ],
+    "parameters": {
+      "Left": []
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      false,
+      false
+    ]
+  },
+  "hash": "937d9832ea4437533e25c3ea8b3c7407296fdeeb5c29efa245d7326240590879"
+}
diff --git a/.sqlx/query-9464e308d213a1d1d92f12b3db3622ba0da448a3fe044411a2df24350c3d1d34.json b/.sqlx/query-9464e308d213a1d1d92f12b3db3622ba0da448a3fe044411a2df24350c3d1d34.json
new file mode 100644
index 000000000..719f7d410
--- /dev/null
+++ b/.sqlx/query-9464e308d213a1d1d92f12b3db3622ba0da448a3fe044411a2df24350c3d1d34.json
@@ -0,0 +1,33 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nUPDATE auth_providers\nSET name = $1, enabled = $2, issuer = $3, typ = $4, authorization_endpoint = $5,\ntoken_endpoint = $6, userinfo_endpoint = $7, client_id = $8, secret = $9, scope = $10,\nadmin_claim_path = $11, admin_claim_value = $12, mfa_claim_path = $13, mfa_claim_value = $14,\nallow_insecure_requests = $15, use_pkce = $16, root_pem = $17, client_secret_basic = $18,\nclient_secret_post = $19\nWHERE id = $20",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Bool",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Bytea",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Bool",
+        "Bool",
+        "Varchar",
+        "Bool",
+        "Bool",
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "9464e308d213a1d1d92f12b3db3622ba0da448a3fe044411a2df24350c3d1d34"
+}
diff --git a/.sqlx/query-972a769f104414da146d8d6e82b22052239bf11e9241b3a70437f2d9613d3128.json b/.sqlx/query-972a769f104414da146d8d6e82b22052239bf11e9241b3a70437f2d9613d3128.json
new file mode 100644
index 000000000..9bd29fe85
--- /dev/null
+++ b/.sqlx/query-972a769f104414da146d8d6e82b22052239bf11e9241b3a70437f2d9613d3128.json
@@ -0,0 +1,61 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nSELECT * FROM events\nWHERE timestamp >= $1 AND timestamp <= $2 AND level >= $3 AND typ = $4\nORDER BY timestamp DESC",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "timestamp",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 2,
+        "name": "typ",
+        "type_info": "Int2"
+      },
+      {
+        "ordinal": 3,
+        "name": "level",
+        "type_info": "Int2"
+      },
+      {
+        "ordinal": 4,
+        "name": "ip",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 5,
+        "name": "data",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 6,
+        "name": "text",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Int8",
+        "Int8",
+        "Int2",
+        "Int2"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      false,
+      true,
+      true,
+      true
+    ]
+  },
+  "hash": "972a769f104414da146d8d6e82b22052239bf11e9241b3a70437f2d9613d3128"
+}
diff --git a/.sqlx/query-989fa2b8dea449d84df8d3bd61f432697a24d29f338f9cc63386c49c8b258d92.json b/.sqlx/query-989fa2b8dea449d84df8d3bd61f432697a24d29f338f9cc63386c49c8b258d92.json
new file mode 100644
index 000000000..58342e13e
--- /dev/null
+++ b/.sqlx/query-989fa2b8dea449d84df8d3bd61f432697a24d29f338f9cc63386c49c8b258d92.json
@@ -0,0 +1,131 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM users WHERE password_expires <= $1 AND password_expires > $2",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "email",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "given_name",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 3,
+        "name": "family_name",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 4,
+        "name": "password",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 5,
+        "name": "roles",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 6,
+        "name": "groups",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 7,
+        "name": "enabled",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 8,
+        "name": "email_verified",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 9,
+        "name": "password_expires",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 10,
+        "name": "created_at",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 11,
+        "name": "last_login",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 12,
+        "name": "last_failed_login",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 13,
+        "name": "failed_login_attempts",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 14,
+        "name": "language",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 15,
+        "name": "webauthn_user_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 16,
+        "name": "user_expires",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 17,
+        "name": "auth_provider_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 18,
+        "name": "federation_uid",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Int8",
+        "Int8"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      true,
+      true,
+      false,
+      true,
+      false,
+      false,
+      true,
+      false,
+      true,
+      true,
+      true,
+      false,
+      true,
+      true,
+      true,
+      true
+    ]
+  },
+  "hash": "989fa2b8dea449d84df8d3bd61f432697a24d29f338f9cc63386c49c8b258d92"
+}
diff --git a/.sqlx/query-98dba1ea43b2a41075b8ca980a3b998a5f059019152db9514bcc5323d563a751.json b/.sqlx/query-98dba1ea43b2a41075b8ca980a3b998a5f059019152db9514bcc5323d563a751.json
new file mode 100644
index 000000000..a614320d6
--- /dev/null
+++ b/.sqlx/query-98dba1ea43b2a41075b8ca980a3b998a5f059019152db9514bcc5323d563a751.json
@@ -0,0 +1,15 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "INSERT INTO roles (id, name) VALUES ($1, $2)",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "98dba1ea43b2a41075b8ca980a3b998a5f059019152db9514bcc5323d563a751"
+}
diff --git a/.sqlx/query-9906e138e8d3b479df437cb5dbfb44995e6bb8ac679a725e75260153e7851877.json b/.sqlx/query-9906e138e8d3b479df437cb5dbfb44995e6bb8ac679a725e75260153e7851877.json
new file mode 100644
index 000000000..34b986815
--- /dev/null
+++ b/.sqlx/query-9906e138e8d3b479df437cb5dbfb44995e6bb8ac679a725e75260153e7851877.json
@@ -0,0 +1,62 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM pg_tables WHERE tablename = 'passkeys' LIMIT 1",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "schemaname",
+        "type_info": "Name"
+      },
+      {
+        "ordinal": 1,
+        "name": "tablename",
+        "type_info": "Name"
+      },
+      {
+        "ordinal": 2,
+        "name": "tableowner",
+        "type_info": "Name"
+      },
+      {
+        "ordinal": 3,
+        "name": "tablespace",
+        "type_info": "Name"
+      },
+      {
+        "ordinal": 4,
+        "name": "hasindexes",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 5,
+        "name": "hasrules",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 6,
+        "name": "hastriggers",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 7,
+        "name": "rowsecurity",
+        "type_info": "Bool"
+      }
+    ],
+    "parameters": {
+      "Left": []
+    },
+    "nullable": [
+      true,
+      true,
+      true,
+      true,
+      true,
+      true,
+      true,
+      true
+    ]
+  },
+  "hash": "9906e138e8d3b479df437cb5dbfb44995e6bb8ac679a725e75260153e7851877"
+}
diff --git a/.sqlx/query-99d815d0cd8d375c203265af3b1bd38b4df7d07720304f9946b8fcabfb01d6cd.json b/.sqlx/query-99d815d0cd8d375c203265af3b1bd38b4df7d07720304f9946b8fcabfb01d6cd.json
new file mode 100644
index 000000000..c38b62a95
--- /dev/null
+++ b/.sqlx/query-99d815d0cd8d375c203265af3b1bd38b4df7d07720304f9946b8fcabfb01d6cd.json
@@ -0,0 +1,14 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "DELETE FROM refresh_tokens_devices WHERE user_id = $1",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "99d815d0cd8d375c203265af3b1bd38b4df7d07720304f9946b8fcabfb01d6cd"
+}
diff --git a/.sqlx/query-9efef3632d1d26f851dbcf3a686d0506d2ff1d62718072747f48eed6280fed74.json b/.sqlx/query-9efef3632d1d26f851dbcf3a686d0506d2ff1d62718072747f48eed6280fed74.json
new file mode 100644
index 000000000..577917057
--- /dev/null
+++ b/.sqlx/query-9efef3632d1d26f851dbcf3a686d0506d2ff1d62718072747f48eed6280fed74.json
@@ -0,0 +1,77 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM sessions WHERE id LIKE $1 ORDER BY exp DESC LIMIT $2",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "csrf_token",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "user_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 3,
+        "name": "roles",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 4,
+        "name": "groups",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 5,
+        "name": "is_mfa",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 6,
+        "name": "state",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 7,
+        "name": "exp",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 8,
+        "name": "last_seen",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 9,
+        "name": "remote_ip",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text",
+        "Int8"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      true,
+      true,
+      true,
+      false,
+      false,
+      false,
+      false,
+      true
+    ]
+  },
+  "hash": "9efef3632d1d26f851dbcf3a686d0506d2ff1d62718072747f48eed6280fed74"
+}
diff --git a/.sqlx/query-a51152f96ebfd0b136aa301a432c9b8bb64585843b5b8b886c6e6bf1a22b9af0.json b/.sqlx/query-a51152f96ebfd0b136aa301a432c9b8bb64585843b5b8b886c6e6bf1a22b9af0.json
new file mode 100644
index 000000000..7869fd640
--- /dev/null
+++ b/.sqlx/query-a51152f96ebfd0b136aa301a432c9b8bb64585843b5b8b886c6e6bf1a22b9af0.json
@@ -0,0 +1,14 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nDELETE FROM devices\nWHERE access_exp < $1 AND (refresh_exp < $1 OR refresh_exp is null)",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Int8"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "a51152f96ebfd0b136aa301a432c9b8bb64585843b5b8b886c6e6bf1a22b9af0"
+}
diff --git a/.sqlx/query-a5124f407d8ad58e2bcf792f188b5d5332ef9f90a7b8a2fdf87cf37cb7c91ef9.json b/.sqlx/query-a5124f407d8ad58e2bcf792f188b5d5332ef9f90a7b8a2fdf87cf37cb7c91ef9.json
new file mode 100644
index 000000000..e1bc0287e
--- /dev/null
+++ b/.sqlx/query-a5124f407d8ad58e2bcf792f188b5d5332ef9f90a7b8a2fdf87cf37cb7c91ef9.json
@@ -0,0 +1,41 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nSELECT id, email, created_at, last_login\nFROM users\nORDER BY created_at DESC\nLIMIT $1\nOFFSET $2",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "email",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "created_at",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 3,
+        "name": "last_login",
+        "type_info": "Int8"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Int8",
+        "Int8"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      true
+    ]
+  },
+  "hash": "a5124f407d8ad58e2bcf792f188b5d5332ef9f90a7b8a2fdf87cf37cb7c91ef9"
+}
diff --git a/.sqlx/query-a5fc3e20274c6c1ec5086e7f4fc50bc78a2bbe56c6b7d9b290a5783d17120c88.json b/.sqlx/query-a5fc3e20274c6c1ec5086e7f4fc50bc78a2bbe56c6b7d9b290a5783d17120c88.json
new file mode 100644
index 000000000..a59e2ea72
--- /dev/null
+++ b/.sqlx/query-a5fc3e20274c6c1ec5086e7f4fc50bc78a2bbe56c6b7d9b290a5783d17120c88.json
@@ -0,0 +1,53 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM refresh_tokens_devices WHERE id = $1 AND exp > $2",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "device_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "user_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 3,
+        "name": "nbf",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 4,
+        "name": "exp",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 5,
+        "name": "scope",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text",
+        "Int8"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      false,
+      false,
+      true
+    ]
+  },
+  "hash": "a5fc3e20274c6c1ec5086e7f4fc50bc78a2bbe56c6b7d9b290a5783d17120c88"
+}
diff --git a/.sqlx/query-a6ccb928136f9a3785ea77b046dc3f77e9e4609cd74ca33397d4519532af26e4.json b/.sqlx/query-a6ccb928136f9a3785ea77b046dc3f77e9e4609cd74ca33397d4519532af26e4.json
new file mode 100644
index 000000000..2c453ab14
--- /dev/null
+++ b/.sqlx/query-a6ccb928136f9a3785ea77b046dc3f77e9e4609cd74ca33397d4519532af26e4.json
@@ -0,0 +1,22 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT COUNT (*) AS count FROM passkeys WHERE user_id = $1",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "count",
+        "type_info": "Int8"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": [
+      null
+    ]
+  },
+  "hash": "a6ccb928136f9a3785ea77b046dc3f77e9e4609cd74ca33397d4519532af26e4"
+}
diff --git a/.sqlx/query-a70ef381b3e3438f98d1b061a33e4766c54c303ebf075818e7aa7a2b758eb473.json b/.sqlx/query-a70ef381b3e3438f98d1b061a33e4766c54c303ebf075818e7aa7a2b758eb473.json
new file mode 100644
index 000000000..446f1f1c7
--- /dev/null
+++ b/.sqlx/query-a70ef381b3e3438f98d1b061a33e4766c54c303ebf075818e7aa7a2b758eb473.json
@@ -0,0 +1,79 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nSELECT *\nFROM sessions\nWHERE exp <= $1 AND id != $2\nORDER BY exp DESC\nLIMIT $3\nOFFSET $4",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "csrf_token",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "user_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 3,
+        "name": "roles",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 4,
+        "name": "groups",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 5,
+        "name": "is_mfa",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 6,
+        "name": "state",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 7,
+        "name": "exp",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 8,
+        "name": "last_seen",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 9,
+        "name": "remote_ip",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Int8",
+        "Text",
+        "Int8",
+        "Int8"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      true,
+      true,
+      true,
+      false,
+      false,
+      false,
+      false,
+      true
+    ]
+  },
+  "hash": "a70ef381b3e3438f98d1b061a33e4766c54c303ebf075818e7aa7a2b758eb473"
+}
diff --git a/.sqlx/query-a79d77a26d5f318e640bcc6e4a4c3eb4aa830315c69a1f8c8138b3e35e2896e5.json b/.sqlx/query-a79d77a26d5f318e640bcc6e4a4c3eb4aa830315c69a1f8c8138b3e35e2896e5.json
new file mode 100644
index 000000000..edd3cf2d2
--- /dev/null
+++ b/.sqlx/query-a79d77a26d5f318e640bcc6e4a4c3eb4aa830315c69a1f8c8138b3e35e2896e5.json
@@ -0,0 +1,18 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nINSERT INTO refresh_tokens (id, user_id, nbf, exp, scope)\nVALUES ($1, $2, $3, $4, $5)",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar",
+        "Int8",
+        "Int8",
+        "Varchar"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "a79d77a26d5f318e640bcc6e4a4c3eb4aa830315c69a1f8c8138b3e35e2896e5"
+}
diff --git a/.sqlx/query-a8425724795408542a26840c64463ccd4f58fb9593e0f81421eac15570b7d275.json b/.sqlx/query-a8425724795408542a26840c64463ccd4f58fb9593e0f81421eac15570b7d275.json
new file mode 100644
index 000000000..8b37de2ce
--- /dev/null
+++ b/.sqlx/query-a8425724795408542a26840c64463ccd4f58fb9593e0f81421eac15570b7d275.json
@@ -0,0 +1,77 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM sessions WHERE remote_ip LIKE $1 ORDER BY exp DESC LIMIT $2",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "csrf_token",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "user_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 3,
+        "name": "roles",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 4,
+        "name": "groups",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 5,
+        "name": "is_mfa",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 6,
+        "name": "state",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 7,
+        "name": "exp",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 8,
+        "name": "last_seen",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 9,
+        "name": "remote_ip",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text",
+        "Int8"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      true,
+      true,
+      true,
+      false,
+      false,
+      false,
+      false,
+      true
+    ]
+  },
+  "hash": "a8425724795408542a26840c64463ccd4f58fb9593e0f81421eac15570b7d275"
+}
diff --git a/.sqlx/query-a86df519a984439afed039574038a52cab483579ba9a726ec565a86c0882de41.json b/.sqlx/query-a86df519a984439afed039574038a52cab483579ba9a726ec565a86c0882de41.json
new file mode 100644
index 000000000..bcf302aac
--- /dev/null
+++ b/.sqlx/query-a86df519a984439afed039574038a52cab483579ba9a726ec565a86c0882de41.json
@@ -0,0 +1,15 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "UPDATE users SET email_verified = $1 WHERE id = $2",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Bool",
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "a86df519a984439afed039574038a52cab483579ba9a726ec565a86c0882de41"
+}
diff --git a/.sqlx/query-a88fcc0640f56934b0b00f2aaba6df6c92676c192f58dc6fb596d8045593c0b5.json b/.sqlx/query-a88fcc0640f56934b0b00f2aaba6df6c92676c192f58dc6fb596d8045593c0b5.json
new file mode 100644
index 000000000..0eaa158e1
--- /dev/null
+++ b/.sqlx/query-a88fcc0640f56934b0b00f2aaba6df6c92676c192f58dc6fb596d8045593c0b5.json
@@ -0,0 +1,14 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "DELETE FROM themes WHERE client_id = $1",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "a88fcc0640f56934b0b00f2aaba6df6c92676c192f58dc6fb596d8045593c0b5"
+}
diff --git a/.sqlx/query-a8f2397d8d6b2c2ad756f0c5bafafed29ff3239bdb607fe9ce0f2bc78b9821d7.json b/.sqlx/query-a8f2397d8d6b2c2ad756f0c5bafafed29ff3239bdb607fe9ce0f2bc78b9821d7.json
new file mode 100644
index 000000000..5754bc2cb
--- /dev/null
+++ b/.sqlx/query-a8f2397d8d6b2c2ad756f0c5bafafed29ff3239bdb607fe9ce0f2bc78b9821d7.json
@@ -0,0 +1,64 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM devices WHERE id = $1",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "client_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "user_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 3,
+        "name": "created",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 4,
+        "name": "access_exp",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 5,
+        "name": "refresh_exp",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 6,
+        "name": "peer_ip",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 7,
+        "name": "name",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      true,
+      false,
+      false,
+      true,
+      false,
+      false
+    ]
+  },
+  "hash": "a8f2397d8d6b2c2ad756f0c5bafafed29ff3239bdb607fe9ce0f2bc78b9821d7"
+}
diff --git a/.sqlx/query-a90566f5b4f63946b0bf377b0719067497a0366441d0e637eacbc2509abe8377.json b/.sqlx/query-a90566f5b4f63946b0bf377b0719067497a0366441d0e637eacbc2509abe8377.json
new file mode 100644
index 000000000..75416cfab
--- /dev/null
+++ b/.sqlx/query-a90566f5b4f63946b0bf377b0719067497a0366441d0e637eacbc2509abe8377.json
@@ -0,0 +1,34 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM user_attr_values WHERE key = $1",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "user_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "key",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "value",
+        "type_info": "Bytea"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      false
+    ]
+  },
+  "hash": "a90566f5b4f63946b0bf377b0719067497a0366441d0e637eacbc2509abe8377"
+}
diff --git a/.sqlx/query-aaa73f898ca5f30c1260d41c15b4aeedf472416b17c4557704ff479730b399be.json b/.sqlx/query-aaa73f898ca5f30c1260d41c15b4aeedf472416b17c4557704ff479730b399be.json
new file mode 100644
index 000000000..0ce3cd573
--- /dev/null
+++ b/.sqlx/query-aaa73f898ca5f30c1260d41c15b4aeedf472416b17c4557704ff479730b399be.json
@@ -0,0 +1,16 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "UPDATE user_attr_config SET name  = $1, \"desc\" = $2 WHERE name = $3",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar",
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "aaa73f898ca5f30c1260d41c15b4aeedf472416b17c4557704ff479730b399be"
+}
diff --git a/.sqlx/query-ab786fd59274add3942a8ea6fbb5b44e96ad1700ed7226b4d8b3f10c98fbcc55.json b/.sqlx/query-ab786fd59274add3942a8ea6fbb5b44e96ad1700ed7226b4d8b3f10c98fbcc55.json
new file mode 100644
index 000000000..7bbaa1609
--- /dev/null
+++ b/.sqlx/query-ab786fd59274add3942a8ea6fbb5b44e96ad1700ed7226b4d8b3f10c98fbcc55.json
@@ -0,0 +1,41 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nSELECT id, email, created_at, last_login\nFROM users\nWHERE id LIKE $1\nORDER BY created_at ASC\nLIMIT $2",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "email",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "created_at",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 3,
+        "name": "last_login",
+        "type_info": "Int8"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text",
+        "Int8"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      true
+    ]
+  },
+  "hash": "ab786fd59274add3942a8ea6fbb5b44e96ad1700ed7226b4d8b3f10c98fbcc55"
+}
diff --git a/.sqlx/query-ad5ebd447162efbbf289426cb72bcdd74dc9b29ec839ccffbab29b9167d7d970.json b/.sqlx/query-ad5ebd447162efbbf289426cb72bcdd74dc9b29ec839ccffbab29b9167d7d970.json
new file mode 100644
index 000000000..48292c74e
--- /dev/null
+++ b/.sqlx/query-ad5ebd447162efbbf289426cb72bcdd74dc9b29ec839ccffbab29b9167d7d970.json
@@ -0,0 +1,21 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nINSERT INTO devices\n(id, client_id, user_id, created, access_exp, refresh_exp, peer_ip, name)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Int8",
+        "Int8",
+        "Int8",
+        "Varchar",
+        "Varchar"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "ad5ebd447162efbbf289426cb72bcdd74dc9b29ec839ccffbab29b9167d7d970"
+}
diff --git a/.sqlx/query-adc4b90ad3d391b39768d1a80b8d956c55ef2a82a052aee34972eef59ea25116.json b/.sqlx/query-adc4b90ad3d391b39768d1a80b8d956c55ef2a82a052aee34972eef59ea25116.json
new file mode 100644
index 000000000..771293043
--- /dev/null
+++ b/.sqlx/query-adc4b90ad3d391b39768d1a80b8d956c55ef2a82a052aee34972eef59ea25116.json
@@ -0,0 +1,26 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM roles",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "name",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": []
+    },
+    "nullable": [
+      false,
+      false
+    ]
+  },
+  "hash": "adc4b90ad3d391b39768d1a80b8d956c55ef2a82a052aee34972eef59ea25116"
+}
diff --git a/.sqlx/query-affbb6164932a584ac5facdf981824bdc2f12c6a4b68e7022d0b656ab72fbf87.json b/.sqlx/query-affbb6164932a584ac5facdf981824bdc2f12c6a4b68e7022d0b656ab72fbf87.json
new file mode 100644
index 000000000..5df6cd6aa
--- /dev/null
+++ b/.sqlx/query-affbb6164932a584ac5facdf981824bdc2f12c6a4b68e7022d0b656ab72fbf87.json
@@ -0,0 +1,41 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nSELECT id, email, created_at, last_login\nFROM users\nORDER BY created_at ASC\nLIMIT $1\nOFFSET $2",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "email",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "created_at",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 3,
+        "name": "last_login",
+        "type_info": "Int8"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Int8",
+        "Int8"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      true
+    ]
+  },
+  "hash": "affbb6164932a584ac5facdf981824bdc2f12c6a4b68e7022d0b656ab72fbf87"
+}
diff --git a/.sqlx/query-b0edffcbb027307a7dc1cc7ac597273161dd765c1023442202f27991bc77c9b9.json b/.sqlx/query-b0edffcbb027307a7dc1cc7ac597273161dd765c1023442202f27991bc77c9b9.json
new file mode 100644
index 000000000..f89fd85c6
--- /dev/null
+++ b/.sqlx/query-b0edffcbb027307a7dc1cc7ac597273161dd765c1023442202f27991bc77c9b9.json
@@ -0,0 +1,15 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "INSERT INTO config (id, data) VALUES ($1, $2)",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Bytea"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "b0edffcbb027307a7dc1cc7ac597273161dd765c1023442202f27991bc77c9b9"
+}
diff --git a/.sqlx/query-b49df69102c893022fe6fdc97ffb0c46c6e05ea98d587aa24ffc4bb1908bed86.json b/.sqlx/query-b49df69102c893022fe6fdc97ffb0c46c6e05ea98d587aa24ffc4bb1908bed86.json
new file mode 100644
index 000000000..668110aed
--- /dev/null
+++ b/.sqlx/query-b49df69102c893022fe6fdc97ffb0c46c6e05ea98d587aa24ffc4bb1908bed86.json
@@ -0,0 +1,15 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "UPDATE roles SET name = $1 WHERE id = $2",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "b49df69102c893022fe6fdc97ffb0c46c6e05ea98d587aa24ffc4bb1908bed86"
+}
diff --git a/.sqlx/query-b6c33763b3c08fb3386a87ff958c7b17497d3ae6f8a2431eb36077abbc291318.json b/.sqlx/query-b6c33763b3c08fb3386a87ff958c7b17497d3ae6f8a2431eb36077abbc291318.json
new file mode 100644
index 000000000..81048d9ba
--- /dev/null
+++ b/.sqlx/query-b6c33763b3c08fb3386a87ff958c7b17497d3ae6f8a2431eb36077abbc291318.json
@@ -0,0 +1,22 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "DELETE FROM sessions WHERE user_id = $1 RETURNING id",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": [
+      false
+    ]
+  },
+  "hash": "b6c33763b3c08fb3386a87ff958c7b17497d3ae6f8a2431eb36077abbc291318"
+}
diff --git a/.sqlx/query-b9f542d480fece4043f63ef0d59a3a775578bd0b29ac68662336b355c95866c2.json b/.sqlx/query-b9f542d480fece4043f63ef0d59a3a775578bd0b29ac68662336b355c95866c2.json
new file mode 100644
index 000000000..3f7807500
--- /dev/null
+++ b/.sqlx/query-b9f542d480fece4043f63ef0d59a3a775578bd0b29ac68662336b355c95866c2.json
@@ -0,0 +1,20 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "select data from config where id = 'latest_version'",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "data",
+        "type_info": "Bytea"
+      }
+    ],
+    "parameters": {
+      "Left": []
+    },
+    "nullable": [
+      true
+    ]
+  },
+  "hash": "b9f542d480fece4043f63ef0d59a3a775578bd0b29ac68662336b355c95866c2"
+}
diff --git a/.sqlx/query-be3e3336329486bab6ffb813917d73b8e6aef525149944f55501e3ba230480c3.json b/.sqlx/query-be3e3336329486bab6ffb813917d73b8e6aef525149944f55501e3ba230480c3.json
new file mode 100644
index 000000000..3c36aed36
--- /dev/null
+++ b/.sqlx/query-be3e3336329486bab6ffb813917d73b8e6aef525149944f55501e3ba230480c3.json
@@ -0,0 +1,15 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "INSERT INTO groups (id, name) VALUES ($1, $2)",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "be3e3336329486bab6ffb813917d73b8e6aef525149944f55501e3ba230480c3"
+}
diff --git a/.sqlx/query-bfbfde98b7d5745eccecbf06133b3ad4cb7cdf544b8e619bee36d821bd886738.json b/.sqlx/query-bfbfde98b7d5745eccecbf06133b3ad4cb7cdf544b8e619bee36d821bd886738.json
new file mode 100644
index 000000000..8448acce7
--- /dev/null
+++ b/.sqlx/query-bfbfde98b7d5745eccecbf06133b3ad4cb7cdf544b8e619bee36d821bd886738.json
@@ -0,0 +1,38 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT id, email, created_at, last_login FROM users ORDER BY created_at ASC",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "email",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "created_at",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 3,
+        "name": "last_login",
+        "type_info": "Int8"
+      }
+    ],
+    "parameters": {
+      "Left": []
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      true
+    ]
+  },
+  "hash": "bfbfde98b7d5745eccecbf06133b3ad4cb7cdf544b8e619bee36d821bd886738"
+}
diff --git a/.sqlx/query-c0867219d490d8c27a104686a6e7efb78cb2633617e79053853d25e96e78342f.json b/.sqlx/query-c0867219d490d8c27a104686a6e7efb78cb2633617e79053853d25e96e78342f.json
new file mode 100644
index 000000000..f3b62414a
--- /dev/null
+++ b/.sqlx/query-c0867219d490d8c27a104686a6e7efb78cb2633617e79053853d25e96e78342f.json
@@ -0,0 +1,52 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM api_keys WHERE name = $1",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "name",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "secret",
+        "type_info": "Bytea"
+      },
+      {
+        "ordinal": 2,
+        "name": "created",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 3,
+        "name": "expires",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 4,
+        "name": "enc_key_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 5,
+        "name": "access",
+        "type_info": "Bytea"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      true,
+      false,
+      false
+    ]
+  },
+  "hash": "c0867219d490d8c27a104686a6e7efb78cb2633617e79053853d25e96e78342f"
+}
diff --git a/.sqlx/query-c095a1526cd807a3f3ad218a5e98b39c7f77e44b0b472685a153a5ac8b152897.json b/.sqlx/query-c095a1526cd807a3f3ad218a5e98b39c7f77e44b0b472685a153a5ac8b152897.json
new file mode 100644
index 000000000..10a9b5c20
--- /dev/null
+++ b/.sqlx/query-c095a1526cd807a3f3ad218a5e98b39c7f77e44b0b472685a153a5ac8b152897.json
@@ -0,0 +1,16 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "INSERT INTO user_attr_values (user_id, key, value) VALUES ($1, $2, $3)",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar",
+        "Bytea"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "c095a1526cd807a3f3ad218a5e98b39c7f77e44b0b472685a153a5ac8b152897"
+}
diff --git a/.sqlx/query-c3079a26ef775fd6b1b43cb2a511d0150c2322a690b1a61d370f8c6f5992d38f.json b/.sqlx/query-c3079a26ef775fd6b1b43cb2a511d0150c2322a690b1a61d370f8c6f5992d38f.json
new file mode 100644
index 000000000..fab8cc49e
--- /dev/null
+++ b/.sqlx/query-c3079a26ef775fd6b1b43cb2a511d0150c2322a690b1a61d370f8c6f5992d38f.json
@@ -0,0 +1,18 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nUPDATE api_keys\nSET secret = $1, expires = $2, enc_key_id = $3, access = $4\nWHERE name = $5",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Bytea",
+        "Int8",
+        "Varchar",
+        "Bytea",
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "c3079a26ef775fd6b1b43cb2a511d0150c2322a690b1a61d370f8c6f5992d38f"
+}
diff --git a/.sqlx/query-c37af1928b270e09a92d910388f2e59343904117fbaac912c38bf641dcd4e076.json b/.sqlx/query-c37af1928b270e09a92d910388f2e59343904117fbaac912c38bf641dcd4e076.json
new file mode 100644
index 000000000..f2a752c7e
--- /dev/null
+++ b/.sqlx/query-c37af1928b270e09a92d910388f2e59343904117fbaac912c38bf641dcd4e076.json
@@ -0,0 +1,14 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "DELETE FROM refresh_tokens_devices WHERE device_id = $1",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "c37af1928b270e09a92d910388f2e59343904117fbaac912c38bf641dcd4e076"
+}
diff --git a/.sqlx/query-c3d0b2be1ec741d2709ef651e61f54504e37e3293b1a99ab79e6fad960e3f7a0.json b/.sqlx/query-c3d0b2be1ec741d2709ef651e61f54504e37e3293b1a99ab79e6fad960e3f7a0.json
new file mode 100644
index 000000000..67504f6bc
--- /dev/null
+++ b/.sqlx/query-c3d0b2be1ec741d2709ef651e61f54504e37e3293b1a99ab79e6fad960e3f7a0.json
@@ -0,0 +1,14 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "UPDATE config SET data = $1 WHERE id = 'password_policy'",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Bytea"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "c3d0b2be1ec741d2709ef651e61f54504e37e3293b1a99ab79e6fad960e3f7a0"
+}
diff --git a/.sqlx/query-c6e94bccd19cc46bf1e7ec79935f42c2c77c32a4ef99188dd263e1017af827b3.json b/.sqlx/query-c6e94bccd19cc46bf1e7ec79935f42c2c77c32a4ef99188dd263e1017af827b3.json
new file mode 100644
index 000000000..600cc77ab
--- /dev/null
+++ b/.sqlx/query-c6e94bccd19cc46bf1e7ec79935f42c2c77c32a4ef99188dd263e1017af827b3.json
@@ -0,0 +1,14 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "UPDATE refresh_tokens_devices SET exp = $1 WHERE exp > $1",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Int8"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "c6e94bccd19cc46bf1e7ec79935f42c2c77c32a4ef99188dd263e1017af827b3"
+}
diff --git a/.sqlx/query-c9a8bc985c9d2a7c8a9c782a37471a5de21529b393bc008e5b26dc43d8e1f06b.json b/.sqlx/query-c9a8bc985c9d2a7c8a9c782a37471a5de21529b393bc008e5b26dc43d8e1f06b.json
new file mode 100644
index 000000000..12579daff
--- /dev/null
+++ b/.sqlx/query-c9a8bc985c9d2a7c8a9c782a37471a5de21529b393bc008e5b26dc43d8e1f06b.json
@@ -0,0 +1,14 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nINSERT INTO config (id, data) VALUES ('latest_version', $1)\nON CONFLICT(id) DO UPDATE SET data = $1",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Bytea"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "c9a8bc985c9d2a7c8a9c782a37471a5de21529b393bc008e5b26dc43d8e1f06b"
+}
diff --git a/.sqlx/query-cd5113b6e8e12d0f50cb46ce38c911e6d6ee138a2af2a2ab43062910c6c7c47d.json b/.sqlx/query-cd5113b6e8e12d0f50cb46ce38c911e6d6ee138a2af2a2ab43062910c6c7c47d.json
new file mode 100644
index 000000000..7865e8690
--- /dev/null
+++ b/.sqlx/query-cd5113b6e8e12d0f50cb46ce38c911e6d6ee138a2af2a2ab43062910c6c7c47d.json
@@ -0,0 +1,20 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nINSERT INTO magic_links\n(id, user_id, csrf_token, cookie, exp, used, usage)\nVALUES ($1, $2, $3, $4, $5, $6, $7)",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Int8",
+        "Bool",
+        "Varchar"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "cd5113b6e8e12d0f50cb46ce38c911e6d6ee138a2af2a2ab43062910c6c7c47d"
+}
diff --git a/.sqlx/query-ceb8ea9d2130d195a25f95f60356167c5520e4988464ee34e82b8625ec6e0b66.json b/.sqlx/query-ceb8ea9d2130d195a25f95f60356167c5520e4988464ee34e82b8625ec6e0b66.json
new file mode 100644
index 000000000..46ea656af
--- /dev/null
+++ b/.sqlx/query-ceb8ea9d2130d195a25f95f60356167c5520e4988464ee34e82b8625ec6e0b66.json
@@ -0,0 +1,27 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nINSERT INTO USERS\n(id, email, given_name, family_name, roles, groups, enabled, email_verified, created_at,\nlast_login, language, user_expires, auth_provider_id, federation_uid)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Bool",
+        "Bool",
+        "Int8",
+        "Int8",
+        "Varchar",
+        "Int8",
+        "Varchar",
+        "Varchar"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "ceb8ea9d2130d195a25f95f60356167c5520e4988464ee34e82b8625ec6e0b66"
+}
diff --git a/.sqlx/query-ceda93eeb98367d12d94c3fbd948861e5a61ad5b78ab418867ac34a06354aacd.json b/.sqlx/query-ceda93eeb98367d12d94c3fbd948861e5a61ad5b78ab418867ac34a06354aacd.json
new file mode 100644
index 000000000..c404728e2
--- /dev/null
+++ b/.sqlx/query-ceda93eeb98367d12d94c3fbd948861e5a61ad5b78ab418867ac34a06354aacd.json
@@ -0,0 +1,79 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nSELECT *\nFROM sessions\nWHERE exp >= $1 AND id != $2\nORDER BY exp ASC\nLIMIT $3\nOFFSET $4",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "csrf_token",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "user_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 3,
+        "name": "roles",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 4,
+        "name": "groups",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 5,
+        "name": "is_mfa",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 6,
+        "name": "state",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 7,
+        "name": "exp",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 8,
+        "name": "last_seen",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 9,
+        "name": "remote_ip",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Int8",
+        "Text",
+        "Int8",
+        "Int8"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      true,
+      true,
+      true,
+      false,
+      false,
+      false,
+      false,
+      true
+    ]
+  },
+  "hash": "ceda93eeb98367d12d94c3fbd948861e5a61ad5b78ab418867ac34a06354aacd"
+}
diff --git a/.sqlx/query-cf3c7a8fbfdc6e7170abbf694a49ef24714dfee13fd47246ff99c116e928172c.json b/.sqlx/query-cf3c7a8fbfdc6e7170abbf694a49ef24714dfee13fd47246ff99c116e928172c.json
new file mode 100644
index 000000000..946fcbbfd
--- /dev/null
+++ b/.sqlx/query-cf3c7a8fbfdc6e7170abbf694a49ef24714dfee13fd47246ff99c116e928172c.json
@@ -0,0 +1,16 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "INSERT INTO webids (user_id, custom_triples, expose_email) VALUES ($1, $2, $3)",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar",
+        "Bool"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "cf3c7a8fbfdc6e7170abbf694a49ef24714dfee13fd47246ff99c116e928172c"
+}
diff --git a/.sqlx/query-cf8ac230e4accc56477b3bd89ca8b5e8a8c10eb2ce5a0105be59c9370a8eef33.json b/.sqlx/query-cf8ac230e4accc56477b3bd89ca8b5e8a8c10eb2ce5a0105be59c9370a8eef33.json
new file mode 100644
index 000000000..796fdd6c8
--- /dev/null
+++ b/.sqlx/query-cf8ac230e4accc56477b3bd89ca8b5e8a8c10eb2ce5a0105be59c9370a8eef33.json
@@ -0,0 +1,15 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "UPDATE users SET language = $1 WHERE id = $2",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "cf8ac230e4accc56477b3bd89ca8b5e8a8c10eb2ce5a0105be59c9370a8eef33"
+}
diff --git a/.sqlx/query-cfe603c8063b41e88e380d244b2df7545ce3c2af2fa0a761bb533b0e4ca8728e.json b/.sqlx/query-cfe603c8063b41e88e380d244b2df7545ce3c2af2fa0a761bb533b0e4ca8728e.json
new file mode 100644
index 000000000..e6e90704b
--- /dev/null
+++ b/.sqlx/query-cfe603c8063b41e88e380d244b2df7545ce3c2af2fa0a761bb533b0e4ca8728e.json
@@ -0,0 +1,19 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nINSERT INTO refresh_tokens_devices\n(id, device_id, user_id, nbf, exp, scope)\nVALUES ($1, $2, $3, $4, $5, $6)\nON CONFLICT(id) DO UPDATE\nSET device_id = $2, user_id = $3, nbf = $4, exp = $5, scope = $6",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Int8",
+        "Int8",
+        "Varchar"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "cfe603c8063b41e88e380d244b2df7545ce3c2af2fa0a761bb533b0e4ca8728e"
+}
diff --git a/.sqlx/query-d006a5473134e85a56d53edff8fa8926f4ba08f5b04a0079adf68537696ccd2d.json b/.sqlx/query-d006a5473134e85a56d53edff8fa8926f4ba08f5b04a0079adf68537696ccd2d.json
new file mode 100644
index 000000000..8a712ad35
--- /dev/null
+++ b/.sqlx/query-d006a5473134e85a56d53edff8fa8926f4ba08f5b04a0079adf68537696ccd2d.json
@@ -0,0 +1,28 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM recent_passwords WHERE user_id = $1",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "user_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "passwords",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": [
+      false,
+      false
+    ]
+  },
+  "hash": "d006a5473134e85a56d53edff8fa8926f4ba08f5b04a0079adf68537696ccd2d"
+}
diff --git a/.sqlx/query-d1f9ab51f78e6f7fe71ea765e472796f6ccad3f9ea655b05bb376fb61d06d754.json b/.sqlx/query-d1f9ab51f78e6f7fe71ea765e472796f6ccad3f9ea655b05bb376fb61d06d754.json
new file mode 100644
index 000000000..a06c6f93f
--- /dev/null
+++ b/.sqlx/query-d1f9ab51f78e6f7fe71ea765e472796f6ccad3f9ea655b05bb376fb61d06d754.json
@@ -0,0 +1,34 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM webids WHERE user_id = $1",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "user_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "custom_triples",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "expose_email",
+        "type_info": "Bool"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": [
+      false,
+      true,
+      false
+    ]
+  },
+  "hash": "d1f9ab51f78e6f7fe71ea765e472796f6ccad3f9ea655b05bb376fb61d06d754"
+}
diff --git a/.sqlx/query-d7fdb5fb0e3b6416997f6f1afeb2c8c06d9e10dce3d942fc881d5dab8577a71a.json b/.sqlx/query-d7fdb5fb0e3b6416997f6f1afeb2c8c06d9e10dce3d942fc881d5dab8577a71a.json
new file mode 100644
index 000000000..7bcb13de3
--- /dev/null
+++ b/.sqlx/query-d7fdb5fb0e3b6416997f6f1afeb2c8c06d9e10dce3d942fc881d5dab8577a71a.json
@@ -0,0 +1,17 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nUPDATE clients_dyn\nSET registration_token = $1, token_endpoint_auth_method = $2, last_used = $3\nWHERE id = $4",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Bytea",
+        "Varchar",
+        "Int8",
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "d7fdb5fb0e3b6416997f6f1afeb2c8c06d9e10dce3d942fc881d5dab8577a71a"
+}
diff --git a/.sqlx/query-dc535ae89602c03172dc24b740c4f1cec57373a9ab84c905dc347d951c9e4d73.json b/.sqlx/query-dc535ae89602c03172dc24b740c4f1cec57373a9ab84c905dc347d951c9e4d73.json
new file mode 100644
index 000000000..ff1d8608a
--- /dev/null
+++ b/.sqlx/query-dc535ae89602c03172dc24b740c4f1cec57373a9ab84c905dc347d951c9e4d73.json
@@ -0,0 +1,21 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\n    INSERT INTO devices\n    (id, client_id, user_id, created, access_exp, refresh_exp, peer_ip, name)\n    VALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Int8",
+        "Int8",
+        "Int8",
+        "Varchar",
+        "Varchar"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "dc535ae89602c03172dc24b740c4f1cec57373a9ab84c905dc347d951c9e4d73"
+}
diff --git a/.sqlx/query-de5aeecef179c8ea2d48a60019f3fe67678dac4418310559fed96b4afa0a99e0.json b/.sqlx/query-de5aeecef179c8ea2d48a60019f3fe67678dac4418310559fed96b4afa0a99e0.json
new file mode 100644
index 000000000..713ff885a
--- /dev/null
+++ b/.sqlx/query-de5aeecef179c8ea2d48a60019f3fe67678dac4418310559fed96b4afa0a99e0.json
@@ -0,0 +1,17 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "UPDATE api_keys SET secret = $1, enc_key_id = $2, access = $3 WHERE name = $4",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Bytea",
+        "Varchar",
+        "Bytea",
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "de5aeecef179c8ea2d48a60019f3fe67678dac4418310559fed96b4afa0a99e0"
+}
diff --git a/.sqlx/query-df305cff92072bb40ddc1857e9f0fcc0bae24190c153bd5ec80c62cb4f462899.json b/.sqlx/query-df305cff92072bb40ddc1857e9f0fcc0bae24190c153bd5ec80c62cb4f462899.json
new file mode 100644
index 000000000..bf4b574e1
--- /dev/null
+++ b/.sqlx/query-df305cff92072bb40ddc1857e9f0fcc0bae24190c153bd5ec80c62cb4f462899.json
@@ -0,0 +1,41 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nSELECT id, email, created_at, last_login\nFROM users\nWHERE email LIKE $1\nORDER BY created_at ASC\nLIMIT $2",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "email",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "created_at",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 3,
+        "name": "last_login",
+        "type_info": "Int8"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text",
+        "Int8"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      true
+    ]
+  },
+  "hash": "df305cff92072bb40ddc1857e9f0fcc0bae24190c153bd5ec80c62cb4f462899"
+}
diff --git a/.sqlx/query-e32a3145dae26932ca954c47505310de539335e259d2ab03080dca8f232387fb.json b/.sqlx/query-e32a3145dae26932ca954c47505310de539335e259d2ab03080dca8f232387fb.json
new file mode 100644
index 000000000..84e9a53c8
--- /dev/null
+++ b/.sqlx/query-e32a3145dae26932ca954c47505310de539335e259d2ab03080dca8f232387fb.json
@@ -0,0 +1,14 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "DELETE FROM groups WHERE id = $1",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "e32a3145dae26932ca954c47505310de539335e259d2ab03080dca8f232387fb"
+}
diff --git a/.sqlx/query-e9cf2498004d2921583595cc1c03b64e52ed4c57e68f7d0e591cb2fa0e59481e.json b/.sqlx/query-e9cf2498004d2921583595cc1c03b64e52ed4c57e68f7d0e591cb2fa0e59481e.json
new file mode 100644
index 000000000..ee22d3152
--- /dev/null
+++ b/.sqlx/query-e9cf2498004d2921583595cc1c03b64e52ed4c57e68f7d0e591cb2fa0e59481e.json
@@ -0,0 +1,15 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nINSERT INTO colors (client_id, data)\nVALUES ($1, $2)\nON CONFLICT(client_id) DO UPDATE\nSET data = $2",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Bytea"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "e9cf2498004d2921583595cc1c03b64e52ed4c57e68f7d0e591cb2fa0e59481e"
+}
diff --git a/.sqlx/query-eab99f97b237cb62ba2e8dae999225290bbb0ceb182ccfd67932870fb4b64a88.json b/.sqlx/query-eab99f97b237cb62ba2e8dae999225290bbb0ceb182ccfd67932870fb4b64a88.json
new file mode 100644
index 000000000..40a5f7c73
--- /dev/null
+++ b/.sqlx/query-eab99f97b237cb62ba2e8dae999225290bbb0ceb182ccfd67932870fb4b64a88.json
@@ -0,0 +1,43 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nSELECT id, email, created_at, last_login\nFROM users\nWHERE created_at >= $1 AND id != $2\nORDER BY created_at ASC\nLIMIT $3\nOFFSET $4",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "email",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "created_at",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 3,
+        "name": "last_login",
+        "type_info": "Int8"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Int8",
+        "Text",
+        "Int8",
+        "Int8"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      true
+    ]
+  },
+  "hash": "eab99f97b237cb62ba2e8dae999225290bbb0ceb182ccfd67932870fb4b64a88"
+}
diff --git a/.sqlx/query-eaec5510fdbb5d2a69ff23c3e9ed2610c75d49d8fbdfd516c0e018a9d799dcac.json b/.sqlx/query-eaec5510fdbb5d2a69ff23c3e9ed2610c75d49d8fbdfd516c0e018a9d799dcac.json
new file mode 100644
index 000000000..a963d7e36
--- /dev/null
+++ b/.sqlx/query-eaec5510fdbb5d2a69ff23c3e9ed2610c75d49d8fbdfd516c0e018a9d799dcac.json
@@ -0,0 +1,130 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM users WHERE roles LIKE $1",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "email",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "given_name",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 3,
+        "name": "family_name",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 4,
+        "name": "password",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 5,
+        "name": "roles",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 6,
+        "name": "groups",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 7,
+        "name": "enabled",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 8,
+        "name": "email_verified",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 9,
+        "name": "password_expires",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 10,
+        "name": "created_at",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 11,
+        "name": "last_login",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 12,
+        "name": "last_failed_login",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 13,
+        "name": "failed_login_attempts",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 14,
+        "name": "language",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 15,
+        "name": "webauthn_user_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 16,
+        "name": "user_expires",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 17,
+        "name": "auth_provider_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 18,
+        "name": "federation_uid",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      true,
+      true,
+      false,
+      true,
+      false,
+      false,
+      true,
+      false,
+      true,
+      true,
+      true,
+      false,
+      true,
+      true,
+      true,
+      true
+    ]
+  },
+  "hash": "eaec5510fdbb5d2a69ff23c3e9ed2610c75d49d8fbdfd516c0e018a9d799dcac"
+}
diff --git a/.sqlx/query-eb939995472d3023cef2f5e499aa9cbbc92fd927c53f5f4c700d44c0f8f8950b.json b/.sqlx/query-eb939995472d3023cef2f5e499aa9cbbc92fd927c53f5f4c700d44c0f8f8950b.json
new file mode 100644
index 000000000..c274f7a70
--- /dev/null
+++ b/.sqlx/query-eb939995472d3023cef2f5e499aa9cbbc92fd927c53f5f4c700d44c0f8f8950b.json
@@ -0,0 +1,50 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM refresh_tokens_devices",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "device_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "user_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 3,
+        "name": "nbf",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 4,
+        "name": "exp",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 5,
+        "name": "scope",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": []
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      false,
+      false,
+      true
+    ]
+  },
+  "hash": "eb939995472d3023cef2f5e499aa9cbbc92fd927c53f5f4c700d44c0f8f8950b"
+}
diff --git a/.sqlx/query-ebc6676ee43f285c76f0d356486da079ad77d23451ff613e7e62bb564cde88af.json b/.sqlx/query-ebc6676ee43f285c76f0d356486da079ad77d23451ff613e7e62bb564cde88af.json
new file mode 100644
index 000000000..a452f5100
--- /dev/null
+++ b/.sqlx/query-ebc6676ee43f285c76f0d356486da079ad77d23451ff613e7e62bb564cde88af.json
@@ -0,0 +1,33 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nINSERT INTO clients\n(id, name, enabled, confidential, secret, secret_kid, redirect_uris, post_logout_redirect_uris,\nallowed_origins, flows_enabled, access_token_alg, id_token_alg, auth_code_lifetime,\naccess_token_lifetime, scopes, default_scopes, challenge, force_mfa, client_uri, contacts)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20)",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar",
+        "Bool",
+        "Bool",
+        "Bytea",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Int4",
+        "Int4",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Bool",
+        "Varchar",
+        "Varchar"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "ebc6676ee43f285c76f0d356486da079ad77d23451ff613e7e62bb564cde88af"
+}
diff --git a/.sqlx/query-edcb1d8e096ca4e7fa84b546c244a0f19f6db3befb235a225531b62eb59ad68f.json b/.sqlx/query-edcb1d8e096ca4e7fa84b546c244a0f19f6db3befb235a225531b62eb59ad68f.json
new file mode 100644
index 000000000..bb71e3684
--- /dev/null
+++ b/.sqlx/query-edcb1d8e096ca4e7fa84b546c244a0f19f6db3befb235a225531b62eb59ad68f.json
@@ -0,0 +1,26 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM groups",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "name",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": []
+    },
+    "nullable": [
+      false,
+      false
+    ]
+  },
+  "hash": "edcb1d8e096ca4e7fa84b546c244a0f19f6db3befb235a225531b62eb59ad68f"
+}
diff --git a/.sqlx/query-ee88059633b946dea0c6f53ceb1ffdec86ed6508b9d48120661c1b3e27c248b3.json b/.sqlx/query-ee88059633b946dea0c6f53ceb1ffdec86ed6508b9d48120661c1b3e27c248b3.json
new file mode 100644
index 000000000..9212f5f03
--- /dev/null
+++ b/.sqlx/query-ee88059633b946dea0c6f53ceb1ffdec86ed6508b9d48120661c1b3e27c248b3.json
@@ -0,0 +1,21 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nINSERT INTO passkeys\n(user_id, name, passkey_user_id, passkey, credential_id, registered, last_used, user_verified)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Bytea",
+        "Int8",
+        "Int8",
+        "Bool"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "ee88059633b946dea0c6f53ceb1ffdec86ed6508b9d48120661c1b3e27c248b3"
+}
diff --git a/.sqlx/query-eea61d07e54c99e5278b95db56205d991c6a9dd156f1cf26b6183e2d01cfe6d5.json b/.sqlx/query-eea61d07e54c99e5278b95db56205d991c6a9dd156f1cf26b6183e2d01cfe6d5.json
new file mode 100644
index 000000000..507bdc90d
--- /dev/null
+++ b/.sqlx/query-eea61d07e54c99e5278b95db56205d991c6a9dd156f1cf26b6183e2d01cfe6d5.json
@@ -0,0 +1,14 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "DELETE FROM api_keys WHERE name = $1",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "eea61d07e54c99e5278b95db56205d991c6a9dd156f1cf26b6183e2d01cfe6d5"
+}
diff --git a/.sqlx/query-eec70f5e791d1c7e993afe45148baf15b0a10b8bdd4eed793d369465f7dcf88f.json b/.sqlx/query-eec70f5e791d1c7e993afe45148baf15b0a10b8bdd4eed793d369465f7dcf88f.json
new file mode 100644
index 000000000..26514c22a
--- /dev/null
+++ b/.sqlx/query-eec70f5e791d1c7e993afe45148baf15b0a10b8bdd4eed793d369465f7dcf88f.json
@@ -0,0 +1,15 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "UPDATE groups SET name = $1 WHERE id = $2",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "eec70f5e791d1c7e993afe45148baf15b0a10b8bdd4eed793d369465f7dcf88f"
+}
diff --git a/.sqlx/query-eec9183b1e98dac7a2cc94a354600a47f15c3185b4bdd6d706545a275ee588fc.json b/.sqlx/query-eec9183b1e98dac7a2cc94a354600a47f15c3185b4bdd6d706545a275ee588fc.json
new file mode 100644
index 000000000..78af49dbb
--- /dev/null
+++ b/.sqlx/query-eec9183b1e98dac7a2cc94a354600a47f15c3185b4bdd6d706545a275ee588fc.json
@@ -0,0 +1,43 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nSELECT id, email, created_at, last_login\nFROM users\nWHERE created_at <= $1 AND id != $2\nORDER BY created_at DESC\nLIMIT $3\nOFFSET $4",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "email",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "created_at",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 3,
+        "name": "last_login",
+        "type_info": "Int8"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Int8",
+        "Text",
+        "Int8",
+        "Int8"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      true
+    ]
+  },
+  "hash": "eec9183b1e98dac7a2cc94a354600a47f15c3185b4bdd6d706545a275ee588fc"
+}
diff --git a/.sqlx/query-eedc2697013f0dc1f74e6c6496e8182eadc1631718fd4415e02b57d6c16bca12.json b/.sqlx/query-eedc2697013f0dc1f74e6c6496e8182eadc1631718fd4415e02b57d6c16bca12.json
new file mode 100644
index 000000000..d48116e43
--- /dev/null
+++ b/.sqlx/query-eedc2697013f0dc1f74e6c6496e8182eadc1631718fd4415e02b57d6c16bca12.json
@@ -0,0 +1,130 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM users WHERE groups LIKE $1",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "email",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "given_name",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 3,
+        "name": "family_name",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 4,
+        "name": "password",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 5,
+        "name": "roles",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 6,
+        "name": "groups",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 7,
+        "name": "enabled",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 8,
+        "name": "email_verified",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 9,
+        "name": "password_expires",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 10,
+        "name": "created_at",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 11,
+        "name": "last_login",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 12,
+        "name": "last_failed_login",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 13,
+        "name": "failed_login_attempts",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 14,
+        "name": "language",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 15,
+        "name": "webauthn_user_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 16,
+        "name": "user_expires",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 17,
+        "name": "auth_provider_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 18,
+        "name": "federation_uid",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      true,
+      true,
+      false,
+      true,
+      false,
+      false,
+      true,
+      false,
+      true,
+      true,
+      true,
+      false,
+      true,
+      true,
+      true,
+      true
+    ]
+  },
+  "hash": "eedc2697013f0dc1f74e6c6496e8182eadc1631718fd4415e02b57d6c16bca12"
+}
diff --git a/.sqlx/query-f035d18ad0c84c2602af178b4a39befd1be0b78fb3d94fdf109d6f2e4124e746.json b/.sqlx/query-f035d18ad0c84c2602af178b4a39befd1be0b78fb3d94fdf109d6f2e4124e746.json
new file mode 100644
index 000000000..7804b8660
--- /dev/null
+++ b/.sqlx/query-f035d18ad0c84c2602af178b4a39befd1be0b78fb3d94fdf109d6f2e4124e746.json
@@ -0,0 +1,15 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "INSERT INTO user_attr_config (name, \"desc\") VALUES ($1, $2)",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "f035d18ad0c84c2602af178b4a39befd1be0b78fb3d94fdf109d6f2e4124e746"
+}
diff --git a/.sqlx/query-f08f2971b6eed81db93046b21289a4a09ea3229bf675b46122fda3e2fb9ccdc5.json b/.sqlx/query-f08f2971b6eed81db93046b21289a4a09ea3229bf675b46122fda3e2fb9ccdc5.json
new file mode 100644
index 000000000..78f26c48a
--- /dev/null
+++ b/.sqlx/query-f08f2971b6eed81db93046b21289a4a09ea3229bf675b46122fda3e2fb9ccdc5.json
@@ -0,0 +1,50 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM refresh_tokens",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "user_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "nbf",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 3,
+        "name": "exp",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 4,
+        "name": "scope",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 5,
+        "name": "is_mfa",
+        "type_info": "Bool"
+      }
+    ],
+    "parameters": {
+      "Left": []
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      false,
+      true,
+      false
+    ]
+  },
+  "hash": "f08f2971b6eed81db93046b21289a4a09ea3229bf675b46122fda3e2fb9ccdc5"
+}
diff --git a/.sqlx/query-f3f58600e971f1be6cbe206bba24f77769f54c6230e28f5b3dc719b869d9cb3f.json b/.sqlx/query-f3f58600e971f1be6cbe206bba24f77769f54c6230e28f5b3dc719b869d9cb3f.json
new file mode 100644
index 000000000..845c5b0d4
--- /dev/null
+++ b/.sqlx/query-f3f58600e971f1be6cbe206bba24f77769f54c6230e28f5b3dc719b869d9cb3f.json
@@ -0,0 +1,130 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM users WHERE email = $1",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "email",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "given_name",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 3,
+        "name": "family_name",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 4,
+        "name": "password",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 5,
+        "name": "roles",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 6,
+        "name": "groups",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 7,
+        "name": "enabled",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 8,
+        "name": "email_verified",
+        "type_info": "Bool"
+      },
+      {
+        "ordinal": 9,
+        "name": "password_expires",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 10,
+        "name": "created_at",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 11,
+        "name": "last_login",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 12,
+        "name": "last_failed_login",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 13,
+        "name": "failed_login_attempts",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 14,
+        "name": "language",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 15,
+        "name": "webauthn_user_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 16,
+        "name": "user_expires",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 17,
+        "name": "auth_provider_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 18,
+        "name": "federation_uid",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      true,
+      true,
+      false,
+      true,
+      false,
+      false,
+      true,
+      false,
+      true,
+      true,
+      true,
+      false,
+      true,
+      true,
+      true,
+      true
+    ]
+  },
+  "hash": "f3f58600e971f1be6cbe206bba24f77769f54c6230e28f5b3dc719b869d9cb3f"
+}
diff --git a/.sqlx/query-f4d143ff76a4f09517195dcd5fd20a17dca8f5fe7d22a78414487019502afa1a.json b/.sqlx/query-f4d143ff76a4f09517195dcd5fd20a17dca8f5fe7d22a78414487019502afa1a.json
new file mode 100644
index 000000000..79f314cef
--- /dev/null
+++ b/.sqlx/query-f4d143ff76a4f09517195dcd5fd20a17dca8f5fe7d22a78414487019502afa1a.json
@@ -0,0 +1,14 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "DELETE FROM auth_provider_logos WHERE auth_provider_id = $1",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "f4d143ff76a4f09517195dcd5fd20a17dca8f5fe7d22a78414487019502afa1a"
+}
diff --git a/.sqlx/query-f5ea9039c0e9770185613fd18ed465a4783bed414fc78e6bfea0110c6179f72b.json b/.sqlx/query-f5ea9039c0e9770185613fd18ed465a4783bed414fc78e6bfea0110c6179f72b.json
new file mode 100644
index 000000000..834328938
--- /dev/null
+++ b/.sqlx/query-f5ea9039c0e9770185613fd18ed465a4783bed414fc78e6bfea0110c6179f72b.json
@@ -0,0 +1,65 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM passkeys WHERE user_id = $1 AND name = $2",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "user_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "name",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "passkey_user_id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 3,
+        "name": "passkey",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 4,
+        "name": "credential_id",
+        "type_info": "Bytea"
+      },
+      {
+        "ordinal": 5,
+        "name": "registered",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 6,
+        "name": "last_used",
+        "type_info": "Int8"
+      },
+      {
+        "ordinal": 7,
+        "name": "user_verified",
+        "type_info": "Bool"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text",
+        "Text"
+      ]
+    },
+    "nullable": [
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      false,
+      true
+    ]
+  },
+  "hash": "f5ea9039c0e9770185613fd18ed465a4783bed414fc78e6bfea0110c6179f72b"
+}
diff --git a/.sqlx/query-f7b883a045b8bfd094254f83641a8d865c3a46a4102caac60e51fe00c6944ebb.json b/.sqlx/query-f7b883a045b8bfd094254f83641a8d865c3a46a4102caac60e51fe00c6944ebb.json
new file mode 100644
index 000000000..d4b8cd65f
--- /dev/null
+++ b/.sqlx/query-f7b883a045b8bfd094254f83641a8d865c3a46a4102caac60e51fe00c6944ebb.json
@@ -0,0 +1,14 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "DELETE FROM clients WHERE id = $1",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "f7b883a045b8bfd094254f83641a8d865c3a46a4102caac60e51fe00c6944ebb"
+}
diff --git a/.sqlx/query-f7c2eba048c19f4f8c8fcb013739540dffae5cfbb54eaa2bf37b052d6274254c.json b/.sqlx/query-f7c2eba048c19f4f8c8fcb013739540dffae5cfbb54eaa2bf37b052d6274254c.json
new file mode 100644
index 000000000..b71bd1949
--- /dev/null
+++ b/.sqlx/query-f7c2eba048c19f4f8c8fcb013739540dffae5cfbb54eaa2bf37b052d6274254c.json
@@ -0,0 +1,14 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "UPDATE refresh_tokens SET exp = $1 WHERE exp > $1",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Int8"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "f7c2eba048c19f4f8c8fcb013739540dffae5cfbb54eaa2bf37b052d6274254c"
+}
diff --git a/.sqlx/query-f9d79451d3415ea0992e57e9d74764041e8122405e0f763676645b81f9a30183.json b/.sqlx/query-f9d79451d3415ea0992e57e9d74764041e8122405e0f763676645b81f9a30183.json
new file mode 100644
index 000000000..154c3e0ed
--- /dev/null
+++ b/.sqlx/query-f9d79451d3415ea0992e57e9d74764041e8122405e0f763676645b81f9a30183.json
@@ -0,0 +1,16 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "UPDATE devices SET name = $1 WHERE id = $2 AND user_id = $3",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Text",
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "f9d79451d3415ea0992e57e9d74764041e8122405e0f763676645b81f9a30183"
+}
diff --git a/.sqlx/query-f9fb5b2d1f0a6652fdb78984dfb37249f75a8cc2ff356c41299bc02774fef112.json b/.sqlx/query-f9fb5b2d1f0a6652fdb78984dfb37249f75a8cc2ff356c41299bc02774fef112.json
new file mode 100644
index 000000000..beda409fc
--- /dev/null
+++ b/.sqlx/query-f9fb5b2d1f0a6652fdb78984dfb37249f75a8cc2ff356c41299bc02774fef112.json
@@ -0,0 +1,12 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "DELETE FROM clients WHERE id = 'init_client'",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": []
+    },
+    "nullable": []
+  },
+  "hash": "f9fb5b2d1f0a6652fdb78984dfb37249f75a8cc2ff356c41299bc02774fef112"
+}
diff --git a/.sqlx/query-faffa565a683f0db53199d7b03cd27d4fd54f99ea1ddd79db83001262fb8122c.json b/.sqlx/query-faffa565a683f0db53199d7b03cd27d4fd54f99ea1ddd79db83001262fb8122c.json
new file mode 100644
index 000000000..d8a6fb18b
--- /dev/null
+++ b/.sqlx/query-faffa565a683f0db53199d7b03cd27d4fd54f99ea1ddd79db83001262fb8122c.json
@@ -0,0 +1,28 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM groups WHERE id = $1",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "name",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": [
+        "Text"
+      ]
+    },
+    "nullable": [
+      false,
+      false
+    ]
+  },
+  "hash": "faffa565a683f0db53199d7b03cd27d4fd54f99ea1ddd79db83001262fb8122c"
+}
diff --git a/.sqlx/query-fdfb43cae011fa1a43a7794723730454dc8d7019eb4597ef76d3886796f73707.json b/.sqlx/query-fdfb43cae011fa1a43a7794723730454dc8d7019eb4597ef76d3886796f73707.json
new file mode 100644
index 000000000..d87b5c5b2
--- /dev/null
+++ b/.sqlx/query-fdfb43cae011fa1a43a7794723730454dc8d7019eb4597ef76d3886796f73707.json
@@ -0,0 +1,18 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\n    UPDATE api_keys\n    SET secret = $1, expires = $2, enc_key_id = $3, access = $4\n    WHERE name = $5",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Bytea",
+        "Int8",
+        "Varchar",
+        "Bytea",
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "fdfb43cae011fa1a43a7794723730454dc8d7019eb4597ef76d3886796f73707"
+}
diff --git a/.sqlx/query-fea872c5e507460874609fc2719742f85036645a43ac15365e4728a17bd9787c.json b/.sqlx/query-fea872c5e507460874609fc2719742f85036645a43ac15365e4728a17bd9787c.json
new file mode 100644
index 000000000..086815556
--- /dev/null
+++ b/.sqlx/query-fea872c5e507460874609fc2719742f85036645a43ac15365e4728a17bd9787c.json
@@ -0,0 +1,19 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nINSERT INTO refresh_tokens_devices\n(id, device_id, user_id, nbf, exp, scope)\nVALUES ($1, $2, $3, $4, $5, $6)",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Int8",
+        "Int8",
+        "Varchar"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "fea872c5e507460874609fc2719742f85036645a43ac15365e4728a17bd9787c"
+}
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 1a093c22f..5fce1655f 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -72,6 +72,9 @@ Afterward, it will create a docker network named `rauthy-dev` and start `mailcra
 
 As the last step, it will do a `cargo build` to make sure there are not compile errors.
 
+> If you want to use a Postgres other than the one created by `just setup`, you most probably need to provide a
+> different `DATABASE_URL` than the default in `rauthy.cfg`.
+
 ### Config
 
 The default config file is the `rauthy.cfg`. This has reasonable defaults for local dev.
diff --git a/justfile b/justfile
index 400a102da..35f87870c 100644
--- a/justfile
+++ b/justfile
@@ -153,6 +153,8 @@ mailcrab-stop:
 
 # Starts mailcrab
 postgres-start:
+    #!/usr/bin/env bash
+
     {{ docker }} run -d \
       -e POSTGRES_USER=rauthy \
       -e POSTGRES_PASSWORD=123SuperSafe \
@@ -163,8 +165,10 @@ postgres-start:
       --restart unless-stopped \
       docker.io/library/postgres:17.2-alpine
 
-    sleep 3
-    just migrate-postgres
+    while ! just migrate-postgres; do
+        echo "Database migrations failed - Postgres is probably still starting up"
+        sleep 3
+    done
 
 # Stops mailcrab
 postgres-stop:
@@ -192,7 +196,8 @@ delete-hiqlite:
 
 # migrate the postgres database with sqlx
 migrate-postgres:
-    sqlx migrate run --source migrations/postgres
+    cargo sqlx migrate run --source migrations/postgres
+    cargo sqlx prepare --workspace
 
 # runs any of: none (hiqlite), postgres, ui
 run ty="hiqlite":
diff --git a/migrations/sqlite/10_events.sql b/migrations/sqlite/10_events.sql
deleted file mode 100644
index 89b63f307..000000000
--- a/migrations/sqlite/10_events.sql
+++ /dev/null
@@ -1,15 +0,0 @@
-create table events
-(
-    id        varchar  not null,
-    timestamp bigint   not null,
-    typ       smallint not null,
-    level     smallint not null,
-    ip        varchar,
-    data      bigint,
-    text      varchar,
-    constraint events_pk
-        primary key (id, timestamp)
-);
-
-create index events_timestamp_index
-    on events (timestamp desc);
diff --git a/migrations/sqlite/11_api_keys.sql b/migrations/sqlite/11_api_keys.sql
deleted file mode 100644
index 681d918c3..000000000
--- a/migrations/sqlite/11_api_keys.sql
+++ /dev/null
@@ -1,17 +0,0 @@
-create table api_keys
-(
-    name             varchar           not null
-        constraint api_keys_pk
-            primary key,
-    secret           blob              not null,
-    created          bigint            not null,
-    expires          bigint,
-    enc_key_id       varchar           not null,
-    access           blob              not null
-);
-
-create index api_keys_enc_key_id_index
-    on api_keys (enc_key_id);
-
-create index api_keys_expires_index
-    on api_keys (expires);
diff --git a/migrations/sqlite/12_clients_force_mfa.sql b/migrations/sqlite/12_clients_force_mfa.sql
deleted file mode 100644
index 2b9e33bf4..000000000
--- a/migrations/sqlite/12_clients_force_mfa.sql
+++ /dev/null
@@ -1,117 +0,0 @@
--- modify the clients table and add 'force_mfa'
-
-alter table clients
-    rename to clients_old;
-
-create table clients
-(
-    id                        varchar not null
-        constraint clients_pk
-            primary key,
-    name                      varchar,
-    enabled                   bool    not null,
-    confidential              bool    not null,
-    secret                    blob,
-    secret_kid                varchar,
-    redirect_uris             varchar not null,
-    post_logout_redirect_uris varchar,
-    allowed_origins           varchar,
-    flows_enabled             varchar not null,
-    access_token_alg          varchar not null,
-    id_token_alg              varchar not null,
-    refresh_token             bool    not null,
-    auth_code_lifetime        integer not null,
-    access_token_lifetime     integer not null,
-    scopes                    varchar not null,
-    default_scopes            varchar not null,
-    challenge                 varchar,
-    force_mfa                 bool    not null
-);
-
-insert into clients(id,
-                    name,
-                    enabled,
-                    confidential,
-                    secret,
-                    secret_kid,
-                    redirect_uris,
-                    post_logout_redirect_uris,
-                    allowed_origins,
-                    flows_enabled,
-                    access_token_alg,
-                    id_token_alg,
-                    refresh_token,
-                    auth_code_lifetime,
-                    access_token_lifetime,
-                    scopes,
-                    default_scopes,
-                    challenge,
-                    force_mfa)
-select id,
-       name,
-       enabled,
-       confidential,
-       secret,
-       secret_kid,
-       redirect_uris,
-       post_logout_redirect_uris,
-       allowed_origins,
-       flows_enabled,
-       access_token_alg,
-       id_token_alg,
-       refresh_token,
-       auth_code_lifetime,
-       access_token_lifetime,
-       scopes,
-       default_scopes,
-       challenge,
-       false as force_mfa
-from clients_old;
-
--- recreate all tables with foreign keys to clients
-
--- colors
-alter table colors
-    rename to colors_old;
-
-create table colors
-(
-    client_id varchar(36) not null
-        constraint colors_pk
-            primary key
-        constraint colors_clients_id_fk
-            references clients
-            on update cascade
-            on delete cascade,
-    data      blob not null
-);
-
-insert into colors(client_id, data)
-select client_id, data
-from colors_old;
-
--- logos
-alter table logos
-    rename to logos_old;
-
-create table logos
-(
-    client_id varchar(36) not null
-        constraint logos_pk
-            primary key
-        constraint logos_clients_id_fk
-            references clients
-            on update cascade
-            on delete cascade,
-    data     blob not null
-);
-
-insert into logos(client_id, data)
-select client_id, data
-from logos_old;
-
--- finally, drop all the old tables
-
-drop table colors_old;
-drop table logos_old;
-drop table clients_old;
diff --git a/migrations/sqlite/13_webids.sql b/migrations/sqlite/13_webids.sql
deleted file mode 100644
index 2b97337f6..000000000
--- a/migrations/sqlite/13_webids.sql
+++ /dev/null
@@ -1,11 +0,0 @@
-create table webids
-(
-    user_id        varchar not null
-        constraint webids_pk
-            primary key
-        constraint webids_users_id_fk
-            references users
-            on update cascade on delete cascade,
-    custom_triples text,
-    expose_email   bool    not null
-);
diff --git a/migrations/sqlite/14_user_attr_values_fk_fix.sql b/migrations/sqlite/14_user_attr_values_fk_fix.sql
deleted file mode 100644
index 0bfa40417..000000000
--- a/migrations/sqlite/14_user_attr_values_fk_fix.sql
+++ /dev/null
@@ -1,22 +0,0 @@
-create table user_attr_values_dg_tmp
-(
-    user_id varchar not null
-        constraint user_attr_values_users_id_fk
-            references users
-            on update cascade on delete cascade,
-    key     varchar not null
-        references user_attr_config
-            on update cascade on delete cascade,
-    value   blob    not null,
-    constraint user_attr_values_pk
-        primary key (user_id, key)
-);
-
-insert into user_attr_values_dg_tmp(user_id, key, value)
-select user_id, key, value
-from user_attr_values;
-
-drop table user_attr_values;
-
-alter table user_attr_values_dg_tmp
-    rename to user_attr_values;
diff --git a/migrations/sqlite/15_users_values.sql b/migrations/sqlite/15_users_values.sql
deleted file mode 100644
index c6a5be94b..000000000
--- a/migrations/sqlite/15_users_values.sql
+++ /dev/null
@@ -1,15 +0,0 @@
-create table users_values
-(
-    id        text not null
-        constraint users_values_pk
-            primary key
-        constraint users_values_users_id_fk
-            references users
-            on update cascade on delete cascade,
-    birthdate text,
-    phone     text,
-    street    text,
-    zip       integer,
-    city      text,
-    country   text
-);
diff --git a/migrations/sqlite/16_additional_scopes.sql b/migrations/sqlite/16_additional_scopes.sql
deleted file mode 100644
index 2439cea71..000000000
--- a/migrations/sqlite/16_additional_scopes.sql
+++ /dev/null
@@ -1,3 +0,0 @@
-insert or ignore into scopes (id, name, attr_include_access, attr_include_id)
-values  ('awyOUa5rjFkowidSw03otjXU', 'address', null, null),
-        ('ImGlzlvfeOrJ9iY394AVeJgJ', 'phone', null, null);
diff --git a/migrations/sqlite/17_dynamic_clients.sql b/migrations/sqlite/17_dynamic_clients.sql
deleted file mode 100644
index d43361617..000000000
--- a/migrations/sqlite/17_dynamic_clients.sql
+++ /dev/null
@@ -1,16 +0,0 @@
-create table clients_dyn
-(
-    id                         text    not null
-        constraint clients_dyn_pk
-            primary key
-        constraint clients_dyn_clients_id_fk
-            references clients
-            on update cascade on delete cascade,
-    created                    integer not null,
-    last_used                  integer,
-    registration_token         blob    not null,
-    token_endpoint_auth_method text    not null
-);
-
-create index clients_dyn_last_used_index
-    on clients_dyn (last_used);
diff --git a/migrations/sqlite/18_dev_init_client_secret_update.sql b/migrations/sqlite/18_dev_init_client_secret_update.sql
deleted file mode 100644
index 1979e6563..000000000
--- a/migrations/sqlite/18_dev_init_client_secret_update.sql
+++ /dev/null
@@ -1,3 +0,0 @@
-update clients
-set secret = x'0101001600006256437954734761676756793579715147746CA4685D12B041464FEA154EAF7BEED2C71475DA6C3AE070688F9ABECD87539D54C9E981A5C02BAC2E9AEAFB5C0DF8D516218F4CD677CF180AF42FC4354F34DCBBC666784A9EBDF3524B8AE80D669575B1780CFB667CA19F4F1F'
-where id = 'init_client';
diff --git a/migrations/sqlite/19_auth_providers.sql b/migrations/sqlite/19_auth_providers.sql
deleted file mode 100644
index 932609b20..000000000
--- a/migrations/sqlite/19_auth_providers.sql
+++ /dev/null
@@ -1,367 +0,0 @@
--- create ne auth_providers table for upstream auth providers
-
-create table auth_providers
-(
-    id                      varchar not null
-        constraint auth_providers_pk
-            primary key,
-    enabled                 bool    not null,
-    name                    varchar not null,
-    typ                     varchar not null,
-    issuer                  varchar not null,
-    authorization_endpoint  varchar not null,
-    token_endpoint          varchar not null,
-    userinfo_endpoint       varchar not null,
-    client_id               varchar not null,
-    secret                  blob,
-    scope                   varchar not null,
-    admin_claim_path        varchar,
-    admin_claim_value       varchar,
-    mfa_claim_path          varchar,
-    mfa_claim_value         varchar,
-    allow_insecure_requests bool    not null,
-    use_pkce                bool    not null,
-    root_pem                varchar
-);
-
--- modify users table with fk to auth_providers
-
-alter table users
-    rename to users_old;
-
-drop index users_email_uindex;
-drop index users_webauthn_user_id_index;
-
-create table users
-(
-    id                    varchar              not null
-        constraint users_pk
-            primary key,
-    email                 varchar              not null
-        constraint users_email
-            unique,
-    given_name            varchar              not null,
-    family_name           varchar              not null,
-    password              varchar,
-    roles                 varchar              not null,
-    groups                varchar,
-    enabled               boolean              not null,
-    email_verified        boolean              not null,
-    password_expires      int,
-    created_at            int                  not null,
-    last_login            int,
-    last_failed_login     int,
-    failed_login_attempts int,
-    language              varchar default 'en' not null,
-    webauthn_user_id      varchar,
-    user_expires          int,
-    auth_provider_id      varchar
-        constraint users_auth_providers_id_fk
-            references auth_providers
-            on update cascade on delete set null,
-    federation_uid        varchar,
-    constraint users_federation_key
-        unique (auth_provider_id, federation_uid)
-);
-
-create unique index users_email_uindex
-    on users (email);
-
-create unique index users_webauthn_user_id_index
-    on users (webauthn_user_id);
-
-insert into users(id, email, given_name, family_name, password, roles, groups, enabled, email_verified,
-                  password_expires, created_at, last_login, last_failed_login, failed_login_attempts, language,
-                  webauthn_user_id, user_expires)
-select id,
-       email,
-       given_name,
-       family_name,
-       password,
-       roles,
-       groups,
-       enabled,
-       email_verified,
-       password_expires,
-       created_at,
-       last_login,
-       last_failed_login,
-       failed_login_attempts,
-       language,
-       webauthn_user_id,
-       user_expires
-from users_old;
-
--- recreate all tables with foreign keys to users
-
-alter table magic_links
-    rename to magic_links_old;
-
-drop index magic_links_exp_index;
-drop index magic_links_user_id_index;
-
-create table magic_links
-(
-    id         varchar not null
-        constraint magic_links_pk
-            primary key,
-    user_id    varchar not null
-        references users
-            on update cascade on delete cascade,
-    csrf_token varchar not null,
-    cookie     varchar,
-    exp        integer not null,
-    used       bool    not null,
-    usage      varchar not null
-);
-
-create index magic_links_exp_index
-    on magic_links (exp);
-
-create index magic_links_user_id_index
-    on magic_links (user_id);
-
-insert into magic_links(id, user_id, csrf_token, cookie, exp, used, usage)
-select id, user_id, csrf_token, cookie, exp, used, usage
-from magic_links_old;
-
-drop table magic_links_old;
-
---
-
-alter table recent_passwords
-    rename to recent_passwords_old;
-
-create table recent_passwords
-(
-    user_id   varchar not null
-        references users
-            on delete cascade
-            on update cascade
-        constraint recent_passwords_pk
-            primary key,
-    passwords varchar not null
-);
-
-insert into recent_passwords(user_id, passwords)
-select user_id, passwords
-from recent_passwords_old;
-
-drop table recent_passwords_old;
-
---
-
-alter table refresh_tokens
-    rename to refresh_tokens_old;
-
-drop index refresh_tokens_exp_index;
-drop index refresh_tokens_user_id_index;
-
-create table refresh_tokens
-(
-    id      varchar            not null
-        constraint refresh_tokens_pk
-            primary key,
-    user_id varchar            not null
-        references users
-            on delete cascade
-            on update cascade,
-    nbf     integer            not null,
-    exp     integer            not null,
-    scope   varchar,
-    is_mfa  bool default false not null
-);
-
-create index refresh_tokens_exp_index
-    on refresh_tokens (exp);
-
-create index refresh_tokens_user_id_index
-    on refresh_tokens (user_id);
-
-insert into refresh_tokens(id, user_id, nbf, exp, scope, is_mfa)
-select id, user_id, nbf, exp, scope, is_mfa
-from refresh_tokens_old;
-
-drop table refresh_tokens_old;
-
---
-
-alter table sessions
-    rename to sessions_old;
-
-drop index sessions_exp_index;
-
-create table sessions
-(
-    id         varchar not null
-        constraint sessions_pk
-            primary key,
-    csrf_token varchar not null,
-    user_id    varchar
-        references users
-            on update cascade on delete cascade,
-    roles      varchar,
-    groups     varchar,
-    is_mfa     bool    not null,
-    state      varchar not null,
-    exp        int     not null,
-    last_seen  int     not null,
-    remote_ip  varchar
-);
-
-create index sessions_exp_index
-    on sessions (exp);
-
-insert into sessions(id, csrf_token, user_id, roles, groups, is_mfa, state, exp, last_seen, remote_ip)
-select id,
-       csrf_token,
-       user_id,
-       roles,
-       groups,
-       is_mfa,
-       state,
-       exp,
-       last_seen,
-       remote_ip
-from sessions_old;
-
-drop table sessions_old;
-
---
-
-alter table passkeys
-    rename to passkeys_old;
-
-drop index passkeys_credential_id_index;
-drop index passkeys_passkey_user_id_index;
-
-create table passkeys
-(
-    user_id         varchar not null
-        constraint passkeys_users_id_fk
-            references users
-            on update cascade on delete cascade,
-    name            varchar not null,
-    passkey_user_id varchar not null,
-    passkey         varchar not null,
-    credential_id   blob    not null,
-    registered      integer not null,
-    last_used       integer not null,
-    user_verified   bool,
-    constraint passkeys_pk
-        primary key (user_id, name)
-);
-
-create unique index passkeys_credential_id_index
-    on passkeys (credential_id);
-
-create index passkeys_passkey_user_id_index
-    on passkeys (passkey_user_id);
-
-insert into passkeys(user_id, name, passkey_user_id, passkey, credential_id, registered, last_used, user_verified)
-select user_id,
-       name,
-       passkey_user_id,
-       passkey,
-       credential_id,
-       registered,
-       last_used,
-       user_verified
-from passkeys_old;
-
-drop table passkeys_old;
-
---
-
-alter table user_attr_values
-    rename to user_attr_values_old;
-
-create table user_attr_values
-(
-    user_id varchar not null
-        constraint user_attr_values_users_id_fk
-            references users
-            on update cascade on delete cascade,
-    key     varchar not null
-        references user_attr_config
-            on update cascade on delete cascade,
-    value   blob    not null,
-    constraint user_attr_values_pk
-        primary key (user_id, key)
-);
-
-insert into user_attr_values(user_id, key, value)
-select user_id, key, value
-from user_attr_values_old;
-
-drop table user_attr_values_old;
-
---
-
-alter table users_values
-    rename to users_values_old;
-
-create table users_values
-(
-    id        text not null
-        constraint users_values_pk
-            primary key
-        constraint users_values_users_id_fk
-            references users
-            on update cascade on delete cascade,
-    birthdate text,
-    phone     text,
-    street    text,
-    zip       integer,
-    city      text,
-    country   text
-);
-
-insert into users_values(id, birthdate, phone, street, zip, city, country)
-select id, birthdate, phone, street, zip, city, country
-from users_values_old;
-
-drop table users_values_old;
-
---
-
-
-alter table webids
-    rename to webids_old;
-
-create table webids
-(
-    user_id        varchar not null
-        constraint webids_pk
-            primary key
-        constraint webids_users_id_fk
-            references users
-            on update cascade on delete cascade,
-    custom_triples text,
-    expose_email   bool    not null
-);
-
-insert into webids(user_id, custom_triples, expose_email)
-select user_id, custom_triples, expose_email
-from webids_old;
-
-drop table webids_old;
-
--- finally drop the old users table
-
-drop table users_old;
-
--- auth_provider_logos table
-
-create table auth_provider_logos
-(
-    auth_provider_id varchar not null
-        constraint auth_provider_logos_auth_providers_id_fk
-            references auth_providers
-            on update cascade on delete cascade,
-    res              varchar not null,
-    content_type     varchar not null,
-    data             blob    not null,
-    constraint auth_provider_logos_pk
-        primary key (auth_provider_id, res)
-);
\ No newline at end of file
diff --git a/migrations/sqlite/1_init_schema.sql b/migrations/sqlite/1_init_schema.sql
deleted file mode 100644
index bcd823f94..000000000
--- a/migrations/sqlite/1_init_schema.sql
+++ /dev/null
@@ -1,208 +0,0 @@
-create table webauthn
-(
-    id      varchar(36) not null
-        constraint webauthn_pk
-        primary key,
-    passkey varchar(1024) not null
-);
-
-create table users
-(
-    id                    varchar(36)  not null
-        constraint users_pk
-        primary key,
-    email                 varchar(64)  not null
-        constraint users_email
-        unique,
-    given_name            varchar(128) not null,
-    family_name           varchar(128) not null,
-    password              varchar(128),
-    roles                 varchar(128) not null,
-    groups                varchar(128),
-    enabled               boolean      not null,
-    email_verified        boolean      not null,
-    password_expires      int,
-    created_at            int          not null,
-    last_login            int,
-    last_failed_login     int,
-    failed_login_attempts int,
-    mfa_app               varchar(36),
-    sec_key_1             varchar(36)
-        references webauthn,
-    sec_key_2             varchar(36)
-        references webauthn
-);
-
-create unique index users_email_uindex
-    on users (email);
-
-create table clients
-(
-    id                        varchar(36) not null
-        constraint clients_pk
-        primary key,
-    name                      varchar(128),
-    enabled                   bool         not null,
-    confidential              bool         not null,
-    secret                    blob,
-    secret_kid                varchar(24),
-    redirect_uris             varchar(255) not null,
-    post_logout_redirect_uris varchar(255),
-    allowed_origins           varchar(255),
-    flows_enabled             varchar(128) not null,
-    access_token_alg          varchar(8)  not null,
-    id_token_alg              varchar(8)  not null,
-    refresh_token             bool         not null,
-    auth_code_lifetime        integer      not null,
-    access_token_lifetime     integer      not null,
-    scopes                    varchar(128) not null,
-    default_scopes            varchar(128) not null,
-    challenge                 varchar(16)
-);
-
-create table groups
-(
-    id   varchar(36) not null
-        constraint groups_pk
-        primary key,
-    name varchar(32)
-);
-
-create table jwks
-(
-    kid        varchar(36) not null
-        constraint jwks_pk
-        primary key,
-    created_at integer     not null,
-    signature  blob        not null,
-    enc_key_id varchar(24) not null,
-    jwk        blob        not null
-);
-
-create table magic_links
-(
-    id         varchar(64) not null
-        constraint magic_links_pk
-        primary key,
-    user_id    varchar(36) not null
-        references users
-        on delete cascade
-        on update cascade,
-    csrf_token varchar(48) not null,
-    cookie     varchar(48),
-    exp        integer     not null,
-    used       bool
-);
-
-create index magic_links_exp_index
-    on magic_links (exp);
-
-create index magic_links_user_id_index
-    on magic_links (user_id);
-
-create table mfa_apps
-(
-    app_id varchar(64) not null
-        constraint mfa_apps_pk
-        primary key,
-    email  varchar(64) not null,
-    secret varchar(64) not null
-);
-
-create table config
-(
-    id   varchar(32)
-        constraint config_pk
-        primary key,
-    data blob
-);
-
-create table recent_passwords
-(
-    user_id  varchar(36) not null
-        references users
-            on delete cascade
-            on update cascade
-        constraint recent_passwords_pk
-        primary key,
-    passwords varchar(1024)
-);
-
-create table refresh_tokens
-(
-    id      varchar(36) not null
-        constraint refresh_tokens_pk
-        primary key,
-    user_id varchar(36) not null
-        references users
-            on delete cascade
-            on update cascade,
-    nbf     integer     not null,
-    exp     integer     not null,
-    scope   varchar(128)
-);
-
-create index refresh_tokens_exp_index
-    on refresh_tokens (exp);
-
-create index refresh_tokens_user_id_index
-    on refresh_tokens (user_id);
-
-create table roles
-(
-    id   varchar(36)  not null
-        constraint roles_pk
-        primary key,
-    name varchar(32) not null
-);
-
-create table scopes
-(
-    id                  varchar(36) not null
-        constraint scopes_pk
-        primary key,
-    name                varchar(32) not null,
-    attr_include_access varchar(128),
-    attr_include_id     varchar(128)
-);
-
-create table user_attr_config
-(
-    name varchar(128) not null
-        constraint user_attr_config_pk
-        primary key,
-    desc varchar(128)
-);
-
-create table user_attr_values
-(
-    user_id varchar(36) not null,
-    key     varchar(32)
-        references user_attr_config
-            on delete cascade
-            on update cascade,
-    value   blob,
-    constraint user_attr_values_pk
-        primary key (user_id, key)
-);
-
-create table sessions
-(
-    id         varchar(36) not null
-        constraint sessions_pk
-        primary key,
-    csrf_token varchar(32) not null,
-    user_id    varchar(36)
-        references users
-            on delete cascade
-            on update cascade,
-    roles      varchar(255),
-    groups     varchar(255),
-    is_mfa     bool        not null,
-    state      varchar(8)  not null,
-    exp        int         not null,
-    last_seen  int         not null
-);
-
-create index sessions_exp_index
-    on sessions (exp);
diff --git a/migrations/sqlite/20_clients_uri_contacts_logos.sql b/migrations/sqlite/20_clients_uri_contacts_logos.sql
deleted file mode 100644
index e58c9b21c..000000000
--- a/migrations/sqlite/20_clients_uri_contacts_logos.sql
+++ /dev/null
@@ -1,214 +0,0 @@
--- modify the clients table and add 'force_mfa'
-
-alter table clients
-    rename to clients_old;
-
-create table clients
-(
-    id                        varchar not null
-        constraint clients_pk
-            primary key,
-    name                      varchar,
-    enabled                   bool    not null,
-    confidential              bool    not null,
-    secret                    blob,
-    secret_kid                varchar,
-    redirect_uris             varchar not null,
-    post_logout_redirect_uris varchar,
-    allowed_origins           varchar,
-    flows_enabled             varchar not null,
-    access_token_alg          varchar not null,
-    id_token_alg              varchar not null,
-    refresh_token             bool    not null,
-    auth_code_lifetime        integer not null,
-    access_token_lifetime     integer not null,
-    scopes                    varchar not null,
-    default_scopes            varchar not null,
-    challenge                 varchar,
-    force_mfa                 bool    not null,
-    client_uri                varchar,
-    contacts                  varchar
-);
-
-insert into clients(id,
-                    name,
-                    enabled,
-                    confidential,
-                    secret,
-                    secret_kid,
-                    redirect_uris,
-                    post_logout_redirect_uris,
-                    allowed_origins,
-                    flows_enabled,
-                    access_token_alg,
-                    id_token_alg,
-                    refresh_token,
-                    auth_code_lifetime,
-                    access_token_lifetime,
-                    scopes,
-                    default_scopes,
-                    challenge,
-                    force_mfa)
-select id,
-       name,
-       enabled,
-       confidential,
-       secret,
-       secret_kid,
-       redirect_uris,
-       post_logout_redirect_uris,
-       allowed_origins,
-       flows_enabled,
-       access_token_alg,
-       id_token_alg,
-       refresh_token,
-       auth_code_lifetime,
-       access_token_lifetime,
-       scopes,
-       default_scopes,
-       challenge,
-       false as force_mfa
-from clients_old;
-
--- recreate all tables with foreign keys to clients
-
--- clients_dyn
-
-alter table clients_dyn
-    rename to clients_dyn_old;
-
-drop index clients_dyn_last_used_index;
-
-create table clients_dyn
-(
-    id                         text    not null
-        constraint clients_dyn_pk
-            primary key
-        constraint clients_dyn_clients_id_fk
-            references clients
-            on update cascade on delete cascade,
-    created                    integer not null,
-    last_used                  integer,
-    registration_token         blob    not null,
-    token_endpoint_auth_method text    not null
-);
-
-create index clients_dyn_last_used_index
-    on clients_dyn (last_used);
-
-insert into clients_dyn(id, created, last_used, registration_token, token_endpoint_auth_method)
-select id, created, last_used, registration_token, token_endpoint_auth_method
-from clients_dyn_old;
-
--- colors
-alter table colors
-    rename to colors_old;
-
-create table colors
-(
-    client_id varchar not null
-        constraint colors_pk
-            primary key
-        constraint colors_clients_id_fk
-            references clients
-            on update cascade
-            on delete cascade,
-    data      blob    not null
-);
-
-insert into colors(client_id, data)
-select client_id, data
-from colors_old;
-
--- logos
-alter table logos
-    rename to logos_old;
-
-create table logos
-(
-    client_id varchar not null
-        constraint logos_pk
-            primary key
-        constraint logos_clients_id_fk
-            references clients
-            on update cascade
-            on delete cascade,
-    data      blob    not null
-);
-
-insert into logos(client_id, data)
-select client_id, data
-from logos_old;
-
--- finally, drop all the old tables
-
-drop table clients_dyn_old;
-drop table colors_old;
-drop table logos_old;
-drop table clients_old;
-
--- re-create the logos table
-
-drop table logos;
-
-create table client_logos
-(
-    client_id    varchar not null
-        constraint client_logos_client_id_fk
-            references clients
-            on update cascade on delete cascade,
-    res          varchar not null,
-    content_type varchar not null,
-    data         blob    not null,
-    constraint client_logos_pk
-        primary key (client_id, res)
-);
-
--- rauthy default logo
-
-insert or ignore into client_logos (client_id, res, content_type, data)
-values ('rauthy', 'svg', 'image/svg+xml',
-        '<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg width="100%" height="100%" viewBox="0 0 512 138" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
-    <g transform="matrix(1,0,0,1,0,-11)">
-        <g transform="matrix(1,0,0,1,0,-176)">
-            <g transform="matrix(0.920325,0,0,1.84151,45.9279,26.459)">
-                <rect x="27.741" y="151.57" width="200.517" height="10.148" style="fill:rgb(4,7,11);"/>
-            </g>
-            <g transform="matrix(1.93472,0,0,1.82732,8.35618,28.7533)">
-                <rect x="33.307" y="97.15" width="94.693" height="54.42" style="fill:rgb(4,7,11);stroke:rgb(4,7,11);stroke-width:1.06px;"/>
-            </g>
-            <g transform="matrix(1.82732,0,0,1.82732,-160.822,70.1806)">
-                <g transform="matrix(72,0,0,72,227.174,123.417)">
-                </g>
-                <text x="128.982px" y="123.417px" style="font-family:''Calibri-Bold'', ''Calibri'', sans-serif;font-weight:700;font-size:72px;fill:white;">r<tspan x="152.994px 188.537px " y="123.417px 123.417px ">au</tspan></text>
-            </g>
-            <g transform="matrix(1,0,0,1.01617,-1.42109e-14,-5.24492)">
-                <path d="M440.936,322.643L439.204,324.266L255.482,324.266L255.482,305.721L440.936,305.721L440.936,322.643Z" style="fill:url(#_Linear1);"/>
-            </g>
-            <g transform="matrix(0.920191,0,0,1.84121,46.2464,-91.3383)">
-                <rect x="27.741" y="151.57" width="200.517" height="10.148" style="fill:url(#_Linear2);"/>
-            </g>
-            <g transform="matrix(1.97598,0,0,1.84619,190.187,26.062)">
-                <rect x="33.307" y="97.15" width="94.693" height="54.42" style="fill:rgb(43,65,107);"/>
-            </g>
-            <path d="M439.204,187.734L440.557,189.007L440.557,206.279L256,206.279L256,187.734L439.204,187.734Z" style="fill:rgb(43,65,107);"/>
-            <g transform="matrix(1.82732,0,0,1.82732,-154.661,70.1806)">
-                <g transform="matrix(72,0,0,72,323.045,123.417)">
-                </g>
-                <text x="226.646px" y="123.417px" style="font-family:''Calibri-Bold'', ''Calibri'', sans-serif;font-weight:700;font-size:72px;fill:white;">th<tspan x="288.943px " y="123.417px ">y</tspan></text>
-            </g>
-            <g transform="matrix(2,0,0,2,0,0)">
-                <path d="M219.602,93.867L256,128L219.602,162.133L219.602,93.867Z" style="fill:rgb(43,65,107);"/>
-            </g>
-            <g transform="matrix(2,0,0,1.95739,0,3.99997)">
-                <path d="M36.398,93.867L0,93.867L35.908,128.524L0,163.619L36.398,163.619" style="fill:rgb(4,7,11);"/>
-            </g>
-        </g>
-    </g>
-    <defs>
-        <linearGradient id="_Linear1" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(185.454,0,0,18.5443,255.482,314.994)"><stop offset="0" style="stop-color:rgb(4,7,11);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(43,65,107);stop-opacity:1"/></linearGradient>
-        <linearGradient id="_Linear2" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(200.517,0,0,10.1483,27.7414,156.645)"><stop offset="0" style="stop-color:rgb(4,7,11);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(43,65,107);stop-opacity:1"/></linearGradient>
-    </defs>
-</svg>');
\ No newline at end of file
diff --git a/migrations/sqlite/21_user_failed_logins_bigint.sql b/migrations/sqlite/21_user_failed_logins_bigint.sql
deleted file mode 100644
index 0cb5deb9a..000000000
--- a/migrations/sqlite/21_user_failed_logins_bigint.sql
+++ /dev/null
@@ -1,1 +0,0 @@
--- noop - this migration is postgres only
diff --git a/migrations/sqlite/22_users_created_at_index.sql b/migrations/sqlite/22_users_created_at_index.sql
deleted file mode 100644
index 2b0337381..000000000
--- a/migrations/sqlite/22_users_created_at_index.sql
+++ /dev/null
@@ -1,2 +0,0 @@
-create index users_created_at_index
-    on users (created_at);
\ No newline at end of file
diff --git a/migrations/sqlite/23_devices.sql b/migrations/sqlite/23_devices.sql
deleted file mode 100644
index f19e0943f..000000000
--- a/migrations/sqlite/23_devices.sql
+++ /dev/null
@@ -1,43 +0,0 @@
-create table devices
-(
-    id          varchar not null
-        constraint devices_pk
-            primary key,
-    client_id   varchar not null
-        constraint devices_clients_id_fk
-            references clients
-            on update cascade on delete cascade,
-    user_id     varchar
-        constraint devices_users_id_fk
-            references users
-            on update cascade on delete cascade,
-    created     bigint  not null,
-    access_exp  bigint  not null,
-    refresh_exp bigint,
-    peer_ip     varchar not null,
-    name        varchar not null
-);
-
-create index devices_access_exp_refresh_exp_index
-    on devices (access_exp, refresh_exp);
-
-create table refresh_tokens_devices
-(
-    id        varchar not null
-        constraint refresh_tokens_devices_pk
-            primary key,
-    device_id varchar not null
-        constraint refresh_tokens_devices_devices_id_fk
-            references devices
-            on update cascade on delete cascade,
-    user_id   varchar not null
-        constraint refresh_tokens_users_user_id_fk
-            references users
-            on update cascade on delete cascade,
-    nbf       bigint  not null,
-    exp       bigint  not null,
-    scope     varchar
-);
-
-create index refresh_tokens_devices_exp_index
-    on refresh_tokens_devices (exp);
diff --git a/migrations/sqlite/24_roles_groups_scopes_limit.sql b/migrations/sqlite/24_roles_groups_scopes_limit.sql
deleted file mode 100644
index 982c49a21..000000000
--- a/migrations/sqlite/24_roles_groups_scopes_limit.sql
+++ /dev/null
@@ -1,55 +0,0 @@
--- remove the limit checks on id and name fields for roles, groups, scopes
--- to allow longer scope names like i.e. 'urn:ietf:params:oauth:grant-type:device_code'
-
-create table scopes_dg_tmp
-(
-    id                  varchar(36) not null
-        constraint scopes_pk
-            primary key,
-    name                varchar     not null,
-    attr_include_access varchar,
-    attr_include_id     varchar
-);
-
-insert into scopes_dg_tmp(id, name, attr_include_access, attr_include_id)
-select id, name, attr_include_access, attr_include_id
-from scopes;
-
-drop table scopes;
-
-alter table scopes_dg_tmp
-    rename to scopes;
-
-create table groups_dg_tmp
-(
-    id   varchar not null
-        constraint groups_pk
-            primary key,
-    name varchar not null
-);
-
-insert into groups_dg_tmp(id, name)
-select id, name
-from groups;
-
-drop table groups;
-
-alter table groups_dg_tmp
-    rename to groups;
-
-create table roles_dg_tmp
-(
-    id   varchar not null
-        constraint roles_pk
-            primary key,
-    name varchar not null
-);
-
-insert into roles_dg_tmp(id, name)
-select id, name
-from roles;
-
-drop table roles;
-
-alter table roles_dg_tmp
-    rename to roles;
diff --git a/migrations/sqlite/25_remove_client_refresh_token.sql b/migrations/sqlite/25_remove_client_refresh_token.sql
deleted file mode 100644
index c81dbbaf6..000000000
--- a/migrations/sqlite/25_remove_client_refresh_token.sql
+++ /dev/null
@@ -1,219 +0,0 @@
--- modify the clients table and remove obsolete `refresh_token` column
--- the new logic will just take a look at the flows_enabled value
-
-alter table clients
-    rename to clients_old;
-
-create table clients
-(
-    id                        varchar not null
-        constraint clients_pk
-            primary key,
-    name                      varchar,
-    enabled                   bool    not null,
-    confidential              bool    not null,
-    secret                    blob,
-    secret_kid                varchar,
-    redirect_uris             varchar not null,
-    post_logout_redirect_uris varchar,
-    allowed_origins           varchar,
-    flows_enabled             varchar not null,
-    access_token_alg          varchar not null,
-    id_token_alg              varchar not null,
-    auth_code_lifetime        integer not null,
-    access_token_lifetime     integer not null,
-    scopes                    varchar not null,
-    default_scopes            varchar not null,
-    challenge                 varchar,
-    force_mfa                 bool    not null,
-    client_uri                varchar,
-    contacts                  varchar
-);
-
-insert into clients(id,
-                    name,
-                    enabled,
-                    confidential,
-                    secret,
-                    secret_kid,
-                    redirect_uris,
-                    post_logout_redirect_uris,
-                    allowed_origins,
-                    flows_enabled,
-                    access_token_alg,
-                    id_token_alg,
-                    auth_code_lifetime,
-                    access_token_lifetime,
-                    scopes,
-                    default_scopes,
-                    challenge,
-                    force_mfa)
-select id,
-       name,
-       enabled,
-       confidential,
-       secret,
-       secret_kid,
-       redirect_uris,
-       post_logout_redirect_uris,
-       allowed_origins,
-       flows_enabled,
-       access_token_alg,
-       id_token_alg,
-       auth_code_lifetime,
-       access_token_lifetime,
-       scopes,
-       default_scopes,
-       challenge,
-       false as force_mfa
-from clients_old;
-
--- recreate all tables with foreign keys to clients
-
--- clients_dyn
-
-alter table clients_dyn
-    rename to clients_dyn_old;
-
-drop index clients_dyn_last_used_index;
-
-create table clients_dyn
-(
-    id                         text    not null
-        constraint clients_dyn_pk
-            primary key
-        constraint clients_dyn_clients_id_fk
-            references clients
-            on update cascade on delete cascade,
-    created                    integer not null,
-    last_used                  integer,
-    registration_token         blob    not null,
-    token_endpoint_auth_method text    not null
-);
-
-create index clients_dyn_last_used_index
-    on clients_dyn (last_used);
-
-insert into clients_dyn(id, created, last_used, registration_token, token_endpoint_auth_method)
-select id, created, last_used, registration_token, token_endpoint_auth_method
-from clients_dyn_old;
-
--- colors
-alter table colors
-    rename to colors_old;
-
-create table colors
-(
-    client_id varchar not null
-        constraint colors_pk
-            primary key
-        constraint colors_clients_id_fk
-            references clients
-            on update cascade
-            on delete cascade,
-    data      blob    not null
-);
-
-insert into colors(client_id, data)
-select client_id, data
-from colors_old;
-
--- client_logos
-alter table client_logos
-    rename to client_logos_old;
-
-create table client_logos
-(
-    client_id    varchar not null
-        constraint client_logos_client_id_fk
-            references clients
-            on update cascade on delete cascade,
-    res          varchar not null,
-    content_type varchar not null,
-    data         blob    not null,
-    constraint client_logos_pk
-        primary key (client_id, res)
-);
-insert into client_logos(client_id, res, content_Type, data)
-select client_id, res, content_Type, data
-from client_logos_old;
-
--- devices
-alter table devices
-    rename to devices_old;
-
-drop index devices_access_exp_refresh_exp_index;
-
-create table devices
-(
-    id          varchar not null
-        constraint devices_pk
-            primary key,
-    client_id   varchar not null
-        constraint devices_clients_id_fk
-            references clients
-            on update cascade on delete cascade,
-    user_id     varchar
-        constraint devices_users_id_fk
-            references users
-            on update cascade on delete cascade,
-    created     bigint  not null,
-    access_exp  bigint  not null,
-    refresh_exp bigint,
-    peer_ip     varchar not null,
-    name        varchar not null
-);
-
-create index devices_access_exp_refresh_exp_index
-    on devices (access_exp, refresh_exp);
-
-insert into devices(id, client_id, user_id, created, access_exp, refresh_exp, peer_ip, name)
-select id,
-       client_id,
-       user_id,
-       created,
-       access_exp,
-       refresh_exp,
-       peer_ip,
-       name
-from devices_old;
-
--- refresh_tokens_devices
-alter table refresh_tokens_devices
-    rename to refresh_tokens_devices_old;
-
-drop index refresh_tokens_devices_exp_index;
-
-create table refresh_tokens_devices
-(
-    id        varchar not null
-        constraint refresh_tokens_devices_pk
-            primary key,
-    device_id varchar not null
-        constraint refresh_tokens_devices_devices_id_fk
-            references devices
-            on update cascade on delete cascade,
-    user_id   varchar not null
-        constraint refresh_tokens_users_user_id_fk
-            references users
-            on update cascade on delete cascade,
-    nbf       bigint  not null,
-    exp       bigint  not null,
-    scope     varchar
-);
-
-create index refresh_tokens_devices_exp_index
-    on refresh_tokens_devices (exp);
-
-insert into refresh_tokens_devices(id, device_id, user_id, nbf, exp, scope)
-select id, device_id, user_id, nbf, exp, scope
-from refresh_tokens_devices_old;
-
--- finally, drop all the old tables
-
-drop table clients_dyn_old;
-drop table colors_old;
-drop table client_logos_old;
-drop table clients_old;
-drop table devices_old;
-drop table refresh_tokens_devices_old;
diff --git a/migrations/sqlite/2_init_data.sql b/migrations/sqlite/2_init_data.sql
deleted file mode 100644
index 4582221e2..000000000
--- a/migrations/sqlite/2_init_data.sql
+++ /dev/null
@@ -1,26 +0,0 @@
-insert into clients (id, name, enabled, confidential, secret, secret_kid, redirect_uris, post_logout_redirect_uris, allowed_origins, flows_enabled, access_token_alg, id_token_alg, refresh_token, auth_code_lifetime, access_token_lifetime, scopes, default_scopes, challenge)
-values  ('init_client', 'Init Client', 1, 1, x'45AEEA59D2E65A9178FF90AEDC1CB7F3C8C970912A99594A8317FE0CE7223E2150B261C35DED44410110F724852AAD7A7C792957C82A42013B3F1F06B79894F9B6BFE5E47AAD5E3EB46CE52F8A1EFAE89F64AC6636DF60547F245A24', 'bVCyTsGaggVy5yqQ', 'http://localhost:3000/oidc/callback', 'http://localhost:8080', 'http://localhost:8080/*', 'authorization_code,password,client_credentials,refresh_token', 'EdDSA', 'RS512', 1, 60, 60, 'openid,email,profile,groups', 'openid', 'S256,plain'),
-        ('rauthy', 'Rauthy', 1, 0, null, null, 'http://localhost:8080/auth/v1/oidc/*,http://localhost:5173/auth/v1/oidc/*', 'http://localhost:8080/auth/v1/*,http://localhost:5173/auth/v1/*', 'http://localhost:5173', 'authorization_code,password', 'EdDSA', 'EdDSA', 0, 60, 1800, 'openid,email,profile,groups', 'openid', 'S256');
-
-insert into config (id, data)
-values  ('password_policy', x'0A000000800000000101000000010100000001010000000101000000015A0000000103000000');
-
-insert into groups (id, name)
-values  ('GfQ7Eghqnmc2qLWu5TF25vus', 'user'),
-        ('vjYA59RaZ5Kgqzch5VJVWmyo', 'admin');
-
-insert into roles (id, name)
-values  ('3kv6Yokr3qsgepwQWyXJWLzs', 'admin'),
-        ('9Pr9NVgu4HGLH7SnMB4a73i8', 'user'),
-        ('JJsvMJH7ZJXC3xRbocw8E7Um', 'rauthy_admin');
-
-insert into scopes (id, name, attr_include_access, attr_include_id)
-values  ('26D4MoZBSUTZb2pnDP9r24tn', 'email', null, null),
-        ('XpQDpteCrvByhXYcnf9n2gyN', 'openid', null, null),
-        ('YKZvMGRaE6zEdgk4jabQNfDY', 'profile', null, null),
-        ('fwL9emEMcnbHyNE8n3pUs9J5', 'groups', null, null);
-
-insert into users (id, email, given_name, family_name, password, roles, groups, enabled, email_verified, password_expires, created_at, last_login, last_failed_login, failed_login_attempts, mfa_app, sec_key_1, sec_key_2)
-values  ('2PYV3STNz3MN7VnPjJVcPQap', 'test_admin@localhost.de', 'Admin', 'Test', null, 'rauthy_admin', 'admin', 1, 1, null, 1680971459, null, null, null, null, null, null),
-        ('m4PJ3TnyP32LA8hzY23deme3', 'init_admin@localhost.de', 'Admin', 'Init', '$argon2id$v=19$m=32768,t=3,p=2$PoAwNZm4cqhNK0hQV2hSOQ$Xc2ECqWOU3aVvVLswmu29Hk7eGTYmKQQgo2qtyp2GwQ', 'rauthy_admin', 'admin', 1, 1, null, 1680971459, null, null, null, null, null, null),
-        ('za9UxpH7XVxqrtpEbThoqvn2', 'admin@localhost.de', 'Rauthy', 'Admin', '$argon2id$v=19$m=32768,t=3,p=2$xr23OhOHw+pNyy3dYKZUcA$CBO4NpGvyi6gvrb5uNrnsS/z/Ew+IuS0/gVqFmLKncA', 'rauthy_admin,admin', 'admin', 1, 1, null, 1680971457, 1680975378, null, null, null, null, null);
diff --git a/migrations/sqlite/3_colors_logos_schema.sql b/migrations/sqlite/3_colors_logos_schema.sql
deleted file mode 100644
index cac89a377..000000000
--- a/migrations/sqlite/3_colors_logos_schema.sql
+++ /dev/null
@@ -1,23 +0,0 @@
-create table colors
-(
-    client_id varchar(36) not null
-        constraint colors_pk
-        primary key
-        constraint colors_clients_id_fk
-        references clients
-        on update cascade
-        on delete cascade,
-    data      blob not null
-);
-
-create table logos
-(
-    client_id varchar(36) not null
-        constraint logos_pk
-        primary key
-        constraint logos_clients_id_fk
-        references clients
-        on update cascade
-        on delete cascade,
-    data     blob not null
-);
diff --git a/migrations/sqlite/4_refresh_token_mfa.sql b/migrations/sqlite/4_refresh_token_mfa.sql
deleted file mode 100644
index f80ad978e..000000000
--- a/migrations/sqlite/4_refresh_token_mfa.sql
+++ /dev/null
@@ -1,2 +0,0 @@
-alter table refresh_tokens
-    add is_mfa bool default false not null;
diff --git a/migrations/sqlite/5_migration_fixes.sql b/migrations/sqlite/5_migration_fixes.sql
deleted file mode 100644
index a4ee3025e..000000000
--- a/migrations/sqlite/5_migration_fixes.sql
+++ /dev/null
@@ -1,118 +0,0 @@
-alter table groups
-    rename to groups_old;
-
-create table groups
-(
-    id   varchar(36) not null
-        constraint groups_pk
-            primary key,
-    name varchar(32) not null
-);
-
-insert into groups(id, name)
-select id, name
-from groups_old;
-
-drop table groups_old;
-
---
-
-alter table jwks
-    rename to jwks_old;
-
-create table jwks
-(
-    kid        varchar not null
-        constraint jwks_pk
-            primary key,
-    created_at integer not null,
-    signature  varchar not null,
-    enc_key_id varchar not null,
-    jwk        blob    not null
-);
-
-insert into jwks(kid, created_at, signature, enc_key_id, jwk)
-select kid, created_at, signature, enc_key_id, jwk
-from jwks_old;
-
-drop table jwks_old;
-
---
-
-alter table magic_links
-    rename to magic_links_old;
-
-drop index magic_links_exp_index;
-drop index magic_links_user_id_index;
-
-create table magic_links
-(
-    id         varchar(64) not null
-        constraint magic_links_pk
-            primary key,
-    user_id    varchar(36) not null
-        references users
-            on delete cascade
-            on update cascade,
-    csrf_token varchar(48) not null,
-    cookie     varchar(48),
-    exp        integer     not null,
-    used       bool        not null
-);
-
-create index magic_links_exp_index
-    on magic_links (exp);
-
-create index magic_links_user_id_index
-    on magic_links (user_id);
-
-insert into magic_links(id, user_id, csrf_token, cookie, exp, used)
-select id, user_id, csrf_token, cookie, exp, used
-from magic_links_old;
-
-drop table magic_links_old;
-
---
-
-alter table recent_passwords
-    rename to recent_passwords_old;
-
-create table recent_passwords
-(
-    user_id   varchar(36)   not null
-        references users
-            on delete cascade
-            on update cascade
-        constraint recent_passwords_pk
-            primary key,
-    passwords varchar(1024) not null
-);
-
-insert into recent_passwords(user_id, passwords)
-select user_id, passwords
-from recent_passwords_old;
-
-drop table recent_passwords_old;
-
---
-
-alter table user_attr_values
-    rename to user_attr_values_old;
-
-create table user_attr_values
-(
-    user_id varchar not null,
-    key     varchar not null
-        references user_attr_config
-            on delete cascade
-            on update cascade,
-    value   blob    not null,
-    constraint user_attr_values_pk
-        primary key (user_id, key)
-);
-
-insert into user_attr_values(user_id, key, value)
-select user_id, key, value
-from user_attr_values_old;
-
-drop table user_attr_values_old;
diff --git a/migrations/sqlite/6_user_language.sql b/migrations/sqlite/6_user_language.sql
deleted file mode 100644
index a82c54a2b..000000000
--- a/migrations/sqlite/6_user_language.sql
+++ /dev/null
@@ -1,187 +0,0 @@
-alter table users
-    rename to users_old;
-
-drop index users_email_uindex;
-
-create table users
-(
-    id                    varchar              not null
-        constraint users_pk
-            primary key,
-    email                 varchar              not null
-        constraint users_email
-            unique,
-    given_name            varchar              not null,
-    family_name           varchar              not null,
-    password              varchar,
-    roles                 varchar              not null,
-    groups                varchar,
-    enabled               boolean              not null,
-    email_verified        boolean              not null,
-    password_expires      int,
-    created_at            int                  not null,
-    last_login            int,
-    last_failed_login     int,
-    failed_login_attempts int,
-    mfa_app               varchar,
-    sec_key_1             varchar
-        references webauthn,
-    sec_key_2             varchar
-        references webauthn,
-    language              varchar default 'en' not null
-);
-
-create unique index users_email_uindex
-    on users (email);
-
-insert into users(id, email, given_name, family_name, password, roles, groups, enabled, email_verified,
-                  password_expires, created_at, last_login, last_failed_login, failed_login_attempts, mfa_app,
-                  sec_key_1, sec_key_2)
-select id,
-       email,
-       given_name,
-       family_name,
-       password,
-       roles,
-       groups,
-       enabled,
-       email_verified,
-       password_expires,
-       created_at,
-       last_login,
-       last_failed_login,
-       failed_login_attempts,
-       mfa_app,
-       sec_key_1,
-       sec_key_2
-from users_old;
-
--- recreate all tables with foreign keys to users
-
-alter table magic_links
-    rename to magic_links_old;
-
-drop index magic_links_exp_index;
-drop index magic_links_user_id_index;
-
-create table magic_links
-(
-    id         varchar not null
-        constraint magic_links_pk
-            primary key,
-    user_id    varchar not null
-        references users
-            on delete cascade
-            on update cascade,
-    csrf_token varchar not null,
-    cookie     varchar,
-    exp        integer not null,
-    used       bool    not null
-);
-
-create index magic_links_exp_index
-    on magic_links (exp);
-
-create index magic_links_user_id_index
-    on magic_links (user_id);
-
-insert into magic_links(id, user_id, csrf_token, cookie, exp, used)
-select id, user_id, csrf_token, cookie, exp, used
-from magic_links_old;
-
-drop table magic_links_old;
-
---
-
-alter table recent_passwords
-    rename to recent_passwords_old;
-
-create table recent_passwords
-(
-    user_id   varchar not null
-        references users
-            on delete cascade
-            on update cascade
-        constraint recent_passwords_pk
-            primary key,
-    passwords varchar not null
-);
-
-insert into recent_passwords(user_id, passwords)
-select user_id, passwords
-from recent_passwords_old;
-
-drop table recent_passwords_old;
-
---
-
-alter table refresh_tokens
-    rename to refresh_tokens_old;
-
-drop index refresh_tokens_exp_index;
-drop index refresh_tokens_user_id_index;
-
-create table refresh_tokens
-(
-    id      varchar not null
-        constraint refresh_tokens_pk
-            primary key,
-    user_id varchar not null
-        references users
-            on delete cascade
-            on update cascade,
-    nbf     integer not null,
-    exp     integer not null,
-    scope   varchar,
-    is_mfa bool default false not null
-);
-
-create index refresh_tokens_exp_index
-    on refresh_tokens (exp);
-
-create index refresh_tokens_user_id_index
-    on refresh_tokens (user_id);
-
-insert into refresh_tokens(id, user_id, nbf, exp, scope, is_mfa)
-select id, user_id, nbf, exp, scope, is_mfa
-from refresh_tokens_old;
-
-drop table refresh_tokens_old;
-
---
-
-alter table sessions
-    rename to sessions_old;
-
-drop index sessions_exp_index;
-
-create table sessions
-(
-    id         varchar not null
-        constraint sessions_pk
-            primary key,
-    csrf_token varchar not null,
-    user_id    varchar
-        references users
-            on delete cascade
-            on update cascade,
-    roles      varchar,
-    groups     varchar,
-    is_mfa     bool    not null,
-    state      varchar not null,
-    exp        int     not null,
-    last_seen  int     not null
-);
-
-create index sessions_exp_index
-    on sessions (exp);
-
-insert into sessions(id, csrf_token, user_id, roles, groups, is_mfa, state, exp, last_seen)
-select id, csrf_token, user_id, roles, groups, is_mfa, state, exp, last_seen
-from sessions_old;
-
-drop table sessions_old;
-
--- finally drop the old users table
-
-drop table users_old;
diff --git a/migrations/sqlite/7_passkey_features.sql b/migrations/sqlite/7_passkey_features.sql
deleted file mode 100644
index 7cafec91f..000000000
--- a/migrations/sqlite/7_passkey_features.sql
+++ /dev/null
@@ -1,219 +0,0 @@
--- modify the users table and add the 'webauthn_enabled' column
-
-alter table users
-    rename to users_old;
-
-drop index users_email_uindex;
-
-create table users
-(
-    id                    varchar               not null
-        constraint users_pk
-            primary key,
-    email                 varchar               not null
-        constraint users_email
-            unique,
-    given_name            varchar               not null,
-    family_name           varchar               not null,
-    password              varchar,
-    roles                 varchar               not null,
-    groups                varchar,
-    enabled               boolean               not null,
-    email_verified        boolean               not null,
-    password_expires      int,
-    created_at            int                   not null,
-    last_login            int,
-    last_failed_login     int,
-    failed_login_attempts int,
-    mfa_app               varchar,
-    sec_key_1             varchar
-        references webauthn,
-    sec_key_2             varchar
-        references webauthn,
-    language              varchar default 'en'  not null,
-    webauthn_user_id      varchar
-);
-
-create unique index users_webauthn_user_id_index
-    on users (webauthn_user_id);
-
-insert into users(id, email, given_name, family_name, password, roles, groups, enabled, email_verified,
-                  password_expires, created_at, last_login, last_failed_login, failed_login_attempts, mfa_app,
-                  sec_key_1, sec_key_2)
-select id,
-       email,
-       given_name,
-       family_name,
-       password,
-       roles,
-       groups,
-       enabled,
-       email_verified,
-       password_expires,
-       created_at,
-       last_login,
-       last_failed_login,
-       failed_login_attempts,
-       mfa_app,
-       sec_key_1,
-       sec_key_2
-from users_old;
-
--- recreate all tables with foreign keys to users
-
-alter table magic_links
-    rename to magic_links_old;
-
-drop index magic_links_exp_index;
-drop index magic_links_user_id_index;
-
-create table magic_links
-(
-    id         varchar not null
-        constraint magic_links_pk
-            primary key,
-    user_id    varchar not null
-        references users
-            on delete cascade
-            on update cascade,
-    csrf_token varchar not null,
-    cookie     varchar,
-    exp        integer not null,
-    used       bool    not null
-);
-
-create index magic_links_exp_index
-    on magic_links (exp);
-
-create index magic_links_user_id_index
-    on magic_links (user_id);
-
-insert into magic_links(id, user_id, csrf_token, cookie, exp, used)
-select id, user_id, csrf_token, cookie, exp, used
-from magic_links_old;
-
-drop table magic_links_old;
-
---
-
-alter table recent_passwords
-    rename to recent_passwords_old;
-
-create table recent_passwords
-(
-    user_id   varchar not null
-        references users
-            on delete cascade
-            on update cascade
-        constraint recent_passwords_pk
-            primary key,
-    passwords varchar not null
-);
-
-insert into recent_passwords(user_id, passwords)
-select user_id, passwords
-from recent_passwords_old;
-
-drop table recent_passwords_old;
-
---
-
-alter table refresh_tokens
-    rename to refresh_tokens_old;
-
-drop index refresh_tokens_exp_index;
-drop index refresh_tokens_user_id_index;
-
-create table refresh_tokens
-(
-    id      varchar            not null
-        constraint refresh_tokens_pk
-            primary key,
-    user_id varchar            not null
-        references users
-            on delete cascade
-            on update cascade,
-    nbf     integer            not null,
-    exp     integer            not null,
-    scope   varchar,
-    is_mfa  bool default false not null
-);
-
-create index refresh_tokens_exp_index
-    on refresh_tokens (exp);
-
-create index refresh_tokens_user_id_index
-    on refresh_tokens (user_id);
-
-insert into refresh_tokens(id, user_id, nbf, exp, scope, is_mfa)
-select id, user_id, nbf, exp, scope, is_mfa
-from refresh_tokens_old;
-
-drop table refresh_tokens_old;
-
---
-
-alter table sessions
-    rename to sessions_old;
-
-drop index sessions_exp_index;
-
-create table sessions
-(
-    id         varchar not null
-        constraint sessions_pk
-            primary key,
-    csrf_token varchar not null,
-    user_id    varchar
-        references users
-            on delete cascade
-            on update cascade,
-    roles      varchar,
-    groups     varchar,
-    is_mfa     bool    not null,
-    state      varchar not null,
-    exp        int     not null,
-    last_seen  int     not null
-);
-
-create index sessions_exp_index
-    on sessions (exp);
-
-insert into sessions(id, csrf_token, user_id, roles, groups, is_mfa, state, exp, last_seen)
-select id,
-       csrf_token,
-       user_id,
-       roles,
-       groups,
-       is_mfa,
-       state,
-       exp,
-       last_seen
-from sessions_old;
-
-drop table sessions_old;
-
--- finally drop the old users table
-
-drop table users_old;
-
--- now we can add the new passkeys table
-
-create table passkeys
-(
-    user_id    varchar not null
-        constraint passkeys_users_id_fk
-            references users
-            on update cascade on delete cascade,
-    name       varchar not null,
-    passkey_user_id varchar not null,
-    passkey    varchar not null,
-    credential_id   blob not null,
-    registered integer not null,
-    last_used  integer not null,
-    constraint passkeys_pk
-        primary key (user_id, name)
-);
-
-create unique index passkeys_credential_id_index
-    on passkeys (credential_id);
diff --git a/migrations/sqlite/8_legacy_passkey_cleanup.sql b/migrations/sqlite/8_legacy_passkey_cleanup.sql
deleted file mode 100644
index 626e8f2e6..000000000
--- a/migrations/sqlite/8_legacy_passkey_cleanup.sql
+++ /dev/null
@@ -1,241 +0,0 @@
--- modify the users table and get rid of 'mfa_app', 'sec_key_1' and sec_key_2'
-
-alter table users
-    rename to users_old;
-
-drop index users_webauthn_user_id_index;
-
-create table users
-(
-    id                    varchar              not null
-        constraint users_pk
-            primary key,
-    email                 varchar              not null
-        constraint users_email
-            unique,
-    given_name            varchar              not null,
-    family_name           varchar              not null,
-    password              varchar,
-    roles                 varchar              not null,
-    groups                varchar,
-    enabled               boolean              not null,
-    email_verified        boolean              not null,
-    password_expires      int,
-    created_at            int                  not null,
-    last_login            int,
-    last_failed_login     int,
-    failed_login_attempts int,
-    language              varchar default 'en' not null,
-    webauthn_user_id      varchar,
-    user_expires          int
-);
-
-create unique index users_email_uindex
-    on users (email);
-
-create unique index users_webauthn_user_id_index
-    on users (webauthn_user_id);
-
-insert into users(id, email, given_name, family_name, password, roles, groups, enabled, email_verified,
-                  password_expires, created_at, last_login, last_failed_login, failed_login_attempts, language,
-                  webauthn_user_id)
-select id,
-       email,
-       given_name,
-       family_name,
-       password,
-       roles,
-       groups,
-       enabled,
-       email_verified,
-       password_expires,
-       created_at,
-       last_login,
-       last_failed_login,
-       failed_login_attempts,
-       language,
-       webauthn_user_id
-from users_old;
-
--- recreate all tables with foreign keys to users
-
--- add 'usage' to 'magic_links' for future usage
-
-alter table magic_links
-    rename to magic_links_old;
-
-drop index magic_links_exp_index;
-drop index magic_links_user_id_index;
-
-create table magic_links
-(
-    id         varchar not null
-        constraint magic_links_pk
-            primary key,
-    user_id    varchar not null
-        references users
-            on delete cascade
-            on update cascade,
-    csrf_token varchar not null,
-    cookie     varchar,
-    exp        integer not null,
-    used       bool    not null,
-    usage      varchar not null
-);
-
-create index magic_links_exp_index
-    on magic_links (exp);
-
-create index magic_links_user_id_index
-    on magic_links (user_id);
-
-insert into magic_links(id, user_id, csrf_token, cookie, exp, used, usage)
-select id, user_id, csrf_token, cookie, exp, used, 'password_reset' as usage
-from magic_links_old;
-
-drop table magic_links_old;
-
---
-
-alter table recent_passwords
-    rename to recent_passwords_old;
-
-create table recent_passwords
-(
-    user_id   varchar not null
-        references users
-            on delete cascade
-            on update cascade
-        constraint recent_passwords_pk
-            primary key,
-    passwords varchar not null
-);
-
-insert into recent_passwords(user_id, passwords)
-select user_id, passwords
-from recent_passwords_old;
-
-drop table recent_passwords_old;
-
---
-
-alter table refresh_tokens
-    rename to refresh_tokens_old;
-
-drop index refresh_tokens_exp_index;
-drop index refresh_tokens_user_id_index;
-
-create table refresh_tokens
-(
-    id      varchar            not null
-        constraint refresh_tokens_pk
-            primary key,
-    user_id varchar            not null
-        references users
-            on delete cascade
-            on update cascade,
-    nbf     integer            not null,
-    exp     integer            not null,
-    scope   varchar,
-    is_mfa  bool default false not null
-);
-
-create index refresh_tokens_exp_index
-    on refresh_tokens (exp);
-
-create index refresh_tokens_user_id_index
-    on refresh_tokens (user_id);
-
-insert into refresh_tokens(id, user_id, nbf, exp, scope, is_mfa)
-select id, user_id, nbf, exp, scope, is_mfa
-from refresh_tokens_old;
-
-drop table refresh_tokens_old;
-
--- add the 'remote_ip' column to the 'sessions' table for future use
-
-alter table sessions
-    rename to sessions_old;
-
-drop index sessions_exp_index;
-
-create table sessions
-(
-    id         varchar not null
-        constraint sessions_pk
-            primary key,
-    csrf_token varchar not null,
-    user_id    varchar
-        references users
-            on delete cascade
-            on update cascade,
-    roles      varchar,
-    groups     varchar,
-    is_mfa     bool    not null,
-    state      varchar not null,
-    exp        int     not null,
-    last_seen  int     not null,
-    remote_ip  varchar
-);
-
-create index sessions_exp_index
-    on sessions (exp);
-
-insert into sessions(id, csrf_token, user_id, roles, groups, is_mfa, state, exp, last_seen)
-select id,
-       csrf_token,
-       user_id,
-       roles,
-       groups,
-       is_mfa,
-       state,
-       exp,
-       last_seen
-from sessions_old;
-
-drop table sessions_old;
-
--- migrate 'passkeys' table
-
-alter table passkeys
-    rename to passkeys_old;
-
-drop index passkeys_credential_id_index;
-
-create table passkeys
-(
-    user_id         varchar not null
-        constraint passkeys_users_id_fk
-            references users
-            on update cascade on delete cascade,
-    name            varchar not null,
-    passkey_user_id varchar not null,
-    passkey         varchar not null,
-    credential_id   blob    not null,
-    registered      integer not null,
-    last_used       integer not null,
-    user_verified   bool,
-    constraint passkeys_pk
-        primary key (user_id, name)
-);
-
-create unique index passkeys_credential_id_index
-    on passkeys (credential_id);
-
-create index passkeys_passkey_user_id_index
-    on passkeys (passkey_user_id);
-
-insert into passkeys(user_id, name, passkey_user_id, passkey, credential_id, registered, last_used)
-select user_id, name, passkey_user_id, passkey, credential_id, registered, last_used
-from passkeys_old;
-
-drop table passkeys_old;
-
--- finally drop the old users table
-
-drop table users_old;
-
--- now we can cleanup legacy tables
-
-drop table mfa_apps;
-drop table webauthn;
diff --git a/migrations/sqlite/9_update_password_policy.sql b/migrations/sqlite/9_update_password_policy.sql
deleted file mode 100644
index 6f5b01e21..000000000
--- a/migrations/sqlite/9_update_password_policy.sql
+++ /dev/null
@@ -1,3 +0,0 @@
-update config
-set data = x'0E000000800000000101000000010100000001010000000001B40000000103000000'
-where id = 'password_policy';


Test patch:
diff --git a/.sqlx/query-0eed84ef51f25747a15d566caa28271cb6fc42e2ea913537c5a7d17679ed62bf.json b/.sqlx/query-0eed84ef51f25747a15d566caa28271cb6fc42e2ea913537c5a7d17679ed62bf.json
new file mode 100644
index 000000000..9ccd00f06
--- /dev/null
+++ b/.sqlx/query-0eed84ef51f25747a15d566caa28271cb6fc42e2ea913537c5a7d17679ed62bf.json
@@ -0,0 +1,33 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "\nUPDATE clients\nSET name = $1, enabled = $2, confidential = $3, secret = $4, secret_kid = $5, redirect_uris = $6,\npost_logout_redirect_uris = $7, allowed_origins = $8, flows_enabled = $9, access_token_alg = $10,\nid_token_alg = $11, auth_code_lifetime = $12, access_token_lifetime = $13, scopes = $14,\ndefault_scopes = $15, challenge = $16, force_mfa= $17, client_uri = $18, contacts = $19\nWHERE id = $20",
+  "describe": {
+    "columns": [],
+    "parameters": {
+      "Left": [
+        "Varchar",
+        "Bool",
+        "Bool",
+        "Bytea",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Int4",
+        "Int4",
+        "Varchar",
+        "Varchar",
+        "Varchar",
+        "Bool",
+        "Varchar",
+        "Varchar",
+        "Text"
+      ]
+    },
+    "nullable": []
+  },
+  "hash": "0eed84ef51f25747a15d566caa28271cb6fc42e2ea913537c5a7d17679ed62bf"
+}
diff --git a/.sqlx/query-c046ad99ab0b6fffef28edae1eddc5de2e8e5e21f05f845082eac987ed44ec95.json b/.sqlx/query-c046ad99ab0b6fffef28edae1eddc5de2e8e5e21f05f845082eac987ed44ec95.json
new file mode 100644
index 000000000..78b6995d3
--- /dev/null
+++ b/.sqlx/query-c046ad99ab0b6fffef28edae1eddc5de2e8e5e21f05f845082eac987ed44ec95.json
@@ -0,0 +1,38 @@
+{
+  "db_name": "PostgreSQL",
+  "query": "SELECT * FROM scopes",
+  "describe": {
+    "columns": [
+      {
+        "ordinal": 0,
+        "name": "id",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 1,
+        "name": "name",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 2,
+        "name": "attr_include_access",
+        "type_info": "Varchar"
+      },
+      {
+        "ordinal": 3,
+        "name": "attr_include_id",
+        "type_info": "Varchar"
+      }
+    ],
+    "parameters": {
+      "Left": []
+    },
+    "nullable": [
+      false,
+      false,
+      true,
+      true
+    ]
+  },
+  "hash": "c046ad99ab0b6fffef28edae1eddc5de2e8e5e21f05f845082eac987ed44ec95"
+}