Switch to a system where you can use either a verifyCode or a captcha token for any endpoint with one or the other
This commit is contained in:
23
src/index.ts
23
src/index.ts
@@ -585,10 +585,11 @@ app.post(
|
|||||||
tags: ['Accounts']
|
tags: ['Accounts']
|
||||||
},
|
},
|
||||||
body: t.Object({
|
body: t.Object({
|
||||||
|
token: t.Optional(t.String()),
|
||||||
|
verifyCode: t.Optional(t.String()),
|
||||||
username: t.String(),
|
username: t.String(),
|
||||||
password: t.String(),
|
password: t.String(),
|
||||||
email: t.String(),
|
email: t.String()
|
||||||
verifyCode: t.String()
|
|
||||||
}),
|
}),
|
||||||
headers: t.Object({
|
headers: t.Object({
|
||||||
'x-forwarded-for': t.Optional(
|
'x-forwarded-for': t.Optional(
|
||||||
@@ -654,8 +655,9 @@ app.post('/account/forgot-username', accountForgotUsernamePostHandler, {
|
|||||||
tags: ['Accounts']
|
tags: ['Accounts']
|
||||||
},
|
},
|
||||||
body: t.Object({
|
body: t.Object({
|
||||||
email: t.String(),
|
token: t.Optional(t.String()),
|
||||||
verifyCode: t.String()
|
verifyCode: t.Optional(t.String()),
|
||||||
|
email: t.String()
|
||||||
}),
|
}),
|
||||||
headers: t.Object({
|
headers: t.Object({
|
||||||
'x-forwarded-for': t.Optional(
|
'x-forwarded-for': t.Optional(
|
||||||
@@ -671,8 +673,9 @@ app.post('/account/forgot-password', accountForgotPasswordPostHandler, {
|
|||||||
tags: ['Accounts']
|
tags: ['Accounts']
|
||||||
},
|
},
|
||||||
body: t.Object({
|
body: t.Object({
|
||||||
email: t.String(),
|
token: t.Optional(t.String()),
|
||||||
verifyCode: t.String()
|
verifyCode: t.Optional(t.String()),
|
||||||
|
email: t.String()
|
||||||
}),
|
}),
|
||||||
headers: t.Object({
|
headers: t.Object({
|
||||||
'x-forwarded-for': t.Optional(
|
'x-forwarded-for': t.Optional(
|
||||||
@@ -687,7 +690,8 @@ app.post('/account/reset-password', accountResetPasswordPostHandler, {
|
|||||||
hide: true
|
hide: true
|
||||||
},
|
},
|
||||||
body: t.Object({
|
body: t.Object({
|
||||||
token: t.String(),
|
token: t.Optional(t.String()),
|
||||||
|
verifyCode: t.Optional(t.String()),
|
||||||
code: t.String(),
|
code: t.String(),
|
||||||
password: t.String()
|
password: t.String()
|
||||||
}),
|
}),
|
||||||
@@ -1087,8 +1091,8 @@ app.post(
|
|||||||
tags: ['Berry Dash', 'Icon Marketplace']
|
tags: ['Berry Dash', 'Icon Marketplace']
|
||||||
},
|
},
|
||||||
body: t.Object({
|
body: t.Object({
|
||||||
verifyCode: t.Optional(t.String()),
|
|
||||||
token: t.Optional(t.String()),
|
token: t.Optional(t.String()),
|
||||||
|
verifyCode: t.Optional(t.String()),
|
||||||
price: t.String(),
|
price: t.String(),
|
||||||
name: t.String(),
|
name: t.String(),
|
||||||
fileContent: t.String()
|
fileContent: t.String()
|
||||||
@@ -1233,7 +1237,8 @@ app.post('/berrydash/splash-text', berryDashSplashTextPostHandler, {
|
|||||||
hide: true
|
hide: true
|
||||||
},
|
},
|
||||||
body: t.Object({
|
body: t.Object({
|
||||||
token: t.String(),
|
token: t.Optional(t.String()),
|
||||||
|
verifyCode: t.Optional(t.String()),
|
||||||
content: t.String()
|
content: t.String()
|
||||||
}),
|
}),
|
||||||
headers: t.Object({
|
headers: t.Object({
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import mysql from 'mysql2'
|
import mysql from 'mysql2'
|
||||||
import { drizzle } from 'drizzle-orm/mysql2'
|
import { drizzle, MySql2Database } from 'drizzle-orm/mysql2'
|
||||||
import {
|
import {
|
||||||
allowedDatabaseVersions,
|
allowedDatabaseVersions,
|
||||||
allowedVersions,
|
allowedVersions,
|
||||||
@@ -11,6 +11,8 @@ import axios from 'axios'
|
|||||||
import FormData from 'form-data'
|
import FormData from 'form-data'
|
||||||
import nodemailer from 'nodemailer'
|
import nodemailer from 'nodemailer'
|
||||||
import { createHash } from 'crypto'
|
import { createHash } from 'crypto'
|
||||||
|
import { and, eq, sql } from 'drizzle-orm'
|
||||||
|
import { verifyCodes } from './tables'
|
||||||
|
|
||||||
export function jsonResponse (data: any, status = 200) {
|
export function jsonResponse (data: any, status = 200) {
|
||||||
return new Response(JSON.stringify(data, null, 2), {
|
return new Response(JSON.stringify(data, null, 2), {
|
||||||
@@ -123,7 +125,57 @@ export const validateTurnstile = async (token: string, remoteip: string) => {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
return response.data
|
return response.data.success
|
||||||
|
}
|
||||||
|
|
||||||
|
export const validateVerifyCode = async (
|
||||||
|
db0: MySql2Database,
|
||||||
|
ip: string,
|
||||||
|
verifyCode: string
|
||||||
|
): Promise<boolean> => {
|
||||||
|
const time = Math.floor(Date.now() / 1000)
|
||||||
|
const codeExists = await db0
|
||||||
|
.select({ id: verifyCodes.id })
|
||||||
|
.from(verifyCodes)
|
||||||
|
.where(
|
||||||
|
and(
|
||||||
|
eq(verifyCodes.ip, ip),
|
||||||
|
eq(verifyCodes.usedTimestamp, 0),
|
||||||
|
eq(verifyCodes.code, verifyCode),
|
||||||
|
sql`${verifyCodes.timestamp} >= UNIX_TIMESTAMP() - 600`
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.limit(1)
|
||||||
|
.execute()
|
||||||
|
if (codeExists[0]) {
|
||||||
|
await db0
|
||||||
|
.update(verifyCodes)
|
||||||
|
.set({ usedTimestamp: time })
|
||||||
|
.where(
|
||||||
|
and(
|
||||||
|
eq(verifyCodes.id, codeExists[0].id),
|
||||||
|
eq(verifyCodes.ip, ip),
|
||||||
|
eq(verifyCodes.usedTimestamp, 0),
|
||||||
|
eq(verifyCodes.code, verifyCode)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.execute()
|
||||||
|
return true
|
||||||
|
} else return false
|
||||||
|
}
|
||||||
|
|
||||||
|
export const verifyTurstileOrVerifyCode = (
|
||||||
|
token: string | null,
|
||||||
|
verifyCode: string | null,
|
||||||
|
ip: string,
|
||||||
|
db0: MySql2Database
|
||||||
|
) => {
|
||||||
|
if (token != null) {
|
||||||
|
return validateTurnstile(token, ip)
|
||||||
|
} else if (verifyCode != null) {
|
||||||
|
return validateVerifyCode(db0, ip, verifyCode)
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
export const sendEmail = async (to: string, title: string, body: string) => {
|
export const sendEmail = async (to: string, title: string, body: string) => {
|
||||||
|
|||||||
@@ -3,16 +3,18 @@ import {
|
|||||||
getClientIp,
|
getClientIp,
|
||||||
getDatabaseConnection,
|
getDatabaseConnection,
|
||||||
jsonResponse,
|
jsonResponse,
|
||||||
sendEmail
|
sendEmail,
|
||||||
|
verifyTurstileOrVerifyCode
|
||||||
} from '../../../lib/util'
|
} from '../../../lib/util'
|
||||||
import { resetCodes, users, verifyCodes } from '../../../lib/tables'
|
import { resetCodes, users } from '../../../lib/tables'
|
||||||
import { and, desc, eq, sql } from 'drizzle-orm'
|
import { and, desc, eq, sql } from 'drizzle-orm'
|
||||||
import isEmail from 'validator/lib/isEmail'
|
import isEmail from 'validator/lib/isEmail'
|
||||||
import { randomBytes } from 'crypto'
|
import { randomBytes } from 'crypto'
|
||||||
|
|
||||||
type Body = {
|
type Body = {
|
||||||
|
token: string | null
|
||||||
|
verifyCode: string | null
|
||||||
email: string
|
email: string
|
||||||
verifyCode: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function handler (context: Context) {
|
export async function handler (context: Context) {
|
||||||
@@ -58,38 +60,14 @@ export async function handler (context: Context) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
const time = Math.floor(Date.now() / 1000)
|
const time = Math.floor(Date.now() / 1000)
|
||||||
const codeExists = await db0
|
if (!(await verifyTurstileOrVerifyCode(body.token, body.verifyCode, ip, db0)))
|
||||||
.select({ id: verifyCodes.id })
|
|
||||||
.from(verifyCodes)
|
|
||||||
.where(
|
|
||||||
and(
|
|
||||||
eq(verifyCodes.ip, ip),
|
|
||||||
eq(verifyCodes.usedTimestamp, 0),
|
|
||||||
eq(verifyCodes.code, body.verifyCode),
|
|
||||||
sql`${verifyCodes.timestamp} >= UNIX_TIMESTAMP() - 600`
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.orderBy(desc(verifyCodes.id))
|
|
||||||
.limit(1)
|
|
||||||
.execute()
|
|
||||||
if (codeExists[0]) {
|
|
||||||
await db0
|
|
||||||
.update(verifyCodes)
|
|
||||||
.set({ usedTimestamp: time })
|
|
||||||
.where(
|
|
||||||
and(
|
|
||||||
eq(verifyCodes.id, codeExists[0].id),
|
|
||||||
eq(verifyCodes.ip, ip),
|
|
||||||
eq(verifyCodes.usedTimestamp, 0),
|
|
||||||
eq(verifyCodes.code, body.verifyCode)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.execute()
|
|
||||||
} else
|
|
||||||
return jsonResponse(
|
return jsonResponse(
|
||||||
{
|
{
|
||||||
success: false,
|
success: false,
|
||||||
message: 'Invalid verify code (codes can only be used once)'
|
message:
|
||||||
|
body.token != null
|
||||||
|
? 'Invalid captcha token'
|
||||||
|
: 'Invalid verify code (codes can only be used once)'
|
||||||
},
|
},
|
||||||
400
|
400
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -3,15 +3,17 @@ import {
|
|||||||
getClientIp,
|
getClientIp,
|
||||||
getDatabaseConnection,
|
getDatabaseConnection,
|
||||||
jsonResponse,
|
jsonResponse,
|
||||||
sendEmail
|
sendEmail,
|
||||||
|
verifyTurstileOrVerifyCode
|
||||||
} from '../../../lib/util'
|
} from '../../../lib/util'
|
||||||
import { users, verifyCodes } from '../../../lib/tables'
|
|
||||||
import { and, desc, eq, sql } from 'drizzle-orm'
|
|
||||||
import isEmail from 'validator/lib/isEmail'
|
import isEmail from 'validator/lib/isEmail'
|
||||||
|
import { users } from '../../../lib/tables'
|
||||||
|
import { eq } from 'drizzle-orm'
|
||||||
|
|
||||||
type Body = {
|
type Body = {
|
||||||
|
token: string | null
|
||||||
|
verifyCode: string | null
|
||||||
email: string
|
email: string
|
||||||
verifyCode: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function handler (context: Context) {
|
export async function handler (context: Context) {
|
||||||
@@ -57,38 +59,14 @@ export async function handler (context: Context) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
const time = Math.floor(Date.now() / 1000)
|
const time = Math.floor(Date.now() / 1000)
|
||||||
const codeExists = await db0
|
if (!(await verifyTurstileOrVerifyCode(body.token, body.verifyCode, ip, db0)))
|
||||||
.select({ id: verifyCodes.id })
|
|
||||||
.from(verifyCodes)
|
|
||||||
.where(
|
|
||||||
and(
|
|
||||||
eq(verifyCodes.ip, ip),
|
|
||||||
eq(verifyCodes.usedTimestamp, 0),
|
|
||||||
eq(verifyCodes.code, body.verifyCode),
|
|
||||||
sql`${verifyCodes.timestamp} >= UNIX_TIMESTAMP() - 600`
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.orderBy(desc(verifyCodes.id))
|
|
||||||
.limit(1)
|
|
||||||
.execute()
|
|
||||||
if (codeExists[0]) {
|
|
||||||
await db0
|
|
||||||
.update(verifyCodes)
|
|
||||||
.set({ usedTimestamp: time })
|
|
||||||
.where(
|
|
||||||
and(
|
|
||||||
eq(verifyCodes.id, codeExists[0].id),
|
|
||||||
eq(verifyCodes.ip, ip),
|
|
||||||
eq(verifyCodes.usedTimestamp, 0),
|
|
||||||
eq(verifyCodes.code, body.verifyCode)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.execute()
|
|
||||||
} else
|
|
||||||
return jsonResponse(
|
return jsonResponse(
|
||||||
{
|
{
|
||||||
success: false,
|
success: false,
|
||||||
message: 'Invalid verify code (codes can only be used once)'
|
message:
|
||||||
|
body.token != null
|
||||||
|
? 'Invalid captcha token'
|
||||||
|
: 'Invalid verify code (codes can only be used once)'
|
||||||
},
|
},
|
||||||
400
|
400
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,19 +2,20 @@ import { Context } from 'elysia'
|
|||||||
import {
|
import {
|
||||||
getClientIp,
|
getClientIp,
|
||||||
getDatabaseConnection,
|
getDatabaseConnection,
|
||||||
jsonResponse
|
jsonResponse,
|
||||||
|
verifyTurstileOrVerifyCode
|
||||||
} from '../../../lib/util'
|
} from '../../../lib/util'
|
||||||
import isEmail from 'validator/lib/isEmail'
|
import isEmail from 'validator/lib/isEmail'
|
||||||
import { berryDashUserData, users, verifyCodes } from '../../../lib/tables'
|
import { berryDashUserData, users } from '../../../lib/tables'
|
||||||
import { and, desc, eq, sql } from 'drizzle-orm'
|
|
||||||
import bcrypt from 'bcryptjs'
|
import bcrypt from 'bcryptjs'
|
||||||
import { randomBytes } from 'crypto'
|
import { randomBytes } from 'crypto'
|
||||||
|
|
||||||
type Body = {
|
type Body = {
|
||||||
|
token: string | null
|
||||||
|
verifyCode: string | null
|
||||||
username: string
|
username: string
|
||||||
password: string
|
password: string
|
||||||
email: string
|
email: string
|
||||||
verifyCode: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function handler (context: Context) {
|
export async function handler (context: Context) {
|
||||||
@@ -65,37 +66,14 @@ export async function handler (context: Context) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
const time = Math.floor(Date.now() / 1000)
|
const time = Math.floor(Date.now() / 1000)
|
||||||
const codeExists = await db0
|
if (!(await verifyTurstileOrVerifyCode(body.token, body.verifyCode, ip, db0)))
|
||||||
.select({ id: verifyCodes.id })
|
|
||||||
.from(verifyCodes)
|
|
||||||
.where(
|
|
||||||
and(
|
|
||||||
eq(verifyCodes.ip, ip),
|
|
||||||
eq(verifyCodes.usedTimestamp, 0),
|
|
||||||
eq(verifyCodes.code, body.verifyCode),
|
|
||||||
sql`${verifyCodes.timestamp} >= UNIX_TIMESTAMP() - 600`
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.orderBy(desc(verifyCodes.id))
|
|
||||||
.limit(1)
|
|
||||||
.execute()
|
|
||||||
if (codeExists[0]) {
|
|
||||||
await db0
|
|
||||||
.update(verifyCodes)
|
|
||||||
.set({ usedTimestamp: time })
|
|
||||||
.where(
|
|
||||||
and(
|
|
||||||
eq(verifyCodes.id, codeExists[0].id),
|
|
||||||
eq(verifyCodes.ip, ip),
|
|
||||||
eq(verifyCodes.usedTimestamp, 0),
|
|
||||||
eq(verifyCodes.code, body.verifyCode)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
} else
|
|
||||||
return jsonResponse(
|
return jsonResponse(
|
||||||
{
|
{
|
||||||
success: false,
|
success: false,
|
||||||
message: 'Invalid verify code (codes can only be used once)'
|
message:
|
||||||
|
body.token != null
|
||||||
|
? 'Invalid captcha token'
|
||||||
|
: 'Invalid verify code (codes can only be used once)'
|
||||||
},
|
},
|
||||||
400
|
400
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -3,14 +3,15 @@ import {
|
|||||||
getClientIp,
|
getClientIp,
|
||||||
getDatabaseConnection,
|
getDatabaseConnection,
|
||||||
jsonResponse,
|
jsonResponse,
|
||||||
validateTurnstile
|
verifyTurstileOrVerifyCode
|
||||||
} from '../../../lib/util'
|
} from '../../../lib/util'
|
||||||
import { resetCodes, users } from '../../../lib/tables'
|
import { resetCodes, users } from '../../../lib/tables'
|
||||||
import { and, desc, eq, sql } from 'drizzle-orm'
|
import { and, desc, eq, sql } from 'drizzle-orm'
|
||||||
import bcrypt from 'bcryptjs'
|
import bcrypt from 'bcryptjs'
|
||||||
|
|
||||||
type Body = {
|
type Body = {
|
||||||
token: string
|
token: string | null
|
||||||
|
verifyCode: string | null
|
||||||
code: string
|
code: string
|
||||||
password: string
|
password: string
|
||||||
}
|
}
|
||||||
@@ -58,17 +59,17 @@ export async function handler (context: Context) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await validateTurnstile(body.token, ip)
|
if (!(await verifyTurstileOrVerifyCode(body.token, body.verifyCode, ip, db0)))
|
||||||
if (!result.success) {
|
|
||||||
connection0.end()
|
|
||||||
return jsonResponse(
|
return jsonResponse(
|
||||||
{
|
{
|
||||||
success: false,
|
success: false,
|
||||||
message: 'Unable to verify captcha key'
|
message:
|
||||||
|
body.token != null
|
||||||
|
? 'Invalid captcha token'
|
||||||
|
: 'Invalid verify code (codes can only be used once)'
|
||||||
},
|
},
|
||||||
400
|
400
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
const time = Math.floor(Date.now() / 1000)
|
const time = Math.floor(Date.now() / 1000)
|
||||||
const codeExists = await db0
|
const codeExists = await db0
|
||||||
|
|||||||
@@ -4,18 +4,17 @@ import {
|
|||||||
getDatabaseConnection,
|
getDatabaseConnection,
|
||||||
hash,
|
hash,
|
||||||
jsonResponse,
|
jsonResponse,
|
||||||
validateTurnstile
|
verifyTurstileOrVerifyCode
|
||||||
} from '../../../../lib/util'
|
} from '../../../../lib/util'
|
||||||
import { checkAuthorization } from '../../../../lib/auth'
|
import { checkAuthorization } from '../../../../lib/auth'
|
||||||
import { berryDashMarketplaceIcons, verifyCodes } from '../../../../lib/tables'
|
import { berryDashMarketplaceIcons } from '../../../../lib/tables'
|
||||||
import { and, desc, eq, sql } from 'drizzle-orm'
|
|
||||||
import { Buffer } from 'buffer'
|
import { Buffer } from 'buffer'
|
||||||
import sizeOf from 'image-size'
|
import sizeOf from 'image-size'
|
||||||
import { Connection } from 'mysql2/typings/mysql/lib/Connection'
|
import { Connection } from 'mysql2/typings/mysql/lib/Connection'
|
||||||
|
|
||||||
type Body = {
|
type Body = {
|
||||||
verifyCode: string
|
token: string | null
|
||||||
token: string
|
verifyCode: string | null
|
||||||
price: string
|
price: string
|
||||||
name: string
|
name: string
|
||||||
fileContent: string
|
fileContent: string
|
||||||
@@ -136,55 +135,17 @@ export async function handler (context: Context) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
const time = Math.floor(Date.now() / 1000)
|
const time = Math.floor(Date.now() / 1000)
|
||||||
if (body.verifyCode) {
|
if (!(await verifyTurstileOrVerifyCode(body.token, body.verifyCode, ip, db0)))
|
||||||
const codeExists = await db0
|
|
||||||
.select({ id: verifyCodes.id })
|
|
||||||
.from(verifyCodes)
|
|
||||||
.where(
|
|
||||||
and(
|
|
||||||
eq(verifyCodes.ip, ip),
|
|
||||||
eq(verifyCodes.usedTimestamp, 0),
|
|
||||||
eq(verifyCodes.code, body.verifyCode),
|
|
||||||
sql`${verifyCodes.timestamp} >= UNIX_TIMESTAMP() - 600`
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.orderBy(desc(verifyCodes.id))
|
|
||||||
.limit(1)
|
|
||||||
.execute()
|
|
||||||
if (codeExists[0]) {
|
|
||||||
await db0
|
|
||||||
.update(verifyCodes)
|
|
||||||
.set({ usedTimestamp: time })
|
|
||||||
.where(
|
|
||||||
and(
|
|
||||||
eq(verifyCodes.id, codeExists[0].id),
|
|
||||||
eq(verifyCodes.ip, ip),
|
|
||||||
eq(verifyCodes.usedTimestamp, 0),
|
|
||||||
eq(verifyCodes.code, body.verifyCode)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.execute()
|
|
||||||
} else
|
|
||||||
return jsonResponse(
|
return jsonResponse(
|
||||||
{
|
{
|
||||||
success: false,
|
success: false,
|
||||||
message: 'Invalid verify code (codes can only be used once)'
|
message:
|
||||||
|
body.token != null
|
||||||
|
? 'Invalid captcha token'
|
||||||
|
: 'Invalid verify code (codes can only be used once)'
|
||||||
},
|
},
|
||||||
400
|
400
|
||||||
)
|
)
|
||||||
} else {
|
|
||||||
const result = await validateTurnstile(body.token, ip)
|
|
||||||
if (!result.success) {
|
|
||||||
connection0.end()
|
|
||||||
return jsonResponse(
|
|
||||||
{
|
|
||||||
success: false,
|
|
||||||
message: 'Unable to verify captcha key'
|
|
||||||
},
|
|
||||||
400
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const hashResult = hash(atob(body.fileContent), 'sha512')
|
const hashResult = hash(atob(body.fileContent), 'sha512')
|
||||||
const id = crypto.randomUUID()
|
const id = crypto.randomUUID()
|
||||||
|
|||||||
@@ -3,14 +3,15 @@ import {
|
|||||||
getClientIp,
|
getClientIp,
|
||||||
getDatabaseConnection,
|
getDatabaseConnection,
|
||||||
jsonResponse,
|
jsonResponse,
|
||||||
validateTurnstile
|
verifyTurstileOrVerifyCode
|
||||||
} from '../../../lib/util'
|
} from '../../../lib/util'
|
||||||
import { checkAuthorization } from '../../../lib/auth'
|
import { checkAuthorization } from '../../../lib/auth'
|
||||||
import { berryDashSplashTexts } from '../../../lib/tables'
|
import { berryDashSplashTexts } from '../../../lib/tables'
|
||||||
import { eq } from 'drizzle-orm'
|
import { eq } from 'drizzle-orm'
|
||||||
|
|
||||||
type Body = {
|
type Body = {
|
||||||
token: string
|
token: string | null
|
||||||
|
verifyCode: string | null
|
||||||
content: string
|
content: string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,18 +108,17 @@ export async function handler (context: Context) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await validateTurnstile(body.token, ip)
|
if (!(await verifyTurstileOrVerifyCode(body.token, body.verifyCode, ip, db0)))
|
||||||
if (!result.success) {
|
|
||||||
connection0.end()
|
|
||||||
connection1.end()
|
|
||||||
return jsonResponse(
|
return jsonResponse(
|
||||||
{
|
{
|
||||||
success: false,
|
success: false,
|
||||||
message: 'Unable to verify captcha key'
|
message:
|
||||||
|
body.token != null
|
||||||
|
? 'Invalid captcha token'
|
||||||
|
: 'Invalid verify code (codes can only be used once)'
|
||||||
},
|
},
|
||||||
400
|
400
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
const time = Math.floor(Date.now() / 1000)
|
const time = Math.floor(Date.now() / 1000)
|
||||||
await db1
|
await db1
|
||||||
|
|||||||
Reference in New Issue
Block a user