saM69420
saM69420
Explore posts from servers
DTDrizzle Team
Created by saM69420 on 3/17/2024 in #help
is there a way to log the outputs of a queries with a custom logger?
I have a custom logger for logging out the sql query, but I would love to be able to log the results of all queries too
1 replies
KKinde
Created by saM69420 on 1/16/2024 in #💻┃support
Kinde + Bun + Hono + React
Hey I was just hoping to get some advice/validation on code I've written for using Kinde with a bun and hono app. I'm using the typescript SDK. My session manager is storing all the session items in cookies as the next.js libary does. Then I have some custom middleware for protected routes. My backend is serving up a react app, the cookies get sent with every request, and everything is working there. I have a /api/me endpoint that checks if the user is logged in. The react app calls that endpoint when it first loads to check if the user is logged in.
// auth.ts
import {
createKindeServerClient,
GrantType,
SessionManager,
UserType,
} from "@kinde-oss/kinde-typescript-sdk";

import { Hono, Context, MiddlewareHandler } from "hono";
import { getCookie, setCookie, deleteCookie } from "hono/cookie";

export const kindeClient = createKindeServerClient(
GrantType.AUTHORIZATION_CODE,
{
authDomain: process.env.KINDE_DOMAIN!,
clientId: process.env.KINDE_CLIENT_ID!,
clientSecret: process.env.KINDE_CLIENT_SECRET!,
redirectURL: process.env.KINDE_REDIRECT_URI!,
logoutRedirectURL: process.env.KINDE_LOGOUT_REDIRECT_URI!,
}
);

export const sessionManager = (c: Context): SessionManager => ({
async getSessionItem(key: string) {
const result = getCookie(c, key);
return result;
},
async setSessionItem(key: string, value: unknown) {
if (typeof value === "string") {
setCookie(c, key, value);
} else {
setCookie(c, key, JSON.stringify(value));
}
},
async removeSessionItem(key: string) {
deleteCookie(c, key);
},
async destroySession() {
["id_token", "access_token", "user", "refresh_token"].forEach((key) => {
deleteCookie(c, key);
});
},
});

export const protectRoute: MiddlewareHandler = async (c, next) => {
try {
const manager = sessionManager(c);
const isAuthenticated = await kindeClient.isAuthenticated(manager);
if (!isAuthenticated) {
return c.json({ error: "Unauthorized" }, 401);
}
await next();
} catch (e) {
console.error(e);
return c.json({ error: "Unauthorized" }, 401);
}
};

export const getUser: MiddlewareHandler<{
Variables: {
user: UserType;
};
}> = async (c, next) => {
try {
const manager = sessionManager(c);
const isAuthenticated = await kindeClient.isAuthenticated(manager);
if (!isAuthenticated) {
return c.json({ error: "Unauthorized" }, 401);
}
const profile = await kindeClient.getUserProfile(manager);
c.set("user", profile);
await next();
} catch (e) {
console.error(e);
return c.json({ error: "Unauthorized" }, 401);
}
};

export const authRoutes = new Hono()
.get("/logout", async (c) => {
const logoutUrl = await kindeClient.logout(sessionManager(c));
return c.redirect(logoutUrl.toString());
})
.get("/login", async (c) => {
const loginUrl = await kindeClient.login(sessionManager(c));
return c.redirect(loginUrl.toString());
})
.get("/register", async (c) => {
const registerUrl = await kindeClient.register(sessionManager(c));
return c.redirect(registerUrl.toString());
})
.get("/callback", async (c) => {
await kindeClient.handleRedirectToApp(
sessionManager(c),
new URL(c.req.url)
);
return c.redirect("/");
});
// auth.ts
import {
createKindeServerClient,
GrantType,
SessionManager,
UserType,
} from "@kinde-oss/kinde-typescript-sdk";

import { Hono, Context, MiddlewareHandler } from "hono";
import { getCookie, setCookie, deleteCookie } from "hono/cookie";

export const kindeClient = createKindeServerClient(
GrantType.AUTHORIZATION_CODE,
{
authDomain: process.env.KINDE_DOMAIN!,
clientId: process.env.KINDE_CLIENT_ID!,
clientSecret: process.env.KINDE_CLIENT_SECRET!,
redirectURL: process.env.KINDE_REDIRECT_URI!,
logoutRedirectURL: process.env.KINDE_LOGOUT_REDIRECT_URI!,
}
);

export const sessionManager = (c: Context): SessionManager => ({
async getSessionItem(key: string) {
const result = getCookie(c, key);
return result;
},
async setSessionItem(key: string, value: unknown) {
if (typeof value === "string") {
setCookie(c, key, value);
} else {
setCookie(c, key, JSON.stringify(value));
}
},
async removeSessionItem(key: string) {
deleteCookie(c, key);
},
async destroySession() {
["id_token", "access_token", "user", "refresh_token"].forEach((key) => {
deleteCookie(c, key);
});
},
});

export const protectRoute: MiddlewareHandler = async (c, next) => {
try {
const manager = sessionManager(c);
const isAuthenticated = await kindeClient.isAuthenticated(manager);
if (!isAuthenticated) {
return c.json({ error: "Unauthorized" }, 401);
}
await next();
} catch (e) {
console.error(e);
return c.json({ error: "Unauthorized" }, 401);
}
};

