Update to Rust edition 2024.

This commit is contained in:
Sebastian Jeltsch
2025-04-19 23:04:59 +02:00
parent ebddc51d85
commit d6b199587d
116 changed files with 423 additions and 379 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
[package]
name = "trailbase-client"
version = "0.4.0"
edition = "2021"
edition = "2024"
license = "OSL-3.0"
description = "Client for accessing TrailBase's record APIs"
homepage = "https://trailbase.io"
+3 -3
View File
@@ -396,10 +396,10 @@ impl RecordApi {
return Ok(());
}
pub async fn subscribe<'a>(
pub async fn subscribe<'a, T: RecordId<'a>>(
&self,
id: impl RecordId<'a>,
) -> Result<impl Stream<Item = DbEvent>, Error> {
id: T,
) -> Result<impl Stream<Item = DbEvent> + use<T>, Error> {
// TODO: Might have to add HeaderValue::from_static("text/event-stream").
let response = self
.client
+1 -1
View File
@@ -1,7 +1,7 @@
[package]
name = "record_api_rs"
version = "0.1.0"
edition = "2021"
edition = "2024"
publish = false
[dependencies]
+1 -1
View File
@@ -1,7 +1,7 @@
[package]
name = "custom-binary"
version = "0.1.0"
edition = "2021"
edition = "2024"
publish = false
[dependencies]
+1 -1
View File
@@ -1,7 +1,7 @@
use axum::{
extract::{FromRef, State},
response::{Html, IntoResponse, Response},
routing::{get, Router},
routing::{Router, get},
};
use trailbase::{AppState, DataDir, Server, ServerOptions, User};
+1 -1
View File
@@ -1,7 +1,7 @@
[package]
name = "trailbase-apalis"
version = "0.1.0"
edition = "2021"
edition = "2024"
publish = false
license = "OSL-3.0"
+17 -22
View File
@@ -1,12 +1,12 @@
use crate::context::SqlContext;
use crate::{calculate_status, Config, SqlError};
use crate::{Config, SqlError, calculate_status};
use apalis_core::backend::{BackendExpose, Stat, WorkerState};
use apalis_core::codec::json::JsonCodec;
use apalis_core::error::Error;
use apalis_core::layers::{Ack, AckLayer};
use apalis_core::poller::Poller;
use apalis_core::poller::controller::Controller;
use apalis_core::poller::stream::BackendStream;
use apalis_core::poller::Poller;
use apalis_core::request::{Parts, Request, RequestStream, State};
use apalis_core::response::Response;
use apalis_core::storage::Storage;
@@ -18,7 +18,7 @@ use async_stream::try_stream;
use chrono::{DateTime, Utc};
use futures::{FutureExt, Stream, StreamExt, TryFutureExt, TryStreamExt};
use log::error;
use serde::{de::DeserializeOwned, Serialize};
use serde::{Serialize, de::DeserializeOwned};
use std::any::type_name;
use std::convert::TryInto;
use std::fmt;
@@ -28,7 +28,7 @@ use std::{marker::PhantomData, time::Duration};
pub use trailbase_sqlite::Connection;
use crate::from_row::{from_row, SqlRequest};
use crate::from_row::{SqlRequest, from_row};
/// Represents a [Storage] that persists to Sqlite
pub struct SqliteStorage<T, C = JsonCodec<String>> {
@@ -221,7 +221,8 @@ where
worker: &Worker<Context>,
interval: Duration,
buffer_size: usize,
) -> impl Stream<Item = Result<Option<Request<T, SqlContext>>, trailbase_sqlite::Error>> {
) -> impl Stream<Item = Result<Option<Request<T, SqlContext>>, trailbase_sqlite::Error>> + use<T, C>
{
const FETCH_QUERY : &str = "SELECT id FROM Jobs
WHERE (status = 'Pending' OR (status = 'Failed' AND attempts < max_attempts)) AND run_at < ?1 AND job_type = ?2 ORDER BY priority DESC LIMIT ?3";
@@ -287,7 +288,7 @@ where
&mut self,
job: Request<Self::Job, SqlContext>,
) -> Result<Parts<SqlContext>, Self::Error> {
const QUERY : &str = "INSERT INTO Jobs VALUES (?1, ?2, ?3, 'Pending', 0, ?4, strftime('%s','now'), NULL, NULL, NULL, NULL, ?5)";
const QUERY: &str = "INSERT INTO Jobs VALUES (?1, ?2, ?3, 'Pending', 0, ?4, strftime('%s','now'), NULL, NULL, NULL, NULL, ?5)";
let (task, parts) = job.take_parts();
let raw = C::encode(&task).map_err(|e| trailbase_sqlite::Error::Other(e.into()))?;
let job_type = self.config.namespace.clone();
@@ -313,7 +314,7 @@ where
&mut self,
job: Request<Self::Compact, SqlContext>,
) -> Result<Parts<SqlContext>, Self::Error> {
const QUERY :&str = "INSERT INTO Jobs VALUES (?1, ?2, ?3, 'Pending', 0, ?4, strftime('%s','now'), NULL, NULL, NULL, NULL, ?5)";
const QUERY: &str = "INSERT INTO Jobs VALUES (?1, ?2, ?3, 'Pending', 0, ?4, strftime('%s','now'), NULL, NULL, NULL, NULL, ?5)";
let (task, parts) = job.take_parts();
let raw = C::encode(&task).map_err(|e| trailbase_sqlite::Error::Other(e.into()))?;
@@ -388,7 +389,7 @@ where
}
async fn len(&mut self) -> Result<i64, Self::Error> {
const QUERY : &str = "SELECT COUNT(*) AS count FROM Jobs WHERE (status = 'Pending' OR (status = 'Failed' AND attempts < max_attempts))";
const QUERY: &str = "SELECT COUNT(*) AS count FROM Jobs WHERE (status = 'Pending' OR (status = 'Failed' AND attempts < max_attempts))";
let count: Option<i64> = self
.conn
@@ -405,8 +406,7 @@ where
) -> Result<(), Self::Error> {
let task_id = job.parts.task_id;
const QUERY : &str =
"UPDATE Jobs SET status = 'Failed', done_at = NULL, lock_by = NULL, lock_at = NULL, run_at = ?2 WHERE id = ?1";
const QUERY: &str = "UPDATE Jobs SET status = 'Failed', done_at = NULL, lock_by = NULL, lock_at = NULL, run_at = ?2 WHERE id = ?1";
let wait: i64 = wait.as_secs() as i64;
let now: i64 = Utc::now().timestamp();
@@ -434,8 +434,7 @@ where
let priority = *ctx.priority();
let job_id = job.parts.task_id;
const QUERY : &str =
"UPDATE Jobs SET status = ?1, attempts = ?2, done_at = ?3, lock_by = ?4, lock_at = ?5, last_error = ?6, priority = ?7 WHERE id = ?8";
const QUERY: &str = "UPDATE Jobs SET status = ?1, attempts = ?2, done_at = ?3, lock_by = ?4, lock_at = ?5, last_error = ?6, priority = ?7 WHERE id = ?8";
self
.conn
@@ -478,8 +477,7 @@ impl<T, C> SqliteStorage<T, C> {
worker_id: &WorkerId,
job_id: &TaskId,
) -> Result<(), trailbase_sqlite::Error> {
const QUERY : &str =
"UPDATE Jobs SET status = 'Pending', done_at = NULL, lock_by = NULL WHERE id = ?1 AND lock_by = ?2";
const QUERY: &str = "UPDATE Jobs SET status = 'Pending', done_at = NULL, lock_by = NULL WHERE id = ?1 AND lock_by = ?2";
self
.conn
@@ -497,8 +495,7 @@ impl<T, C> SqliteStorage<T, C> {
worker_id: &WorkerId,
job_id: &TaskId,
) -> Result<(), trailbase_sqlite::Error> {
const QUERY : &str =
"UPDATE Jobs SET status = 'Killed', done_at = strftime('%s','now') WHERE id = ?1 AND lock_by = ?2";
const QUERY: &str = "UPDATE Jobs SET status = 'Killed', done_at = strftime('%s','now') WHERE id = ?1 AND lock_by = ?2";
self
.conn
@@ -632,8 +629,7 @@ impl<T: Sync + Send, C: Send, Res: Serialize + Sync> Ack<T, Res, C> for SqliteSt
res: &Response<Res>,
) -> Result<(), trailbase_sqlite::Error> {
let conn = self.conn.clone();
const QUERY : &str =
"UPDATE Jobs SET status = ?4, attempts = ?5, done_at = strftime('%s','now'), last_error = ?3 WHERE id = ?1 AND lock_by = ?2";
const QUERY: &str = "UPDATE Jobs SET status = ?4, attempts = ?5, done_at = strftime('%s','now'), last_error = ?3 WHERE id = ?1 AND lock_by = ?2";
let result = serde_json::to_string(&res.inner.as_ref().map_err(|r| r.to_string()))
.map_err(|e| trailbase_sqlite::Error::Other(e.into()))?;
@@ -703,7 +699,7 @@ impl<J: 'static + Serialize + DeserializeOwned + Unpin + Send + Sync> BackendExp
}
async fn list_jobs(&self, status: &State, page: i32) -> Result<Vec<Self::Request>, Self::Error> {
const FETCH_QUERY : &str = "SELECT * FROM Jobs WHERE status = ? AND job_type = ? ORDER BY done_at DESC, run_at DESC LIMIT 10 OFFSET ?";
const FETCH_QUERY: &str = "SELECT * FROM Jobs WHERE status = ? AND job_type = ? ORDER BY done_at DESC, run_at DESC LIMIT 10 OFFSET ?";
let status = status.to_string();
let res: Vec<SqlRequest<String>> = self
@@ -730,8 +726,7 @@ impl<J: 'static + Serialize + DeserializeOwned + Unpin + Send + Sync> BackendExp
}
async fn list_workers(&self) -> Result<Vec<Worker<WorkerState>>, Self::Error> {
const FETCH_QUERY : &str =
"SELECT id, layers, last_seen FROM Workers WHERE worker_type = ? ORDER BY last_seen DESC LIMIT 20 OFFSET ?";
const FETCH_QUERY: &str = "SELECT id, layers, last_seen FROM Workers WHERE worker_type = ? ORDER BY last_seen DESC LIMIT 20 OFFSET ?";
let res: Vec<(String, String, i64)> = self
.conn
@@ -757,8 +752,8 @@ mod tests {
use apalis_core::generic_storage_test;
use apalis_core::request::State;
use apalis_core::test_utils::apalis_test_service_fn;
use apalis_core::test_utils::TestWrapper;
use apalis_core::test_utils::apalis_test_service_fn;
use futures::StreamExt;
use std::io;
+1 -1
View File
@@ -1,7 +1,7 @@
[package]
name = "trailbase-assets"
version = "0.1.0"
edition = "2021"
edition = "2024"
license = "OSL-3.0"
description = "Assets for the TrailBase framework"
homepage = "https://trailbase.io"
+1 -1
View File
@@ -1,7 +1,7 @@
[package]
name = "trailbase-cli"
version = "0.2.0"
edition = "2021"
edition = "2024"
license = "OSL-3.0"
publish = false
+1 -1
View File
@@ -1,7 +1,7 @@
use clap::{Args, Parser, Subcommand, ValueEnum};
use trailbase::api::JsonSchemaMode;
use trailbase::DataDir;
use trailbase::api::JsonSchemaMode;
#[derive(ValueEnum, Clone, Copy, Debug)]
pub enum JsonSchemaModeArg {
+2 -2
View File
@@ -10,9 +10,9 @@ use serde::Deserialize;
use std::rc::Rc;
use tokio::{fs, io::AsyncWriteExt};
use trailbase::{
api::{self, init_app_state, Email, InitArgs, JsonSchemaMode, TokenClaims},
constants::USER_TABLE,
DataDir, Server, ServerOptions,
api::{self, Email, InitArgs, JsonSchemaMode, TokenClaims, init_app_state},
constants::USER_TABLE,
};
use trailbase_cli::{AdminSubCommands, DefaultCommandLineArgs, SubCommands, UserSubCommands};
+1 -1
View File
@@ -1,7 +1,7 @@
[package]
name = "trailbase"
version = "0.1.0"
edition = "2021"
edition = "2024"
license = "OSL-3.0"
description = "Package to use TrailBase as a framework"
homepage = "https://trailbase.io"
+3 -3
View File
@@ -1,6 +1,6 @@
#![allow(clippy::needless_return)]
use criterion::{criterion_group, criterion_main, Bencher, Criterion, Throughput};
use criterion::{Bencher, Criterion, Throughput, criterion_group, criterion_main};
use axum::body::Body;
use axum::extract::{Json, State};
@@ -10,10 +10,10 @@ use hyper::StatusCode;
use std::time::{Duration, Instant};
use tower::{Service, ServiceExt};
use trailbase::api::{create_user_handler, login_with_password, CreateUserRequest};
use trailbase::AppState;
use trailbase::api::{CreateUserRequest, create_user_handler, login_with_password};
use trailbase::config::proto::{PermissionFlag, RecordApiConfig};
use trailbase::constants::RECORD_API_PATH;
use trailbase::AppState;
use trailbase::{DataDir, Server, ServerOptions};
use trailbase_sqlite::params;
@@ -4,7 +4,7 @@ use axum_extra::protobuf::Protobuf;
use crate::admin::AdminError as Error;
use crate::app_state::AppState;
use crate::config::{
proto::{hash_config, GetConfigResponse},
proto::{GetConfigResponse, hash_config},
redact_secrets,
};
+1 -1
View File
@@ -1,5 +1,5 @@
use axum::body::Body;
use axum::http::{header::CONTENT_TYPE, StatusCode};
use axum::http::{StatusCode, header::CONTENT_TYPE};
use axum::response::{IntoResponse, Response};
use log::*;
use thiserror::Error;
+1 -1
View File
@@ -1,4 +1,4 @@
use axum::{extract::State, Json};
use axum::{Json, extract::State};
use serde::Serialize;
use ts_rs::TS;
+2 -2
View File
@@ -1,9 +1,9 @@
use axum::{extract::State, Json};
use axum::{Json, extract::State};
use serde::Serialize;
use ts_rs::TS;
use crate::admin::AdminError as Error;
use crate::AppState;
use crate::admin::AdminError as Error;
#[derive(Debug, Serialize, TS)]
pub struct Job {
+2 -2
View File
@@ -1,9 +1,9 @@
use axum::{extract::State, Json};
use axum::{Json, extract::State};
use serde::{Deserialize, Serialize};
use ts_rs::TS;
use crate::admin::AdminError as Error;
use crate::AppState;
use crate::admin::AdminError as Error;
#[derive(Debug, Deserialize, TS)]
#[ts(export)]
+4 -4
View File
@@ -1,6 +1,6 @@
use axum::{
extract::{RawQuery, State},
Json,
extract::{RawQuery, State},
};
use chrono::{DateTime, Duration, Utc};
use lazy_static::lazy_static;
@@ -15,10 +15,10 @@ use crate::admin::AdminError as Error;
use crate::app_state::AppState;
use crate::constants::{LOGS_RETENTION_DEFAULT, LOGS_TABLE_ID_COLUMN};
use crate::listing::{
build_filter_where_clause, limit_or_default, parse_and_sanitize_query, Cursor, Order,
QueryParseResult, WhereClause,
Cursor, Order, QueryParseResult, WhereClause, build_filter_where_clause, limit_or_default,
parse_and_sanitize_query,
};
use crate::table_metadata::{lookup_and_parse_table_schema, TableMetadata};
use crate::table_metadata::{TableMetadata, lookup_and_parse_table_schema};
#[derive(Debug, Serialize, TS)]
pub struct LogJson {
+1 -1
View File
@@ -16,8 +16,8 @@ pub use error::AdminError;
use crate::app_state::AppState;
use axum::{
routing::{delete, get, patch, post},
Router,
routing::{delete, get, patch, post},
};
pub fn router() -> Router<AppState> {
+1 -1
View File
@@ -1,4 +1,4 @@
use axum::{extract::State, Json};
use axum::{Json, extract::State};
use base64::prelude::*;
use serde::{Deserialize, Serialize};
use trailbase_schema::sqlite::sqlite3_parse_into_statement;
+2 -2
View File
@@ -1,6 +1,6 @@
use axum::{extract::State, Json};
use axum::{Json, extract::State};
use serde::{Deserialize, Serialize};
use trailbase_schema::sqlite::{sqlite3_parse_into_statements, Column};
use trailbase_schema::sqlite::{Column, sqlite3_parse_into_statements};
use ts_rs::TS;
use crate::admin::AdminError as Error;
+3 -3
View File
@@ -1,8 +1,8 @@
use axum::{
Json,
extract::{Path, State},
http::StatusCode,
response::{IntoResponse, Response},
Json,
};
use serde::{Deserialize, Serialize};
use ts_rs::TS;
@@ -111,8 +111,8 @@ mod tests {
use super::*;
use crate::admin::rows::insert_row::insert_row;
use crate::admin::rows::list_rows::list_rows_handler;
use crate::admin::rows::update_row::{update_row_handler, UpdateRowRequest};
use crate::admin::table::{create_table_handler, CreateTableRequest};
use crate::admin::rows::update_row::{UpdateRowRequest, update_row_handler};
use crate::admin::table::{CreateTableRequest, create_table_handler};
use crate::app_state::*;
use crate::records::test_utils::json_row_from_value;
use crate::util::uuid_to_b64;
+1 -1
View File
@@ -1,5 +1,5 @@
use axum::extract::{Path, State};
use axum::Json;
use axum::extract::{Path, State};
use serde::{Deserialize, Serialize};
use ts_rs::TS;
+2 -2
View File
@@ -9,8 +9,8 @@ use ts_rs::TS;
use crate::admin::AdminError as Error;
use crate::app_state::AppState;
use crate::listing::{
build_filter_where_clause, limit_or_default, parse_and_sanitize_query, Cursor, Order,
QueryParseResult, WhereClause,
Cursor, Order, QueryParseResult, WhereClause, build_filter_where_clause, limit_or_default,
parse_and_sanitize_query,
};
use crate::records::sql_to_json::rows_to_json_arrays;
use crate::table_metadata::{TableMetadata, TableOrViewMetadata};
+2 -2
View File
@@ -1,11 +1,11 @@
use axum::extract::{Path, State};
use axum::Json;
use axum::extract::{Path, State};
use serde::{Deserialize, Serialize};
use ts_rs::TS;
use crate::admin::AdminError as Error;
use crate::app_state::AppState;
use crate::records::params::{simple_json_value_to_param, JsonRow, Params};
use crate::records::params::{JsonRow, Params, simple_json_value_to_param};
use crate::records::query_builder::UpdateQueryBuilder;
#[derive(Debug, Serialize, Deserialize, Default, TS)]
@@ -1,8 +1,8 @@
use axum::{
Json,
extract::State,
http::StatusCode,
response::{IntoResponse, Response},
Json,
};
use log::*;
use serde::Deserialize;
@@ -1,10 +1,10 @@
use std::collections::HashSet;
use axum::{
Json,
extract::State,
http::StatusCode,
response::{IntoResponse, Response},
Json,
};
use log::*;
use serde::Deserialize;
@@ -139,7 +139,7 @@ mod tests {
use trailbase_schema::sqlite::{Column, ColumnDataType, ColumnOption, Table};
use super::*;
use crate::admin::table::{create_table_handler, CreateTableRequest};
use crate::admin::table::{CreateTableRequest, create_table_handler};
use crate::app_state::*;
#[tokio::test]
@@ -1,4 +1,4 @@
use axum::{extract::State, Json};
use axum::{Json, extract::State};
use serde::{Deserialize, Serialize};
use trailbase_schema::sqlite::TableIndex;
use ts_rs::TS;
@@ -1,4 +1,4 @@
use axum::{extract::State, Json};
use axum::{Json, extract::State};
use serde::{Deserialize, Serialize};
use trailbase_schema::sqlite::Table;
use ts_rs::TS;
+1 -1
View File
@@ -1,8 +1,8 @@
use axum::{
Json,
extract::State,
http::StatusCode,
response::{IntoResponse, Response},
Json,
};
use log::*;
use serde::Deserialize;
+1 -1
View File
@@ -1,8 +1,8 @@
use axum::{
Json,
extract::State,
http::StatusCode,
response::{IntoResponse, Response},
Json,
};
use log::*;
use serde::Deserialize;
@@ -1,7 +1,7 @@
use axum::{extract::State, Json};
use axum::{Json, extract::State};
use log::*;
use serde::{Deserialize, Serialize};
use trailbase_schema::sqlite::{sqlite3_parse_into_statement, Table, TableIndex, View};
use trailbase_schema::sqlite::{Table, TableIndex, View, sqlite3_parse_into_statement};
use ts_rs::TS;
use crate::admin::AdminError as Error;
+1 -1
View File
@@ -14,7 +14,7 @@ mod drop_table;
pub(crate) use alter_table::alter_table_handler;
#[allow(unused)]
pub(crate) use create_table::{create_table_handler, CreateTableRequest};
pub(crate) use create_table::{CreateTableRequest, create_table_handler};
pub(crate) use drop_table::drop_table_handler;
// Lists both Tables and Indexes
+1 -1
View File
@@ -1,4 +1,4 @@
use axum::{extract::State, Json};
use axum::{Json, extract::State};
use lazy_static::lazy_static;
use serde::{Deserialize, Serialize};
use trailbase_sqlite::named_params;
+2 -2
View File
@@ -1,15 +1,15 @@
use axum::{
Json,
extract::State,
http::StatusCode,
response::{IntoResponse, Response},
Json,
};
use serde::Deserialize;
use ts_rs::TS;
use crate::admin::AdminError as Error;
use crate::admin::rows::delete_row;
use crate::admin::user::is_demo_admin;
use crate::admin::AdminError as Error;
use crate::app_state::AppState;
use crate::util::uuid_to_b64;
+3 -3
View File
@@ -1,6 +1,6 @@
use axum::{
extract::{RawQuery, State},
Json,
extract::{RawQuery, State},
};
use lazy_static::lazy_static;
use serde::Serialize;
@@ -13,8 +13,8 @@ use crate::app_state::AppState;
use crate::auth::user::DbUser;
use crate::constants::{USER_TABLE, USER_TABLE_ID_COLUMN};
use crate::listing::{
build_filter_where_clause, limit_or_default, parse_and_sanitize_query, Cursor, Order,
QueryParseResult, WhereClause,
Cursor, Order, QueryParseResult, WhereClause, build_filter_where_clause, limit_or_default,
parse_and_sanitize_query,
};
use crate::util::id_to_b64;
+5 -5
View File
@@ -1,15 +1,15 @@
use trailbase_sqlite::params;
use uuid::Uuid;
use crate::constants::USER_TABLE;
use crate::AppState;
use crate::constants::USER_TABLE;
mod create_user;
mod delete_user;
mod list_users;
mod update_user;
pub use create_user::{create_user_handler, CreateUserRequest};
pub use create_user::{CreateUserRequest, create_user_handler};
pub(super) use delete_user::delete_user_handler;
pub(super) use list_users::list_users_handler;
pub(super) use update_user::update_user_handler;
@@ -39,15 +39,15 @@ pub(crate) use create_user::create_user_for_test;
#[cfg(test)]
mod tests {
use axum::{extract::State, Json};
use axum::{Json, extract::State};
use std::sync::Arc;
use trailbase_sqlite::params;
use uuid::Uuid;
use crate::app_state::{test_state, TestStateOptions};
use crate::app_state::{TestStateOptions, test_state};
use crate::auth::util::user_by_email;
use crate::constants::USER_TABLE;
use crate::email::{testing::TestAsyncSmtpTransport, Mailer};
use crate::email::{Mailer, testing::TestAsyncSmtpTransport};
use super::create_user::*;
+2 -2
View File
@@ -1,16 +1,16 @@
use axum::{
Json,
extract::State,
http::StatusCode,
response::{IntoResponse, Response},
Json,
};
use lazy_static::lazy_static;
use rusqlite::params;
use serde::{Deserialize, Serialize};
use ts_rs::TS;
use crate::admin::user::is_demo_admin;
use crate::admin::AdminError as Error;
use crate::admin::user::is_demo_admin;
use crate::app_state::AppState;
use crate::auth::password::hash_password;
use crate::constants::USER_TABLE;
+3 -3
View File
@@ -5,14 +5,14 @@ use std::sync::Arc;
use crate::auth::jwt::JwtHelper;
use crate::auth::oauth::providers::{ConfiguredOAuthProviders, OAuthProviderType};
use crate::config::proto::{hash_config, Config, RecordApiConfig, S3StorageConfig};
use crate::config::proto::{Config, RecordApiConfig, S3StorageConfig, hash_config};
use crate::config::{validate_config, write_config_and_vault_textproto};
use crate::data_dir::DataDir;
use crate::email::Mailer;
use crate::js::RuntimeHandle;
use crate::records::subscribe::SubscriptionManager;
use crate::records::RecordApi;
use crate::scheduler::{build_job_registry_from_config, JobRegistry};
use crate::records::subscribe::SubscriptionManager;
use crate::scheduler::{JobRegistry, build_job_registry_from_config};
use crate::table_metadata::TableMetadataCache;
use crate::value_notifier::{Computed, ValueNotifier};
+12 -10
View File
@@ -1,5 +1,5 @@
use axum::extract::{Json, Path, State};
use axum::http::{header, HeaderMap, StatusCode};
use axum::http::{HeaderMap, StatusCode, header};
use axum::response::{IntoResponse, Redirect, Response};
use lazy_static::lazy_static;
use serde::{Deserialize, Serialize};
@@ -8,9 +8,9 @@ use trailbase_sqlite::params;
use uuid::Uuid;
use crate::app_state::AppState;
use crate::auth::AuthError;
use crate::auth::user::DbUser;
use crate::auth::util::user_by_id;
use crate::auth::AuthError;
use crate::constants::{AVATAR_TABLE, RECORD_API_PATH};
use crate::util::{assert_uuidv7_version, id_to_b64};
@@ -118,7 +118,7 @@ mod tests {
use crate::constants::{AVATAR_TABLE, USER_TABLE};
use crate::extract::Either;
use crate::records::create_record::{
create_record_handler, CreateRecordQuery, CreateRecordResponse,
CreateRecordQuery, CreateRecordResponse, create_record_handler,
};
use crate::records::read_record::get_uploaded_file_from_record_handler;
use crate::test::unpack_json_response;
@@ -262,13 +262,15 @@ mod tests {
);
// Test non png/jpeg types will be rejected
assert!(upload_avatar(
&state,
User::from_auth_token(&state, &user_x_token.auth_token),
b"<html><body>Body 0</body></html>",
)
.await
.is_err());
assert!(
upload_avatar(
&state,
User::from_auth_token(&state, &user_x_token.auth_token),
b"<html><body>Body 0</body></html>",
)
.await
.is_err()
);
let avatar_response = get_avatar_url_handler(
State(state.clone()),
+1 -1
View File
@@ -5,9 +5,9 @@ use lazy_static::lazy_static;
use tower_cookies::Cookies;
use crate::app_state::AppState;
use crate::auth::AuthError;
use crate::auth::user::User;
use crate::auth::util::{delete_all_sessions_for_user, remove_all_cookies};
use crate::auth::AuthError;
use crate::constants::USER_TABLE;
/// Get public profile of the given user.
+3 -3
View File
@@ -1,8 +1,8 @@
use argon2::{Argon2, PasswordHash, PasswordVerifier};
use axum::{
Json,
extract::{Query, State},
response::{IntoResponse, Redirect, Response},
Json,
};
use lazy_static::lazy_static;
use serde::{Deserialize, Serialize};
@@ -12,11 +12,11 @@ use ts_rs::TS;
use utoipa::{IntoParams, ToSchema};
use crate::app_state::AppState;
use crate::auth::AuthError;
use crate::auth::api::register::validate_and_normalize_email_address;
use crate::auth::tokens::{mint_new_tokens, Tokens};
use crate::auth::tokens::{Tokens, mint_new_tokens};
use crate::auth::user::DbUser;
use crate::auth::util::{new_cookie, user_by_email, validate_redirects};
use crate::auth::AuthError;
use crate::constants::{
COOKIE_AUTH_TOKEN, COOKIE_REFRESH_TOKEN, USER_TABLE, VERIFICATION_CODE_LENGTH,
};
+2 -2
View File
@@ -8,12 +8,12 @@ use tower_cookies::Cookies;
use ts_rs::TS;
use utoipa::{IntoParams, ToSchema};
use crate::AppState;
use crate::auth::AuthError;
use crate::auth::user::User;
use crate::auth::util::{
delete_all_sessions_for_user, delete_session, remove_all_cookies, validate_redirects,
};
use crate::auth::AuthError;
use crate::AppState;
#[derive(Debug, Default, Deserialize, IntoParams)]
pub struct LogoutQuery {
+1 -1
View File
@@ -4,8 +4,8 @@ use ts_rs::TS;
use utoipa::ToSchema;
use crate::app_state::AppState;
use crate::auth::tokens::reauth_with_refresh_token;
use crate::auth::AuthError;
use crate::auth::tokens::reauth_with_refresh_token;
#[derive(Debug, Deserialize, ToSchema, TS)]
#[ts(export)]
+1 -1
View File
@@ -9,10 +9,10 @@ use utoipa::ToSchema;
use validator::ValidateEmail;
use crate::app_state::AppState;
use crate::auth::AuthError;
use crate::auth::password::{hash_password, validate_passwords};
use crate::auth::user::DbUser;
use crate::auth::util::user_exists;
use crate::auth::AuthError;
use crate::constants::{PASSWORD_OPTIONS, USER_TABLE, VERIFICATION_CODE_LENGTH};
use crate::email::Email;
use crate::rand::generate_random_string;
@@ -16,10 +16,10 @@ use crate::email::Email;
use crate::extract::Either;
use crate::rand::generate_random_string;
use crate::auth::AuthError;
use crate::auth::api::register::validate_and_normalize_email_address;
use crate::auth::password::{hash_password, validate_passwords};
use crate::auth::util::user_by_email;
use crate::auth::AuthError;
const TTL_SEC: i64 = 3600;
const RATE_LIMIT_SEC: i64 = 4 * 3600;
+1 -1
View File
@@ -5,9 +5,9 @@ use trailbase_sqlite::params;
use ts_rs::TS;
use utoipa::ToSchema;
use crate::auth::AuthError;
use crate::auth::tokens::mint_new_tokens;
use crate::auth::util::derive_pkce_code_challenge;
use crate::auth::AuthError;
use crate::constants::{USER_TABLE, VERIFICATION_CODE_LENGTH};
use crate::{app_state::AppState, auth::user::DbUser};
+1 -1
View File
@@ -9,8 +9,8 @@ use trailbase_sqlite::params;
use utoipa::{IntoParams, ToSchema};
use crate::app_state::AppState;
use crate::auth::util::{user_by_email, validate_redirects};
use crate::auth::AuthError;
use crate::auth::util::{user_by_email, validate_redirects};
use crate::constants::{USER_TABLE, VERIFICATION_CODE_LENGTH};
use crate::email::Email;
use crate::rand::generate_random_string;
+62 -46
View File
@@ -4,25 +4,25 @@ use tower_cookies::Cookies;
use trailbase_sqlite::params;
use crate::api::TokenClaims;
use crate::app_state::{test_state, TestStateOptions};
use crate::app_state::{TestStateOptions, test_state};
use crate::auth::api::change_email;
use crate::auth::api::change_email::ChangeEmailConfigQuery;
use crate::auth::api::change_password::{
change_password_handler, ChangePasswordQuery, ChangePasswordRequest,
ChangePasswordQuery, ChangePasswordRequest, change_password_handler,
};
use crate::auth::api::delete::delete_handler;
use crate::auth::api::login::login_with_password;
use crate::auth::api::logout::{logout_handler, LogoutQuery};
use crate::auth::api::refresh::{refresh_handler, RefreshRequest};
use crate::auth::api::register::{register_user_handler, RegisterUserRequest};
use crate::auth::api::logout::{LogoutQuery, logout_handler};
use crate::auth::api::refresh::{RefreshRequest, refresh_handler};
use crate::auth::api::register::{RegisterUserRequest, register_user_handler};
use crate::auth::api::reset_password::{
reset_password_request_handler, reset_password_update_handler, ResetPasswordRequest,
ResetPasswordUpdateRequest,
ResetPasswordRequest, ResetPasswordUpdateRequest, reset_password_request_handler,
reset_password_update_handler,
};
use crate::auth::api::verify_email::{verify_email_handler, VerifyEmailQuery};
use crate::auth::api::verify_email::{VerifyEmailQuery, verify_email_handler};
use crate::auth::user::{DbUser, User};
use crate::constants::*;
use crate::email::{testing::TestAsyncSmtpTransport, Mailer};
use crate::email::{Mailer, testing::TestAsyncSmtpTransport};
use crate::extract::Either;
#[tokio::test]
@@ -90,9 +90,11 @@ async fn test_auth_registration_reset_and_change_email() {
);
// Check that log in pre-verification fails.
assert!(login_with_password(&state, &email, &password)
.await
.is_err());
assert!(
login_with_password(&state, &email, &password)
.await
.is_err()
);
let _ = verify_email_handler(
State(state.clone()),
@@ -130,9 +132,11 @@ async fn test_auth_registration_reset_and_change_email() {
.await;
assert!(response.is_err());
assert!(login_with_password(&state, &email, "Wrong Password")
.await
.is_err());
assert!(
login_with_password(&state, &email, "Wrong Password")
.await
.is_err()
);
let tokens = login_with_password(&state, &email, &password)
.await
@@ -200,14 +204,16 @@ async fn test_auth_registration_reset_and_change_email() {
assert_eq!(mailer.get_logs().len(), 2);
// Test rate limiting.
assert!(reset_password_request_handler(
State(state.clone()),
Either::Json(ResetPasswordRequest {
email: email.clone()
}),
)
.await
.is_err());
assert!(
reset_password_request_handler(
State(state.clone()),
Either::Json(ResetPasswordRequest {
email: email.clone()
}),
)
.await
.is_err()
);
assert_eq!(mailer.get_logs().len(), 2);
@@ -248,9 +254,11 @@ async fn test_auth_registration_reset_and_change_email() {
.unwrap();
{
assert!(login_with_password(&state, &email, &password)
.await
.is_err());
assert!(
login_with_password(&state, &email, &password)
.await
.is_err()
);
let tokens = login_with_password(&state, &email, &new_password)
.await
@@ -297,17 +305,19 @@ async fn test_auth_registration_reset_and_change_email() {
// Change Email flow.
// Form requests require old email
assert!(change_email::change_email_request_handler(
State(state.clone()),
user.clone(),
Either::Form(change_email::ChangeEmailRequest {
csrf_token: user.csrf_token.clone(),
old_email: None,
new_email: new_email.clone(),
}),
)
.await
.is_err());
assert!(
change_email::change_email_request_handler(
State(state.clone()),
user.clone(),
Either::Form(change_email::ChangeEmailRequest {
csrf_token: user.csrf_token.clone(),
old_email: None,
new_email: new_email.clone(),
}),
)
.await
.is_err()
);
change_email::change_email_request_handler(
State(state.clone()),
@@ -370,9 +380,11 @@ async fn test_auth_registration_reset_and_change_email() {
assert_eq!(new_email, db_email);
assert!(login_with_password(&state, &email, &reset_password)
.await
.is_err());
assert!(
login_with_password(&state, &email, &reset_password)
.await
.is_err()
);
let _ = login_with_password(&state, &new_email, &reset_password)
.await
.unwrap();
@@ -396,12 +408,16 @@ async fn test_auth_registration_reset_and_change_email() {
.await
.unwrap();
assert!(login_with_password(&state, &new_email, &password)
.await
.is_err());
assert!(login_with_password(&state, &new_email, &old_password)
.await
.is_err());
assert!(
login_with_password(&state, &new_email, &password)
.await
.is_err()
);
assert!(
login_with_password(&state, &new_email, &old_password)
.await
.is_err()
);
let _ = login_with_password(&state, &new_email, &new_password)
.await
+1 -1
View File
@@ -1,5 +1,5 @@
use axum::body::Body;
use axum::http::{header::CONTENT_TYPE, StatusCode};
use axum::http::{StatusCode, header::CONTENT_TYPE};
use axum::response::{IntoResponse, Response};
use log::*;
use thiserror::Error;
+2 -2
View File
@@ -4,8 +4,8 @@ use argon2::password_hash::rand_core::OsRng;
use ed25519_dalek::pkcs8::spki::der::pem::LineEnding;
use ed25519_dalek::pkcs8::{EncodePrivateKey, EncodePublicKey};
use ed25519_dalek::{SigningKey, VerifyingKey};
use jsonwebtoken::{errors::Error as JwtError, DecodingKey, EncodingKey, Header, Validation};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use jsonwebtoken::{DecodingKey, EncodingKey, Header, Validation, errors::Error as JwtError};
use serde::{Deserialize, Serialize, de::DeserializeOwned};
use std::path::{Path, PathBuf};
use thiserror::Error;
use tokio::{
+1 -1
View File
@@ -1,6 +1,6 @@
use axum::{
routing::{delete, get, post},
Router,
routing::{delete, get, post},
};
use utoipa::OpenApi;
+4 -4
View File
@@ -11,18 +11,18 @@ use tower_cookies::Cookies;
use trailbase_sqlite::{named_params, params};
use uuid::Uuid;
use crate::auth::oauth::state::{OAuthState, ResponseType};
use crate::AppState;
use crate::auth::AuthError;
use crate::auth::oauth::OAuthUser;
use crate::auth::tokens::{mint_new_tokens, FreshTokens};
use crate::auth::oauth::state::{OAuthState, ResponseType};
use crate::auth::tokens::{FreshTokens, mint_new_tokens};
use crate::auth::user::DbUser;
use crate::auth::util::{new_cookie, remove_cookie, user_by_id, validate_redirects};
use crate::auth::AuthError;
use crate::config::proto::OAuthProviderId;
use crate::constants::{
COOKIE_AUTH_TOKEN, COOKIE_OAUTH_STATE, COOKIE_REFRESH_TOKEN, USER_TABLE, VERIFICATION_CODE_LENGTH,
};
use crate::rand::generate_random_string;
use crate::AppState;
#[derive(Debug, Deserialize)]
pub struct AuthRequest {
@@ -1,10 +1,10 @@
use axum::extract::State;
use axum::Json;
use axum::extract::State;
use serde::Serialize;
use ts_rs::TS;
use crate::auth::AuthError;
use crate::AppState;
use crate::auth::AuthError;
#[derive(Debug, Serialize, TS)]
#[ts(export)]
+2 -2
View File
@@ -8,11 +8,11 @@ use serde::Deserialize;
use tower_cookies::Cookies;
use utoipa::IntoParams;
use crate::AppState;
use crate::auth::AuthError;
use crate::auth::oauth::state::{OAuthState, ResponseType};
use crate::auth::util::{new_cookie_opts, validate_redirects};
use crate::auth::AuthError;
use crate::constants::COOKIE_OAUTH_STATE;
use crate::AppState;
#[derive(Debug, Default, Deserialize, IntoParams)]
pub(crate) struct LoginQuery {
+1 -1
View File
@@ -9,8 +9,8 @@ mod state;
#[cfg(test)]
mod oauth_test;
use axum::routing::get;
use axum::Router;
use axum::routing::get;
pub(crate) use provider::{OAuthClientSettings, OAuthProvider, OAuthUser};
+2 -2
View File
@@ -1,12 +1,12 @@
use axum::extract::{Form, Json, Path, Query, State};
use axum::http::StatusCode;
use axum::response::{IntoResponse, Redirect};
use axum::routing::{get, post, Router};
use axum::routing::{Router, get, post};
use axum_test::{TestServer, TestServerConfig};
use serde::{Deserialize, Serialize};
use tower_cookies::Cookies;
use crate::app_state::{test_state, TestStateOptions};
use crate::app_state::{TestStateOptions, test_state};
use crate::auth::oauth::providers::test::{TestOAuthProvider, TestUser};
use crate::auth::oauth::state::OAuthState;
use crate::auth::oauth::{callback, list_providers, login};
@@ -3,9 +3,9 @@ use lazy_static::lazy_static;
use serde::Deserialize;
use url::Url;
use crate::auth::AuthError;
use crate::auth::oauth::providers::{OAuthProviderError, OAuthProviderFactory};
use crate::auth::oauth::{OAuthClientSettings, OAuthProvider, OAuthUser};
use crate::auth::AuthError;
use crate::config::proto::{OAuthProviderConfig, OAuthProviderId};
pub(crate) struct DiscordOAuthProvider {
@@ -3,9 +3,9 @@ use lazy_static::lazy_static;
use serde::Deserialize;
use url::Url;
use crate::auth::AuthError;
use crate::auth::oauth::providers::{OAuthProviderError, OAuthProviderFactory};
use crate::auth::oauth::{OAuthClientSettings, OAuthProvider, OAuthUser};
use crate::auth::AuthError;
use crate::config::proto::{OAuthProviderConfig, OAuthProviderId};
#[derive(Default, Deserialize, Debug)]
@@ -3,9 +3,9 @@ use lazy_static::lazy_static;
use serde::Deserialize;
use url::Url;
use crate::auth::AuthError;
use crate::auth::oauth::providers::{OAuthProviderError, OAuthProviderFactory};
use crate::auth::oauth::{OAuthClientSettings, OAuthProvider, OAuthUser};
use crate::auth::AuthError;
use crate::config::proto::{OAuthProviderConfig, OAuthProviderId};
pub(crate) struct GitlabOAuthProvider {
@@ -3,9 +3,9 @@ use lazy_static::lazy_static;
use serde::Deserialize;
use url::Url;
use crate::auth::AuthError;
use crate::auth::oauth::providers::{OAuthProviderError, OAuthProviderFactory};
use crate::auth::oauth::{OAuthClientSettings, OAuthProvider, OAuthUser};
use crate::auth::AuthError;
use crate::config::proto::{OAuthProviderConfig, OAuthProviderId};
pub(crate) struct GoogleOAuthProvider {
@@ -3,9 +3,9 @@ use lazy_static::lazy_static;
use serde::Deserialize;
use url::Url;
use crate::auth::AuthError;
use crate::auth::oauth::providers::{OAuthProviderError, OAuthProviderFactory};
use crate::auth::oauth::{OAuthClientSettings, OAuthProvider, OAuthUser};
use crate::auth::AuthError;
use crate::config::proto::{OAuthProviderConfig, OAuthProviderId};
#[derive(Default, Deserialize, Debug)]
@@ -2,9 +2,9 @@ use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use url::Url;
use crate::auth::AuthError;
use crate::auth::oauth::providers::OAuthProviderFactory;
use crate::auth::oauth::{OAuthClientSettings, OAuthProvider, OAuthUser};
use crate::auth::AuthError;
use crate::config::proto::{OAuthProviderConfig, OAuthProviderId};
// TODO: Add name/display name and this would already be a generic CustomOAuthProvider.
@@ -2,9 +2,9 @@ use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use url::Url;
use crate::auth::AuthError;
use crate::auth::oauth::providers::OAuthProviderFactory;
use crate::auth::oauth::{OAuthClientSettings, OAuthProvider, OAuthUser};
use crate::auth::AuthError;
use crate::config::proto::{OAuthProviderConfig, OAuthProviderId};
pub struct TestOAuthProvider {
+1 -1
View File
@@ -1,6 +1,6 @@
use argon2::{
password_hash::{rand_core::OsRng, SaltString},
Argon2, PasswordHasher,
password_hash::{SaltString, rand_core::OsRng},
};
use crate::auth::AuthError;
+1 -1
View File
@@ -8,10 +8,10 @@ use tower_cookies::Cookies;
use trailbase_sqlite::params;
use crate::app_state::AppState;
use crate::auth::AuthError;
use crate::auth::jwt::TokenClaims;
use crate::auth::user::DbUser;
use crate::auth::util::new_cookie;
use crate::auth::AuthError;
use crate::constants::{
COOKIE_AUTH_TOKEN, COOKIE_REFRESH_TOKEN, HEADER_REFRESH_TOKEN, REFRESH_TOKEN_LENGTH,
SESSION_TABLE, USER_TABLE,
+2 -2
View File
@@ -1,15 +1,15 @@
use askama::Template;
use axum::Router;
use axum::extract::Query;
use axum::response::{Html, IntoResponse, Redirect, Response};
use axum::routing::get;
use axum::Router;
use reqwest::StatusCode;
use serde::Deserialize;
use trailbase_assets::AssetService;
use trailbase_assets::auth::{
ChangeEmailTemplate, ChangePasswordTemplate, LoginTemplate, RegisterTemplate,
ResetPasswordRequestTemplate, ResetPasswordUpdateTemplate,
};
use trailbase_assets::AssetService;
use crate::auth::User;
+2 -2
View File
@@ -5,9 +5,9 @@ use axum::{
use serde::{Deserialize, Serialize};
use uuid::Uuid;
use crate::auth::AuthError;
use crate::auth::jwt::TokenClaims;
use crate::auth::tokens::extract_tokens_from_request_parts;
use crate::auth::AuthError;
use crate::{app_state::AppState, util::b64_to_uuid};
#[derive(Debug, Clone, Deserialize, Serialize)]
@@ -149,7 +149,7 @@ where
mod tests {
use super::*;
use axum::body::Body;
use axum::http::{header, Request};
use axum::http::{Request, header};
use crate::admin::user::create_user_for_test;
use crate::app_state::test_state;
+3 -3
View File
@@ -3,17 +3,17 @@ use chrono::Duration;
use lazy_static::lazy_static;
use sha2::{Digest, Sha256};
use tower_cookies::{
cookie::{self, SameSite},
Cookie, Cookies,
cookie::{self, SameSite},
};
use trailbase_sqlite::params;
use crate::auth::user::{DbUser, User};
use crate::AppState;
use crate::auth::AuthError;
use crate::auth::user::{DbUser, User};
use crate::constants::{
COOKIE_AUTH_TOKEN, COOKIE_OAUTH_STATE, COOKIE_REFRESH_TOKEN, SESSION_TABLE, USER_TABLE,
};
use crate::AppState;
pub(crate) fn validate_redirects(
state: &AppState,
+2 -2
View File
@@ -11,11 +11,11 @@ use thiserror::Error;
use tokio::fs;
use validator::{ValidateEmail, ValidateUrl};
use crate::DESCRIPTOR_POOL;
use crate::auth::oauth::providers::oauth_provider_registry;
use crate::data_dir::DataDir;
use crate::records::validate_record_api_config;
use crate::table_metadata::TableMetadataCache;
use crate::DESCRIPTOR_POOL;
#[derive(Debug, Error)]
pub enum ConfigError {
@@ -71,12 +71,12 @@ pub mod proto {
use prost_reflect::{DynamicMessage, MessageDescriptor, ReflectMessage};
use std::hash::{DefaultHasher, Hash, Hasher};
use crate::DESCRIPTOR_POOL;
use crate::config::ConfigError;
use crate::constants::{
AVATAR_TABLE, DEFAULT_AUTH_TOKEN_TTL, DEFAULT_REFRESH_TOKEN_TTL, LOGS_RETENTION_DEFAULT,
};
use crate::email;
use crate::DESCRIPTOR_POOL;
include!(concat!(env!("OUT_DIR"), "/config.rs"));
+4 -4
View File
@@ -1,13 +1,13 @@
use lettre::address::AddressError;
use lettre::message::{header::ContentType, Body, Mailbox, Message};
use lettre::message::{Body, Mailbox, Message, header::ContentType};
use lettre::transport::smtp;
use lettre::{AsyncSendmailTransport, AsyncSmtpTransport, AsyncTransport, Tokio1Executor};
use minijinja::{context, Environment};
use minijinja::{Environment, context};
use std::sync::Arc;
use thiserror::Error;
use crate::config::proto::{Config, EmailTemplate};
use crate::AppState;
use crate::config::proto::{Config, EmailTemplate};
#[derive(Debug, Error)]
pub enum EmailError {
@@ -362,9 +362,9 @@ pub(crate) mod defaults {
#[cfg(test)]
pub mod testing {
use lettre::AsyncTransport;
use lettre::address::Envelope;
use lettre::transport::smtp::response::{Category, Code, Detail, Response, Severity};
use lettre::AsyncTransport;
use parking_lot::Mutex;
use std::sync::Arc;
+6 -6
View File
@@ -1,15 +1,15 @@
use axum::extract::{rejection::*, Form, FromRequest, Request};
use axum::http::header::CONTENT_TYPE;
use axum::http::StatusCode;
use axum::response::{IntoResponse, Response};
use axum::Json;
use axum::extract::{Form, FromRequest, Request, rejection::*};
use axum::http::StatusCode;
use axum::http::header::CONTENT_TYPE;
use axum::response::{IntoResponse, Response};
use log::*;
use serde::de::DeserializeOwned;
use serde::Serialize;
use serde::de::DeserializeOwned;
use thiserror::Error;
use trailbase_schema::FileUploadInput;
use crate::extract::multipart::{parse_multipart, Rejection as MultipartRejection};
use crate::extract::multipart::{Rejection as MultipartRejection, parse_multipart};
#[derive(Debug, Error)]
pub enum EitherRejection {
+1 -1
View File
@@ -1,6 +1,6 @@
use rustyscript::deno_core::{
anyhow::{anyhow, Error},
ModuleSpecifier, RequestedModuleType, ResolutionKind,
anyhow::{Error, anyhow},
};
use rustyscript::module_loader::ImportProvider;
+4 -4
View File
@@ -1,13 +1,13 @@
use axum::Router;
use axum::body::Body;
use axum::extract::{RawPathParams, Request};
use axum::http::{header::CONTENT_TYPE, request::Parts, HeaderName, HeaderValue, StatusCode};
use axum::http::{HeaderName, HeaderValue, StatusCode, header::CONTENT_TYPE, request::Parts};
use axum::response::{IntoResponse, Response};
use axum::Router;
use log::*;
use parking_lot::Mutex;
use rustyscript::{
deno_core::PollEventLoopOptions, init_platform, js_value::Promise, json_args, Error as RSError,
Module, Runtime,
Error as RSError, Module, Runtime, deno_core::PollEventLoopOptions, init_platform,
js_value::Promise, json_args,
};
use serde::{Deserialize, Serialize};
use serde_json::from_value;
+4 -4
View File
@@ -58,14 +58,14 @@ pub mod openapi {
}
pub mod api {
pub use crate::admin::user::{create_user_handler, CreateUserRequest};
pub use crate::admin::user::{CreateUserRequest, create_user_handler};
pub use crate::auth::api::login::login_with_password;
pub use crate::auth::{force_password_reset, JwtHelper, TokenClaims};
pub use crate::auth::{JwtHelper, TokenClaims, force_password_reset};
pub use crate::connection::connect_sqlite;
pub use crate::email::{Email, EmailError};
pub use crate::migrations::new_unique_migration_filename;
pub use crate::records::json_schema::build_api_json_schema;
pub use crate::server::{init_app_state, serve, InitArgs};
pub use crate::server::{InitArgs, init_app_state, serve};
pub use crate::table_metadata::TableMetadataCache;
pub use trailbase_schema::json_schema::JsonSchemaMode;
@@ -73,8 +73,8 @@ pub mod api {
pub(crate) mod rand {
use rand::{
distr::{Alphanumeric, SampleString},
CryptoRng,
distr::{Alphanumeric, SampleString},
};
pub(crate) fn generate_random_string(length: usize) -> String {
+3 -3
View File
@@ -1,5 +1,5 @@
use axum::body::Body;
use axum::http::{header, Request};
use axum::http::{Request, header};
use axum::response::Response;
use axum_client_ip::InsecureClientIp;
use futures_util::StreamExt;
@@ -7,14 +7,14 @@ use serde::{Deserialize, Serialize};
use serde_json::json;
use std::time::Duration;
use tokio::io::AsyncWriteExt;
use tracing::Level;
use tracing::field::Field;
use tracing::span::{Attributes, Id, Record, Span};
use tracing::Level;
use tracing_subscriber::layer::{Context, Layer};
use uuid::Uuid;
use crate::util::get_header;
use crate::AppState;
use crate::util::get_header;
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
enum HttpMethod {
+1 -1
View File
@@ -63,7 +63,7 @@ mod test {
use crate::config::proto::PermissionFlag;
use crate::extract::Either;
use crate::records::create_record::{
create_record_handler, CreateRecordQuery, CreateRecordResponse,
CreateRecordQuery, CreateRecordResponse, create_record_handler,
};
use crate::records::test_utils::*;
use crate::records::*;
+1 -1
View File
@@ -1,5 +1,5 @@
use axum::body::Body;
use axum::http::{header::CONTENT_TYPE, StatusCode};
use axum::http::{StatusCode, header::CONTENT_TYPE};
use axum::response::{IntoResponse, Response};
use log::*;
use thiserror::Error;
+1 -1
View File
@@ -1,7 +1,7 @@
use axum::extract::{Json, Path, Query, State};
use serde::Deserialize;
use trailbase_schema::json_schema::{
build_json_schema, build_json_schema_expanded, Expand, JsonSchemaMode,
Expand, JsonSchemaMode, build_json_schema, build_json_schema_expanded,
};
use crate::app_state::AppState;
+5 -5
View File
@@ -1,7 +1,7 @@
use askama::Template;
use axum::{
extract::{Path, RawQuery, State},
Json,
extract::{Path, RawQuery, State},
};
use itertools::Itertools;
use serde::Serialize;
@@ -10,8 +10,8 @@ use trailbase_sqlite::Value;
use crate::auth::user::User;
use crate::listing::{
build_filter_where_clause, limit_or_default, parse_and_sanitize_query, Order, QueryParseResult,
WhereClause,
Order, QueryParseResult, WhereClause, build_filter_where_clause, limit_or_default,
parse_and_sanitize_query,
};
use crate::records::query_builder::ExpandedTable;
use crate::records::sql_to_json::{row_to_json, row_to_json_expand, rows_to_json_expand};
@@ -272,10 +272,10 @@ mod tests {
use crate::auth::api::login::login_with_password;
use crate::auth::user::User;
use crate::config::proto::PermissionFlag;
use crate::records::Acls;
use crate::records::query_builder::expand_tables;
use crate::records::test_utils::*;
use crate::records::Acls;
use crate::records::{add_record_api, AccessRules, RecordError};
use crate::records::{AccessRules, RecordError, add_record_api};
use crate::table_metadata::TableMetadataCache;
use crate::util::id_to_b64;
use crate::util::urlencode;
+2 -2
View File
@@ -1,6 +1,6 @@
use axum::{
routing::{delete, get, patch, post},
Router,
routing::{delete, get, patch, post},
};
use utoipa::OpenApi;
@@ -24,9 +24,9 @@ pub(crate) use error::RecordError;
pub use record_api::RecordApi;
pub(crate) use validate::validate_record_api_config;
use crate::AppState;
use crate::config::proto::PermissionFlag;
use crate::constants::RECORD_API_PATH;
use crate::AppState;
#[derive(OpenApi)]
#[openapi(
+2 -2
View File
@@ -501,9 +501,9 @@ pub(crate) fn prefix_colon(s: &str) -> String {
#[cfg(test)]
mod tests {
use base64::prelude::*;
use schemars::{schema_for, JsonSchema};
use schemars::{JsonSchema, schema_for};
use serde_json::json;
use trailbase_schema::sqlite::{sqlite3_parse_into_statement, Table};
use trailbase_schema::sqlite::{Table, sqlite3_parse_into_statement};
use super::*;
use crate::constants::USER_TABLE;
+2 -2
View File
@@ -6,12 +6,12 @@ use trailbase_schema::sqlite::{Column, ColumnOption};
use trailbase_schema::{FileUpload, FileUploads};
use trailbase_sqlite::{NamedParams, Params as _, Value};
use crate::AppState;
use crate::config::proto::ConflictResolutionStrategy;
use crate::records::error::RecordError;
use crate::records::files::{delete_pending_files, FileManager};
use crate::records::files::{FileManager, delete_pending_files};
use crate::records::params::{FileMetadataContents, Params};
use crate::table_metadata::{JsonColumnMetadata, TableMetadata, TableMetadataCache};
use crate::AppState;
#[derive(Debug, thiserror::Error)]
pub enum QueryError {
+22 -18
View File
@@ -1,7 +1,7 @@
use axum::{
Json,
extract::{Path, Query, State},
response::Response,
Json,
};
use serde::Deserialize;
@@ -255,8 +255,8 @@ fn prefix_filter(col_name: &str) -> bool {
#[cfg(test)]
mod test {
use axum::extract::{Path, Query, State};
use axum::Json;
use axum::extract::{Path, Query, State};
use trailbase_schema::{FileUpload, FileUploadInput};
use super::*;
@@ -268,7 +268,7 @@ mod test {
use crate::constants::USER_TABLE;
use crate::extract::Either;
use crate::records::create_record::{
create_record_handler, CreateRecordQuery, CreateRecordResponse,
CreateRecordQuery, CreateRecordResponse, create_record_handler,
};
use crate::records::delete_record::delete_record_handler;
use crate::records::params::JsonRow;
@@ -371,14 +371,16 @@ mod test {
.unwrap();
// No creds, no read
assert!(read_record_handler(
State(state.clone()),
Path(("messages_api".to_string(), id_to_b64(&message_id),)),
Query(ReadRecordQuery::default()),
None
)
.await
.is_err());
assert!(
read_record_handler(
State(state.clone()),
Path(("messages_api".to_string(), id_to_b64(&message_id),)),
Query(ReadRecordQuery::default()),
None
)
.await
.is_err()
);
{
// User X
@@ -627,13 +629,15 @@ mod test {
}
assert_eq!(dir_cnt, 0);
assert!(get_uploaded_file_from_record_handler(
State(state.clone()),
Path(record_file_path.clone()),
None,
)
.await
.is_err());
assert!(
get_uploaded_file_from_record_handler(
State(state.clone()),
Path(record_file_path.clone()),
None,
)
.await
.is_err()
);
}
#[tokio::test]
+4 -4
View File
@@ -5,16 +5,16 @@ use std::borrow::Cow;
use std::collections::HashMap;
use std::sync::Arc;
use trailbase_schema::metadata::{
find_file_column_indexes, find_user_id_foreign_key_columns, JsonColumnMetadata, TableMetadata,
TableOrViewMetadata, ViewMetadata,
JsonColumnMetadata, TableMetadata, TableOrViewMetadata, ViewMetadata, find_file_column_indexes,
find_user_id_foreign_key_columns,
};
use trailbase_schema::sqlite::{sqlite3_parse_into_statement, Column, ColumnDataType};
use trailbase_schema::sqlite::{Column, ColumnDataType, sqlite3_parse_into_statement};
use trailbase_sqlite::{NamedParamRef, NamedParams, Params as _, Value};
use crate::auth::user::User;
use crate::config::proto::{ConflictResolutionStrategy, RecordApiConfig};
use crate::constants::USER_TABLE;
use crate::records::params::{prefix_colon, LazyParams};
use crate::records::params::{LazyParams, prefix_colon};
use crate::records::{Permission, RecordError};
use crate::util::{assert_uuidv7, b64_to_id};
+1 -1
View File
@@ -235,7 +235,7 @@ mod tests {
use super::*;
use crate::app_state::*;
use crate::constants::USER_TABLE;
use crate::table_metadata::{lookup_and_parse_table_schema, TableMetadata};
use crate::table_metadata::{TableMetadata, lookup_and_parse_table_schema};
#[tokio::test]
async fn test_read_rows() {
+12 -10
View File
@@ -12,19 +12,19 @@ use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::pin::Pin;
use std::sync::{
atomic::{AtomicI64, Ordering},
Arc,
atomic::{AtomicI64, Ordering},
};
use std::task::{Context, Poll};
use trailbase_sqlite::connection::{extract_record_values, extract_row_id};
use crate::AppState;
use crate::auth::user::User;
use crate::records::sql_to_json::valueref_to_json;
use crate::records::RecordApi;
use crate::records::sql_to_json::valueref_to_json;
use crate::records::{Permission, RecordError};
use crate::table_metadata::{TableMetadata, TableMetadataCache};
use crate::value_notifier::Computed;
use crate::AppState;
static SUBSCRIPTION_COUNTER: AtomicI64 = AtomicI64::new(0);
@@ -692,7 +692,7 @@ mod tests {
use crate::app_state::test_state;
use crate::auth::api::login::login_with_password;
use crate::config::proto::RecordApiConfig;
use crate::records::{add_record_api_config, PermissionFlag};
use crate::records::{PermissionFlag, add_record_api_config};
use crate::util::uuid_to_b64;
async fn decode_db_event(event: Event) -> DbEvent {
@@ -1149,12 +1149,14 @@ mod tests {
};
// User y should *not* have received the insert event.
assert!(tokio::time::timeout(
tokio::time::Duration::from_millis(300),
user_y_subscription.receiver.clone().count()
)
.await
.is_err());
assert!(
tokio::time::timeout(
tokio::time::Duration::from_millis(300),
user_y_subscription.receiver.clone().count()
)
.await
.is_err()
);
assert_eq!(
user_y_subscription.receiver.try_recv().err().unwrap(),
TryRecvError::Empty
+1 -1
View File
@@ -2,8 +2,8 @@
mod tests {
use trailbase_sqlite::params;
use crate::records::params::JsonRow;
use crate::AppState;
use crate::records::params::JsonRow;
pub async fn create_chat_message_app_tables(state: &AppState) -> Result<(), anyhow::Error> {
// Create a messages, chat room and members tables.
+1 -1
View File
@@ -79,7 +79,7 @@ mod test {
use crate::config::proto::PermissionFlag;
use crate::extract::Either;
use crate::records::create_record::{
create_record_handler, CreateRecordQuery, CreateRecordResponse,
CreateRecordQuery, CreateRecordResponse, create_record_handler,
};
use crate::records::test_utils::*;
use crate::records::*;
+1 -1
View File
@@ -1,7 +1,7 @@
use itertools::Itertools;
use trailbase_schema::sqlite::ColumnOption;
use crate::config::{proto, ConfigError};
use crate::config::{ConfigError, proto};
use crate::records::record_api::validate_rule;
use crate::table_metadata::{TableMetadataCache, TableOrViewMetadata};
+5 -5
View File
@@ -3,19 +3,19 @@ use cron::Schedule;
use futures_util::future::BoxFuture;
use log::*;
use parking_lot::Mutex;
use std::collections::{hash_map::Entry, HashMap};
use std::collections::{HashMap, hash_map::Entry};
use std::future::Future;
use std::str::FromStr;
use std::sync::{
atomic::{AtomicI32, Ordering},
Arc,
atomic::{AtomicI32, Ordering},
};
use trailbase_sqlite::{params, Connection};
use trailbase_sqlite::{Connection, params};
use crate::DataDir;
use crate::config::proto::{Config, SystemJob, SystemJobId};
use crate::constants::{DEFAULT_REFRESH_TOKEN_TTL, LOGS_RETENTION_DEFAULT, SESSION_TABLE};
use crate::records::files::{delete_pending_files_impl, FileDeletionsDb, FileError};
use crate::DataDir;
use crate::records::files::{FileDeletionsDb, FileError, delete_pending_files_impl};
type CallbackError = Box<dyn std::error::Error + Sync + Send>;
type CallbackFunction = dyn Fn() -> BoxFuture<'static, Result<(), CallbackError>> + Sync + Send;
+1 -1
View File
@@ -4,7 +4,7 @@ use std::path::PathBuf;
use std::sync::Arc;
use thiserror::Error;
use crate::app_state::{build_objectstore, AppState, AppStateArgs};
use crate::app_state::{AppState, AppStateArgs, build_objectstore};
use crate::auth::jwt::{JwtHelper, JwtHelperError};
use crate::config::load_or_init_config_textproto;
use crate::constants::USER_TABLE;
+3 -3
View File
@@ -14,9 +14,9 @@ use std::sync::Arc;
use tokio::signal;
use tokio::task::JoinSet;
use tokio_rustls::{
rustls::pki_types::{pem::PemObject, CertificateDer, PrivateKeyDer},
rustls::ServerConfig,
TlsAcceptor,
rustls::ServerConfig,
rustls::pki_types::{CertificateDer, PrivateKeyDer, pem::PemObject},
};
use tower_cookies::CookieManagerLayer;
use tower_http::{cors, limit::RequestBodyLimitLayer, services::ServeDir, trace::TraceLayer};
@@ -32,7 +32,7 @@ use crate::data_dir::DataDir;
use crate::logging;
use crate::records;
pub use init::{init_app_state, InitArgs, InitError};
pub use init::{InitArgs, InitError, init_app_state};
/// A set of options to configure serving behaviors. Changing any of these options
/// requires a server restart, which makes them a natural fit for being exposed as command line
+6 -6
View File
@@ -3,7 +3,7 @@
//! Ripped straight from axum::serve to add rustls support.
use axum::{body::Body, extract::Request, response::Response};
use futures_util::{pin_mut, FutureExt};
use futures_util::{FutureExt, pin_mut};
use hyper::body::Incoming;
use hyper_util::rt::{TokioExecutor, TokioIo};
use hyper_util::{server::conn::auto::Builder, service::TowerToHyperService};
@@ -11,7 +11,7 @@ use log::*;
use std::{
convert::Infallible,
fmt::Debug,
future::{poll_fn, Future, IntoFuture},
future::{Future, IntoFuture, poll_fn},
io,
marker::PhantomData,
net::SocketAddr,
@@ -527,16 +527,16 @@ mod private {
#[cfg(test)]
mod tests {
use std::{
future::{pending, IntoFuture as _},
future::{IntoFuture as _, pending},
net::{IpAddr, Ipv4Addr},
};
use axum::http::StatusCode;
use axum::{
body::{to_bytes, Body},
Router,
body::{Body, to_bytes},
extract::Request,
routing::get,
Router,
};
use hyper_util::rt::TokioIo;
use tokio::{
@@ -544,7 +544,7 @@ mod tests {
net::TcpListener,
};
use super::{serve, Listener};
use super::{Listener, serve};
#[allow(dead_code, unused_must_use)]
async fn if_it_compiles_it_works() {
+3 -3
View File
@@ -3,7 +3,7 @@ use log::*;
use std::collections::HashMap;
use std::sync::Arc;
use thiserror::Error;
use trailbase_schema::sqlite::{sqlite3_parse_into_statement, SchemaError, Table, View};
use trailbase_schema::sqlite::{SchemaError, Table, View, sqlite3_parse_into_statement};
use trailbase_sqlite::params;
pub use trailbase_schema::metadata::{
@@ -246,12 +246,12 @@ pub async fn lookup_and_parse_all_view_schemas(
mod tests {
use axum::extract::{Json, Path, Query, RawQuery, State};
use serde_json::json;
use trailbase_schema::json_schema::{build_json_schema_expanded, Expand, JsonSchemaMode};
use trailbase_schema::json_schema::{Expand, JsonSchemaMode, build_json_schema_expanded};
use crate::app_state::*;
use crate::config::proto::{PermissionFlag, RecordApiConfig};
use crate::records::list_records::list_records_handler;
use crate::records::read_record::{read_record_handler, ReadRecordQuery};
use crate::records::read_record::{ReadRecordQuery, read_record_handler};
use crate::records::*;
#[tokio::test]
+3 -3
View File
@@ -1,16 +1,16 @@
use axum::extract::{Json, State};
use axum::http::StatusCode;
use axum_test::multipart::MultipartForm;
use axum_test::TestServer;
use axum_test::multipart::MultipartForm;
use tower_cookies::Cookie;
use tracing_subscriber::prelude::*;
use trailbase_sqlite::params;
use trailbase::api::{create_user_handler, login_with_password, CreateUserRequest};
use trailbase::AppState;
use trailbase::api::{CreateUserRequest, create_user_handler, login_with_password};
use trailbase::config::proto::{PermissionFlag, RecordApiConfig};
use trailbase::constants::{COOKIE_AUTH_TOKEN, RECORD_API_PATH};
use trailbase::util::id_to_b64;
use trailbase::AppState;
use trailbase::{DataDir, Server, ServerOptions};
pub(crate) async fn add_record_api_config(
+2 -2
View File
@@ -1,5 +1,5 @@
use rcgen::{generate_simple_self_signed, CertifiedKey};
use tokio_rustls::rustls::pki_types::{pem::PemObject, PrivateKeyDer};
use rcgen::{CertifiedKey, generate_simple_self_signed};
use tokio_rustls::rustls::pki_types::{PrivateKeyDer, pem::PemObject};
use tracing::*;
use trailbase::{DataDir, Server, ServerOptions};
+1 -1
View File
@@ -1,7 +1,7 @@
[package]
name = "trailbase-extension"
version = "0.2.0"
edition = "2021"
edition = "2024"
license = "OSL-3.0"
description = "SQLite extension used by TrailBase"
homepage = "https://trailbase.io"
+17 -13
View File
@@ -1,8 +1,8 @@
use jsonschema::Validator;
use lru::LruCache;
use parking_lot::Mutex;
use rusqlite::functions::Context;
use rusqlite::Error;
use rusqlite::functions::Context;
use std::collections::HashMap;
use std::ffi;
use std::num::NonZeroUsize;
@@ -235,12 +235,14 @@ mod tests {
}
{
assert!(conn
.execute(
r#"INSERT INTO test (text0, text1) VALUES ('{"name": "foo", "age": -5}', '"text"')"#,
params!(),
)
.is_err());
assert!(
conn
.execute(
r#"INSERT INTO test (text0, text1) VALUES ('{"name": "foo", "age": -5}', '"text"')"#,
params!(),
)
.is_err()
);
}
}
@@ -299,11 +301,13 @@ mod tests {
)
.unwrap();
assert!(conn
.execute(
r#"INSERT INTO test (text0) VALUES ('{"name": "WRONG_PREFIX_foo"}')"#,
params!(),
)
.is_err());
assert!(
conn
.execute(
r#"INSERT INTO test (text0) VALUES ('{"name": "WRONG_PREFIX_foo"}')"#,
params!(),
)
.is_err()
);
}
}

Some files were not shown because too many files have changed in this diff Show More