Fix merge conflicts and add withTransaction helper

- Add withTransaction helper that gracefully handles nested transactions
  (reuses existing transaction in tests, starts new one otherwise)
- Update auth procedures to use withTransaction instead of direct .transaction()
- Add email config to all e2e test contexts (required by merged code)
- Remove duplicate verification token code from signup procedure

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
igm
2026-01-12 17:07:14 +08:00
parent 8e65c2e698
commit e43c006bb1
10 changed files with 82 additions and 20 deletions

View File

@@ -10,6 +10,7 @@ import type {
import type { Kysely } from "kysely";
import type { RPInfo } from "../../utils/webauthn.js";
import { ORPCError } from "@orpc/server";
import { withTransaction } from "@reviq/db";
import { sendVerificationEmail } from "@reviq/emails";
import { verifyRegistrationResponse } from "@simplewebauthn/server";
import {
@@ -159,7 +160,7 @@ export async function signupWithPasskey(
// Create user and passkey in a transaction (handle race condition if concurrent signup)
try {
const result = await db.transaction().execute(async (trx) => {
const result = await withTransaction(db, async (trx) => {
// Create user
const user = await trx
.insertInto("users")
@@ -276,7 +277,7 @@ export const signup = os.auth.signup.handler(async ({ input, context }) => {
);
// Create session and email verification in transaction
const session = await context.db.transaction().execute(async (trx) => {
const session = await withTransaction(context.db, async (trx) => {
// Create session (7 days, trusted mode false initially, no device)
const newSession = await createSession(trx, {
userId,
@@ -307,20 +308,6 @@ export const signup = os.auth.signup.handler(async ({ input, context }) => {
COOKIE_OPTIONS.session,
);
// Generate verification token
const verificationToken = generateSecureBase58Token();
const expiresAt = generateExpiry(TOKEN_DURATIONS.EMAIL_VERIFICATION);
// Store verification token (store raw token, not hash - it's already high-entropy)
await context.db
.insertInto("email_verifications")
.values({
user_id: userId,
token: verificationToken,
expires_at: expiresAt,
})
.execute();
// Send verification email
await sendVerificationEmail({
client: context.email.client,