add: purchased accounts
This commit is contained in:
parent
0aa2ea362f
commit
2ec8d86edf
22 changed files with 1279 additions and 124 deletions
|
@ -138,6 +138,15 @@ pub async fn stripe_webhook(
|
|||
return Json(e.into());
|
||||
}
|
||||
|
||||
if data.0.0.security.enable_invite_codes && user.awaiting_purchase {
|
||||
if let Err(e) = data
|
||||
.update_user_awaiting_purchased_status(user.id, false, user.clone(), false)
|
||||
.await
|
||||
{
|
||||
return Json(e.into());
|
||||
}
|
||||
}
|
||||
|
||||
if let Err(e) = data
|
||||
.create_notification(Notification::new(
|
||||
"Welcome new supporter!".to_string(),
|
||||
|
@ -174,6 +183,18 @@ pub async fn stripe_webhook(
|
|||
return Json(e.into());
|
||||
}
|
||||
|
||||
if data.0.0.security.enable_invite_codes && user.was_purchased && user.invite_code == 0
|
||||
{
|
||||
// user doesn't come from an invite code, and is a purchased account
|
||||
// this means their account must be locked if they stop paying
|
||||
if let Err(e) = data
|
||||
.update_user_awaiting_purchased_status(user.id, true, user.clone(), false)
|
||||
.await
|
||||
{
|
||||
return Json(e.into());
|
||||
}
|
||||
}
|
||||
|
||||
if let Err(e) = data
|
||||
.create_notification(Notification::new(
|
||||
"Sorry to see you go... :(".to_string(),
|
||||
|
|
|
@ -88,41 +88,46 @@ pub async fn register_request(
|
|||
|
||||
// check invite code
|
||||
if data.0.0.security.enable_invite_codes {
|
||||
if props.invite_code.is_empty() {
|
||||
return (
|
||||
None,
|
||||
Json(Error::MiscError("Missing invite code".to_string()).into()),
|
||||
);
|
||||
if !props.purchase {
|
||||
if props.invite_code.is_empty() {
|
||||
return (
|
||||
None,
|
||||
Json(Error::MiscError("Missing invite code".to_string()).into()),
|
||||
);
|
||||
}
|
||||
|
||||
let invite_code = match data.get_invite_code_by_code(&props.invite_code).await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return (None, Json(e.into())),
|
||||
};
|
||||
|
||||
if invite_code.is_used {
|
||||
return (
|
||||
None,
|
||||
Json(Error::MiscError("This code has already been used".to_string()).into()),
|
||||
);
|
||||
}
|
||||
|
||||
// let owner = match data.get_user_by_id(invite_code.owner).await {
|
||||
// Ok(u) => u,
|
||||
// Err(e) => return (None, Json(e.into())),
|
||||
// };
|
||||
|
||||
// if !owner.permissions.check(FinePermission::SUPPORTER) {
|
||||
// return (
|
||||
// None,
|
||||
// Json(
|
||||
// Error::MiscError("Invite code owner must be an active supporter".to_string())
|
||||
// .into(),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
|
||||
user.invite_code = invite_code.id;
|
||||
} else {
|
||||
// this account is being purchased
|
||||
user.awaiting_purchase = true;
|
||||
}
|
||||
|
||||
let invite_code = match data.get_invite_code_by_code(&props.invite_code).await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return (None, Json(e.into())),
|
||||
};
|
||||
|
||||
if invite_code.is_used {
|
||||
return (
|
||||
None,
|
||||
Json(Error::MiscError("This code has already been used".to_string()).into()),
|
||||
);
|
||||
}
|
||||
|
||||
// let owner = match data.get_user_by_id(invite_code.owner).await {
|
||||
// Ok(u) => u,
|
||||
// Err(e) => return (None, Json(e.into())),
|
||||
// };
|
||||
|
||||
// if !owner.permissions.check(FinePermission::SUPPORTER) {
|
||||
// return (
|
||||
// None,
|
||||
// Json(
|
||||
// Error::MiscError("Invite code owner must be an active supporter".to_string())
|
||||
// .into(),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
|
||||
user.invite_code = invite_code.id;
|
||||
}
|
||||
|
||||
// push initial token
|
||||
|
@ -133,7 +138,7 @@ pub async fn register_request(
|
|||
match data.create_user(user).await {
|
||||
Ok(_) => {
|
||||
// mark invite as used
|
||||
if data.0.0.security.enable_invite_codes {
|
||||
if data.0.0.security.enable_invite_codes && !props.purchase {
|
||||
let invite_code = match data.get_invite_code_by_code(&props.invite_code).await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return (None, Json(e.into())),
|
||||
|
|
|
@ -4,8 +4,8 @@ use crate::{
|
|||
model::{ApiReturn, Error},
|
||||
routes::api::v1::{
|
||||
AppendAssociations, AwardAchievement, DeleteUser, DisableTotp, RefreshGrantToken,
|
||||
UpdateSecondaryUserRole, UpdateUserIsVerified, UpdateUserPassword, UpdateUserRole,
|
||||
UpdateUserUsername,
|
||||
UpdateSecondaryUserRole, UpdateUserAwaitingPurchase, UpdateUserInviteCode,
|
||||
UpdateUserIsVerified, UpdateUserPassword, UpdateUserRole, UpdateUserUsername,
|
||||
},
|
||||
State,
|
||||
};
|
||||
|
@ -343,6 +343,34 @@ pub async fn update_user_is_verified_request(
|
|||
}
|
||||
}
|
||||
|
||||
/// Update the verification status of the given user.
|
||||
///
|
||||
/// Does not support third-party grants.
|
||||
pub async fn update_user_awaiting_purchase_request(
|
||||
jar: CookieJar,
|
||||
Path(id): Path<usize>,
|
||||
Extension(data): Extension<State>,
|
||||
Json(req): Json<UpdateUserAwaitingPurchase>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
||||
match data
|
||||
.update_user_awaiting_purchased_status(id, req.awaiting_purchase, user, true)
|
||||
.await
|
||||
{
|
||||
Ok(_) => Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "Awaiting purchase status updated".to_string(),
|
||||
payload: (),
|
||||
}),
|
||||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Update the role of the given user.
|
||||
///
|
||||
/// Does not support third-party grants.
|
||||
|
@ -949,3 +977,55 @@ pub async fn self_serve_achievement_request(
|
|||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Update the verification status of the given user.
|
||||
///
|
||||
/// Does not support third-party grants.
|
||||
pub async fn update_user_invite_code_request(
|
||||
jar: CookieJar,
|
||||
Extension(data): Extension<State>,
|
||||
Json(req): Json<UpdateUserInviteCode>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let user = match get_user_from_token!(jar, data) {
|
||||
Some(ua) => ua,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
||||
if req.invite_code.is_empty() {
|
||||
return Json(Error::MiscError("Missing invite code".to_string()).into());
|
||||
}
|
||||
|
||||
let invite_code = match data.get_invite_code_by_code(&req.invite_code).await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Json(e.into()),
|
||||
};
|
||||
|
||||
if invite_code.is_used {
|
||||
return Json(Error::MiscError("This code has already been used".to_string()).into());
|
||||
}
|
||||
|
||||
if let Err(e) = data.update_invite_code_is_used(invite_code.id, true).await {
|
||||
return Json(e.into());
|
||||
}
|
||||
|
||||
match data
|
||||
.update_user_invite_code(user.id, invite_code.id as i64)
|
||||
.await
|
||||
{
|
||||
Ok(_) => {
|
||||
match data
|
||||
.update_user_awaiting_purchased_status(user.id, false, user, false)
|
||||
.await
|
||||
{
|
||||
Ok(_) => Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "Invite code updated".to_string(),
|
||||
payload: (),
|
||||
}),
|
||||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
||||
Err(e) => Json(e.into()),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue