페이지 형식 선택과 접속 IP 기록 수정 v1.5.7
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { randomBytes } from 'node:crypto'
|
||||
import { z } from 'zod'
|
||||
import { createError, getRequestIP, readBody } from 'h3'
|
||||
import { createError, readBody } from 'h3'
|
||||
import { getPostgresClient } from '../../../repositories/postgres-client'
|
||||
import { getMemberBootstrapState, getUserByEmail } from '../../../repositories/member-repository'
|
||||
import {
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
import { generateSixDigitOtp, hashOtpCode, normalizeOtpEmail } from '../../../utils/email-otp'
|
||||
import { isResendConfigured, sendResendEmail } from '../../../utils/resend-mail'
|
||||
import { getRuntimeEnvValue } from '../../../utils/runtime-env'
|
||||
import { getClientIp } from '../../../utils/request-ip'
|
||||
|
||||
const bodySchema = z.object({
|
||||
email: z.string().trim().email(),
|
||||
@@ -113,7 +114,7 @@ export default defineEventHandler(async (event) => {
|
||||
if (!user) {
|
||||
const dummyHash = randomBytes(32).toString('hex')
|
||||
const expiresAt = new Date(Date.now() + OTP_TTL_MS)
|
||||
const createdIp = String(getRequestIP(event) || '')
|
||||
const createdIp = getClientIp(event)
|
||||
await invalidatePendingOtpChallenges(sql, email, purpose)
|
||||
await insertOtpChallenge(sql, {
|
||||
email,
|
||||
@@ -130,7 +131,7 @@ export default defineEventHandler(async (event) => {
|
||||
const code = generateSixDigitOtp()
|
||||
const codeHash = hashOtpCode({ pepper, email, purpose, code })
|
||||
const expiresAt = new Date(Date.now() + OTP_TTL_MS)
|
||||
const createdIp = String(getRequestIP(event) || '')
|
||||
const createdIp = getClientIp(event)
|
||||
|
||||
const challengeId = await insertOtpChallenge(sql, {
|
||||
email,
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import bcrypt from 'bcrypt'
|
||||
import { z } from 'zod'
|
||||
import { createError, getRequestIP, readBody } from 'h3'
|
||||
import { createError, readBody } from 'h3'
|
||||
import { getUserByEmail, touchUserActivity } from '../../repositories/member-repository'
|
||||
import { setMemberSession } from '../../utils/member-auth'
|
||||
import { getClientIp } from '../../utils/request-ip'
|
||||
|
||||
const loginSchema = z.object({
|
||||
email: z.string().trim().email(),
|
||||
@@ -38,7 +39,7 @@ export default defineEventHandler(async (event) => {
|
||||
setMemberSession(event, { userId: user.id, email: user.email })
|
||||
await touchUserActivity({
|
||||
userId: user.id,
|
||||
ip: String(getRequestIP(event) || '')
|
||||
ip: getClientIp(event)
|
||||
})
|
||||
|
||||
return {
|
||||
@@ -48,4 +49,3 @@ export default defineEventHandler(async (event) => {
|
||||
avatarUrl: user.avatarUrl || ''
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import bcrypt from 'bcrypt'
|
||||
import { z } from 'zod'
|
||||
import { createError, getRequestIP, readBody } from 'h3'
|
||||
import { createError, readBody } from 'h3'
|
||||
import { createUser, getUserByEmail, getMemberBootstrapState, isUsernameTaken, touchUserActivity } from '../../repositories/member-repository'
|
||||
import { verifyAndConsumeEmailOtp } from '../../repositories/email-otp-repository'
|
||||
import { setMemberSession } from '../../utils/member-auth'
|
||||
@@ -8,6 +8,7 @@ import { setAdminSession } from '../../utils/admin-auth'
|
||||
import { isResendConfigured } from '../../utils/resend-mail'
|
||||
import { getRuntimeEnvValue } from '../../utils/runtime-env'
|
||||
import { assertSignupUsernameAllowed } from '../../utils/member-username-policy'
|
||||
import { getClientIp } from '../../utils/request-ip'
|
||||
|
||||
const signupSchema = z.object({
|
||||
username: z.string().trim().min(1),
|
||||
@@ -112,7 +113,7 @@ export default defineEventHandler(async (event) => {
|
||||
}
|
||||
await touchUserActivity({
|
||||
userId: created.id,
|
||||
ip: String(getRequestIP(event) || '')
|
||||
ip: getClientIp(event)
|
||||
})
|
||||
|
||||
return {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { createError, getRequestIP, readBody } from 'h3'
|
||||
import { createError, readBody } from 'h3'
|
||||
import { z } from 'zod'
|
||||
import { createComment } from '../../../repositories/comment-repository'
|
||||
import { touchUserActivity } from '../../../repositories/member-repository'
|
||||
import { requireMemberSession } from '../../../utils/member-auth'
|
||||
import { getClientIp } from '../../../utils/request-ip'
|
||||
|
||||
const createCommentSchema = z.object({
|
||||
body: z.string().trim().min(1).max(5000),
|
||||
@@ -34,11 +35,10 @@ export default defineEventHandler(async (event) => {
|
||||
})
|
||||
await touchUserActivity({
|
||||
userId: session.userId,
|
||||
ip: String(getRequestIP(event) || '')
|
||||
ip: getClientIp(event)
|
||||
})
|
||||
|
||||
return {
|
||||
comment
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { getRequestIP } from 'h3'
|
||||
import { toggleCommentLike } from '../../../../../repositories/comment-repository'
|
||||
import { touchUserActivity } from '../../../../../repositories/member-repository'
|
||||
import { requireMemberSession } from '../../../../../utils/member-auth'
|
||||
import { getClientIp } from '../../../../../utils/request-ip'
|
||||
|
||||
/**
|
||||
* 댓글 좋아요 토글 API
|
||||
@@ -21,7 +21,7 @@ export default defineEventHandler(async (event) => {
|
||||
|
||||
await touchUserActivity({
|
||||
userId: session.userId,
|
||||
ip: String(getRequestIP(event) || '')
|
||||
ip: getClientIp(event)
|
||||
})
|
||||
|
||||
return result
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { z } from 'zod'
|
||||
import { createError, getRequestIP, readBody } from 'h3'
|
||||
import { createError, readBody } from 'h3'
|
||||
import bcrypt from 'bcrypt'
|
||||
import { safeCompare, setAdminSession } from '../../../../utils/admin-auth'
|
||||
import { getAdminUserByEmail, getMemberBootstrapState, touchUserActivity, upsertBootstrapOwner } from '../../../../repositories/member-repository'
|
||||
import { setMemberSession } from '../../../../utils/member-auth'
|
||||
import { getRuntimeEnvValue } from '../../../../utils/runtime-env'
|
||||
import { getClientIp } from '../../../../utils/request-ip'
|
||||
|
||||
const loginSchema = z.object({
|
||||
email: z.string().email(),
|
||||
@@ -86,7 +87,7 @@ export default defineEventHandler(async (event) => {
|
||||
})
|
||||
await touchUserActivity({
|
||||
userId: adminUser.id,
|
||||
ip: String(getRequestIP(event) || '')
|
||||
ip: getClientIp(event)
|
||||
})
|
||||
|
||||
return {
|
||||
|
||||
8
server/utils/request-ip.js
Normal file
8
server/utils/request-ip.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import { getRequestIP } from 'h3'
|
||||
|
||||
/**
|
||||
* 프록시 헤더를 포함해 요청 IP를 조회한다.
|
||||
* @param {import('h3').H3Event} event - 요청 이벤트
|
||||
* @returns {string} 요청 IP
|
||||
*/
|
||||
export const getClientIp = (event) => String(getRequestIP(event, { xForwardedFor: true }) || '')
|
||||
Reference in New Issue
Block a user