Skip to content

Commit 092bdb4

Browse files
author
waleed
committed
update chat client otp
1 parent 40c401f commit 092bdb4

File tree

1 file changed

+35
-56
lines changed
  • apps/sim/app/api/chat/[identifier]/otp

1 file changed

+35
-56
lines changed

apps/sim/app/api/chat/[identifier]/otp/route.ts

Lines changed: 35 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { z } from 'zod'
66
import { renderOTPEmail } from '@/components/emails/render-email'
77
import { sendEmail } from '@/lib/email/mailer'
88
import { createLogger } from '@/lib/logs/console/logger'
9-
import { getRedisClient, markMessageAsProcessed, releaseLock } from '@/lib/redis'
9+
import { getRedisClient } from '@/lib/redis'
1010
import { generateRequestId } from '@/lib/utils'
1111
import { addCorsHeaders, setChatAuthCookie } from '@/app/api/chat/utils'
1212
import { createErrorResponse, createSuccessResponse } from '@/app/api/workflows/utils'
@@ -21,83 +21,52 @@ function generateOTP() {
2121
// We use 15 minutes (900 seconds) expiry for OTPs
2222
const OTP_EXPIRY = 15 * 60
2323

24-
// Store OTP in Redis
25-
async function storeOTP(email: string, chatId: string, otp: string): Promise<void> {
24+
async function storeOTP(email: string, chatId: string, otp: string): Promise<boolean> {
2625
const key = `otp:${email}:${chatId}`
2726
const redis = getRedisClient()
2827

29-
if (redis) {
30-
// Use Redis if available
31-
await redis.set(key, otp, 'EX', OTP_EXPIRY)
32-
} else {
33-
// Use the existing function as fallback to mark that an OTP exists
34-
await markMessageAsProcessed(key, OTP_EXPIRY)
28+
if (!redis) {
29+
logger.warn('Redis not available, OTP functionality requires Redis')
30+
return false
31+
}
3532

36-
// For the fallback case, we need to handle storing the OTP value separately
37-
// since markMessageAsProcessed only stores "1"
38-
const valueKey = `${key}:value`
39-
try {
40-
// Access the in-memory cache directly - hacky but works for fallback
41-
const inMemoryCache = (global as any).inMemoryCache
42-
if (inMemoryCache) {
43-
const fullKey = `processed:${valueKey}`
44-
const expiry = OTP_EXPIRY ? Date.now() + OTP_EXPIRY * 1000 : null
45-
inMemoryCache.set(fullKey, { value: otp, expiry })
46-
}
47-
} catch (error) {
48-
logger.error('Error storing OTP in fallback cache:', error)
49-
}
33+
try {
34+
await redis.set(key, otp, 'EX', OTP_EXPIRY)
35+
return true
36+
} catch (error) {
37+
logger.error('Error storing OTP in Redis:', error)
38+
return false
5039
}
5140
}
5241

53-
// Get OTP from Redis
5442
async function getOTP(email: string, chatId: string): Promise<string | null> {
5543
const key = `otp:${email}:${chatId}`
5644
const redis = getRedisClient()
5745

58-
if (redis) {
59-
// Use Redis if available
60-
return await redis.get(key)
46+
if (!redis) {
47+
return null
6148
}
62-
// Use the existing function as fallback - check if it exists
63-
const exists = await new Promise((resolve) => {
64-
try {
65-
// Check the in-memory cache directly - hacky but works for fallback
66-
const inMemoryCache = (global as any).inMemoryCache
67-
const fullKey = `processed:${key}`
68-
const cacheEntry = inMemoryCache?.get(fullKey)
69-
resolve(!!cacheEntry)
70-
} catch {
71-
resolve(false)
72-
}
73-
})
74-
75-
if (!exists) return null
7649

77-
// Try to get the value key
78-
const valueKey = `${key}:value`
7950
try {
80-
const inMemoryCache = (global as any).inMemoryCache
81-
const fullKey = `processed:${valueKey}`
82-
const cacheEntry = inMemoryCache?.get(fullKey)
83-
return cacheEntry?.value || null
84-
} catch {
51+
return await redis.get(key)
52+
} catch (error) {
53+
logger.error('Error getting OTP from Redis:', error)
8554
return null
8655
}
8756
}
8857

89-
// Delete OTP from Redis
9058
async function deleteOTP(email: string, chatId: string): Promise<void> {
9159
const key = `otp:${email}:${chatId}`
9260
const redis = getRedisClient()
9361

94-
if (redis) {
95-
// Use Redis if available
62+
if (!redis) {
63+
return
64+
}
65+
66+
try {
9667
await redis.del(key)
97-
} else {
98-
// Use the existing function as fallback
99-
await releaseLock(`processed:${key}`)
100-
await releaseLock(`processed:${key}:value`)
68+
} catch (error) {
69+
logger.error('Error deleting OTP from Redis:', error)
10170
}
10271
}
10372

@@ -177,7 +146,17 @@ export async function POST(
177146

178147
const otp = generateOTP()
179148

180-
await storeOTP(email, deployment.id, otp)
149+
const stored = await storeOTP(email, deployment.id, otp)
150+
if (!stored) {
151+
logger.error(`[${requestId}] Failed to store OTP - Redis unavailable`)
152+
return addCorsHeaders(
153+
createErrorResponse(
154+
'Email verification temporarily unavailable, please try again later',
155+
503
156+
),
157+
request
158+
)
159+
}
181160

182161
const emailHtml = await renderOTPEmail(
183162
otp,

0 commit comments

Comments
 (0)