From f0dc54214454199cf4ff1aebb5509084994c6c26 Mon Sep 17 00:00:00 2001 From: Jai A Date: Fri, 2 Aug 2024 23:06:01 -0700 Subject: [PATCH] [wip] Payments/subscriptions support --- .env | 6 +- ...3a461acde17dd1978f580f253d3c7b665857a.json | 58 + ...0cebccc187268c46d44f06874ec50c9f94fcf.json | 46 + ...2f668c8bf7e00f3ca3ae4abd60a7aa36c943b.json | 34 + ...91eeeddd9b913fb848602dca5e35570a56b27.json | 22 + ...af80fcc428014795c719fcafe1272db2c0177.json | 15 + ...238527ec210f20de13bd8995885159c6d277.json} | 10 +- ...05c34a42c6d4db9a13b35f30ef50e6ff4017c.json | 46 + ...24c872c72bb4f37f0c2c9bdd58ca76d41cb7f.json | 15 + ...bbd159acfabdb4302d5b73536efc09e9c6451.json | 20 + ...51f5d0ddc7be1d1b650a86a43712786fd4a4d.json | 34 + ...608166e1fa1f4ce5f655849874858d5f9e27.json} | 5 +- ...cc020a8ba20811d92cb6f2bcd225aa08b6210.json | 22 + ...927ee9dd167e1bb99f37cb3000d73b74de8ed.json | 58 + ...2b6a9bb08ac99448208895946cb010141cde2.json | 22 + Cargo.lock | 1858 +++++++++++------ Cargo.toml | 7 +- migrations/20240702213250_subscriptions.sql | 35 + src/auth/mod.rs | 1 + src/auth/validate.rs | 3 +- src/database/models/ids.rs | 67 + src/database/models/mod.rs | 2 + src/database/models/product_item.rs | 187 ++ src/database/models/user_item.rs | 11 +- src/database/models/user_subscription_item.rs | 120 ++ src/lib.rs | 27 + src/models/mod.rs | 1 + src/models/v3/billing.rs | 104 + src/models/v3/ids.rs | 8 +- src/models/v3/mod.rs | 1 + src/models/v3/users.rs | 3 +- src/routes/internal/billing.rs | 903 ++++++++ src/routes/internal/flows.rs | 20 + src/routes/internal/mod.rs | 4 +- src/routes/mod.rs | 4 + src/routes/v3/payouts.rs | 2 +- 36 files changed, 3083 insertions(+), 698 deletions(-) create mode 100644 .sqlx/query-1b924fd53e72564aab4a11333a93a461acde17dd1978f580f253d3c7b665857a.json create mode 100644 .sqlx/query-26db5e0232042725e9fb746c73f0cebccc187268c46d44f06874ec50c9f94fcf.json create mode 100644 .sqlx/query-37da053e79c32173d7420edbe9d2f668c8bf7e00f3ca3ae4abd60a7aa36c943b.json create mode 100644 .sqlx/query-4065dd9c79f220db9daa3e162d791eeeddd9b913fb848602dca5e35570a56b27.json create mode 100644 .sqlx/query-494610831c7303d9cb3c033ff94af80fcc428014795c719fcafe1272db2c0177.json rename .sqlx/{query-a47456ecddbd1787301a2765168db0df31980ae48cb2ec37c323da10ba55a785.json => query-6a0ca2045bd91a27dce32c730cb5238527ec210f20de13bd8995885159c6d277.json} (88%) create mode 100644 .sqlx/query-71b58e3970dec1efe8921ffb60005c34a42c6d4db9a13b35f30ef50e6ff4017c.json create mode 100644 .sqlx/query-83ad5d39f795c631e1cba90cadd24c872c72bb4f37f0c2c9bdd58ca76d41cb7f.json create mode 100644 .sqlx/query-8b147e69d4e1647a3e27a0d9987bbd159acfabdb4302d5b73536efc09e9c6451.json create mode 100644 .sqlx/query-ba2e3eab0daba9698686cbf324351f5d0ddc7be1d1b650a86a43712786fd4a4d.json rename .sqlx/{query-36c8a2fe704197539ee5010e94a03a48637ac9227d683e0c75eb2603ba156610.json => query-c33fb3503d040fd91a049b10853f608166e1fa1f4ce5f655849874858d5f9e27.json} (69%) create mode 100644 .sqlx/query-eb32f61d58b71eb55c348abe51bcc020a8ba20811d92cb6f2bcd225aa08b6210.json create mode 100644 .sqlx/query-f09d4db12cdc0921dd0fff57564927ee9dd167e1bb99f37cb3000d73b74de8ed.json create mode 100644 .sqlx/query-f2711811ac8f67ead8e307259692b6a9bb08ac99448208895946cb010141cde2.json create mode 100644 migrations/20240702213250_subscriptions.sql create mode 100644 src/database/models/product_item.rs create mode 100644 src/database/models/user_subscription_item.rs create mode 100644 src/models/v3/billing.rs create mode 100644 src/routes/internal/billing.rs diff --git a/.env b/.env index 85f578ac..55786ebf 100644 --- a/.env +++ b/.env @@ -84,6 +84,7 @@ SMTP_HOST=none SITE_VERIFY_EMAIL_PATH=none SITE_RESET_PASSWORD_PATH=none +SITE_BILLING_PATH=none BEEHIIV_PUBLICATION_ID=none BEEHIIV_API_KEY=none @@ -99,4 +100,7 @@ MAXMIND_LICENSE_KEY=none PAYOUTS_BUDGET=100 -FLAME_ANVIL_URL=none \ No newline at end of file +FLAME_ANVIL_URL=none + +STRIPE_API_KEY=none +STRIPE_WEBHOOK_SECRET=none \ No newline at end of file diff --git a/.sqlx/query-1b924fd53e72564aab4a11333a93a461acde17dd1978f580f253d3c7b665857a.json b/.sqlx/query-1b924fd53e72564aab4a11333a93a461acde17dd1978f580f253d3c7b665857a.json new file mode 100644 index 00000000..072389af --- /dev/null +++ b/.sqlx/query-1b924fd53e72564aab4a11333a93a461acde17dd1978f580f253d3c7b665857a.json @@ -0,0 +1,58 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n id, user_id, price_id, created, expires, last_charge, status\n FROM users_subscriptions\n WHERE id = ANY($1::bigint[])", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "user_id", + "type_info": "Int8" + }, + { + "ordinal": 2, + "name": "price_id", + "type_info": "Int8" + }, + { + "ordinal": 3, + "name": "created", + "type_info": "Timestamptz" + }, + { + "ordinal": 4, + "name": "expires", + "type_info": "Timestamptz" + }, + { + "ordinal": 5, + "name": "last_charge", + "type_info": "Timestamptz" + }, + { + "ordinal": 6, + "name": "status", + "type_info": "Varchar" + } + ], + "parameters": { + "Left": [ + "Int8Array" + ] + }, + "nullable": [ + false, + false, + false, + false, + false, + true, + false + ] + }, + "hash": "1b924fd53e72564aab4a11333a93a461acde17dd1978f580f253d3c7b665857a" +} diff --git a/.sqlx/query-26db5e0232042725e9fb746c73f0cebccc187268c46d44f06874ec50c9f94fcf.json b/.sqlx/query-26db5e0232042725e9fb746c73f0cebccc187268c46d44f06874ec50c9f94fcf.json new file mode 100644 index 00000000..5499600a --- /dev/null +++ b/.sqlx/query-26db5e0232042725e9fb746c73f0cebccc187268c46d44f06874ec50c9f94fcf.json @@ -0,0 +1,46 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT id, product_id, interval, price, currency_code\n FROM products_prices\n WHERE product_id = ANY($1::bigint[])", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "product_id", + "type_info": "Int8" + }, + { + "ordinal": 2, + "name": "interval", + "type_info": "Jsonb" + }, + { + "ordinal": 3, + "name": "price", + "type_info": "Int4" + }, + { + "ordinal": 4, + "name": "currency_code", + "type_info": "Text" + } + ], + "parameters": { + "Left": [ + "Int8Array" + ] + }, + "nullable": [ + false, + false, + false, + false, + false + ] + }, + "hash": "26db5e0232042725e9fb746c73f0cebccc187268c46d44f06874ec50c9f94fcf" +} diff --git a/.sqlx/query-37da053e79c32173d7420edbe9d2f668c8bf7e00f3ca3ae4abd60a7aa36c943b.json b/.sqlx/query-37da053e79c32173d7420edbe9d2f668c8bf7e00f3ca3ae4abd60a7aa36c943b.json new file mode 100644 index 00000000..248d9cea --- /dev/null +++ b/.sqlx/query-37da053e79c32173d7420edbe9d2f668c8bf7e00f3ca3ae4abd60a7aa36c943b.json @@ -0,0 +1,34 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT id, metadata, unitary\n FROM products\n WHERE id = ANY($1::bigint[])", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "metadata", + "type_info": "Jsonb" + }, + { + "ordinal": 2, + "name": "unitary", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [ + "Int8Array" + ] + }, + "nullable": [ + false, + false, + false + ] + }, + "hash": "37da053e79c32173d7420edbe9d2f668c8bf7e00f3ca3ae4abd60a7aa36c943b" +} diff --git a/.sqlx/query-4065dd9c79f220db9daa3e162d791eeeddd9b913fb848602dca5e35570a56b27.json b/.sqlx/query-4065dd9c79f220db9daa3e162d791eeeddd9b913fb848602dca5e35570a56b27.json new file mode 100644 index 00000000..de3d7a51 --- /dev/null +++ b/.sqlx/query-4065dd9c79f220db9daa3e162d791eeeddd9b913fb848602dca5e35570a56b27.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT EXISTS(SELECT 1 FROM products WHERE id=$1)", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "exists", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [ + "Int8" + ] + }, + "nullable": [ + null + ] + }, + "hash": "4065dd9c79f220db9daa3e162d791eeeddd9b913fb848602dca5e35570a56b27" +} diff --git a/.sqlx/query-494610831c7303d9cb3c033ff94af80fcc428014795c719fcafe1272db2c0177.json b/.sqlx/query-494610831c7303d9cb3c033ff94af80fcc428014795c719fcafe1272db2c0177.json new file mode 100644 index 00000000..9f0aa93c --- /dev/null +++ b/.sqlx/query-494610831c7303d9cb3c033ff94af80fcc428014795c719fcafe1272db2c0177.json @@ -0,0 +1,15 @@ +{ + "db_name": "PostgreSQL", + "query": "\n UPDATE users\n SET stripe_customer_id = $1\n WHERE id = $2\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Text", + "Int8" + ] + }, + "nullable": [] + }, + "hash": "494610831c7303d9cb3c033ff94af80fcc428014795c719fcafe1272db2c0177" +} diff --git a/.sqlx/query-a47456ecddbd1787301a2765168db0df31980ae48cb2ec37c323da10ba55a785.json b/.sqlx/query-6a0ca2045bd91a27dce32c730cb5238527ec210f20de13bd8995885159c6d277.json similarity index 88% rename from .sqlx/query-a47456ecddbd1787301a2765168db0df31980ae48cb2ec37c323da10ba55a785.json rename to .sqlx/query-6a0ca2045bd91a27dce32c730cb5238527ec210f20de13bd8995885159c6d277.json index fca3ad56..759630e8 100644 --- a/.sqlx/query-a47456ecddbd1787301a2765168db0df31980ae48cb2ec37c323da10ba55a785.json +++ b/.sqlx/query-6a0ca2045bd91a27dce32c730cb5238527ec210f20de13bd8995885159c6d277.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT id, name, email,\n avatar_url, username, bio,\n created, role, badges,\n balance,\n github_id, discord_id, gitlab_id, google_id, steam_id, microsoft_id,\n email_verified, password, totp_secret, paypal_id, paypal_country, paypal_email,\n venmo_handle\n FROM users\n WHERE id = ANY($1) OR LOWER(username) = ANY($2)\n ", + "query": "\n SELECT id, name, email,\n avatar_url, username, bio,\n created, role, badges,\n balance,\n github_id, discord_id, gitlab_id, google_id, steam_id, microsoft_id,\n email_verified, password, totp_secret, paypal_id, paypal_country, paypal_email,\n venmo_handle, stripe_customer_id\n FROM users\n WHERE id = ANY($1) OR LOWER(username) = ANY($2)\n ", "describe": { "columns": [ { @@ -117,6 +117,11 @@ "ordinal": 22, "name": "venmo_handle", "type_info": "Text" + }, + { + "ordinal": 23, + "name": "stripe_customer_id", + "type_info": "Text" } ], "parameters": { @@ -148,8 +153,9 @@ true, true, true, + true, true ] }, - "hash": "a47456ecddbd1787301a2765168db0df31980ae48cb2ec37c323da10ba55a785" + "hash": "6a0ca2045bd91a27dce32c730cb5238527ec210f20de13bd8995885159c6d277" } diff --git a/.sqlx/query-71b58e3970dec1efe8921ffb60005c34a42c6d4db9a13b35f30ef50e6ff4017c.json b/.sqlx/query-71b58e3970dec1efe8921ffb60005c34a42c6d4db9a13b35f30ef50e6ff4017c.json new file mode 100644 index 00000000..e8ab4fbd --- /dev/null +++ b/.sqlx/query-71b58e3970dec1efe8921ffb60005c34a42c6d4db9a13b35f30ef50e6ff4017c.json @@ -0,0 +1,46 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT id, product_id, interval, price, currency_code\n FROM products_prices\n WHERE id = ANY($1::bigint[])", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "product_id", + "type_info": "Int8" + }, + { + "ordinal": 2, + "name": "interval", + "type_info": "Jsonb" + }, + { + "ordinal": 3, + "name": "price", + "type_info": "Int4" + }, + { + "ordinal": 4, + "name": "currency_code", + "type_info": "Text" + } + ], + "parameters": { + "Left": [ + "Int8Array" + ] + }, + "nullable": [ + false, + false, + false, + false, + false + ] + }, + "hash": "71b58e3970dec1efe8921ffb60005c34a42c6d4db9a13b35f30ef50e6ff4017c" +} diff --git a/.sqlx/query-83ad5d39f795c631e1cba90cadd24c872c72bb4f37f0c2c9bdd58ca76d41cb7f.json b/.sqlx/query-83ad5d39f795c631e1cba90cadd24c872c72bb4f37f0c2c9bdd58ca76d41cb7f.json new file mode 100644 index 00000000..8e30b9e9 --- /dev/null +++ b/.sqlx/query-83ad5d39f795c631e1cba90cadd24c872c72bb4f37f0c2c9bdd58ca76d41cb7f.json @@ -0,0 +1,15 @@ +{ + "db_name": "PostgreSQL", + "query": "\n UPDATE users\n SET badges = $1\n WHERE (id = $2)\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Int8", + "Int8" + ] + }, + "nullable": [] + }, + "hash": "83ad5d39f795c631e1cba90cadd24c872c72bb4f37f0c2c9bdd58ca76d41cb7f" +} diff --git a/.sqlx/query-8b147e69d4e1647a3e27a0d9987bbd159acfabdb4302d5b73536efc09e9c6451.json b/.sqlx/query-8b147e69d4e1647a3e27a0d9987bbd159acfabdb4302d5b73536efc09e9c6451.json new file mode 100644 index 00000000..fed32af6 --- /dev/null +++ b/.sqlx/query-8b147e69d4e1647a3e27a0d9987bbd159acfabdb4302d5b73536efc09e9c6451.json @@ -0,0 +1,20 @@ +{ + "db_name": "PostgreSQL", + "query": "\n INSERT INTO users_subscriptions (\n id, user_id, price_id, created, expires, last_charge, status\n )\n VALUES (\n $1, $2, $3, $4, $5, $6, $7\n )\n ON CONFLICT (id)\n DO UPDATE\n SET expires = EXCLUDED.expires,\n last_charge = EXCLUDED.last_charge,\n status = EXCLUDED.status\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Int8", + "Int8", + "Int8", + "Timestamptz", + "Timestamptz", + "Timestamptz", + "Varchar" + ] + }, + "nullable": [] + }, + "hash": "8b147e69d4e1647a3e27a0d9987bbd159acfabdb4302d5b73536efc09e9c6451" +} diff --git a/.sqlx/query-ba2e3eab0daba9698686cbf324351f5d0ddc7be1d1b650a86a43712786fd4a4d.json b/.sqlx/query-ba2e3eab0daba9698686cbf324351f5d0ddc7be1d1b650a86a43712786fd4a4d.json new file mode 100644 index 00000000..ee4696d2 --- /dev/null +++ b/.sqlx/query-ba2e3eab0daba9698686cbf324351f5d0ddc7be1d1b650a86a43712786fd4a4d.json @@ -0,0 +1,34 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT id, metadata, unitary\n FROM products\n WHERE 1 = $1", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "metadata", + "type_info": "Jsonb" + }, + { + "ordinal": 2, + "name": "unitary", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [ + "Int4" + ] + }, + "nullable": [ + false, + false, + false + ] + }, + "hash": "ba2e3eab0daba9698686cbf324351f5d0ddc7be1d1b650a86a43712786fd4a4d" +} diff --git a/.sqlx/query-36c8a2fe704197539ee5010e94a03a48637ac9227d683e0c75eb2603ba156610.json b/.sqlx/query-c33fb3503d040fd91a049b10853f608166e1fa1f4ce5f655849874858d5f9e27.json similarity index 69% rename from .sqlx/query-36c8a2fe704197539ee5010e94a03a48637ac9227d683e0c75eb2603ba156610.json rename to .sqlx/query-c33fb3503d040fd91a049b10853f608166e1fa1f4ce5f655849874858d5f9e27.json index bb894c59..da480468 100644 --- a/.sqlx/query-36c8a2fe704197539ee5010e94a03a48637ac9227d683e0c75eb2603ba156610.json +++ b/.sqlx/query-c33fb3503d040fd91a049b10853f608166e1fa1f4ce5f655849874858d5f9e27.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n INSERT INTO users (\n id, username, name, email,\n avatar_url, bio, created,\n github_id, discord_id, gitlab_id, google_id, steam_id, microsoft_id,\n email_verified, password, paypal_id, paypal_country, paypal_email,\n venmo_handle\n )\n VALUES (\n $1, $2, $3, $4, $5,\n $6, $7,\n $8, $9, $10, $11, $12, $13,\n $14, $15, $16, $17, $18, $19\n )\n ", + "query": "\n INSERT INTO users (\n id, username, name, email,\n avatar_url, bio, created,\n github_id, discord_id, gitlab_id, google_id, steam_id, microsoft_id,\n email_verified, password, paypal_id, paypal_country, paypal_email,\n venmo_handle, stripe_customer_id\n )\n VALUES (\n $1, $2, $3, $4, $5,\n $6, $7,\n $8, $9, $10, $11, $12, $13,\n $14, $15, $16, $17, $18, $19, $20\n )\n ", "describe": { "columns": [], "parameters": { @@ -23,10 +23,11 @@ "Text", "Text", "Text", + "Text", "Text" ] }, "nullable": [] }, - "hash": "36c8a2fe704197539ee5010e94a03a48637ac9227d683e0c75eb2603ba156610" + "hash": "c33fb3503d040fd91a049b10853f608166e1fa1f4ce5f655849874858d5f9e27" } diff --git a/.sqlx/query-eb32f61d58b71eb55c348abe51bcc020a8ba20811d92cb6f2bcd225aa08b6210.json b/.sqlx/query-eb32f61d58b71eb55c348abe51bcc020a8ba20811d92cb6f2bcd225aa08b6210.json new file mode 100644 index 00000000..312ddc3e --- /dev/null +++ b/.sqlx/query-eb32f61d58b71eb55c348abe51bcc020a8ba20811d92cb6f2bcd225aa08b6210.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT EXISTS(SELECT 1 FROM products_prices WHERE id=$1)", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "exists", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [ + "Int8" + ] + }, + "nullable": [ + null + ] + }, + "hash": "eb32f61d58b71eb55c348abe51bcc020a8ba20811d92cb6f2bcd225aa08b6210" +} diff --git a/.sqlx/query-f09d4db12cdc0921dd0fff57564927ee9dd167e1bb99f37cb3000d73b74de8ed.json b/.sqlx/query-f09d4db12cdc0921dd0fff57564927ee9dd167e1bb99f37cb3000d73b74de8ed.json new file mode 100644 index 00000000..a31ad018 --- /dev/null +++ b/.sqlx/query-f09d4db12cdc0921dd0fff57564927ee9dd167e1bb99f37cb3000d73b74de8ed.json @@ -0,0 +1,58 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n id, user_id, price_id, created, expires, last_charge, status\n FROM users_subscriptions\n WHERE user_id = $1", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "user_id", + "type_info": "Int8" + }, + { + "ordinal": 2, + "name": "price_id", + "type_info": "Int8" + }, + { + "ordinal": 3, + "name": "created", + "type_info": "Timestamptz" + }, + { + "ordinal": 4, + "name": "expires", + "type_info": "Timestamptz" + }, + { + "ordinal": 5, + "name": "last_charge", + "type_info": "Timestamptz" + }, + { + "ordinal": 6, + "name": "status", + "type_info": "Varchar" + } + ], + "parameters": { + "Left": [ + "Int8" + ] + }, + "nullable": [ + false, + false, + false, + false, + false, + true, + false + ] + }, + "hash": "f09d4db12cdc0921dd0fff57564927ee9dd167e1bb99f37cb3000d73b74de8ed" +} diff --git a/.sqlx/query-f2711811ac8f67ead8e307259692b6a9bb08ac99448208895946cb010141cde2.json b/.sqlx/query-f2711811ac8f67ead8e307259692b6a9bb08ac99448208895946cb010141cde2.json new file mode 100644 index 00000000..9e6a21fe --- /dev/null +++ b/.sqlx/query-f2711811ac8f67ead8e307259692b6a9bb08ac99448208895946cb010141cde2.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT EXISTS(SELECT 1 FROM users_subscriptions WHERE id=$1)", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "exists", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [ + "Int8" + ] + }, + "nullable": [ + null + ] + }, + "hash": "f2711811ac8f67ead8e307259692b6a9bb08ac99448208895946cb010141cde2" +} diff --git a/Cargo.lock b/Cargo.lock index 1ebca561..91c07464 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,11 +4,11 @@ version = 3 [[package]] name = "actix-codec" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "617a8268e3537fe1d8c9ead925fca49ef6400927ee7bc26750e90ecee14ce4b8" +checksum = "5f7b0a21988c1bf877cf4759ef5ddaac04c1c9fe808c9142ecb78ba97d97a28a" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", "bytes", "futures-core", "futures-sink", @@ -36,15 +36,15 @@ dependencies = [ [[package]] name = "actix-files" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf0bdd6ff79de7c9a021f5d9ea79ce23e108d8bfc9b49b5b4a2cf6fad5a35212" +checksum = "0773d59061dedb49a8aed04c67291b9d8cf2fe0b60130a381aab53c6dd86e9be" dependencies = [ "actix-http", "actix-service", "actix-utils", "actix-web", - "bitflags 2.4.1", + "bitflags 2.6.0", "bytes", "derive_more", "futures-core", @@ -59,17 +59,17 @@ dependencies = [ [[package]] name = "actix-http" -version = "3.5.1" +version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "129d4c88e98860e1758c5de288d1632b07970a16d59bdf7b8d66053d582bb71f" +checksum = "3ae682f693a9cd7b058f2b0b5d9a6d7728a8555779bedbbc35dd88528611d020" dependencies = [ "actix-codec", "actix-rt", "actix-service", "actix-utils", - "ahash 0.8.7", - "base64 0.21.7", - "bitflags 2.4.1", + "ahash 0.8.11", + "base64 0.22.1", + "bitflags 2.6.0", "brotli", "bytes", "bytestring", @@ -78,7 +78,7 @@ dependencies = [ "flate2", "futures-core", "h2", - "http", + "http 0.2.12", "httparse", "httpdate", "itoa", @@ -87,13 +87,13 @@ dependencies = [ "mime", "percent-encoding", "pin-project-lite", - "rand", + "rand 0.8.5", "sha1 0.10.6", "smallvec", "tokio", "tokio-util", "tracing", - "zstd 0.13.0", + "zstd 0.13.1", ] [[package]] @@ -103,14 +103,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" dependencies = [ "quote", - "syn 2.0.48", + "syn 2.0.68", ] [[package]] name = "actix-multipart" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b960e2aea75f49c8f069108063d12a48d329fc8b60b786dfc7552a9d5918d2d" +checksum = "d974dd6c4f78d102d057c672dcf6faa618fafa9df91d44f9c466688fc1275a3a" dependencies = [ "actix-multipart-derive", "actix-utils", @@ -124,6 +124,7 @@ dependencies = [ "log", "memchr", "mime", + "rand 0.8.5", "serde", "serde_json", "serde_plain", @@ -137,31 +138,33 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a0a77f836d869f700e5b47ac7c3c8b9c8bc82e4aec861954c6198abee3ebd4d" dependencies = [ - "darling 0.20.3", + "darling 0.20.9", "parse-size", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.68", ] [[package]] name = "actix-router" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d22475596539443685426b6bdadb926ad0ecaefdfc5fb05e5e3441f15463c511" +checksum = "13d324164c51f63867b57e73ba5936ea151b8a41a1d23d1031eeb9f70d0236f8" dependencies = [ "bytestring", - "http", + "cfg-if", + "http 0.2.12", "regex", + "regex-lite", "serde", "tracing", ] [[package]] name = "actix-rt" -version = "2.9.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28f32d40287d3f402ae0028a9d54bef51af15c8769492826a69d28f81893151d" +checksum = "24eda4e2a6e042aa4e55ac438a2ae052d3b5da0ecf83d7411e1a368946925208" dependencies = [ "actix-macros", "futures-core", @@ -170,9 +173,9 @@ dependencies = [ [[package]] name = "actix-server" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eb13e7eef0423ea6eab0e59f6c72e7cb46d33691ad56a726b3cd07ddec2c2d4" +checksum = "b02303ce8d4e8be5b855af6cf3c3a08f3eff26880faad82bab679c22d3650cb5" dependencies = [ "actix-rt", "actix-service", @@ -180,7 +183,7 @@ dependencies = [ "futures-core", "futures-util", "mio", - "socket2 0.5.5", + "socket2 0.5.7", "tokio", "tracing", ] @@ -208,9 +211,9 @@ dependencies = [ [[package]] name = "actix-web" -version = "4.4.1" +version = "4.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e43428f3bf11dee6d166b00ec2df4e3aa8cc1606aaa0b7433c146852e2f4e03b" +checksum = "1988c02af8d2b718c05bc4aeb6a66395b7cdf32858c2c71131e5637a8c05a9ff" dependencies = [ "actix-codec", "actix-http", @@ -221,7 +224,7 @@ dependencies = [ "actix-service", "actix-utils", "actix-web-codegen", - "ahash 0.8.7", + "ahash 0.8.11", "bytes", "bytestring", "cfg-if", @@ -237,38 +240,41 @@ dependencies = [ "once_cell", "pin-project-lite", "regex", + "regex-lite", "serde", "serde_json", "serde_urlencoded", "smallvec", - "socket2 0.5.5", + "socket2 0.5.7", "time", "url", ] [[package]] name = "actix-web-codegen" -version = "4.2.2" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1f50ebbb30eca122b188319a4398b3f7bb4a8cdf50ecfb73bfc6a3c3ce54f5" +checksum = "f591380e2e68490b5dfaf1dd1aa0ebe78d84ba7067078512b4ea6e4492d622b8" dependencies = [ "actix-router", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.68", ] [[package]] name = "actix-web-prom" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f23f332a652836b8f3a6876103c70c9ed436d0e69fa779ab5d7f57b1d5c8d488" +checksum = "76743e67d4e7efa9fc2ac7123de0dd7b2ca592668e19334f1d81a3b077afc6ac" dependencies = [ "actix-web", "futures-core", + "log", "pin-project-lite", "prometheus", "regex", + "strfmt", ] [[package]] @@ -286,9 +292,9 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" dependencies = [ "gimli", ] @@ -301,9 +307,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aes" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", "cipher", @@ -312,23 +318,23 @@ dependencies = [ [[package]] name = "ahash" -version = "0.7.7" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ - "getrandom", + "getrandom 0.2.15", "once_cell", "version_check", ] [[package]] name = "ahash" -version = "0.8.7" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", - "getrandom", + "getrandom 0.2.15", "once_cell", "version_check", "zerocopy", @@ -336,9 +342,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] @@ -360,9 +366,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "android-tzdata" @@ -379,11 +385,17 @@ dependencies = [ "libc", ] +[[package]] +name = "anyhow" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" + [[package]] name = "argon2" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ba4cac0a46bc1d2912652a751c47f2a9f3a7fe89bcae2275d418f5270402f9" +checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072" dependencies = [ "base64ct", "blake2", @@ -408,15 +420,40 @@ dependencies = [ "futures-core", ] +[[package]] +name = "async-stripe" +version = "0.37.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2f14b5943a52cf051bbbbb68538e93a69d1e291934174121e769f4b181113f5" +dependencies = [ + "chrono", + "futures-util", + "hex", + "hmac 0.12.1", + "http-types", + "hyper 0.14.29", + "hyper-rustls", + "serde", + "serde_json", + "serde_path_to_error", + "serde_qs 0.10.1", + "sha2 0.10.8", + "smart-default", + "smol_str", + "thiserror", + "tokio", + "uuid 0.8.2", +] + [[package]] name = "async-trait" -version = "0.1.77" +version = "0.1.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.68", ] [[package]] @@ -428,23 +465,13 @@ dependencies = [ "num-traits", ] -[[package]] -name = "atomic-write-file" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edcdbedc2236483ab103a53415653d6b4442ea6141baf1ffa85df29635e88436" -dependencies = [ - "nix", - "rand", -] - [[package]] name = "attohttpc" version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fcf00bc6d5abb29b5f97e3c61a90b6d3caa12f3faf897d4a3e3607c050a35a7" dependencies = [ - "http", + "http 0.2.12", "log", "native-tls", "serde", @@ -454,9 +481,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "aws-creds" @@ -486,9 +513,9 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" dependencies = [ "addr2line", "cc", @@ -517,6 +544,12 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "base64ct" version = "1.6.0" @@ -561,9 +594,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" dependencies = [ "serde", ] @@ -609,9 +642,9 @@ dependencies = [ [[package]] name = "borsh" -version = "1.3.1" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f58b559fd6448c6e2fd0adb5720cd98a2506594cafa4737ff98c396f3e82f667" +checksum = "a6362ed55def622cddc70a4746a68554d7b687713770de539e59a739b249f8ed" dependencies = [ "borsh-derive", "cfg_aliases", @@ -619,23 +652,23 @@ dependencies = [ [[package]] name = "borsh-derive" -version = "1.3.1" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aadb5b6ccbd078890f6d7003694e33816e6b784358f18e15e7e6d9f065a57cd" +checksum = "c3ef8005764f53cd4dca619f5bf64cafd4664dada50ece25e4d81de54c80cc0b" dependencies = [ "once_cell", "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.68", "syn_derive", ] [[package]] name = "brotli" -version = "3.4.0" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "516074a47ef4bce09577a3b379392300159ce5b1ba2e501ff1c819950066100f" +checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -644,9 +677,9 @@ dependencies = [ [[package]] name = "brotli-decompressor" -version = "2.5.1" +version = "4.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" +checksum = "9a45bd2e4095a8b518033b128020dd4a55aab1c0a381ba4404a472630f4bc362" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -663,15 +696,15 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytecheck" -version = "0.6.11" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627" +checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" dependencies = [ "bytecheck_derive", "ptr_meta", @@ -680,9 +713,9 @@ dependencies = [ [[package]] name = "bytecheck_derive" -version = "0.6.11" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" +checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" dependencies = [ "proc-macro2", "quote", @@ -691,9 +724,9 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.14.0" +version = "1.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" +checksum = "b236fc92302c97ed75b38da1f4917b5cdda4984745740f153a5d3059e48d725e" [[package]] name = "byteorder" @@ -703,9 +736,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" [[package]] name = "bytestring" @@ -745,12 +778,13 @@ checksum = "a2698f953def977c68f935bb0dfa959375ad4638570e969e2f1e9f433cbf1af6" [[package]] name = "cc" -version = "1.0.83" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +checksum = "74b6a57f98764a267ff415d50a25e6e166f3831a5071af4995296ea97d210490" dependencies = [ "jobserver", "libc", + "once_cell", ] [[package]] @@ -770,15 +804,15 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cfg_aliases" -version = "0.1.1" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", @@ -786,7 +820,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.48.5", + "windows-targets 0.52.5", ] [[package]] @@ -795,7 +829,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8eebd66744a15ded14960ab4ccdbfb51ad3b81f51f3f04a80adac98c985396c9" dependencies = [ - "hashbrown 0.14.3", + "hashbrown 0.14.5", "stacker", ] @@ -820,8 +854,8 @@ dependencies = [ "clickhouse-derive", "clickhouse-rs-cityhash-sys", "futures", - "hyper", - "hyper-tls", + "hyper 0.14.29", + "hyper-tls 0.5.0", "lz4", "sealed", "serde", @@ -830,7 +864,7 @@ dependencies = [ "time", "tokio", "url", - "uuid", + "uuid 1.9.1", ] [[package]] @@ -871,9 +905,9 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] name = "combine" -version = "4.6.6" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" dependencies = [ "bytes", "futures-core", @@ -885,9 +919,9 @@ dependencies = [ [[package]] name = "concurrent-queue" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" dependencies = [ "crossbeam-utils", ] @@ -963,9 +997,9 @@ dependencies = [ [[package]] name = "crc" -version = "3.0.1" +version = "3.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" dependencies = [ "crc-catalog", ] @@ -978,9 +1012,9 @@ checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] @@ -1015,9 +1049,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crunchy" @@ -1037,9 +1071,9 @@ dependencies = [ [[package]] name = "crypto-mac" -version = "0.11.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +checksum = "25fab6889090c8133f3deb8f73ba3c65a7f456f66436fc012a1b1e272b1e103e" dependencies = [ "generic-array", "subtle", @@ -1068,24 +1102,24 @@ dependencies = [ [[package]] name = "curl" -version = "0.4.44" +version = "0.4.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "509bd11746c7ac09ebd19f0b17782eae80aadee26237658a6b4808afb5c11a22" +checksum = "1e2161dd6eba090ff1594084e95fd67aeccf04382ffea77999ea94ed42ec67b6" dependencies = [ "curl-sys", "libc", "openssl-probe", "openssl-sys", "schannel", - "socket2 0.4.10", - "winapi", + "socket2 0.5.7", + "windows-sys 0.52.0", ] [[package]] name = "curl-sys" -version = "0.4.70+curl-8.5.0" +version = "0.4.73+curl-8.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c0333d8849afe78a4c8102a429a446bfdd055832af071945520e835ae2d841e" +checksum = "450ab250ecf17227c39afb9a2dd9261dc0035cb80f2612472fc0c4aac2dcb84d" dependencies = [ "cc", "libc", @@ -1094,7 +1128,7 @@ dependencies = [ "openssl-sys", "pkg-config", "vcpkg", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1109,12 +1143,12 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.3" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" dependencies = [ - "darling_core 0.20.3", - "darling_macro 0.20.3", + "darling_core 0.20.9", + "darling_macro 0.20.9", ] [[package]] @@ -1127,22 +1161,22 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim", + "strsim 0.10.0", "syn 1.0.109", ] [[package]] name = "darling_core" -version = "0.20.3" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "strsim", - "syn 2.0.48", + "strsim 0.11.1", + "syn 2.0.68", ] [[package]] @@ -1158,13 +1192,13 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.20.3" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" dependencies = [ - "darling_core 0.20.3", + "darling_core 0.20.9", "quote", - "syn 2.0.48", + "syn 2.0.68", ] [[package]] @@ -1174,7 +1208,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "lock_api", "once_cell", "parking_lot_core", @@ -1204,9 +1238,9 @@ dependencies = [ [[package]] name = "deadpool-runtime" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63dfa964fe2a66f3fde91fc70b267fe193d822c7e603e2a675a49a7f46ad3f49" +checksum = "092966b41edc516079bdf31ec78a2e0588d1d0c08f78b91d8307215928642b2b" dependencies = [ "tokio", ] @@ -1218,14 +1252,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" dependencies = [ "serde", - "uuid", + "uuid 1.9.1", ] [[package]] name = "der" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", "pem-rfc7468", @@ -1250,7 +1284,7 @@ checksum = "d150dea618e920167e5973d70ae6ece4385b7164e0d799fe7c122dd0a5d912ad" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.68", ] [[package]] @@ -1286,15 +1320,15 @@ dependencies = [ [[package]] name = "derive_more" -version = "0.99.17" +version = "0.99.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" dependencies = [ "convert_case 0.4.0", "proc-macro2", "quote", "rustc_version", - "syn 1.0.109", + "syn 2.0.68", ] [[package]] @@ -1373,20 +1407,20 @@ checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" [[package]] name = "either" -version = "1.9.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" dependencies = [ "serde", ] [[package]] name = "email-encoding" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbfb21b9878cf7a348dcb8559109aabc0ec40d69924bd706fa5149846c4fef75" +checksum = "60d1d33cdaede7e24091f039632eb5d3c7469fe5b066a985281a34fc70fa317f" dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "memchr", ] @@ -1404,18 +1438,18 @@ checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" dependencies = [ "cfg-if", ] [[package]] name = "env_logger" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" dependencies = [ "humantime", "is-terminal", @@ -1432,9 +1466,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -1459,9 +1493,9 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "exr" -version = "1.71.0" +version = "1.72.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "832a761f35ab3e6664babfbdc6cef35a4860e816ec3916dcfd0882954e98a8a8" +checksum = "887d93f60543e9a9362ef8a21beedd0a833c5d9610e18c67abe15a5963dcb1a4" dependencies = [ "bit_field", "flume", @@ -1494,15 +1528,15 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "fdeflate" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "209098dd6dfc4445aa6111f0e98653ac323eaa4dfd212c9ca3931bf9955c31bd" +checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645" dependencies = [ "simd-adler32", ] @@ -1515,7 +1549,7 @@ checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.4.1", "windows-sys 0.52.0", ] @@ -1531,22 +1565,25 @@ dependencies = [ "winapi", ] -[[package]] -name = "finl_unicode" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" - [[package]] name = "flate2" -version = "1.0.28" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" dependencies = [ "crc32fast", "miniz_oxide", ] +[[package]] +name = "fluent-uri" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17c704e9dbe1ddd863da1e6ff3567795087b1eb201ce80d8fa81162e1516500d" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "flume" version = "0.11.0" @@ -1588,12 +1625,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "fs_extra" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" - [[package]] name = "funty" version = "2.0.0" @@ -1682,7 +1713,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.68", ] [[package]] @@ -1699,9 +1730,9 @@ checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-timer" -version = "3.0.2" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" [[package]] name = "futures-util" @@ -1733,20 +1764,31 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", ] [[package]] name = "gif" -version = "0.12.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80792593675e051cf94a4b111980da2ba60d4a83e43e0048c5693baab3977045" +checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2" dependencies = [ "color_quant", "weezl", @@ -1754,9 +1796,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" [[package]] name = "governor" @@ -1773,24 +1815,24 @@ dependencies = [ "parking_lot", "portable-atomic", "quanta", - "rand", + "rand 0.8.5", "smallvec", "spinning_top", ] [[package]] name = "h2" -version = "0.3.23" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b553656127a00601c8ae5590fcfdc118e4083a7924b6cf4ffc1ea4b99dc429d7" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ "bytes", "fnv", "futures-core", "futures-sink", "futures-util", - "http", - "indexmap 2.1.0", + "http 0.2.12", + "indexmap 2.2.6", "slab", "tokio", "tokio-util", @@ -1799,10 +1841,11 @@ dependencies = [ [[package]] name = "half" -version = "2.2.1" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b4af3693f1b705df946e9fe5631932443781d0aabb423b62fcd4d73f6d2fd0" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" dependencies = [ + "cfg-if", "crunchy", ] @@ -1812,16 +1855,16 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "ahash 0.7.7", + "ahash 0.7.8", ] [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ - "ahash 0.8.7", + "ahash 0.8.11", "allocator-api2", ] @@ -1831,7 +1874,7 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" dependencies = [ - "hashbrown 0.14.3", + "hashbrown 0.14.5", ] [[package]] @@ -1852,11 +1895,17 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" -version = "0.3.3" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hex" @@ -1903,20 +1952,31 @@ dependencies = [ [[package]] name = "hostname" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +checksum = "f9c7c7c8ac16c798734b8a24560c1362120597c40d5e1459f09498f8f6c8f2ba" dependencies = [ + "cfg-if", "libc", - "match_cfg", - "winapi", + "windows", +] + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", ] [[package]] name = "http" -version = "0.2.11" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes", "fnv", @@ -1930,7 +1990,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", - "http", + "http 0.2.12", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +dependencies = [ + "bytes", + "http 1.1.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", "pin-project-lite", ] @@ -1940,11 +2023,32 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573" +[[package]] +name = "http-types" +version = "2.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e9b187a72d63adbfba487f48095306ac823049cb504ee195541e91c7775f5ad" +dependencies = [ + "anyhow", + "async-channel", + "base64 0.13.1", + "futures-lite", + "http 0.2.12", + "infer", + "pin-project-lite", + "rand 0.7.3", + "serde", + "serde_json", + "serde_qs 0.8.5", + "serde_urlencoded", + "url", +] + [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" [[package]] name = "httpdate" @@ -1960,28 +2064,63 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.28" +version = "0.14.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +checksum = "f361cde2f109281a220d4307746cdfd5ee3f410da58a70377762396775634b33" dependencies = [ "bytes", "futures-channel", "futures-core", "futures-util", "h2", - "http", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "httparse", "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.5", + "socket2 0.5.7", "tokio", "tower-service", "tracing", "want", ] +[[package]] +name = "hyper" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4fe55fb7a772d59a5ff1dfbff4fe0258d19b89fec4b233e75d35d5d2316badc" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http 0.2.12", + "hyper 0.14.29", + "log", + "rustls", + "rustls-native-certs", + "tokio", + "tokio-rustls", +] + [[package]] name = "hyper-tls" version = "0.5.0" @@ -1989,17 +2128,53 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes", - "hyper", + "hyper 0.14.29", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper 1.4.0", + "hyper-util", "native-tls", "tokio", "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ab92f4f49ee4fb4f997c784b7a2e0fa70050211e0b6a287f898c3c9785ca956" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "hyper 1.4.0", + "pin-project-lite", + "socket2 0.5.7", + "tokio", + "tower", + "tower-service", + "tracing", ] [[package]] name = "iana-time-zone" -version = "0.1.59" +version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -2052,9 +2227,9 @@ checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" [[package]] name = "image" -version = "0.24.8" +version = "0.24.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "034bbe799d1909622a74d1193aa50147769440040ff36cb2baa947609b0a4e23" +checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" dependencies = [ "bytemuck", "byteorder", @@ -2081,15 +2256,21 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.1.0" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "serde", ] +[[package]] +name = "infer" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64e9829a50b42bb782c1df523f78d332fe371b10c661e78b7a3c34b0198e9fac" + [[package]] name = "inout" version = "0.1.3" @@ -2101,9 +2282,9 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ "cfg-if", ] @@ -2125,12 +2306,12 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.10" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" dependencies = [ "hermit-abi", - "rustix", + "libc", "windows-sys 0.52.0", ] @@ -2148,7 +2329,7 @@ dependencies = [ "encoding_rs", "event-listener", "futures-lite", - "http", + "http 0.2.12", "log", "mime", "once_cell", @@ -2181,44 +2362,34 @@ dependencies = [ [[package]] name = "itertools" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" dependencies = [ "either", ] [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jemalloc-sys" -version = "0.3.2" +version = "0.5.4+5.3.0-patched" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d3b9f3f5c9b31aa0f5ed3260385ac205db665baa41d49bb8338008ae94ede45" +checksum = "ac6c1946e1cea1788cbfde01c993b52a10e2da07f4bac608228d1bed20bfebf2" dependencies = [ "cc", - "fs_extra", "libc", ] [[package]] name = "jemallocator" -version = "0.3.2" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43ae63fcfc45e99ab3d1b29a46782ad679e98436c3169d15a167a1108a724b69" +checksum = "a0de374a9f8e63150e6f5e8a60cc14c668226d7a347d8aee1a45766e3c4dd3bc" dependencies = [ "jemalloc-sys", "libc", @@ -2226,9 +2397,9 @@ dependencies = [ [[package]] name = "jobserver" -version = "0.1.27" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" dependencies = [ "libc", ] @@ -2244,23 +2415,34 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.67" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] [[package]] name = "json-patch" -version = "1.2.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55ff1e1486799e3f64129f8ccad108b38290df9cd7015cd31bed17239f0789d6" +checksum = "5b1fb8864823fad91877e6caea0baca82e49e8db50f8e5c9f9a453e27d3330fc" dependencies = [ + "jsonptr", "serde", "serde_json", "thiserror", - "treediff", +] + +[[package]] +name = "jsonptr" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c6e529149475ca0b2820835d3dce8fcc41c6b943ca608d32f35b449255e4627" +dependencies = [ + "fluent-uri", + "serde", + "serde_json", ] [[package]] @@ -2288,9 +2470,10 @@ dependencies = [ "actix-web-prom", "actix-ws", "argon2", + "async-stripe", "async-trait", "base64 0.21.7", - "bitflags 2.4.1", + "bitflags 2.6.0", "bytes", "censor", "chrono", @@ -2308,10 +2491,10 @@ dependencies = [ "governor", "hex", "hmac 0.11.0", - "hyper", - "hyper-tls", + "hyper 0.14.29", + "hyper-tls 0.5.0", "image", - "itertools 0.12.0", + "itertools 0.12.1", "jemallocator", "json-patch", "lazy_static", @@ -2320,14 +2503,15 @@ dependencies = [ "maxminddb", "meilisearch-sdk", "murmur2", - "rand", - "rand_chacha", + "rand 0.8.5", + "rand_chacha 0.3.1", "redis", "regex", - "reqwest", + "reqwest 0.11.27", "rust-s3", "rust_decimal", "rust_iso3166", + "rusty-money", "sentry", "sentry-actix", "serde", @@ -2344,7 +2528,7 @@ dependencies = [ "totp-rs", "url", "urlencoding", - "uuid", + "uuid 1.9.1", "validator", "woothee", "xml-rs", @@ -2362,11 +2546,11 @@ checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" dependencies = [ - "spin 0.5.2", + "spin 0.9.8", ] [[package]] @@ -2377,15 +2561,15 @@ checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" [[package]] name = "lettre" -version = "0.11.3" +version = "0.11.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5aaf628956b6b0852e12ac3505d20d7a12ecc1e32d5ea921f002af4a74036a5" +checksum = "1a62049a808f1c4e2356a2a380bd5f2aca3b011b0b482cf3b914ba1731426969" dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "chumsky", "email-encoding", "email_address", - "fastrand 2.0.1", + "fastrand 2.1.0", "futures-util", "hostname", "httpdate", @@ -2393,17 +2577,18 @@ dependencies = [ "mime", "native-tls", "nom", + "percent-encoding", "quoted_printable", - "socket2 0.5.5", + "socket2 0.5.7", "tokio", "url", ] [[package]] name = "libc" -version = "0.2.152" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libm" @@ -2413,9 +2598,9 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "libnghttp2-sys" -version = "0.1.9+1.58.0" +version = "0.1.10+1.61.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b57e858af2798e167e709b9d969325b6d8e9d50232fcbc494d7d54f976854a64" +checksum = "959c25552127d2e1fa72f0e52548ec04fc386e827ba71a7bd01db46a447dc135" dependencies = [ "cc", "libc", @@ -2423,13 +2608,12 @@ dependencies = [ [[package]] name = "libredox" -version = "0.0.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.6.0", "libc", - "redox_syscall", ] [[package]] @@ -2445,9 +2629,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.14" +version = "1.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "295c17e837573c8c821dbaeb3cceb3d745ad082f7572191409e69cbc1b3fd050" +checksum = "c15da26e5af7e25c90b37a2d75cdbf940cf4a55316de9d84c679c9b8bfabf82e" dependencies = [ "cc", "libc", @@ -2463,9 +2647,9 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.4.12" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "local-channel" @@ -2486,9 +2670,9 @@ checksum = "4d873d7c67ce09b42110d801813efbc9364414e356be9935700d368351657487" [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -2496,9 +2680,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "lru-cache" @@ -2511,9 +2695,9 @@ dependencies = [ [[package]] name = "lz4" -version = "1.24.0" +version = "1.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e9e2dd86df36ce760a60f6ff6ad526f7ba1f14ba0356f8254fb6905e6494df1" +checksum = "d6eab492fe7f8651add23237ea56dbf11b3c4ff762ab83d40a47f11433421f91" dependencies = [ "libc", "lz4-sys", @@ -2521,20 +2705,14 @@ dependencies = [ [[package]] name = "lz4-sys" -version = "1.9.4" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57d27b317e207b10f69f5e75494119e391a96f48861ae870d1da6edac98ca900" +checksum = "e9764018d143cc854c9f17f0b907de70f14393b1f502da6375dce70f00514eb3" dependencies = [ "cc", "libc", ] -[[package]] -name = "match_cfg" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" - [[package]] name = "maxminddb" version = "0.24.0" @@ -2549,13 +2727,13 @@ dependencies = [ [[package]] name = "maybe-async" -version = "0.2.7" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f1b8c13cb1f814b634a96b2c725449fe7ed464a7b8781de8688be5ffbd3f305" +checksum = "5cf92c10c7e361d6b99666ec1c6f9805b0bea2c3bd8c78dc6fe98ac5bd78db11" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.68", ] [[package]] @@ -2606,7 +2784,7 @@ dependencies = [ "serde_json", "thiserror", "time", - "uuid", + "uuid 1.9.1", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -2615,9 +2793,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "mime" @@ -2627,9 +2805,9 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "mime_guess" -version = "2.0.4" +version = "2.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" dependencies = [ "mime", "unicase", @@ -2652,9 +2830,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", "simd-adler32", @@ -2662,13 +2840,13 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", "log", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.48.0", ] @@ -2680,11 +2858,10 @@ checksum = "fb585ade2549a017db2e35978b77c319214fa4b37cede841e27954dd6e8f3ca8" [[package]] name = "native-tls" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" dependencies = [ - "lazy_static", "libc", "log", "openssl", @@ -2696,17 +2873,6 @@ dependencies = [ "tempfile", ] -[[package]] -name = "nix" -version = "0.27.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" -dependencies = [ - "bitflags 2.4.1", - "cfg-if", - "libc", -] - [[package]] name = "no-std-compat" version = "0.4.1" @@ -2741,26 +2907,31 @@ dependencies = [ "num-integer", "num-iter", "num-traits", - "rand", + "rand 0.8.5", "smallvec", "zeroize", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-integer" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-iter" -version = "0.1.43" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" dependencies = [ "autocfg", "num-integer", @@ -2769,9 +2940,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", "libm", @@ -2789,9 +2960,9 @@ dependencies = [ [[package]] name = "object" -version = "0.32.2" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce" dependencies = [ "memchr", ] @@ -2810,17 +2981,17 @@ checksum = "44d11de466f4a3006fe8a5e7ec84e93b79c70cb992ae0aa0eb631ad2df8abfe2" [[package]] name = "opaque-debug" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.62" +version = "0.10.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cde4d2d9200ad5909f8dac647e29482e07c3a35de8a13fce7c9c7747ad9f671" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.6.0", "cfg-if", "foreign-types", "libc", @@ -2837,7 +3008,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.68", ] [[package]] @@ -2848,9 +3019,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.98" +version = "0.9.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1665caf8ab2dc9aef43d1c0023bd904633a6a05cb30b0ad59bec2ae986e57a7" +checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" dependencies = [ "cc", "libc", @@ -2870,13 +3041,13 @@ dependencies = [ [[package]] name = "os_info" -version = "3.7.0" +version = "3.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "006e42d5b888366f1880eda20371fedde764ed2213dc8496f49622fa0c99cd5e" +checksum = "ae99c7fa6dd38c7cafe1ec085e804f8f555a2f8659b0dbe03f1f9963a9b51092" dependencies = [ "log", "serde", - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -2887,9 +3058,9 @@ checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -2897,15 +3068,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.5.2", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.5", ] [[package]] @@ -2921,7 +3092,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" dependencies = [ "base64ct", - "rand_core", + "rand_core 0.6.4", "subtle", ] @@ -2932,15 +3103,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" dependencies = [ "base64ct", - "rand_core", + "rand_core 0.6.4", "subtle", ] [[package]] name = "paste" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "pbkdf2" @@ -2986,7 +3157,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" dependencies = [ "phf_shared", - "rand", + "rand 0.8.5", ] [[package]] @@ -2999,7 +3170,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.68", ] [[package]] @@ -3013,17 +3184,17 @@ dependencies = [ [[package]] name = "phonenumber" -version = "0.3.3+8.13.9" +version = "0.3.6+8.13.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "635f3e6288e4f01c049d89332a031bd74f25d64b6fb94703ca966e819488cd06" +checksum = "11756237b57b8cc5e97dc8b1e70ea436324d30e7075de63b14fd15073a8f692a" dependencies = [ "bincode", "either", "fnv", - "itertools 0.11.0", + "itertools 0.12.1", "lazy_static", "nom", - "quick-xml 0.28.2", + "quick-xml 0.31.0", "regex", "regex-cache", "serde", @@ -3034,29 +3205,29 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.68", ] [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -3087,15 +3258,15 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "png" -version = "0.17.11" +version = "0.17.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f6c3c3e617595665b8ea2ff95a86066be38fb121ff920a9c0eb282abcd1da5a" +checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1" dependencies = [ "bitflags 1.3.2", "crc32fast", @@ -3154,9 +3325,9 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.0.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b2685dd208a3771337d8d386a89840f0f43cd68be8dae90a5f8c2384effc9cd" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" dependencies = [ "toml_edit", ] @@ -3187,24 +3358,49 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.76" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] +[[package]] +name = "procfs" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "731e0d9356b0c25f16f33b5be79b1c57b562f141ebfcdb0ad8ac2c13a24293b4" +dependencies = [ + "bitflags 2.6.0", + "hex", + "lazy_static", + "procfs-core", + "rustix", +] + +[[package]] +name = "procfs-core" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d3554923a69f4ce04c4a754260c338f505ce22642d3830e049a399fc2059a29" +dependencies = [ + "bitflags 2.6.0", + "hex", +] + [[package]] name = "prometheus" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "449811d15fbdf5ceb5c1144416066429cf82316e2ec8ce0c1f6f8a02e7bbcf8c" +checksum = "3d33c28a30771f7f96db69893f78b857f7450d7e0237e9c8fc6427a81bae7ed1" dependencies = [ "cfg-if", "fnv", "lazy_static", + "libc", "memchr", "parking_lot", + "procfs", "thiserror", ] @@ -3248,15 +3444,15 @@ dependencies = [ [[package]] name = "quanta" -version = "0.12.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ca0b7bac0b97248c40bb77288fc52029cf1459c0461ea1b05ee32ccf011de2c" +checksum = "8e5167a477619228a0b284fac2674e3c388cba90631d7b7de620e6f1fcd08da5" dependencies = [ "crossbeam-utils", "libc", "once_cell", "raw-cpuid", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "web-sys", "winapi", ] @@ -3279,18 +3475,18 @@ dependencies = [ [[package]] name = "quick-xml" -version = "0.28.2" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce5e73202a820a31f8a0ee32ada5e21029c81fd9e3ebf668a40832e4219d9d1" +checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" dependencies = [ "memchr", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -3318,6 +3514,19 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", +] + [[package]] name = "rand" version = "0.8.5" @@ -3325,8 +3534,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", ] [[package]] @@ -3336,7 +3555,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", ] [[package]] @@ -3345,23 +3573,32 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.15", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", ] [[package]] name = "raw-cpuid" -version = "11.0.1" +version = "11.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d86a7c4638d42c44551f4791a20e687dbb4c3de1f33c43dd71e355cd429def1" +checksum = "e29830cbb1290e404f24c73af91c5d8d631ce7e128691e9477556b540cd01ecd" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.6.0", ] [[package]] name = "rayon" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -3369,9 +3606,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -3383,7 +3620,7 @@ version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c580d9cbbe1d1b479e8d67cf9daf6a62c957e6846048408b80b43ac3f6af84cd" dependencies = [ - "ahash 0.8.7", + "ahash 0.8.11", "async-trait", "bytes", "combine", @@ -3409,38 +3646,47 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_syscall" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" +dependencies = [ + "bitflags 2.6.0", +] + [[package]] name = "redox_users" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" dependencies = [ - "getrandom", + "getrandom 0.2.15", "libredox", "thiserror", ] [[package]] name = "regex" -version = "1.10.2" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", "regex-automata", - "regex-syntax 0.8.2", + "regex-syntax 0.8.4", ] [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.2", + "regex-syntax 0.8.4", ] [[package]] @@ -3455,6 +3701,12 @@ dependencies = [ "regex-syntax 0.6.29", ] +[[package]] +name = "regex-lite" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" + [[package]] name = "regex-syntax" version = "0.6.29" @@ -3463,24 +3715,24 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "rend" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2571463863a6bd50c32f94402933f03457a3fbaf697a707c5be741e459f08fd" +checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" dependencies = [ "bytecheck", ] [[package]] name = "reqwest" -version = "0.11.23" +version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ "base64 0.21.7", "bytes", @@ -3488,10 +3740,10 @@ dependencies = [ "futures-core", "futures-util", "h2", - "http", - "http-body", - "hyper", - "hyper-tls", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.29", + "hyper-tls 0.5.0", "ipnet", "js-sys", "log", @@ -3501,9 +3753,11 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", + "rustls-pemfile 1.0.4", "serde", "serde_json", "serde_urlencoded", + "sync_wrapper 0.1.2", "system-configuration", "tokio", "tokio-native-tls", @@ -3514,14 +3768,54 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "winreg", + "winreg 0.50.0", +] + +[[package]] +name = "reqwest" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "http-body-util", + "hyper 1.4.0", + "hyper-tls 0.6.0", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile 2.1.2", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper 1.0.1", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg 0.52.0", ] [[package]] name = "rgb" -version = "0.8.37" +version = "0.8.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05aaa8004b64fd573fc9d002f4e632d51ad4f026c2b5ba95fcb6c2f32c2c47d8" +checksum = "a7439be6844e40133eda024efd85bf07f59d0dd2f59b10c00dd6cfb92cc5c741" dependencies = [ "bytemuck", ] @@ -3543,23 +3837,24 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.7" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", - "getrandom", + "cfg-if", + "getrandom 0.2.15", "libc", "spin 0.9.8", "untrusted 0.9.0", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "rkyv" -version = "0.7.43" +version = "0.7.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "527a97cdfef66f65998b5f3b637c26f5a5ec09cc52a3f9932313ac645f4190f5" +checksum = "5cba464629b3394fc4dbc6f940ff8f5b4ff5c7aef40f29166fd4ad12acbc99c0" dependencies = [ "bitvec", "bytecheck", @@ -3570,14 +3865,14 @@ dependencies = [ "rkyv_derive", "seahash", "tinyvec", - "uuid", + "uuid 1.9.1", ] [[package]] name = "rkyv_derive" -version = "0.7.43" +version = "0.7.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5c462a1328c8e67e4d6dbad1eb0355dd43e8ab432c6e227a43657f16ade5033" +checksum = "a7dddfff8de25e6f62b9d64e6e432bf1c6736c57d20323e15ee10435fbda7c65" dependencies = [ "proc-macro2", "quote", @@ -3597,7 +3892,7 @@ dependencies = [ "num-traits", "pkcs1", "pkcs8", - "rand_core", + "rand_core 0.6.4", "signature", "spki", "subtle", @@ -3629,14 +3924,14 @@ dependencies = [ "futures", "hex", "hmac 0.12.1", - "http", + "http 0.2.12", "log", "maybe-async", "md5", "minidom", "percent-encoding", "quick-xml 0.26.0", - "reqwest", + "reqwest 0.11.27", "serde", "serde_derive", "sha2 0.10.8", @@ -3649,25 +3944,35 @@ dependencies = [ [[package]] name = "rust_decimal" -version = "1.33.1" +version = "1.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06676aec5ccb8fc1da723cc8c0f9a46549f21ebb8753d3915c6c41db1e7f1dc4" +checksum = "1790d1c4c0ca81211399e0e0af16333276f375209e71a37b67698a373db5b47a" dependencies = [ "arrayvec", "borsh", "bytes", "num-traits", - "rand", + "rand 0.8.5", "rkyv", "serde", "serde_json", ] +[[package]] +name = "rust_decimal_macros" +version = "1.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a05bf7103af0797dbce0667c471946b29b9eaea34652eff67324f360fec027de" +dependencies = [ + "quote", + "rust_decimal", +] + [[package]] name = "rust_iso3166" -version = "0.1.11" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc46f436f726b768364d35d099f43a94f22fd34857ff4f679b1f5cbcb03b9f71" +checksum = "dd3126eab517ef8ca4761a366cb0d55e1bf5ab9c7b7f18301d712a57de000a90" dependencies = [ "js-sys", "phf", @@ -3677,9 +3982,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc_version" @@ -3692,11 +3997,11 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.30" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", @@ -3705,15 +4010,28 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.10" +version = "0.21.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ - "ring 0.17.7", + "log", + "ring 0.17.8", "rustls-webpki", "sct", ] +[[package]] +name = "rustls-native-certs" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +dependencies = [ + "openssl-probe", + "rustls-pemfile 1.0.4", + "schannel", + "security-framework", +] + [[package]] name = "rustls-pemfile" version = "1.0.4" @@ -3723,21 +4041,47 @@ dependencies = [ "base64 0.21.7", ] +[[package]] +name = "rustls-pemfile" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" +dependencies = [ + "base64 0.22.1", + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" + [[package]] name = "rustls-webpki" version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring 0.17.7", + "ring 0.17.8", "untrusted 0.9.0", ] [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" + +[[package]] +name = "rusty-money" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "5b28f881005eac7ad8d46b6f075da5f322bd7f4f83a38720fc069694ddadd683" +dependencies = [ + "rust_decimal", + "rust_decimal_macros", +] [[package]] name = "rxml" @@ -3758,9 +4102,9 @@ checksum = "22a197350ece202f19a166d1ad6d9d6de145e1d2a8ef47db299abe164dbd7530" [[package]] name = "ryu" -version = "1.0.16" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "schannel" @@ -3792,7 +4136,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring 0.17.7", + "ring 0.17.8", "untrusted 0.9.0", ] @@ -3816,11 +4160,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.9.2" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", "core-foundation", "core-foundation-sys", "libc", @@ -3829,9 +4173,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.1" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" dependencies = [ "core-foundation-sys", "libc", @@ -3839,19 +4183,19 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "sentry" -version = "0.32.1" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab18211f62fb890f27c9bb04861f76e4be35e4c2fcbfc2d98afa37aadebb16f1" +checksum = "00421ed8fa0c995f07cde48ba6c89e80f2b312f74ff637326f392fbfd23abe02" dependencies = [ "httpdate", "native-tls", - "reqwest", + "reqwest 0.12.5", "sentry-backtrace", "sentry-contexts", "sentry-core", @@ -3864,9 +4208,9 @@ dependencies = [ [[package]] name = "sentry-actix" -version = "0.32.1" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2576f4d8380c3a5baa1f2f3796e442b6afceb178b6a6e573760e95d07dbb3dd" +checksum = "d1986312ea8425a28299262ead2483ca8f0e167994f9239848d5718041abcd49" dependencies = [ "actix-web", "futures-util", @@ -3875,9 +4219,9 @@ dependencies = [ [[package]] name = "sentry-backtrace" -version = "0.32.1" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf018ff7d5ce5b23165a9cbfee60b270a55ae219bc9eebef2a3b6039356dd7e5" +checksum = "a79194074f34b0cbe5dd33896e5928bbc6ab63a889bd9df2264af5acb186921e" dependencies = [ "backtrace", "once_cell", @@ -3887,9 +4231,9 @@ dependencies = [ [[package]] name = "sentry-contexts" -version = "0.32.1" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d934df6f9a17b8c15b829860d9d6d39e78126b5b970b365ccbd817bc0fe82c9" +checksum = "eba8870c5dba2bfd9db25c75574a11429f6b95957b0a78ac02e2970dd7a5249a" dependencies = [ "hostname", "libc", @@ -3901,12 +4245,12 @@ dependencies = [ [[package]] name = "sentry-core" -version = "0.32.1" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e362d3fb1c5de5124bf1681086eaca7adf6a8c4283a7e1545359c729f9128ff" +checksum = "46a75011ea1c0d5c46e9e57df03ce81f5c7f0a9e199086334a1f9c0a541e0826" dependencies = [ "once_cell", - "rand", + "rand 0.8.5", "sentry-types", "serde", "serde_json", @@ -3914,9 +4258,9 @@ dependencies = [ [[package]] name = "sentry-debug-images" -version = "0.32.1" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8bca420d75d9e7a8e54a4806bf4fa8a7e9a804e8f2ff05c7c80234168c6ca66" +checksum = "7ec2a486336559414ab66548da610da5e9626863c3c4ffca07d88f7dc71c8de8" dependencies = [ "findshlibs", "once_cell", @@ -3925,9 +4269,9 @@ dependencies = [ [[package]] name = "sentry-panic" -version = "0.32.1" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0224e7a8e2bd8a32d96804acb8243d6d6e073fed55618afbdabae8249a964d8" +checksum = "2eaa3ecfa3c8750c78dcfd4637cfa2598b95b52897ed184b4dc77fcf7d95060d" dependencies = [ "sentry-backtrace", "sentry-core", @@ -3935,9 +4279,9 @@ dependencies = [ [[package]] name = "sentry-tracing" -version = "0.32.1" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "087bed8c616d176a9c6b662a8155e5f23b40dc9e1fa96d0bd5fb56e8636a9275" +checksum = "f715932bf369a61b7256687c6f0554141b7ce097287e30e3f7ed6e9de82498fe" dependencies = [ "sentry-backtrace", "sentry-core", @@ -3947,39 +4291,39 @@ dependencies = [ [[package]] name = "sentry-types" -version = "0.32.1" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb4f0e37945b7a8ce7faebc310af92442e2d7c5aa7ef5b42fe6daa98ee133f65" +checksum = "4519c900ce734f7a0eb7aba0869dfb225a7af8820634a7dd51449e3b093cfb7c" dependencies = [ "debugid", "hex", - "rand", + "rand 0.8.5", "serde", "serde_json", "thiserror", "time", "url", - "uuid", + "uuid 1.9.1", ] [[package]] name = "serde" -version = "1.0.195" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.195" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.68", ] [[package]] @@ -3995,15 +4339,25 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.111" +version = "1.0.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" +checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" dependencies = [ "itoa", "ryu", "serde", ] +[[package]] +name = "serde_path_to_error" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" +dependencies = [ + "itoa", + "serde", +] + [[package]] name = "serde_plain" version = "1.0.2" @@ -4013,6 +4367,28 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_qs" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7715380eec75f029a4ef7de39a9200e0a63823176b759d055b613f5a87df6a6" +dependencies = [ + "percent-encoding", + "serde", + "thiserror", +] + +[[package]] +name = "serde_qs" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cac3f1e2ca2fe333923a1ae72caca910b98ed0630bb35ef6f8c8517d6e81afa" +dependencies = [ + "percent-encoding", + "serde", + "thiserror", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -4027,16 +4403,17 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.4.0" +version = "3.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23" +checksum = "079f3a42cd87588d924ed95b533f8d30a483388c4e400ab736a7058e34f16169" dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.1.0", + "indexmap 2.2.6", "serde", + "serde_derive", "serde_json", "serde_with_macros", "time", @@ -4044,14 +4421,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.4.0" +version = "3.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93634eb5f75a2323b16de4748022ac4297f9e76b6dced2be287a099f41b5e788" +checksum = "bc03aad67c1d26b7de277d51c86892e7d9a0110a2fe44bf6b26cc569fba302d6" dependencies = [ - "darling 0.20.3", + "darling 0.20.9", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.68", ] [[package]] @@ -4106,9 +4483,9 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] @@ -4120,7 +4497,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ "digest 0.10.7", - "rand_core", + "rand_core 0.6.4", ] [[package]] @@ -4163,9 +4540,20 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.12.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2593d31f82ead8df961d8bd23a64c2ccf2eb5dd34b0a34bfb4dd54011c72009e" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "smart-default" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "133659a15339456eeeb07572eb02a91c91e9815e9cbc89566944d2c8d3efdbf6" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] [[package]] name = "smartstring" @@ -4178,6 +4566,15 @@ dependencies = [ "version_check", ] +[[package]] +name = "smol_str" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fad6c857cbab2627dcf01ec85a623ca4e7dcb5691cbaa3d7fb7653671f0d09c9" +dependencies = [ + "serde", +] + [[package]] name = "socket2" version = "0.4.10" @@ -4190,19 +4587,19 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.5" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "spdx" -version = "0.10.3" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bde1398b09b9f93fc2fc9b9da86e362693e999d3a54a8ac47a99a5a73f638b" +checksum = "47317bbaf63785b53861e1ae2d11b80d6b624211d42cb20efcd210ee6f8a14bc" dependencies = [ "smallvec", ] @@ -4243,20 +4640,19 @@ dependencies = [ [[package]] name = "sqlformat" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce81b7bd7c4493975347ef60d8c7e8b742d4694f4c49f93e0a12ea263938176c" +checksum = "f895e3734318cc55f1fe66258926c9b910c124d47520339efecbb6c59cec7c1f" dependencies = [ - "itertools 0.12.0", "nom", "unicode_categories", ] [[package]] name = "sqlx" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dba03c279da73694ef99763320dea58b51095dfe87d001b1d4b5fe78ba8763cf" +checksum = "c9a2ccff1a000a5a59cd33da541d9f2fdcd9e6e8229cc200565942bff36d0aaa" dependencies = [ "sqlx-core", "sqlx-macros", @@ -4267,18 +4663,17 @@ dependencies = [ [[package]] name = "sqlx-core" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d84b0a3c3739e220d94b3239fd69fb1f74bc36e16643423bd99de3b43c21bfbd" +checksum = "24ba59a9342a3d9bab6c56c118be528b27c9b60e490080e9711a04dccac83ef6" dependencies = [ - "ahash 0.8.7", + "ahash 0.8.11", "atoi", "byteorder", "bytes", "chrono", "crc", "crossbeam-queue", - "dotenvy", "either", "event-listener", "futures-channel", @@ -4288,7 +4683,7 @@ dependencies = [ "futures-util", "hashlink", "hex", - "indexmap 2.1.0", + "indexmap 2.2.6", "log", "memchr", "once_cell", @@ -4296,7 +4691,7 @@ dependencies = [ "percent-encoding", "rust_decimal", "rustls", - "rustls-pemfile", + "rustls-pemfile 1.0.4", "serde", "serde_json", "sha2 0.10.8", @@ -4312,9 +4707,9 @@ dependencies = [ [[package]] name = "sqlx-macros" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89961c00dc4d7dffb7aee214964b065072bff69e36ddb9e2c107541f75e4f2a5" +checksum = "4ea40e2345eb2faa9e1e5e326db8c34711317d2b5e08d0d5741619048a803127" dependencies = [ "proc-macro2", "quote", @@ -4325,11 +4720,10 @@ dependencies = [ [[package]] name = "sqlx-macros-core" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0bd4519486723648186a08785143599760f7cc81c52334a55d6a83ea1e20841" +checksum = "5833ef53aaa16d860e92123292f1f6a3d53c34ba8b1969f152ef1a7bb803f3c8" dependencies = [ - "atomic-write-file", "dotenvy", "either", "heck 0.4.1", @@ -4352,13 +4746,13 @@ dependencies = [ [[package]] name = "sqlx-mysql" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e37195395df71fd068f6e2082247891bc11e3289624bbc776a0cdfa1ca7f1ea4" +checksum = "1ed31390216d20e538e447a7a9b959e06ed9fc51c37b514b46eb758016ecd418" dependencies = [ "atoi", "base64 0.21.7", - "bitflags 2.4.1", + "bitflags 2.6.0", "byteorder", "bytes", "chrono", @@ -4380,7 +4774,7 @@ dependencies = [ "memchr", "once_cell", "percent-encoding", - "rand", + "rand 0.8.5", "rsa", "rust_decimal", "serde", @@ -4396,13 +4790,13 @@ dependencies = [ [[package]] name = "sqlx-postgres" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6ac0ac3b7ccd10cc96c7ab29791a7dd236bd94021f31eec7ba3d46a74aa1c24" +checksum = "7c824eb80b894f926f89a0b9da0c7f435d27cdd35b8c655b114e58223918577e" dependencies = [ "atoi", "base64 0.21.7", - "bitflags 2.4.1", + "bitflags 2.6.0", "byteorder", "chrono", "crc", @@ -4421,11 +4815,10 @@ dependencies = [ "md-5", "memchr", "once_cell", - "rand", + "rand 0.8.5", "rust_decimal", "serde", "serde_json", - "sha1 0.10.6", "sha2 0.10.8", "smallvec", "sqlx-core", @@ -4437,9 +4830,9 @@ dependencies = [ [[package]] name = "sqlx-sqlite" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "210976b7d948c7ba9fced8ca835b11cbb2d677c59c79de41ac0d397e14547490" +checksum = "b244ef0a8414da0bed4bb1910426e890b19e5e9bccc27ada6b797d05c55ae0aa" dependencies = [ "atoi", "chrono", @@ -4478,15 +4871,21 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "strfmt" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a8348af2d9fc3258c8733b8d9d8db2e56f54b2363a4b5b81585c7875ed65e65" + [[package]] name = "stringprep" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb41d74e231a107a1b4ee36bd1214b11285b77768d2e3824aedafa988fd36ee6" +checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" dependencies = [ - "finl_unicode", "unicode-bidi", "unicode-normalization", + "unicode-properties", ] [[package]] @@ -4495,33 +4894,39 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "strum" -version = "0.24.1" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" dependencies = [ "strum_macros", ] [[package]] name = "strum_macros" -version = "0.24.3" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ - "heck 0.4.1", + "heck 0.5.0", "proc-macro2", "quote", "rustversion", - "syn 1.0.109", + "syn 2.0.68", ] [[package]] name = "subtle" -version = "2.4.1" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" @@ -4536,9 +4941,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "901fa70d88b9d6c98022e23b4136f9f3e54e4662c3bc1bd1d84a42a9a0f0c1e9" dependencies = [ "proc-macro2", "quote", @@ -4554,9 +4959,21 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.68", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "sync_wrapper" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" + [[package]] name = "system-configuration" version = "0.5.1" @@ -4586,9 +5003,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tar" -version = "0.4.40" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b16afcea1f22891c49a00c751c7b63b2233284064f11a200fc624137c51e2ddb" +checksum = "cb797dad5fb5b76fcf519e702f4a589483b5ef06567f160c392832c1f5e44909" dependencies = [ "filetime", "libc", @@ -4597,13 +5014,12 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.9.0" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", - "fastrand 2.0.1", - "redox_syscall", + "fastrand 2.1.0", "rustix", "windows-sys 0.52.0", ] @@ -4630,22 +5046,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.56" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.56" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.68", ] [[package]] @@ -4661,12 +5077,13 @@ dependencies = [ [[package]] name = "time" -version = "0.3.31" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", + "num-conv", "powerfmt", "serde", "time-core", @@ -4681,18 +5098,19 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ + "num-conv", "time-core", ] [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "c55115c6fbe2d2bef26eb09ad74bde02d8255476fc0c7b515ef09fbb35742d82" dependencies = [ "tinyvec_macros", ] @@ -4705,32 +5123,31 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.35.1" +version = "1.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" +checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" dependencies = [ "backtrace", "bytes", "libc", "mio", - "num_cpus", "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.5", + "socket2 0.5.7", "tokio-macros", "windows-sys 0.48.0", ] [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.68", ] [[package]] @@ -4743,11 +5160,21 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio", +] + [[package]] name = "tokio-stream" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" dependencies = [ "futures-core", "pin-project-lite", @@ -4756,49 +5183,69 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" [[package]] name = "toml_edit" -version = "0.21.0" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.2.6", "toml_datetime", "winnow", ] [[package]] name = "totp-rs" -version = "5.4.0" +version = "5.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3504f96adf86d28e7eb16fa236a7951ec72c15ee100d1b5318e225944bc8cb" +checksum = "6c4ae9724c5888c0417d2396037ed3b60665925624766416e3e342b6ba5dbd3f" dependencies = [ "base32", "constant_time_eq 0.2.6", "hmac 0.12.1", - "rand", + "rand 0.8.5", "sha1 0.10.6", "sha2 0.10.8", ] +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + [[package]] name = "tower-service" version = "0.3.2" @@ -4825,7 +5272,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.68", ] [[package]] @@ -4857,15 +5304,6 @@ dependencies = [ "tracing-core", ] -[[package]] -name = "treediff" -version = "4.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52984d277bdf2a751072b5df30ec0377febdb02f7696d64c2d7d54630bac4303" -dependencies = [ - "serde_json", -] - [[package]] name = "try-lock" version = "0.2.5" @@ -4898,9 +5336,9 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" @@ -4910,24 +5348,30 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-properties" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4259d9d4425d9f0661581b804cb85fe66a4c631cadd8f490d1c13a35d5d9291" + [[package]] name = "unicode-segmentation" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" [[package]] name = "unicode_categories" @@ -4949,11 +5393,11 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "2.9.1" +version = "2.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8cdd25c339e200129fe4de81451814e5228c9b771d57378817d6117cc2b3f97" +checksum = "d11a831e3c0b56e438a28308e7c810799e3c118417f342d30ecec080105395cd" dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "log", "native-tls", "once_cell", @@ -4962,9 +5406,9 @@ dependencies = [ [[package]] name = "url" -version = "2.5.0" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna 0.5.0", @@ -4980,12 +5424,21 @@ checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" [[package]] name = "uuid" -version = "1.6.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" dependencies = [ - "getrandom", - "rand", + "getrandom 0.2.15", +] + +[[package]] +name = "uuid" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de17fd2f7da591098415cff336e12965a28061ddace43b59cb3c430179c9439" +dependencies = [ + "getrandom 0.2.15", + "rand 0.8.5", "serde", ] @@ -5058,9 +5511,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "waker-fn" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" +checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" [[package]] name = "want" @@ -5071,17 +5524,29 @@ dependencies = [ "try-lock", ] +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" + [[package]] name = "wasm-bindgen" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -5089,24 +5554,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.68", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.40" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" dependencies = [ "cfg-if", "js-sys", @@ -5116,9 +5581,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5126,28 +5591,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.68", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "wasm-streams" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4609d447824375f43e1ffbc051b50ad8f4b3ae8219680c94452ea05eb240ac7" +checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129" dependencies = [ "futures-util", "js-sys", @@ -5158,9 +5623,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.67" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" dependencies = [ "js-sys", "wasm-bindgen", @@ -5168,21 +5633,25 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.25.3" +version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "weezl" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" +checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" [[package]] name = "whoami" -version = "1.4.1" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50" +checksum = "a44ab49fad634e88f55bf8f9bb3abd2f27d7204172a112c7c9987e01c1c94ea9" +dependencies = [ + "redox_syscall 0.4.1", + "wasite", +] [[package]] name = "winapi" @@ -5202,11 +5671,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -5215,13 +5684,23 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core", + "windows-targets 0.52.5", +] + [[package]] name = "windows-core" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.5", ] [[package]] @@ -5239,7 +5718,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.5", ] [[package]] @@ -5259,17 +5738,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] [[package]] @@ -5280,9 +5760,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" @@ -5292,9 +5772,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" @@ -5304,9 +5784,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" @@ -5316,9 +5802,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" @@ -5328,9 +5814,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" @@ -5340,9 +5826,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" @@ -5352,15 +5838,15 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "winnow" -version = "0.5.34" +version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7cf47b659b318dccbd69cc4797a39ae128f533dce7902a1096044d1967b9c16" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" dependencies = [ "memchr", ] @@ -5375,6 +5861,16 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "winreg" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "woothee" version = "0.13.0" @@ -5396,9 +5892,9 @@ dependencies = [ [[package]] name = "xattr" -version = "1.2.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "914566e6413e7fa959cc394fb30e563ba80f3541fbd40816d4c05a0fc3f2a0f1" +checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" dependencies = [ "libc", "linux-raw-sys", @@ -5407,9 +5903,9 @@ dependencies = [ [[package]] name = "xml-rs" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a" +checksum = "791978798f0597cfc70478424c2b4fdc2b7a8024aaff78497ef00f24ef674193" [[package]] name = "yaserde" @@ -5447,29 +5943,29 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.32" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.32" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.68", ] [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" [[package]] name = "zip" @@ -5502,11 +5998,11 @@ dependencies = [ [[package]] name = "zstd" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bffb3309596d527cfcba7dfc6ed6052f1d39dfbd7c867aa2e865e4a449c10110" +checksum = "2d789b1514203a1120ad2429eae43a7bd32b90976a7bb8a05f7ec02fa88cc23a" dependencies = [ - "zstd-safe 7.0.0", + "zstd-safe 7.1.0", ] [[package]] @@ -5521,18 +6017,18 @@ dependencies = [ [[package]] name = "zstd-safe" -version = "7.0.0" +version = "7.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43747c7422e2924c11144d5229878b98180ef8b06cca4ab5af37afc8a8d8ea3e" +checksum = "1cd99b45c6bc03a018c8b8a86025678c87e55526064e38f9df301989dce7ec0a" dependencies = [ "zstd-sys", ] [[package]] name = "zstd-sys" -version = "2.0.9+zstd.1.5.5" +version = "2.0.11+zstd.1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" +checksum = "75652c55c0b6f3e6f12eb786fe1bc960396bf05a1eb3bf1f3691c3610ac2e6d4" dependencies = [ "cc", "pkg-config", diff --git a/Cargo.toml b/Cargo.toml index 092a15e1..7b59cec4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ actix-multipart = "0.6.1" actix-cors = "0.7.0" actix-ws = "0.2.5" actix-files = "0.6.5" -actix-web-prom = "0.7.0" +actix-web-prom = { version = "0.8.0", features = ["process"]} governor = "0.6.3" tokio = { version = "1.35.1", features = ["sync"] } @@ -110,7 +110,10 @@ lettre = "0.11.3" derive-new = "0.6.0" rust_iso3166 = "0.1.11" -jemallocator = {version = "0.3.2", optional = true} +jemallocator = {version = "0.5.4", optional = true} + +async-stripe = { version = "0.37.3", features = ["runtime-tokio-hyper-rustls"] } +rusty-money = "0.4.1" [dev-dependencies] actix-http = "3.4.0" diff --git a/migrations/20240702213250_subscriptions.sql b/migrations/20240702213250_subscriptions.sql new file mode 100644 index 00000000..34bc0be2 --- /dev/null +++ b/migrations/20240702213250_subscriptions.sql @@ -0,0 +1,35 @@ +ALTER TABLE users ADD COLUMN stripe_customer_id TEXT NULL; + +CREATE TABLE products ( + id bigint PRIMARY KEY, + metadata jsonb NOT NULL, + unitary BOOLEAN NOT NULL DEFAULT FALSE +); + +CREATE TABLE products_prices ( + id bigint PRIMARY KEY, + product_id bigint REFERENCES products NOT NULL, + interval jsonb NOT NULL, + -- price in smallest currency unit (cents for USD) + price int not null, + currency_code text not null +); + +CREATE TABLE users_subscriptions ( + id bigint PRIMARY KEY, + user_id bigint REFERENCES users NOT NULL, + price_id bigint REFERENCES products_prices NOT NULL, + created timestamptz DEFAULT CURRENT_TIMESTAMP NOT NULL, + expires timestamptz DEFAULT CURRENT_TIMESTAMP NOT NULL, + last_charge timestamptz NULL, + status varchar(255) NOT NULL +); + +CREATE UNIQUE INDEX users_stripe_customer_id + ON users (stripe_customer_id); + +CREATE INDEX products_prices_product + ON products_prices (product_id); + +CREATE INDEX users_subscriptions_users + ON users_subscriptions (user_id); diff --git a/src/auth/mod.rs b/src/auth/mod.rs index bd7ac0ef..7ec2c3e3 100644 --- a/src/auth/mod.rs +++ b/src/auth/mod.rs @@ -3,6 +3,7 @@ pub mod email; pub mod oauth; pub mod templates; pub mod validate; +pub use crate::auth::email::send_email; pub use checks::{ filter_enlisted_projects_ids, filter_enlisted_version_ids, filter_visible_collections, filter_visible_project_ids, filter_visible_projects, diff --git a/src/auth/validate.rs b/src/auth/validate.rs index 4bfd404b..bf0f1893 100644 --- a/src/auth/validate.rs +++ b/src/auth/validate.rs @@ -6,9 +6,9 @@ use crate::models::pats::Scopes; use crate::models::users::{Role, User, UserId, UserPayoutData}; use crate::queue::session::AuthQueue; use crate::routes::internal::session::get_session_metadata; +use actix_web::http::header::{HeaderValue, AUTHORIZATION}; use actix_web::HttpRequest; use chrono::Utc; -use reqwest::header::{HeaderValue, AUTHORIZATION}; pub async fn get_user_from_headers<'a, E>( req: &HttpRequest, @@ -69,6 +69,7 @@ where venmo_handle: db_user.venmo_handle, balance: db_user.balance, }), + stripe_customer_id: db_user.stripe_customer_id, }; if let Some(required_scopes) = required_scopes { diff --git a/src/database/models/ids.rs b/src/database/models/ids.rs index 1adfac19..fd85a64c 100644 --- a/src/database/models/ids.rs +++ b/src/database/models/ids.rs @@ -232,6 +232,30 @@ generate_ids!( PayoutId ); +generate_ids!( + pub generate_product_id, + ProductId, + 8, + "SELECT EXISTS(SELECT 1 FROM products WHERE id=$1)", + ProductId +); + +generate_ids!( + pub generate_product_price_id, + ProductPriceId, + 8, + "SELECT EXISTS(SELECT 1 FROM products_prices WHERE id=$1)", + ProductPriceId +); + +generate_ids!( + pub generate_user_subscription_id, + UserSubscriptionId, + 8, + "SELECT EXISTS(SELECT 1 FROM users_subscriptions WHERE id=$1)", + UserSubscriptionId +); + #[derive(Copy, Clone, Debug, PartialEq, Eq, Type, Hash, Serialize, Deserialize)] #[sqlx(transparent)] pub struct UserId(pub i64); @@ -351,6 +375,17 @@ pub struct OAuthAccessTokenId(pub i64); #[sqlx(transparent)] pub struct PayoutId(pub i64); +#[derive(Copy, Clone, Debug, Type, Serialize, Deserialize, Eq, PartialEq, Hash)] +#[sqlx(transparent)] +pub struct ProductId(pub i64); +#[derive(Copy, Clone, Debug, Type, Serialize, Deserialize, Eq, PartialEq, Hash)] +#[sqlx(transparent)] +pub struct ProductPriceId(pub i64); + +#[derive(Copy, Clone, Debug, Type, Serialize, Deserialize, Eq, PartialEq, Hash)] +#[sqlx(transparent)] +pub struct UserSubscriptionId(pub i64); + use crate::models::ids; impl From for ProjectId { @@ -504,3 +539,35 @@ impl From for ids::PayoutId { ids::PayoutId(id.0 as u64) } } + +impl From for ProductId { + fn from(id: ids::ProductId) -> Self { + ProductId(id.0 as i64) + } +} +impl From for ids::ProductId { + fn from(id: ProductId) -> Self { + ids::ProductId(id.0 as u64) + } +} +impl From for ProductPriceId { + fn from(id: ids::ProductPriceId) -> Self { + ProductPriceId(id.0 as i64) + } +} +impl From for ids::ProductPriceId { + fn from(id: ProductPriceId) -> Self { + ids::ProductPriceId(id.0 as u64) + } +} + +impl From for UserSubscriptionId { + fn from(id: ids::UserSubscriptionId) -> Self { + UserSubscriptionId(id.0 as i64) + } +} +impl From for ids::UserSubscriptionId { + fn from(id: UserSubscriptionId) -> Self { + ids::UserSubscriptionId(id.0 as u64) + } +} diff --git a/src/database/models/mod.rs b/src/database/models/mod.rs index eafde1b4..51dafed6 100644 --- a/src/database/models/mod.rs +++ b/src/database/models/mod.rs @@ -14,12 +14,14 @@ pub mod oauth_token_item; pub mod organization_item; pub mod pat_item; pub mod payout_item; +pub mod product_item; pub mod project_item; pub mod report_item; pub mod session_item; pub mod team_item; pub mod thread_item; pub mod user_item; +pub mod user_subscription_item; pub mod version_item; pub use collection_item::Collection; diff --git a/src/database/models/product_item.rs b/src/database/models/product_item.rs new file mode 100644 index 00000000..2ff0b0c7 --- /dev/null +++ b/src/database/models/product_item.rs @@ -0,0 +1,187 @@ +use crate::database::models::{DatabaseError, ProductId, ProductPriceId}; +use crate::models::billing::{PriceInterval, ProductMetadata}; +use dashmap::DashMap; +use itertools::Itertools; +use std::convert::TryFrom; +use std::convert::TryInto; + +pub struct ProductItem { + pub id: ProductId, + pub metadata: ProductMetadata, + pub unitary: bool, +} + +struct ProductResult { + id: i64, + metadata: serde_json::Value, + unitary: bool, +} + +macro_rules! select_products_with_predicate { + ($predicate:tt, $param:ident) => { + sqlx::query_as!( + ProductResult, + r#" + SELECT id, metadata, unitary + FROM products + "# + + $predicate, + $param + ) + }; +} + +impl TryFrom for ProductItem { + type Error = serde_json::Error; + + fn try_from(r: ProductResult) -> Result { + Ok(ProductItem { + id: ProductId(r.id), + metadata: serde_json::from_value(r.metadata)?, + unitary: r.unitary, + }) + } +} + +impl ProductItem { + pub async fn get( + id: ProductId, + exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + ) -> Result, DatabaseError> { + Ok(Self::get_many(&[id], exec).await?.into_iter().next()) + } + + pub async fn get_many( + ids: &[ProductId], + exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + ) -> Result, DatabaseError> { + let ids = ids.iter().map(|id| id.0).collect_vec(); + let ids_ref: &[i64] = &ids; + let results = select_products_with_predicate!("WHERE id = ANY($1::bigint[])", ids_ref) + .fetch_all(exec) + .await?; + + Ok(results + .into_iter() + .map(|r| r.try_into()) + .collect::, serde_json::Error>>()?) + } + + pub async fn get_all( + exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + ) -> Result, DatabaseError> { + let one = 1; + let results = select_products_with_predicate!("WHERE 1 = $1", one) + .fetch_all(exec) + .await?; + + Ok(results + .into_iter() + .map(|r| r.try_into()) + .collect::, serde_json::Error>>()?) + } +} + +pub struct ProductPriceItem { + pub id: ProductPriceId, + pub product_id: ProductId, + pub interval: PriceInterval, + pub price: i32, + pub currency_code: String, +} + +struct ProductPriceResult { + id: i64, + product_id: i64, + interval: serde_json::Value, + price: i32, + currency_code: String, +} + +macro_rules! select_prices_with_predicate { + ($predicate:tt, $param:ident) => { + sqlx::query_as!( + ProductPriceResult, + r#" + SELECT id, product_id, interval, price, currency_code + FROM products_prices + "# + + $predicate, + $param + ) + }; +} + +impl TryFrom for ProductPriceItem { + type Error = serde_json::Error; + + fn try_from(r: ProductPriceResult) -> Result { + Ok(ProductPriceItem { + id: ProductPriceId(r.id), + product_id: ProductId(r.product_id), + interval: serde_json::from_value(r.interval)?, + price: r.price, + currency_code: r.currency_code, + }) + } +} + +impl ProductPriceItem { + pub async fn get( + id: ProductPriceId, + exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + ) -> Result, DatabaseError> { + Ok(Self::get_many(&[id], exec).await?.into_iter().next()) + } + + pub async fn get_many( + ids: &[ProductPriceId], + exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + ) -> Result, DatabaseError> { + let ids = ids.iter().map(|id| id.0).collect_vec(); + let ids_ref: &[i64] = &ids; + let results = select_prices_with_predicate!("WHERE id = ANY($1::bigint[])", ids_ref) + .fetch_all(exec) + .await?; + + Ok(results + .into_iter() + .map(|r| r.try_into()) + .collect::, serde_json::Error>>()?) + } + + pub async fn get_all_product_prices( + product_id: ProductId, + exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + ) -> Result, DatabaseError> { + let res = Self::get_all_products_prices(&[product_id], exec).await?; + + Ok(res.remove(&product_id).map(|x| x.1).unwrap_or_default()) + } + + pub async fn get_all_products_prices( + product_ids: &[ProductId], + exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + ) -> Result>, DatabaseError> { + let ids = product_ids.iter().map(|id| id.0).collect_vec(); + let ids_ref: &[i64] = &ids; + + use futures_util::TryStreamExt; + let prices = select_prices_with_predicate!("WHERE product_id = ANY($1::bigint[])", ids_ref) + .fetch(exec) + .try_fold( + DashMap::new(), + |acc: DashMap>, x| { + if let Ok(item) = >::try_into(x) + { + acc.entry(item.product_id).or_default().push(item); + } + + async move { Ok(acc) } + }, + ) + .await?; + + Ok(prices) + } +} diff --git a/src/database/models/user_item.rs b/src/database/models/user_item.rs index bc4c1b85..134e6ffa 100644 --- a/src/database/models/user_item.rs +++ b/src/database/models/user_item.rs @@ -32,6 +32,7 @@ pub struct User { pub paypal_country: Option, pub paypal_email: Option, pub venmo_handle: Option, + pub stripe_customer_id: Option, pub totp_secret: Option, @@ -60,13 +61,13 @@ impl User { avatar_url, bio, created, github_id, discord_id, gitlab_id, google_id, steam_id, microsoft_id, email_verified, password, paypal_id, paypal_country, paypal_email, - venmo_handle + venmo_handle, stripe_customer_id ) VALUES ( $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, - $14, $15, $16, $17, $18, $19 + $14, $15, $16, $17, $18, $19, $20 ) ", self.id as UserId, @@ -87,7 +88,8 @@ impl User { self.paypal_id, self.paypal_country, self.paypal_email, - self.venmo_handle + self.venmo_handle, + self.stripe_customer_id ) .execute(&mut **transaction) .await?; @@ -170,7 +172,7 @@ impl User { balance, github_id, discord_id, gitlab_id, google_id, steam_id, microsoft_id, email_verified, password, totp_secret, paypal_id, paypal_country, paypal_email, - venmo_handle + venmo_handle, stripe_customer_id FROM users WHERE id = ANY($1) OR LOWER(username) = ANY($2) ", @@ -202,6 +204,7 @@ impl User { paypal_country: u.paypal_country, paypal_email: u.paypal_email, venmo_handle: u.venmo_handle, + stripe_customer_id: u.stripe_customer_id, totp_secret: u.totp_secret, }; diff --git a/src/database/models/user_subscription_item.rs b/src/database/models/user_subscription_item.rs new file mode 100644 index 00000000..1c5844c0 --- /dev/null +++ b/src/database/models/user_subscription_item.rs @@ -0,0 +1,120 @@ +use crate::database::models::{DatabaseError, ProductPriceId, UserId, UserSubscriptionId}; +use crate::models::billing::SubscriptionStatus; +use chrono::{DateTime, Utc}; +use itertools::Itertools; + +pub struct UserSubscriptionItem { + pub id: UserSubscriptionId, + pub user_id: UserId, + pub price_id: ProductPriceId, + pub created: DateTime, + pub expires: DateTime, + pub last_charge: Option>, + pub status: SubscriptionStatus, +} + +struct UserSubscriptionResult { + id: i64, + user_id: i64, + price_id: i64, + pub created: DateTime, + pub expires: DateTime, + pub last_charge: Option>, + pub status: String, +} + +macro_rules! select_user_subscriptions_with_predicate { + ($predicate:tt, $param:ident) => { + sqlx::query_as!( + UserSubscriptionResult, + r#" + SELECT + id, user_id, price_id, created, expires, last_charge, status + FROM users_subscriptions + "# + + $predicate, + $param + ) + }; +} + +impl From for UserSubscriptionItem { + fn from(r: UserSubscriptionResult) -> Self { + UserSubscriptionItem { + id: UserSubscriptionId(r.id), + user_id: UserId(r.user_id), + price_id: ProductPriceId(r.price_id), + created: r.created, + expires: r.expires, + last_charge: r.last_charge, + status: SubscriptionStatus::from_string(&r.status), + } + } +} + +impl UserSubscriptionItem { + pub async fn get( + id: UserSubscriptionId, + exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + ) -> Result, DatabaseError> { + Ok(Self::get_many(&[id], exec).await?.into_iter().next()) + } + + pub async fn get_many( + ids: &[UserSubscriptionId], + exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + ) -> Result, DatabaseError> { + let ids = ids.iter().map(|id| id.0).collect_vec(); + let ids_ref: &[i64] = &ids; + let results = + select_user_subscriptions_with_predicate!("WHERE id = ANY($1::bigint[])", ids_ref) + .fetch_all(exec) + .await?; + + Ok(results.into_iter().map(|r| r.into()).collect()) + } + + pub async fn get_all_user( + user_id: UserId, + exec: impl sqlx::Executor<'_, Database = sqlx::Postgres>, + ) -> Result, DatabaseError> { + let user_id = user_id.0; + let results = select_user_subscriptions_with_predicate!("WHERE user_id = $1", user_id) + .fetch_all(exec) + .await?; + + Ok(results.into_iter().map(|r| r.into()).collect()) + } + + pub async fn upsert( + &self, + transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + ) -> Result<(), DatabaseError> { + sqlx::query!( + " + INSERT INTO users_subscriptions ( + id, user_id, price_id, created, expires, last_charge, status + ) + VALUES ( + $1, $2, $3, $4, $5, $6, $7 + ) + ON CONFLICT (id) + DO UPDATE + SET expires = EXCLUDED.expires, + last_charge = EXCLUDED.last_charge, + status = EXCLUDED.status + ", + self.id.0, + self.user_id.0, + self.price_id.0, + self.created, + self.expires, + self.last_charge, + self.status.as_str(), + ) + .execute(&mut **transaction) + .await?; + + Ok(()) + } +} diff --git a/src/lib.rs b/src/lib.rs index 248de49a..ca6151c2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -58,6 +58,7 @@ pub struct LabrinthConfig { pub active_sockets: web::Data>, pub automated_moderation_queue: web::Data, pub rate_limiter: KeyedRateLimiter, + pub stripe_client: stripe::Client, } pub fn app_setup( @@ -257,6 +258,24 @@ pub fn app_setup( }); } + { + let pool_ref = pool.clone(); + let redis_ref = redis_pool.clone(); + scheduler.run(std::time::Duration::from_secs(60 * 30), move || { + let pool_ref = pool_ref.clone(); + let redis_ref = redis_ref.clone(); + + async move { + info!("Indexing billing queue"); + let result = crate::routes::internal::billing::task(&pool_ref, &redis_ref).await; + if let Err(e) = result { + warn!("Indexing billing queue failed: {:?}", e); + } + info!("Done indexing billing queue"); + } + }); + } + let ip_salt = Pepper { pepper: models::ids::Base62Id(models::ids::random_base62(11)).to_string(), }; @@ -264,6 +283,8 @@ pub fn app_setup( let payouts_queue = web::Data::new(PayoutsQueue::new()); let active_sockets = web::Data::new(RwLock::new(ActiveSockets::default())); + let stripe_client = stripe::Client::new(dotenvy::var("STRIPE_API_KEY").unwrap()); + LabrinthConfig { pool, redis_pool, @@ -279,6 +300,7 @@ pub fn app_setup( active_sockets, automated_moderation_queue, rate_limiter: limiter, + stripe_client, } } @@ -311,6 +333,7 @@ pub fn app_config(cfg: &mut web::ServiceConfig, labrinth_config: LabrinthConfig) .app_data(web::Data::new(labrinth_config.maxmind.clone())) .app_data(labrinth_config.active_sockets.clone()) .app_data(labrinth_config.automated_moderation_queue.clone()) + .app_data(web::Data::new(labrinth_config.stripe_client.clone())) .configure(routes::v2::config) .configure(routes::v3::config) .configure(routes::internal::config) @@ -416,6 +439,7 @@ pub fn check_env_vars() -> bool { failed |= check_var::("SITE_VERIFY_EMAIL_PATH"); failed |= check_var::("SITE_RESET_PASSWORD_PATH"); + failed |= check_var::("SITE_BILLING_PATH"); failed |= check_var::("BEEHIIV_PUBLICATION_ID"); failed |= check_var::("BEEHIIV_API_KEY"); @@ -438,5 +462,8 @@ pub fn check_env_vars() -> bool { failed |= check_var::("FLAME_ANVIL_URL"); + failed |= check_var::("STRIPE_API_KEY"); + failed |= check_var::("STRIPE_WEBHOOK_SECRET"); + failed } diff --git a/src/models/mod.rs b/src/models/mod.rs index b1a12c9b..aea510d7 100644 --- a/src/models/mod.rs +++ b/src/models/mod.rs @@ -3,6 +3,7 @@ pub mod v2; pub mod v3; pub use v3::analytics; +pub use v3::billing; pub use v3::collections; pub use v3::ids; pub use v3::images; diff --git a/src/models/v3/billing.rs b/src/models/v3/billing.rs new file mode 100644 index 00000000..c5d782a8 --- /dev/null +++ b/src/models/v3/billing.rs @@ -0,0 +1,104 @@ +use crate::models::ids::Base62Id; +use crate::models::ids::UserId; +use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; + +#[derive(Copy, Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] +#[serde(from = "Base62Id")] +#[serde(into = "Base62Id")] +pub struct ProductId(pub u64); + +#[derive(Serialize, Deserialize)] +pub struct Product { + pub id: ProductId, + pub metadata: ProductMetadata, + pub prices: Vec, + pub unitary: bool, +} + +#[derive(Serialize, Deserialize)] +#[serde(tag = "type", rename_all = "kebab-case")] +pub enum ProductMetadata { + Midas, +} + +#[derive(Copy, Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] +#[serde(from = "Base62Id")] +#[serde(into = "Base62Id")] +pub struct ProductPriceId(pub u64); + +#[derive(Serialize, Deserialize)] +pub struct ProductPrice { + pub id: ProductPriceId, + pub product_id: ProductId, + pub interval: PriceInterval, + pub price: i32, + pub currency_code: String, +} + +#[derive(Serialize, Deserialize)] +#[serde(tag = "type", rename_all = "kebab-case")] +pub enum PriceInterval { + OneTime, + /// For recurring payments. amount: 1 and duration: 'week' would result in a recurring payment + /// every week + Recurring { + amount: usize, + duration: PriceDuration, + }, +} + +#[derive(Serialize, Deserialize)] +#[serde(rename_all = "kebab-case")] +pub enum PriceDuration { + Day, + Week, + Month, + Year, +} + +#[derive(Copy, Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] +#[serde(from = "Base62Id")] +#[serde(into = "Base62Id")] +pub struct UserSubscriptionId(pub u64); + +#[derive(Serialize, Deserialize)] +pub struct UserSubscription { + pub id: UserSubscriptionId, + pub user_id: UserId, + pub price_id: ProductPriceId, + pub status: SubscriptionStatus, + pub created: DateTime, + pub expires: DateTime, + pub last_charge: Option>, +} + +#[derive(Serialize, Deserialize, Eq, PartialEq)] +#[serde(rename_all = "kebab-case")] +pub enum SubscriptionStatus { + Active, + PaymentProcessing, + PaymentFailed, + Cancelled, +} + +impl SubscriptionStatus { + pub fn from_string(string: &str) -> SubscriptionStatus { + match string { + "active" => SubscriptionStatus::Active, + "payment-processing" => SubscriptionStatus::PaymentProcessing, + "payment-failed" => SubscriptionStatus::PaymentFailed, + "cancelled" => SubscriptionStatus::Cancelled, + _ => SubscriptionStatus::Cancelled, + } + } + + pub fn as_str(&self) -> &'static str { + match self { + SubscriptionStatus::Active => "active", + SubscriptionStatus::PaymentProcessing => "payment-processing", + SubscriptionStatus::PaymentFailed => "payment-failed", + SubscriptionStatus::Cancelled => "cancelled", + } + } +} diff --git a/src/models/v3/ids.rs b/src/models/v3/ids.rs index d2a6672d..839d6587 100644 --- a/src/models/v3/ids.rs +++ b/src/models/v3/ids.rs @@ -1,5 +1,3 @@ -use thiserror::Error; - pub use super::collections::CollectionId; pub use super::images::ImageId; pub use super::notifications::NotificationId; @@ -15,6 +13,9 @@ pub use super::teams::TeamId; pub use super::threads::ThreadId; pub use super::threads::ThreadMessageId; pub use super::users::UserId; +pub use crate::models::billing::UserSubscriptionId; +pub use crate::models::v3::billing::{ProductId, ProductPriceId}; +use thiserror::Error; /// Generates a random 64 bit integer that is exactly `n` characters /// long when encoded as base62. @@ -133,6 +134,9 @@ base62_id_impl!(OAuthClientId, OAuthClientId); base62_id_impl!(OAuthRedirectUriId, OAuthRedirectUriId); base62_id_impl!(OAuthClientAuthorizationId, OAuthClientAuthorizationId); base62_id_impl!(PayoutId, PayoutId); +base62_id_impl!(ProductId, ProductId); +base62_id_impl!(ProductPriceId, ProductPriceId); +base62_id_impl!(UserSubscriptionId, UserSubscriptionId); pub mod base62_impl { use serde::de::{self, Deserializer, Visitor}; diff --git a/src/models/v3/mod.rs b/src/models/v3/mod.rs index 34f5836b..d9ffb845 100644 --- a/src/models/v3/mod.rs +++ b/src/models/v3/mod.rs @@ -1,4 +1,5 @@ pub mod analytics; +pub mod billing; pub mod collections; pub mod ids; pub mod images; diff --git a/src/models/v3/users.rs b/src/models/v3/users.rs index e810e261..64be5405 100644 --- a/src/models/v3/users.rs +++ b/src/models/v3/users.rs @@ -14,7 +14,6 @@ pub const DELETED_USER: UserId = UserId(127155982985829); bitflags::bitflags! { #[derive(Copy, Clone, Debug)] pub struct Badges: u64 { - // 1 << 0 unused - ignore + replace with something later const MIDAS = 1 << 0; const EARLY_MODPACK_ADOPTER = 1 << 1; const EARLY_RESPACK_ADOPTER = 1 << 2; @@ -53,6 +52,7 @@ pub struct User { pub has_password: Option, pub has_totp: Option, pub payout_data: Option, + pub stripe_customer_id: Option, // DEPRECATED. Always returns None pub github_id: Option, @@ -86,6 +86,7 @@ impl From for User { has_password: None, has_totp: None, github_id: None, + stripe_customer_id: None, } } } diff --git a/src/routes/internal/billing.rs b/src/routes/internal/billing.rs new file mode 100644 index 00000000..02aa3160 --- /dev/null +++ b/src/routes/internal/billing.rs @@ -0,0 +1,903 @@ +use crate::auth::{get_user_from_headers, send_email}; +use crate::database::models::{ + generate_user_subscription_id, product_item, user_subscription_item, +}; +use crate::database::redis::RedisPool; +use crate::models::billing::{ + PriceDuration, PriceInterval, Product, ProductMetadata, ProductPrice, SubscriptionStatus, + UserSubscription, +}; +use crate::models::ids::base62_impl::{parse_base62, to_base62}; +use crate::models::pats::Scopes; +use crate::models::users::Badges; +use crate::queue::session::AuthQueue; +use crate::routes::ApiError; +use actix_web::{delete, get, patch, post, web, HttpRequest, HttpResponse}; +use chrono::{Duration, Utc}; +use serde_with::serde_derive::Deserialize; +use sqlx::PgPool; +use std::collections::HashMap; +use std::str::FromStr; +use stripe::{ + CreateCustomer, CreatePaymentIntent, CreatePaymentIntentAutomaticPaymentMethods, + CreatePaymentIntentAutomaticPaymentMethodsAllowRedirects, CreateSetupIntent, + CreateSetupIntentAutomaticPaymentMethods, + CreateSetupIntentAutomaticPaymentMethodsAllowRedirects, Currency, CustomerId, + CustomerInvoiceSettings, CustomerPaymentMethodRetrieval, EventObject, EventType, ListCharges, + PaymentIntentOffSession, PaymentIntentStatus, PaymentMethodId, SetupIntent, UpdateCustomer, + Webhook, +}; + +pub fn config(cfg: &mut web::ServiceConfig) { + cfg.service( + web::scope("billing") + .service(products) + .service(subscriptions) + .service(user_customer) + .service(cancel_subscription) + .service(payment_methods) + .service(add_payment_method_flow) + .service(edit_payment_method) + .service(remove_payment_method) + .service(charges) + .service(initiate_payment) + .service(stripe_webhook), + ); +} + +// TODO: cache this +#[get("products")] +pub async fn products(pool: web::Data) -> Result { + let products = product_item::ProductItem::get_all(&**pool).await?; + let prices = product_item::ProductPriceItem::get_all_products_prices( + &products.iter().map(|x| x.id).collect::>(), + &**pool, + ) + .await?; + + let products = products + .into_iter() + .map(|x| Product { + id: x.id.into(), + metadata: x.metadata, + prices: prices + .remove(&x.id) + .map(|x| x.1) + .unwrap_or_default() + .into_iter() + .map(|x| ProductPrice { + id: x.id.into(), + product_id: x.product_id.into(), + interval: x.interval, + price: x.price, + currency_code: x.currency_code, + }) + .collect(), + unitary: x.unitary, + }) + .collect::>(); + + Ok(HttpResponse::Ok().json(products)) +} + +#[get("subscriptions")] +pub async fn subscriptions( + req: HttpRequest, + pool: web::Data, + redis: web::Data, + session_queue: web::Data, +) -> Result { + let user = get_user_from_headers( + &req, + &**pool, + &redis, + &session_queue, + Some(&[Scopes::SESSION_ACCESS]), + ) + .await? + .1; + + let subscriptions = + user_subscription_item::UserSubscriptionItem::get_all_user(user.id.into(), &**pool) + .await? + .into_iter() + .map(|x| UserSubscription { + id: x.id.into(), + user_id: x.user_id.into(), + price_id: x.price_id.into(), + status: x.status, + created: x.created, + expires: x.expires, + last_charge: x.last_charge, + }) + .collect::>(); + + Ok(HttpResponse::Ok().json(subscriptions)) +} + +#[patch("subscription/{id}")] +pub async fn cancel_subscription( + req: HttpRequest, + info: web::Path<(crate::models::ids::UserSubscriptionId,)>, + pool: web::Data, + redis: web::Data, + session_queue: web::Data, +) -> Result { + let user = get_user_from_headers( + &req, + &**pool, + &redis, + &session_queue, + Some(&[Scopes::SESSION_ACCESS]), + ) + .await? + .1; + + let (id,) = info.into_inner(); + + if let Some(mut subscription) = + user_subscription_item::UserSubscriptionItem::get(id.into(), &**pool).await? + { + if subscription.user_id != user.id.into() || !user.role.is_admin() { + return Err(ApiError::NotFound); + } + + let mut transaction = pool.begin().await?; + + subscription.status = SubscriptionStatus::Cancelled; + subscription.upsert(&mut transaction).await?; + + transaction.commit().await?; + + Ok(HttpResponse::NoContent().body("")) + } else { + Err(ApiError::NotFound) + } +} + +#[get("customer")] +pub async fn user_customer( + req: HttpRequest, + pool: web::Data, + redis: web::Data, + session_queue: web::Data, + stripe_client: web::Data, +) -> Result { + let user = get_user_from_headers( + &req, + &**pool, + &redis, + &session_queue, + Some(&[Scopes::SESSION_ACCESS]), + ) + .await? + .1; + + let customer_id = get_or_create_customer(&user, &*stripe_client, &pool, &redis).await?; + let customer = stripe::Customer::retrieve(&stripe_client, &customer_id, &[]).await?; + + Ok(HttpResponse::Ok().json(customer)) +} + +#[get("payments")] +pub async fn charges( + req: HttpRequest, + pool: web::Data, + redis: web::Data, + session_queue: web::Data, + stripe_client: web::Data, +) -> Result { + let user = get_user_from_headers( + &req, + &**pool, + &redis, + &session_queue, + Some(&[Scopes::SESSION_ACCESS]), + ) + .await? + .1; + + if let Some(customer_id) = user + .stripe_customer_id + .as_ref() + .and_then(|x| stripe::CustomerId::from_str(x).ok()) + { + let charges = stripe::Charge::list( + &stripe_client, + &ListCharges { + customer: Some(customer_id), + limit: Some(100), + ..Default::default() + }, + ) + .await?; + + Ok(HttpResponse::Ok().json(charges.data)) + } else { + Ok(HttpResponse::NoContent().finish()) + } +} + +#[post("payment_method")] +pub async fn add_payment_method_flow( + req: HttpRequest, + pool: web::Data, + redis: web::Data, + session_queue: web::Data, + stripe_client: web::Data, +) -> Result { + let user = get_user_from_headers( + &req, + &**pool, + &redis, + &session_queue, + Some(&[Scopes::SESSION_ACCESS]), + ) + .await? + .1; + + let customer = get_or_create_customer(&user, &*stripe_client, &pool, &redis).await?; + + let intent = SetupIntent::create( + &stripe_client, + CreateSetupIntent { + customer: Some(customer), + automatic_payment_methods: Some(CreateSetupIntentAutomaticPaymentMethods { + allow_redirects: Some( + CreateSetupIntentAutomaticPaymentMethodsAllowRedirects::Never, + ), + enabled: true, + }), + ..Default::default() + }, + ) + .await?; + + Ok(HttpResponse::Ok().json(serde_json::json!({ + "client_secret": intent.client_secret + }))) +} + +#[derive(Deserialize)] +pub struct EditPaymentMethod { + pub primary: bool, +} + +#[patch("payment_method/{id}")] +pub async fn edit_payment_method( + req: HttpRequest, + info: web::Path<(String,)>, + pool: web::Data, + redis: web::Data, + session_queue: web::Data, + stripe_client: web::Data, +) -> Result { + let user = get_user_from_headers( + &req, + &**pool, + &redis, + &session_queue, + Some(&[Scopes::SESSION_ACCESS]), + ) + .await? + .1; + + let (id,) = info.into_inner(); + + let payment_method_id = if let Ok(id) = PaymentMethodId::from_str(&id) { + id + } else { + return Err(ApiError::NotFound); + }; + + let customer = get_or_create_customer(&user, &*stripe_client, &pool, &redis).await?; + + let payment_method = + stripe::PaymentMethod::retrieve(&stripe_client, &payment_method_id, &[]).await?; + + if payment_method + .customer + .map(|x| x.id() == customer) + .unwrap_or(false) + || user.role.is_admin() + { + stripe::Customer::update( + &stripe_client, + &customer, + UpdateCustomer { + invoice_settings: Some(CustomerInvoiceSettings { + default_payment_method: Some(payment_method.id.to_string()), + ..Default::default() + }), + ..Default::default() + }, + ) + .await?; + + Ok(HttpResponse::NoContent().finish()) + } else { + Err(ApiError::NotFound) + } +} + +#[delete("payment_method/{id}")] +pub async fn remove_payment_method( + req: HttpRequest, + info: web::Path<(String,)>, + pool: web::Data, + redis: web::Data, + session_queue: web::Data, + stripe_client: web::Data, +) -> Result { + let user = get_user_from_headers( + &req, + &**pool, + &redis, + &session_queue, + Some(&[Scopes::SESSION_ACCESS]), + ) + .await? + .1; + + let (id,) = info.into_inner(); + + let payment_method_id = if let Ok(id) = PaymentMethodId::from_str(&id) { + id + } else { + return Err(ApiError::NotFound); + }; + + let customer = get_or_create_customer(&user, &*stripe_client, &pool, &redis).await?; + + let payment_method = + stripe::PaymentMethod::retrieve(&stripe_client, &payment_method_id, &[]).await?; + + let user_subscriptions = + user_subscription_item::UserSubscriptionItem::get_all_user(user.id.into(), &**pool).await?; + + if user_subscriptions + .iter() + .any(|x| x.status != SubscriptionStatus::Cancelled) + { + let customer = stripe::Customer::retrieve(&stripe_client, &customer, &[]).await?; + + if customer + .invoice_settings + .and_then(|x| { + x.default_payment_method + .map(|x| x.id() == payment_method_id) + }) + .unwrap_or(false) + { + return Err(ApiError::InvalidInput( + "You may not remove the default payment method if you have active subscriptions!" + .to_string(), + )); + } + } + + if payment_method + .customer + .map(|x| x.id() == customer) + .unwrap_or(false) + || user.role.is_admin() + { + stripe::PaymentMethod::detach(&stripe_client, &payment_method_id).await?; + + Ok(HttpResponse::NoContent().finish()) + } else { + Err(ApiError::NotFound) + } +} + +#[get("payment_methods")] +pub async fn payment_methods( + req: HttpRequest, + pool: web::Data, + redis: web::Data, + session_queue: web::Data, + stripe_client: web::Data, +) -> Result { + let user = get_user_from_headers( + &req, + &**pool, + &redis, + &session_queue, + Some(&[Scopes::SESSION_ACCESS]), + ) + .await? + .1; + + if let Some(customer_id) = user + .stripe_customer_id + .as_ref() + .and_then(|x| stripe::CustomerId::from_str(x).ok()) + { + let methods = stripe::Customer::retrieve_payment_methods( + &stripe_client, + &customer_id, + CustomerPaymentMethodRetrieval { + limit: Some(100), + ..Default::default() + }, + ) + .await?; + + Ok(HttpResponse::Ok().json(methods.data)) + } else { + Ok(HttpResponse::NoContent().finish()) + } +} + +#[derive(Deserialize)] +pub struct PaymentRequest { + pub price_id: crate::models::ids::ProductPriceId, + pub payment_method_id: Option, +} + +// TODO: Change to use confirmation tokens once async_stripe supports api +#[post("payment")] +pub async fn initiate_payment( + req: HttpRequest, + pool: web::Data, + redis: web::Data, + session_queue: web::Data, + stripe_client: web::Data, + payment_request: web::Json, +) -> Result { + let user = get_user_from_headers( + &req, + &**pool, + &redis, + &session_queue, + Some(&[Scopes::SESSION_ACCESS]), + ) + .await? + .1; + + let price = product_item::ProductPriceItem::get(payment_request.price_id.into(), &**pool) + .await? + .ok_or_else(|| { + ApiError::InvalidInput("Specified product price could not be found!".to_string()) + })?; + + let product = product_item::ProductItem::get(price.product_id, &**pool) + .await? + .ok_or_else(|| { + ApiError::InvalidInput("Specified product could not be found!".to_string()) + })?; + + let customer_id = get_or_create_customer(&user, &*stripe_client, &pool, &redis).await?; + + let mut intent = CreatePaymentIntent::new( + price.price as i64, + Currency::from_str(&price.currency_code).unwrap_or(Currency::USD), + ); + + let mut metadata = HashMap::new(); + metadata.insert("modrinth_user_id".to_string(), to_base62(user.id.0)); + metadata.insert("modrinth_price_id".to_string(), to_base62(user.id.0)); + + if product.unitary { + let user_subscriptions = + user_subscription_item::UserSubscriptionItem::get_all_user(user.id.into(), &**pool) + .await?; + + let user_products = product_item::ProductPriceItem::get_many( + &user_subscriptions + .iter() + .map(|x| x.price_id) + .collect::>(), + &**pool, + ) + .await?; + + if let Some(product) = user_products + .into_iter() + .find(|x| x.product_id == product.id) + { + if let Some(subscription) = user_subscriptions + .into_iter() + .find(|x| x.price_id == product.id) + { + if subscription.status == SubscriptionStatus::Cancelled + || subscription.status == SubscriptionStatus::PaymentFailed + { + metadata.insert("modrinth_subscription_id".to_string(), to_base62(user.id.0)); + } else { + return Err(ApiError::InvalidInput( + "You are already subscribed to this product!".to_string(), + )); + } + } + } + } + + if let PriceInterval::Recurring { .. } = price.interval { + if !metadata.contains_key("modrinth_subscription_id") { + let mut transaction = pool.begin().await?; + let user_subscription_id = generate_user_subscription_id(&mut transaction).await?; + } + } + + intent.metadata = Some(metadata); + + intent.automatic_payment_methods = Some(CreatePaymentIntentAutomaticPaymentMethods { + allow_redirects: Some(CreatePaymentIntentAutomaticPaymentMethodsAllowRedirects::Never), + enabled: true, + }); + + if let Some(payment_method) = payment_request + .payment_method_id + .clone() + .and_then(|x| stripe::PaymentMethodId::from_str(&x).ok()) + { + intent.payment_method = Some(payment_method); + intent.confirm = Some(false); + intent.off_session = Some(PaymentIntentOffSession::Exists(true)) + } + + intent.receipt_email = user.email.as_deref(); + + let payment_intent = stripe::PaymentIntent::create(&stripe_client, intent).await?; + + if payment_intent.status == PaymentIntentStatus::Succeeded { + return Ok(HttpResponse::NoContent().finish()); + } + + Ok(HttpResponse::Ok().json(serde_json::json!({ + "status": payment_intent.status, + "client_secret": payment_intent.client_secret + }))) +} + +#[post("_stripe")] +pub async fn stripe_webhook( + req: HttpRequest, + payload: String, + pool: web::Data, + redis: web::Data, + stripe_client: web::Data, +) -> Result { + let stripe_signature = req + .headers() + .get("Stripe-Signature") + .and_then(|x| x.to_str().ok()) + .unwrap_or_default(); + + if let Ok(event) = Webhook::construct_event( + &*payload, + stripe_signature, + &*dotenvy::var("STRIPE_WEBHOOK_SECRET")?, + ) { + struct PaymentIntentMetadata { + user: crate::database::models::User, + user_subscription_id: Option, + user_subscription: Option, + product: product_item::ProductItem, + product_price: product_item::ProductPriceItem, + } + + async fn get_payment_intent_metadata( + metadata: HashMap, + pool: &PgPool, + redis: &RedisPool, + ) -> Result { + if let Some(user_id) = metadata + .get("modrinth_user_id") + .and_then(|x| parse_base62(x).ok()) + .map(|x| crate::database::models::ids::UserId(x as i64)) + { + let user = + crate::database::models::user_item::User::get_id(user_id, pool, &redis).await?; + + if let Some(user) = user { + let (user_subscription_id, user_subscription) = if let Some(subscription_id) = + metadata + .get("modrinth_subscription_id") + .and_then(|x| parse_base62(x).ok()) + .map(|x| crate::database::models::ids::UserSubscriptionId(x as i64)) + { + let subscription = user_subscription_item::UserSubscriptionItem::get( + subscription_id, + pool, + ) + .await?; + + (Some(subscription_id), subscription) + } else { + (None, None) + }; + + if let Some(price_id) = metadata + .get("modrinth_price_id") + .and_then(|x| parse_base62(x).ok()) + .map(|x| crate::database::models::ids::ProductPriceId(x as i64)) + { + let price = product_item::ProductPriceItem::get(price_id, pool).await?; + + if let Some(product_price) = price { + let product = + product_item::ProductItem::get(product_price.product_id, pool) + .await?; + + if let Some(product) = product { + return Ok(PaymentIntentMetadata { + user, + user_subscription_id, + user_subscription, + product, + product_price, + }); + } + } + } + } + } + + Err(ApiError::InvalidInput( + "Webhook missing required webhook metadata!".to_string(), + )) + } + + match event.type_ { + EventType::PaymentIntentSucceeded => { + if let EventObject::PaymentIntent(payment_intent) = event.data.object { + let metadata = + get_payment_intent_metadata(payment_intent.metadata, &pool, &redis).await?; + + let mut transaction = pool.begin().await?; + + if let PriceInterval::Recurring { amount, duration } = + metadata.product_price.interval + { + if let Some(subscription_id) = metadata.user_subscription_id { + let duration = match duration { + PriceDuration::Day => Duration::days(amount as i64), + PriceDuration::Week => Duration::days((amount * 7) as i64), + PriceDuration::Month => Duration::days((amount * 30) as i64), + PriceDuration::Year => Duration::days((amount * 365) as i64), + }; + + if let Some(mut user_subscription) = metadata.user_subscription { + user_subscription.expires = Utc::now() + duration; + user_subscription.status = SubscriptionStatus::Active; + user_subscription.upsert(&mut transaction).await?; + } else { + user_subscription_item::UserSubscriptionItem { + id: subscription_id, + user_id: metadata.user.id, + price_id: metadata.product_price.id, + created: Utc::now(), + expires: Utc::now() + duration, + last_charge: None, + status: SubscriptionStatus::Active, + } + .upsert(&mut transaction) + .await?; + } + } + } + + // Provision subscription + match metadata.product.metadata { + ProductMetadata::Midas => { + let badges = metadata.user.badges & Badges::MIDAS; + + sqlx::query!( + " + UPDATE users + SET badges = $1 + WHERE (id = $2) + ", + badges.bits() as i64, + metadata.user.id as crate::database::models::ids::UserId, + ) + .execute(&mut *transaction) + .await?; + } + } + + transaction.commit().await?; + } + } + EventType::PaymentIntentProcessing => { + if let EventObject::PaymentIntent(payment_intent) = event.data.object { + let metadata = + get_payment_intent_metadata(payment_intent.metadata, &pool, &redis).await?; + + let mut transaction = pool.begin().await?; + + if let PriceInterval::Recurring { .. } = metadata.product_price.interval { + if let Some(subscription_id) = metadata.user_subscription_id { + if let Some(mut user_subscription) = metadata.user_subscription { + user_subscription.status = SubscriptionStatus::PaymentProcessing; + user_subscription.upsert(&mut transaction).await?; + } else { + user_subscription_item::UserSubscriptionItem { + id: subscription_id, + user_id: metadata.user.id, + price_id: metadata.product_price.id, + created: Utc::now(), + expires: Utc::now(), + last_charge: None, + status: SubscriptionStatus::PaymentProcessing, + } + .upsert(&mut transaction) + .await?; + } + } + } + + transaction.commit().await?; + } + } + EventType::PaymentIntentPaymentFailed => { + if let EventObject::PaymentIntent(payment_intent) = event.data.object { + let metadata = + get_payment_intent_metadata(payment_intent.metadata, &pool, &redis).await?; + + let mut transaction = pool.begin().await?; + + if let PriceInterval::Recurring { .. } = metadata.product_price.interval { + if let Some(subscription_id) = metadata.user_subscription_id { + if let Some(mut user_subscription) = metadata.user_subscription { + user_subscription.last_charge = Some(Utc::now()); + user_subscription.status = SubscriptionStatus::PaymentFailed; + user_subscription.upsert(&mut transaction).await?; + } else { + user_subscription_item::UserSubscriptionItem { + id: subscription_id, + user_id: metadata.user.id, + price_id: metadata.product_price.id, + created: Utc::now(), + expires: Utc::now(), + last_charge: Some(Utc::now()), + status: SubscriptionStatus::PaymentFailed, + } + .upsert(&mut transaction) + .await?; + } + } + } + + if let Some(email) = metadata.user.email { + let money = rusty_money::Money::from_minor( + metadata.product_price.price as i64, + rusty_money::iso::find(&metadata.product_price.currency_code) + .unwrap_or(rusty_money::iso::USD), + ); + + send_email( + email, + "[Action Required] Payment Failed for Modrinth", + &format!("Our attempt to collect payment for {money} from the payment card on file was unsuccessful."), + "Please visit the following link below to update your payment method or contact your card provider. If the button does not work, you can copy the link and paste it into your browser.", + Some(("Update billing settings", &format!("{}/{}", dotenvy::var("SITE_URL")?, dotenvy::var("SITE_BILLING_PATH")?))), + )?; + } + + transaction.commit().await?; + } + } + EventType::SetupIntentSucceeded => { + if let EventObject::SetupIntent(setup_intent) = event.data.object { + if let Some(customer_id) = setup_intent.customer.map(|x| x.id()) { + if let Some(payment_method_id) = setup_intent.payment_method.map(|x| x.id()) + { + let customer = + stripe::Customer::retrieve(&stripe_client, &customer_id, &[]) + .await?; + + if !customer + .invoice_settings + .map(|x| x.default_payment_method.is_some()) + .unwrap_or(false) + { + stripe::Customer::update( + &stripe_client, + &customer_id, + UpdateCustomer { + invoice_settings: Some(CustomerInvoiceSettings { + default_payment_method: Some( + payment_method_id.to_string(), + ), + ..Default::default() + }), + ..Default::default() + }, + ) + .await?; + } + } + } + } + } + _ => {} + } + } else { + return Err(ApiError::InvalidInput( + "Webhook signature validation failed!".to_string(), + )); + } + + Ok(HttpResponse::Ok().finish()) +} + +async fn get_or_create_customer( + user: &crate::models::users::User, + client: &stripe::Client, + pool: &PgPool, + redis: &RedisPool, +) -> Result { + if let Some(customer_id) = user + .stripe_customer_id + .as_ref() + .and_then(|x| stripe::CustomerId::from_str(x).ok()) + { + Ok(customer_id) + } else { + let mut metadata = HashMap::new(); + metadata.insert("modrinth_user_id".to_string(), to_base62(user.id.0)); + + let customer = stripe::Customer::create( + client, + CreateCustomer { + email: user.email.as_deref(), + metadata: Some(metadata), + ..Default::default() + }, + ) + .await?; + + sqlx::query!( + " + UPDATE users + SET stripe_customer_id = $1 + WHERE id = $2 + ", + customer.id.as_str(), + user.id.0 as i64 + ) + .execute(&*pool) + .await?; + + crate::database::models::user_item::User::clear_caches(&[(user.id.into(), None)], &redis) + .await?; + + Ok(customer.id) + } +} + +pub async fn task(pool: &PgPool, redis: &RedisPool) -> Result<(), ApiError> { + Ok(()) + + // TODO: scheduler for charging recurring payments + + // if subscription is cancelled and expired, unprovision + // if subscription is payment failed and expired, unprovision + // if subscription is payment failed and last attempt is > 4 days ago, try again to charge + // if subscription is active and expired, attempt to charge and set as processing + + // get all users + // get all user customers + + // Un provision subscription + // match metadata.product.metadata { + // ProductMetadata::Midas => { + // let badges = metadata.user.badges - Badges::MIDAS; + // + // sqlx::query!( + // " + // UPDATE users + // SET badges = $1 + // WHERE (id = $2) + // ", + // badges.bits() as i64, + // metadata.user.id as crate::database::models::ids::UserId, + // ) + // .execute(&mut *transaction) + // .await?; + // } + // } +} diff --git a/src/routes/internal/flows.rs b/src/routes/internal/flows.rs index bf831544..46069393 100644 --- a/src/routes/internal/flows.rs +++ b/src/routes/internal/flows.rs @@ -30,6 +30,7 @@ use rust_decimal::Decimal; use serde::{Deserialize, Serialize}; use sqlx::postgres::PgPool; use std::collections::HashMap; +use std::str::FromStr; use std::sync::Arc; use tokio::sync::RwLock; use validator::Validate; @@ -217,6 +218,7 @@ impl TempUser { None }, venmo_handle: None, + stripe_customer_id: None, totp_secret: None, username, name: self.name, @@ -1523,6 +1525,7 @@ pub async fn create_account_with_password( paypal_country: None, paypal_email: None, venmo_handle: None, + stripe_customer_id: None, totp_secret: None, username: new_account.username.clone(), name: Some(new_account.username), @@ -2157,6 +2160,7 @@ pub async fn set_email( redis: Data, email: web::Json, session_queue: Data, + stripe_client: Data, ) -> Result { email .0 @@ -2197,6 +2201,22 @@ pub async fn set_email( )?; } + if let Some(customer_id) = user + .stripe_customer_id + .as_ref() + .and_then(|x| stripe::CustomerId::from_str(x).ok()) + { + stripe::Customer::update( + &stripe_client, + &customer_id, + stripe::UpdateCustomer { + email: Some(&email.email), + ..Default::default() + }, + ) + .await?; + } + let flow = Flow::ConfirmEmail { user_id: user.id.into(), confirm_email: email.email.clone(), diff --git a/src/routes/internal/mod.rs b/src/routes/internal/mod.rs index 5c1d782a..ddd78077 100644 --- a/src/routes/internal/mod.rs +++ b/src/routes/internal/mod.rs @@ -1,4 +1,5 @@ pub(crate) mod admin; +pub mod billing; pub mod flows; pub mod moderation; pub mod pats; @@ -17,6 +18,7 @@ pub fn config(cfg: &mut actix_web::web::ServiceConfig) { .configure(session::config) .configure(flows::config) .configure(pats::config) - .configure(moderation::config), + .configure(moderation::config) + .configure(billing::config), ); } diff --git a/src/routes/mod.rs b/src/routes/mod.rs index be706988..e0b81327 100644 --- a/src/routes/mod.rs +++ b/src/routes/mod.rs @@ -131,6 +131,8 @@ pub enum ApiError { NotFound, #[error("You are being rate-limited. Please wait {0} milliseconds. 0/{1} remaining.")] RateLimitError(u128, u32), + #[error("Error while interacting with payment processor: {0}")] + Stripe(#[from] stripe::StripeError), } impl ApiError { @@ -163,6 +165,7 @@ impl ApiError { ApiError::Zip(..) => "zip_error", ApiError::Io(..) => "io_error", ApiError::RateLimitError(..) => "ratelimit_error", + ApiError::Stripe(..) => "stripe_error", }, description: self.to_string(), } @@ -198,6 +201,7 @@ impl actix_web::ResponseError for ApiError { ApiError::Zip(..) => StatusCode::BAD_REQUEST, ApiError::Io(..) => StatusCode::BAD_REQUEST, ApiError::RateLimitError(..) => StatusCode::TOO_MANY_REQUESTS, + ApiError::Stripe(..) => StatusCode::FAILED_DEPENDENCY, } } diff --git a/src/routes/v3/payouts.rs b/src/routes/v3/payouts.rs index 197d6d84..52492b4c 100644 --- a/src/routes/v3/payouts.rs +++ b/src/routes/v3/payouts.rs @@ -12,7 +12,7 @@ use actix_web::{delete, get, post, web, HttpRequest, HttpResponse}; use chrono::Utc; use hex::ToHex; use hmac::{Hmac, Mac, NewMac}; -use hyper::Method; +use reqwest::Method; use rust_decimal::Decimal; use serde::Deserialize; use serde_json::json;