A6E2XPCE63XLJR5Z75CZMUWX2NLODPPVSLURXLXPXLSVJ7QOXO6QC
B74R5YOFFEHPTIAGTFHBBQHDAU4RLWS457OCK3ZDVNVPGP45NNMAC
OBXY6BHNROIV7W4O3MMQ6GTQXU2XUKF5A4DCJYDLUEUHV72E7BNAC
LSAQ6ZM2NELU3FIWKEFBOXKVLSZS2ZOK2PHPHJRWPVZ5CVILSUYQC
QPZE42LFURFXW6QNTVXY6AF7DZI7KTOLHMNSJHLFCRZMNMGQ6EVQC
YX7LU4WRAUDMWS3DEDXZDSF6DXBHLYDWVSMSRK6KIW3MO6GRXSVQC
M3JUJ2WWZGCVMBITKRM5FUJMHFYL2QRMXJUVRUE4AC2RF74AOL5AC
import { Hono } from 'hono';
import * as jose from 'jose';
import { DateTime } from 'luxon';
import { userRole } from '../../../db/schema';
import { createDatabase } from '../utils/database';
import type { Env } from '../types';
const app = new Hono<{ Bindings: Env }>();
interface KindeWebhookEvent {
type: string;
data: {
user: {
id: string;
email: string;
given_name?: string;
family_name?: string;
};
};
}
app.post('/W7YwJjZbQqB6z40Va6vio', async (c) => {
try {
const token = await c.req.text();
if (!token) {
return c.json({ error: 'No token provided' }, 400);
}
const issuerUrl = c.env.KINDE_ISSUER_URL;
const jwksUrl = `${issuerUrl}/.well-known/jwks.json`;
const keyStore = jose.createRemoteJWKSet(new URL(jwksUrl));
const { payload } = await jose.jwtVerify(token, keyStore, {
// Remove issuer validation as Kinde webhooks may not include iss claim
});
const event = payload as unknown as KindeWebhookEvent;
if (event.type === 'user.created') {
const db = createDatabase(c.env);
const userId = event.data.user.id;
try {
const utcNow = DateTime.utc().toJSDate();
await db.insert(userRole).values({
userId,
role: 'USER',
createdBy: 'backend',
modifiedBy: 'backend',
createdAt: utcNow,
lastModified: utcNow,
}).onConflictDoNothing();
console.log(`Successfully assigned USER role to new user: ${userId}`);
} catch (dbError) {
console.error('Database error assigning user role:', dbError);
return c.json({ error: 'Database error' }, 500);
}
}
return c.json({ status: 'success' }, 200);
} catch (error) {
console.error('Webhook verification error:', error);
return c.json({ error: 'Invalid token' }, 401);
}
});
export default app;
import { Hono } from 'hono';
import * as jose from 'jose';
import { DateTime } from 'luxon';
import { userRole } from '../../../db/schema';
import { createDatabase } from '../utils/database';
import type { Env } from '../types';
const app = new Hono<{ Bindings: Env }>();
interface KindeWebhookEvent {
type: string;
data: {
user: {
id: string;
email: string;
given_name?: string;
family_name?: string;
};
};
}
// IMPORTANT: This endpoint path is configured in Kinde and MUST NOT be changed
app.post('/W7YwJjZbQqB6z40Va6vio', async (c) => {
try {
const token = await c.req.text();
if (!token) {
return c.json({ error: 'No token provided' }, 400);
}
const issuerUrl = c.env.KINDE_ISSUER_URL;
const jwksUrl = `${issuerUrl}/.well-known/jwks.json`;
const keyStore = jose.createRemoteJWKSet(new URL(jwksUrl));
const { payload } = await jose.jwtVerify(token, keyStore, {
// Remove issuer validation as Kinde webhooks may not include iss claim
});
const event = payload as unknown as KindeWebhookEvent;
if (event.type === 'user.created') {
const db = createDatabase(c.env);
const userId = event.data.user.id;
try {
const utcNow = DateTime.utc().toJSDate();
await db.insert(userRole).values({
userId,
role: 'USER',
createdBy: 'backend',
modifiedBy: 'backend',
createdAt: utcNow,
lastModified: utcNow,
}).onConflictDoNothing();
console.log(`Successfully assigned USER role to new user: ${userId}`);
} catch (dbError) {
console.error('Database error assigning user role:', dbError);
return c.json({ error: 'Database error' }, 500);
}
}
return c.json({ status: 'success' }, 200);
} catch (error) {
console.error('Webhook verification error:', error);
return c.json({ error: 'Invalid token' }, 401);
}
});
export default app;