remove: marketplace
This commit is contained in:
parent
2407e6b213
commit
b5f841a990
27 changed files with 22 additions and 1067 deletions
|
@ -1,7 +1,5 @@
|
|||
use std::{str::FromStr, time::Duration};
|
||||
|
||||
use std::time::Duration;
|
||||
use axum::{http::HeaderMap, response::IntoResponse, Extension, Json};
|
||||
use crate::cookie::CookieJar;
|
||||
use tetratto_core::model::{
|
||||
auth::{Notification, User},
|
||||
moderation::AuditLogEntry,
|
||||
|
@ -9,7 +7,7 @@ use tetratto_core::model::{
|
|||
ApiReturn, Error,
|
||||
};
|
||||
use stripe::{EventObject, EventType};
|
||||
use crate::{get_user_from_token, State};
|
||||
use crate::State;
|
||||
|
||||
pub async fn stripe_webhook(
|
||||
Extension(data): Extension<State>,
|
||||
|
@ -471,145 +469,3 @@ pub async fn stripe_webhook(
|
|||
payload: (),
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn onboarding_account_link_request(
|
||||
jar: CookieJar,
|
||||
Extension(data): Extension<State>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await);
|
||||
let user = match get_user_from_token!(jar, data.0) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
||||
if user.seller_data.account_id.is_some() {
|
||||
return Json(Error::NotAllowed.into());
|
||||
}
|
||||
|
||||
let client = match data.3 {
|
||||
Some(ref c) => c,
|
||||
None => return Json(Error::Unknown.into()),
|
||||
};
|
||||
|
||||
match stripe::AccountLink::create(
|
||||
&client,
|
||||
stripe::CreateAccountLink {
|
||||
account: match user.seller_data.account_id {
|
||||
Some(id) => stripe::AccountId::from_str(&id).unwrap(),
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
},
|
||||
type_: stripe::AccountLinkType::AccountOnboarding,
|
||||
collect: None,
|
||||
expand: &[],
|
||||
refresh_url: Some(&format!(
|
||||
"{}/auth/connections_link/seller/refresh",
|
||||
data.0.0.0.host
|
||||
)),
|
||||
return_url: Some(&format!(
|
||||
"{}/auth/connections_link/seller/return",
|
||||
data.0.0.0.host
|
||||
)),
|
||||
collection_options: None,
|
||||
},
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(x) => Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "Acceptable".to_string(),
|
||||
payload: Some(x.url),
|
||||
}),
|
||||
Err(e) => Json(Error::MiscError(e.to_string()).into()),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn create_seller_account_request(
|
||||
jar: CookieJar,
|
||||
Extension(data): Extension<State>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await);
|
||||
let mut user = match get_user_from_token!(jar, data.0) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
||||
if user.seller_data.account_id.is_some() {
|
||||
return Json(Error::NotAllowed.into());
|
||||
}
|
||||
|
||||
let client = match data.3 {
|
||||
Some(ref c) => c,
|
||||
None => return Json(Error::Unknown.into()),
|
||||
};
|
||||
|
||||
let account = match stripe::Account::create(
|
||||
&client,
|
||||
stripe::CreateAccount {
|
||||
type_: Some(stripe::AccountType::Express),
|
||||
capabilities: Some(stripe::CreateAccountCapabilities {
|
||||
card_payments: Some(stripe::CreateAccountCapabilitiesCardPayments {
|
||||
requested: Some(true),
|
||||
}),
|
||||
transfers: Some(stripe::CreateAccountCapabilitiesTransfers {
|
||||
requested: Some(true),
|
||||
}),
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(a) => a,
|
||||
Err(e) => return Json(Error::MiscError(e.to_string()).into()),
|
||||
};
|
||||
|
||||
user.seller_data.account_id = Some(account.id.to_string());
|
||||
match data
|
||||
.0
|
||||
.update_user_seller_data(user.id, user.seller_data)
|
||||
.await
|
||||
{
|
||||
Ok(_) => Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "Acceptable".to_string(),
|
||||
payload: (),
|
||||
}),
|
||||
Err(e) => return Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn login_link_request(
|
||||
jar: CookieJar,
|
||||
Extension(data): Extension<State>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await);
|
||||
let user = match get_user_from_token!(jar, data.0) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
||||
if user.seller_data.account_id.is_none() | !user.seller_data.completed_onboarding {
|
||||
return Json(Error::NotAllowed.into());
|
||||
}
|
||||
|
||||
let client = match data.3 {
|
||||
Some(ref c) => c,
|
||||
None => return Json(Error::Unknown.into()),
|
||||
};
|
||||
|
||||
match stripe::LoginLink::create(
|
||||
&client,
|
||||
&stripe::AccountId::from_str(&user.seller_data.account_id.unwrap()).unwrap(),
|
||||
&data.0.0.0.host,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(x) => Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "Acceptable".to_string(),
|
||||
payload: Some(x.url),
|
||||
}),
|
||||
Err(e) => Json(Error::MiscError(e.to_string()).into()),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use std::{str::FromStr, time::Duration};
|
||||
use std::time::Duration;
|
||||
use crate::{
|
||||
get_user_from_token,
|
||||
model::{ApiReturn, Error},
|
||||
|
@ -572,28 +572,11 @@ pub async fn delete_user_request(
|
|||
.delete_user(id, &req.password, user.permissions.check_manager())
|
||||
.await
|
||||
{
|
||||
Ok(ua) => {
|
||||
// delete stripe user
|
||||
if let Some(stripe_id) = ua.seller_data.account_id
|
||||
&& let Some(ref client) = data.3
|
||||
{
|
||||
if let Err(e) = stripe::Account::delete(
|
||||
&client,
|
||||
&stripe::AccountId::from_str(&stripe_id).unwrap(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
return Json(Error::MiscError(e.to_string()).into());
|
||||
}
|
||||
}
|
||||
|
||||
// ...
|
||||
Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "User deleted".to_string(),
|
||||
payload: (),
|
||||
})
|
||||
}
|
||||
Ok(_) => Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "User deleted".to_string(),
|
||||
payload: (),
|
||||
}),
|
||||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ pub mod journals;
|
|||
pub mod letters;
|
||||
pub mod notes;
|
||||
pub mod notifications;
|
||||
pub mod products;
|
||||
pub mod reactions;
|
||||
pub mod reports;
|
||||
pub mod requests;
|
||||
|
@ -34,7 +33,6 @@ use tetratto_core::model::{
|
|||
littleweb::{DomainData, DomainTld, ServiceFsEntry},
|
||||
oauth::AppScope,
|
||||
permissions::{FinePermission, SecondaryPermission},
|
||||
products::{ProductPrice, ProductType},
|
||||
reactions::AssetType,
|
||||
stacks::{StackMode, StackPrivacy, StackSort},
|
||||
};
|
||||
|
@ -566,18 +564,6 @@ pub fn routes() -> Router {
|
|||
"/service_hooks/stripe",
|
||||
post(auth::connections::stripe::stripe_webhook),
|
||||
)
|
||||
.route(
|
||||
"/service_hooks/stripe/seller/register",
|
||||
post(auth::connections::stripe::create_seller_account_request),
|
||||
)
|
||||
.route(
|
||||
"/service_hooks/stripe/seller/onboarding",
|
||||
post(auth::connections::stripe::onboarding_account_link_request),
|
||||
)
|
||||
.route(
|
||||
"/service_hooks/stripe/seller/login",
|
||||
post(auth::connections::stripe::login_link_request),
|
||||
)
|
||||
// channels
|
||||
.route("/channels", post(channels::channels::create_request))
|
||||
.route(
|
||||
|
@ -716,17 +702,6 @@ pub fn routes() -> Router {
|
|||
.route("/domains/{id}", get(domains::get_request))
|
||||
.route("/domains/{id}", delete(domains::delete_request))
|
||||
.route("/domains/{id}/data", post(domains::update_data_request))
|
||||
// products
|
||||
.route("/products", get(products::list_request))
|
||||
.route("/products", post(products::create_request))
|
||||
.route("/products/{id}", get(products::get_request))
|
||||
.route("/products/{id}", delete(products::delete_request))
|
||||
.route("/products/{id}/name", post(products::update_name_request))
|
||||
.route(
|
||||
"/products/{id}/description",
|
||||
post(products::update_description_request),
|
||||
)
|
||||
.route("/products/{id}/price", post(products::update_price_request))
|
||||
// letters
|
||||
.route("/letters", post(letters::create_request))
|
||||
.route("/letters/{id}", get(letters::get_request))
|
||||
|
@ -1207,29 +1182,6 @@ pub struct UpdateDomainData {
|
|||
pub data: Vec<(String, DomainData)>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct CreateProduct {
|
||||
pub name: String,
|
||||
pub description: String,
|
||||
pub product_type: ProductType,
|
||||
pub price: ProductPrice,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct UpdateProductName {
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct UpdateProductDescription {
|
||||
pub description: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct UpdateProductPrice {
|
||||
pub price: ProductPrice,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct UpdateUploadAlt {
|
||||
pub alt: String,
|
||||
|
|
|
@ -1,234 +0,0 @@
|
|||
use crate::{
|
||||
get_user_from_token,
|
||||
image::{save_webp_buffer, JsonMultipart},
|
||||
routes::{
|
||||
api::v1::{
|
||||
communities::posts::MAXIMUM_FILE_SIZE, CreateProduct, UpdateProductDescription,
|
||||
UpdateProductName, UpdateProductPrice,
|
||||
},
|
||||
pages::PaginatedQuery,
|
||||
},
|
||||
State,
|
||||
};
|
||||
use axum::{
|
||||
extract::{Path, Query},
|
||||
response::IntoResponse,
|
||||
Extension, Json,
|
||||
};
|
||||
use crate::cookie::CookieJar;
|
||||
use tetratto_core::model::{
|
||||
oauth,
|
||||
products::Product,
|
||||
uploads::{MediaType, MediaUpload},
|
||||
ApiReturn, Error,
|
||||
};
|
||||
|
||||
pub async fn get_request(
|
||||
Path(id): Path<usize>,
|
||||
Extension(data): Extension<State>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
match data.get_product_by_id(id).await {
|
||||
Ok(x) => Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "Success".to_string(),
|
||||
payload: Some(x),
|
||||
}),
|
||||
Err(e) => return Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn list_request(
|
||||
jar: CookieJar,
|
||||
Extension(data): Extension<State>,
|
||||
Query(props): Query<PaginatedQuery>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserReadProducts) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
||||
match data.get_products_by_user(user.id, 12, props.page).await {
|
||||
Ok(x) => Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "Success".to_string(),
|
||||
payload: Some(x),
|
||||
}),
|
||||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn create_request(
|
||||
jar: CookieJar,
|
||||
Extension(data): Extension<State>,
|
||||
JsonMultipart(uploads, req): JsonMultipart<CreateProduct>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserCreateProducts) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
||||
if uploads.len() > 4 {
|
||||
return Json(
|
||||
Error::MiscError("Too many uploads. Please use a maximum of 4".to_string()).into(),
|
||||
);
|
||||
}
|
||||
|
||||
let mut product = Product::new(
|
||||
user.id,
|
||||
req.name,
|
||||
req.description,
|
||||
req.price,
|
||||
req.product_type,
|
||||
);
|
||||
|
||||
// check sizes
|
||||
for img in &uploads {
|
||||
if img.len() > MAXIMUM_FILE_SIZE {
|
||||
return Json(Error::FileTooLarge.into());
|
||||
}
|
||||
}
|
||||
|
||||
// create uploads
|
||||
for _ in 0..uploads.len() {
|
||||
product.uploads.push(
|
||||
match data
|
||||
.create_upload(MediaUpload::new(MediaType::Webp, product.owner))
|
||||
.await
|
||||
{
|
||||
Ok(u) => u.id,
|
||||
Err(e) => return Json(e.into()),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
let product_uploads = product.uploads.clone();
|
||||
match data.create_product(product).await {
|
||||
Ok(x) => {
|
||||
// store uploads
|
||||
for (i, upload_id) in product_uploads.iter().enumerate() {
|
||||
let image = match uploads.get(i) {
|
||||
Some(img) => img,
|
||||
None => {
|
||||
if let Err(e) = data.delete_upload(*upload_id).await {
|
||||
return Json(e.into());
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
let upload = match data.get_upload_by_id(*upload_id).await {
|
||||
Ok(u) => u,
|
||||
Err(e) => return Json(e.into()),
|
||||
};
|
||||
|
||||
if let Err(e) =
|
||||
save_webp_buffer(&upload.path(&data.0.0).to_string(), image.to_vec(), None)
|
||||
{
|
||||
return Json(Error::MiscError(e.to_string()).into());
|
||||
}
|
||||
}
|
||||
|
||||
// ...
|
||||
Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "Product created".to_string(),
|
||||
payload: x.id.to_string(),
|
||||
})
|
||||
}
|
||||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn update_name_request(
|
||||
jar: CookieJar,
|
||||
Extension(data): Extension<State>,
|
||||
Path(id): Path<usize>,
|
||||
Json(req): Json<UpdateProductName>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserManageProducts) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
||||
match data.update_product_name(id, &user, &req.name).await {
|
||||
Ok(_) => Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "Product updated".to_string(),
|
||||
payload: (),
|
||||
}),
|
||||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn update_description_request(
|
||||
jar: CookieJar,
|
||||
Extension(data): Extension<State>,
|
||||
Path(id): Path<usize>,
|
||||
Json(req): Json<UpdateProductDescription>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserManageProducts) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
||||
match data
|
||||
.update_product_description(id, &user, &req.description)
|
||||
.await
|
||||
{
|
||||
Ok(_) => Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "Product updated".to_string(),
|
||||
payload: (),
|
||||
}),
|
||||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn update_price_request(
|
||||
jar: CookieJar,
|
||||
Extension(data): Extension<State>,
|
||||
Path(id): Path<usize>,
|
||||
Json(req): Json<UpdateProductPrice>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserManageProducts) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
||||
match data.update_product_price(id, &user, req.price).await {
|
||||
Ok(_) => Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "Product updated".to_string(),
|
||||
payload: (),
|
||||
}),
|
||||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn delete_request(
|
||||
jar: CookieJar,
|
||||
Extension(data): Extension<State>,
|
||||
Path(id): Path<usize>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserManageProducts) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
||||
match data.delete_product(id, &user).await {
|
||||
Ok(_) => Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "Product deleted".to_string(),
|
||||
payload: (),
|
||||
}),
|
||||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
|
@ -1,107 +0,0 @@
|
|||
use super::render_error;
|
||||
use crate::{
|
||||
assets::initial_context, get_lang, get_user_from_token, State, routes::pages::PaginatedQuery,
|
||||
};
|
||||
use axum::{
|
||||
extract::Query,
|
||||
response::{Html, IntoResponse},
|
||||
Extension,
|
||||
};
|
||||
use crate::cookie::CookieJar;
|
||||
use tetratto_core::model::Error;
|
||||
|
||||
/// `/settings/seller`
|
||||
pub async fn seller_settings_request(
|
||||
jar: CookieJar,
|
||||
Extension(data): Extension<State>,
|
||||
Query(props): Query<PaginatedQuery>,
|
||||
) -> impl IntoResponse {
|
||||
let data = data.read().await;
|
||||
let user = match get_user_from_token!(jar, data.0) {
|
||||
Some(ua) => ua,
|
||||
None => {
|
||||
return Err(Html(
|
||||
render_error(Error::NotAllowed, &jar, &data, &None).await,
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
let products = match data.0.get_products_by_user(user.id, 12, props.page).await {
|
||||
Ok(x) => x,
|
||||
Err(e) => return Err(Html(render_error(e, &jar, &data, &None).await)),
|
||||
};
|
||||
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
||||
|
||||
context.insert("list", &products);
|
||||
context.insert("page", &props.page);
|
||||
|
||||
// return
|
||||
Ok(Html(
|
||||
data.1.render("marketplace/seller.html", &context).unwrap(),
|
||||
))
|
||||
}
|
||||
|
||||
pub async fn connection_return_request(
|
||||
jar: CookieJar,
|
||||
Extension(data): Extension<State>,
|
||||
) -> impl IntoResponse {
|
||||
let data = data.read().await;
|
||||
let mut user = match get_user_from_token!(jar, data.0) {
|
||||
Some(ua) => ua,
|
||||
None => {
|
||||
return Err(Html(
|
||||
render_error(Error::NotAllowed, &jar, &data, &None).await,
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
// update user
|
||||
user.seller_data.completed_onboarding = true;
|
||||
if let Err(e) = data
|
||||
.0
|
||||
.update_user_seller_data(user.id, user.seller_data.clone())
|
||||
.await
|
||||
{
|
||||
return Err(Html(render_error(e, &jar, &data, &None).await));
|
||||
}
|
||||
|
||||
// ...
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
||||
context.insert("connection_type", "return");
|
||||
|
||||
// return
|
||||
Ok(Html(
|
||||
data.1
|
||||
.render("auth/seller_connection.html", &context)
|
||||
.unwrap(),
|
||||
))
|
||||
}
|
||||
|
||||
pub async fn connection_reload_request(
|
||||
jar: CookieJar,
|
||||
Extension(data): Extension<State>,
|
||||
) -> impl IntoResponse {
|
||||
let data = data.read().await;
|
||||
let user = match get_user_from_token!(jar, data.0) {
|
||||
Some(ua) => ua,
|
||||
None => {
|
||||
return Err(Html(
|
||||
render_error(Error::NotAllowed, &jar, &data, &None).await,
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
||||
context.insert("connection_type", "reload");
|
||||
|
||||
// return
|
||||
Ok(Html(
|
||||
data.1
|
||||
.render("auth/seller_connection.html", &context)
|
||||
.unwrap(),
|
||||
))
|
||||
}
|
|
@ -6,7 +6,6 @@ pub mod forge;
|
|||
pub mod journals;
|
||||
pub mod littleweb;
|
||||
pub mod mail;
|
||||
pub mod marketplace;
|
||||
pub mod misc;
|
||||
pub mod mod_panel;
|
||||
pub mod profile;
|
||||
|
@ -77,14 +76,6 @@ pub fn routes() -> Router {
|
|||
"/auth/connections_link/app/{id}",
|
||||
get(developer::connection_callback_request),
|
||||
)
|
||||
.route(
|
||||
"/auth/connections_link/seller/reload",
|
||||
get(marketplace::connection_reload_request),
|
||||
)
|
||||
.route(
|
||||
"/auth/connections_link/seller/return",
|
||||
get(marketplace::connection_return_request),
|
||||
)
|
||||
// profile
|
||||
.route("/settings", get(profile::settings_request))
|
||||
.route("/@{username}", get(profile::posts_request))
|
||||
|
@ -163,11 +154,6 @@ pub fn routes() -> Router {
|
|||
.route("/domains/{id}", get(littleweb::domain_request))
|
||||
.route("/net", get(littleweb::browser_home_request))
|
||||
.route("/net/{*uri}", get(littleweb::browser_request))
|
||||
// marketplace
|
||||
.route(
|
||||
"/settings/seller",
|
||||
get(marketplace::seller_settings_request),
|
||||
)
|
||||
// mail
|
||||
.route("/mail", get(mail::received_request))
|
||||
.route("/mail/sent", get(mail::sent_request))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue