Need help with roles (setPermission(s), setRole(s))
After careful search through this server, gooby is now enhanced with the knowledge that there exists a
Kinde Management API
With our upcoming Billing feature, you can create plans and set the features under each plan. So that when a user signs-up to a plan, they will get entitled to the features under that plan, and those features will be claims in the user tokens.
I cannot provide concrete information yet on how to do Billing with Kinde on a NextJS environment, but we are on-track to release a private beta of our Billing feature by the end of March.
It would be great if you could explain a bit more about:
- What you are building
- Is your product B2B? B2C? Something else?
- Ideally what pricing plans and models (e.g. $10/month) do you wish to offer your customers?
Hey.
I tried through basic rest calls with the fetch library and it seemed to work, at that point I found out about the existence of clientAPI and tried to use that to give organization user a role, it gave 400 bad request.
I had all 3 params, roleId, orgCode and userId existing and I checked the types matched your defs.
Then I realized that the clientApi way doesn't ask for bearer access_token like the rest way of interacting with the API does, but I don't think that's it because the clientApi worked and gives me users, roles, perms with the gets, just like in the n.js app v2 example docs.
I also tried using clientApi in server side component, in route handler and in form action that is exported from actions.ts, and I get this error about "setting cookies is only allowed on request handlers/form actions", but thats another story.
But basically, getting 400 bad req when calling clientApi.organizationApi.methodThatCreatesUserARole()
Sorry, I'm at bed, I'll get back to it when I wake up and form a proper answer + test more. Probably just still misscalling because I get 400. Thank you for reaching
Hey @ooi cat,
I'm sorry to hear that you're having trouble with assigning roles to users. The 400 Bad Request error usually indicates that the server could not understand the request due to invalid syntax.
Here are a few things you could check:
- Make sure you're using the correct method. The method to assign a role to a user in an organization is
addOrganizationUserRole()
, not methodThatCreatesUserARole()
.
- Ensure that the parameters you're passing to the method are correct. The
addOrganizationUserRole()
method requires three parameters: orgCode
, userId
, and roleId
. Make sure these are all valid and exist in your database.
- Check the order of the parameters. The order should be
orgCode
, userId
, roleId
.
- Make sure you're using the correct instance of the Kinde Management API. If you're calling this method in a server-side component or route handler, you should be using
createKindeManagementAPIClient()
to create the API client.
- Regarding the error about setting cookies, this is because cookies can only be set in request handlers or form actions in Next.js. If you're trying to set a cookie in a server-side component, you'll need to move this logic to a request handler or form action.
If you're still having trouble, could you please provide the exact code you're using to call the
addOrganizationUserRole()
method? This will help me understand the issue better and provide a more accurate solution.
Let me know if you have any other questions! I'm here to help.
I called it like this:
const response = await apiClient.organizationsApi.createOrganizationUserRole({
createOrganizationUserRoleRequest: {
roleId: roleId
},
orgCode: orgCode,
userId: userId
})
in the libs its:
export interface CreateOrganizationUserRoleOperationRequest {
orgCode: string;
userId: string;
createOrganizationUserRoleRequest: CreateOrganizationUserRoleRequest;
}
export interface CreateOrganizationUserRoleRequest {
/**
* The role id.
* @type {string}
* @memberof CreateOrganizationUserRoleRequest
*/
roleId?: string;
}
Ah you are totally right.
In that case, here are a few things you could check:
- Make sure the
roleId
, orgCode
, and userId
are valid and exist in your database.
- Ensure that the
roleId
is a string. If it's a number, you might need to convert it to a string before passing it to the method.
- Check if the
roleId
is optional in your database. If it's not, you need to provide a valid roleId
.
- Make sure you're using the correct instance of the Kinde Management API. If you're calling this method in a server-side component or route handler, you should be using
createKindeManagementAPIClient()
to create the API client.
If you're still having trouble, could you please provide the exact error message you're getting? This will help me understand the issue better and provide a more accurate solution.
Let me know if you have any other questions! I'm here to help.
I'll ensure the types
I use this:
import { createKindeManagementAPIClient, getKindeServerSession } from "@kinde-oss/kinde-auth-nextjs/server"
// in React server-component: ...
const apiClient = await createKindeManagementAPIClient();
Missed this.
- Drafting tool for a game called League of Legends
- B2C
- We are going to have 2-3 paid tiers, eg 5$ 10$ and one more
It's usable at
https://www.drafter.lol but it's still under heavy work
It's going to be fairly small application / userbase
just a passion project really
Not quite sure what the "Check if the roleId is optional in your database" means. I'm using the roleId from kinde:
const roles = await apiClient.rolesApi.getRoles()
...then get role id I want
Exciting! Thanks for explaining the details above.
I will have to pass on your issue to my expert nextjs teammate on Monday
I could create organizations with the apiClient for example
maybe I'll just try fetch + bearer token
thanks for quick reach mate!
No worries.
I'll get back to you on Monday
Ok, got it working using fetch and bearer tokens:
would like to use the api though
/**
* @returns access_token for accessing Kinde management API
*/
export const getKindeAccessToken = async (): Promise<any> => {
const response = await fetch("https://riku.kinde.com/oauth2/token", {
method: "POST",
headers: {
"content-type": "application/x-www-form-urlencoded",
},
body: new URLSearchParams({
audience: "https://riku.kinde.com/api",
grant_type: "client_credentials",
client_id: process.env.KINDE_CLIENT_ID as string,
client_secret: process.env.KINDE_CLIENT_SECRET as string,
})
})
return response.json()
}
/**
* @param roleId role to give to the Kinde user
* @param userId id of the user to update
* @param orgCode Kinde organization where the update happens in
*/
export const kindeAddRoleToUser = async (roleId: string, userId: string, orgCode: string): Promise<any> => {
if(!roleId || !userId) { return }
const { access_token: accessToken } = await getKindeAccessToken()
console.log("using accessToken:", accessToken)
const inputBody = JSON.stringify({
"role_id": roleId
})
const headers = {
"Content-Type":"application/json",
"Accept":"application/json",
"Authorization":`Bearer ${accessToken}`
};
const response = await fetch(`https://riku.kinde.com/api/v1/organizations/${orgCode}/users/${userId}/roles`, {
method: "POST",
headers: headers,
body: inputBody
})
return response.json()
}
edit: (feel free to tag or even directly dm. dm has higher chance of quick response)
Hey @ooi cat,
I'm glad to hear that you were able to get it working using fetch and bearer tokens!
If you want to use the Kinde Management API client, you can do so by creating an instance of the client and setting the access token in the headers. Here's how you can do it:
import { KindeManagementAPIClient, CreateOrganizationUserRoleRequest } from '@kinde/management-api-client';
// Create an instance of the Kinde Management API client
const apiClient = new KindeManagementAPIClient({
basePath: 'https://riku.kinde.com/api/v1',
headers: {
'Authorization': `Bearer ${accessToken}`
}
});
// Create a request to add a role to a user
const request: CreateOrganizationUserRoleRequest = {
roleId: roleId
};
// Call the method to add a role to a user
const response = await apiClient.organizationsApi.createOrganizationUserRole({
orgCode: orgCode,
userId: userId,
createOrganizationUserRoleRequest: request
});
In this example,
accessToken
is the access token you obtained from
getKindeAccessToken()
.
Please note that you'll need to install the
@kinde/management-api-client
package to use the Kinde Management API client. You can install it using npm:
npm install @kinde/management-api-client
I hope this helps! Let me know if you have any other questions. I'm here to help.
Sounds like you are building LoL project.
Thanks for sharing these details.
We are going to have 2-3 paid tiers, eg 5$ 10$ and one more
Is it going to be like, e.g. $5/month, $10/month, etc...?
Good morning and thanks for reaching back
I'm trying to integrate Stripe to the app now and I'm doing it by making customers database table to our database, which only includes users who
have subscribed to our service via stripe.
Sounds like a good approach.
Our initial Billing feature v1 will handle plans e.g. $5/month, $10/month, etc...
I'm trying to integrate Stripe to the app now and I'm doing it by making customers database table to our database, which only includes users who
have subscribed to our service via stripe.
We will handle syncing your user data with Stripe in our Billing feature.
Yup. Definitely switching to billing when it comes.
Comes is a wrong word, it doesn't come, it has to be made