4 Commits
Author SHA1 Message Date
phoenix 79f9fc3972 Update rust (#31)
Rust Build / Check (push) Successful in 2m28s
Rust Build / Test Suite (push) Successful in 3m12s
Rust Build / Rustfmt (push) Successful in 1m8s
Rust Build / Clippy (push) Successful in 1m27s
Rust Build / build (push) Successful in 3m59s
textsender_api PR / Clippy (pull_request) Has been cancelled
textsender_api PR / Check (pull_request) Has been cancelled
textsender_api PR / Rustfmt (pull_request) Has been cancelled
Reviewed-on: phoenix/textsender_api#31
2026-07-06 22:31:22 -04:00
phoenix 23f9a1430a Update dependencies (#30)
Rust Build / Test Suite (push) Failing after 58s
Rust Build / Rustfmt (push) Successful in 27s
Rust Build / Clippy (push) Successful in 1m21s
Rust Build / Check (push) Successful in 2m7s
Rust Build / build (push) Successful in 3m5s
textsender_api PR / Rustfmt (pull_request) Successful in 2m0s
textsender_api PR / Check (pull_request) Successful in 2m2s
textsender_api PR / Clippy (pull_request) Successful in 2m37s
Reviewed-on: phoenix/textsender_api#30
2026-07-04 21:07:30 -04:00
phoenix ba485261da Fixed issue (#29)
Rust Build / Rustfmt (push) Successful in 46s
Rust Build / Test Suite (push) Successful in 1m21s
Rust Build / Check (push) Successful in 2m20s
Rust Build / Clippy (push) Successful in 1m48s
Rust Build / build (push) Successful in 2m11s
textsender_api PR / Rustfmt (pull_request) Successful in 1m6s
textsender_api PR / Clippy (pull_request) Successful in 1m22s
textsender_api PR / Check (pull_request) Successful in 2m9s
Reviewed-on: phoenix/textsender_api#29
2026-07-04 18:34:51 -04:00
phoenix 71da521a53 CORS bug fix (#28)
Rust Build / Test Suite (push) Successful in 2m15s
Rust Build / Rustfmt (push) Successful in 48s
Rust Build / Check (push) Successful in 1m59s
Rust Build / Clippy (push) Successful in 1m38s
Rust Build / build (push) Successful in 3m44s
Reviewed-on: phoenix/textsender_api#28
2026-06-30 11:55:32 -04:00
14 changed files with 190 additions and 710 deletions
+2 -1
View File
@@ -10,4 +10,5 @@ TWILIO_AUTH_SID=9M438C93R943U4329MCU43C34U
TWILIO_SERVICE_SID=9M4J3X8439U398NUVT3342MC349C348T
TWILIO_AUTH_TOKEN="MA08HJp9tYtkfs72m8JIIROofRVm74oR0ixEYBHGYpB9"
TWILIO_PHONE_NUMBER=+10123456789
ALLOWED_ORIGINS="http://textsender.com"
ALLOWED_ORIGINS="http://textsender.com,http://localhost:5173,http://localhost:9080,http://localhost:9081"
APP_ENV=production
+2 -1
View File
@@ -10,4 +10,5 @@ TWILIO_AUTH_SID=9M438C93R943U4329MCU43C34U
TWILIO_SERVICE_SID=9M4J3X8439U398NUVT3342MC349C348T
TWILIO_AUTH_TOKEN="MA08HJp9tYtkfs72m8JIIROofRVm74oR0ixEYBHGYpB9"
TWILIO_PHONE_NUMBER=+10123456789
ALLOWED_ORIGINS="http://textsender.com"
ALLOWED_ORIGINS="http://textsender.com,http://localhost:5173,http://localhost:9080,http://localhost:9081"
APP_ENV=production
+10 -6
View File
@@ -5,15 +5,19 @@ on:
branches:
- main
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
check:
name: Check
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.96
toolchain: 1.96.1
- uses: Swatinem/rust-cache@v2
- run: |
mkdir -p ~/.ssh
@@ -30,10 +34,10 @@ jobs:
name: Rustfmt
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.96
toolchain: 1.96.1
- run: rustup component add rustfmt
- uses: Swatinem/rust-cache@v2
- run: |
@@ -50,10 +54,10 @@ jobs:
name: Clippy
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.96
toolchain: 1.96.1
- run: rustup component add clippy
- uses: Swatinem/rust-cache@v2
- run: |
+4 -4
View File
@@ -32,10 +32,10 @@ jobs:
--health-retries 5
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.96
toolchain: 1.96.1
# --- Add this step for explicit verification ---
- name: Verify Docker Environment
run: |
@@ -74,10 +74,10 @@ jobs:
name: Rustfmt
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.96
toolchain: 1.96.1
- run: rustup component add rustfmt
- uses: Swatinem/rust-cache@v2
- run: |
+10 -10
View File
@@ -15,10 +15,10 @@ jobs:
name: Check
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.96
toolchain: 1.96.1
- uses: Swatinem/rust-cache@v2
- run: |
mkdir -p ~/.ssh
@@ -52,10 +52,10 @@ jobs:
--health-retries 5
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.96
toolchain: 1.96.1
# --- Add this step for explicit verification ---
- name: Verify Docker Environment
run: |
@@ -94,10 +94,10 @@ jobs:
name: Rustfmt
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.96
toolchain: 1.96.1
- run: rustup component add rustfmt
- uses: Swatinem/rust-cache@v2
- run: |
@@ -114,10 +114,10 @@ jobs:
name: Clippy
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.96
toolchain: 1.96.1
- run: rustup component add clippy
- uses: Swatinem/rust-cache@v2
- run: |
@@ -134,10 +134,10 @@ jobs:
name: build
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.96
toolchain: 1.96.1
- uses: Swatinem/rust-cache@v2
- run: |
mkdir -p ~/.ssh
Generated
+117 -636
View File
File diff suppressed because it is too large Load Diff
+8 -11
View File
@@ -1,8 +1,8 @@
[package]
name = "textsender_api"
version = "0.2.0"
version = "0.2.3"
edition = "2024"
rust-version = "1.96"
rust-version = "1.96.1"
[dependencies]
axum = { version = "0.8.9", features = ["multipart"] }
@@ -10,21 +10,18 @@ axum-extra = { version = "0.12.6", features = ["cookie"] }
serde = { version = "1.0.228", features = ["derive"] }
serde_json = { version = "1.0.150" }
tokio = { version = "1.52.3", features = ["full"] }
tokio-util = { version = "0.7.18", features = ["io"] }
tower = { version = "0.5.3", features = ["full"] }
tower-http = { version = "0.6.11", features = ["cors", "timeout"] }
tower-http = { version = "0.7.0", features = ["cors", "timeout"] }
tracing-subscriber = "0.3.23"
futures = { version = "0.3.32" }
uuid = { version = "1.23.3", features = ["v4", "serde"] }
sqlx = { version = "0.9.0", features = ["runtime-tokio", "tls-native-tls", "postgres", "time", "uuid"] }
time = { version = "0.3.49", features = ["formatting", "macros", "parsing", "serde"] }
time = { version = "0.3.53", features = ["formatting", "macros", "parsing", "serde"] }
jsonwebtoken = { version = "10.4.0", features = ["rust_crypto"] }
josekit = { version = "0.10.3" }
utoipa = { version = "5.5.0", features = ["axum_extras"] }
utoipa-swagger-ui = { version = "9.0.2", features = ["axum"] }
textsender_models = { git = "ssh://git@git.kundeng.us/phoenix/textsender_models.git", tag = "v0.4.10" }
swoosh = { git = "ssh://git@git.kundeng.us/phoenix/swoosh.git", tag = "v0.4.2.0" }
textsender_models = { git = "ssh://git@git.kundeng.us/phoenix/textsender_models.git", tag = "v0.5.1" }
swoosh = { git = "ssh://git@git.kundeng.us/phoenix/swoosh.git", tag = "v0.5.2" }
[dev-dependencies]
tower = { version = "0.5.3", features = ["full"] }
josekit = { version = "0.10.3" }
url = { version = "2.5.8" }
tempfile = { version = "3.27.0" }
+1 -1
View File
@@ -1,5 +1,5 @@
# Stage 1: Build the application
FROM rust:1.96 as builder
FROM rust:1.96.1 as builder
# Set the working directory inside the container
WORKDIR /usr/src/app
+1 -3
View File
@@ -36,9 +36,7 @@ pub async fn auth<B>(
(StatusCode::UNAUTHORIZED, Json(json_error))
})?;
let secret_key = textsender_models::envy::environment::get_secret_main_key()
.await
.value;
let secret_key = textsender_models::envy::environment::get_secret_main_key().value;
let mut validation = Validation::new(jsonwebtoken::Algorithm::HS256);
validation.set_audience(&["textsender"]); // Must match exactly what's in the token
+22 -17
View File
@@ -81,18 +81,17 @@ pub mod endpoint {
match message_repo::get(&pool, &payload.message_id).await {
Ok(message) => {
println!("Valid message");
let t_config =
match textsender_models::config::auxiliary::load_config().await {
Ok(config) => config,
Err(err) => {
eprintln!("Error: {err:?}");
response.message = String::from("Error getting config");
return (
axum::http::StatusCode::INTERNAL_SERVER_ERROR,
axum::Json(response),
);
}
};
let t_config = match textsender_models::config::auxiliary::load_config() {
Ok(config) => config,
Err(err) => {
eprintln!("Error: {err:?}");
response.message = String::from("Error getting config");
return (
axum::http::StatusCode::INTERNAL_SERVER_ERROR,
axum::Json(response),
);
}
};
let mut results: Vec<
textsender_models::message::event::MessageEventResponse,
> = Vec::new();
@@ -101,12 +100,18 @@ pub mod endpoint {
schedule_at: None,
};
let mut sendmsg = swoosh::SendMsg::default();
sendmsg.load_config(
&t_config.auth_token,
&t_config.phone_number,
&t_config.service_sid,
&t_config.account_sid,
);
for contact in &contacts {
match swoosh::twilio::api::send_message(
&message, contact, &pp, &t_config,
)
.await
{
sendmsg.load_message(&message.content);
sendmsg.load_recipient(&contact.phone_number);
match sendmsg.send_message(&pp).await {
Ok(result) => {
let val = swoosh::twilio::api::response_to_json(result).await;
let mer = textsender_models::message::event::MessageEventResponse {
+2 -1
View File
@@ -33,6 +33,7 @@ pub mod init {
let cors = tower_http::cors::CorsLayer::new()
.allow_methods([
axum::http::Method::GET,
axum::http::Method::PATCH,
axum::http::Method::POST,
axum::http::Method::PUT,
axum::http::Method::DELETE,
@@ -49,7 +50,7 @@ pub mod init {
Ok("production") => {
// In production, allow only your specific, trusted origins
let allowed_origins_env =
textsender_models::envy::environment::get_allowed_origins().await;
textsender_models::envy::environment::get_allowed_origins();
match textsender_models::envy::utility::delimitize(&allowed_origins_env) {
Ok(alwd) => {
let allowed_origins: Vec<axum::http::HeaderValue> = alwd
+1 -3
View File
@@ -5,9 +5,7 @@ pub mod connection_settings {
}
pub async fn create_pool() -> Result<sqlx::PgPool, sqlx::Error> {
let database_url = textsender_models::envy::environment::get_db_url()
.await
.value;
let database_url = textsender_models::envy::environment::get_db_url().value;
println!("Database url: {database_url}");
PgPoolOptions::new()
+4 -2
View File
@@ -96,7 +96,9 @@ async fn parse_row(
let contact_id: uuid::Uuid = row.try_get("contact_id")?;
let message_id: uuid::Uuid = row.try_get("message_id")?;
let sent: time::OffsetDateTime = row.try_get("sent")?;
let scheduled_message_event_id: uuid::Uuid = row.try_get("scheduled_message_event_id")?;
let scheduled_message_event_id: Option<uuid::Uuid> = row
.try_get("scheduled_message_event_id")
.unwrap_or_default();
let user_id: uuid::Uuid = row.try_get("user_id")?;
Ok(textsender_models::message::event::MessageEventResponse {
@@ -106,7 +108,7 @@ async fn parse_row(
message_id,
status,
sent: Some(sent),
scheduled_message_event_id: Some(scheduled_message_event_id),
scheduled_message_event_id,
user_id,
})
}
+6 -14
View File
@@ -6,9 +6,7 @@ mod db_mgr {
pub const LIMIT: usize = 6;
pub async fn get_pool() -> Result<sqlx::PgPool, sqlx::Error> {
let tm_db_url = textsender_models::envy::environment::get_db_url()
.await
.value;
let tm_db_url = textsender_models::envy::environment::get_db_url().value;
let tm_options = sqlx::postgres::PgConnectOptions::from_str(&tm_db_url).unwrap();
sqlx::PgPool::connect_with(tm_options).await
}
@@ -20,9 +18,7 @@ mod db_mgr {
}
pub async fn connect_to_db(db_name: &str) -> Result<sqlx::PgPool, sqlx::Error> {
let db_url = textsender_models::envy::environment::get_db_url()
.await
.value;
let db_url = textsender_models::envy::environment::get_db_url().value;
let options = sqlx::postgres::PgConnectOptions::from_str(&db_url)?.database(db_name);
sqlx::PgPool::connect_with(options).await
}
@@ -81,9 +77,7 @@ mod db_mgr {
}
pub async fn get_database_name() -> Result<String, Box<dyn std::error::Error>> {
let database_url = textsender_models::envy::environment::get_db_url()
.await
.value;
let database_url = textsender_models::envy::environment::get_db_url().value;
let parsed_url = url::Url::parse(&database_url)?;
if parsed_url.scheme() == "postgres" || parsed_url.scheme() == "postgresql" {
@@ -191,9 +185,7 @@ pub fn test_mer_response() -> serde_json::Value {
}
pub async fn test_token() -> Result<String, josekit::JoseError> {
let key: String = textsender_models::envy::environment::get_secret_main_key()
.await
.value;
let key: String = textsender_models::envy::environment::get_secret_main_key().value;
let (message, issuer, audience) = token_fields();
let token_resource = textsender_models::token::TokenResource {
@@ -203,8 +195,8 @@ pub async fn test_token() -> Result<String, josekit::JoseError> {
user_id: TEST_USER_ID,
};
match textsender_models::token::create_token(&key, &token_resource, time::Duration::hours(1)) {
Ok((access_token, _some_time)) => Ok(access_token),
match textsender_models::token::create_token(&key, token_resource, time::Duration::hours(1)) {
Ok(access_token) => Ok(access_token.access_token),
Err(err) => Err(err),
}
}