Our Personal Data Server from scratch! tranquil.farm
oauth atproto pds rust postgresql objectstorage fun

DRAFT: Better code quality via type safety #5

merged opened by lewis.moe targeting main from fix/code-quality-in-general

Ensuring at compile-time that we're definitely handling possible early failures in functions

Labels

None yet.

assignee

None yet.

Participants 1
AT URI
at://did:plc:3fwecdnvtcscjnrx2p4n7alz/sh.tangled.repo.pull/3mdbo7zq5ae22
+1856 -194
Interdiff #1 #2
.sqlx/query-03fc2ba947ee547e000b044fafb486e71b9b65a7dd923b5354c5a4dde98332eb.json

This file has not been changed.

+22
.sqlx/query-05fd99170e31e68fa5028c862417cdf535cd70e09fde0a8a28249df0070eb2fc.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT t.token FROM plc_operation_tokens t JOIN users u ON t.user_id = u.id WHERE u.did = $1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "token", 9 + "type_info": "Text" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Text" 15 + ] 16 + }, 17 + "nullable": [ 18 + false 19 + ] 20 + }, 21 + "hash": "05fd99170e31e68fa5028c862417cdf535cd70e09fde0a8a28249df0070eb2fc" 22 + }
+15
.sqlx/query-0710b57fb9aa933525f617b15e6e2e5feaa9c59c38ec9175568abdacda167107.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "UPDATE users SET deactivated_at = $1 WHERE did = $2", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Timestamptz", 9 + "Text" 10 + ] 11 + }, 12 + "nullable": [] 13 + }, 14 + "hash": "0710b57fb9aa933525f617b15e6e2e5feaa9c59c38ec9175568abdacda167107" 15 + }
.sqlx/query-0d32a592a97ad47c65aa37cf0d45417f2966fcbd688be7434626ae5f6971fa1f.json

This file has not been changed.

+22
.sqlx/query-0ec60bb854a4991d0d7249a68f7445b65c8cc8c723baca221d85f5e4f2478b99.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT body FROM comms_queue WHERE user_id = (SELECT id FROM users WHERE did = $1) AND comms_type = 'email_update' ORDER BY created_at DESC LIMIT 1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "body", 9 + "type_info": "Text" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Text" 15 + ] 16 + }, 17 + "nullable": [ 18 + false 19 + ] 20 + }, 21 + "hash": "0ec60bb854a4991d0d7249a68f7445b65c8cc8c723baca221d85f5e4f2478b99" 22 + }
+22
.sqlx/query-0fae1be7a75bdc58c69a9af97cad4aec23c32a9378764b8d6d7eb2cc89c562b1.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT token FROM sso_pending_registration WHERE token = $1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "token", 9 + "type_info": "Text" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Text" 15 + ] 16 + }, 17 + "nullable": [ 18 + false 19 + ] 20 + }, 21 + "hash": "0fae1be7a75bdc58c69a9af97cad4aec23c32a9378764b8d6d7eb2cc89c562b1" 22 + }
+22
.sqlx/query-1c84643fd6bc57c76517849a64d2d877df337e823d4c2c2b077f695bbfc9e9ac.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "\n DELETE FROM sso_pending_registration\n WHERE token = $1 AND expires_at > NOW()\n RETURNING token\n ", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "token", 9 + "type_info": "Text" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Text" 15 + ] 16 + }, 17 + "nullable": [ 18 + false 19 + ] 20 + }, 21 + "hash": "1c84643fd6bc57c76517849a64d2d877df337e823d4c2c2b077f695bbfc9e9ac" 22 + }
.sqlx/query-200ecf153f1433ae8f6fbe81ab888a04ddd035ec9e88ef5f207e2487a02a1224.json

This file has not been changed.

.sqlx/query-247470d26a90617e7dc9b5b3a2146ee3f54448e3c24943f7005e3a8e28820d43.json

This file has not been changed.

+28
.sqlx/query-24b823043ab60f36c29029137fef30dfe33922bb06067f2fdbfc1fbb4b0a2a81.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "\n DELETE FROM sso_pending_registration\n WHERE token = $1 AND expires_at > NOW()\n RETURNING token, request_uri\n ", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "token", 9 + "type_info": "Text" 10 + }, 11 + { 12 + "ordinal": 1, 13 + "name": "request_uri", 14 + "type_info": "Text" 15 + } 16 + ], 17 + "parameters": { 18 + "Left": [ 19 + "Text" 20 + ] 21 + }, 22 + "nullable": [ 23 + false, 24 + false 25 + ] 26 + }, 27 + "hash": "24b823043ab60f36c29029137fef30dfe33922bb06067f2fdbfc1fbb4b0a2a81" 28 + }
.sqlx/query-25309f4a08845a49557d694ad9b5b9a137be4dcce28e9293551c8c3fd40fdd86.json

This file has not been changed.

+38
.sqlx/query-2841093a67480e75e1e9e4046bf3eb74afae2d04f5ea0ec17a4d433983e6d71c.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "\n INSERT INTO external_identities (did, provider, provider_user_id)\n VALUES ($1, $2, $3)\n RETURNING id\n ", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "id", 9 + "type_info": "Uuid" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Text", 15 + { 16 + "Custom": { 17 + "name": "sso_provider_type", 18 + "kind": { 19 + "Enum": [ 20 + "github", 21 + "discord", 22 + "google", 23 + "gitlab", 24 + "oidc", 25 + "apple" 26 + ] 27 + } 28 + } 29 + }, 30 + "Text" 31 + ] 32 + }, 33 + "nullable": [ 34 + false 35 + ] 36 + }, 37 + "hash": "2841093a67480e75e1e9e4046bf3eb74afae2d04f5ea0ec17a4d433983e6d71c" 38 + }
+14
.sqlx/query-29ef76852bb89af1ab9e679ceaa4abcf8bc8268a348d3be0da9840d1708d20b5.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "UPDATE users SET password_reset_code_expires_at = NOW() - INTERVAL '1 hour' WHERE email = $1", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Text" 9 + ] 10 + }, 11 + "nullable": [] 12 + }, 13 + "hash": "29ef76852bb89af1ab9e679ceaa4abcf8bc8268a348d3be0da9840d1708d20b5" 14 + }
.sqlx/query-36441073d3fb87230f88ddce4e597c248fbf7360e510d703b9eec42efe9e049e.json

This file has not been changed.

