Add typed context and middleware for oRPC procedures

Use implement(contract).$context<APIContext>() for proper type safety
in all procedure handlers. Create authMiddleware and loginRequestMiddleware
using os.middleware() and apply with .use() on routes requiring auth.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
RevIQ
2026-01-09 15:36:26 +08:00
parent 829d365e80
commit a4d1f28f3d
12 changed files with 483 additions and 334 deletions

View File

@@ -1,12 +1,3 @@
import type { AuthenticatedContext } from "../../context.js";
import { implement } from "@orpc/server";
import { contract } from "@reviq/api-contract";
import { TOKEN_DURATIONS } from "../../utils/cookies.js";
import { generateExpiry, generateSecureToken } from "../../utils/crypto.js";
import { sendVerificationEmail } from "../../utils/email.js";
const os = implement(contract);
/**
* Resend email verification to authenticated user
* Requires authentication
@@ -18,37 +9,41 @@ const os = implement(contract);
* 4. Create new email_verifications record with 24 hour expiry
* 5. Send verification email (stubbed)
*/
export const resendVerificationEmail = os.auth.resendVerificationEmail.handler(
async ({ context }) => {
const ctx = context as AuthenticatedContext;
// Check if email is already verified
if (ctx.user.emailVerifiedAt !== null) {
// Email already verified, return early
return;
}
import { TOKEN_DURATIONS } from "../../utils/cookies.js";
import { generateExpiry, generateSecureToken } from "../../utils/crypto.js";
import { sendVerificationEmail } from "../../utils/email.js";
import { authMiddleware, os } from "../base.js";
// Delete any existing verification tokens for this user
await ctx.db
.deleteFrom("email_verifications")
.where("user_id", "=", ctx.user.id)
.execute();
export const resendVerificationEmail = os.auth.resendVerificationEmail
.use(authMiddleware)
.handler(async ({ context }) => {
// Check if email is already verified
if (context.user.emailVerifiedAt !== null) {
// Email already verified, return early
return;
}
// Generate new secure token
const token = generateSecureToken();
const expiresAt = generateExpiry(TOKEN_DURATIONS.EMAIL_VERIFICATION);
// Delete any existing verification tokens for this user
await context.db
.deleteFrom("email_verifications")
.where("user_id", "=", context.user.id)
.execute();
// Create new verification record
await ctx.db
.insertInto("email_verifications")
.values({
user_id: ctx.user.id,
token,
expires_at: expiresAt,
})
.execute();
// Generate new secure token
const token = generateSecureToken();
const expiresAt = generateExpiry(TOKEN_DURATIONS.EMAIL_VERIFICATION);
// Send verification email (stubbed)
await sendVerificationEmail(ctx.user.email, token);
},
);
// Create new verification record
await context.db
.insertInto("email_verifications")
.values({
user_id: context.user.id,
token,
expires_at: expiresAt,
})
.execute();
// Send verification email (stubbed)
await sendVerificationEmail(context.user.email, token);
});