This cashout link is missing its token.
; + if (state === "failed") returnThis cashout link is invalid or has expired.
; + if (state === "confirmed") returnYour cashout has been confirmed.
; + returnConfirming your cashout…
; +}; + +export default CashoutConfirmation; diff --git a/jb/managers/thl.py b/jb/managers/thl.py index f88acad..59bd2ab 100644 --- a/jb/managers/thl.py +++ b/jb/managers/thl.py @@ -10,6 +10,8 @@ from generalresearch.models.thl.wallet.cashout_method import ( ) from jb.config import settings + + def get_task_status(tsid: str) -> TaskStatusResponse | None: url = f"{settings.fsb_host}{settings.product_id}/status/{tsid}/" d = requests.get(url).json() @@ -61,6 +63,41 @@ def manage_pending_cashout( return UserPayoutEvent.model_validate(d) +def get_paypal_cashout_method_if_exists(product_user_id: str) -> str | None: + """ + Todo: This does not work right now for new users, in that this endpoint expects the user + to have IP history or the request made from the client + (b/c it needs their country to know which tango card are available). + We don't care about that for paypal, but, it expects it anyways. + Once a user can change their paypal email, this needs to change to avoid overwriting it + every time they login. + """ + url = f"{settings.fsb_host}{settings.product_id}/cashout_methods/" + params = {"bpuid": product_user_id} + res = requests.get(url, params=params) + assert res.status_code == status.HTTP_200_OK, res.text + cms = res.json()["cashout_methods"] + res = next(filter(lambda x: x["type"] == "PAYPAL", cms), None) + if res: + return res["id"] + return None + + +def create_paypal_cashout_method(product_user_id: str, email: str) -> dict: + url = f"{settings.fsb_host}{settings.product_id}/cashout_methods/" + body = {"bpuid": product_user_id, "type": "PAYPAL", "email": email} + res = requests.post(url, json=body) + assert res.status_code == status.HTTP_200_OK, res.text + return res.json()["cashout_method"] + + +def create_paypal_cashout_method_if_not_exists( + product_user_id: str, email: str +) -> None: + if not get_paypal_cashout_method_if_exists(product_user_id): + create_paypal_cashout_method(product_user_id, email) + + def get_wallet_balance(amt_worker_id: str) -> USDCent: # This will raise an Exception if wallet balance is negative url = f"{settings.fsb_host}{settings.product_id}/wallet/" diff --git a/jb/views/auth.py b/jb/views/auth.py index cc1224f..36b013f 100644 --- a/jb/views/auth.py +++ b/jb/views/auth.py @@ -26,6 +26,10 @@ from jb.managers.email_manager import ( send_login_email, ) from jb.managers.gr_api import GRApiManager +from jb.managers.thl import ( + create_paypal_cashout_method_if_not_exists, + create_paypal_cashout_method, +) from jb.models.auth import ( AccountLogin, AmtAccountLink, @@ -112,6 +116,14 @@ def exchange_magic_link( def _exchange_magic_link(token: str, response: Response, gr_api: GRApiManager) -> None: user_email = consume_magic_token(token) user = gr_api.ensure_user_exists(User.model_validate({"email": user_email})) + + # create_paypal_cashout_method_if_not_exists( + # product_user_id=user.product_user_id, email=user.email + # ) + create_paypal_cashout_method( + product_user_id=user.product_user_id, email=user.email + ) + response.set_cookie( key=SESSION_COOKIE_NAME, value=create_session(user.product_user_id), @@ -210,6 +222,8 @@ def _exchange_amt_account_link(token: str, response: Response, gr_api: GRApiMana user = User(email=email) user = gr_api.transition_user_from_amt(user=user, amt_worker_id=amt_worker_id) + # create_paypal_cashout_method_if_not_exists(product_user_id=user.product_user_id, email=user.email) + create_paypal_cashout_method(product_user_id=user.product_user_id, email=user.email) # In Mautic, associate the email with the worker ID (AFTER the user has transitioned) get_or_create_contact(email=email, amt_worker_id=amt_worker_id) diff --git a/jb/views/wallet.py b/jb/views/wallet.py index 90e8de8..c281698 100644 --- a/jb/views/wallet.py +++ b/jb/views/wallet.py @@ -58,6 +58,7 @@ def cashout_confirmation_page() -> HTMLResponse: @wallet_router.post("/cashout/confirm/", response_model=CashoutRequestInfo) def confirm_cashout( body: CashoutConfirmation, + user: Annotated[User, Depends(get_authenticated_user)], ) -> CashoutRequestInfo: cashout = consume_cashout_token(body.token) diff --git a/nginx_amt-jb.conf b/nginx_amt-jb.conf index 6d6947c..0b0f385 100644 --- a/nginx_amt-jb.conf +++ b/nginx_amt-jb.conf @@ -30,6 +30,16 @@ server { return 200 '{"status":"ok"}'; } + location = /docs/ { + include nginx_amt-jb_proxy_pass.conf; + proxy_pass http://uvicorn/docs; + } + + location = /redoc/ { + include nginx_amt-jb_proxy_pass.conf; + proxy_pass http://uvicorn/redoc; + } + location / { include nginx_amt-jb_proxy_pass.conf; proxy_pass http://uvicorn; -- cgit v1.2.3