export const getUser: MiddlewareHandler<{
Variables: {
user: UserType;
};
}> = async (c, next) => {
try {
const manager = sessionManager(c);
const isAuthenticated = await kindeClient.isAuthenticated(manager);
if (!isAuthenticated) {
return c.json({ error: "Unauthorized" }, 401);
}
const profile = await kindeClient.getUserProfile(manager);
c.set("user", profile);
await next();
} catch (e) {
console.error(e);
return c.json({ error: "Unauthorized" }, 401);
}
};

export const authRoutes = new Hono()
.get("/logout", async (c) => {
const logoutUrl = await kindeClient.logout(sessionManager(c));
return c.redirect(logoutUrl.toString());
})
.get("/login", async (c) => {
const loginUrl = await kindeClient.login(sessionManager(c));
return c.redirect(loginUrl.toString());
})
.get("/register", async (c) => {
const registerUrl = await kindeClient.register(sessionManager(c));
return c.redirect(registerUrl.toString());
})
.get("/callback", async (c) => {
await kindeClient.handleRedirectToApp(
sessionManager(c),
new URL(c.req.url)
);
return c.redirect("/");
});
// app.ts
import { Hono } from "hono";
import { serveStatic } from "hono/bun";

import { authRoutes, getUser } from "./auth";
import expenseRoute from "./expenses";

const app = new Hono();

const apiRoutes = app
.basePath("/api")
.route("/expenses", expenseRoute)
.get("/me", getUser, async (c) => {
const user = await c.var.user;
return c.json({ user });
});

app.route("/", authRoutes);

// app.use('/favicon.ico', serveStatic({ path: './favicon.ico' }))
app.get("*", serveStatic({ root: "./frontend/dist" }));
app.get("*", serveStatic({ path: "./frontend/dist/index.html" }));

export default app;
export type ApiRoutes = typeof apiRoutes;
// app.ts
import { Hono } from "hono";
import { serveStatic } from "hono/bun";

import { authRoutes, getUser } from "./auth";
import expenseRoute from "./expenses";

const app = new Hono();

const apiRoutes = app
.basePath("/api")
.route("/expenses", expenseRoute)
.get("/me", getUser, async (c) => {
const user = await c.var.user;
return c.json({ user });
});

app.route("/", authRoutes);

// app.use('/favicon.ico', serveStatic({ path: './favicon.ico' }))
app.get("*", serveStatic({ root: "./frontend/dist" }));
app.get("*", serveStatic({ path: "./frontend/dist/index.html" }));

export default app;
export type ApiRoutes = typeof apiRoutes;
10 replies
KKinde
Created by saM69420 on 11/27/2023 in #💻┃support
New Application Environments
I'm trying to figure out the correct workflow when setting up a new application and i'm a little confused about environments. What is the correct way of setting up environments for a new application? Currently my experience looks like this: - Sign in to my kinde account, or create an account - Add a new business for my app - Navigate to that business and select start project from scratch - Select Nextjs as the framework - select social providers and email - Select connect to get to the quick start where I can copy all my env vars and “start quickly” This seems really easy and simple, but I’m automatically put into my production environment with no other environments available. I think I actually want a localhost environment to test things out with. So then I: - Add environment (local or dev or something) - Switch to that environment I have a backend and a frontend application in this new environment even though I only had a next.js environment in my initially setup production environment. - Delete the frontend app - Go to settings/authentication to add social connections - select the backend app - Select Nextjs as the framework and go through the quick start It seems easy to just use production but a bit awkward to get a dev environment the way i'm doing it
22 replies
KKinde
Created by saM69420 on 11/16/2023 in #💻┃support
Customize Registration Fields
No description
6 replies
DTDrizzle Team
Created by saM69420 on 10/5/2023 in #help
Creating a Case-Insensitive Unique Index
I want to be able to select a user by their username but have usernames be case insensitive:
const user = await db.select()
.from(users)
.where(eq(sql`lower(${usersTable.username})`, sql`lower(${params.username})`))
.then((result) => result[0]);
const user = await db.select()
.from(users)
.where(eq(sql`lower(${usersTable.username})`, sql`lower(${params.username})`))
.then((result) => result[0]);
If I setup a users table like this:
export const users = pgTable("users", {
username: varchar("username", { length: 30 })
.notNull()
.unique("users_username_unique", { nulls: "not distinct" }),
//...
});
export const users = pgTable("users", {
username: varchar("username", { length: 30 })
.notNull()
.unique("users_username_unique", { nulls: "not distinct" }),
//...
});
It will create in an index definition:
CREATE UNIQUE INDEX users_username_unique ON public.users USING btree (username) NULLS NOT DISTINCT;
CREATE UNIQUE INDEX users_username_unique ON public.users USING btree (username) NULLS NOT DISTINCT;
Is there a way to create a lowercase index:
CREATE UNIQUE INDEX users_username_unique ON public.users USING btree (LOWER(username)) NULLS NOT DISTINCT
CREATE UNIQUE INDEX users_username_unique ON public.users USING btree (LOWER(username)) NULLS NOT DISTINCT
Or is there another way to achieve a lowercase equality check on a unique index?
8 replies