W
Wasp8mo ago
terrence

payment tiered access control middleware

Hi, I know wasp integrated with stripe, and defined 3 tiers, how can I add an access control? like hobby can upload 5 times, read 20 times, pro can upload 20 times, read unlimited, enterprise everything unlimited, like I was thiking of add a middleware to my specific api, but will the middleware has to be global? or do you have have any solution for this type of feature? Thank you. @miho @sodic
5 Replies
kapa.ai
kapa.ai8mo ago
Hi @terrence. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- In Wasp, you can customize middleware at three levels: globally, per-api, and per-path. This means you can add middleware to a specific API route, which could be useful for your case of tiered access control. Here's how you can customize middleware for a specific API route:
// In your serverSetup.js or serverSetup.ts file
export const serverMiddlewareFn = (middlewareConfig) => {
middlewareConfig.forRoute({ method: 'POST', path: '/api/upload' })
.add(customMiddlewareForUpload)
return middlewareConfig
}
// In your serverSetup.js or serverSetup.ts file
export const serverMiddlewareFn = (middlewareConfig) => {
middlewareConfig.forRoute({ method: 'POST', path: '/api/upload' })
.add(customMiddlewareForUpload)
return middlewareConfig
}
In this example, customMiddlewareForUpload would be your custom middleware function that checks the user's tier and limits their upload attempts accordingly. However, this only sets up the middleware. You would still need to implement the logic for tracking and limiting the number of uploads and reads for each user, which could involve updating your data model and operations. For more complex access control, Wasp is considering adding support for permissions-focused middleware, but this feature is still under discussion. You can follow the progress on this Github issue (https://github.com/wasp-lang/wasp/issues/584). For more information on configuring middleware in Wasp, you can check out the official documentation (https://wasp-lang.dev/docs/advanced/middleware-config). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @terrence, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
terrence
terrenceOP8mo ago
what about payment tiered feature access control @kapa.ai
kapa.ai
kapa.ai8mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- For implementing payment tiered feature access control in Wasp, you would need to manually implement this logic in your application. Currently, Wasp does not provide built-in support for this feature. Here's a basic idea of how you could approach this: 1. Add a tier field to your User entity to track the user's current payment tier. This could be a string or an enum, depending on your preference. 2. In your queries or actions, check the value of the user's tier field to determine what they should be able to do. For example, if a user tries to upload a file, you would first check their tier and how many times they've already uploaded. If they're over their limit, you can throw an HTTP error. Here's a rough example of what this might look like in code:
// In your Wasp action
export const uploadFile = async ({ user, file }) => {
if (!user) {
throw new HttpError(403)
}

const uploads = await getUploadCountForUser(user)

if (user.tier === 'hobby' && uploads >= 5) {
throw new HttpError(403, 'Upload limit reached for hobby tier')
} else if (user.tier === 'pro' && uploads >= 20) {
throw new HttpError(403, 'Upload limit reached for pro tier')
}

// Continue with file upload...
}
// In your Wasp action
export const uploadFile = async ({ user, file }) => {
if (!user) {
throw new HttpError(403)
}

const uploads = await getUploadCountForUser(user)

if (user.tier === 'hobby' && uploads >= 5) {
throw new HttpError(403, 'Upload limit reached for hobby tier')
} else if (user.tier === 'pro' && uploads >= 20) {
throw new HttpError(403, 'Upload limit reached for pro tier')
}

// Continue with file upload...
}
In this example, getUploadCountForUser would be a function you define that queries your database to get the number of uploads for a user. This is a simplified example and you would need to adapt it to your specific use case. For more complex access control, you might want to consider using a dedicated access control library. Wasp is considering adding support for permissions-focused middleware, but this feature is still under discussion. You can follow the progress on this Github issue (https://github.com/wasp-lang/wasp/issues/584). For more information on how to implement this in Wasp, you can check out the official documentation (https://wasp-lang.dev/docs/main/introduction). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @terrence, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
Filip
Filip8mo ago
Hi @terrence. As you guessed, there's no first-class support for something like this in Wasp. This is mostly by design, since we're dealing with business logic here. The solution proposed by the bot seems reasonable. You need to somehow keep track of a user's tier, and then perform (or not perform) the operation based on that. What did you originally want to have in your middleware? It can't see how middleware could play into this kind of thing, but I may be missing context. Maybe you wanted to have a middleware that returns 403 when, for example, the upload limit is reached (to avoid cluttering the operation's code with tiered pricing logic)? If that's the case, the bot's first answer seems appropriate. Still, I'd probably go for a more direct solution myself and write a higher-order function that acts as a guard for tiered pricing. More explicit this way:
// This thing implements the checks for the pricing limitations
import { withTieredPricing } from './pricing'

export const uploadFile = withTieredPricing(async ({ user, file }) => {
// this block only contains the upload logic
}
// This thing implements the checks for the pricing limitations
import { withTieredPricing } from './pricing'

export const uploadFile = withTieredPricing(async ({ user, file }) => {
// this block only contains the upload logic
}
Hope this helps! 🙂
Filip
Filip8mo ago
FYI, there are plans to introduce more first-class support for such features (if I got you correctly): https://github.com/wasp-lang/wasp/issues/1133
GitHub
Revisit our auth middleware behaviour Queries, Actions and APIs ·...
We have multiple places where we have some sort of auth related logic. Some of the logic is maybe a bit unclear and we might want to extend the existing logic. 1️⃣ Current state Backend Users can u...
Want results from more Discord servers?
Add your server