File size: 3,299 Bytes
05cee1f
24727a3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27bb290
24727a3
 
 
 
 
 
 
 
 
05cee1f
24727a3
 
 
 
 
 
6001748
 
 
05cee1f
24727a3
 
 
 
 
6001748
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
05cee1f
24727a3
 
 
 
 
 
 
f8151ee
 
05cee1f
24727a3
 
 
 
 
 
 
05cee1f
24727a3
 
 
 
05cee1f
24727a3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import { success, created } from '../../lib/response.js'
import * as authService from './auth.service.js'
import { config } from '../../config/index.js'
import { toPublicUrl } from '../../middleware/upload.js'

function parseExpires(expiresStr) {
  const match = expiresStr.match(/^(\d+)([dhms])$/)
  if (!match) return 7 * 24 * 60 * 60 * 1000
  const num = parseInt(match[1])
  const unit = match[2]
  const mul = { d: 86400000, h: 3600000, m: 60000, s: 1000 }
  return num * (mul[unit] || 86400000)
}

const REFRESH_COOKIE_OPTIONS = {
  httpOnly: true,
  secure: process.env.NODE_ENV === 'production',
  sameSite: process.env.NODE_ENV === 'production' ? 'none' : 'lax',
  maxAge: parseExpires(config.JWT_REFRESH_EXPIRES),
  path: '/api/auth/refresh'
}

export async function register(req, res, next) {
  try {
    const avatarUrl = toPublicUrl(req.file?.path) || null
    const { user, accessToken, refreshToken } = await authService.registerUser(req.validatedData, avatarUrl)
    res.cookie('refresh_token', refreshToken, REFRESH_COOKIE_OPTIONS)
    created(res, { user, accessToken })
  } catch (err) { next(err) }
}

export async function login(req, res, next) {
  try {
    const { email, password } = req.validatedData
    const result = await authService.loginUser(email, password)
    const cookieName = result.user.role !== 'CLIENT' ? 'admin_refresh_token' : 'refresh_token'
    res.cookie(cookieName, result.refreshToken, REFRESH_COOKIE_OPTIONS)
    success(res, { user: result.user, accessToken: result.accessToken })
  } catch (err) { next(err) }
}

export async function refresh(req, res, next) {
  try {
    let user, accessToken, refreshToken, isAdmin

    if (req.cookies.refresh_token) {
      try {
        const result = await authService.refreshUserToken(req.cookies.refresh_token, true)
        user = result.user; accessToken = result.accessToken; refreshToken = result.refreshToken; isAdmin = result.isAdmin
      } catch {}
    }

    if (!user && req.cookies.admin_refresh_token) {
      const result = await authService.refreshUserToken(req.cookies.admin_refresh_token, false)
      user = result.user; accessToken = result.accessToken; refreshToken = result.refreshToken; isAdmin = true
    }

    if (!user) throw new Error('NO_TOKEN')

    const cookieName = isAdmin ? 'admin_refresh_token' : 'refresh_token'
    res.cookie(cookieName, refreshToken, REFRESH_COOKIE_OPTIONS)
    success(res, { user, accessToken })
  } catch (err) { next(err) }
}

export async function logout(req, res, next) {
  try {
    const accessToken = req.headers.authorization?.split(' ')[1]
    await authService.logoutUser(req.user.id, accessToken)
    const isAdmin = req.user.role !== 'CLIENT'
    res.clearCookie(isAdmin ? 'admin_refresh_token' : 'refresh_token', { path: '/api/auth/refresh' })
    success(res, null, 'تم تسجيل الخروج بنجاح')
  } catch (err) { next(err) }
}

export async function changePassword(req, res, next) {
  try {
    const { currentPassword, newPassword } = req.validatedData
    await authService.changeUserPassword(req.user.id, currentPassword, newPassword)
    success(res, null, 'تم تغيير كلمة المرور بنجاح')
  } catch (err) { next(err) }
}

export async function getMe(req, res) {
  success(res, { user: req.user })
}