Kenton
Kenton
KKinde
Created by Kenton on 9/12/2024 in #💻┃support
Do Roles or Permissions update immediately in user session?
Hi Oli, thanks for the update! I'll try it tonight 👍
16 replies
KKinde
Created by Kenton on 9/12/2024 in #💻┃support
Do Roles or Permissions update immediately in user session?
Hey @Andre @ Kinde , has a dev had a chance to look at my message? Thanks!
16 replies
KKinde
Created by Kenton on 9/12/2024 in #💻┃support
Do Roles or Permissions update immediately in user session?
Thanks @Andre @ Kinde !
16 replies
KKinde
Created by Kenton on 9/12/2024 in #💻┃support
Do Roles or Permissions update immediately in user session?
Hey Claire, is this something you could help with?
16 replies
KKinde
Created by Kenton on 9/12/2024 in #💻┃support
Do Roles or Permissions update immediately in user session?
That fixed roles appearing, thank you Clair. I've tried await Users.refreshUserClaims(userClaimsData) but the user access token still references the old role in middleware and in the browser.
import { NextRequest, NextResponse } from "next/server";
import { Users, init } from "@kinde/management-api-js";
import { getUserAndOrg } from "@/utils/auth";
import {RefreshUserClaimsData} from "@kinde/management-api-js/dist/api/types.gen";

function delay(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}

export async function GET(req: NextRequest) {
init();
const { userId, orgId, error } = await getUserAndOrg();

if (error) {
return error;
}

console.log(userId)
const userClaimsData: RefreshUserClaimsData = {
userId: userId
}
await Users.refreshUserClaims(userClaimsData)

await delay(500);

return NextResponse.json({});
}
import { NextRequest, NextResponse } from "next/server";
import { Users, init } from "@kinde/management-api-js";
import { getUserAndOrg } from "@/utils/auth";
import {RefreshUserClaimsData} from "@kinde/management-api-js/dist/api/types.gen";

function delay(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}

export async function GET(req: NextRequest) {
init();
const { userId, orgId, error } = await getUserAndOrg();

if (error) {
return error;
}

console.log(userId)
const userClaimsData: RefreshUserClaimsData = {
userId: userId
}
await Users.refreshUserClaims(userClaimsData)

await delay(500);

return NextResponse.json({});
}
16 replies
KKinde
Created by Kenton on 9/12/2024 in #💻┃support
Do Roles or Permissions update immediately in user session?
export default withAuth(
async function middleware(req: KindeNextRequest) {
const pathname = req.nextUrl.pathname;
const orgCode = req.kindeAuth?.token?.org_code;
const userRoles = req.kindeAuth?.token?.roles || []; // Default to empty array if roles is undefined

// Check if the user has the "admin" role
const isAdmin = userRoles.some(role => role.key === "admin");

export default withAuth(
async function middleware(req: KindeNextRequest) {
const pathname = req.nextUrl.pathname;
const orgCode = req.kindeAuth?.token?.org_code;
const userRoles = req.kindeAuth?.token?.roles || []; // Default to empty array if roles is undefined

// Check if the user has the "admin" role
const isAdmin = userRoles.some(role => role.key === "admin");

req.kindeAuth?.token?.roles used to be present when I originally sent this message but now roles is not present.
16 replies
KKinde
Created by Kenton on 9/12/2024 in #💻┃support
Do Roles or Permissions update immediately in user session?
Hi Claire, thanks for the follow-up message. Since my message on Sep 11th, it looks like token no longer include roles, only permissions. Was this intended?
16 replies
KKinde
Created by Kenton on 9/12/2024 in #💻┃support
Do Roles or Permissions update immediately in user session?
Hey Sam, curious if you have a response to my above message. Thanks!
16 replies
KKinde
Created by Kenton on 9/12/2024 in #💻┃support
Do Roles or Permissions update immediately in user session?
Thanks for the response. Does refreshTokens() trigger a refresh for all users in an organization or only the current users session? If it's only the current users session, this will have no impact on my use-case since an admin user would be updating the role/permissions of another user.
16 replies
KKinde
Created by Kenton on 8/27/2024 in #💻┃support
Kinde Management API - 400 Bad Request: malformed Host header
This is all very hacky. Will clean it all up over the weekend so others can reuse it. Peter, still interested in knowing the purpose of the refreshTokens in this flow.
15 replies
KKinde
Created by Kenton on 8/27/2024 in #💻┃support
Kinde Management API - 400 Bad Request: malformed Host header
middleware.ts
import { withAuth } from "@kinde-oss/kinde-auth-nextjs/middleware";
import { NextResponse } from "next/server";

const DEFAULT_ORG_ID = 'your-default-org-id';

export default withAuth(
async function middleware(req) {
// Correctly access the pathname
const pathname = req.nextUrl.pathname;
console.log('Pathname:', pathname);

const orgCode = req.kindeAuth?.token?.org_code;
console.log('Org Code:', orgCode);

// Redirect logic based on org_code and pathname
if (pathname !== '/' && !pathname.includes('auth') && pathname !== '/create-org' && orgCode === DEFAULT_ORG_ID) {
const url = req.nextUrl.clone();
url.pathname = '/create-org';
return NextResponse.redirect(url);
}
},
{
isReturnToCurrentPage: true,
loginPage: "/login",
}
);

export const config = {
matcher: ["/home"]
};
import { withAuth } from "@kinde-oss/kinde-auth-nextjs/middleware";
import { NextResponse } from "next/server";

const DEFAULT_ORG_ID = 'your-default-org-id';

export default withAuth(
async function middleware(req) {
// Correctly access the pathname
const pathname = req.nextUrl.pathname;
console.log('Pathname:', pathname);

const orgCode = req.kindeAuth?.token?.org_code;
console.log('Org Code:', orgCode);

// Redirect logic based on org_code and pathname
if (pathname !== '/' && !pathname.includes('auth') && pathname !== '/create-org' && orgCode === DEFAULT_ORG_ID) {
const url = req.nextUrl.clone();
url.pathname = '/create-org';
return NextResponse.redirect(url);
}
},
{
isReturnToCurrentPage: true,
loginPage: "/login",
}
);

export const config = {
matcher: ["/home"]
};
15 replies
KKinde
Created by Kenton on 8/27/2024 in #💻┃support
Kinde Management API - 400 Bad Request: malformed Host header
Create a /create-org page:
"use client";

import CreateOrgButton from "@/components/create-org-button";
import { useRouter } from "next/navigation";

export default function Page() {
const router = useRouter();

// Define a server action
const handleCreateOrg = async (orgName) => {
try {
const response = await fetch('/api/create-org', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ name: orgName }),
});

if (!response.ok) {
throw new Error('Failed to create organization');
}

const data = await response.json();
console.log('Organization created:', data);

// Should log the user in with the the new org code instead of the default org code.
router.push(`/api/auth/login?org_code=${data.orgId}`);
} catch (error) {
console.error('Error creating organization:', error);
}
};
return (
<>
<CreateOrgButton handleCreateOrg={handleCreateOrg} />
</>
)
}
"use client";

import CreateOrgButton from "@/components/create-org-button";
import { useRouter } from "next/navigation";

export default function Page() {
const router = useRouter();

// Define a server action
const handleCreateOrg = async (orgName) => {
try {
const response = await fetch('/api/create-org', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ name: orgName }),
});

if (!response.ok) {
throw new Error('Failed to create organization');
}

const data = await response.json();
console.log('Organization created:', data);

// Should log the user in with the the new org code instead of the default org code.
router.push(`/api/auth/login?org_code=${data.orgId}`);
} catch (error) {
console.error('Error creating organization:', error);
}
};
return (
<>
<CreateOrgButton handleCreateOrg={handleCreateOrg} />
</>
)
}
15 replies
KKinde
Created by Kenton on 8/27/2024 in #💻┃support
Kinde Management API - 400 Bad Request: malformed Host header
What's the purpose of the refreshTokens? The following works for me. create route /create-org
import {NextRequest, NextResponse} from "next/server";
import {Organizations, init} from "@kinde/management-api-js";
import {getUserAndOrg} from "@/utils/auth";

