Middleware
Auth Middleware
Authentication middleware for URPC
Basic Usage
import { URPC } from "@unilab/urpc-hono";
import { auth } from "@unilab/urpc-core/middleware";
import { Allow } from "@unilab/urpc-core";
const app = URPC.init({
middlewares: [
auth({
getUser: async (c: Context) => {
try {
const token = c.req.header("Authorization")?.split(" ")[1];
if (!token) {
return null;
}
const user = decodeToken(token);
return user;
} catch (error) {
return null;
}
},
}),
],
});Entity Access Control
Built-in Allow Options
const app = URPC.init({
entityConfigs: {
post: {
// Only authenticated users can perform CRUD operations
allowApiCrud: Allow.authenticated,
// Allows all CRUD operations
allowApiCrud: Allow.everyone,
// Same as Allow.everyone
allowApiCrud: true,
},
},
});Role-based Access Control
const app = URPC.init({
entityConfigs: {
post: {
// Only users with the 'admin' role can update
allowApiCrud: "admin",
// Only users with 'admin' or 'manager' roles can delete
allowApiDelete: ["admin", "manager"],
},
},
});Custom Authorization Functions
const app = URPC.init({
entityConfigs: {
post: {
// Only the user 'Jane' can read
allowApiCrud: (user: AuthUser | null) => user?.name == "Jane",
// Users can only read posts they own
allowApiRead: (user, entityData) => {
if (Array.isArray(entityData)) {
return true;
}
return entityData?.authorId == user?.id;
},
},
},
});Granular Permissions
const app = URPC.init({
entityConfigs: {
post: {
allowApiCreate: Allow.authenticated,
allowApiRead: Allow.everyone,
allowApiUpdate: (user, entityData) => entityData?.authorId == user?.id,
allowApiDelete: ["admin", "manager"],
},
},
});Client Configuration
import { URPC } from "@unilab/urpc";
URPC.init({
baseUrl: "http://localhost:9000",
timeout: 10000,
});
URPC.setHeaders({
Authorization: `Bearer ${token}`,
});Better-Auth Integration
Better-Auth Setup
import { betterAuth } from "better-auth";
import { admin, organization } from "better-auth/plugins";
import { Pool } from "pg";
export const auth = betterAuth({
database: new Pool({
connectionString: process.env.DATABASE_URL!,
ssl: {},
}),
socialProviders: {
github: {
clientId: process.env.GITHUB_CLIENT_ID!,
clientSecret: process.env.GITHUB_CLIENT_SECRET!,
},
google: {
clientId: process.env.GOOGLE_CLIENT_ID!,
clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
},
},
session: {
expiresIn: 60 * 60 * 24 * 30, // 30 days
},
plugins: [admin(), organization()],
});URPC Integration with Better-Auth
import { URPC } from "@unilab/urpc-next/app-router";
import { auth as authMiddleware } from "@unilab/urpc-core/middleware";
import { auth as betterAuth } from "./lib/auth";
import { headers } from "next/headers";
export const api = URPC.init({
middlewares: [
authMiddleware({
getUser: async (request: any) => {
try {
const session = await betterAuth.api.getSession({
headers: await headers(),
});
const user = session
? {
id: session.user.id,
name: session.user.name,
email: session.user.email,
roles: [session.user.role || ""],
activeOrganizationId: session.session.activeOrganizationId,
}
: null;
return user;
} catch (error) {
return null;
}
},
}),
],
entityConfigs: {
post: {
allowApiCreate: Allow.authenticated,
allowApiRead: Allow.everyone,
allowApiUpdate: (user, entityData) => entityData?.authorId == user?.id,
allowApiDelete: ["admin", "manager"],
},
},
});