summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen Jacobson <owen@grimoire.ca>2025-08-24 15:35:39 -0400
committerOwen Jacobson <owen@grimoire.ca>2025-08-26 01:06:48 -0400
commit218d6dbb56727721d19019c8514f5e4395596e98 (patch)
tree9790c8433e169c7345717538ac7a54d187579b0b
parentc52e24f17ed615b2e2dd55a285eb272014a2ccbf (diff)
Split the `user` table into an authentication portion and a chat portion.
We'll be building separate entities around this in future commits, to better separate the authentication data (non-synchronized and indeed "not public") from the chat data (synchronized and public).
-rw-r--r--.sqlx/query-0b1543ec93e02c48c5cbaafd391b5812dc2d1d4a52ea3072b5dd52d71637b33d.json (renamed from .sqlx/query-613199c25e16a52d85761e213750fe202abfa2af5347010dee59d3b8075eb19e.json)4
-rw-r--r--.sqlx/query-0bd9ba049b839f3187dc74578f26eca4b9f1850dfc30734b516e8cdd17f92a5c.json (renamed from .sqlx/query-79495da0101ad12e7e983666b2ca84cbe31458ff73a94648c30b62f3130a5a8b.json)6
-rw-r--r--.sqlx/query-20e525a7b6f354e99b9c6722966d85ded0cbd27125093208d7f7f0aabb0ea61b.json (renamed from .sqlx/query-afc6db503a3c49c18a9cb07cf0360789d46d94d9cd98887a3d9660d9b753d416.json)6
-rw-r--r--.sqlx/query-27c3ffb5c284cf2d1c7cee713f6354d6150088a052d1f261853f327a83e8dd75.json20
-rw-r--r--.sqlx/query-48f407dc8e63236f2f30634f7c249ec8f6c5e2c3a30a9995738de714c8b53509.json (renamed from .sqlx/query-9cf211b1f37708fc8f19b3af911f7488a708d5a50920bb042c0229c314ee3281.json)4
-rw-r--r--.sqlx/query-7c87864e6d077640e4f3ef4a354a47265238010f4c53d3c5982f4fd95ed1f6d0.json12
-rw-r--r--.sqlx/query-7fb50c1ab5bafc69c43f6136d8c99e1ecfeab41fb7baba21a1a7fdc6d1134234.json (renamed from .sqlx/query-684b4bef3e553b8ccfa20d8de3272e44b1c15ed75977ce24f25fd62042fb20fb.json)6
-rw-r--r--.sqlx/query-8b474c8ed7859f745888644db639b7a4a21210ebf0b7fba97cd016ff6ab4d769.json (renamed from .sqlx/query-0be9484c8d277b08a925b7776b5d0e847cf52c68f24f5ea878b897944e70254c.json)4
-rw-r--r--.sqlx/query-8dae7dbe085898659013167a6bbb9dfe26bce0812a215573a276043095cd872c.json (renamed from .sqlx/query-9e4e8544c86e36901b4543d84b6ac46f63d2804ef3528d833e6d17bec8864454.json)4
-rw-r--r--.sqlx/query-963e21b97f4932da6632ab0fd1eb959e6e8ff1719c0a0111a868b7bd60499477.json (renamed from .sqlx/query-53193435a6eeb72266d0e526a3c6adfcfa20b687ac886efe6d41d5abfd7bc183.json)4
-rw-r--r--.sqlx/query-be644101e1fd50880fa7c82b07cc6e9f69c64bb790d6c52ad84872f256c749aa.json (renamed from .sqlx/query-9eb1e7d793fe6a992dc937b041e5b5206628c3f0cd5230f6671bf8d8946d01f2.json)4
-rw-r--r--.sqlx/query-cc75dd8bb08771698f0156c6fccd5ef25a4a7040f8e5095bc7dc5265f43b0d9c.json20
-rw-r--r--.sqlx/query-f9a6a39c45c3b039f139da0475c25112ffb2b26584ada60c324fc2f945c3d2fa.json12
-rw-r--r--.sqlx/query-f9abb172f96bff3a5fb4ad29f3a52be8d3134fc68e37c6074c69970604ae3844.json12
-rw-r--r--migrations/20250822213537_split_user.sql195
-rw-r--r--src/invite/repo.rs3
-rw-r--r--src/token/repo/auth.rs28
-rw-r--r--src/token/repo/token.rs17
-rw-r--r--src/user/repo.rs47
19 files changed, 315 insertions, 93 deletions
diff --git a/.sqlx/query-613199c25e16a52d85761e213750fe202abfa2af5347010dee59d3b8075eb19e.json b/.sqlx/query-0b1543ec93e02c48c5cbaafd391b5812dc2d1d4a52ea3072b5dd52d71637b33d.json
index 1657efa..937b07e 100644
--- a/.sqlx/query-613199c25e16a52d85761e213750fe202abfa2af5347010dee59d3b8075eb19e.json
+++ b/.sqlx/query-0b1543ec93e02c48c5cbaafd391b5812dc2d1d4a52ea3072b5dd52d71637b33d.json
@@ -1,6 +1,6 @@
{
"db_name": "SQLite",
- "query": "\n delete\n from token\n where user = $1\n returning id as \"id: Id\"\n ",
+ "query": "\n delete\n from token\n where login = $1\n returning id as \"id: Id\"\n ",
"describe": {
"columns": [
{
@@ -16,5 +16,5 @@
false
]
},
- "hash": "613199c25e16a52d85761e213750fe202abfa2af5347010dee59d3b8075eb19e"
+ "hash": "0b1543ec93e02c48c5cbaafd391b5812dc2d1d4a52ea3072b5dd52d71637b33d"
}
diff --git a/.sqlx/query-79495da0101ad12e7e983666b2ca84cbe31458ff73a94648c30b62f3130a5a8b.json b/.sqlx/query-0bd9ba049b839f3187dc74578f26eca4b9f1850dfc30734b516e8cdd17f92a5c.json
index 8f9be21..4bc5119 100644
--- a/.sqlx/query-79495da0101ad12e7e983666b2ca84cbe31458ff73a94648c30b62f3130a5a8b.json
+++ b/.sqlx/query-0bd9ba049b839f3187dc74578f26eca4b9f1850dfc30734b516e8cdd17f92a5c.json
@@ -1,6 +1,6 @@
{
"db_name": "SQLite",
- "query": "\n select\n id as \"id: user::Id\",\n display_name as \"display_name: String\",\n canonical_name as \"canonical_name: String\",\n created_sequence as \"created_sequence: Sequence\",\n created_at as \"created_at: DateTime\",\n password_hash as \"password_hash: StoredHash\"\n from user\n where canonical_name = $1\n ",
+ "query": "\n select\n id as \"id: user::Id\",\n login.display_name as \"display_name: String\",\n login.canonical_name as \"canonical_name: String\",\n user.created_sequence as \"created_sequence: Sequence\",\n user.created_at as \"created_at: DateTime\",\n login.password as \"password: StoredHash\"\n from user\n join login using (id)\n where id = $1\n ",
"describe": {
"columns": [
{
@@ -29,7 +29,7 @@
"type_info": "Text"
},
{
- "name": "password_hash: StoredHash",
+ "name": "password: StoredHash",
"ordinal": 5,
"type_info": "Text"
}
@@ -46,5 +46,5 @@
false
]
},
- "hash": "79495da0101ad12e7e983666b2ca84cbe31458ff73a94648c30b62f3130a5a8b"
+ "hash": "0bd9ba049b839f3187dc74578f26eca4b9f1850dfc30734b516e8cdd17f92a5c"
}
diff --git a/.sqlx/query-afc6db503a3c49c18a9cb07cf0360789d46d94d9cd98887a3d9660d9b753d416.json b/.sqlx/query-20e525a7b6f354e99b9c6722966d85ded0cbd27125093208d7f7f0aabb0ea61b.json
index b7e6c1b..f4ae749 100644
--- a/.sqlx/query-afc6db503a3c49c18a9cb07cf0360789d46d94d9cd98887a3d9660d9b753d416.json
+++ b/.sqlx/query-20e525a7b6f354e99b9c6722966d85ded0cbd27125093208d7f7f0aabb0ea61b.json
@@ -1,6 +1,6 @@
{
"db_name": "SQLite",
- "query": "\n select\n id as \"id: user::Id\",\n display_name as \"display_name: String\",\n canonical_name as \"canonical_name: String\",\n created_sequence as \"created_sequence: Sequence\",\n created_at as \"created_at: DateTime\",\n password_hash as \"password_hash: StoredHash\"\n from user\n where id = $1\n ",
+ "query": "\n select\n id as \"id: user::Id\",\n login.display_name as \"display_name: String\",\n login.canonical_name as \"canonical_name: String\",\n user.created_sequence as \"created_sequence: Sequence\",\n user.created_at as \"created_at: DateTime\",\n login.password as \"password: StoredHash\"\n from user\n join login using (id)\n where login.canonical_name = $1\n ",
"describe": {
"columns": [
{
@@ -29,7 +29,7 @@
"type_info": "Text"
},
{
- "name": "password_hash: StoredHash",
+ "name": "password: StoredHash",
"ordinal": 5,
"type_info": "Text"
}
@@ -46,5 +46,5 @@
false
]
},
- "hash": "afc6db503a3c49c18a9cb07cf0360789d46d94d9cd98887a3d9660d9b753d416"
+ "hash": "20e525a7b6f354e99b9c6722966d85ded0cbd27125093208d7f7f0aabb0ea61b"
}
diff --git a/.sqlx/query-27c3ffb5c284cf2d1c7cee713f6354d6150088a052d1f261853f327a83e8dd75.json b/.sqlx/query-27c3ffb5c284cf2d1c7cee713f6354d6150088a052d1f261853f327a83e8dd75.json
deleted file mode 100644
index c02667e..0000000
--- a/.sqlx/query-27c3ffb5c284cf2d1c7cee713f6354d6150088a052d1f261853f327a83e8dd75.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "db_name": "SQLite",
- "query": "\n update user\n set password_hash = $1\n where id = $2\n returning id as \"id: Id\"\n ",
- "describe": {
- "columns": [
- {
- "name": "id: Id",
- "ordinal": 0,
- "type_info": "Text"
- }
- ],
- "parameters": {
- "Right": 2
- },
- "nullable": [
- false
- ]
- },
- "hash": "27c3ffb5c284cf2d1c7cee713f6354d6150088a052d1f261853f327a83e8dd75"
-}
diff --git a/.sqlx/query-9cf211b1f37708fc8f19b3af911f7488a708d5a50920bb042c0229c314ee3281.json b/.sqlx/query-48f407dc8e63236f2f30634f7c249ec8f6c5e2c3a30a9995738de714c8b53509.json
index 0926b67..1a4389f 100644
--- a/.sqlx/query-9cf211b1f37708fc8f19b3af911f7488a708d5a50920bb042c0229c314ee3281.json
+++ b/.sqlx/query-48f407dc8e63236f2f30634f7c249ec8f6c5e2c3a30a9995738de714c8b53509.json
@@ -1,6 +1,6 @@
{
"db_name": "SQLite",
- "query": "\n select\n id as \"id: user::Id\",\n display_name as \"display_name: String\",\n canonical_name as \"canonical_name: String\",\n created_sequence as \"created_sequence: Sequence\",\n created_at as \"created_at: DateTime\"\n from user\n where id = $1\n ",
+ "query": "\n select\n id as \"id: user::Id\",\n login.display_name as \"display_name: String\",\n login.canonical_name as \"canonical_name: String\",\n user.created_sequence as \"created_sequence: Sequence\",\n user.created_at as \"created_at: DateTime\"\n from user\n join login using (id)\n where id = $1\n ",
"describe": {
"columns": [
{
@@ -40,5 +40,5 @@
false
]
},
- "hash": "9cf211b1f37708fc8f19b3af911f7488a708d5a50920bb042c0229c314ee3281"
+ "hash": "48f407dc8e63236f2f30634f7c249ec8f6c5e2c3a30a9995738de714c8b53509"
}
diff --git a/.sqlx/query-7c87864e6d077640e4f3ef4a354a47265238010f4c53d3c5982f4fd95ed1f6d0.json b/.sqlx/query-7c87864e6d077640e4f3ef4a354a47265238010f4c53d3c5982f4fd95ed1f6d0.json
new file mode 100644
index 0000000..012274a
--- /dev/null
+++ b/.sqlx/query-7c87864e6d077640e4f3ef4a354a47265238010f4c53d3c5982f4fd95ed1f6d0.json
@@ -0,0 +1,12 @@
+{
+ "db_name": "SQLite",
+ "query": "\n insert into login (id, display_name, canonical_name, password)\n values ($1, $2, $3, $4)\n ",
+ "describe": {
+ "columns": [],
+ "parameters": {
+ "Right": 4
+ },
+ "nullable": []
+ },
+ "hash": "7c87864e6d077640e4f3ef4a354a47265238010f4c53d3c5982f4fd95ed1f6d0"
+}
diff --git a/.sqlx/query-684b4bef3e553b8ccfa20d8de3272e44b1c15ed75977ce24f25fd62042fb20fb.json b/.sqlx/query-7fb50c1ab5bafc69c43f6136d8c99e1ecfeab41fb7baba21a1a7fdc6d1134234.json
index d1c2732..1efb9a7 100644
--- a/.sqlx/query-684b4bef3e553b8ccfa20d8de3272e44b1c15ed75977ce24f25fd62042fb20fb.json
+++ b/.sqlx/query-7fb50c1ab5bafc69c43f6136d8c99e1ecfeab41fb7baba21a1a7fdc6d1134234.json
@@ -1,6 +1,6 @@
{
"db_name": "SQLite",
- "query": "\n update token\n set last_used_at = $1\n where secret = $2\n returning\n id as \"token: Id\",\n user as \"user: user::Id\"\n ",
+ "query": "\n update token\n set last_used_at = $1\n where secret = $2\n returning\n id as \"token: Id\",\n login as \"login: user::Id\"\n ",
"describe": {
"columns": [
{
@@ -9,7 +9,7 @@
"type_info": "Text"
},
{
- "name": "user: user::Id",
+ "name": "login: user::Id",
"ordinal": 1,
"type_info": "Text"
}
@@ -22,5 +22,5 @@
false
]
},
- "hash": "684b4bef3e553b8ccfa20d8de3272e44b1c15ed75977ce24f25fd62042fb20fb"
+ "hash": "7fb50c1ab5bafc69c43f6136d8c99e1ecfeab41fb7baba21a1a7fdc6d1134234"
}
diff --git a/.sqlx/query-0be9484c8d277b08a925b7776b5d0e847cf52c68f24f5ea878b897944e70254c.json b/.sqlx/query-8b474c8ed7859f745888644db639b7a4a21210ebf0b7fba97cd016ff6ab4d769.json
index 182f996..b433e4c 100644
--- a/.sqlx/query-0be9484c8d277b08a925b7776b5d0e847cf52c68f24f5ea878b897944e70254c.json
+++ b/.sqlx/query-8b474c8ed7859f745888644db639b7a4a21210ebf0b7fba97cd016ff6ab4d769.json
@@ -1,6 +1,6 @@
{
"db_name": "SQLite",
- "query": "\n insert\n into token (id, secret, user, issued_at, last_used_at)\n values ($1, $2, $3, $4, $4)\n returning secret as \"secret!: Secret\"\n ",
+ "query": "\n insert\n into token (id, secret, login, issued_at, last_used_at)\n values ($1, $2, $3, $4, $4)\n returning secret as \"secret!: Secret\"\n ",
"describe": {
"columns": [
{
@@ -16,5 +16,5 @@
false
]
},
- "hash": "0be9484c8d277b08a925b7776b5d0e847cf52c68f24f5ea878b897944e70254c"
+ "hash": "8b474c8ed7859f745888644db639b7a4a21210ebf0b7fba97cd016ff6ab4d769"
}
diff --git a/.sqlx/query-9e4e8544c86e36901b4543d84b6ac46f63d2804ef3528d833e6d17bec8864454.json b/.sqlx/query-8dae7dbe085898659013167a6bbb9dfe26bce0812a215573a276043095cd872c.json
index beacb24..cbe1cdf 100644
--- a/.sqlx/query-9e4e8544c86e36901b4543d84b6ac46f63d2804ef3528d833e6d17bec8864454.json
+++ b/.sqlx/query-8dae7dbe085898659013167a6bbb9dfe26bce0812a215573a276043095cd872c.json
@@ -1,6 +1,6 @@
{
"db_name": "SQLite",
- "query": "\n select\n id as \"id: Id\",\n display_name as \"display_name: String\",\n canonical_name as \"canonical_name: String\",\n created_sequence as \"created_sequence: Sequence\",\n created_at as \"created_at: DateTime\"\n from user\n where created_sequence > $1\n ",
+ "query": "\n select\n id as \"id: Id\",\n login.display_name as \"display_name: String\",\n login.canonical_name as \"canonical_name: String\",\n user.created_sequence as \"created_sequence: Sequence\",\n user.created_at as \"created_at: DateTime\"\n from user\n join login using (id)\n where user.created_sequence > $1\n ",
"describe": {
"columns": [
{
@@ -40,5 +40,5 @@
false
]
},
- "hash": "9e4e8544c86e36901b4543d84b6ac46f63d2804ef3528d833e6d17bec8864454"
+ "hash": "8dae7dbe085898659013167a6bbb9dfe26bce0812a215573a276043095cd872c"
}
diff --git a/.sqlx/query-53193435a6eeb72266d0e526a3c6adfcfa20b687ac886efe6d41d5abfd7bc183.json b/.sqlx/query-963e21b97f4932da6632ab0fd1eb959e6e8ff1719c0a0111a868b7bd60499477.json
index 31c14de..1025308 100644
--- a/.sqlx/query-53193435a6eeb72266d0e526a3c6adfcfa20b687ac886efe6d41d5abfd7bc183.json
+++ b/.sqlx/query-963e21b97f4932da6632ab0fd1eb959e6e8ff1719c0a0111a868b7bd60499477.json
@@ -1,6 +1,6 @@
{
"db_name": "SQLite",
- "query": "\n select\n invite.id as \"invite_id: Id\",\n issuer.id as \"issuer_id: user::Id\",\n issuer.display_name as \"issuer_name: nfc::String\",\n invite.issued_at as \"invite_issued_at: DateTime\"\n from invite\n join user as issuer on (invite.issuer = issuer.id)\n where invite.id = $1\n ",
+ "query": "\n select\n invite.id as \"invite_id: Id\",\n issuer.id as \"issuer_id: user::Id\",\n issuer_login.display_name as \"issuer_name: nfc::String\",\n invite.issued_at as \"invite_issued_at: DateTime\"\n from invite\n join user as issuer on (invite.issuer = issuer.id)\n join login as issuer_login on (issuer.id = issuer_login.id)\n where invite.id = $1\n ",
"describe": {
"columns": [
{
@@ -34,5 +34,5 @@
false
]
},
- "hash": "53193435a6eeb72266d0e526a3c6adfcfa20b687ac886efe6d41d5abfd7bc183"
+ "hash": "963e21b97f4932da6632ab0fd1eb959e6e8ff1719c0a0111a868b7bd60499477"
}
diff --git a/.sqlx/query-9eb1e7d793fe6a992dc937b041e5b5206628c3f0cd5230f6671bf8d8946d01f2.json b/.sqlx/query-be644101e1fd50880fa7c82b07cc6e9f69c64bb790d6c52ad84872f256c749aa.json
index 45177f3..e56faa9 100644
--- a/.sqlx/query-9eb1e7d793fe6a992dc937b041e5b5206628c3f0cd5230f6671bf8d8946d01f2.json
+++ b/.sqlx/query-be644101e1fd50880fa7c82b07cc6e9f69c64bb790d6c52ad84872f256c749aa.json
@@ -1,6 +1,6 @@
{
"db_name": "SQLite",
- "query": "\n select\n id as \"id: Id\",\n display_name as \"display_name: String\",\n canonical_name as \"canonical_name: String\",\n created_sequence as \"created_sequence: Sequence\",\n created_at as \"created_at: DateTime\"\n from user\n where created_sequence <= $1\n order by canonical_name\n ",
+ "query": "\n select\n id as \"id: Id\",\n login.display_name as \"display_name: String\",\n login.canonical_name as \"canonical_name: String\",\n user.created_sequence as \"created_sequence: Sequence\",\n user.created_at as \"created_at: DateTime\"\n from user\n join login using (id)\n where user.created_sequence <= $1\n order by canonical_name\n ",
"describe": {
"columns": [
{
@@ -40,5 +40,5 @@
false
]
},
- "hash": "9eb1e7d793fe6a992dc937b041e5b5206628c3f0cd5230f6671bf8d8946d01f2"
+ "hash": "be644101e1fd50880fa7c82b07cc6e9f69c64bb790d6c52ad84872f256c749aa"
}
diff --git a/.sqlx/query-cc75dd8bb08771698f0156c6fccd5ef25a4a7040f8e5095bc7dc5265f43b0d9c.json b/.sqlx/query-cc75dd8bb08771698f0156c6fccd5ef25a4a7040f8e5095bc7dc5265f43b0d9c.json
new file mode 100644
index 0000000..200c357
--- /dev/null
+++ b/.sqlx/query-cc75dd8bb08771698f0156c6fccd5ef25a4a7040f8e5095bc7dc5265f43b0d9c.json
@@ -0,0 +1,20 @@
+{
+ "db_name": "SQLite",
+ "query": "\n update login\n set password = $1\n where id = $2\n returning id as \"id: Id\"\n ",
+ "describe": {
+ "columns": [
+ {
+ "name": "id: Id",
+ "ordinal": 0,
+ "type_info": "Text"
+ }
+ ],
+ "parameters": {
+ "Right": 2
+ },
+ "nullable": [
+ false
+ ]
+ },
+ "hash": "cc75dd8bb08771698f0156c6fccd5ef25a4a7040f8e5095bc7dc5265f43b0d9c"
+}
diff --git a/.sqlx/query-f9a6a39c45c3b039f139da0475c25112ffb2b26584ada60c324fc2f945c3d2fa.json b/.sqlx/query-f9a6a39c45c3b039f139da0475c25112ffb2b26584ada60c324fc2f945c3d2fa.json
new file mode 100644
index 0000000..6050e22
--- /dev/null
+++ b/.sqlx/query-f9a6a39c45c3b039f139da0475c25112ffb2b26584ada60c324fc2f945c3d2fa.json
@@ -0,0 +1,12 @@
+{
+ "db_name": "SQLite",
+ "query": "\n insert into user (id, created_sequence, created_at)\n values ($1, $2, $3)\n ",
+ "describe": {
+ "columns": [],
+ "parameters": {
+ "Right": 3
+ },
+ "nullable": []
+ },
+ "hash": "f9a6a39c45c3b039f139da0475c25112ffb2b26584ada60c324fc2f945c3d2fa"
+}
diff --git a/.sqlx/query-f9abb172f96bff3a5fb4ad29f3a52be8d3134fc68e37c6074c69970604ae3844.json b/.sqlx/query-f9abb172f96bff3a5fb4ad29f3a52be8d3134fc68e37c6074c69970604ae3844.json
deleted file mode 100644
index 9d1bc77..0000000
--- a/.sqlx/query-f9abb172f96bff3a5fb4ad29f3a52be8d3134fc68e37c6074c69970604ae3844.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "db_name": "SQLite",
- "query": "\n insert\n into user (id, display_name, canonical_name, password_hash, created_sequence, created_at)\n values ($1, $2, $3, $4, $5, $6)\n ",
- "describe": {
- "columns": [],
- "parameters": {
- "Right": 6
- },
- "nullable": []
- },
- "hash": "f9abb172f96bff3a5fb4ad29f3a52be8d3134fc68e37c6074c69970604ae3844"
-}
diff --git a/migrations/20250822213537_split_user.sql b/migrations/20250822213537_split_user.sql
new file mode 100644
index 0000000..1dbbad6
--- /dev/null
+++ b/migrations/20250822213537_split_user.sql
@@ -0,0 +1,195 @@
+-- First, migrate the table we're actually interested in - `user`. This splits it into two parts:
+--
+-- * login, which is concerned with authentication data (and is non-synchronized,
+-- though at the DB that doesn't matter much), and
+-- * user, which is concerned with chat data (and is synchronized, ditto).
+
+alter table user
+ rename to old_user;
+
+create table login (
+ id text
+ not null
+ primary key,
+ display_name text
+ not null,
+ canonical_name text
+ not null
+ unique,
+ password text
+ not null
+);
+
+insert into
+ login (id, display_name, canonical_name, password)
+select
+ id,
+ display_name,
+ canonical_name,
+ password_hash as password
+from
+ old_user;
+
+create table user (
+ id text
+ not null
+ primary key
+ references login (id),
+ created_at text
+ not null,
+ created_sequence bigint
+ not null
+ unique
+);
+
+insert into
+ user (id, created_at, created_sequence)
+select
+ id,
+ created_at,
+ created_sequence
+from
+ old_user;
+
+-- Now, recreate the entire rest of the owl. Everything that referenced the original `user` table _except tokens_
+-- references the user table. Tokens, which are authentication data, reference the login (authn) table.
+
+alter table token
+ rename to old_token;
+
+create table token (
+ id text
+ not null
+ primary key,
+ secret text
+ not null
+ unique,
+ login text
+ not null
+ references login (id),
+ issued_at text
+ not null,
+ last_used_at text
+ not null
+);
+
+insert into
+ token (id, secret, login, issued_at, last_used_at)
+select
+ id,
+ secret,
+ user as login,
+ issued_at,
+ last_used_at
+from
+ old_token;
+
+alter table invite
+ rename to old_invite;
+
+create table invite (
+ id text
+ primary key
+ not null,
+ issuer text
+ not null
+ references user (id),
+ issued_at text
+ not null
+);
+
+insert into
+ invite (id, issuer, issued_at)
+select
+ id,
+ issuer,
+ issued_at
+from
+ old_invite;
+
+alter table message
+ rename to old_message;
+
+create table message (
+ id text
+ not null
+ primary key,
+ conversation text
+ not null
+ references conversation (id),
+ sender text
+ not null
+ references user (id),
+ body text
+ null,
+ sent_at text
+ not null,
+ sent_sequence bigint
+ unique
+ not null,
+ last_sequence bigint
+ not null
+);
+
+insert into
+ message (id, conversation, sender, body, sent_at, sent_sequence, last_sequence)
+select
+ id,
+ conversation,
+ sender,
+ body,
+ sent_at,
+ sent_sequence,
+ last_sequence
+from
+ old_message;
+
+alter table message_deleted
+ rename to old_message_deleted;
+
+create table message_deleted (
+ id text
+ not null
+ primary key
+ references message (id),
+ deleted_at text
+ not null,
+ deleted_sequence bigint
+ unique
+ not null
+);
+
+insert into
+ message_deleted (id, deleted_at, deleted_sequence)
+select
+ id,
+ deleted_at,
+ deleted_sequence
+from
+ message_deleted;
+
+drop table old_message_deleted;
+drop table old_message;
+drop table old_invite;
+drop table old_token;
+drop table old_user;
+
+create index token_issued_at
+ on token (issued_at);
+create index token_last_used_at
+ on token (last_used_at);
+create index token_login
+ on token (login);
+
+create index invite_issued_at
+ on invite (issued_at);
+
+create index message_sent_at
+ on message (sent_at);
+create index message_conversation
+ on message (conversation);
+create index message_last_sequence
+ on message (last_sequence);
+
+create index message_deleted_deleted_at
+ on message_deleted (deleted_at);
diff --git a/src/invite/repo.rs b/src/invite/repo.rs
index 7cfa18e..934b0ce 100644
--- a/src/invite/repo.rs
+++ b/src/invite/repo.rs
@@ -71,10 +71,11 @@ impl Invites<'_> {
select
invite.id as "invite_id: Id",
issuer.id as "issuer_id: user::Id",
- issuer.display_name as "issuer_name: nfc::String",
+ issuer_login.display_name as "issuer_name: nfc::String",
invite.issued_at as "invite_issued_at: DateTime"
from invite
join user as issuer on (invite.issuer = issuer.id)
+ join login as issuer_login on (issuer.id = issuer_login.id)
where invite.id = $1
"#,
invite,
diff --git a/src/token/repo/auth.rs b/src/token/repo/auth.rs
index 600855d..a42fa1a 100644
--- a/src/token/repo/auth.rs
+++ b/src/token/repo/auth.rs
@@ -28,13 +28,14 @@ impl Auth<'_> {
r#"
select
id as "id: user::Id",
- display_name as "display_name: String",
- canonical_name as "canonical_name: String",
- created_sequence as "created_sequence: Sequence",
- created_at as "created_at: DateTime",
- password_hash as "password_hash: StoredHash"
+ login.display_name as "display_name: String",
+ login.canonical_name as "canonical_name: String",
+ user.created_sequence as "created_sequence: Sequence",
+ user.created_at as "created_at: DateTime",
+ login.password as "password: StoredHash"
from user
- where canonical_name = $1
+ join login using (id)
+ where login.canonical_name = $1
"#,
name,
)
@@ -49,7 +50,7 @@ impl Auth<'_> {
created: Instant::new(row.created_at, row.created_sequence),
};
- Ok((login, row.password_hash))
+ Ok((login, row.password))
}
pub async fn for_user(&mut self, user: &User) -> Result<(History, StoredHash), LoadError> {
@@ -57,12 +58,13 @@ impl Auth<'_> {
r#"
select
id as "id: user::Id",
- display_name as "display_name: String",
- canonical_name as "canonical_name: String",
- created_sequence as "created_sequence: Sequence",
- created_at as "created_at: DateTime",
- password_hash as "password_hash: StoredHash"
+ login.display_name as "display_name: String",
+ login.canonical_name as "canonical_name: String",
+ user.created_sequence as "created_sequence: Sequence",
+ user.created_at as "created_at: DateTime",
+ login.password as "password: StoredHash"
from user
+ join login using (id)
where id = $1
"#,
user.id,
@@ -78,7 +80,7 @@ impl Auth<'_> {
created: Instant::new(row.created_at, row.created_sequence),
};
- Ok((user, row.password_hash))
+ Ok((user, row.password))
}
}
diff --git a/src/token/repo/token.rs b/src/token/repo/token.rs
index 7ac4ac5..5368fee 100644
--- a/src/token/repo/token.rs
+++ b/src/token/repo/token.rs
@@ -37,7 +37,7 @@ impl Tokens<'_> {
let secret = sqlx::query_scalar!(
r#"
insert
- into token (id, secret, user, issued_at, last_used_at)
+ into token (id, secret, login, issued_at, last_used_at)
values ($1, $2, $3, $4, $4)
returning secret as "secret!: Secret"
"#,
@@ -91,7 +91,7 @@ impl Tokens<'_> {
r#"
delete
from token
- where user = $1
+ where login = $1
returning id as "id: Id"
"#,
user,
@@ -139,12 +139,12 @@ impl Tokens<'_> {
where secret = $2
returning
id as "token: Id",
- user as "user: user::Id"
+ login as "login: user::Id"
"#,
used_at,
secret,
)
- .map(|row| (row.token, row.user))
+ .map(|row| (row.token, row.login))
.fetch_one(&mut *self.0)
.await?;
@@ -152,11 +152,12 @@ impl Tokens<'_> {
r#"
select
id as "id: user::Id",
- display_name as "display_name: String",
- canonical_name as "canonical_name: String",
- created_sequence as "created_sequence: Sequence",
- created_at as "created_at: DateTime"
+ login.display_name as "display_name: String",
+ login.canonical_name as "canonical_name: String",
+ user.created_sequence as "created_sequence: Sequence",
+ user.created_at as "created_at: DateTime"
from user
+ join login using (id)
where id = $1
"#,
user,
diff --git a/src/user/repo.rs b/src/user/repo.rs
index 0f67e9a..bfb603d 100644
--- a/src/user/repo.rs
+++ b/src/user/repo.rs
@@ -25,7 +25,7 @@ impl Users<'_> {
pub async fn create(
&mut self,
name: &Name,
- password_hash: &StoredHash,
+ password: &StoredHash,
created: &Instant,
) -> Result<History, sqlx::Error> {
let id = Id::generate();
@@ -34,14 +34,23 @@ impl Users<'_> {
sqlx::query!(
r#"
- insert
- into user (id, display_name, canonical_name, password_hash, created_sequence, created_at)
- values ($1, $2, $3, $4, $5, $6)
+ insert into login (id, display_name, canonical_name, password)
+ values ($1, $2, $3, $4)
"#,
id,
display_name,
canonical_name,
- password_hash,
+ password,
+ )
+ .execute(&mut *self.0)
+ .await?;
+
+ sqlx::query!(
+ r#"
+ insert into user (id, created_sequence, created_at)
+ values ($1, $2, $3)
+ "#,
+ id,
created.sequence,
created.at,
)
@@ -68,8 +77,8 @@ impl Users<'_> {
sqlx::query_scalar!(
r#"
- update user
- set password_hash = $1
+ update login
+ set password = $1
where id = $2
returning id as "id: Id"
"#,
@@ -87,13 +96,14 @@ impl Users<'_> {
r#"
select
id as "id: Id",
- display_name as "display_name: String",
- canonical_name as "canonical_name: String",
- created_sequence as "created_sequence: Sequence",
- created_at as "created_at: DateTime"
+ login.display_name as "display_name: String",
+ login.canonical_name as "canonical_name: String",
+ user.created_sequence as "created_sequence: Sequence",
+ user.created_at as "created_at: DateTime"
from user
- where created_sequence <= $1
- order by canonical_name
+ join login using (id)
+ where user.created_sequence <= $1
+ order by canonical_name
"#,
resume_at,
)
@@ -119,12 +129,13 @@ impl Users<'_> {
r#"
select
id as "id: Id",
- display_name as "display_name: String",
- canonical_name as "canonical_name: String",
- created_sequence as "created_sequence: Sequence",
- created_at as "created_at: DateTime"
+ login.display_name as "display_name: String",
+ login.canonical_name as "canonical_name: String",
+ user.created_sequence as "created_sequence: Sequence",
+ user.created_at as "created_at: DateTime"
from user
- where created_sequence > $1
+ join login using (id)
+ where user.created_sequence > $1
"#,
resume_at,
)