const DEFAULT_ORG_ID = 'your-default-org-id';

export async function POST(req: NextRequest) {
init();
try {
const { userId, orgId, user, error } = await getUserAndOrg();
console.log(user)
if (!userId) {
console.log("Redirect to login")
}
// Default org, prevent users from creating another org
if (orgId !== DEFAULT_ORG_ID) {
console.log("Redirect to home")
}
const orgResponse = await Organizations.createOrganization({
requestBody: {
name: "test-org",
handle: "test-org",
},
});
console.log(orgResponse)

const orgCode = orgResponse.organization?.code;
console.log(orgCode)

if (orgCode && userId) {
const response = await Organizations.addOrganizationUsers({
orgCode: orgCode,
requestBody: {
users: [{
id: userId,
roles: ["admin"]
}],
},
});

await Organizations.removeOrganizationUser({
orgCode: DEFAULT_ORG_ID,
userId: userId,
})
console.log("User added successfully:", response);
return NextResponse.json({orgId: orgCode});
} else {
console.error("Invalid orgCode or user ID");
}
} catch (error) {
console.error("Error creating organization or adding user:", error);
}

return NextResponse.json({});
}
import {NextRequest, NextResponse} from "next/server";
import {Organizations, init} from "@kinde/management-api-js";
import {getUserAndOrg} from "@/utils/auth";

const DEFAULT_ORG_ID = 'your-default-org-id';

export async function POST(req: NextRequest) {
init();
try {
const { userId, orgId, user, error } = await getUserAndOrg();
console.log(user)
if (!userId) {
console.log("Redirect to login")
}
// Default org, prevent users from creating another org
if (orgId !== DEFAULT_ORG_ID) {
console.log("Redirect to home")
}
const orgResponse = await Organizations.createOrganization({
requestBody: {
name: "test-org",
handle: "test-org",
},
});
console.log(orgResponse)

const orgCode = orgResponse.organization?.code;
console.log(orgCode)

if (orgCode && userId) {
const response = await Organizations.addOrganizationUsers({
orgCode: orgCode,
requestBody: {
users: [{
id: userId,
roles: ["admin"]
}],
},
});

await Organizations.removeOrganizationUser({
orgCode: DEFAULT_ORG_ID,
userId: userId,
})
console.log("User added successfully:", response);
return NextResponse.json({orgId: orgCode});
} else {
console.error("Invalid orgCode or user ID");
}
} catch (error) {
console.error("Error creating organization or adding user:", error);
}

return NextResponse.json({});
}
15 replies
KKinde
Created by Kenton on 8/27/2024 in #💻┃support
Kinde Management API - 400 Bad Request: malformed Host header
@Daniel_Kinde yesterday, I moved one of my users from the default org to a newly created org. What's surprising, is that the users orgCode in the active session didn't update to the new org the user was moved to but instead remained the same until the user session expired and the user logged back in again. I presume I'll need to do a change session of some kind after creating the new org and moving the user to that org? Hopefully the user doesn't have to login again.
15 replies
KKinde
Created by Dave on 8/26/2024 in #💻┃support
How to use Is_create_org in NextJs.
The middleware I provided is working well but I’m running into issues with the Kinde Management API: https://discord.com/channels/1070212618549219328/1278099615916490843/1278099615916490843 I did manually move one of my users to a different org and theoretically it all worked as expected. If you know how to use the management API, let me know.
9 replies
KKinde
Created by Kenton on 8/27/2024 in #💻┃support
Kinde Management API - 400 Bad Request: malformed Host header
I created a POST request in my NextJS app to create the org and move the user:
import {NextRequest, NextResponse} from "next/server";
import {Organizations} from "@kinde/management-api-js";

export async function POST(req: NextRequest) {
try {
const orgResponse = await Organizations.createOrganization({
requestBody: {
name: "test-org",
handle: "test-org",
},
});

const orgCode = orgResponse.organization?.code;
const userId = "hard_coded_user_id"
if (orgCode && userId) {
const response = await Organizations.addOrganizationUsers({
orgCode: orgCode,
requestBody: {
users: [{ id: userId }],
},
});
console.log("User added successfully:", response);
} else {
console.error("Invalid orgCode or user ID");
}
} catch (error) {
console.error("Error creating organization or adding user:", error);
}

return NextResponse.json({});
}
import {NextRequest, NextResponse} from "next/server";
import {Organizations} from "@kinde/management-api-js";