+32
.sqlx/query-376b72306b50f747bc9161985ff4f50c35c53025a55ccf5e9933dc3795d29313.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "\n INSERT INTO sso_pending_registration (token, request_uri, provider, provider_user_id, provider_email_verified)\n VALUES ($1, $2, $3, $4, $5)\n ", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Text", 9 + "Text", 10 + { 11 + "Custom": { 12 + "name": "sso_provider_type", 13 + "kind": { 14 + "Enum": [ 15 + "github", 16 + "discord", 17 + "google", 18 + "gitlab", 19 + "oidc", 20 + "apple" 21 + ] 22 + } 23 + } 24 + }, 25 + "Text", 26 + "Bool" 27 + ] 28 + }, 29 + "nullable": [] 30 + }, 31 + "hash": "376b72306b50f747bc9161985ff4f50c35c53025a55ccf5e9933dc3795d29313" 32 + }
+22
.sqlx/query-3933ea5b147ab6294936de147b98e116cfae848ecd76ea5d367585eb5117f2ad.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT id FROM external_identities WHERE id = $1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "id", 9 + "type_info": "Uuid" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Uuid" 15 + ] 16 + }, 17 + "nullable": [ 18 + false 19 + ] 20 + }, 21 + "hash": "3933ea5b147ab6294936de147b98e116cfae848ecd76ea5d367585eb5117f2ad" 22 + }
+16
.sqlx/query-3bed8d4843545f4a9676207513806603c50eb2af92957994abaf1c89c0294c12.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "INSERT INTO users (did, handle, email, password_hash) VALUES ($1, $2, $3, 'hash')", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Text", 9 + "Text", 10 + "Text" 11 + ] 12 + }, 13 + "nullable": [] 14 + }, 15 + "hash": "3bed8d4843545f4a9676207513806603c50eb2af92957994abaf1c89c0294c12" 16 + }
+54
.sqlx/query-4445cc86cdf04894b340e67661b79a3c411917144a011f50849b737130b24dbe.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT subject, body, comms_type as \"comms_type: String\" FROM comms_queue WHERE user_id = $1 AND comms_type = 'admin_email' ORDER BY created_at DESC LIMIT 1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "subject", 9 + "type_info": "Text" 10 + }, 11 + { 12 + "ordinal": 1, 13 + "name": "body", 14 + "type_info": "Text" 15 + }, 16 + { 17 + "ordinal": 2, 18 + "name": "comms_type: String", 19 + "type_info": { 20 + "Custom": { 21 + "name": "comms_type", 22 + "kind": { 23 + "Enum": [ 24 + "welcome", 25 + "email_verification", 26 + "password_reset", 27 + "email_update", 28 + "account_deletion", 29 + "admin_email", 30 + "plc_operation", 31 + "two_factor_code", 32 + "channel_verification", 33 + "passkey_recovery", 34 + "legacy_login_alert", 35 + "migration_verification" 36 + ] 37 + } 38 + } 39 + } 40 + } 41 + ], 42 + "parameters": { 43 + "Left": [ 44 + "Uuid" 45 + ] 46 + }, 47 + "nullable": [ 48 + true, 49 + false, 50 + false 51 + ] 52 + }, 53 + "hash": "4445cc86cdf04894b340e67661b79a3c411917144a011f50849b737130b24dbe" 54 + }
+22
.sqlx/query-4560c237741ce9d4166aecd669770b3360a3ac71e649b293efb88d92c3254068.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT id FROM users WHERE email = $1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "id", 9 + "type_info": "Uuid" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Text" 15 + ] 16 + }, 17 + "nullable": [ 18 + false 19 + ] 20 + }, 21 + "hash": "4560c237741ce9d4166aecd669770b3360a3ac71e649b293efb88d92c3254068" 22 + }
+28
.sqlx/query-47fe4a54857344d8f789f37092a294cd58f64b4fb431b54b5deda13d64525e88.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT token, expires_at FROM account_deletion_requests WHERE did = $1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "token", 9 + "type_info": "Text" 10 + }, 11 + { 12 + "ordinal": 1, 13 + "name": "expires_at", 14 + "type_info": "Timestamptz" 15 + } 16 + ], 17 + "parameters": { 18 + "Left": [ 19 + "Text" 20 + ] 21 + }, 22 + "nullable": [ 23 + false, 24 + false 25 + ] 26 + }, 27 + "hash": "47fe4a54857344d8f789f37092a294cd58f64b4fb431b54b5deda13d64525e88" 28 + }
+22
.sqlx/query-49cbc923cc4a0dcf7dea4ead5ab9580ff03b717586c4ca2d5343709e2dac86b6.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT email_verified FROM users WHERE did = $1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "email_verified", 9 + "type_info": "Bool" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Text" 15 + ] 16 + }, 17 + "nullable": [ 18 + false 19 + ] 20 + }, 21 + "hash": "49cbc923cc4a0dcf7dea4ead5ab9580ff03b717586c4ca2d5343709e2dac86b6" 22 + }
+22
.sqlx/query-4fef326fa2d03d04869af3fec702c901d1ecf392545a3a032438b2c1859d46cc.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "\n SELECT token FROM sso_pending_registration\n WHERE token = $1 AND expires_at > NOW()\n ", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "token", 9 + "type_info": "Text" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Text" 15 + ] 16 + }, 17 + "nullable": [ 18 + false 19 + ] 20 + }, 21 + "hash": "4fef326fa2d03d04869af3fec702c901d1ecf392545a3a032438b2c1859d46cc" 22 + }
+15
.sqlx/query-575c1e5529874f8f523e6fe22ccf4ee3296806581b1765dfb91a84ffab347f15.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "\n INSERT INTO oauth_authorization_request (id, client_id, parameters, expires_at)\n VALUES ($1, 'https://test.example.com', $2, NOW() + INTERVAL '1 hour')\n ", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Text", 9 + "Jsonb" 10 + ] 11 + }, 12 + "nullable": [] 13 + }, 14 + "hash": "575c1e5529874f8f523e6fe22ccf4ee3296806581b1765dfb91a84ffab347f15" 15 + }
+33
.sqlx/query-596c3400a60c77c7645fd46fcea61fa7898b6832e58c0f647f382b23b81d350e.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "\n INSERT INTO sso_pending_registration (token, request_uri, provider, provider_user_id, provider_username, provider_email)\n VALUES ($1, $2, $3, $4, $5, $6)\n ", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Text", 9 + "Text", 10 + { 11 + "Custom": { 12 + "name": "sso_provider_type", 13 + "kind": { 14 + "Enum": [ 15 + "github", 16 + "discord", 17 + "google", 18 + "gitlab", 19 + "oidc", 20 + "apple" 21 + ] 22 + } 23 + } 24 + }, 25 + "Text", 26 + "Text", 27 + "Text" 28 + ] 29 + }, 30 + "nullable": [] 31 + }, 32 + "hash": "596c3400a60c77c7645fd46fcea61fa7898b6832e58c0f647f382b23b81d350e" 33 + }
+81
.sqlx/query-59e63c5cf92985714e9586d1ce012efef733d4afaa4ea09974daf8303805e5d2.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "\n SELECT id, did, provider as \"provider: SsoProviderType\", provider_user_id, provider_username, provider_email\n FROM external_identities\n WHERE provider = $1 AND provider_user_id = $2\n ", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "id", 9 + "type_info": "Uuid" 10 + }, 11 + { 12 + "ordinal": 1, 13 + "name": "did", 14 + "type_info": "Text" 15 + }, 16 + { 17 + "ordinal": 2, 18 + "name": "provider: SsoProviderType", 19 + "type_info": { 20 + "Custom": { 21 + "name": "sso_provider_type", 22 + "kind": { 23 + "Enum": [ 24 + "github", 25 + "discord", 26 + "google", 27 + "gitlab", 28 + "oidc", 29 + "apple" 30 + ] 31 + } 32 + } 33 + } 34 + }, 35 + { 36 + "ordinal": 3, 37 + "name": "provider_user_id", 38 + "type_info": "Text" 39 + }, 40 + { 41 + "ordinal": 4, 42 + "name": "provider_username", 43 + "type_info": "Text" 44 + }, 45 + { 46 + "ordinal": 5, 47 + "name": "provider_email", 48 + "type_info": "Text" 49 + } 50 + ], 51 + "parameters": { 52 + "Left": [ 53 + { 54 + "Custom": { 55 + "name": "sso_provider_type", 56 + "kind": { 57 + "Enum": [ 58 + "github", 59 + "discord", 60 + "google", 61 + "gitlab", 62 + "oidc", 63 + "apple" 64 + ] 65 + } 66 + } 67 + }, 68 + "Text" 69 + ] 70 + }, 71 + "nullable": [ 72 + false, 73 + false, 74 + false, 75 + false, 76 + true, 77 + true 78 + ] 79 + }, 80 + "hash": "59e63c5cf92985714e9586d1ce012efef733d4afaa4ea09974daf8303805e5d2" 81 + }
+28
.sqlx/query-5a016f289caf75177731711e56e92881ba343c73a9a6e513e205c801c5943ec0.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "\n SELECT k.key_bytes, k.encryption_version\n FROM user_keys k\n JOIN users u ON k.user_id = u.id\n WHERE u.did = $1\n ", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "key_bytes", 9 + "type_info": "Bytea" 10 + }, 11 + { 12 + "ordinal": 1, 13 + "name": "encryption_version", 14 + "type_info": "Int4" 15 + } 16 + ], 17 + "parameters": { 18 + "Left": [ 19 + "Text" 20 + ] 21 + }, 22 + "nullable": [ 23 + false, 24 + true 25 + ] 26 + }, 27 + "hash": "5a016f289caf75177731711e56e92881ba343c73a9a6e513e205c801c5943ec0" 28 + }
+22
.sqlx/query-5af4a386c1632903ad7102551a5bd148bcf541baab6a84c8649666a695f9c4d1.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "\n DELETE FROM sso_auth_state\n WHERE state = $1 AND expires_at > NOW()\n RETURNING state\n ", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "state", 9 + "type_info": "Text" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Text" 15 + ] 16 + }, 17 + "nullable": [ 18 + false 19 + ] 20 + }, 21 + "hash": "5af4a386c1632903ad7102551a5bd148bcf541baab6a84c8649666a695f9c4d1" 22 + }
+43
.sqlx/query-5e4c0dd92ac3c4b5e2eae5d129f2649cf3a8f068105f44a8dca9625427affc06.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "\n SELECT provider_user_id, provider_email_verified\n FROM external_identities\n WHERE did = $1 AND provider = $2\n ", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "provider_user_id", 9 + "type_info": "Text" 10 + }, 11 + { 12 + "ordinal": 1, 13 + "name": "provider_email_verified", 14 + "type_info": "Bool" 15 + } 16 + ], 17 + "parameters": { 18 + "Left": [ 19 + "Text", 20 + { 21 + "Custom": { 22 + "name": "sso_provider_type", 23 + "kind": { 24 + "Enum": [ 25 + "github", 26 + "discord", 27 + "google", 28 + "gitlab", 29 + "oidc", 30 + "apple" 31 + ] 32 + } 33 + } 34 + } 35 + ] 36 + }, 37 + "nullable": [ 38 + false, 39 + false 40 + ] 41 + }, 42 + "hash": "5e4c0dd92ac3c4b5e2eae5d129f2649cf3a8f068105f44a8dca9625427affc06" 43 + }
+33
.sqlx/query-5e9c6ec72c2c0ea1c8dff551d01baddd1dd953c828a5656db2ee39dea996f890.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "\n INSERT INTO sso_auth_state (state, request_uri, provider, action, nonce, code_verifier)\n VALUES ($1, $2, $3, $4, $5, $6)\n ", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Text", 9 + "Text", 10 + { 11 + "Custom": { 12 + "name": "sso_provider_type", 13 + "kind": { 14 + "Enum": [ 15 + "github", 16 + "discord", 17 + "google", 18 + "gitlab", 19 + "oidc", 20 + "apple" 21 + ] 22 + } 23 + } 24 + }, 25 + "Text", 26 + "Text", 27 + "Text" 28 + ] 29 + }, 30 + "nullable": [] 31 + }, 32 + "hash": "5e9c6ec72c2c0ea1c8dff551d01baddd1dd953c828a5656db2ee39dea996f890" 33 + }
+28
.sqlx/query-63f6f2a89650794fe90e10ce7fc785a6b9f7d37c12b31a6ff13f7c5214eef19e.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT did, email_verified FROM users WHERE did = $1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "did", 9 + "type_info": "Text" 10 + }, 11 + { 12 + "ordinal": 1, 13 + "name": "email_verified", 14 + "type_info": "Bool" 15 + } 16 + ], 17 + "parameters": { 18 + "Left": [ 19 + "Text" 20 + ] 21 + }, 22 + "nullable": [ 23 + false, 24 + false 25 + ] 26 + }, 27 + "hash": "63f6f2a89650794fe90e10ce7fc785a6b9f7d37c12b31a6ff13f7c5214eef19e" 28 + }
+66
.sqlx/query-6c7ace2a64848adc757af6c93b9162e1d95788b372370a7ad0d7540338bb73ee.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "\n SELECT state, request_uri, provider as \"provider: SsoProviderType\", action, nonce, code_verifier\n FROM sso_auth_state\n WHERE state = $1\n ", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "state", 9 + "type_info": "Text" 10 + }, 11 + { 12 + "ordinal": 1, 13 + "name": "request_uri", 14 + "type_info": "Text" 15 + }, 16 + { 17 + "ordinal": 2, 18 + "name": "provider: SsoProviderType", 19 + "type_info": { 20 + "Custom": { 21 + "name": "sso_provider_type", 22 + "kind": { 23 + "Enum": [ 24 + "github", 25 + "discord", 26 + "google", 27 + "gitlab", 28 + "oidc", 29 + "apple" 30 + ] 31 + } 32 + } 33 + } 34 + }, 35 + { 36 + "ordinal": 3, 37 + "name": "action", 38 + "type_info": "Text" 39 + }, 40 + { 41 + "ordinal": 4, 42 + "name": "nonce", 43 + "type_info": "Text" 44 + }, 45 + { 46 + "ordinal": 5, 47 + "name": "code_verifier", 48 + "type_info": "Text" 49 + } 50 + ], 51 + "parameters": { 52 + "Left": [ 53 + "Text" 54 + ] 55 + }, 56 + "nullable": [ 57 + false, 58 + false, 59 + false, 60 + false, 61 + true, 62 + true 63 + ] 64 + }, 65 + "hash": "6c7ace2a64848adc757af6c93b9162e1d95788b372370a7ad0d7540338bb73ee" 66 + }
+22
.sqlx/query-6fbcff0206599484bfb6cef165b6f729d27e7a342f7718ee4ac07f0ca94412ba.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT state FROM sso_auth_state WHERE state = $1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "state", 9 + "type_info": "Text" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Text" 15 + ] 16 + }, 17 + "nullable": [ 18 + false 19 + ] 20 + }, 21 + "hash": "6fbcff0206599484bfb6cef165b6f729d27e7a342f7718ee4ac07f0ca94412ba" 22 + }
.sqlx/query-7061e8763ef7d91ff152ed0124f99e1820172fd06916d225ca6c5137a507b8fa.json

This file has not been changed.

