HotTRDealsBackend/routes/auth.routes.js
2026-02-04 06:39:10 +00:00

182 lines
5.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// routes/auth.js
const express = require("express")
const router = express.Router()
const requireAuth = require("../middleware/requireAuth.js")
const { validate } = require("../middleware/validate.middleware")
const authService = require("../services/auth.service")
const { endpoints } = require("@shared/contracts")
const { mapLoginRequestToLoginInput, mapLoginResultToResponse } = require("../adapters/responses/login.adapter")
const { mapRegisterRequestToRegisterInput, mapRegisterResultToResponse } = require("../adapters/responses/register.adapter")
const { mapMeRequestToUserId, mapMeResultToResponse } = require("../adapters/responses/me.adapter")
const { auth } = endpoints
// NOT: app.jsde cookie-parser olmali:
// const cookieParser = require("cookie-parser")
// app.use(cookieParser())
function getCookieOptions() {
const isProd = process.env.NODE_ENV === "production"
return {
httpOnly: true,
secure: isProd,
sameSite: "lax",
path: "/",
}
}
function parseExpiresInToMs(value) {
if (!value) return 15 * 60 * 1000
if (typeof value === "number" && Number.isFinite(value)) return value * 1000
const str = String(value).trim().toLowerCase()
const match = str.match(/^(\d+)(ms|s|m|h|d)?$/)
if (!match) return 15 * 60 * 1000
const n = Number(match[1])
const unit = match[2] || "s"
const mult =
unit === "ms" ? 1 :
unit === "s" ? 1000 :
unit === "m" ? 60 * 1000 :
unit === "h" ? 60 * 60 * 1000 :
unit === "d" ? 24 * 60 * 60 * 1000 :
1000
return n * mult
}
function setRefreshCookie(res, refreshToken) {
const opts = getCookieOptions()
const maxAgeMs = Number(process.env.REFRESH_COOKIE_MAX_AGE_MS || 1000 * 60 * 60 * 24 * 30)
res.cookie("rt", refreshToken, { ...opts, maxAge: maxAgeMs })
}
function setAccessCookie(res, accessToken) {
const opts = getCookieOptions()
const maxAgeMs = parseExpiresInToMs(process.env.ACCESS_TOKEN_EXPIRES_IN || "15m")
res.cookie("at", accessToken, { ...opts, maxAge: maxAgeMs })
}
function clearRefreshCookie(res) {
const opts = getCookieOptions()
res.clearCookie("rt", { ...opts })
}
function clearAccessCookie(res) {
const opts = getCookieOptions()
res.clearCookie("at", { ...opts })
}
router.post(
"/register",
validate(auth.registerRequestSchema, "body", "validatedRegisterInput"),
async (req, res) => {
try {
const input = mapRegisterRequestToRegisterInput(req.validatedRegisterInput)
const result = await authService.register({
...input,
meta: { ip: req.ip, userAgent: req.headers["user-agent"] || null },
})
// refresh + access cookie set
if (result.refreshToken) setRefreshCookie(res, result.refreshToken)
if (result.accessToken) setAccessCookie(res, result.accessToken)
const response = auth.authResponseSchema.parse(mapRegisterResultToResponse(result))
res.json(response)
} catch (err) {
const status = err.statusCode || 500
res.status(status).json({ message: err.message || "Kayit islemi basarisiz." })
}
}
)
router.post(
"/login",
validate(auth.loginRequestSchema, "body", "validatedLoginInput"),
async (req, res) => {
try {
const input = mapLoginRequestToLoginInput(req.validatedLoginInput)
const result = await authService.login({
...input,
meta: { ip: req.ip, userAgent: req.headers["user-agent"] || null },
})
// refresh + access cookie set
setRefreshCookie(res, result.refreshToken)
setAccessCookie(res, result.accessToken)
const response = auth.authResponseSchema.parse(mapLoginResultToResponse(result))
res.json(response)
} catch (err) {
const status = err.statusCode || 500
res.status(status).json({
message: err.statusCode ? err.message : "Giris islemi basarisiz.",
})
}
}
)
router.post("/refresh", async (req, res) => {
try {
const refreshToken = req.cookies?.rt
if (!refreshToken) return res.status(401).json({ message: "Refresh token yok" })
const result = await authService.refresh({
refreshToken,
meta: { ip: req.ip, userAgent: req.headers["user-agent"] || null },
})
// rotate -> yeni refresh + access cookie
setRefreshCookie(res, result.refreshToken)
setAccessCookie(res, result.accessToken)
const response = auth.authResponseSchema.parse(mapLoginResultToResponse(result))
res.json(response)
} catch (err) {
clearRefreshCookie(res)
clearAccessCookie(res)
const status = err.statusCode || 401
res.status(status).json({ message: err.message || "Refresh basarisiz" })
}
})
router.post("/logout", async (req, res) => {
try {
const refreshToken = req.cookies?.rt
if (refreshToken) {
await authService.logout({
refreshToken,
meta: { ip: req.ip, userAgent: req.headers["user-agent"] || null },
})
}
clearRefreshCookie(res)
clearAccessCookie(res)
res.status(204).send()
} catch (err) {
clearRefreshCookie(res)
clearAccessCookie(res)
const status = err.statusCode || 500
res.status(status).json({ message: err.message || "Cikis basarisiz" })
}
})
router.get("/me", requireAuth, async (req, res) => {
try {
const userId = mapMeRequestToUserId(req)
const user = await authService.getMe(userId)
const response = auth.meResponseSchema.parse(mapMeResultToResponse(user))
res.json(response)
} catch (err) {
const status = err.statusCode || 500
res.status(status).json({ message: err.message || "Sunucu hatasi" })
}
})
module.exports = router