Fix #277 -- Embeddable shop (#622)

* Vendor vue.js

* Refactor item_group_by_category to support vouchers

* Widget: Show product list

* Widget: free prices

* Widget: pictures and loading indicator

* Widget: First iframe steps

* Widget: Do not rerender iframe

* Widget: Error handling

* Improve widget

* Widget: localization tech

* Fix invoice style

* Voucher attribute and waiting list

* Add some iframe chrome

* First step to namespaced carts

* More isolation steps

* More cart isolation things

* More cart isolation things

* Mobile stuff

* Show cart on checkout pages

* PayPal and Stripe support

* Enable downloads

* Locale handling

* change text "save URL to this exact page"

* Widget: voucher redemption

* Widget: CSS

* CSS: Responsive

* Widget: CSS improvements

* Widget: Add embedding code generator

* Widget: Error messages and SSL check

* First tests

* Widget: tests

* Don't use IDs in widgets

* Widget: static files caching
This commit is contained in:
Raphael Michel
2017-10-28 21:54:27 +02:00
committed by GitHub
parent df7fbe5a66
commit 9767243a6d
56 changed files with 12819 additions and 317 deletions

View File

@@ -1,4 +1,5 @@
from django.conf.urls import url
from django.conf.urls import include, url
from django.views.decorators.csrf import csrf_exempt
import pretix.presale.views.cart
import pretix.presale.views.checkout
@@ -9,23 +10,44 @@ import pretix.presale.views.organizer
import pretix.presale.views.robots
import pretix.presale.views.user
import pretix.presale.views.waiting
import pretix.presale.views.widget
# This is not a valid Django URL configuration, as the final
# configuration is done by the pretix.multidomain package.
event_patterns = [
url(r'^cart/add$', pretix.presale.views.cart.CartAdd.as_view(), name='event.cart.add'),
frame_wrapped_urls = [
url(r'^cart/remove$', pretix.presale.views.cart.CartRemove.as_view(), name='event.cart.remove'),
url(r'^cart/clear$', pretix.presale.views.cart.CartClear.as_view(), name='event.cart.clear'),
url(r'^cart/answer/(?P<answer>[^/]+)/$',
pretix.presale.views.cart.AnswerDownload.as_view(),
name='event.cart.download.answer'),
url(r'^waitinglist', pretix.presale.views.waiting.WaitingView.as_view(), name='event.waitinglist'),
url(r'^checkout/start$', pretix.presale.views.checkout.CheckoutView.as_view(), name='event.checkout.start'),
url(r'^redeem/?$', pretix.presale.views.cart.RedeemView.as_view(),
name='event.redeem'),
url(r'^checkout/(?P<step>[^/]+)/$', pretix.presale.views.checkout.CheckoutView.as_view(),
name='event.checkout'),
url(r'^redeem/?$', pretix.presale.views.cart.RedeemView.as_view(),
name='event.redeem'),
url(r'^(?P<subevent>[0-9]+)/$', pretix.presale.views.event.EventIndex.as_view(), name='event.index'),
url(r'^waitinglist', pretix.presale.views.waiting.WaitingView.as_view(), name='event.waitinglist'),
url(r'^$', pretix.presale.views.event.EventIndex.as_view(), name='event.index'),
]
event_patterns = [
# Cart/checkout patterns are a bit more complicated, as they should have simple URLs like cart/clear in normal
# cases, but need to have versions with unguessable URLs like w/8l4Y83XNonjLxoBb/cart/clear to be used in widget
# mode. This is required to prevent all clickjacking and CSRF attacks that would otherwise be possible.
# First, we define the normal version
url(r'', include(frame_wrapped_urls)),
# Second, the widget version
url(r'w/(?P<cart_namespace>[a-zA-Z0-9]{16})/', include(frame_wrapped_urls)),
# Third, a fake version that is defined like the first (and never gets called), but makes reversing URLs easier
url(r'(?P<cart_namespace>[_]{0})', include(frame_wrapped_urls)),
# CartAdd goes extra since it also gets a csrf_exempt decorator in one of the cases
url(r'^cart/add$', pretix.presale.views.cart.CartAdd.as_view(), name='event.cart.add'),
url(r'^(?P<cart_namespace>[_]{0})cart/add$', pretix.presale.views.cart.CartAdd.as_view(), name='event.cart.add'),
url(r'w/(?P<cart_namespace>[a-zA-Z0-9]{16})/cart/add',
csrf_exempt(pretix.presale.views.cart.CartAdd.as_view()),
name='event.cart.add'),
url(r'resend/$', pretix.presale.views.user.ResendLinkView.as_view(), name='event.resend_link'),
url(r'^order/(?P<order>[^/]+)/(?P<secret>[A-Za-z0-9]+)/$', pretix.presale.views.order.OrderDetails.as_view(),
name='event.order'),
@@ -71,8 +93,12 @@ event_patterns = [
pretix.presale.views.event.EventIcalDownload.as_view(),
name='event.ical.download'),
url(r'^auth/$', pretix.presale.views.event.EventAuth.as_view(), name='event.auth'),
url(r'^(?P<subevent>[0-9]+)/$', pretix.presale.views.event.EventIndex.as_view(), name='event.index'),
url(r'^$', pretix.presale.views.event.EventIndex.as_view(), name='event.index'),
url(r'^widget/product_list$', pretix.presale.views.widget.WidgetAPIProductList.as_view(),
name='event.widget.productlist'),
url(r'^widget/v1.css$', pretix.presale.views.widget.widget_css, name='event.widget.css'),
url(r'^(?P<subevent>\d+)/widget/product_list$', pretix.presale.views.widget.WidgetAPIProductList.as_view(),
name='event.widget.productlist'),
]
organizer_patterns = [
@@ -85,4 +111,5 @@ organizer_patterns = [
locale_patterns = [
url(r'^locale/set$', pretix.presale.views.locale.LocaleSet.as_view(), name='locale.set'),
url(r'^robots.txt$', pretix.presale.views.robots.robots_txt, name='robots.txt'),
url(r'^widget/v1\.(?P<lang>[a-zA-Z0-9_\-]+)\.js$', pretix.presale.views.widget.widget_js, name='widget.js'),
]