Skip to content

Auth#2

Merged
emma31-dev merged 8 commits into
masterfrom
auth
May 22, 2026
Merged

Auth#2
emma31-dev merged 8 commits into
masterfrom
auth

Conversation

@emma31-dev
Copy link
Copy Markdown
Owner

No description provided.

@qodo-code-review
Copy link
Copy Markdown

Review Summary by Qodo

Implement authentication with bcrypt hashing and comprehensive tracing

✨ Enhancement 🐞 Bug fix

Grey Divider

Walkthroughs

Description
• Replaced AES-GCM encryption with bcrypt for password hashing
• Added comprehensive tracing/logging with file and console output
• Implemented login endpoint with password verification
• Improved error handling using context and proper status codes
• Added readiness check endpoint for database connectivity
• Refactored configuration management and environment variable handling
Diagram
flowchart LR
  A["User Request"] --> B["Login/Signup Endpoint"]
  B --> C["Bcrypt Password Hashing"]
  C --> D["Database Operations"]
  D --> E["JWT Token Generation"]
  E --> F["Tracing Logger"]
  F --> G["Console & File Output"]
  B --> H["Error Handling with Context"]
  H --> G

Loading

File Changes

1. src/config.rs ✨ Enhancement +5/-5

Reorganized config struct and improved error handling

src/config.rs


2. src/db/mod.rs ⚙️ Configuration changes +1/-1

Updated migration path from schemas to migrations

src/db/mod.rs


3. src/lib.rs ✨ Enhancement +1/-0

Added tracing module to public exports

src/lib.rs


View more (11)
4. src/main.rs ✨ Enhancement +15/-6

Integrated tracing initialization and improved error context

src/main.rs


5. src/routes/helper.rs ✨ Enhancement +4/-8

Simplified JWT creation with config-based secret retrieval

src/routes/helper.rs


6. src/routes/login.rs ✨ Enhancement +79/-0

Implemented complete login endpoint with bcrypt verification

src/routes/login.rs


7. src/routes/mod.rs ✨ Enhancement +18/-3

Added login route and readiness check endpoint

src/routes/mod.rs


8. src/routes/signup.rs ✨ Enhancement +19/-20

Replaced AES-GCM with bcrypt and added tracing

src/routes/signup.rs


9. src/tracing.rs ✨ Enhancement +20/-0

Created new tracing module with file and console logging

src/tracing.rs


10. .github/workflows/rust.yml ⚙️ Configuration changes +0/-2

Removed cargo test step from CI workflow

.github/workflows/rust.yml


11. Cargo.toml Dependencies +4/-0

Added bcrypt and tracing dependencies

Cargo.toml


12. migrations/20260521102510_initial_schema.sql 📝 Documentation +17/-15

Refined schema with improved comments and structure

migrations/20260521102510_initial_schema.sql


13. migrations/20260521141725_changing_password_hash_to_blob.sql ✨ Enhancement +34/-0

Added migration to convert password_hash to BLOB type

migrations/20260521141725_changing_password_hash_to_blob.sql


14. migrations/20260521151036_drop_nonce_from_users.sql ✨ Enhancement +16/-0

Added migration to remove nonce column from users table

migrations/20260521151036_drop_nonce_from_users.sql


Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Copy Markdown

qodo-code-review Bot commented May 22, 2026

Code Review by Qodo

🐞 Bugs (6) 📘 Rule violations (0)

Grey Divider


Action required

1. sqlx query! breaks CI 🐞 Bug ☼ Reliability
Description
src/routes/login.rs uses sqlx::query!, which requires a DATABASE_URL at compile-time (or
pre-generated offline metadata), but the GitHub workflow runs cargo check without providing
DATABASE_URL, so CI will fail to build.
Code

src/routes/login.rs[R27-33]

Evidence
The login handler introduces sqlx::query!, and the CI workflow runs cargo check without any
DATABASE_URL env configured, which is required for compile-time query checking.

src/routes/login.rs[27-33]
.github/workflows/rust.yml[9-22]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`sqlx::query!` performs compile-time query validation and needs a build-time DATABASE_URL or offline metadata. Current CI (`cargo check`) does not set DATABASE_URL, so builds will fail.

