Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
8c4d22e
feat(backend): add email verification functionality with token manage…
yupix May 20, 2026
88ec75f
refactor(backend): SeaORMのv2で推奨されているエラーハンドリングに変更
yupix May 20, 2026
f184165
refactor(backend): トークンの更新をLuaSccriptで原始的に実行するように
yupix May 20, 2026
835e83f
feat(backend): add urlencoding dependency and use it for token encodi…
yupix May 20, 2026
7c5e840
feat(backend): implement verification email outbox for transactional …
yupix May 20, 2026
b691478
chore(front): openapi.jsonからapi呼び出し用の関数を生成
yupix May 20, 2026
46c9b87
feat(backend): add email_verification_app_url to settings with valida…
yupix May 20, 2026
9b59eaf
feat(backend): enhance verification email outbox with processing stat…
yupix May 21, 2026
3c68222
refactor(backend): streamline email worker processing logic and impro…
yupix May 21, 2026
883f35e
feat(backend): introduce centralized error handling with AppError and…
yupix May 21, 2026
1371d4b
feat(backend): タイミング攻撃の対策
yupix May 21, 2026
4632626
feat(backend): implement verification email job processing with Apali…
yupix May 21, 2026
8c3837c
feat(backend): enhance personal_tokens model with ToSchema and remove…
yupix May 21, 2026
2db4f55
feat(backend): implement user registration and email verification flo…
yupix May 21, 2026
43e5187
feat(backend): update personal_tokens model to include ScopeList for …
yupix May 21, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions apps/backend/.env.example
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# 未指定時は info,sqlx=warn(2秒/30秒ポーリングの空 SELECT をログに出さない)
# RUST_LOG=info,sqlx=warn
database_url=postgresql://username:password@host:port/db_name
redis_url=redis://127.0.0.1:6379
sentry_dsn=
Expand All @@ -6,3 +8,5 @@ smtp_port=587
smtp_username=your_smtp_username
smtp_password=your_smtp_password
smtp_from=no-reply@example.com
# 必須。認証メールのリンク先(本番では実際のフロント URL を指定)
email_verification_app_url=http://localhost:3000
9 changes: 9 additions & 0 deletions apps/backend/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions apps/backend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,13 @@ sentry = { version = "0.48.2", features = ["tower-axum-matched-path"] }
tower = "0.5.2"
argon2 = "0.5.3"
anyhow = "1.0.102"
chrono = { version = "0.4", default-features = false, features = ["clock"] }
thiserror = "2.0.10"
base64 = "0.22.1"
redis_pool = "0.10.0"
redis = { version = "1.2.1", features = ["tokio-comp"] }
url = "2.5"
urlencoding = "2.1"
hmac = "0.13"
sha2 = "0.11"
rand = "0.10"
Expand Down
4 changes: 2 additions & 2 deletions apps/backend/src/entities/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# entities Module
# entities

このモジュールは、データベースのエンティティを定義します。各エンティティは、SeaORMのマクロを使用して定義されており、データベースのテーブル構造に対応しています。また、OpenAPIドキュメント生成のために、`utoipa::ToSchema`トレイトも実装しています。これにより、APIエンドポイントで使用されるデータ構造が明確になり、クライアントとのインターフェースが一貫性を持つようになります
API や永続化で使うモデルをまとめるモジュールです。レスポンス用の `@ToSchema` 付きモデルもここに置きます
1 change: 1 addition & 0 deletions apps/backend/src/entities/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ pub mod personal_tokens;
pub mod scopes;
pub mod tenants;
pub mod users;
pub mod verification_email_outbox;
2 changes: 1 addition & 1 deletion apps/backend/src/entities/scopes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub enum Scope {
AdminAll,
}

/// JSON カラム用の `Vec<Scope>` ラッパ(SeaORM エンティティ向け)
/// アクセストークン等に付与する権限スコープのリスト
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, FromJsonQueryResult, ToSchema)]
#[serde(transparent)]
pub struct ScopeList(pub Vec<Scope>);
Expand Down
3 changes: 3 additions & 0 deletions apps/backend/src/entities/users.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@ pub struct Model {
#[sea_orm(nullable)]
#[schema(nullable)]
pub avatar_url: Option<String>,
#[sea_orm(unique)]
#[schema(value_type = String, format="email")]
pub email: String,
/// メールアドレスの確認が済んでいるかどうか
pub email_verified: bool,
Comment thread
yupix marked this conversation as resolved.
#[schema(ignore)]
#[serde(skip_serializing)]
pub password_hash: String,
Expand Down
53 changes: 53 additions & 0 deletions apps/backend/src/entities/verification_email_outbox.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use sea_orm::entity::prelude::*;

#[derive(Clone, Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum)]
#[sea_orm(rs_type = "String", db_type = "String(StringLen::N(20))")]
pub enum OutboxStatus {
#[sea_orm(string_value = "pending")]
Pending,
#[sea_orm(string_value = "sent")]
Sent,
#[sea_orm(string_value = "failed")]
Failed,
}

#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
#[sea_orm(table_name = "verification_email_outbox")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: Uuid,
#[sea_orm(indexed)]
pub user_id: Uuid,
pub email: String,
/// 送信完了後はクリアする(平文トークンを永続保持しない)
#[sea_orm(nullable)]
pub token: Option<String>,
#[sea_orm(indexed)]
pub status: OutboxStatus,
pub attempts: i32,
#[sea_orm(nullable)]
pub last_error: Option<String>,
pub created_at: DateTimeWithTimeZone,
#[sea_orm(nullable)]
pub sent_at: Option<DateTimeWithTimeZone>,
}

#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::users::Entity",
from = "Column::UserId",
to = "super::users::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
Users,
}

impl Related<super::users::Entity> for Entity {
fn to() -> RelationDef {
Relation::Users.def()
}
}

impl ActiveModelBehavior for ActiveModel {}
Loading