W
Wasp-lang7mo ago
Yuriy

Is these a server side validation of isAdmin?

On OpenSaaS the following snippet cehcks isAdmin access rights to validate access to the admin page.
const Dashboard = ({ user }: { user: User }) => {
const history = useHistory();
if (!user.isAdmin) {
history.push('/');
}
const Dashboard = ({ user }: { user: User }) => {
const history = useHistory();
if (!user.isAdmin) {
history.push('/');
}
This looks very light one, frontend validaition. Is there any backend validation?
13 Replies
kapa.ai
kapa.ai7mo ago
Hi @Yuriy. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Based on the provided knowledge sources, there isn't a specific example of server-side validation for the isAdmin property. However, Wasp does provide mechanisms for server-side validation, such as checking if a user is authenticated before performing certain operations or accessing certain data. For example, in the tutorial on adding authentication (https://wasp-lang.dev/docs/tutorial/auth#updating-operations-to-check-authentication), Wasp demonstrates how to update queries and actions to forbid access to non-authenticated users. This is done by checking the context.user object in the server-side function:
export const getTasks = async (args, context) => {
if (!context.user) {
throw new HttpError(401)
}
return context.entities.Task.findMany({
where: { user: { id: context.user.id } },
orderBy: { id: 'asc' },
})
}
export const getTasks = async (args, context) => {
if (!context.user) {
throw new HttpError(401)
}
return context.entities.Task.findMany({
where: { user: { id: context.user.id } },
orderBy: { id: 'asc' },
})
}
In this example, if context.user is not defined, an HTTP 401 error is thrown, indicating that the user is not authenticated. You could extend this concept to check if the user is an admin by adding an additional condition to check context.user.isAdmin. However, it's important to note that this is just a general concept. The actual implementation would depend on your specific use case and how you've structured your data and authentication system. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @Yuriy, 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?
Yuriy
YuriyOP7mo ago
@kapa.ai Do I have access to context.user in queries and actions ?
kapa.ai
kapa.ai7mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- Yes, you do have access to context.user in both queries and actions in Wasp. When authentication is enabled, all queries and actions have access to the user object through the context argument. The context.user contains all User entity's fields and the auth identities connected to the user. The hashedPassword field from the identities is stripped out for security reasons. Here is an example of how you can use context.user in an action:
export const createTask = async (task, context) => {
if (!context.user) {
throw new HttpError(403)
}

const Task = context.entities.Task
return Task.create({
data: {
description: task.description,
user: {
connect: { id: context.user.id },
},
},
})
}
export const createTask = async (task, context) => {
if (!context.user) {
throw new HttpError(403)
}

const Task = context.entities.Task
return Task.create({
data: {
description: task.description,
user: {
connect: { id: context.user.id },
},
},
})
}
And here is an example of how you can use context.user in a query:
export const getTasks = async (args, context) => {
if (!context.user) {
throw new HttpError(401)
}
return context.entities.Task.findMany({
where: { user: { id: context.user.id } },
orderBy: { id: 'asc' },
})
}
export const getTasks = async (args, context) => {
if (!context.user) {
throw new HttpError(401)
}
return context.entities.Task.findMany({
where: { user: { id: context.user.id } },
orderBy: { id: 'asc' },
})
}
In both examples, context.user is used to check if the user is authenticated before performing the operation. If context.user is undefined, it means the user is not authenticated, and an HTTP error is thrown. You can read more about this in the Wasp documentation (https://wasp-lang.dev/docs/auth/overview#using-the-contextuser-object). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @Yuriy, 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?
miho
miho7mo ago
Did this work out for you in the end?
Yuriy
YuriyOP7mo ago
Working on it, thank you.
MEE6
MEE67mo ago
Wohooo @Yuriy, you just became a Waspeteer level 1!
Yuriy
YuriyOP7mo ago
In this context, while using Google SSO, is it possible to customize the authentication process, or any way to do it after, to explicitly verify if the authenticated user is authorized to access the service?
miho
miho7mo ago
to explicitly verify if the authenticated user is authorized to access the service?
What kind of check would you need to perform?
Yuriy
YuriyOP7mo ago
I'd like to restrict access to explicitly allowed domains (i.e. prevent login from public gmail.com, but allow for Google Workspace users at example.com) . The Google token has a specific hd claim for these usages.
No description
Filip
Filip7mo ago
Hey @Yuriy, this will soon be supported through auth hooks: https://github.com/wasp-lang/wasp/pull/1993 @miho correct me if I'm wrong
GitHub
Auth Hooks by infomiho · Pull Request #1993 · wasp-lang/wasp
Closes #1556 Adding hooks: onBeforeSignup onAfterSignup onBeforeOAuthRedirect onAfterOAuthTokenReceived Left to do: Changelog Docs Headless tests #2022
miho
miho7mo ago
Yes, the new onBeforeOAuthRedirect would help with this 😄
martinsos
martinsos7mo ago
To answer this initial question directly: Yes you are right, this check is not a real security, just DX convenience. Real checks are done on the server side. You can see that Dashboard component uses getDailyStats query. If you check that query on the server, you will see that it starts with if (!context.user?.isAdmin) {, which is the check that ensures on the server side that only admin can access that data. So yes, the check is also done on the server side! Regarding Google SSO allowing only specific domains, I remember when seting it up for my app, that I was able to choose from which domains can people sign-in. I am not sure if this was only for when the app is in development / testing mode, or is it also for "production" mode, but maybe that can be configured there also, on Google?
Yuriy
YuriyOP7mo ago
Hmm... interesting, will take a look. Thanks. Awesome 👍
Want results from more Discord servers?
Add your server