+33
.sqlx/query-712459c27fc037f45389e2766cf1057e86e93ef756a784ed12beb453b03c5da1.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "\n INSERT INTO sso_pending_registration (token, request_uri, provider, provider_user_id, provider_username, provider_email_verified)\n VALUES ($1, $2, $3, $4, $5, $6)\n ", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Text", 9 + "Text", 10 + { 11 + "Custom": { 12 + "name": "sso_provider_type", 13 + "kind": { 14 + "Enum": [ 15 + "github", 16 + "discord", 17 + "google", 18 + "gitlab", 19 + "oidc", 20 + "apple" 21 + ] 22 + } 23 + } 24 + }, 25 + "Text", 26 + "Text", 27 + "Bool" 28 + ] 29 + }, 30 + "nullable": [] 31 + }, 32 + "hash": "712459c27fc037f45389e2766cf1057e86e93ef756a784ed12beb453b03c5da1" 33 + }
+22
.sqlx/query-785a864944c5939331704c71b0cd3ed26ffdd64f3fd0f26ecc28b6a0557bbe8f.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT subject FROM comms_queue WHERE user_id = $1 AND comms_type = 'admin_email' AND body = 'Email without subject' LIMIT 1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "subject", 9 + "type_info": "Text" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Uuid" 15 + ] 16 + }, 17 + "nullable": [ 18 + true 19 + ] 20 + }, 21 + "hash": "785a864944c5939331704c71b0cd3ed26ffdd64f3fd0f26ecc28b6a0557bbe8f" 22 + }
+22
.sqlx/query-7caa8f9083b15ec1209dda35c4c6f6fba9fe338e4a6a10636b5389d426df1631.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "\n SELECT t.token\n FROM plc_operation_tokens t\n JOIN users u ON t.user_id = u.id\n WHERE u.did = $1\n ", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "token", 9 + "type_info": "Text" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Text" 15 + ] 16 + }, 17 + "nullable": [ 18 + false 19 + ] 20 + }, 21 + "hash": "7caa8f9083b15ec1209dda35c4c6f6fba9fe338e4a6a10636b5389d426df1631" 22 + }
+28
.sqlx/query-7d24e744a4e63570b1410e50b45b745ce8915ab3715b3eff7efc2d84f27735d0.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT provider_username, last_login_at FROM external_identities WHERE id = $1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "provider_username", 9 + "type_info": "Text" 10 + }, 11 + { 12 + "ordinal": 1, 13 + "name": "last_login_at", 14 + "type_info": "Timestamptz" 15 + } 16 + ], 17 + "parameters": { 18 + "Left": [ 19 + "Uuid" 20 + ] 21 + }, 22 + "nullable": [ 23 + true, 24 + true 25 + ] 26 + }, 27 + "hash": "7d24e744a4e63570b1410e50b45b745ce8915ab3715b3eff7efc2d84f27735d0" 28 + }
+28
.sqlx/query-82717b6f61cd79347e1ca7e92c4413743ba168d1e0d8b85566711e54d4048f81.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT t.token, t.expires_at FROM plc_operation_tokens t JOIN users u ON t.user_id = u.id WHERE u.did = $1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "token", 9 + "type_info": "Text" 10 + }, 11 + { 12 + "ordinal": 1, 13 + "name": "expires_at", 14 + "type_info": "Timestamptz" 15 + } 16 + ], 17 + "parameters": { 18 + "Left": [ 19 + "Text" 20 + ] 21 + }, 22 + "nullable": [ 23 + false, 24 + false 25 + ] 26 + }, 27 + "hash": "82717b6f61cd79347e1ca7e92c4413743ba168d1e0d8b85566711e54d4048f81" 28 + }
+34
.sqlx/query-85ffc37a77af832d7795f5f37efe304fced4bf56b4f2287fe9aeb3fc97e1b191.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "\n INSERT INTO sso_pending_registration (token, request_uri, provider, provider_user_id, provider_username, provider_email, provider_email_verified)\n VALUES ($1, $2, $3, $4, $5, $6, $7)\n ", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Text", 9 + "Text", 10 + { 11 + "Custom": { 12 + "name": "sso_provider_type", 13 + "kind": { 14 + "Enum": [ 15 + "github", 16 + "discord", 17 + "google", 18 + "gitlab", 19 + "oidc", 20 + "apple" 21 + ] 22 + } 23 + } 24 + }, 25 + "Text", 26 + "Text", 27 + "Text", 28 + "Bool" 29 + ] 30 + }, 31 + "nullable": [] 32 + }, 33 + "hash": "85ffc37a77af832d7795f5f37efe304fced4bf56b4f2287fe9aeb3fc97e1b191" 34 + }
+22
.sqlx/query-9ad422bf3c43e3cfd86fc88c73594246ead214ca794760d3fe77bb5cf4f27be5.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT body FROM comms_queue WHERE user_id = (SELECT id FROM users WHERE did = $1) AND comms_type = 'email_verification' ORDER BY created_at DESC LIMIT 1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "body", 9 + "type_info": "Text" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Text" 15 + ] 16 + }, 17 + "nullable": [ 18 + false 19 + ] 20 + }, 21 + "hash": "9ad422bf3c43e3cfd86fc88c73594246ead214ca794760d3fe77bb5cf4f27be5" 22 + }
+28
.sqlx/query-9b035b051769e6b9d45910a8bb42ac0f84c73de8c244ba4560f004ee3f4b7002.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT did, public_key_did_key FROM reserved_signing_keys WHERE public_key_did_key = $1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "did", 9 + "type_info": "Text" 10 + }, 11 + { 12 + "ordinal": 1, 13 + "name": "public_key_did_key", 14 + "type_info": "Text" 15 + } 16 + ], 17 + "parameters": { 18 + "Left": [ 19 + "Text" 20 + ] 21 + }, 22 + "nullable": [ 23 + true, 24 + false 25 + ] 26 + }, 27 + "hash": "9b035b051769e6b9d45910a8bb42ac0f84c73de8c244ba4560f004ee3f4b7002" 28 + }
+22
.sqlx/query-9dba64081d4f95b5490c9a9bf30a7175db3429f39df4f25e212f38f33882fc65.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "\n SELECT id FROM external_identities WHERE did = $1\n ", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "id", 9 + "type_info": "Uuid" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Text" 15 + ] 16 + }, 17 + "nullable": [ 18 + false 19 + ] 20 + }, 21 + "hash": "9dba64081d4f95b5490c9a9bf30a7175db3429f39df4f25e212f38f33882fc65" 22 + }
+66
.sqlx/query-9fd56986c1c843d386d1e5884acef8573eb55a3e9f5cb0122fcf8b93d6d667a5.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "\n SELECT token, request_uri, provider as \"provider: SsoProviderType\", provider_user_id,\n provider_username, provider_email\n FROM sso_pending_registration\n WHERE token = $1 AND expires_at > NOW()\n ", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "token", 9 + "type_info": "Text" 10 + }, 11 + { 12 + "ordinal": 1, 13 + "name": "request_uri", 14 + "type_info": "Text" 15 + }, 16 + { 17 + "ordinal": 2, 18 + "name": "provider: SsoProviderType", 19 + "type_info": { 20 + "Custom": { 21 + "name": "sso_provider_type", 22 + "kind": { 23 + "Enum": [ 24 + "github", 25 + "discord", 26 + "google", 27 + "gitlab", 28 + "oidc", 29 + "apple" 30 + ] 31 + } 32 + } 33 + } 34 + }, 35 + { 36 + "ordinal": 3, 37 + "name": "provider_user_id", 38 + "type_info": "Text" 39 + }, 40 + { 41 + "ordinal": 4, 42 + "name": "provider_username", 43 + "type_info": "Text" 44 + }, 45 + { 46 + "ordinal": 5, 47 + "name": "provider_email", 48 + "type_info": "Text" 49 + } 50 + ], 51 + "parameters": { 52 + "Left": [ 53 + "Text" 54 + ] 55 + }, 56 + "nullable": [ 57 + false, 58 + false, 59 + false, 60 + false, 61 + true, 62 + true 63 + ] 64 + }, 65 + "hash": "9fd56986c1c843d386d1e5884acef8573eb55a3e9f5cb0122fcf8b93d6d667a5" 66 + }
+34
.sqlx/query-a23a390659616779d7dbceaa3b5d5171e70fa25e3b8393e142cebcbff752f0f5.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT private_key_bytes, expires_at, used_at FROM reserved_signing_keys WHERE public_key_did_key = $1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "private_key_bytes", 9 + "type_info": "Bytea" 10 + }, 11 + { 12 + "ordinal": 1, 13 + "name": "expires_at", 14 + "type_info": "Timestamptz" 15 + }, 16 + { 17 + "ordinal": 2, 18 + "name": "used_at", 19 + "type_info": "Timestamptz" 20 + } 21 + ], 22 + "parameters": { 23 + "Left": [ 24 + "Text" 25 + ] 26 + }, 27 + "nullable": [ 28 + false, 29 + false, 30 + true 31 + ] 32 + }, 33 + "hash": "a23a390659616779d7dbceaa3b5d5171e70fa25e3b8393e142cebcbff752f0f5" 34 + }
+15
.sqlx/query-a3d549a32e76c24e265c73a98dd739067623f275de0740bd576ee288f4444496.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "\n UPDATE external_identities\n SET provider_username = $2, last_login_at = NOW()\n WHERE id = $1\n ", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Uuid", 9 + "Text" 10 + ] 11 + }, 12 + "nullable": [] 13 + }, 14 + "hash": "a3d549a32e76c24e265c73a98dd739067623f275de0740bd576ee288f4444496" 15 + }
+22
.sqlx/query-a802d7d860f263eace39ce82bb27b633cec7287c1cc177f0e1d47ec6571564d5.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT token FROM account_deletion_requests WHERE did = $1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "token", 9 + "type_info": "Text" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Text" 15 + ] 16 + }, 17 + "nullable": [ 18 + false 19 + ] 20 + }, 21 + "hash": "a802d7d860f263eace39ce82bb27b633cec7287c1cc177f0e1d47ec6571564d5" 22 + }
+28
.sqlx/query-aee3e8e1d8924d41bec7d866e274f8bb2ddef833eb03326103c2d0a17ee56154.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "\n DELETE FROM sso_auth_state\n WHERE state = $1 AND expires_at > NOW()\n RETURNING state, request_uri\n ", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "state", 9 + "type_info": "Text" 10 + }, 11 + { 12 + "ordinal": 1, 13 + "name": "request_uri", 14 + "type_info": "Text" 15 + } 16 + ], 17 + "parameters": { 18 + "Left": [ 19 + "Text" 20 + ] 21 + }, 22 + "nullable": [ 23 + false, 24 + false 25 + ] 26 + }, 27 + "hash": "aee3e8e1d8924d41bec7d866e274f8bb2ddef833eb03326103c2d0a17ee56154" 28 + }
.sqlx/query-b26bf97a27783eb7fb524a92dda3e68ef8470a9751fcaefe5fd2d7909dead54b.json

This patch was likely rebased, as context lines do not match.

.sqlx/query-b8101757a50075d20147014e450cb7deb7e58f84310690c7bde61e1834dc5903.json

This file has not been changed.

+31
.sqlx/query-ba9684872fad5201b8504c2606c29364a2df9631fe98817e7bfacd3f3f51f6cb.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "\n INSERT INTO sso_pending_registration (token, request_uri, provider, provider_user_id, expires_at)\n VALUES ($1, $2, $3, $4, NOW() - INTERVAL '1 hour')\n ", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Text", 9 + "Text", 10 + { 11 + "Custom": { 12 + "name": "sso_provider_type", 13 + "kind": { 14 + "Enum": [ 15 + "github", 16 + "discord", 17 + "google", 18 + "gitlab", 19 + "oidc", 20 + "apple" 21 + ] 22 + } 23 + } 24 + }, 25 + "Text" 26 + ] 27 + }, 28 + "nullable": [] 29 + }, 30 + "hash": "ba9684872fad5201b8504c2606c29364a2df9631fe98817e7bfacd3f3f51f6cb" 31 + }
+12
.sqlx/query-bb4460f75d30f48b79d71b97f2c7d54190260deba2d2ade177dbdaa507ab275b.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "DELETE FROM sso_auth_state WHERE expires_at < NOW()", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [] 8 + }, 9 + "nullable": [] 10 + }, 11 + "hash": "bb4460f75d30f48b79d71b97f2c7d54190260deba2d2ade177dbdaa507ab275b" 12 + }
+22
.sqlx/query-cd3b8098ad4c1056c1d23acd8a6b29f7abfe18ee6f559bd94ab16274b1cfdfee.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT password_reset_code FROM users WHERE email = $1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "password_reset_code", 9 + "type_info": "Text" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Text" 15 + ] 16 + }, 17 + "nullable": [ 18 + true 19 + ] 20 + }, 21 + "hash": "cd3b8098ad4c1056c1d23acd8a6b29f7abfe18ee6f559bd94ab16274b1cfdfee" 22 + }
+22
.sqlx/query-cda68f9b6c60295a196fc853b70ec5fd51a8ffaa2bac5942c115c99d1cbcafa3.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT COUNT(*) as \"count!\" FROM plc_operation_tokens t JOIN users u ON t.user_id = u.id WHERE u.did = $1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "count!", 9 + "type_info": "Int8" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Text" 15 + ] 16 + }, 17 + "nullable": [ 18 + null 19 + ] 20 + }, 21 + "hash": "cda68f9b6c60295a196fc853b70ec5fd51a8ffaa2bac5942c115c99d1cbcafa3" 22 + }
+31
.sqlx/query-d0d4fb4b44cda3442b20037b4d5efaa032e1d004c775e2b6077c5050d7d62041.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "\n INSERT INTO sso_auth_state (state, request_uri, provider, action, expires_at)\n VALUES ($1, $2, $3, $4, NOW() - INTERVAL '1 hour')\n ", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Text", 9 + "Text", 10 + { 11 + "Custom": { 12 + "name": "sso_provider_type", 13 + "kind": { 14 + "Enum": [ 15 + "github", 16 + "discord", 17 + "google", 18 + "gitlab", 19 + "oidc", 20 + "apple" 21 + ] 22 + } 23 + } 24 + }, 25 + "Text" 26 + ] 27 + }, 28 + "nullable": [] 29 + }, 30 + "hash": "d0d4fb4b44cda3442b20037b4d5efaa032e1d004c775e2b6077c5050d7d62041" 31 + }
+14
.sqlx/query-d529d6dc9858c1da360f0417e94a3b40041b043bae57e95002d4bf5df46a4ab4.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "UPDATE account_deletion_requests SET expires_at = NOW() - INTERVAL '1 hour' WHERE token = $1", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Text" 9 + ] 10 + }, 11 + "nullable": [] 12 + }, 13 + "hash": "d529d6dc9858c1da360f0417e94a3b40041b043bae57e95002d4bf5df46a4ab4" 14 + }
.sqlx/query-d8524ad3f5dc03eb09ed60396a78df5003f804c43ad253d6476523eacdebf811.json

This file has not been changed.

.sqlx/query-d8fd97c8be3211b2509669dd859245b14e15f81a42d7e0c4c428b65f466af5ee.json

Failed to calculate interdiff for this file.

+40
.sqlx/query-dd7d80d4d118a5fc95b574e2ca9ffaccf974e52fb6ac368f716409c55f9d3ab0.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "\n INSERT INTO external_identities (did, provider, provider_user_id, provider_username, provider_email)\n VALUES ($1, $2, $3, $4, $5)\n RETURNING id\n ", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "id", 9 + "type_info": "Uuid" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Text", 15 + { 16 + "Custom": { 17 + "name": "sso_provider_type", 18 + "kind": { 19 + "Enum": [ 20 + "github", 21 + "discord", 22 + "google", 23 + "gitlab", 24 + "oidc", 25 + "apple" 26 + ] 27 + } 28 + } 29 + }, 30 + "Text", 31 + "Text", 32 + "Text" 33 + ] 34 + }, 35 + "nullable": [ 36 + false 37 + ] 38 + }, 39 + "hash": "dd7d80d4d118a5fc95b574e2ca9ffaccf974e52fb6ac368f716409c55f9d3ab0" 40 + }
+22
.sqlx/query-e20cbe2a939d790aaea718b084a80d8ede655ba1cc0fd4346d7e91d6de7d6cf3.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT COUNT(*) FROM comms_queue WHERE user_id = $1 AND comms_type = 'password_reset'", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "count", 9 + "type_info": "Int8" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Uuid" 15 + ] 16 + }, 17 + "nullable": [ 18 + null 19 + ] 20 + }, 21 + "hash": "e20cbe2a939d790aaea718b084a80d8ede655ba1cc0fd4346d7e91d6de7d6cf3" 22 + }
.sqlx/query-e3aeec9a759b2b68cb11fa48b5d34ffc19430a6b16adb0c49307da0cacdf1ca3.json

This file has not been changed.

+22
.sqlx/query-e64cd36284d10ab7f3d9f6959975a1a627809f444b0faff7e611d985f31b90e9.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT used_at FROM reserved_signing_keys WHERE public_key_did_key = $1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "used_at", 9 + "type_info": "Timestamptz" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Text" 15 + ] 16 + }, 17 + "nullable": [ 18 + true 19 + ] 20 + }, 21 + "hash": "e64cd36284d10ab7f3d9f6959975a1a627809f444b0faff7e611d985f31b90e9" 22 + }
.sqlx/query-e7aa1080be9eb3a8ddf1f050c93dc8afd10478f41e22307014784b4ee3740b4a.json

This patch was likely rebased, as context lines do not match.

