Files
publisher-dashboard/apps/api-server/src/procedures/auth/verify-email.ts
RevIQ 1bf05465c3 Replace void returns with { success: true } across all API endpoints
- Add successResponseSchema to common.ts for explicit success responses
- Update all auth, me, orgs, and admin procedures to return { success: true }
- Update contract.ts to use successResponseSchema instead of z.void()
- Add ast-grep rule to prevent future z.void() usage in contracts
- Add build:packages script to root package.json
- Fix test file lint errors with eslint-disable comments

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 16:30:22 +08:00

61 lines
1.5 KiB
TypeScript

/**
* Verify user email with token from URL
* Public procedure - no authentication required
*
* Flow:
* 1. Find token in email_verifications table
* 2. Check if token is expired
* 3. Update user's email_verified_at timestamp
* 4. Delete the verification record
*/
import { ORPCError } from "@orpc/server";
import { os } from "../base.js";
export const verifyEmail = os.auth.verifyEmail.handler(
async ({ input, context }) => {
const { token } = input;
// Find the verification record
const verification = await context.db
.selectFrom("email_verifications")
.select(["id", "user_id", "expires_at"])
.where("token", "=", token)
.executeTakeFirst();
if (!verification) {
throw new ORPCError("BAD_REQUEST", {
message: "Invalid or expired token",
});
}
// Check if token is expired
if (new Date() > verification.expires_at) {
// Clean up expired token
await context.db
.deleteFrom("email_verifications")
.where("id", "=", verification.id)
.execute();
throw new ORPCError("BAD_REQUEST", {
message: "Invalid or expired token",
});
}
// Update user's email_verified_at
await context.db
.updateTable("users")
.set({ email_verified_at: new Date() })
.where("id", "=", verification.user_id)
.execute();
// Delete the verification record
await context.db
.deleteFrom("email_verifications")
.where("id", "=", verification.id)
.execute();
return { success: true };
},
);