grandnode / grandnode2

Open-Source eCommerce Platform on .NET Core, MongoDB, AWS DocumentDB, Azure CosmosDB, LiteDB & Vue.js
https://grandnode.com/
GNU General Public License v3.0
1.06k stars 435 forks source link

return Challenge() in [HttpPost] methods #400

Closed TheFlo closed 1 year ago

TheFlo commented 1 year ago

Hi GrandNode team,

Following addition of [HttpGet] and [HttpPost] attributes on controller methods in commit 791cf2b, there seems to be a breaking change on method StartCheckout in ShoppingCartController.cs with [HttpPost] attribute :

Adding a [HttpGet] method with the same ActionName seems to solve the issue:

[HttpGet]
[DenySystemAccount]
[ActionName("StartCheckout")]
public virtual IActionResult RedirectStartCheckout()
{
    return RedirectToAction("Cart");
}

Do you see a better solution in order to fix this issue ?

There are other methods with a [HttpPost] attribute using return Challenge() which might needs futher investigation.

Kind regards

KrzysztofPajak commented 1 year ago

@TheFlo Thanks, it looks is a bug, we will fix it asap.

KrzysztofPajak commented 1 year ago

Please check it https://github.com/grandnode/grandnode2/pull/401/ I think, this logic should be fixed in View/JS

TheFlo commented 1 year ago

Many thanks @KrzysztofPajak for your fast answer, the fix works like a charm 👍

In order to cover the case when no term of service is activated in the cart, I've extended and refactored the fix using the following code:

In src/Web/Grand.Web/Views/ShoppingCart/Partials/ModelScript.cshtml line 61, I've extracted the checkout logic in a dedicated function:

termsCheck(guest) {
    if (vmorder.cart.MinOrderSubtotalWarning == null) {
        if (this.terms) {
            this.vmorder.checkout(guest);
            vmorder.acceptTerms = false;
        }
        else {
            vmorder.acceptTerms = true;
        }
    }
},
checkout(guest) {
    if (guest) {
        window.location = '@Url.RouteUrl("Checkout")';
    } else {
        if (!vmorder.cart.ShowCheckoutAsGuestButton && vmorder.cart.IsGuest) {
            window.location = '@Url.RouteUrl("Login")?returnurl=@Url.RouteUrl("ShoppingCart")';
        }
        else {
            document.getElementById('shopping-cart-form').setAttribute('action', '@Url.RouteUrl("StartCheckout")');
            document.getElementById('shopping-cart-form').submit();
        }
    }
},

In src/Web/Grand.Web/Views/ShoppingCart/Partials/CartSummary.cshtml line 211, the created checkout function is called in the v-else template:

<template v-else>
    <div class="checkout-buttons flex-sm-nowrap flex-wrap text-center mt-3">
        <b-button type="button" id="checkoutasguest" v-if="vmorder.cart.ShowCheckoutAsGuestButton" @@click="vmorder.checkout(true)" variant="secondary" class="checkout-as-guest-button mx-sm-1 mx-0">
            @Loc["Account.Login.CheckoutAsGuest"]
        </b-button>
        <b-button id="checkout" name="checkout" @@click="vmorder.checkout(false)" variant="info" class="checkout-button mt-sm-0 mt-1">
            <span v-if="vmorder.cart.IsGuest">
                @Loc["Checkout.Button.Login"]
            </span>
            <span v-else>
                @Loc["Checkout.Button"]
            </span>
        </b-button>
    </div>
</template>

(I'm sorry that I'm not able to propose a PR for this at this moment...)

Would it be a good addition to your fix ?

KrzysztofPajak commented 1 year ago

@TheFlo Thanks, you have absolutely right, I've committed changes