Backend: - user roles (DB + JWT + first-user-is-admin) - volume-aware file resolver (multi-volume asset serving) - directory scanner uses volume URI directly - date-summary endpoint (capture date from EXIF) - timeline ordered by capture date - list endpoints: volumes, plugins, pipelines, library paths - delete endpoints: volumes, library paths - configurable upload body limit (MAX_UPLOAD_BYTES) Frontend: - auth: login/register, token refresh, role-based admin gate - timeline: date-grouped grid, infinite scroll, date scrubber - image viewer: fullscreen zoom/pan/pinch, metadata sidebar - upload: drag-drop, sequential upload, progress tracking - albums: create, add/remove photos, asset picker dialog - admin: storage (import library), jobs (pagination, error details), plugins (list + toggle), pipelines, sidecars, duplicates - multi-select mode with add-to-album action - TanStack Query for all data fetching
49 lines
1.6 KiB
Rust
49 lines
1.6 KiB
Rust
use std::sync::Arc;
|
|
|
|
use adapters_auth::{BcryptPasswordHasher, JwtTokenIssuer};
|
|
use adapters_postgres::{PgPool, PostgresRefreshTokenRepository, PostgresUserRepository};
|
|
use application::identity::{
|
|
GetProfileHandler, LoginUserHandler, LogoutHandler, RefreshTokenHandler, RegisterUserHandler,
|
|
};
|
|
use domain::ports::TokenIssuer;
|
|
use presentation::state::IdentityHandlers;
|
|
|
|
pub struct IdentityServices {
|
|
pub handlers: IdentityHandlers,
|
|
pub token_issuer: Arc<dyn TokenIssuer>,
|
|
}
|
|
|
|
pub fn build(pool: &PgPool, jwt_secret: &str) -> IdentityServices {
|
|
let user_repo = Arc::new(PostgresUserRepository::new(pool.clone()));
|
|
let hasher = Arc::new(BcryptPasswordHasher);
|
|
let issuer: Arc<JwtTokenIssuer> = Arc::new(JwtTokenIssuer::new(jwt_secret));
|
|
let refresh_repo = Arc::new(PostgresRefreshTokenRepository::new(pool.clone()));
|
|
|
|
let register = Arc::new(RegisterUserHandler::new(user_repo.clone(), hasher.clone()));
|
|
let login = Arc::new(LoginUserHandler::new(
|
|
user_repo.clone(),
|
|
hasher,
|
|
issuer.clone(),
|
|
refresh_repo.clone(),
|
|
));
|
|
let get_profile = Arc::new(GetProfileHandler::new(user_repo.clone()));
|
|
let refresh = Arc::new(RefreshTokenHandler::new(
|
|
refresh_repo.clone(),
|
|
user_repo,
|
|
issuer.clone(),
|
|
));
|
|
let logout = Arc::new(LogoutHandler::new(refresh_repo.clone()));
|
|
|
|
IdentityServices {
|
|
handlers: IdentityHandlers {
|
|
register,
|
|
login,
|
|
get_profile,
|
|
refresh,
|
|
logout,
|
|
refresh_token_repo: refresh_repo,
|
|
},
|
|
token_issuer: issuer,
|
|
}
|
|
}
|