+30
.sqlx/query-eb54d2ce02cab7c2e7f9926bd469b19e5f0513f47173b2738fc01a57082d7abb.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "\n INSERT INTO external_identities (did, provider, provider_user_id)\n VALUES ($1, $2, $3)\n ", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Text", 9 + { 10 + "Custom": { 11 + "name": "sso_provider_type", 12 + "kind": { 13 + "Enum": [ 14 + "github", 15 + "discord", 16 + "google", 17 + "gitlab", 18 + "oidc", 19 + "apple" 20 + ] 21 + } 22 + } 23 + }, 24 + "Text" 25 + ] 26 + }, 27 + "nullable": [] 28 + }, 29 + "hash": "eb54d2ce02cab7c2e7f9926bd469b19e5f0513f47173b2738fc01a57082d7abb" 30 + }
+15
.sqlx/query-ec22a8cc89e480c403a239eac44288e144d83364129491de6156760616666d3d.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "DELETE FROM external_identities WHERE id = $1 AND did = $2", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Uuid", 9 + "Text" 10 + ] 11 + }, 12 + "nullable": [] 13 + }, 14 + "hash": "ec22a8cc89e480c403a239eac44288e144d83364129491de6156760616666d3d" 15 + }
+22
.sqlx/query-f26c13023b47b908ec96da2e6b8bf8b34ca6a2246c20fc96f76f0e95530762a7.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT email FROM users WHERE did = $1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "email", 9 + "type_info": "Text" 10 + } 11 + ], 12 + "parameters": { 13 + "Left": [ 14 + "Text" 15 + ] 16 + }, 17 + "nullable": [ 18 + true 19 + ] 20 + }, 21 + "hash": "f26c13023b47b908ec96da2e6b8bf8b34ca6a2246c20fc96f76f0e95530762a7" 22 + }
+14
.sqlx/query-f29da3bdfbbc547b339b4cdb059fac26435b0feec65cf1c56f851d1c4d6b1814.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "UPDATE users SET is_admin = TRUE WHERE did = $1", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Left": [ 8 + "Text" 9 + ] 10 + }, 11 + "nullable": [] 12 + }, 13 + "hash": "f29da3bdfbbc547b339b4cdb059fac26435b0feec65cf1c56f851d1c4d6b1814" 14 + }
+28
.sqlx/query-f7af28963099aec12cf1d4f8a9a03699bb3a90f39bc9c4c0f738a37827e8f382.json
··· 1 + { 2 + "db_name": "PostgreSQL", 3 + "query": "SELECT password_reset_code, password_reset_code_expires_at FROM users WHERE email = $1", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "ordinal": 0, 8 + "name": "password_reset_code", 9 + "type_info": "Text" 10 + }, 11 + { 12 + "ordinal": 1, 13 + "name": "password_reset_code_expires_at", 14 + "type_info": "Timestamptz" 15 + } 16 + ], 17 + "parameters": { 18 + "Left": [ 19 + "Text" 20 + ] 21 + }, 22 + "nullable": [ 23 + true, 24 + true 25 + ] 26 + }, 27 + "hash": "f7af28963099aec12cf1d4f8a9a03699bb3a90f39bc9c4c0f738a37827e8f382" 28 + }
crates/tranquil-db-traits/src/channel_verification.rs

This file has not been changed.

crates/tranquil-db-traits/src/delegation.rs

This file has not been changed.

+5 -1
crates/tranquil-db-traits/src/infra.rs
··· 33 33 34 34 impl From<bool> for InviteCodeState { 35 35 fn from(disabled: bool) -> Self { 36 - if disabled { Self::Disabled } else { Self::Active } 36 + if disabled { 37 + Self::Disabled 38 + } else { 39 + Self::Active 40 + } 37 41 } 38 42 } 39 43
crates/tranquil-db-traits/src/invite_code.rs

This file has not been changed.

crates/tranquil-db-traits/src/lib.rs

This file has not been changed.