## Issue Context
You currently use runtime-checked `sqlx::query(...)` elsewhere; only `login.rs` introduced the macro form.

## Fix options
1) Replace `sqlx::query!` with `sqlx::query` / `sqlx::query_as` and decode the row manually.
2) Or enable SQLx offline workflow: generate `.sqlx` metadata and set `SQLX_OFFLINE=true` in CI.
3) Or set `DATABASE_URL` in CI to a valid SQLite URL (and ensure schema exists for validation).

## Fix Focus Areas
- src/routes/login.rs[27-33]
- .github/workflows/rust.yml[9-22]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Login ownership/type errors 🐞 Bug ≡ Correctness
Description
login() consumes payload.username in the SQL call and uses it again in the warn! log, and it
also calls unwrap_or_default() on id even though users.id is defined as a non-null primary
key; this will not compile as written.
Code

src/routes/login.rs[R27-53]

Evidence
payload.username is used as a query argument and then referenced again in the None branch log;
additionally, the schema shows users.id is a primary key (non-null), so unwrap_or_default() is
inconsistent with the expected type.

src/routes/login.rs[27-53]
migrations/20260521102510_initial_schema.sql[3-6]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The login handler likely fails to compile due to (1) moving `payload.username` into the query arguments and then reusing it in logging, and (2) calling `unwrap_or_default()` on `id` even though schema defines `users.id` as non-null.

## Issue Context
SQLite schema creates `users(id TEXT PRIMARY KEY, ...)` meaning `id` is NOT NULL. Therefore SQLx should materialize it as `String`, not `Option<String>`.

## Fix
- Pass `&payload.username` into the query and log `&payload.username` (or clone once into a local variable).
- Treat `id` as a `String` and remove `unwrap_or_default()`.

## Fix Focus Areas
- src/routes/login.rs[27-53]
- migrations/20260521102510_initial_schema.sql[3-6]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Dropping users breaks FKs 🐞 Bug ☼ Reliability
Description
The migration recreates users by doing DROP TABLE users while other tables already reference
users(id) and the app enables foreign key enforcement; this will cause the migration to fail with
foreign key constraint errors.
Code

migrations/20260521141725_changing_password_hash_to_blob.sql[R27-31]

Evidence
The initial schema defines foreign keys from chat_participants and messages to users, the
later migration drops users, and the DB pool enables FK enforcement, which makes such drops fail
under SQLite FK checks.

migrations/20260521102510_initial_schema.sql[20-37]
migrations/20260521141725_changing_password_hash_to_blob.sql[27-31]
src/db/mod.rs[4-8]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
SQLite migrations drop the `users` table even though `chat_participants.user_id` and `messages.sender_id` reference it. With `foreign_keys(true)` enabled in connection options, `DROP TABLE users` will fail.

## Issue Context
`src/db/mod.rs` enables FK enforcement for the pool. The initial schema creates FK references to `users` before the later migration runs.

## Fix
Choose one:
- Wrap the table-rebuild with `PRAGMA foreign_keys=OFF; ... PRAGMA foreign_keys=ON;` (ideally in a transaction) and ensure integrity checks after.
- Or migrate without dropping the referenced table (e.g., add a new column / keep table and backfill, or rebuild referencing tables too).

## Fix Focus Areas
- migrations/20260521141725_changing_password_hash_to_blob.sql[27-31]
- migrations/20260521102510_initial_schema.sql[20-37]
- src/db/mod.rs[4-8]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View more (2)
4. SET NULL with NOT NULL 🐞 Bug ≡ Correctness
Description
messages.sender_id is declared NOT NULL but also uses ON DELETE SET NULL, so deleting a user
who has messages will violate the NOT NULL constraint and fail.
Code

migrations/20260521102510_initial_schema.sql[R30-33]

Evidence
The migration explicitly combines NOT NULL with ON DELETE SET NULL on the same column, which
will fail when the FK action is triggered.

