Skip to content

Commit

Permalink
fix(core): update http error codes in authentication endpoints (#4661)
Browse files Browse the repository at this point in the history
* fix(core): update http error codes in authentication endpoints

* fix: lint issues
  • Loading branch information
dolcalmi authored Nov 20, 2024
1 parent c80f599 commit c38451a
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 15 deletions.
3 changes: 3 additions & 0 deletions core/api/src/domain/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ export class NoBtcWalletExistsForAccountError extends ValidationError {}
export class InvalidQuizQuestionIdError extends ValidationError {}
export class QuizClaimedTooEarlyError extends ValidationError {}
export class MissingIPMetadataError extends ValidationError {}
export class UndefinedIPError extends ValidationError {
level = ErrorLevel.Critical
}

export class InvalidIpMetadataError extends ValidationError {
level = ErrorLevel.Critical
Expand Down
1 change: 1 addition & 0 deletions core/api/src/graphql/error-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,7 @@ export const mapError = (error: ApplicationError): CustomGraphQLError => {
case "PhoneCarrierTypeNotAllowedError":
case "PhoneCountryNotAllowedError":
case "MissingIPMetadataError":
case "UndefinedIPError":
case "UnauthorizedIPMetadataASNError":
case "InvalidAccountStatusError":
case "InvalidOnChainAddress":
Expand Down
33 changes: 18 additions & 15 deletions core/api/src/servers/authentication/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@ import { registerCaptchaGeetest } from "@/app/captcha"

import { UNSECURE_IP_FROM_REQUEST_OBJECT } from "@/config"

import { ErrorLevel, parseErrorMessageFromUnknown } from "@/domain/shared"
import { parseIps } from "@/domain/accounts-ips"
import { checkedToEmailCode, validOneTimeAuthCodeValue } from "@/domain/authentication"
import {
EmailCodeInvalidError,
EmailValidationSubmittedTooOftenError,
} from "@/domain/authentication/errors"
import { UndefinedIPError } from "@/domain/errors"
import { UserLoginIpRateLimiterExceededError } from "@/domain/rate-limit/errors"
import { parseErrorMessageFromUnknown } from "@/domain/shared"
import { checkedToEmailAddress, checkedToPhoneNumber } from "@/domain/users"

import {
Expand All @@ -41,16 +42,16 @@ authRouter.use((req: Request, res: Response, next: NextFunction) => {
const ipString = UNSECURE_IP_FROM_REQUEST_OBJECT ? req.ip : req.headers["x-real-ip"]
const ip = parseIps(ipString)
if (!ip) {
recordExceptionInCurrentSpan({ error: "IP is not defined" })
return res.status(500).send({ error: "IP is not defined" })
recordExceptionInCurrentSpan({ error: new UndefinedIPError() })
return res.status(400).send({ error: "IP is not defined" })
}
req["originalIp"] = ip as IpAddress

next()
})

authRouter.use((req: Request, res: Response, next: NextFunction) => {
const routeName = req?.url || "unknownRoute" // Extract route from request, fallback to 'unknownRoute'
const routeName = req?.url || "unknownRoute"
const spanName = `servers.authRouter.${routeName}`

const span = tracer.startSpan(spanName)
Expand Down Expand Up @@ -95,14 +96,14 @@ authRouter.post("/create/device-account", async (req: Request, res: Response) =>
})
if (authToken instanceof Error) {
recordExceptionInCurrentSpan({ error: authToken })
return res.status(500).send({ error: authToken.message })
return res.status(401).send({ error: authToken.message })
}
addAttributesToCurrentSpan({ "login.deviceAccount": deviceId })
return res.status(200).send({
result: authToken,
})
} catch (err) {
recordExceptionInCurrentSpan({ error: err })
recordExceptionInCurrentSpan({ error: err, level: ErrorLevel.Critical })
return res.status(500).send({ error: parseErrorMessageFromUnknown(err) })
}
})
Expand All @@ -127,14 +128,14 @@ authRouter.post("/email/code", async (req: Request, res: Response) => {
const emailLoginId = await Authentication.requestEmailCode({ email, ip })
if (emailLoginId instanceof Error) {
recordExceptionInCurrentSpan({ error: emailLoginId.message })
return res.status(500).send({ error: emailLoginId.message })
return res.status(400).send({ error: emailLoginId.message })
}
return res.status(200).send({
result: emailLoginId,
})
} catch (err) {
recordExceptionInCurrentSpan({ error: err })
return res.status(500).send({ error: err })
recordExceptionInCurrentSpan({ error: err, level: ErrorLevel.Critical })
return res.status(500).send({ error: parseErrorMessageFromUnknown(err) })
}
})

Expand Down Expand Up @@ -180,14 +181,14 @@ authRouter.post("/email/login", async (req: Request, res: Response) => {
}
if (result instanceof Error) {
recordExceptionInCurrentSpan({ error: result })
return res.status(500).send({ error: result.message })
return res.status(400).send({ error: result.message })
}
const { authToken, totpRequired, id } = result
return res.status(200).send({
result: { authToken, totpRequired, id },
})
} catch (err) {
recordExceptionInCurrentSpan({ error: err })
recordExceptionInCurrentSpan({ error: err, level: ErrorLevel.Critical })
return res.status(500).send({ error: parseErrorMessageFromUnknown(err) })
}
})
Expand Down Expand Up @@ -233,19 +234,21 @@ authRouter.post("/totp/validate", async (req: Request, res: Response) => {
}
if (result instanceof Error) {
recordExceptionInCurrentSpan({ error: result })
return res.status(500).send({ error: result.message })
return res.status(400).send({ error: result.message })
}
return res.status(200).send()
} catch (err) {
recordExceptionInCurrentSpan({ error: err })
recordExceptionInCurrentSpan({ error: err, level: ErrorLevel.Critical })
return res.status(500).send({ error: parseErrorMessageFromUnknown(err) })
}
})

authRouter.post("/phone/captcha", async (req: Request, res: Response) => {
const result = await registerCaptchaGeetest()
if (result instanceof Error)
if (result instanceof Error) {
recordExceptionInCurrentSpan({ error: result, level: ErrorLevel.Critical })
return res.status(500).json({ error: "error creating challenge" })
}

const { success, gt, challenge, newCaptcha } = result

Expand Down Expand Up @@ -361,7 +364,7 @@ authRouter.post("/phone/login", async (req: Request, res: Response) => {
ip,
})
if (loginResp instanceof Error) {
return res.status(500).send({ error: mapError(loginResp).message })
return res.status(401).send({ error: mapError(loginResp).message })
}

const { authToken, totpRequired, id } = loginResp
Expand Down

0 comments on commit c38451a

Please sign in to comment.