+5 -1
crates/tranquil-db-traits/src/oauth.rs
··· 305 305 ) -> Result<(), DbError>; 306 306 307 307 async fn list_sessions_by_did(&self, did: &Did) -> Result<Vec<OAuthSessionListItem>, DbError>; 308 - async fn delete_session_by_id(&self, session_id: TokenFamilyId, did: &Did) -> Result<u64, DbError>; 308 + async fn delete_session_by_id( 309 + &self, 310 + session_id: TokenFamilyId, 311 + did: &Did, 312 + ) -> Result<u64, DbError>; 309 313 async fn delete_sessions_by_did(&self, did: &Did) -> Result<u64, DbError>; 310 314 async fn delete_sessions_by_did_except( 311 315 &self,
crates/tranquil-db-traits/src/repo.rs

This file has not been changed.

+17 -2
crates/tranquil-db-traits/src/scope.rs
··· 15 15 Self(String::new()) 16 16 } 17 17 18 - pub fn from_db_unchecked(scope: String) -> Self { 19 - Self(scope) 18 + pub fn from_db(scope: String) -> Self { 19 + match validate_scope_string(&scope) { 20 + Ok(()) => Self(scope), 21 + Err(e) => panic!("corrupted scope data from database: {}", e), 22 + } 20 23 } 21 24 22 25 pub fn as_str(&self) -> &str { ··· 161 164 fn test_display() { 162 165 let scope = DbScope::new("repo:*").unwrap(); 163 166 assert_eq!(format!("{}", scope), "repo:*"); 167 + } 168 + 169 + #[test] 170 + #[should_panic(expected = "corrupted scope data from database")] 171 + fn test_from_db_panics_on_corrupted_data() { 172 + DbScope::from_db("totally_invalid_garbage_scope".to_string()); 173 + } 174 + 175 + #[test] 176 + fn test_from_db_accepts_valid_data() { 177 + let scope = DbScope::from_db("repo:* blob:*/*".to_string()); 178 + assert_eq!(scope.as_str(), "repo:* blob:*/*"); 164 179 } 165 180 }
crates/tranquil-db-traits/src/sequence.rs

This file has not been changed.

+9 -2
crates/tranquil-db-traits/src/session.rs
··· 49 49 50 50 impl From<bool> for AppPasswordPrivilege { 51 51 fn from(privileged: bool) -> Self { 52 - if privileged { Self::Privileged } else { Self::Standard } 52 + if privileged { 53 + Self::Privileged 54 + } else { 55 + Self::Standard 56 + } 53 57 } 54 58 } 55 59 ··· 240 244 app_password_name: &str, 241 245 ) -> Result<Vec<String>, DbError>; 242 246 243 - async fn check_refresh_token_used(&self, refresh_jti: &str) -> Result<Option<SessionId>, DbError>; 247 + async fn check_refresh_token_used( 248 + &self, 249 + refresh_jti: &str, 250 + ) -> Result<Option<SessionId>, DbError>; 244 251 245 252 async fn mark_refresh_token_used( 246 253 &self,
crates/tranquil-db-traits/src/sso.rs

This file has not been changed.

crates/tranquil-db-traits/src/user.rs

This file has not been changed.

+4 -4
crates/tranquil-db/src/postgres/delegation.rs
··· 170 170 id: r.id, 171 171 delegated_did: r.delegated_did.into(), 172 172 controller_did: r.controller_did.into(), 173 - granted_scopes: DbScope::from_db_unchecked(r.granted_scopes), 173 + granted_scopes: DbScope::from_db(r.granted_scopes), 174 174 granted_at: r.granted_at, 175 175 granted_by: r.granted_by.into(), 176 176 revoked_at: r.revoked_at, ··· 206 206 .map(|r| ControllerInfo { 207 207 did: r.did.into(), 208 208 handle: r.handle.into(), 209 - granted_scopes: DbScope::from_db_unchecked(r.granted_scopes), 209 + granted_scopes: DbScope::from_db(r.granted_scopes), 210 210 granted_at: r.granted_at, 211 211 is_active: r.is_active, 212 212 }) ··· 243 243 .map(|r| DelegatedAccountInfo { 244 244 did: r.did.into(), 245 245 handle: r.handle.into(), 246 - granted_scopes: DbScope::from_db_unchecked(r.granted_scopes), 246 + granted_scopes: DbScope::from_db(r.granted_scopes), 247 247 granted_at: r.granted_at, 248 248 }) 249 249 .collect()) ··· 280 280 .map(|r| ControllerInfo { 281 281 did: r.did.into(), 282 282 handle: r.handle.into(), 283 - granted_scopes: DbScope::from_db_unchecked(r.granted_scopes), 283 + granted_scopes: DbScope::from_db(r.granted_scopes), 284 284 granted_at: r.granted_at, 285 285 is_active: r.is_active, 286 286 })
crates/tranquil-db/src/postgres/infra.rs

This file has not been changed.

+5 -1
crates/tranquil-db/src/postgres/oauth.rs
··· 1261 1261 .collect()) 1262 1262 } 1263 1263 1264 - async fn delete_session_by_id(&self, session_id: TokenFamilyId, did: &Did) -> Result<u64, DbError> { 1264 + async fn delete_session_by_id( 1265 + &self, 1266 + session_id: TokenFamilyId, 1267 + did: &Did, 1268 + ) -> Result<u64, DbError> { 1265 1269 let result = sqlx::query!( 1266 1270 "DELETE FROM oauth_token WHERE id = $1 AND did = $2", 1267 1271 session_id.as_i32(),
crates/tranquil-db/src/postgres/repo.rs

This file has not been changed.

+17 -8
crates/tranquil-db/src/postgres/session.rs
··· 154 154 } 155 155 156 156 async fn delete_session_by_id(&self, session_id: SessionId) -> Result<u64, DbError> { 157 - let result = sqlx::query!("DELETE FROM session_tokens WHERE id = $1", session_id.as_i32()) 158 - .execute(&self.pool) 159 - .await 160 - .map_err(map_sqlx_error)?; 157 + let result = sqlx::query!( 158 + "DELETE FROM session_tokens WHERE id = $1", 159 + session_id.as_i32() 160 + ) 161 + .execute(&self.pool) 162 + .await 163 + .map_err(map_sqlx_error)?; 161 164 162 165 Ok(result.rows_affected()) 163 166 } ··· 264 267 Ok(rows) 265 268 } 266 269 267 - async fn check_refresh_token_used(&self, refresh_jti: &str) -> Result<Option<SessionId>, DbError> { 270 + async fn check_refresh_token_used( 271 + &self, 272 + refresh_jti: &str, 273 + ) -> Result<Option<SessionId>, DbError> { 268 274 let row = sqlx::query_scalar!( 269 275 "SELECT session_id FROM used_refresh_tokens WHERE refresh_jti = $1", 270 276 refresh_jti ··· 542 548 .map_err(map_sqlx_error)?; 543 549 544 550 if result.rows_affected() == 0 { 545 - let _ = sqlx::query!("DELETE FROM session_tokens WHERE id = $1", data.session_id.as_i32()) 546 - .execute(&mut *tx) 547 - .await; 551 + let _ = sqlx::query!( 552 + "DELETE FROM session_tokens WHERE id = $1", 553 + data.session_id.as_i32() 554 + ) 555 + .execute(&mut *tx) 556 + .await; 548 557 tx.commit().await.map_err(map_sqlx_error)?; 549 558 return Ok(RefreshSessionResult::ConcurrentRefresh); 550 559 }
+3 -3
crates/tranquil-db/src/postgres/sso.rs
··· 70 70 71 71 Ok(row.map(|r| ExternalIdentity { 72 72 id: r.id, 73 - did: Did::new_unchecked(&r.did), 73 + did: unsafe { Did::new_unchecked(&r.did) }, 74 74 provider: r.provider, 75 75 provider_user_id: ExternalUserId::from(r.provider_user_id), 76 76 provider_username: r.provider_username.map(ExternalUsername::from), ··· 103 103 .into_iter() 104 104 .map(|r| ExternalIdentity { 105 105 id: r.id, 106 - did: Did::new_unchecked(&r.did), 106 + did: unsafe { Did::new_unchecked(&r.did) }, 107 107 provider: r.provider, 108 108 provider_user_id: ExternalUserId::from(r.provider_user_id), 109 109 provider_username: r.provider_username.map(ExternalUsername::from), ··· 210 210 action, 211 211 nonce: r.nonce, 212 212 code_verifier: r.code_verifier, 213 - did: r.did.map(|d| Did::new_unchecked(&d)), 213 + did: r.did.map(|d| unsafe { Did::new_unchecked(&d) }), 214 214 created_at: r.created_at, 215 215 expires_at: r.expires_at, 216 216 })
+6 -5
crates/tranquil-db/src/postgres/user.rs
··· 9 9 DidWebOverrides, NotificationPrefs, OAuthTokenWithUser, PasswordResetResult, SsoProviderType, 10 10 StoredBackupCode, StoredPasskey, TotpRecord, TotpRecordState, User2faStatus, UserAuthInfo, 11 11 UserCommsPrefs, UserConfirmSignup, UserDidWebInfo, UserEmailInfo, UserForDeletion, 12 - UserForDidDoc, UserForDidDocBuild, UserForPasskeyRecovery, UserForPasskeySetup, UserForRecovery, 13 - UserForVerification, UserIdAndHandle, UserIdAndPasswordHash, UserIdHandleEmail, UserInfoForAuth, 14 - UserKeyInfo, UserKeyWithId, UserLegacyLoginPref, UserLoginCheck, UserLoginFull, UserLoginInfo, 15 - UserPasswordInfo, UserRepository, UserResendVerification, UserResetCodeInfo, UserRow, 16 - UserSessionInfo, UserStatus, UserVerificationInfo, UserWithKey, 12 + UserForDidDoc, UserForDidDocBuild, UserForPasskeyRecovery, UserForPasskeySetup, 13 + UserForRecovery, UserForVerification, UserIdAndHandle, UserIdAndPasswordHash, 14 + UserIdHandleEmail, UserInfoForAuth, UserKeyInfo, UserKeyWithId, UserLegacyLoginPref, 15 + UserLoginCheck, UserLoginFull, UserLoginInfo, UserPasswordInfo, UserRepository, 16 + UserResendVerification, UserResetCodeInfo, UserRow, UserSessionInfo, UserStatus, 17 + UserVerificationInfo, UserWithKey, 17 18 }; 18 19 19 20 pub struct PostgresUserRepository {
crates/tranquil-oauth/src/lib.rs

This file has not been changed.

crates/tranquil-oauth/src/types.rs

This file has not been changed.

crates/tranquil-pds/src/api/admin/account/delete.rs

This file has not been changed.

crates/tranquil-pds/src/api/admin/account/email.rs

This file has not been changed.

crates/tranquil-pds/src/api/admin/account/info.rs

This file has not been changed.

crates/tranquil-pds/src/api/admin/account/search.rs

This file has not been changed.

+1 -1
crates/tranquil-pds/src/api/admin/account/update.rs
··· 84 84 .ok() 85 85 .flatten() 86 86 .ok_or(ApiError::AccountNotFound)?; 87 - let handle_for_check = Handle::new_unchecked(&handle); 87 + let handle_for_check = unsafe { Handle::new_unchecked(&handle) }; 88 88 if let Ok(true) = state 89 89 .user_repo 90 90 .check_handle_exists(&handle_for_check, user_id)
+1 -1
crates/tranquil-pds/src/api/admin/config.rs
··· 187 187 }; 188 188 189 189 if let Some(old_cid_str) = should_delete_old { 190 - let old_cid = CidLink::new_unchecked(old_cid_str); 190 + let old_cid = unsafe { CidLink::new_unchecked(old_cid_str) }; 191 191 if let Ok(Some(storage_key)) = 192 192 state.infra_repo.get_blob_storage_key_by_cid(&old_cid).await 193 193 {
crates/tranquil-pds/src/api/admin/invite.rs

This file has not been changed.

+1 -1
crates/tranquil-pds/src/api/admin/status.rs
··· 175 175 Some("com.atproto.admin.defs#repoRef") => { 176 176 let did_str = input.subject.get("did").and_then(|d| d.as_str()); 177 177 if let Some(did_str) = did_str { 178 - let did = Did::new_unchecked(did_str); 178 + let did = unsafe { Did::new_unchecked(did_str) }; 179 179 if let Some(takedown) = &input.takedown { 180 180 let takedown_ref = if takedown.applied { 181 181 takedown.r#ref.as_deref()
crates/tranquil-pds/src/api/age_assurance.rs

This file has not been changed.

+12 -13
crates/tranquil-pds/src/api/delegation.rs
··· 217 217 ) -> Result<Response, ApiError> { 218 218 match state 219 219 .delegation_repo 220 - .update_delegation_scopes( 221 - &auth.did, 222 - &input.controller_did, 223 - &input.granted_scopes, 224 - ) 220 + .update_delegation_scopes(&auth.did, &input.controller_did, &input.granted_scopes) 225 221 .await 226 222 { 227 223 Ok(true) => { ··· 533 529 .into_response()); 534 530 } 535 531 536 - let did = Did::new_unchecked(&genesis_result.did); 537 - let handle = Handle::new_unchecked(&handle); 532 + let did = unsafe { Did::new_unchecked(&genesis_result.did) }; 533 + let handle = unsafe { Handle::new_unchecked(&handle) }; 538 534 info!(did = %did, handle = %handle, controller = %can_control.did(), "Created DID for delegated account"); 539 535 540 536 let encrypted_key_bytes = match crate::config::encrypt_key(&secret_key_bytes) { ··· 603 599 } 604 600 }; 605 601 606 - if let Some(validated) = validated_invite_code { 607 - if let Err(e) = state.infra_repo.record_invite_code_use(&validated, user_id).await { 608 - warn!("Failed to record invite code use for {}: {:?}", did, e); 609 - } 602 + if let Some(validated) = validated_invite_code 603 + && let Err(e) = state 604 + .infra_repo 605 + .record_invite_code_use(&validated, user_id) 606 + .await 607 + { 608 + warn!("Failed to record invite code use for {}: {:?}", did, e); 610 609 } 611 610 612 611 if let Err(e) = ··· 628 627 "$type": "app.bsky.actor.profile", 629 628 "displayName": handle 630 629 }); 631 - let profile_collection = Nsid::new_unchecked("app.bsky.actor.profile"); 632 - let profile_rkey = Rkey::new_unchecked("self"); 630 + let profile_collection = unsafe { Nsid::new_unchecked("app.bsky.actor.profile") }; 631 + let profile_rkey = unsafe { Rkey::new_unchecked("self") }; 633 632 if let Err(e) = crate::api::repo::record::create_record_internal( 634 633 &state, 635 634 &did,
crates/tranquil-pds/src/api/error.rs

This file has not been changed.

+14 -14
crates/tranquil-pds/src/api/identity/account.rs
··· 380 380 }; 381 381 if is_migration { 382 382 let reactivate_input = tranquil_db_traits::MigrationReactivationInput { 383 - did: Did::new_unchecked(&did), 384 - new_handle: Handle::new_unchecked(&handle), 383 + did: unsafe { Did::new_unchecked(&did) }, 384 + new_handle: unsafe { Handle::new_unchecked(&handle) }, 385 385 new_email: email.clone(), 386 386 }; 387 387 match state ··· 435 435 } 436 436 }; 437 437 let session_data = tranquil_db_traits::SessionTokenCreate { 438 - did: Did::new_unchecked(&did), 438 + did: unsafe { Did::new_unchecked(&did) }, 439 439 access_jti: access_meta.jti.clone(), 440 440 refresh_jti: refresh_meta.jti.clone(), 441 441 access_expires_at: access_meta.expires_at, ··· 476 476 axum::http::StatusCode::OK, 477 477 Json(CreateAccountOutput { 478 478 handle: handle.clone().into(), 479 - did: Did::new_unchecked(&did), 479 + did: unsafe { Did::new_unchecked(&did) }, 480 480 did_doc: state.did_resolver.resolve_did_document(&did).await, 481 481 access_jwt: access_meta.token, 482 482 refresh_jwt: refresh_meta.token, ··· 500 500 } 501 501 } 502 502 503 - let handle_typed = Handle::new_unchecked(&handle); 503 + let handle_typed = unsafe { Handle::new_unchecked(&handle) }; 504 504 let handle_available = match state 505 505 .user_repo 506 506 .check_handle_available_for_new_account(&handle_typed) ··· 584 584 } 585 585 }; 586 586 let rev = Tid::now(LimitedU32::MIN); 587 - let did_for_commit = Did::new_unchecked(&did); 587 + let did_for_commit = unsafe { Did::new_unchecked(&did) }; 588 588 let (commit_bytes, _sig) = 589 589 match create_signed_commit(&did_for_commit, mst_root, rev.as_ref(), None, &signing_key) { 590 590 Ok(result) => result, ··· 620 620 }; 621 621 622 622 let create_input = tranquil_db_traits::CreatePasswordAccountInput { 623 - handle: Handle::new_unchecked(&handle), 623 + handle: unsafe { Handle::new_unchecked(&handle) }, 624 624 email: email.clone(), 625 - did: Did::new_unchecked(&did), 625 + did: unsafe { Did::new_unchecked(&did) }, 626 626 password_hash, 627 627 preferred_comms_channel, 628 628 discord_id: input ··· 672 672 }; 673 673 let user_id = create_result.user_id; 674 674 if !is_migration && !is_did_web_byod { 675 - let did_typed = Did::new_unchecked(&did); 676 - let handle_typed = Handle::new_unchecked(&handle); 675 + let did_typed = unsafe { Did::new_unchecked(&did) }; 676 + let handle_typed = unsafe { Handle::new_unchecked(&handle) }; 677 677 if let Err(e) = crate::api::repo::record::sequence_identity_event( 678 678 &state, 679 679 &did_typed, ··· 717 717 "$type": "app.bsky.actor.profile", 718 718 "displayName": input.handle 719 719 }); 720 - let profile_collection = Nsid::new_unchecked("app.bsky.actor.profile"); 721 - let profile_rkey = Rkey::new_unchecked("self"); 720 + let profile_collection = unsafe { Nsid::new_unchecked("app.bsky.actor.profile") }; 721 + let profile_rkey = unsafe { Rkey::new_unchecked("self") }; 722 722 if let Err(e) = crate::api::repo::record::create_record_internal( 723 723 &state, 724 724 &did_typed, ··· 791 791 } 792 792 }; 793 793 let session_data = tranquil_db_traits::SessionTokenCreate { 794 - did: Did::new_unchecked(&did), 794 + did: unsafe { Did::new_unchecked(&did) }, 795 795 access_jti: access_meta.jti.clone(), 796 796 refresh_jti: refresh_meta.jti.clone(), 797 797 access_expires_at: access_meta.expires_at, ··· 820 820 StatusCode::OK, 821 821 Json(CreateAccountOutput { 822 822 handle: handle.clone().into(), 823 - did: Did::new_unchecked(&did), 823 + did: unsafe { Did::new_unchecked(&did) }, 824 824 did_doc, 825 825 access_jwt: access_meta.token, 826 826 refresh_jwt: refresh_meta.token,
+2 -2
crates/tranquil-pds/src/api/identity/did.rs
··· 652 652 format!("{}.{}", new_handle, hostname_for_handles) 653 653 }; 654 654 if full_handle == current_handle { 655 - let handle_typed = Handle::new_unchecked(&full_handle); 655 + let handle_typed = unsafe { Handle::new_unchecked(&full_handle) }; 656 656 if let Err(e) = 657 657 crate::api::repo::record::sequence_identity_event(&state, &did, Some(&handle_typed)) 658 658 .await ··· 675 675 full_handle 676 676 } else { 677 677 if new_handle == current_handle { 678 - let handle_typed = Handle::new_unchecked(&new_handle); 678 + let handle_typed = unsafe { Handle::new_unchecked(&new_handle) }; 679 679 if let Err(e) = 680 680 crate::api::repo::record::sequence_identity_event(&state, &did, Some(&handle_typed)) 681 681 .await
crates/tranquil-pds/src/api/identity/plc/request.rs

This file has not been changed.

crates/tranquil-pds/src/api/identity/plc/sign.rs

This file has not been changed.

crates/tranquil-pds/src/api/identity/plc/submit.rs

This file has not been changed.

crates/tranquil-pds/src/api/notification_prefs.rs

This file has not been changed.

crates/tranquil-pds/src/api/proxy.rs

This file has not been changed.

+1 -1
crates/tranquil-pds/src/api/repo/blob.rs
··· 136 136 }; 137 137 let cid = Cid::new_v1(0x55, multihash); 138 138 let cid_str = cid.to_string(); 139 - let cid_link: CidLink = CidLink::new_unchecked(&cid_str); 139 + let cid_link: CidLink = unsafe { CidLink::new_unchecked(&cid_str) }; 140 140 let storage_key = cid_str.clone(); 141 141 142 142 info!(
+5 -6
crates/tranquil-pds/src/api/repo/import.rs
··· 204 204 let record_uri = 205 205 AtUri::from_parts(did.as_str(), &record.collection, &record.rkey); 206 206 record.blob_refs.iter().map(move |blob_ref| { 207 - ( 208 - record_uri.clone(), 209 - CidLink::new_unchecked(blob_ref.cid.clone()), 210 - ) 207 + (record_uri.clone(), unsafe { 208 + CidLink::new_unchecked(blob_ref.cid.clone()) 209 + }) 211 210 }) 212 211 }) 213 212 .collect(); ··· 272 271 error!("Failed to store new commit block: {:?}", e); 273 272 ApiError::InternalError(None) 274 273 })?; 275 - let new_root_cid_link = CidLink::new_unchecked(new_root_cid.to_string()); 274 + let new_root_cid_link = unsafe { CidLink::new_unchecked(new_root_cid.to_string()) }; 276 275 state 277 276 .repo_repo 278 277 .update_repo_root(user_id, &new_root_cid_link, &new_rev_str) ··· 366 365 let data = tranquil_db::CommitEventData { 367 366 did: did.clone(), 368 367 event_type: tranquil_db::RepoEventType::Commit, 369 - commit_cid: Some(CidLink::new_unchecked(commit_cid)), 368 + commit_cid: Some(unsafe { CidLink::new_unchecked(commit_cid) }), 370 369 prev_cid: None, 371 370 ops: Some(serde_json::json!([])), 372 371 blobs: Some(vec![]),
crates/tranquil-pds/src/api/repo/meta.rs

This file has not been changed.

crates/tranquil-pds/src/api/repo/record/batch.rs

This file has not been changed.

crates/tranquil-pds/src/api/repo/record/delete.rs

This file has not been changed.

crates/tranquil-pds/src/api/repo/record/mod.rs

This file has not been changed.

crates/tranquil-pds/src/api/repo/record/pagination.rs

This file has not been changed.

crates/tranquil-pds/src/api/repo/record/read.rs

This file has not been changed.

+12 -11
crates/tranquil-pds/src/api/repo/record/utils.rs
··· 201 201 upserts.push(RecordUpsert { 202 202 collection: collection.clone(), 203 203 rkey: rkey.clone(), 204 - cid: crate::types::CidLink::new_unchecked(cid.to_string()), 204 + cid: unsafe { crate::types::CidLink::new_unchecked(cid.to_string()) }, 205 205 }); 206 206 } 207 207 RecordOp::Delete { ··· 266 266 let commit_event = CommitEventData { 267 267 did: did.clone(), 268 268 event_type: RepoEventType::Commit, 269 - commit_cid: Some(crate::types::CidLink::new_unchecked( 270 - new_root_cid.to_string(), 271 - )), 272 - prev_cid: current_root_cid.map(|c| crate::types::CidLink::new_unchecked(c.to_string())), 269 + commit_cid: Some(unsafe { crate::types::CidLink::new_unchecked(new_root_cid.to_string()) }), 270 + prev_cid: current_root_cid 271 + .map(|c| unsafe { crate::types::CidLink::new_unchecked(c.to_string()) }), 273 272 ops: Some(json!(ops_json)), 274 273 blobs: Some(blobs.to_vec()), 275 274 blocks_cids: Some(blocks_cids.to_vec()), 276 - prev_data_cid: prev_data_cid.map(|c| crate::types::CidLink::new_unchecked(c.to_string())), 275 + prev_data_cid: prev_data_cid 276 + .map(|c| unsafe { crate::types::CidLink::new_unchecked(c.to_string()) }), 277 277 rev: Some(rev_str.clone()), 278 278 }; 279 279 ··· 281 281 user_id, 282 282 did: did.clone(), 283 283 expected_root_cid: current_root_cid 284 - .map(|c| crate::types::CidLink::new_unchecked(c.to_string())), 285 - new_root_cid: crate::types::CidLink::new_unchecked(new_root_cid.to_string()), 284 + .map(|c| unsafe { crate::types::CidLink::new_unchecked(c.to_string()) }), 285 + new_root_cid: unsafe { crate::types::CidLink::new_unchecked(new_root_cid.to_string()) }, 286 286 new_rev: rev_str.clone(), 287 287 new_block_cids: all_block_cids, 288 288 obsolete_block_cids: obsolete_bytes, ··· 443 443 commit_cid: &str, 444 444 rev: Option<&str>, 445 445 ) -> Result<SequenceNumber, String> { 446 - let cid_link = crate::types::CidLink::new_unchecked(commit_cid); 446 + let cid_link = unsafe { crate::types::CidLink::new_unchecked(commit_cid) }; 447 447 state 448 448 .repo_repo 449 449 .insert_sync_event(did, &cid_link, rev) ··· 458 458 mst_root_cid: &Cid, 459 459 rev: &str, 460 460 ) -> Result<SequenceNumber, String> { 461 - let commit_cid_link = crate::types::CidLink::new_unchecked(commit_cid.to_string()); 462 - let mst_root_cid_link = crate::types::CidLink::new_unchecked(mst_root_cid.to_string()); 461 + let commit_cid_link = unsafe { crate::types::CidLink::new_unchecked(commit_cid.to_string()) }; 462 + let mst_root_cid_link = 463 + unsafe { crate::types::CidLink::new_unchecked(mst_root_cid.to_string()) }; 463 464 state 464 465 .repo_repo 465 466 .insert_genesis_commit_event(did, &commit_cid_link, &mst_root_cid_link, rev)
crates/tranquil-pds/src/api/repo/record/validation_mode.rs

This file has not been changed.

crates/tranquil-pds/src/api/repo/record/write.rs

This file has not been changed.

crates/tranquil-pds/src/api/server/account_status.rs

This file has not been changed.

+2 -1
crates/tranquil-pds/src/api/server/app_password.rs
··· 150 150 ApiError::InternalError(None) 151 151 })?; 152 152 153 - let privilege = tranquil_db_traits::AppPasswordPrivilege::from(input.privileged.unwrap_or(false)); 153 + let privilege = 154 + tranquil_db_traits::AppPasswordPrivilege::from(input.privileged.unwrap_or(false)); 154 155 let created_at = chrono::Utc::now(); 155 156 156 157 let create_data = AppPasswordCreate {
crates/tranquil-pds/src/api/server/email.rs

This file has not been changed.

crates/tranquil-pds/src/api/server/invite.rs

This file has not been changed.

crates/tranquil-pds/src/api/server/meta.rs

This file has not been changed.

crates/tranquil-pds/src/api/server/migration.rs

This file has not been changed.

+4 -4
crates/tranquil-pds/src/api/server/passkey_account.rs
··· 362 362 } 363 363 }; 364 364 let rev = Tid::now(LimitedU32::MIN); 365 - let did_typed = Did::new_unchecked(&did); 365 + let did_typed = unsafe { Did::new_unchecked(&did) }; 366 366 let (commit_bytes, _sig) = 367 367 match create_signed_commit(&did_typed, mst_root, rev.as_ref(), None, &secret_key) { 368 368 Ok(result) => result, ··· 395 395 _ => tranquil_db_traits::CommsChannel::Email, 396 396 }; 397 397 398 - let handle_typed = Handle::new_unchecked(&handle); 398 + let handle_typed = unsafe { Handle::new_unchecked(&handle) }; 399 399 let create_input = tranquil_db_traits::CreatePasskeyAccountInput { 400 400 handle: handle_typed.clone(), 401 401 email: email.clone().unwrap_or_default(), ··· 470 470 "$type": "app.bsky.actor.profile", 471 471 "displayName": handle 472 472 }); 473 - let profile_collection = Nsid::new_unchecked("app.bsky.actor.profile"); 474 - let profile_rkey = Rkey::new_unchecked("self"); 473 + let profile_collection = unsafe { Nsid::new_unchecked("app.bsky.actor.profile") }; 474 + let profile_rkey = unsafe { Rkey::new_unchecked("self") }; 475 475 if let Err(e) = crate::api::repo::record::create_record_internal( 476 476 &state, 477 477 &did_typed,
crates/tranquil-pds/src/api/server/passkeys.rs

This file has not been changed.

crates/tranquil-pds/src/api/server/password.rs

This file has not been changed.

crates/tranquil-pds/src/api/server/reauth.rs

This file has not been changed.

+1 -1
crates/tranquil-pds/src/api/server/service_auth.rs
··· 94 94 .await 95 95 { 96 96 Ok(result) => crate::auth::AuthenticatedUser { 97 - did: Did::new_unchecked(result.did), 97 + did: unsafe { Did::new_unchecked(result.did) }, 98 98 is_admin: false, 99 99 status: AccountStatus::Active, 100 100 scope: result.scope,
+6 -4
crates/tranquil-pds/src/api/server/session.rs
··· 271 271 tranquil_db_traits::CommsChannel::Telegram => "telegram", 272 272 tranquil_db_traits::CommsChannel::Signal => "signal", 273 273 }; 274 - let preferred_channel_verified = 275 - row.channel_verification.is_verified(row.preferred_comms_channel); 274 + let preferred_channel_verified = row 275 + .channel_verification 276 + .is_verified(row.preferred_comms_channel); 276 277 let pds_hostname = pds_hostname(); 277 278 let handle = full_handle(&row.handle, pds_hostname); 278 279 let account_state = AccountState::from_db_fields( ··· 477 478 tranquil_db_traits::CommsChannel::Telegram => "telegram", 478 479 tranquil_db_traits::CommsChannel::Signal => "signal", 479 480 }; 480 - let preferred_channel_verified = 481 - u.channel_verification.is_verified(u.preferred_comms_channel); 481 + let preferred_channel_verified = u 482 + .channel_verification 483 + .is_verified(u.preferred_comms_channel); 482 484 let pds_hostname = pds_hostname(); 483 485 let handle = full_handle(&u.handle, pds_hostname); 484 486 let account_state =
crates/tranquil-pds/src/api/server/totp.rs

This file has not been changed.

crates/tranquil-pds/src/api/server/trusted_devices.rs

This file has not been changed.

crates/tranquil-pds/src/api/server/verify_email.rs

This file has not been changed.

crates/tranquil-pds/src/api/server/verify_token.rs

This file has not been changed.

crates/tranquil-pds/src/auth/account_verified.rs

This file has not been changed.

crates/tranquil-pds/src/auth/auth_extractor.rs

This file has not been changed.

crates/tranquil-pds/src/auth/extractor.rs

This file has not been changed.

crates/tranquil-pds/src/auth/login_identifier.rs

This file has not been changed.

crates/tranquil-pds/src/auth/mfa_verified.rs

This file has not been changed.

+6 -4
crates/tranquil-pds/src/auth/mod.rs
··· 426 426 .claims 427 427 .act 428 428 .as_ref() 429 - .map(|a| Did::new_unchecked(a.sub.clone())); 429 + .map(|a| unsafe { Did::new_unchecked(a.sub.clone()) }); 430 430 let status = 431 431 AccountStatus::from_db_fields(takedown_ref.as_deref(), deactivated_at); 432 432 return Ok(AuthenticatedUser { ··· 478 478 None 479 479 }; 480 480 return Ok(AuthenticatedUser { 481 - did: Did::new_unchecked(oauth_token.did), 481 + did: unsafe { Did::new_unchecked(oauth_token.did) }, 482 482 key_bytes, 483 483 is_admin: oauth_token.is_admin, 484 484 status, 485 485 scope: oauth_info.scope, 486 - controller_did: oauth_info.controller_did.map(Did::new_unchecked), 486 + controller_did: oauth_info 487 + .controller_did 488 + .map(|d| unsafe { Did::new_unchecked(d) }), 487 489 auth_source: AuthSource::OAuth, 488 490 }); 489 491 } else { ··· 562 564 None 563 565 }; 564 566 Ok(AuthenticatedUser { 565 - did: Did::new_unchecked(result.did), 567 + did: unsafe { Did::new_unchecked(result.did) }, 566 568 key_bytes, 567 569 is_admin: user_info.is_admin, 568 570 status,
crates/tranquil-pds/src/auth/scope_verified.rs

This file has not been changed.

crates/tranquil-pds/src/auth/service.rs

This file has not been changed.

crates/tranquil-pds/src/auth/webauthn.rs

This file has not been changed.

crates/tranquil-pds/src/cid_types.rs

This file has not been changed.

+5 -7
crates/tranquil-pds/src/comms/service.rs
··· 3 3 use std::time::Duration; 4 4 5 5 use chrono::Utc; 6 - use tokio::sync::watch; 7 6 use tokio::time::interval; 7 + use tokio_util::sync::CancellationToken; 8 8 use tracing::{debug, error, info, warn}; 9 9 use tranquil_comms::{ 10 10 CommsChannel, CommsSender, CommsStatus, CommsType, NewComms, SendError, format_message, ··· 96 96 !self.senders.is_empty() 97 97 } 98 98 99 - pub async fn run(self, mut shutdown: watch::Receiver<bool>) { 99 + pub async fn run(self, shutdown: CancellationToken) { 100 100 if self.senders.is_empty() { 101 101 warn!( 102 102 "Comms service starting with no senders configured. Messages will be queued but not delivered until senders are configured." ··· 116 116 error!(error = %e, "Failed to process comms batch"); 117 117 } 118 118 } 119 - _ = shutdown.changed() => { 120 - if *shutdown.borrow() { 121 - info!("Comms service shutting down"); 122 - break; 123 - } 119 + _ = shutdown.cancelled() => { 120 + info!("Comms service shutting down"); 121 + break; 124 122 } 125 123 } 126 124 }
+6 -7
crates/tranquil-pds/src/crawlers.rs
··· 5 5 use std::sync::Arc; 6 6 use std::sync::atomic::{AtomicU64, Ordering}; 7 7 use std::time::Duration; 8 - use tokio::sync::{broadcast, watch}; 8 + use tokio::sync::broadcast; 9 + use tokio_util::sync::CancellationToken; 9 10 use tracing::{debug, error, info, warn}; 10 11 use tranquil_db_traits::RepoEventType; 11 12 ··· 148 149 pub async fn start_crawlers_service( 149 150 crawlers: Arc<Crawlers>, 150 151 mut firehose_rx: broadcast::Receiver<SequencedEvent>, 151 - mut shutdown: watch::Receiver<bool>, 152 + shutdown: CancellationToken, 152 153 ) { 153 154 info!( 154 155 hostname = %crawlers.hostname, ··· 176 177 } 177 178 } 178 179 } 179 - _ = shutdown.changed() => { 180 - if *shutdown.borrow() { 181 - info!("Crawlers service shutting down"); 182 - break; 183 - } 180 + _ = shutdown.cancelled() => { 181 + info!("Crawlers service shutting down"); 182 + break; 184 183 } 185 184 } 186 185 }
crates/tranquil-pds/src/delegation/mod.rs

This file has not been changed.

crates/tranquil-pds/src/delegation/roles.rs

This file has not been changed.

+3 -1
crates/tranquil-pds/src/delegation/scopes.rs
··· 1 1 use std::collections::HashSet; 2 2 3 - pub use tranquil_db_traits::{DbScope as ValidatedDelegationScope, InvalidScopeError as InvalidDelegationScopeError}; 3 + pub use tranquil_db_traits::{ 4 + DbScope as ValidatedDelegationScope, InvalidScopeError as InvalidDelegationScopeError, 5 + }; 4 6 5 7 pub struct ScopePreset { 6 8 pub name: &'static str,
crates/tranquil-pds/src/lib.rs

This file has not been changed.

crates/tranquil-pds/src/oauth/endpoints/authorize.rs

This file has not been changed.

crates/tranquil-pds/src/oauth/endpoints/delegation.rs

This file has not been changed.

crates/tranquil-pds/src/oauth/endpoints/metadata.rs

This file has not been changed.

crates/tranquil-pds/src/oauth/endpoints/par.rs

This file has not been changed.

crates/tranquil-pds/src/oauth/endpoints/token/grants.rs

This file has not been changed.

crates/tranquil-pds/src/oauth/endpoints/token/helpers.rs

This file has not been changed.

crates/tranquil-pds/src/oauth/endpoints/token/introspect.rs

This file has not been changed.

crates/tranquil-pds/src/oauth/endpoints/token/mod.rs

This file has not been changed.

crates/tranquil-pds/src/oauth/mod.rs

This file has not been changed.

crates/tranquil-pds/src/oauth/verify.rs

This file has not been changed.

crates/tranquil-pds/src/rate_limit/extractor.rs

This file has not been changed.

crates/tranquil-pds/src/rate_limit/mod.rs

This file has not been changed.

+10 -14
crates/tranquil-pds/src/scheduled.rs
··· 5 5 use std::str::FromStr; 6 6 use std::sync::Arc; 7 7 use std::time::Duration; 8 - use tokio::sync::watch; 9 8 use tokio::time::interval; 9 + use tokio_util::sync::CancellationToken; 10 10 use tracing::{debug, error, info, warn}; 11 11 use tranquil_db_traits::{ 12 12 BackupRepository, BlobRepository, BrokenGenesisCommit, RepoRepository, SequenceNumber, ··· 314 314 record.collection.as_str(), 315 315 record.rkey.as_str(), 316 316 ); 317 - (record_uri, CidLink::new_unchecked(blob_ref.cid)) 317 + (record_uri, unsafe { CidLink::new_unchecked(blob_ref.cid) }) 318 318 }) 319 319 .collect::<Vec<_>>(), 320 320 ) ··· 392 392 blob_repo: Arc<dyn BlobRepository>, 393 393 blob_store: Arc<dyn BlobStorage>, 394 394 sso_repo: Arc<dyn SsoRepository>, 395 - mut shutdown_rx: watch::Receiver<bool>, 395 + shutdown: CancellationToken, 396 396 ) { 397 397 let check_interval = Duration::from_secs( 398 398 std::env::var("SCHEDULED_DELETE_CHECK_INTERVAL_SECS") ··· 411 411 412 412 loop { 413 413 tokio::select! { 414 - _ = shutdown_rx.changed() => { 415 - if *shutdown_rx.borrow() { 416 - info!("Scheduled tasks service shutting down"); 417 - break; 418 - } 414 + _ = shutdown.cancelled() => { 415 + info!("Scheduled tasks service shutting down"); 416 + break; 419 417 } 420 418 _ = ticker.tick() => { 421 419 if let Err(e) = process_scheduled_deletions( ··· 538 536 backup_repo: Arc<dyn BackupRepository>, 539 537 block_store: PostgresBlockStore, 540 538 backup_storage: Arc<dyn BackupStorage>, 541 - mut shutdown_rx: watch::Receiver<bool>, 539 + shutdown: CancellationToken, 542 540 ) { 543 541 let backup_interval = Duration::from_secs(backup_interval_secs()); 544 542 ··· 553 551 554 552 loop { 555 553 tokio::select! { 556 - _ = shutdown_rx.changed() => { 557 - if *shutdown_rx.borrow() { 558 - info!("Backup service shutting down"); 559 - break; 560 - } 554 + _ = shutdown.cancelled() => { 555 + info!("Backup service shutting down"); 556 + break; 561 557 } 562 558 _ = ticker.tick() => { 563 559 if let Err(e) = process_scheduled_backups(
crates/tranquil-pds/src/sso/config.rs

This file has not been changed.

+25 -9
crates/tranquil-pds/src/sso/endpoints.rs
··· 789 789 790 790 let hostname_for_handles = pds_hostname_without_port(); 791 791 let full_handle = format!("{}.{}", validated, hostname_for_handles); 792 - let handle_typed = crate::types::Handle::new_unchecked(&full_handle); 792 + let handle_typed = unsafe { crate::types::Handle::new_unchecked(&full_handle) }; 793 793 794 794 let db_available = state 795 795 .user_repo ··· 881 881 let email = input 882 882 .email 883 883 .clone() 884 - .or_else(|| pending_preview.provider_email.clone().map(|e| e.into_inner())) 884 + .or_else(|| { 885 + pending_preview 886 + .provider_email 887 + .clone() 888 + .map(|e| e.into_inner()) 889 + }) 885 890 .map(|e| e.trim().to_string()) 886 891 .filter(|e| !e.is_empty()); 887 892 match email { ··· 907 912 let email = input 908 913 .email 909 914 .clone() 910 - .or_else(|| pending_preview.provider_email.clone().map(|e| e.into_inner())) 915 + .or_else(|| { 916 + pending_preview 917 + .provider_email 918 + .clone() 919 + .map(|e| e.into_inner()) 920 + }) 911 921 .map(|e| e.trim().to_string()) 912 922 .filter(|e| !e.is_empty()); 913 923 ··· 939 949 None 940 950 }; 941 951 942 - let handle_typed = crate::types::Handle::new_unchecked(&handle); 952 + let handle_typed = unsafe { crate::types::Handle::new_unchecked(&handle) }; 943 953 let reserved = state 944 954 .user_repo 945 955 .reserve_handle(&handle_typed, client_ip) ··· 1041 1051 }; 1042 1052 1043 1053 let rev = Tid::now(LimitedU32::MIN); 1044 - let did_typed = crate::types::Did::new_unchecked(&did); 1054 + let did_typed = unsafe { crate::types::Did::new_unchecked(&did) }; 1045 1055 let (commit_bytes, _sig) = match crate::api::repo::record::utils::create_signed_commit( 1046 1056 &did_typed, 1047 1057 mst_root, ··· 1110 1120 birthdate_pref, 1111 1121 sso_provider: pending_preview.provider, 1112 1122 sso_provider_user_id: pending_preview.provider_user_id.clone().into_inner(), 1113 - sso_provider_username: pending_preview.provider_username.clone().map(|u| u.into_inner()), 1114 - sso_provider_email: pending_preview.provider_email.clone().map(|e| e.into_inner()), 1123 + sso_provider_username: pending_preview 1124 + .provider_username 1125 + .clone() 1126 + .map(|u| u.into_inner()), 1127 + sso_provider_email: pending_preview 1128 + .provider_email 1129 + .clone() 1130 + .map(|e| e.into_inner()), 1115 1131 sso_provider_email_verified: pending_preview.provider_email_verified, 1116 1132 pending_registration_token: input.token.clone(), 1117 1133 }; ··· 1158 1174 "$type": "app.bsky.actor.profile", 1159 1175 "displayName": handle_typed.as_str() 1160 1176 }); 1161 - let profile_collection = crate::types::Nsid::new_unchecked("app.bsky.actor.profile"); 1162 - let profile_rkey = crate::types::Rkey::new_unchecked("self"); 1177 + let profile_collection = unsafe { crate::types::Nsid::new_unchecked("app.bsky.actor.profile") }; 1178 + let profile_rkey = unsafe { crate::types::Rkey::new_unchecked("self") }; 1163 1179 if let Err(e) = crate::api::repo::record::create_record_internal( 1164 1180 &state, 1165 1181 &did_typed,
+6 -3
crates/tranquil-pds/src/state.rs
··· 13 13 use std::error::Error; 14 14 use std::sync::Arc; 15 15 use tokio::sync::broadcast; 16 + use tokio_util::sync::CancellationToken; 16 17 use tranquil_db::{ 17 18 BacklinkRepository, BackupRepository, BlobRepository, DelegationRepository, InfraRepository, 18 19 OAuthRepository, PostgresRepositories, RepoEventNotifier, RepoRepository, SessionRepository, ··· 44 45 pub sso_repo: Arc<dyn SsoRepository>, 45 46 pub sso_manager: SsoManager, 46 47 pub webauthn_config: Arc<WebAuthnConfig>, 48 + pub shutdown: CancellationToken, 47 49 } 48 50 49 51 #[derive(Debug, Clone, Copy)] ··· 120 122 } 121 123 122 124 impl AppState { 123 - pub async fn new() -> Result<Self, Box<dyn Error>> { 125 + pub async fn new(shutdown: CancellationToken) -> Result<Self, Box<dyn Error>> { 124 126 let database_url = std::env::var("DATABASE_URL") 125 127 .map_err(|_| "DATABASE_URL environment variable must be set")?; 126 128 ··· 161 163 .await 162 164 .map_err(|e| format!("Failed to run migrations: {}", e))?; 163 165 164 - Ok(Self::from_db(db).await) 166 + Ok(Self::from_db(db, shutdown).await) 165 167 } 166 168 167 - pub async fn from_db(db: PgPool) -> Self { 169 + pub async fn from_db(db: PgPool, shutdown: CancellationToken) -> Self { 168 170 AuthConfig::init(); 169 171 170 172 let repos = Arc::new(PostgresRepositories::new(db.clone())); ··· 213 215 did_resolver, 214 216 sso_manager, 215 217 webauthn_config, 218 + shutdown, 216 219 } 217 220 } 218 221
crates/tranquil-pds/src/sync/commit.rs

This file has not been changed.

crates/tranquil-pds/src/sync/deprecated.rs

This file has not been changed.

crates/tranquil-pds/src/sync/frame.rs

This file has not been changed.

crates/tranquil-pds/src/sync/listener.rs

This file has not been changed.

crates/tranquil-pds/src/sync/mod.rs

This file has not been changed.

crates/tranquil-pds/src/sync/subscribe_repos.rs

This file has not been changed.

crates/tranquil-pds/src/sync/util.rs

This file has not been changed.

crates/tranquil-pds/src/util.rs

This file has not been changed.

crates/tranquil-pds/tests/firehose_validation.rs

This file has not been changed.

crates/tranquil-scopes/src/parser.rs

This file has not been changed.

+3 -2
Cargo.lock
··· 5733 5733 5734 5734 [[package]] 5735 5735 name = "tokio-util" 5736 - version = "0.7.17" 5736 + version = "0.7.18" 5737 5737 source = "registry+https://github.com/rust-lang/crates.io-index" 5738 - checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594" 5738 + checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" 5739 5739 dependencies = [ 5740 5740 "bytes", 5741 5741 "futures-core", ··· 6115 6115 "thiserror 2.0.17", 6116 6116 "tokio", 6117 6117 "tokio-tungstenite", 6118 + "tokio-util", 6118 6119 "tower", 6119 6120 "tower-http", 6120 6121 "tower-layer",
+1
Cargo.toml
··· 87 87 subtle = "2.5" 88 88 thiserror = "2.0" 89 89 tokio = { version = "1.48", features = ["macros", "rt-multi-thread", "time", "signal", "process"] } 90 + tokio-util = "0.7.18" 90 91 tokio-tungstenite = { version = "0.28", features = ["native-tls"] } 91 92 totp-rs = { version = "5", features = ["qr"] } 92 93 tower = "0.5"
+1
crates/tranquil-pds/Cargo.toml
··· 67 67 thiserror = { workspace = true } 68 68 tokio = { workspace = true } 69 69 tokio-tungstenite = { workspace = true } 70 + tokio-util = { workspace = true } 70 71 tower = { workspace = true } 71 72 tower-http = { workspace = true } 72 73 tower-layer = { workspace = true }
+1 -1
crates/tranquil-pds/src/api/server/logo.rs
··· 21 21 Some(c) if !c.is_empty() => c, 22 22 _ => return StatusCode::NOT_FOUND.into_response(), 23 23 }; 24 - let cid = crate::types::CidLink::new_unchecked(&cid_str); 24 + let cid = unsafe { crate::types::CidLink::new_unchecked(&cid_str) }; 25 25 26 26 let metadata = match state.blob_repo.get_blob_metadata(&cid).await { 27 27 Ok(Some(m)) => m,
+50 -37
crates/tranquil-pds/src/main.rs
··· 1 1 use std::net::SocketAddr; 2 2 use std::process::ExitCode; 3 3 use std::sync::Arc; 4 - use tokio::sync::watch; 4 + use tokio_util::sync::CancellationToken; 5 5 use tracing::{error, info, warn}; 6 6 use tranquil_pds::comms::{CommsService, DiscordSender, EmailSender, SignalSender, TelegramSender}; 7 7 ··· 34 34 } 35 35 36 36 async fn run() -> Result<(), Box<dyn std::error::Error>> { 37 - let state = AppState::new().await?; 38 - tranquil_pds::sync::listener::start_sequencer_listener(state.clone()).await; 37 + let shutdown = CancellationToken::new(); 38 + 39 + let shutdown_for_panic = shutdown.clone(); 40 + let default_panic_hook = std::panic::take_hook(); 41 + std::panic::set_hook(Box::new(move |info| { 42 + error!("PANIC: {}", info); 43 + shutdown_for_panic.cancel(); 44 + default_panic_hook(info); 45 + })); 39 46 40 - let (shutdown_tx, shutdown_rx) = watch::channel(false); 47 + spawn_signal_handler(shutdown.clone()); 48 + 49 + let state = AppState::new(shutdown.clone()).await?; 50 + tranquil_pds::sync::listener::start_sequencer_listener(state.clone()).await; 41 51 42 52 let backfill_repo_repo = state.repo_repo.clone(); 43 53 let backfill_block_store = state.block_store.clone(); ··· 77 87 comms_service = comms_service.register_sender(signal_sender); 78 88 } 79 89 80 - let comms_handle = tokio::spawn(comms_service.run(shutdown_rx.clone())); 90 + let comms_handle = tokio::spawn(comms_service.run(shutdown.clone())); 81 91 82 92 let crawlers_handle = if let Some(crawlers) = Crawlers::from_env() { 83 93 let crawlers = Arc::new( ··· 88 98 Some(tokio::spawn(start_crawlers_service( 89 99 crawlers, 90 100 firehose_rx, 91 - shutdown_rx.clone(), 101 + shutdown.clone(), 92 102 ))) 93 103 } else { 94 104 warn!("Crawlers notification service disabled (PDS_HOSTNAME or CRAWLERS not set)"); ··· 102 112 state.backup_repo.clone(), 103 113 state.block_store.clone(), 104 114 backup_storage, 105 - shutdown_rx.clone(), 115 + shutdown.clone(), 106 116 ))) 107 117 } else { 108 118 warn!("Backup service disabled (BACKUP_S3_BUCKET not set or BACKUP_ENABLED=false)"); ··· 114 124 state.blob_repo.clone(), 115 125 state.blob_store.clone(), 116 126 state.sso_repo.clone(), 117 - shutdown_rx, 127 + shutdown.clone(), 118 128 )); 119 129 120 130 let app = tranquil_pds::app(state); ··· 136 146 .map_err(|e| format!("Failed to bind to {}: {}", addr, e))?; 137 147 138 148 let server_result = axum::serve(listener, app) 139 - .with_graceful_shutdown(shutdown_signal(shutdown_tx)) 149 + .with_graceful_shutdown(shutdown.clone().cancelled_owned()) 140 150 .await; 141 151 142 152 comms_handle.await.ok(); ··· 158 168 Ok(()) 159 169 } 160 170 161 - async fn shutdown_signal(shutdown_tx: watch::Sender<bool>) { 162 - let ctrl_c = async { 163 - match tokio::signal::ctrl_c().await { 164 - Ok(()) => {} 165 - Err(e) => { 166 - error!("Failed to install Ctrl+C handler: {}", e); 167 - } 168 - } 169 - }; 170 - 171 - #[cfg(unix)] 172 - let terminate = async { 173 - match tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate()) { 174 - Ok(mut signal) => { 175 - signal.recv().await; 171 + fn spawn_signal_handler(shutdown: CancellationToken) { 172 + tokio::spawn(async move { 173 + let ctrl_c = async { 174 + match tokio::signal::ctrl_c().await { 175 + Ok(()) => {} 176 + Err(e) => { 177 + error!("Failed to install Ctrl+C handler: {}", e); 178 + std::future::pending::<()>().await; 179 + } 176 180 } 177 - Err(e) => { 178 - error!("Failed to install SIGTERM handler: {}", e); 179 - std::future::pending::<()>().await; 181 + }; 182 + 183 + #[cfg(unix)] 184 + let terminate = async { 185 + match tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate()) { 186 + Ok(mut signal) => { 187 + signal.recv().await; 188 + } 189 + Err(e) => { 190 + error!("Failed to install SIGTERM handler: {}", e); 191 + std::future::pending::<()>().await; 192 + } 180 193 } 181 - } 182 - }; 194 + }; 183 195 184 - #[cfg(not(unix))] 185 - let terminate = std::future::pending::<()>(); 196 + #[cfg(not(unix))] 197 + let terminate = std::future::pending::<()>(); 186 198 187 - tokio::select! { 188 - _ = ctrl_c => {}, 189 - _ = terminate => {}, 190 - } 199 + tokio::select! { 200 + _ = ctrl_c => {}, 201 + _ = terminate => {}, 202 + } 191 203 192 - info!("Shutdown signal received, stopping services..."); 193 - shutdown_tx.send(true).ok(); 204 + info!("Shutdown signal received, stopping services..."); 205 + shutdown.cancel(); 206 + }); 194 207 }
+1 -1
crates/tranquil-pds/tests/commit_signing.rs
··· 99 99 use tranquil_pds::api::repo::record::utils::create_signed_commit; 100 100 101 101 let signing_key = SigningKey::random(&mut rand::thread_rng()); 102 - let did = Did::new_unchecked("did:plc:testuser123456789abcdef"); 102 + let did = unsafe { Did::new_unchecked("did:plc:testuser123456789abcdef") }; 103 103 let data_cid = 104 104 Cid::from_str("bafyreib2rxk3ryblouj3fxza5jvx6psmwewwessc4m6g6e7pqhhkwqomfi").unwrap(); 105 105 let rev = Tid::now(LimitedU32::MIN).to_string();
+2 -1
crates/tranquil-pds/tests/common/mod.rs
··· 14 14 #[allow(unused_imports)] 15 15 use std::time::Duration; 16 16 use tokio::net::TcpListener; 17 + use tokio_util::sync::CancellationToken; 17 18 use tranquil_pds::state::AppState; 18 19 use wiremock::matchers::{method, path}; 19 20 use wiremock::{Mock, MockServer, Request, Respond, ResponseTemplate}; ··· 546 547 .with_email_update_limit(10000) 547 548 .with_oauth_authorize_limit(10000) 548 549 .with_oauth_token_limit(10000); 549 - let state = AppState::from_db(pool) 550 + let state = AppState::from_db(pool, CancellationToken::new()) 550 551 .await 551 552 .with_rate_limiters(rate_limiters); 552 553 tranquil_pds::sync::listener::start_sequencer_listener(state.clone()).await;
+71
crates/tranquil-pds/tests/shutdown_unit.rs
··· 1 + use std::sync::Arc; 2 + use std::sync::atomic::{AtomicBool, Ordering}; 3 + use tokio_util::sync::CancellationToken; 4 + 5 + #[test] 6 + fn test_panic_hook_cancels_shutdown_token() { 7 + let shutdown = CancellationToken::new(); 8 + let shutdown_clone = shutdown.clone(); 9 + 10 + let panic_occurred = Arc::new(AtomicBool::new(false)); 11 + let panic_occurred_clone = panic_occurred.clone(); 12 + 13 + let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { 14 + let default_hook = std::panic::take_hook(); 15 + std::panic::set_hook(Box::new(move |info| { 16 + panic_occurred_clone.store(true, Ordering::SeqCst); 17 + shutdown_clone.cancel(); 18 + default_hook(info); 19 + })); 20 + 21 + panic!("simulated corrupted data panic"); 22 + })); 23 + 24 + assert!(result.is_err()); 25 + assert!(panic_occurred.load(Ordering::SeqCst)); 26 + assert!(shutdown.is_cancelled()); 27 + 28 + let _ = std::panic::take_hook(); 29 + } 30 + 31 + #[test] 32 + fn test_cancellation_token_propagates_to_clones() { 33 + let shutdown = CancellationToken::new(); 34 + let clone1 = shutdown.clone(); 35 + let clone2 = shutdown.clone(); 36 + 37 + assert!(!shutdown.is_cancelled()); 38 + assert!(!clone1.is_cancelled()); 39 + assert!(!clone2.is_cancelled()); 40 + 41 + shutdown.cancel(); 42 + 43 + assert!(shutdown.is_cancelled()); 44 + assert!(clone1.is_cancelled()); 45 + assert!(clone2.is_cancelled()); 46 + } 47 + 48 + #[tokio::test] 49 + async fn test_cancelled_future_completes_on_cancel() { 50 + let shutdown = CancellationToken::new(); 51 + let shutdown_clone = shutdown.clone(); 52 + 53 + let handle = tokio::spawn(async move { 54 + shutdown_clone.cancelled().await; 55 + true 56 + }); 57 + 58 + tokio::time::sleep(std::time::Duration::from_millis(10)).await; 59 + assert!(!handle.is_finished()); 60 + 61 + shutdown.cancel(); 62 + 63 + let result = tokio::time::timeout( 64 + std::time::Duration::from_millis(100), 65 + handle, 66 + ) 67 + .await; 68 + 69 + assert!(result.is_ok()); 70 + assert!(result.unwrap().unwrap()); 71 + }
+25 -17
crates/tranquil-pds/tests/sso.rs
··· 232 232 let _url = base_url().await; 233 233 let pool = get_test_db_pool().await; 234 234 235 - let did = Did::new_unchecked(format!( 236 - "did:plc:test{}", 237 - &uuid::Uuid::new_v4().simple().to_string()[..12] 238 - )); 235 + let did = unsafe { 236 + Did::new_unchecked(format!( 237 + "did:plc:test{}", 238 + &uuid::Uuid::new_v4().simple().to_string()[..12] 239 + )) 240 + }; 239 241 let provider = SsoProviderType::Github; 240 242 let provider_user_id = format!("github_user_{}", uuid::Uuid::new_v4().simple()); 241 243 ··· 350 352 let _url = base_url().await; 351 353 let pool = get_test_db_pool().await; 352 354 353 - let did1 = Did::new_unchecked(format!( 354 - "did:plc:uc1{}", 355 - &uuid::Uuid::new_v4().simple().to_string()[..10] 356 - )); 357 - let did2 = Did::new_unchecked(format!( 358 - "did:plc:uc2{}", 359 - &uuid::Uuid::new_v4().simple().to_string()[..10] 360 - )); 355 + let did1 = unsafe { 356 + Did::new_unchecked(format!( 357 + "did:plc:uc1{}", 358 + &uuid::Uuid::new_v4().simple().to_string()[..10] 359 + )) 360 + }; 361 + let did2 = unsafe { 362 + Did::new_unchecked(format!( 363 + "did:plc:uc2{}", 364 + &uuid::Uuid::new_v4().simple().to_string()[..10] 365 + )) 366 + }; 361 367 let provider_user_id = format!("unique_test_{}", uuid::Uuid::new_v4().simple()); 362 368 363 369 sqlx::query!( ··· 577 583 let _url = base_url().await; 578 584 let pool = get_test_db_pool().await; 579 585 580 - let did = Did::new_unchecked(format!( 581 - "did:plc:del{}", 582 - &uuid::Uuid::new_v4().simple().to_string()[..10] 583 - )); 584 - let wrong_did = Did::new_unchecked("did:plc:wrongdid12345"); 586 + let did = unsafe { 587 + Did::new_unchecked(format!( 588 + "did:plc:del{}", 589 + &uuid::Uuid::new_v4().simple().to_string()[..10] 590 + )) 591 + }; 592 + let wrong_did = unsafe { Did::new_unchecked("did:plc:wrongdid12345") }; 585 593 586 594 sqlx::query!( 587 595 "INSERT INTO users (did, handle, email, password_hash) VALUES ($1, $2, $3, 'hash')",
+6 -3
crates/tranquil-types/src/lib.rs
··· 166 166 Ok(Self(s)) 167 167 } 168 168 169 - pub fn new_unchecked(s: impl Into<String>) -> Self { 169 + #[allow(unsafe_code, clippy::missing_safety_doc)] 170 + pub unsafe fn new_unchecked(s: impl Into<String>) -> Self { 170 171 Self(s.into()) 171 172 } 172 173 } ··· 228 229 Ok(Self(s)) 229 230 } 230 231 231 - pub fn new_unchecked(s: impl Into<String>) -> Self { 232 + #[allow(unsafe_code, clippy::missing_safety_doc)] 233 + pub unsafe fn new_unchecked(s: impl Into<String>) -> Self { 232 234 Self(s.into()) 233 235 } 234 236 } ··· 489 491 Ok(Self(s)) 490 492 } 491 493 492 - pub fn new_unchecked(s: impl Into<String>) -> Self { 494 + #[allow(unsafe_code, clippy::missing_safety_doc)] 495 + pub unsafe fn new_unchecked(s: impl Into<String>) -> Self { 493 496 Self(s.into()) 494 497 } 495 498

History

3 rounds 0 comments
sign up or login to add to the discussion
lewis.moe submitted #2
1 commit
expand
fix: better type-safety
expand 0 comments
pull request successfully merged
1 commit
expand
fix: better type-safety
expand 0 comments
lewis.moe submitted #0
1 commit
expand
fix: better type-safety
expand 0 comments