🎉 Better Boilerplate by Not Quite Unicorns - Our take on what a good Bubble app looks like

Or you can use a proxy service to forward the stripe payload to bubble and inject your own header which you verify in bubble

3 Likes

Oh, sorry Rando, I am focusing on this thread when I comment about ‘nobody else has mentioned’, so hopefully that helps clear up your confusion on what I mean. My comments here are about this thread and this boilerplate stripe integration, Not the Bubble forum at large.

But not used in this boilerplate, nor mentioned in this thread. Why didn’t you mention it if it is ‘widely recommended’ and a good practice as an extra security measure when you saw that George did not include it in his Stripe webhooks?

No it is not, because of course you fail to comprehend that the entire statement should be taken together and not just taking out of context small sentences. The parrot also said ‘naive spoofing of an HTTPS webhook is GENERALLY not possible’. Why do you fail to read words like generally or possible or probable? They have meanings and should be understood. That fact that it generally is not possible, does actually mean, in fact, it is possible, which is why it says to use the allow list as secondary control.

@randomanon are you the new strawman? Backend workflows: In what situations do you allow to run without authentication? - #19 by randomanon

“Secondary control only” means relying on it as a primary control is unsafe. Which would contradict “generally not possible” depending on how you look at the use of the word “generally.”

You can add IP restrictions if you’d like. There’s also nothing inherently insecure about the current implementation. The worst outcome is a WU-DoS, and any motivated attacker would have dozens of ways to do that to a Bubble app.

I’m not (and never have been) saying you shouldn’t add IP restrictions to a Stripe webhook. Just that the implementation in this boilerplate is sufficient.

True, I’ve never really used that feature but this would be a good use case for it. I imagine it would confuse me the first time when I can’t move something about and I’d bang my head against the wall asking why :rofl:

Good stuff, thanks for sharing.

What’s your guideline to adding things to the Global reusable?

I’m currently passing a bunch of messages from reusable to reusable using run Javascript; I’m wondering if there’s a more maintainable way to do that with the Global reusable.

Stuff you use in multiple places which are inconvenient or inefficient to reach via an expression or pieces of front-end custom logic that need to be used in multiple places.

If your global reusable simply has a dynamic expression as its default and you don’t override it where you place it on the page, all the expressions will be identical, you’ll only be WU charged once, and you’ll have the same data accessible everywhere.

Interesting. So the expressions will follow this logic but the HTML will render multiple times.

So I could use that OOP idea (Bringing Object-Oriented Programing (OOP) to Bubble | by Guillaume Maison | Medium), create a reusable for each element that needs creating and then sprinkle that wherever I need in the system.


Which leads me to think (dangerous, I know):

  • Bubble feels snappier when you use CRUD actions in the frontend (optimistic updates? No cold-start time when these functions run in the frontend?)
  • I can have these “Object Reusables” that have those complex workflows built inside of it.
  • so I can move all these complex and slow backend workflows to the frontend.
  • … I would need to re-read your guide on frontend workflow security again.

How bad of an idea is this?

Complex and slow logic should be in the backend :smiley:

If you can help , I want and need to understand this Global logic. :smiley:

Global is a reusable element that can be put whatever we want on application page to use dynamic values.

Design
inOnPageRoot - yes/no - (First question , it is always on the page why we have this option ? is it because i can put it in a group to use the data for the group ?)
Current View - …..URL..**v=“data”

HTML element** : CSS script is in option set , this can be written , or hard coded in to html i guess (Please correct me if i am wrong). All effort is to make it invisible and not blocking any content on screen.

Workflows

  • lastLogin date is changed on page load with a condition.
  • Custom Event to handle Error viewing - This is used for auth errors
  • Unhandled Error viewing / There are 3 permission rule to manage user , subscription and account here

How to Use

First : Put on a desired place and create workflows to manage permission.
Second : On the desired page , the auth. data is there (yes/no) to use to block a group or a menu or a button and you also got the notification.

When a development needed for the application , you can manage permission by doing it or adding it in Global reusable , you can use the auth./perm. data all over the page to finish the design quickly without calling any workflow and extra conditional steps.

Normally , i could create permission table and make desired roles as yes/no value for the users. When i design the page , build logic on ”page is loaded“ workflow for the top perm. control like “Current User’s Permission’s Subscription is yes”. Also for the group based permissions , make some groups not visible to user who has “no” permission to see like “Current User’s Permission’s Payment is yes”. This could get the data from server safely for the user and at first place data should not be downloaded on server side for the groups are not visible… (I guess)

I want to learn because i want the sidebar and menus , some groups act dynamically with the value of Global value , easily.

This just means that it’s in the top level of a page. There should only be one global reusable element where this is set to yes, as it might be used to handle things like page loaded actions. You don’t want that to happen once for each global reusable element on this page - only once in the root element that exists directly on the page.

This means we don’t need to use Get X from page URL everywhere with magic values/hard coded texts. It makes it easier to construct navigation in a maintainable way. You can see this on the visibility conditions on /dashboard.

The use case for the permissions custom events is to prevent client side group data values / states etc being manipulated by the user. It verifies inside the workflow logic that this is a thing the user has permission to modify, and they haven’t just changed the data inside the group to a thing they can read but shouldn’t be able to modify.

1 Like

I see , this is a new approach for me. I was looking for a benefit , design shortcut first so i missed the point. :sweat_smile:

Data privacy , conditions and visibility rules are there to make the application secure , however this is one step ahead for the data security. I know this now : if a user tweak state on client side then they can manipulate the data or viewing options according to design flaws of an application , which leads us to design a solution(here Global) to stop them on client side.

Thank you @georgecollier for the insight and also sharing how it should be. I also have learnt a lot when people shared application statics produced with buildprint , like how many APIs and workflows and longest expressions. Many many thanks. :folded_hands:

Another one ,

Why did you use “FloatingGroup hidden variables” in reusable elements , rather than using the “Custom States” in the reusable element’s page ?

Both can be used in root page and updates with the relevant values.

—

Edit:
Let me ask this way , there are three places that we can use to pass variables. You are not using custom states in the application deliberately as i see , is it about security ?

3 Likes

Group var has a tendency to be overused. Just did a training session to help optimize WUs and app speed. Found an overuse of group var as core source of issue. Were placed inside each reusable that might need value, but value is in URL parameter. So removed all group var and replaced with single Get Data from URL.

Also, if var groups are dependent on some other value, users often overlook conditionally loading the data source, with condition based on existence of dependent value.

In that situation we didn’t need custom states at all, just the Get Data URL and property on reusable to pass through to nested reusable.

Also, definitely best practice is in floating group instead of popup as George mentioned.

1 Like

I got that from you

2 Likes