From e49c146dfdeaf9a338a9bf27d2784f51503a3cb0 Mon Sep 17 00:00:00 2001 From: Philippe Loctaux Date: Thu, 13 Apr 2023 22:01:27 +0200 Subject: [PATCH] users: store timezone, default is "UTC" --- .../20230413115500_users_timezone.down.sql | 2 + .../20230413115500_users_timezone.up.sql | 2 + .../queries/users/get_initial_admin.sql | 3 +- .../queries/users/get_one_by_email.sql | 3 +- .../database/queries/users/get_one_by_id.sql | 3 +- .../queries/users/get_one_by_username.sql | 3 +- .../users/get_one_from_authorization_code.sql | 3 +- .../users/get_one_from_refresh_token.sql | 3 +- .../database/queries/users/set_timezone.sql | 5 + crates/database/sqlx-data.json | 678 ++++++++++-------- crates/database/src/tables/users.rs | 15 + crates/jwt/src/claims.rs | 2 + crates/users/src/database.rs | 11 + crates/users/src/lib.rs | 4 + 14 files changed, 415 insertions(+), 322 deletions(-) create mode 100644 crates/database/migrations/20230413115500_users_timezone.down.sql create mode 100644 crates/database/migrations/20230413115500_users_timezone.up.sql create mode 100644 crates/database/queries/users/set_timezone.sql diff --git a/crates/database/migrations/20230413115500_users_timezone.down.sql b/crates/database/migrations/20230413115500_users_timezone.down.sql new file mode 100644 index 0000000..e0bde97 --- /dev/null +++ b/crates/database/migrations/20230413115500_users_timezone.down.sql @@ -0,0 +1,2 @@ +alter table users + drop column timezone; diff --git a/crates/database/migrations/20230413115500_users_timezone.up.sql b/crates/database/migrations/20230413115500_users_timezone.up.sql new file mode 100644 index 0000000..e7cbdec --- /dev/null +++ b/crates/database/migrations/20230413115500_users_timezone.up.sql @@ -0,0 +1,2 @@ +alter table users + add column timezone TEXT not null default 'UTC'; diff --git a/crates/database/queries/users/get_initial_admin.sql b/crates/database/queries/users/get_initial_admin.sql index 29875d1..f9effa2 100644 --- a/crates/database/queries/users/get_initial_admin.sql +++ b/crates/database/queries/users/get_initial_admin.sql @@ -8,7 +8,8 @@ select u.id, u.password, u.password_recover, u.paper_key, - u.is_archived as "is_archived: bool" + u.is_archived as "is_archived: bool", + u.timezone from users u inner join settings s on u.id = s.first_admin diff --git a/crates/database/queries/users/get_one_by_email.sql b/crates/database/queries/users/get_one_by_email.sql index 5fe7d03..3b20840 100644 --- a/crates/database/queries/users/get_one_by_email.sql +++ b/crates/database/queries/users/get_one_by_email.sql @@ -8,7 +8,8 @@ select id, password, password_recover, paper_key, - is_archived as "is_archived: bool" + is_archived as "is_archived: bool", + timezone from users where email is (?) diff --git a/crates/database/queries/users/get_one_by_id.sql b/crates/database/queries/users/get_one_by_id.sql index 8301739..a0dff1d 100644 --- a/crates/database/queries/users/get_one_by_id.sql +++ b/crates/database/queries/users/get_one_by_id.sql @@ -8,7 +8,8 @@ select id, password, password_recover, paper_key, - is_archived as "is_archived: bool" + is_archived as "is_archived: bool", + timezone from users where id is (?) diff --git a/crates/database/queries/users/get_one_by_username.sql b/crates/database/queries/users/get_one_by_username.sql index 723288d..bd03c86 100644 --- a/crates/database/queries/users/get_one_by_username.sql +++ b/crates/database/queries/users/get_one_by_username.sql @@ -8,7 +8,8 @@ select id, password, password_recover, paper_key, - is_archived as "is_archived: bool" + is_archived as "is_archived: bool", + timezone from users where username is (?) diff --git a/crates/database/queries/users/get_one_from_authorization_code.sql b/crates/database/queries/users/get_one_from_authorization_code.sql index 4c12823..3f13a1f 100644 --- a/crates/database/queries/users/get_one_from_authorization_code.sql +++ b/crates/database/queries/users/get_one_from_authorization_code.sql @@ -8,7 +8,8 @@ select u.id, u.password, u.password_recover, u.paper_key, - u.is_archived as "is_archived: bool" + u.is_archived as "is_archived: bool", + u.timezone from users u inner join authorization_codes ac on u.id = ac.user diff --git a/crates/database/queries/users/get_one_from_refresh_token.sql b/crates/database/queries/users/get_one_from_refresh_token.sql index 1848be8..bedf5fc 100644 --- a/crates/database/queries/users/get_one_from_refresh_token.sql +++ b/crates/database/queries/users/get_one_from_refresh_token.sql @@ -8,7 +8,8 @@ select u.id, u.password, u.password_recover, u.paper_key, - u.is_archived as "is_archived: bool" + u.is_archived as "is_archived: bool", + u.timezone from users u inner join refresh_tokens rt on u.id = rt.user diff --git a/crates/database/queries/users/set_timezone.sql b/crates/database/queries/users/set_timezone.sql new file mode 100644 index 0000000..e654116 --- /dev/null +++ b/crates/database/queries/users/set_timezone.sql @@ -0,0 +1,5 @@ +update users + +set timezone = ? + +where id is ? \ No newline at end of file diff --git a/crates/database/sqlx-data.json b/crates/database/sqlx-data.json index 1dfb7f0..400fdce 100644 --- a/crates/database/sqlx-data.json +++ b/crates/database/sqlx-data.json @@ -110,6 +110,90 @@ }, "query": "update apps\n\nset is_archived = 1\n\nwhere id is ?" }, + "35de1a35e6cf6c683a1b2ca3605791aea9cbb852ac1d3df151cc21c341046361": { + "describe": { + "columns": [ + { + "name": "id", + "ordinal": 0, + "type_info": "Text" + }, + { + "name": "created_at: DateTime", + "ordinal": 1, + "type_info": "Text" + }, + { + "name": "updated_at: DateTime", + "ordinal": 2, + "type_info": "Text" + }, + { + "name": "is_admin: bool", + "ordinal": 3, + "type_info": "Int64" + }, + { + "name": "username", + "ordinal": 4, + "type_info": "Text" + }, + { + "name": "name", + "ordinal": 5, + "type_info": "Text" + }, + { + "name": "email", + "ordinal": 6, + "type_info": "Text" + }, + { + "name": "password", + "ordinal": 7, + "type_info": "Text" + }, + { + "name": "password_recover", + "ordinal": 8, + "type_info": "Text" + }, + { + "name": "paper_key", + "ordinal": 9, + "type_info": "Text" + }, + { + "name": "is_archived: bool", + "ordinal": 10, + "type_info": "Int64" + }, + { + "name": "timezone", + "ordinal": 11, + "type_info": "Text" + } + ], + "nullable": [ + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + false, + false + ], + "parameters": { + "Right": 1 + } + }, + "query": "select id,\n created_at as \"created_at: DateTime\",\n updated_at as \"updated_at: DateTime\",\n is_admin as \"is_admin: bool\",\n username,\n name,\n email,\n password,\n password_recover,\n paper_key,\n is_archived as \"is_archived: bool\",\n timezone\nfrom users\n\nwhere id is (?)\n" + }, "37681902a5f5d87492812a525a6488e75d20c1c436a3ba2c5aa3f54da62fe861": { "describe": { "columns": [ @@ -180,84 +264,6 @@ }, "query": "update refresh_tokens\n\nset used_at = CURRENT_TIMESTAMP\n\nwhere token is ?" }, - "4f83a1908a1980ce4bf65eadf24eed2af6c6225972ef7f9f4cf0c702264033a7": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "created_at: DateTime", - "ordinal": 1, - "type_info": "Text" - }, - { - "name": "updated_at: DateTime", - "ordinal": 2, - "type_info": "Text" - }, - { - "name": "is_admin: bool", - "ordinal": 3, - "type_info": "Int64" - }, - { - "name": "username", - "ordinal": 4, - "type_info": "Text" - }, - { - "name": "name", - "ordinal": 5, - "type_info": "Text" - }, - { - "name": "email", - "ordinal": 6, - "type_info": "Text" - }, - { - "name": "password", - "ordinal": 7, - "type_info": "Text" - }, - { - "name": "password_recover", - "ordinal": 8, - "type_info": "Text" - }, - { - "name": "paper_key", - "ordinal": 9, - "type_info": "Text" - }, - { - "name": "is_archived: bool", - "ordinal": 10, - "type_info": "Int64" - } - ], - "nullable": [ - false, - false, - false, - false, - false, - true, - true, - true, - true, - true, - false - ], - "parameters": { - "Right": 1 - } - }, - "query": "select u.id,\n u.created_at as \"created_at: DateTime\",\n u.updated_at as \"updated_at: DateTime\",\n u.is_admin as \"is_admin: bool\",\n u.username,\n u.name,\n u.email,\n u.password,\n u.password_recover,\n u.paper_key,\n u.is_archived as \"is_archived: bool\"\nfrom users u\n\n inner join refresh_tokens rt on u.id = rt.user\n\nwhere rt.token is ?\n" - }, "520fe30e21f6b6c4d9a47c457675eebd144cf020e9230d154e9e4d0c8d6e01ca": { "describe": { "columns": [], @@ -320,6 +326,16 @@ }, "query": "select id,\n created_at as \"created_at: DateTime\",\n revoked_at as \"revoked_at: DateTime\",\n private_der,\n public_der\n\nfrom keys\norder by created_at desc\n" }, + "58e0626629a768c33783bbc926c3d1477ad7e4e983b61ede013e5b066940eb5c": { + "describe": { + "columns": [], + "nullable": [], + "parameters": { + "Right": 2 + } + }, + "query": "update users\n\nset timezone = ?\n\nwhere id is ?" + }, "5f946348ad62389fab3c97a1563d1592cbc5180abbba6d5abd44326bf0862669": { "describe": { "columns": [ @@ -430,7 +446,7 @@ }, "query": "update users\n\nset paper_key = ?\n\nwhere id is ?" }, - "69752cc2a3fc91d4e7a39e0b167695f431380bd40df9638b5df3534715de04b0": { + "73f0d480c8dbef497a458070a32e65f0140f9a6e098ea082870a9c904629a97b": { "describe": { "columns": [ { @@ -487,6 +503,11 @@ "name": "is_archived: bool", "ordinal": 10, "type_info": "Int64" + }, + { + "name": "timezone", + "ordinal": 11, + "type_info": "Text" } ], "nullable": [ @@ -500,13 +521,14 @@ true, true, true, + false, false ], "parameters": { "Right": 1 } }, - "query": "select id,\n created_at as \"created_at: DateTime\",\n updated_at as \"updated_at: DateTime\",\n is_admin as \"is_admin: bool\",\n username,\n name,\n email,\n password,\n password_recover,\n paper_key,\n is_archived as \"is_archived: bool\"\nfrom users\n\nwhere email is (?)\n" + "query": "select id,\n created_at as \"created_at: DateTime\",\n updated_at as \"updated_at: DateTime\",\n is_admin as \"is_admin: bool\",\n username,\n name,\n email,\n password,\n password_recover,\n paper_key,\n is_archived as \"is_archived: bool\",\n timezone\nfrom users\n\nwhere username is (?)\n" }, "7b7f2430b2a719b3d5ce504c0a9302731b3ff82da99ba7771c2728d88aee642a": { "describe": { @@ -578,6 +600,90 @@ }, "query": "update refresh_tokens\n\nset revoked_at = CURRENT_TIMESTAMP\n\nwhere revoked_at is null" }, + "a2afd616a7d9742e5d416f308c30838ee11520d38a5812432af549a8a25b1393": { + "describe": { + "columns": [ + { + "name": "id", + "ordinal": 0, + "type_info": "Text" + }, + { + "name": "created_at: DateTime", + "ordinal": 1, + "type_info": "Text" + }, + { + "name": "updated_at: DateTime", + "ordinal": 2, + "type_info": "Text" + }, + { + "name": "is_admin: bool", + "ordinal": 3, + "type_info": "Int64" + }, + { + "name": "username", + "ordinal": 4, + "type_info": "Text" + }, + { + "name": "name", + "ordinal": 5, + "type_info": "Text" + }, + { + "name": "email", + "ordinal": 6, + "type_info": "Text" + }, + { + "name": "password", + "ordinal": 7, + "type_info": "Text" + }, + { + "name": "password_recover", + "ordinal": 8, + "type_info": "Text" + }, + { + "name": "paper_key", + "ordinal": 9, + "type_info": "Text" + }, + { + "name": "is_archived: bool", + "ordinal": 10, + "type_info": "Int64" + }, + { + "name": "timezone", + "ordinal": 11, + "type_info": "Text" + } + ], + "nullable": [ + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + false, + false + ], + "parameters": { + "Right": 0 + } + }, + "query": "select u.id,\n u.created_at as \"created_at: DateTime\",\n u.updated_at as \"updated_at: DateTime\",\n u.is_admin as \"is_admin: bool\",\n u.username,\n u.name,\n u.email,\n u.password,\n u.password_recover,\n u.paper_key,\n u.is_archived as \"is_archived: bool\",\n u.timezone\nfrom users u\n\n inner join settings s on u.id = s.first_admin\n\nwhere u.is_admin is 1\n and u.is_archived is 0\n and u.id is s.first_admin\n\nlimit 1" + }, "a55b17a3a70e6445517f19536220f0dafc78a0e8b69221dee4715f84841839da": { "describe": { "columns": [], @@ -608,84 +714,6 @@ }, "query": "insert into refresh_tokens (token, ip_address, user, app, expires_at)\nvalues (?, ?, ?, ?, datetime(?, 'unixepoch'))\n" }, - "b652e67e8e1cd0e2b55c830c5569eb1c6caf73857215b4298265cce5c5462902": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "created_at: DateTime", - "ordinal": 1, - "type_info": "Text" - }, - { - "name": "updated_at: DateTime", - "ordinal": 2, - "type_info": "Text" - }, - { - "name": "is_admin: bool", - "ordinal": 3, - "type_info": "Int64" - }, - { - "name": "username", - "ordinal": 4, - "type_info": "Text" - }, - { - "name": "name", - "ordinal": 5, - "type_info": "Text" - }, - { - "name": "email", - "ordinal": 6, - "type_info": "Text" - }, - { - "name": "password", - "ordinal": 7, - "type_info": "Text" - }, - { - "name": "password_recover", - "ordinal": 8, - "type_info": "Text" - }, - { - "name": "paper_key", - "ordinal": 9, - "type_info": "Text" - }, - { - "name": "is_archived: bool", - "ordinal": 10, - "type_info": "Int64" - } - ], - "nullable": [ - false, - false, - false, - false, - false, - true, - true, - true, - true, - true, - false - ], - "parameters": { - "Right": 1 - } - }, - "query": "select id,\n created_at as \"created_at: DateTime\",\n updated_at as \"updated_at: DateTime\",\n is_admin as \"is_admin: bool\",\n username,\n name,\n email,\n password,\n password_recover,\n paper_key,\n is_archived as \"is_archived: bool\"\nfrom users\n\nwhere username is (?)\n" - }, "c00e5fce25caebdeeb24db20880e6c2210f583cddb0d478075f78124258712dd": { "describe": { "columns": [], @@ -706,84 +734,6 @@ }, "query": "update users\n\nset email = ?\n\nwhere id is ?" }, - "c5a57c971d07532ec0cc897b5ac06e0814e506f9c24647d1eaf44174dc0a5954": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "created_at: DateTime", - "ordinal": 1, - "type_info": "Text" - }, - { - "name": "updated_at: DateTime", - "ordinal": 2, - "type_info": "Text" - }, - { - "name": "is_admin: bool", - "ordinal": 3, - "type_info": "Int64" - }, - { - "name": "username", - "ordinal": 4, - "type_info": "Text" - }, - { - "name": "name", - "ordinal": 5, - "type_info": "Text" - }, - { - "name": "email", - "ordinal": 6, - "type_info": "Text" - }, - { - "name": "password", - "ordinal": 7, - "type_info": "Text" - }, - { - "name": "password_recover", - "ordinal": 8, - "type_info": "Text" - }, - { - "name": "paper_key", - "ordinal": 9, - "type_info": "Text" - }, - { - "name": "is_archived: bool", - "ordinal": 10, - "type_info": "Int64" - } - ], - "nullable": [ - false, - false, - false, - false, - false, - true, - true, - true, - true, - true, - false - ], - "parameters": { - "Right": 0 - } - }, - "query": "select u.id,\n u.created_at as \"created_at: DateTime\",\n u.updated_at as \"updated_at: DateTime\",\n u.is_admin as \"is_admin: bool\",\n u.username,\n u.name,\n u.email,\n u.password,\n u.password_recover,\n u.paper_key,\n u.is_archived as \"is_archived: bool\"\nfrom users u\n\n inner join settings s on u.id = s.first_admin\n\nwhere u.is_admin is 1\n and u.is_archived is 0\n and u.id is s.first_admin\n\nlimit 1" - }, "c6157ec3928527ec0ac5f493a5a91faff7e3668204a179e827a87d6279a02c40": { "describe": { "columns": [], @@ -1004,6 +954,90 @@ }, "query": "select id,\n created_at as \"created_at: DateTime\",\n updated_at as \"updated_at: DateTime\",\n label,\n redirect_uri,\n secret,\n is_confidential as \"is_confidential: bool\",\n is_archived as \"is_archived: bool\"\nfrom apps\n\nwhere id is (?)\n" }, + "e6d72e5ef795c6daa506d27560d6daeb36ffede94228636e2b0fa47a0855c1b2": { + "describe": { + "columns": [ + { + "name": "id", + "ordinal": 0, + "type_info": "Text" + }, + { + "name": "created_at: DateTime", + "ordinal": 1, + "type_info": "Text" + }, + { + "name": "updated_at: DateTime", + "ordinal": 2, + "type_info": "Text" + }, + { + "name": "is_admin: bool", + "ordinal": 3, + "type_info": "Int64" + }, + { + "name": "username", + "ordinal": 4, + "type_info": "Text" + }, + { + "name": "name", + "ordinal": 5, + "type_info": "Text" + }, + { + "name": "email", + "ordinal": 6, + "type_info": "Text" + }, + { + "name": "password", + "ordinal": 7, + "type_info": "Text" + }, + { + "name": "password_recover", + "ordinal": 8, + "type_info": "Text" + }, + { + "name": "paper_key", + "ordinal": 9, + "type_info": "Text" + }, + { + "name": "is_archived: bool", + "ordinal": 10, + "type_info": "Int64" + }, + { + "name": "timezone", + "ordinal": 11, + "type_info": "Text" + } + ], + "nullable": [ + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + false, + false + ], + "parameters": { + "Right": 1 + } + }, + "query": "select u.id,\n u.created_at as \"created_at: DateTime\",\n u.updated_at as \"updated_at: DateTime\",\n u.is_admin as \"is_admin: bool\",\n u.username,\n u.name,\n u.email,\n u.password,\n u.password_recover,\n u.paper_key,\n u.is_archived as \"is_archived: bool\",\n u.timezone\nfrom users u\n\n inner join authorization_codes ac on u.id = ac.user\n\nwhere ac.code is ?" + }, "eaf0744f65a1de803fa8cc21b67bad4bdf22760d431265cf97b911e6456b2fd8": { "describe": { "columns": [ @@ -1144,7 +1178,7 @@ }, "query": "insert into apps (id, label, redirect_uri, secret, is_confidential)\nvalues (?, ?, ?, ?, ?)\n" }, - "f4edf4567542eaead2e0db14b0d4197c5d3c1bc02da1897b571bf63bfcb4526a": { + "f472d850bc00dc01a95c837f22879535d8234aa3085a0087edc79231387b4f3d": { "describe": { "columns": [ { @@ -1201,6 +1235,11 @@ "name": "is_archived: bool", "ordinal": 10, "type_info": "Int64" + }, + { + "name": "timezone", + "ordinal": 11, + "type_info": "Text" } ], "nullable": [ @@ -1214,13 +1253,98 @@ true, true, true, + false, false ], "parameters": { "Right": 1 } }, - "query": "select id,\n created_at as \"created_at: DateTime\",\n updated_at as \"updated_at: DateTime\",\n is_admin as \"is_admin: bool\",\n username,\n name,\n email,\n password,\n password_recover,\n paper_key,\n is_archived as \"is_archived: bool\"\nfrom users\n\nwhere id is (?)\n" + "query": "select id,\n created_at as \"created_at: DateTime\",\n updated_at as \"updated_at: DateTime\",\n is_admin as \"is_admin: bool\",\n username,\n name,\n email,\n password,\n password_recover,\n paper_key,\n is_archived as \"is_archived: bool\",\n timezone\nfrom users\n\nwhere email is (?)\n" + }, + "f50157586b672a848294aca06fbb1b5a2d3c91ff83f7e81b42f32339bed0f35f": { + "describe": { + "columns": [ + { + "name": "id", + "ordinal": 0, + "type_info": "Text" + }, + { + "name": "created_at: DateTime", + "ordinal": 1, + "type_info": "Text" + }, + { + "name": "updated_at: DateTime", + "ordinal": 2, + "type_info": "Text" + }, + { + "name": "is_admin: bool", + "ordinal": 3, + "type_info": "Int64" + }, + { + "name": "username", + "ordinal": 4, + "type_info": "Text" + }, + { + "name": "name", + "ordinal": 5, + "type_info": "Text" + }, + { + "name": "email", + "ordinal": 6, + "type_info": "Text" + }, + { + "name": "password", + "ordinal": 7, + "type_info": "Text" + }, + { + "name": "password_recover", + "ordinal": 8, + "type_info": "Text" + }, + { + "name": "paper_key", + "ordinal": 9, + "type_info": "Text" + }, + { + "name": "is_archived: bool", + "ordinal": 10, + "type_info": "Int64" + }, + { + "name": "timezone", + "ordinal": 11, + "type_info": "Text" + } + ], + "nullable": [ + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + false, + false + ], + "parameters": { + "Right": 1 + } + }, + "query": "select u.id,\n u.created_at as \"created_at: DateTime\",\n u.updated_at as \"updated_at: DateTime\",\n u.is_admin as \"is_admin: bool\",\n u.username,\n u.name,\n u.email,\n u.password,\n u.password_recover,\n u.paper_key,\n u.is_archived as \"is_archived: bool\",\n u.timezone\nfrom users u\n\n inner join refresh_tokens rt on u.id = rt.user\n\nwhere rt.token is ?\n" }, "f705411720bd037562f7e3622832262ac4c0a8fc0921fbd934d2b98146d3f413": { "describe": { @@ -1232,84 +1356,6 @@ }, "query": "insert into keys (id, private_der, public_der)\nvalues (?, ?, ?)\n" }, - "f745e4df7b92e295f31f95b17563fd67684736b61adb37289fdcd34114b12d12": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "created_at: DateTime", - "ordinal": 1, - "type_info": "Text" - }, - { - "name": "updated_at: DateTime", - "ordinal": 2, - "type_info": "Text" - }, - { - "name": "is_admin: bool", - "ordinal": 3, - "type_info": "Int64" - }, - { - "name": "username", - "ordinal": 4, - "type_info": "Text" - }, - { - "name": "name", - "ordinal": 5, - "type_info": "Text" - }, - { - "name": "email", - "ordinal": 6, - "type_info": "Text" - }, - { - "name": "password", - "ordinal": 7, - "type_info": "Text" - }, - { - "name": "password_recover", - "ordinal": 8, - "type_info": "Text" - }, - { - "name": "paper_key", - "ordinal": 9, - "type_info": "Text" - }, - { - "name": "is_archived: bool", - "ordinal": 10, - "type_info": "Int64" - } - ], - "nullable": [ - false, - false, - false, - false, - false, - true, - true, - true, - true, - true, - false - ], - "parameters": { - "Right": 1 - } - }, - "query": "select u.id,\n u.created_at as \"created_at: DateTime\",\n u.updated_at as \"updated_at: DateTime\",\n u.is_admin as \"is_admin: bool\",\n u.username,\n u.name,\n u.email,\n u.password,\n u.password_recover,\n u.paper_key,\n u.is_archived as \"is_archived: bool\"\nfrom users u\n\n inner join authorization_codes ac on u.id = ac.user\n\nwhere ac.code is ?" - }, "fb35faa6eb7349f783d0053509225216693532c7233a3bf61674b64c2fb3dad7": { "describe": { "columns": [ diff --git a/crates/database/src/tables/users.rs b/crates/database/src/tables/users.rs index de55739..19a5421 100644 --- a/crates/database/src/tables/users.rs +++ b/crates/database/src/tables/users.rs @@ -16,6 +16,7 @@ pub struct Users { pub password_recover: Option, pub paper_key: Option, pub is_archived: bool, + pub timezone: String, } impl Users { @@ -163,4 +164,18 @@ impl Users { Ok((query.rows_affected() == 1).then_some(())) } + + pub async fn set_timezone( + conn: impl SqliteExecutor<'_>, + id: &str, + timezone: &str, + ) -> Result, Error> { + let query: SqliteQueryResult = + sqlx::query_file!("queries/users/set_timezone.sql", timezone, id) + .execute(conn) + .await + .map_err(handle_error)?; + + Ok((query.rows_affected() == 1).then_some(())) + } } diff --git a/crates/jwt/src/claims.rs b/crates/jwt/src/claims.rs index 52a2b99..127dfa3 100644 --- a/crates/jwt/src/claims.rs +++ b/crates/jwt/src/claims.rs @@ -21,6 +21,7 @@ pub struct JwtClaims { pub email: Option, pub is_admin: bool, pub roles: Vec, + pub zoneinfo: String, } impl JwtClaims { @@ -42,6 +43,7 @@ impl JwtClaims { email: user.email().map(String::from), is_admin: user.is_admin(), roles, + zoneinfo: user.timezone().into(), } } diff --git a/crates/users/src/database.rs b/crates/users/src/database.rs index 52e2a50..c8e6a5d 100644 --- a/crates/users/src/database.rs +++ b/crates/users/src/database.rs @@ -22,6 +22,7 @@ impl From for User { password_recover: db.password_recover, paper_key: db.paper_key, is_archived: db.is_archived, + timezone: db.timezone, } } } @@ -179,4 +180,14 @@ impl User { Ok(()) } + + pub async fn set_timezone( + &self, + conn: impl SqliteExecutor<'_>, + timezone: &str, + ) -> Result<(), Error> { + DatabaseUsers::set_timezone(conn, self.id.as_ref(), timezone).await?; + + Ok(()) + } } diff --git a/crates/users/src/lib.rs b/crates/users/src/lib.rs index da0499b..9573679 100644 --- a/crates/users/src/lib.rs +++ b/crates/users/src/lib.rs @@ -19,6 +19,7 @@ pub struct User { password_recover: Option, paper_key: Option, is_archived: bool, + timezone: String, } impl User { @@ -43,4 +44,7 @@ impl User { pub fn is_admin(&self) -> bool { self.is_admin } + pub fn timezone(&self) -> &str { + &self.timezone + } }