export async function POST(req: NextRequest) {
try {
const orgResponse = await Organizations.createOrganization({
requestBody: {
name: "test-org",
handle: "test-org",
},
});

const orgCode = orgResponse.organization?.code;
const userId = "hard_coded_user_id"
if (orgCode && userId) {
const response = await Organizations.addOrganizationUsers({
orgCode: orgCode,
requestBody: {
users: [{ id: userId }],
},
});
console.log("User added successfully:", response);
} else {
console.error("Invalid orgCode or user ID");
}
} catch (error) {
console.error("Error creating organization or adding user:", error);
}

return NextResponse.json({});
}
Can anyone see what I'm doing wrong?
15 replies
KKinde
Created by Dave on 8/26/2024 in #💻┃support
How to use Is_create_org in NextJs.
Throwing out an idea. Users are added to default org on signup. What if we added code to middleware to redirect user to /create-org page if the users org-code === default org code? It would look something like this:
import { withAuth } from "@kinde-oss/kinde-auth-nextjs/middleware";
import { NextResponse } from "next/server";

export default withAuth(
async function middleware(req) {
console.log("User Kinde Auth Data", req.kindeAuth);

// Correctly access the pathname
const pathname = req.nextUrl.pathname;
console.log('Pathname:', pathname);

const orgCode = req.kindeAuth?.token?.org_code;
console.log('Org Code:', orgCode);

// Redirect logic based on org_code and pathname
if (pathname !== '/' && !pathname.includes('auth') && pathname !== '/create-org' && orgCode === 'your-default-org-code') {
const url = req.nextUrl.clone();
url.pathname = '/create-org';
return NextResponse.redirect(url);
}
},
{
isReturnToCurrentPage: true,
loginPage: "/login", // update to you sign in page
}
);

export const config = {
matcher: ["/dashboard", "/other-protected-route", "/other-protected-route/:path*"]
};
import { withAuth } from "@kinde-oss/kinde-auth-nextjs/middleware";
import { NextResponse } from "next/server";

export default withAuth(
async function middleware(req) {
console.log("User Kinde Auth Data", req.kindeAuth);

// Correctly access the pathname
const pathname = req.nextUrl.pathname;
console.log('Pathname:', pathname);

const orgCode = req.kindeAuth?.token?.org_code;
console.log('Org Code:', orgCode);

// Redirect logic based on org_code and pathname
if (pathname !== '/' && !pathname.includes('auth') && pathname !== '/create-org' && orgCode === 'your-default-org-code') {
const url = req.nextUrl.clone();
url.pathname = '/create-org';
return NextResponse.redirect(url);
}
},
{
isReturnToCurrentPage: true,
loginPage: "/login", // update to you sign in page
}
);

export const config = {
matcher: ["/dashboard", "/other-protected-route", "/other-protected-route/:path*"]
};
/create-org would show another screen where the user fills out their desired org name. On submit, we create the org and move that user to the org. This flow allows us to continue using the hosted sign up and sign in pages AND we don't run into a situation where we create orgs and user abandons sign up leaving us having to clean up empty orgs. To my knowledge, if a user has been invited to an org and they arrive at the sign up page, they should be added to the org they have been invited to instead of the default org. Could you confirm this quacksire?
9 replies
KKinde
Created by Dave on 8/26/2024 in #💻┃support
How to use Is_create_org in NextJs.
Do you have any guides or repositories showing how to accomplish this sign up flow quacksire? How do Dave and I use is_create_org?
9 replies
KKinde
Created by Dave on 8/26/2024 in #💻┃support
How to use Is_create_org in NextJs.
I am wondering the same thing Dave. When a user signs up, how do we let them specify the name of the org they want to create and associate them with that org. The docs reference is_create_org but where do we use it to enable this flow.
9 replies