From 6f0978c8abdb68717c7890a0191df3551475a3a2 Mon Sep 17 00:00:00 2001 From: Baozier Date: Wed, 4 Sep 2024 21:06:07 -0400 Subject: [PATCH] Add function to get ip for node based server (#139) --- server/src/dtos/app.ts | 4 +-- server/src/dtos/identity.ts | 4 +-- server/src/handlers/identity.tsx | 22 ++++++------ server/src/handlers/oauth.ts | 4 +-- server/src/middlewares/setup.ts | 4 +-- server/src/models/app.ts | 15 ++++---- server/src/models/appScope.ts | 14 ++++---- server/src/models/role.ts | 15 ++++---- server/src/models/scope.ts | 15 ++++---- server/src/models/scopeLocale.ts | 11 +++--- server/src/models/user.ts | 21 +++++------- server/src/models/userAppConsent.ts | 11 +++--- server/src/models/userRole.ts | 15 ++++---- server/src/services/app.ts | 4 +-- server/src/services/kv.ts | 14 ++++---- server/src/services/scope.ts | 4 +-- server/src/services/user.ts | 4 +-- server/src/templates/EmailVerification.tsx | 4 +-- server/src/utils/{format.ts => db.ts} | 30 +++++++--------- server/src/utils/index.ts | 3 +- server/src/utils/request.ts | 40 ++++++++++++++++++++++ server/src/utils/validate.ts | 15 +------- 22 files changed, 137 insertions(+), 136 deletions(-) rename server/src/utils/{format.ts => db.ts} (80%) create mode 100644 server/src/utils/request.ts diff --git a/server/src/dtos/app.ts b/server/src/dtos/app.ts index 1784e34e..876cd8ee 100644 --- a/server/src/dtos/app.ts +++ b/server/src/dtos/app.ts @@ -4,10 +4,10 @@ import { IsNotEmpty, IsOptional, IsString, IsUrl, Length, } from 'class-validator' import { ClientType } from 'shared' -import { formatUtil } from 'utils' +import { requestUtil } from 'utils' const formatRedirectUri = (redirectUris: string[]) => redirectUris - .map((uri) => formatUtil.stripEndingSlash(uri.trim().toLowerCase())) + .map((uri) => requestUtil.stripEndingSlash(uri.trim().toLowerCase())) export class PostAppReqDto { @IsString() diff --git a/server/src/dtos/identity.ts b/server/src/dtos/identity.ts index eb2f8128..407f89f1 100644 --- a/server/src/dtos/identity.ts +++ b/server/src/dtos/identity.ts @@ -5,7 +5,7 @@ import { Context } from 'hono' import { typeConfig } from 'configs' import { oauthDto } from 'dtos' import { - formatUtil, validateUtil, + requestUtil, validateUtil, } from 'utils' import { userModel } from 'models' @@ -113,7 +113,7 @@ export const parseGetAuthorizeFollowUpReq = async (c: Context) => { GOOGLE_AUTH_CLIENT_ID: googleClientId, } = env(c) - const queryString = formatUtil.getQueryString(c) + const queryString = requestUtil.getQueryString(c) return c.html() => { ENABLE_LOCALE_SELECTOR: enableLocaleSelector, } = env(c) const queryDto = await scopeService.parseGetAuthorizeDto(c) - const queryString = formatUtil.getQueryString(c) + const queryString = requestUtil.getQueryString(c) return c.html() => { ? String(reqBody.email).trim() .toLowerCase() : '' - const locale = formatUtil.getLocaleFromQuery( + const locale = requestUtil.getLocaleFromQuery( c, reqBody.locale, ) if (!email) throw new errorConfig.Forbidden() - const ip = c.req.header('cf-connecting-ip') as string + const ip = requestUtil.getRequestIP(c) const resetAttempts = await kvService.getPasswordResetAttemptsByIP( c.env.KV, email, @@ -242,7 +242,7 @@ export const postAuthorizeReset = async (c: Context) => { ) const { UNLOCK_ACCOUNT_VIA_PASSWORD_RESET: allowUnlock } = env(c) - const ip = c.req.header('cf-connecting-ip') as string + const ip = requestUtil.getRequestIP(c) if (allowUnlock) { await kvService.clearFailedLoginAttemptsByIP( c.env.KV, @@ -265,7 +265,7 @@ export const getAuthorizeAccount = async (c: Context) => { ENABLE_LOCALE_SELECTOR: enableLocaleSelector, } = env(c) - const queryString = formatUtil.getQueryString(c) + const queryString = requestUtil.getQueryString(c) return c.html() => { const parsedBody = { ...reqBody, scopes: reqBody.scope.split(' '), - locale: formatUtil.getLocaleFromQuery( + locale: requestUtil.getLocaleFromQuery( c, reqBody.locale, ), @@ -534,7 +534,7 @@ export const postAuthorizeOtpMfa = async (c: Context) => { if (!authCodeStore.user.otpSecret) throw new errorConfig.Forbidden() - const ip = c.req.header('cf-connecting-ip') as string + const ip = requestUtil.getRequestIP(c) const failedAttempts = await kvService.getFailedOtpMfaAttemptsByIP( c.env.KV, authCodeStore.user.id, @@ -759,7 +759,7 @@ export const postAuthorizePassword = async (c: Context) => { export const getVerifyEmail = async (c: Context) => { const queryDto = new identityDto.GetVerifyEmailReqDto({ id: c.req.query('id') ?? '', - locale: formatUtil.getLocaleFromQuery( + locale: requestUtil.getLocaleFromQuery( c, c.req.query('locale'), ), @@ -823,7 +823,7 @@ export const postLogout = async (c: Context) => { } const { AUTH_SERVER_URL } = env(c) - const redirectUri = `${formatUtil.stripEndingSlash(AUTH_SERVER_URL)}${routeConfig.InternalRoute.OAuth}/logout` + const redirectUri = `${requestUtil.stripEndingSlash(AUTH_SERVER_URL)}${routeConfig.InternalRoute.OAuth}/logout` return c.json({ success: true, diff --git a/server/src/handlers/oauth.ts b/server/src/handlers/oauth.ts index 5b3097bc..78605ff6 100644 --- a/server/src/handlers/oauth.ts +++ b/server/src/handlers/oauth.ts @@ -12,7 +12,7 @@ import { appService, consentService, jwtService, kvService, roleService, scopeService, sessionService, userService, } from 'services' import { - cryptoUtil, formatUtil, timeUtil, validateUtil, + cryptoUtil, requestUtil, timeUtil, validateUtil, } from 'utils' import { userModel } from 'models' @@ -62,7 +62,7 @@ export const getAuthorize = async (c: Context) => { return c.redirect(url) } - const queryString = formatUtil.getQueryString(c) + const queryString = requestUtil.getQueryString(c) return c.redirect(`${routeConfig.InternalRoute.Identity}/authorize-password?${queryString}`) } diff --git a/server/src/middlewares/setup.ts b/server/src/middlewares/setup.ts index 4ca22234..ad70703a 100644 --- a/server/src/middlewares/setup.ts +++ b/server/src/middlewares/setup.ts @@ -8,7 +8,7 @@ import { import { errorConfig, localeConfig, typeConfig, } from 'configs' -import { formatUtil } from 'utils' +import { requestUtil } from 'utils' import { kvService } from 'services' const store = new CookieStore() @@ -46,7 +46,7 @@ export const validOrigin = async ( const origin = c.req.header('origin') const { AUTH_SERVER_URL: serverUrl } = env(c) - if (formatUtil.stripEndingSlash(serverUrl) !== origin) { + if (requestUtil.stripEndingSlash(serverUrl) !== origin) { throw new errorConfig.Forbidden(localeConfig.Error.WrongOrigin) } diff --git a/server/src/models/app.ts b/server/src/models/app.ts index 9dc193d0..30690626 100644 --- a/server/src/models/app.ts +++ b/server/src/models/app.ts @@ -2,10 +2,7 @@ import { ClientType } from 'shared' import { adapterConfig, errorConfig, } from 'configs' -import { - formatUtil, - validateUtil, -} from 'utils' +import { dbUtil } from 'utils' export interface Common { id: number; @@ -93,7 +90,7 @@ export const create = async ( create.type, create.redirectUris, ) - const result = await validateUtil.d1Run(stmt) + const result = await dbUtil.d1Run(stmt) if (!result.success) throw new errorConfig.InternalServerError() const id = result.meta.last_row_id const record = await getById( @@ -110,7 +107,7 @@ export const update = async ( const updateKeys: (keyof Update)[] = [ 'name', 'redirectUris', 'isActive', 'deletedAt', 'updatedAt', ] - const stmt = formatUtil.d1UpdateQuery( + const stmt = dbUtil.d1UpdateQuery( db, TableName, id, @@ -118,7 +115,7 @@ export const update = async ( update, ) - const result = await validateUtil.d1Run(stmt) + const result = await dbUtil.d1Run(stmt) if (!result.success) throw new errorConfig.InternalServerError() const record = await getById( db, @@ -131,12 +128,12 @@ export const update = async ( export const remove = async ( db: D1Database, id: number, ): Promise => { - const stmt = formatUtil.d1SoftDeleteQuery( + const stmt = dbUtil.d1SoftDeleteQuery( db, TableName, id, ) - await validateUtil.d1Run(stmt) + await dbUtil.d1Run(stmt) return true } diff --git a/server/src/models/appScope.ts b/server/src/models/appScope.ts index 556b0236..0a0f291a 100644 --- a/server/src/models/appScope.ts +++ b/server/src/models/appScope.ts @@ -1,7 +1,5 @@ import { adapterConfig } from 'configs' -import { - formatUtil, validateUtil, -} from 'utils' +import { dbUtil } from 'utils' export interface Record { id: number; @@ -52,7 +50,7 @@ export const create = async ( create.appId, create.scopeId, ) - const result = await validateUtil.d1Run(stmt) + const result = await dbUtil.d1Run(stmt) return result.success } @@ -62,7 +60,7 @@ export const update = async ( const updateKeys: (keyof Update)[] = [ 'deletedAt', 'updatedAt', ] - const stmt = formatUtil.d1UpdateQuery( + const stmt = dbUtil.d1UpdateQuery( db, TableName, id, @@ -70,20 +68,20 @@ export const update = async ( update, ) - const result = await validateUtil.d1Run(stmt) + const result = await dbUtil.d1Run(stmt) return result.success } export const remove = async ( db: D1Database, scopeId: number, ): Promise => { - const stmt = formatUtil.d1SoftDeleteQuery( + const stmt = dbUtil.d1SoftDeleteQuery( db, TableName, scopeId, 'scopeId', ) - await validateUtil.d1Run(stmt) + await dbUtil.d1Run(stmt) return true } diff --git a/server/src/models/role.ts b/server/src/models/role.ts index 7f1483c7..5776d901 100644 --- a/server/src/models/role.ts +++ b/server/src/models/role.ts @@ -1,10 +1,7 @@ import { adapterConfig, errorConfig, } from 'configs' -import { - formatUtil, - validateUtil, -} from 'utils' +import { dbUtil } from 'utils' export interface Record { id: number; @@ -56,7 +53,7 @@ export const create = async ( create.name, create.note, ) - const result = await validateUtil.d1Run(stmt) + const result = await dbUtil.d1Run(stmt) if (!result.success) throw new errorConfig.InternalServerError() const id = result.meta.last_row_id @@ -74,7 +71,7 @@ export const update = async ( const updateKeys: (keyof Update)[] = [ 'name', 'updatedAt', 'note', ] - const stmt = formatUtil.d1UpdateQuery( + const stmt = dbUtil.d1UpdateQuery( db, TableName, id, @@ -82,7 +79,7 @@ export const update = async ( update, ) - const result = await validateUtil.d1Run(stmt) + const result = await dbUtil.d1Run(stmt) if (!result.success) throw new errorConfig.InternalServerError() const record = await getById( db, @@ -95,12 +92,12 @@ export const update = async ( export const remove = async ( db: D1Database, id: number, ): Promise => { - const stmt = formatUtil.d1SoftDeleteQuery( + const stmt = dbUtil.d1SoftDeleteQuery( db, TableName, id, ) - await validateUtil.d1Run(stmt) + await dbUtil.d1Run(stmt) return true } diff --git a/server/src/models/scope.ts b/server/src/models/scope.ts index da33ffa6..ace55939 100644 --- a/server/src/models/scope.ts +++ b/server/src/models/scope.ts @@ -2,10 +2,7 @@ import { ClientType } from 'shared' import { adapterConfig, errorConfig, } from 'configs' -import { - formatUtil, - validateUtil, -} from 'utils' +import { dbUtil } from 'utils' import { scopeLocaleModel } from 'models' export interface Record { @@ -77,7 +74,7 @@ export const create = async ( create.type, create.note, ) - const result = await validateUtil.d1Run(stmt) + const result = await dbUtil.d1Run(stmt) if (!result.success) throw new errorConfig.InternalServerError() const id = result.meta.last_row_id const record = await getById( @@ -94,7 +91,7 @@ export const update = async ( const updateKeys: (keyof Update)[] = [ 'name', 'deletedAt', 'updatedAt', 'note', ] - const stmt = formatUtil.d1UpdateQuery( + const stmt = dbUtil.d1UpdateQuery( db, TableName, id, @@ -102,7 +99,7 @@ export const update = async ( update, ) - const result = await validateUtil.d1Run(stmt) + const result = await dbUtil.d1Run(stmt) if (!result.success) throw new errorConfig.InternalServerError() const record = await getById( db, @@ -115,12 +112,12 @@ export const update = async ( export const remove = async ( db: D1Database, id: number, ): Promise => { - const stmt = formatUtil.d1SoftDeleteQuery( + const stmt = dbUtil.d1SoftDeleteQuery( db, TableName, id, ) - await validateUtil.d1Run(stmt) + await dbUtil.d1Run(stmt) return true } diff --git a/server/src/models/scopeLocale.ts b/server/src/models/scopeLocale.ts index 9e2668e4..df976b93 100644 --- a/server/src/models/scopeLocale.ts +++ b/server/src/models/scopeLocale.ts @@ -1,10 +1,7 @@ import { adapterConfig, errorConfig, } from 'configs' -import { - formatUtil, - validateUtil, -} from 'utils' +import { dbUtil } from 'utils' export interface Record { id: number; @@ -45,7 +42,7 @@ export const create = async ( create.locale, create.value.trim(), ) - const result = await validateUtil.d1Run(stmt) + const result = await dbUtil.d1Run(stmt) if (!result.success) throw new errorConfig.InternalServerError() const id = result.meta.last_row_id @@ -69,13 +66,13 @@ export const getAllByScope = async ( export const remove = async ( db: D1Database, scopeId: number, ): Promise => { - const stmt = formatUtil.d1SoftDeleteQuery( + const stmt = dbUtil.d1SoftDeleteQuery( db, TableName, scopeId, 'scopeId', ) - await validateUtil.d1Run(stmt) + await dbUtil.d1Run(stmt) return true } diff --git a/server/src/models/user.ts b/server/src/models/user.ts index aeab90c8..03a5666f 100644 --- a/server/src/models/user.ts +++ b/server/src/models/user.ts @@ -2,10 +2,7 @@ import { adapterConfig, errorConfig, typeConfig, } from 'configs' -import { - formatUtil, - validateUtil, -} from 'utils' +import { dbUtil } from 'utils' export enum MfaType { Otp = 'otp', @@ -154,7 +151,7 @@ export const getAll = async ( pagination?: typeConfig.Pagination; }, ): Promise => { - const stmt = formatUtil.d1SelectAllQuery( + const stmt = dbUtil.d1SelectAllQuery( db, TableName, option, @@ -225,13 +222,13 @@ export const create = async ( 'authId', 'email', 'password', 'firstName', 'lastName', 'locale', 'otpSecret', 'googleId', 'emailVerified', ] - const stmt = formatUtil.d1CreateQuery( + const stmt = dbUtil.d1CreateQuery( db, TableName, createKeys, create, ) - const result = await validateUtil.d1Run(stmt) + const result = await dbUtil.d1Run(stmt) if (!result.success) throw new errorConfig.InternalServerError() const id = result.meta.last_row_id const record = await getById( @@ -247,7 +244,7 @@ export const updateCount = async ( ) => { const query = `UPDATE ${TableName} set "loginCount" = "loginCount" + 1 where id = $1` const stmt = db.prepare(query).bind(id) - await validateUtil.d1Run(stmt) + await dbUtil.d1Run(stmt) } export const update = async ( @@ -257,7 +254,7 @@ export const update = async ( 'password', 'firstName', 'lastName', 'deletedAt', 'updatedAt', 'isActive', 'emailVerified', 'loginCount', 'locale', 'otpSecret', 'mfaTypes', 'otpVerified', ] - const stmt = formatUtil.d1UpdateQuery( + const stmt = dbUtil.d1UpdateQuery( db, TableName, id, @@ -265,7 +262,7 @@ export const update = async ( update, ) - const result = await validateUtil.d1Run(stmt) + const result = await dbUtil.d1Run(stmt) if (!result.success) throw new errorConfig.InternalServerError() const record = await getById( db, @@ -278,12 +275,12 @@ export const update = async ( export const remove = async ( db: D1Database, id: number, ): Promise => { - const stmt = formatUtil.d1SoftDeleteQuery( + const stmt = dbUtil.d1SoftDeleteQuery( db, TableName, id, ) - await validateUtil.d1Run(stmt) + await dbUtil.d1Run(stmt) return true } diff --git a/server/src/models/userAppConsent.ts b/server/src/models/userAppConsent.ts index 6949ebc5..86beb0d4 100644 --- a/server/src/models/userAppConsent.ts +++ b/server/src/models/userAppConsent.ts @@ -1,8 +1,7 @@ import { adapterConfig } from 'configs' import { - formatUtil, + dbUtil, timeUtil, - validateUtil, } from 'utils' export interface Record { @@ -38,7 +37,7 @@ export const create = async ( create.userId, create.appId, ) - const result = await validateUtil.d1Run(stmt) + const result = await dbUtil.d1Run(stmt) return result.success } @@ -73,14 +72,14 @@ export const getAllByUser = async ( export const removeByUser = async ( db: D1Database, userId: number, ): Promise => { - const stmt = formatUtil.d1SoftDeleteQuery( + const stmt = dbUtil.d1SoftDeleteQuery( db, TableName, userId, 'userId', ) - await validateUtil.d1Run(stmt) + await dbUtil.d1Run(stmt) return true } @@ -94,6 +93,6 @@ export const removeByUserAndApp = async ( appId, ) - await validateUtil.d1Run(stmt) + await dbUtil.d1Run(stmt) return true } diff --git a/server/src/models/userRole.ts b/server/src/models/userRole.ts index 875d809c..dce5faec 100644 --- a/server/src/models/userRole.ts +++ b/server/src/models/userRole.ts @@ -1,8 +1,5 @@ import { adapterConfig } from 'configs' -import { - formatUtil, - validateUtil, -} from 'utils' +import { dbUtil } from 'utils' export interface Record { id: number; @@ -54,7 +51,7 @@ export const create = async ( create.userId, create.roleId, ) - const result = await validateUtil.d1Run(stmt) + const result = await dbUtil.d1Run(stmt) return result.success } @@ -64,7 +61,7 @@ export const update = async ( const updateKeys: (keyof Update)[] = [ 'deletedAt', 'updatedAt', ] - const stmt = formatUtil.d1UpdateQuery( + const stmt = dbUtil.d1UpdateQuery( db, TableName, id, @@ -72,20 +69,20 @@ export const update = async ( update, ) - const result = await validateUtil.d1Run(stmt) + const result = await dbUtil.d1Run(stmt) return result.success } export const remove = async ( db: D1Database, roleId: number, ): Promise => { - const stmt = formatUtil.d1SoftDeleteQuery( + const stmt = dbUtil.d1SoftDeleteQuery( db, TableName, roleId, 'roleId', ) - await validateUtil.d1Run(stmt) + await dbUtil.d1Run(stmt) return true } diff --git a/server/src/services/app.ts b/server/src/services/app.ts index d8233cdc..29820f4b 100644 --- a/server/src/services/app.ts +++ b/server/src/services/app.ts @@ -8,7 +8,7 @@ import { appModel, appScopeModel, scopeModel, } from 'models' import { - formatUtil, timeUtil, + requestUtil, timeUtil, } from 'utils' import { scopeService } from 'services' import { appDto } from 'dtos' @@ -29,7 +29,7 @@ export const verifySPAClientRequest = async ( if (app.type !== ClientType.SPA) { throw new errorConfig.UnAuthorized(localeConfig.Error.WrongClientType) } - if (!app.redirectUris.includes(formatUtil.stripEndingSlash(redirectUri))) { + if (!app.redirectUris.includes(requestUtil.stripEndingSlash(redirectUri))) { throw new errorConfig.UnAuthorized(localeConfig.Error.WrongRedirectUri) } return app diff --git a/server/src/services/kv.ts b/server/src/services/kv.ts index 0ec5d02a..d64c165b 100644 --- a/server/src/services/kv.ts +++ b/server/src/services/kv.ts @@ -287,7 +287,7 @@ export const verifyPasswordResetCode = async ( export const getPasswordResetAttemptsByIP = async ( kv: KVNamespace, email: string, - ip: string, + ip?: string, ) => { const key = adapterConfig.getKVKey( adapterConfig.BaseKVKey.PasswordResetAttempts, @@ -301,7 +301,7 @@ export const getPasswordResetAttemptsByIP = async ( export const setPasswordResetAttemptsByIP = async ( kv: KVNamespace, email: string, - ip: string, + ip: string | undefined, count: number, ) => { const key = adapterConfig.getKVKey( @@ -319,7 +319,7 @@ export const setPasswordResetAttemptsByIP = async ( export const getFailedOtpMfaAttemptsByIP = async ( kv: KVNamespace, userId: number, - ip: string, + ip?: string, ) => { const key = adapterConfig.getKVKey( adapterConfig.BaseKVKey.FailedOtpMfaAttempts, @@ -333,7 +333,7 @@ export const getFailedOtpMfaAttemptsByIP = async ( export const setFailedOtpMfaAttempts = async ( kv: KVNamespace, userId: number, - ip: string, + ip: string | undefined, count: number, ) => { const key = adapterConfig.getKVKey( @@ -351,7 +351,7 @@ export const setFailedOtpMfaAttempts = async ( export const getFailedLoginAttemptsByIP = async ( kv: KVNamespace, email: string, - ip: string, + ip?: string, ) => { const key = adapterConfig.getKVKey( adapterConfig.BaseKVKey.FailedLoginAttempts, @@ -365,7 +365,7 @@ export const getFailedLoginAttemptsByIP = async ( export const setFailedLoginAttempts = async ( kv: KVNamespace, email: string, - ip: string, + ip: string | undefined, count: number, expiresIn: number, ) => { @@ -384,7 +384,7 @@ export const setFailedLoginAttempts = async ( export const clearFailedLoginAttemptsByIP = async ( kv: KVNamespace, email: string, - ip: string, + ip?: string, ) => { const key = adapterConfig.getKVKey( adapterConfig.BaseKVKey.FailedLoginAttempts, diff --git a/server/src/services/scope.ts b/server/src/services/scope.ts index 47da66eb..39acd3f9 100644 --- a/server/src/services/scope.ts +++ b/server/src/services/scope.ts @@ -10,7 +10,7 @@ import { } from 'models' import { appService } from 'services' import { - formatUtil, validateUtil, + requestUtil, validateUtil, } from 'utils' export const getScopes = async (c: Context): Promise => { @@ -202,7 +202,7 @@ export const parseGetAuthorizeDto = async (c: Context): Prom codeChallenge: c.req.query('code_challenge') ?? '', codeChallengeMethod: c.req.query('code_challenge_method') ?? '', scopes: c.req.query('scope')?.split(' ') ?? [], - locale: formatUtil.getLocaleFromQuery( + locale: requestUtil.getLocaleFromQuery( c, c.req.query('locale'), ), diff --git a/server/src/services/user.ts b/server/src/services/user.ts index 6c11ec86..37af96c7 100644 --- a/server/src/services/user.ts +++ b/server/src/services/user.ts @@ -19,7 +19,7 @@ import { emailService, jwtService, kvService, roleService, } from 'services' import { - cryptoUtil, timeUtil, + cryptoUtil, requestUtil, timeUtil, } from 'utils' export const getUserInfo = async ( @@ -142,7 +142,7 @@ export const verifyPasswordSignIn = async ( ACCOUNT_LOCKOUT_THRESHOLD: lockThreshold, ACCOUNT_LOCKOUT_EXPIRES_IN: lockExpiresIn, } = env(c) - const ip = c.req.header('cf-connecting-ip') as string + const ip = requestUtil.getRequestIP(c) const failedAttempts = lockThreshold ? await kvService.getFailedLoginAttemptsByIP( diff --git a/server/src/templates/EmailVerification.tsx b/server/src/templates/EmailVerification.tsx index 8c4ec70e..c37d3fd1 100644 --- a/server/src/templates/EmailVerification.tsx +++ b/server/src/templates/EmailVerification.tsx @@ -3,7 +3,7 @@ import { typeConfig, } from 'configs' import Layout from 'templates/components/Layout' -import { formatUtil } from 'utils' +import { requestUtil } from 'utils' const EmailVerification = ({ serverUrl, logoUrl, verificationCode, authId, locale, @@ -14,7 +14,7 @@ const EmailVerification = ({ authId: string; locale: typeConfig.Locale; }) => { - const route = `${formatUtil.stripEndingSlash(serverUrl)}${routeConfig.InternalRoute.Identity}` + const route = `${requestUtil.stripEndingSlash(serverUrl)}${routeConfig.InternalRoute.Identity}` return ( { - return val.replace( - /\/$/, - '', - ) -} - -export const getLocaleFromQuery = ( - c: Context, requestedLocale?: string, -): typeConfig.Locale => { - const { SUPPORTED_LOCALES: locales } = env(c) - const locale = requestedLocale?.toLowerCase() ?? '' - return locales.find((supportedLocale) => supportedLocale === locale) ?? locales[0] +export const d1Run = async (stmt: D1PreparedStatement) => { + try { + const res = await stmt.run() + return res + } catch (e) { + console.error(e) + const msg = String(e).includes('UNIQUE constraint failed') ? localeConfig.Error.UniqueKey : undefined + throw new errorConfig.InternalServerError(msg) + } } -export const getQueryString = (c: Context): string => c.req.url.split('?')[1] - export const d1SelectAllQuery = ( db: D1Database, tableName: string, diff --git a/server/src/utils/index.ts b/server/src/utils/index.ts index bb03a5b6..1a8a8a8f 100644 --- a/server/src/utils/index.ts +++ b/server/src/utils/index.ts @@ -1,4 +1,5 @@ export * as validateUtil from 'utils/validate' export * as cryptoUtil from 'utils/crypto' export * as timeUtil from 'utils/time' -export * as formatUtil from 'utils/format' +export * as requestUtil from 'utils/request' +export * as dbUtil from 'utils/db' diff --git a/server/src/utils/request.ts b/server/src/utils/request.ts new file mode 100644 index 00000000..35090345 --- /dev/null +++ b/server/src/utils/request.ts @@ -0,0 +1,40 @@ +import { Context } from 'hono' +import { env } from 'hono/adapter' +import { typeConfig } from 'configs' + +export const stripEndingSlash = (val: string): string => { + return val.replace( + /\/$/, + '', + ) +} + +export const getLocaleFromQuery = ( + c: Context, requestedLocale?: string, +): typeConfig.Locale => { + const { SUPPORTED_LOCALES: locales } = env(c) + const locale = requestedLocale?.toLowerCase() ?? '' + return locales.find((supportedLocale) => supportedLocale === locale) ?? locales[0] +} + +export const getQueryString = (c: Context): string => c.req.url.split('?')[1] + +export const getRequestIP = (c: Context): string | undefined => { + const targets = [ + 'cf-connecting-ip', + 'x-client-ip', + 'x-forwarded-for', + 'do-connecting-ip', + 'fastly-client-ip', + 'true-client-ip', + 'x-real-ip', + 'x-cluster-client-ip', + 'x-forwarded', + 'forwarded-for', + 'x-appengine-user-ip', + ] + const matchedTarget = targets.find((target) => c.req.header(target)) + + const ip = matchedTarget ? c.req.header(matchedTarget) : undefined + return ip +} diff --git a/server/src/utils/validate.ts b/server/src/utils/validate.ts index 0a1b6395..059cc913 100644 --- a/server/src/utils/validate.ts +++ b/server/src/utils/validate.ts @@ -1,7 +1,5 @@ import { validateOrReject } from 'class-validator' -import { - errorConfig, localeConfig, -} from 'configs' +import { errorConfig } from 'configs' export const dto = async (dto: object) => { try { @@ -10,14 +8,3 @@ export const dto = async (dto: object) => { throw new errorConfig.Forbidden(JSON.stringify(e)) } } - -export const d1Run = async (stmt: D1PreparedStatement) => { - try { - const res = await stmt.run() - return res - } catch (e) { - console.error(e) - const msg = String(e).includes('UNIQUE constraint failed') ? localeConfig.Error.UniqueKey : undefined - throw new errorConfig.InternalServerError(msg) - } -}