migrations/20260521102510_initial_schema.sql[28-33]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Schema defines `sender_id TEXT NOT NULL ... ON DELETE SET NULL`, which is a contradiction: FK action tries to set NULL but the column forbids NULL.

## Fix
Pick intended behavior:
- If you want to keep messages: remove `NOT NULL` on `sender_id`.
- If you want to delete messages with users: use `ON DELETE CASCADE`.
- If you want to block deletion: use `ON DELETE RESTRICT`.

## Fix Focus Areas
- migrations/20260521102510_initial_schema.sql[29-33]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. dotenv hard-requirement panics 🐞 Bug ☼ Reliability
Description
Config::from_env() now calls dotenv().expect(...), which will crash the server when .env is
absent (common in production/container deployments) and is also invoked during JWT creation.
Code

src/config.rs[R13-21]

Evidence
Config loading now panics on missing .env, and both server startup and JWT issuance call
Config::from_env(), making the panic reachable in production.

src/config.rs[12-22]
src/main.rs[11-18]
src/routes/helper.rs[13-28]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Requiring `.env` via `dotenv().expect(...)` makes startup and request paths panic when `.env` is missing.

## Issue Context
`main` calls `Config::from_env()` at startup, and `create_jwt()` calls it again during request handling.

## Fix
- Change back to `dotenv().ok();` (or only load dotenv in debug builds).
- Avoid re-loading env per request: pass `jwt_secret`/`Config` via application state and have `create_jwt` take the secret as a parameter.

## Fix Focus Areas
- src/config.rs[12-22]
- src/main.rs[11-18]
- src/routes/helper.rs[13-28]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

6. Signup hashing can panic 🐞 Bug ☼ Reliability
Description
signup() uses bcrypt::hash(...).expect(...), which will panic the server on hashing errors
instead of returning a controlled HTTP error.
Code

src/routes/signup.rs[36]

Evidence
The handler uses .expect("Failed to hash password"), which panics on error instead of returning
the handler’s error type.

src/routes/signup.rs[25-38]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Panicking in request handlers can crash the process; hashing failures should be mapped to a 500 response.

## Fix
Replace `.expect(...)` with error mapping, e.g.:
```rust
let hashed = hash(payload.password, DEFAULT_COST)
   .map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Hash error".to_string()))?;
```

## Fix Focus Areas
- src/routes/signup.rs[36-36]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Copy Markdown

CI Feedback 🧐

A test triggered by this PR failed. Here is an AI-generated analysis of the failure:

Action: build

Failed stage: Checking [❌]

Failed test name: ""

Failure summary:

The action failed during compilation because sqlx::query! requires either:
- DATABASE_URL to be set
at build time (to validate query macros online), or
- a pre-generated SQLx offline cache created via
cargo sqlx prepare.

In CI, neither was available, so Rust compilation stopped with:
- error: set DATABASE_URL to use
query macros online, or run cargo sqlx prepare to update the query cache
- Location:
src/routes/login.rs:27:15 (the sqlx::query! invocation).

Relevant error logs:
1:  ##[group]Runner Image Provisioner
2:  Hosted Compute Agent
...

