Welcome to the Kinde community

Updated 2 months ago

Need help with roles (setPermission(s), setRole(s))

Hey.

I want to programmatically set roles/permissions for users, is this in any way possible, or should I use a seperate db to implement this.

The Kinde next app router v2 server/clientside libs give me getters for a lot of stuff but it seems that a lot of stuff can be set only manually.

My motivation for doing this is that I would like to give user some perm(s)/role(s) when they subscribe with stripe. Dont know yet how I'm implementing that. Just would love to use kinde + subscriptions in my next app

Also see that you guys are working on the "Billing" feature πŸ‘ . How should one do billing currently in kinde next environment?
o
O
35 comments
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
maybe on the right path?
Attachment
image.png
Hi @ooi cat,
Yes you can programmatically set roles and permissions of users (within an organization) via the following 2 API calls:
  1. Add Organization User Role
  2. Add Organization User Permission
Let me know if you have any questions.
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:
  1. What you are building
  2. Is your product B2B? B2C? Something else?
  3. 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:

  1. Make sure you're using the correct method. The method to assign a role to a user in an organization is addOrganizationUserRole(), not methodThatCreatesUserARole().
  1. 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.
  1. Check the order of the parameters. The order should be orgCode, userId, roleId.
  1. 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.
  1. 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:
Plain Text
const response = await apiClient.organizationsApi.createOrganizationUserRole({
      createOrganizationUserRoleRequest: {
        roleId: roleId
      },
      orgCode: orgCode,
      userId: userId
    })


in the libs its:
Plain Text
export interface CreateOrganizationUserRoleOperationRequest {
    orgCode: string;
    userId: string;
    createOrganizationUserRoleRequest: CreateOrganizationUserRoleRequest;
}

Plain Text
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:

  1. Make sure the roleId, orgCode, and userId are valid and exist in your database.
  1. 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.
  1. Check if the roleId is optional in your database. If it's not, you need to provide a valid roleId.
  1. 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:
Plain Text
import { createKindeManagementAPIClient, getKindeServerSession } from "@kinde-oss/kinde-auth-nextjs/server"

// in React server-component: ...
const apiClient = await createKindeManagementAPIClient();
Missed this.

  1. Drafting tool for a game called League of Legends
  2. B2C
  3. 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
Here is the error I get
Attachment
image.png
Not quite sure what the "Check if the roleId is optional in your database" means. I'm using the roleId from kinde:
Plain Text
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

Plain Text
/**
 * @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:

Plain Text
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:

Plain Text
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
Add a reply
Sign up and join the conversation on Discord