176:  �[1m�[92m  Downloaded�[0m url v2.5.8
177:  �[1m�[92m  Downloaded�[0m typenum v1.20.0
178:  �[1m�[92m  Downloaded�[0m universal-hash v0.5.1
179:  �[1m�[92m  Downloaded�[0m rustversion v1.0.22
180:  �[1m�[92m  Downloaded�[0m thread_local v1.1.9
181:  �[1m�[92m  Downloaded�[0m tracing-subscriber v0.3.23
182:  �[1m�[92m  Downloaded�[0m want v0.3.1
183:  �[1m�[92m  Downloaded�[0m num-integer v0.1.46
184:  �[1m�[92m  Downloaded�[0m nu-ansi-term v0.50.3
185:  �[1m�[92m  Downloaded�[0m native-tls v0.2.18
186:  �[1m�[92m  Downloaded�[0m version_check v0.9.5
187:  �[1m�[92m  Downloaded�[0m vcpkg v0.2.15
188:  �[1m�[92m  Downloaded�[0m tinystr v0.8.3
189:  �[1m�[92m  Downloaded�[0m parking_lot_core v0.9.12
190:  �[1m�[92m  Downloaded�[0m time-macros v0.2.27
191:  �[1m�[92m  Downloaded�[0m thiserror v2.0.18
192:  �[1m�[92m  Downloaded�[0m whoami v1.6.1
...

230:  �[1m�[92m  Downloaded�[0m zerocopy v0.8.48
231:  �[1m�[92m  Downloaded�[0m tinyvec v1.11.0
232:  �[1m�[92m  Downloaded�[0m serde_core v1.0.228
233:  �[1m�[92m  Downloaded�[0m proc-macro2 v1.0.106
234:  �[1m�[92m  Downloaded�[0m signal-hook-registry v1.4.8
235:  �[1m�[92m  Downloaded�[0m shlex v1.3.0
236:  �[1m�[92m  Downloaded�[0m pkcs1 v0.7.5
237:  �[1m�[92m  Downloaded�[0m libc v0.2.186
238:  �[1m�[92m  Downloaded�[0m pin-project-lite v0.2.17
239:  �[1m�[92m  Downloaded�[0m parking_lot v0.12.5
240:  �[1m�[92m  Downloaded�[0m synstructure v0.13.2
241:  �[1m�[92m  Downloaded�[0m spki v0.7.3
242:  �[1m�[92m  Downloaded�[0m simple_asn1 v0.6.4
243:  �[1m�[92m  Downloaded�[0m ppv-lite86 v0.2.21
244:  �[1m�[92m  Downloaded�[0m tokio-macros v2.7.0
245:  �[1m�[92m  Downloaded�[0m thiserror-impl v2.0.18
246:  �[1m�[92m  Downloaded�[0m sqlx-macros-core v0.8.6
247:  �[1m�[92m  Downloaded�[0m tokio v1.52.3
248:  �[1m�[92m  Downloaded�[0m slab v0.4.12
249:  �[1m�[92m  Downloaded�[0m sha2 v0.10.9
250:  �[1m�[92m  Downloaded�[0m serde_path_to_error v0.1.20
251:  �[1m�[92m  Downloaded�[0m rand_core v0.6.4
...

378:  �[1m�[92m   Compiling�[0m vcpkg v0.2.15
379:  �[1m�[92m   Compiling�[0m serde v1.0.228
380:  �[1m�[92m   Compiling�[0m parking_lot_core v0.9.12
381:  �[1m�[92m   Compiling�[0m stable_deref_trait v1.2.1
382:  �[1m�[92m   Compiling�[0m icu_normalizer_data v2.2.0
383:  �[1m�[92m   Compiling�[0m crossbeam-utils v0.8.21
384:  �[1m�[92m   Compiling�[0m icu_properties_data v2.2.0
385:  �[1m�[92m    Checking�[0m smallvec v1.15.1
386:  �[1m�[92m    Checking�[0m itoa v1.0.18
387:  �[1m�[92m    Checking�[0m pin-project-lite v0.2.17
388:  �[1m�[92m   Compiling�[0m zmij v1.0.21
389:  �[1m�[92m    Checking�[0m getrandom v0.2.17
390:  �[1m�[92m    Checking�[0m rand_core v0.6.4
391:  �[1m�[92m   Compiling�[0m serde_json v1.0.149
392:  �[1m�[92m    Checking�[0m crypto-common v0.1.7
393:  �[1m�[92m   Compiling�[0m thiserror v2.0.18
394:  �[1m�[92m   Compiling�[0m openssl-sys v0.9.116
...

413:  �[1m�[92m    Checking�[0m slab v0.4.12
414:  �[1m�[92m    Checking�[0m futures-task v0.3.32
415:  �[1m�[92m    Checking�[0m futures-io v0.3.32
416:  �[1m�[92m    Checking�[0m futures-util v0.3.32
417:  �[1m�[92m    Checking�[0m signal-hook-registry v1.4.8
418:  �[1m�[92m   Compiling�[0m zerofrom-derive v0.1.7
419:  �[1m�[92m   Compiling�[0m yoke-derive v0.8.2
420:  �[1m�[92m   Compiling�[0m zerovec-derive v0.11.3
421:  �[1m�[92m   Compiling�[0m displaydoc v0.2.5
422:  �[1m�[92m   Compiling�[0m serde_derive v1.0.228
423:  �[1m�[92m   Compiling�[0m zerofrom v0.1.8
424:  �[1m�[92m   Compiling�[0m yoke v0.8.2
425:  �[1m�[92m   Compiling�[0m tracing-attributes v0.1.31
426:  �[1m�[92m   Compiling�[0m zerovec v0.11.6
427:  �[1m�[92m   Compiling�[0m tinystr v0.8.3
428:  �[1m�[92m   Compiling�[0m thiserror-impl v2.0.18
429:  �[1m�[92m   Compiling�[0m icu_locale_core v2.2.0
...

540:  �[1m�[92m    Checking�[0m untrusted v0.7.1
541:  �[1m�[92m    Checking�[0m byteorder v1.5.0
542:  �[1m�[92m   Compiling�[0m anyhow v1.0.102
543:  �[1m�[92m    Checking�[0m mime v0.3.17
544:  �[1m�[92m    Checking�[0m blowfish v0.10.0
545:  �[1m�[92m    Checking�[0m tracing-subscriber v0.3.23
546:  �[1m�[92m    Checking�[0m hyper v0.14.32
547:  �[1m�[92m    Checking�[0m simple_asn1 v0.6.4
548:  �[1m�[92m   Compiling�[0m sqlx-macros v0.8.6
549:  �[1m�[92m    Checking�[0m tower v0.4.13
550:  �[1m�[92m    Checking�[0m ghash v0.5.1
551:  �[1m�[92m    Checking�[0m aes v0.8.4
552:  �[1m�[92m    Checking�[0m ctr v0.9.2
553:  �[1m�[92m    Checking�[0m pem v3.0.6
554:  �[1m�[92m    Checking�[0m crossbeam-channel v0.5.15
555:  �[1m�[92m    Checking�[0m serde_path_to_error v0.1.20
556:  �[1m�[92m    Checking�[0m aead v0.5.2
557:  �[1m�[92m    Checking�[0m symlink v0.1.0
558:  �[1m�[92m    Checking�[0m sync_wrapper v0.1.2
559:  �[1m�[92m    Checking�[0m matchit v0.7.3
560:  �[1m�[92m    Checking�[0m signature v2.2.0
561:  �[1m�[92m    Checking�[0m bitflags v1.3.2
562:  �[1m�[92m    Checking�[0m tracing-appender v0.2.5
563:  �[1m�[92m    Checking�[0m aes-gcm v0.10.3
564:  �[1m�[92m    Checking�[0m sqlx v0.8.6
565:  �[1m�[92m    Checking�[0m bcrypt v0.19.1
566:  �[1m�[92m    Checking�[0m jsonwebtoken v10.4.0
567:  �[1m�[92m    Checking�[0m encrypted-message-sender v0.1.0 (/home/runner/work/encrypted-message-sender/encrypted-message-sender)
568:  �[1m�[91merror�[0m�[1m: set `DATABASE_URL` to use query macros online, or run `cargo sqlx prepare` to update the query cache�[0m
569:  �[1m�[94m--> �[0msrc/routes/login.rs:27:15
570:  �[1m�[94m|�[0m
571:  �[1m�[94m27�[0m �[1m�[94m|�[0m       let row = sqlx::query!(
572:  �[1m�[94m|�[0m �[1m�[91m _______________^�[0m
573:  �[1m�[94m28�[0m �[1m�[94m|�[0m �[1m�[91m|�[0m         "SELECT id, password_hash FROM users WHERE username = ? AND deleted_at IS NULL",
574:  �[1m�[94m29�[0m �[1m�[94m|�[0m �[1m�[91m|�[0m         payload.username
575:  �[1m�[94m30�[0m �[1m�[94m|�[0m �[1m�[91m|�[0m     )
576:  �[1m�[94m|�[0m �[1m�[91m|_____^�[0m
577:  �[1m�[94m|�[0m
578:  �[1m�[94m= �[0m�[1mnote�[0m: this error originates in the macro `$crate::sqlx_macros::expand_query` which comes from the expansion of the macro `sqlx::query` (in Nightly builds, run with -Z macro-backtrace for more info)
579:  �[1m�[91merror�[0m: could not compile `encrypted-message-sender` (lib) due to 1 previous error
580:  ##[error]Process completed with exit code 101.
581:  Post job cleanup.

@emma31-dev emma31-dev merged commit 5c85691 into master May 22, 2026
0 of 2 checks passed
Comment thread src/routes/login.rs
Comment on lines +27 to +33
let row = sqlx::query!(
"SELECT id, password_hash FROM users WHERE username = ? AND deleted_at IS NULL",
payload.username
)
.fetch_optional(&pool)
.await
.map_err(|e| {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Sqlx query! breaks ci 🐞 Bug ☼ Reliability

src/routes/login.rs uses sqlx::query!, which requires a DATABASE_URL at compile-time (or
pre-generated offline metadata), but the GitHub workflow runs cargo check without providing
DATABASE_URL, so CI will fail to build.
Agent Prompt
## Issue description
`sqlx::query!` performs compile-time query validation and needs a build-time DATABASE_URL or offline metadata. Current CI (`cargo check`) does not set DATABASE_URL, so builds will fail.

## Issue Context
You currently use runtime-checked `sqlx::query(...)` elsewhere; only `login.rs` introduced the macro form.

## Fix options
1) Replace `sqlx::query!` with `sqlx::query` / `sqlx::query_as` and decode the row manually.
2) Or enable SQLx offline workflow: generate `.sqlx` metadata and set `SQLX_OFFLINE=true` in CI.
3) Or set `DATABASE_URL` in CI to a valid SQLite URL (and ensure schema exists for validation).

## Fix Focus Areas
- src/routes/login.rs[27-33]
- .github/workflows/rust.yml[9-22]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread src/routes/login.rs
Comment on lines +27 to +53
let row = sqlx::query!(
"SELECT id, password_hash FROM users WHERE username = ? AND deleted_at IS NULL",
payload.username
)
.fetch_optional(&pool)
.await
.map_err(|e| {
error!(
error = ?e,
"DB failed to initialize"
);
(StatusCode::INTERNAL_SERVER_ERROR, "DB error".to_string())
})?;

let (id, stored_hash) = match row {
Some(r) => (r.id, r.password_hash),
None => {
warn!(
username = payload.username,
"Failed to find record for login attempt of user"
);
return Err((StatusCode::UNAUTHORIZED, "Invalid credentials".to_string()));
}
};

let user_id = id.unwrap_or_default();
debug!(user_id = user_id, "Record found for login of User");
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. Login ownership/type errors 🐞 Bug ≡ Correctness

login() consumes payload.username in the SQL call and uses it again in the warn! log, and it
also calls unwrap_or_default() on id even though users.id is defined as a non-null primary
key; this will not compile as written.
Agent Prompt
## Issue description
The login handler likely fails to compile due to (1) moving `payload.username` into the query arguments and then reusing it in logging, and (2) calling `unwrap_or_default()` on `id` even though schema defines `users.id` as non-null.

## Issue Context
SQLite schema creates `users(id TEXT PRIMARY KEY, ...)` meaning `id` is NOT NULL. Therefore SQLx should materialize it as `String`, not `Option<String>`.

## Fix
- Pass `&payload.username` into the query and log `&payload.username` (or clone once into a local variable).
- Treat `id` as a `String` and remove `unwrap_or_default()`.

## Fix Focus Areas
- src/routes/login.rs[27-53]
- migrations/20260521102510_initial_schema.sql[3-6]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +27 to +31
-- 3. Drop the old table
DROP TABLE users;

-- 4. Rename the new table
ALTER TABLE users_new RENAME TO users;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

3. Dropping users breaks fks 🐞 Bug ☼ Reliability

The migration recreates users by doing DROP TABLE users while other tables already reference
users(id) and the app enables foreign key enforcement; this will cause the migration to fail with
foreign key constraint errors.
Agent Prompt
## Issue description
SQLite migrations drop the `users` table even though `chat_participants.user_id` and `messages.sender_id` reference it. With `foreign_keys(true)` enabled in connection options, `DROP TABLE users` will fail.

## Issue Context
`src/db/mod.rs` enables FK enforcement for the pool. The initial schema creates FK references to `users` before the later migration runs.

## Fix
Choose one:
- Wrap the table-rebuild with `PRAGMA foreign_keys=OFF; ... PRAGMA foreign_keys=ON;` (ideally in a transaction) and ensure integrity checks after.
- Or migrate without dropping the referenced table (e.g., add a new column / keep table and backfill, or rebuild referencing tables too).

## Fix Focus Areas
- migrations/20260521141725_changing_password_hash_to_blob.sql[27-31]
- migrations/20260521102510_initial_schema.sql[20-37]
- src/db/mod.rs[4-8]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +30 to +33
id TEXT PRIMARY KEY,
chat_id TEXT NOT NULL REFERENCES chats(id) ON DELETE CASCADE,
sender_id TEXT REFERENCES users(id) ON DELETE SET NULL,
encrypted_content BLOB NOT NULL, -- AES-GCM ciphertext (without tag)
nonce BLOB NOT NULL, -- 12 bytes unique per message
tag BLOB NOT NULL, -- 16 bytes authentication tag
created_at TEXT NOT NULL DEFAULT (datetime('now'))
sender_id TEXT NOT NULL REFERENCES users(id) ON DELETE SET NULL,
encrypted_content BLOB NOT NULL,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

4. Set null with not null 🐞 Bug ≡ Correctness

messages.sender_id is declared NOT NULL but also uses ON DELETE SET NULL, so deleting a user
who has messages will violate the NOT NULL constraint and fail.
Agent Prompt
## Issue description
Schema defines `sender_id TEXT NOT NULL ... ON DELETE SET NULL`, which is a contradiction: FK action tries to set NULL but the column forbids NULL.

## Fix
Pick intended behavior:
- If you want to keep messages: remove `NOT NULL` on `sender_id`.
- If you want to delete messages with users: use `ON DELETE CASCADE`.
- If you want to block deletion: use `ON DELETE RESTRICT`.

## Fix Focus Areas
- migrations/20260521102510_initial_schema.sql[29-33]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread src/config.rs
Comment on lines +13 to +21
dotenv().expect("Failed to load .env variables");
Self {
database_url: env::var("DATABASE_URL").expect("DATABASE_URL must be set"),
jwt_secret: env::var("JWT_SECRET").expect("JWT_SECRET must be set"),
ip_address: env::var("IP_ADDRESS").expect("Ip address not set"),
port: env::var("PORT")
.unwrap_or_else(|_| "8080".to_string())
.unwrap_or("8080".to_string())
.parse()
.expect("PORT must be a number"),
ip_address: env::var("IP_ADDRESS").expect("Ip address not set")
.expect("PORT not set"),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

5. Dotenv hard-requirement panics 🐞 Bug ☼ Reliability

Config::from_env() now calls dotenv().expect(...), which will crash the server when .env is
absent (common in production/container deployments) and is also invoked during JWT creation.
Agent Prompt
## Issue description
Requiring `.env` via `dotenv().expect(...)` makes startup and request paths panic when `.env` is missing.

## Issue Context
`main` calls `Config::from_env()` at startup, and `create_jwt()` calls it again during request handling.

## Fix
- Change back to `dotenv().ok();` (or only load dotenv in debug builds).
- Avoid re-loading env per request: pass `jwt_secret`/`Config` via application state and have `create_jwt` take the secret as a parameter.

## Fix Focus Areas
- src/config.rs[12-22]
- src/main.rs[11-18]
- src/routes/helper.rs[13-28]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant