Skip to content

Commit 46446c4

Browse files
committed
feat(auth): เพิ่ม remember me
1 parent 04befb8 commit 46446c4

File tree

2 files changed

+35
-19
lines changed

2 files changed

+35
-19
lines changed

server/src/controllers/auth.controller.ts

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ const COOKIE_NAME = process.env.COOKIE_NAME || 'access_token';
1010
const COOKIE_DOMAIN = process.env.COOKIE_DOMAIN || undefined; // เช่น ".example.com"
1111
const COOKIE_SAMESITE = (process.env.COOKIE_SAMESITE as 'lax' | 'none' | 'strict') || 'lax';
1212
const COOKIE_MAX_AGE_MS = Number(process.env.COOKIE_MAX_AGE_MS ?? 60 * 60 * 1000);
13+
const COOKIE_MAX_AGE_REMEMBER_MS = Number(
14+
process.env.COOKIE_MAX_AGE_REMEMBER_MS ?? 7 * 24 * 60 * 60 * 1000
15+
);
16+
const COOKIE_MAX_AGE_TEST_MS = Number(
17+
process.env.COOKIE_MAX_AGE_TEST_MS ?? 5000
18+
);
1319

1420
const cookieBase = {
1521
httpOnly: true,
@@ -34,15 +40,23 @@ const cookieBase = {
3440
* @author Wanasart
3541
*/
3642
export async function login(req: Request, res: Response, next: NextFunction) {
37-
console.log('LOGIN body:', req.body);
38-
3943
try {
40-
const { usernameOrEmail, password } = req.body;
41-
const user = await AuthService.authenticateUser(usernameOrEmail, password);
44+
const { usernameOrEmail, password, remember } = req.body as {
45+
usernameOrEmail: string; password: string; remember?: boolean;
46+
};
47+
48+
const user = await AuthService.authenticateUser(usernameOrEmail, password, !!remember);
4249

43-
const token = AuthService.createSessionToken({ id: user.usr_id, role: user.usr_role }); // Generate a token for the user
50+
// ⬇️ ออกโทเค็นตามอายุที่เลือก (1h หรือ 7d)
51+
const token = AuthService.createSessionToken(
52+
{ id: user.usr_id, role: user.usr_role },
53+
{ remember: !!remember }
54+
);
4455

45-
res.cookie(COOKIE_NAME, token, { ...cookieBase, maxAge: COOKIE_MAX_AGE_MS });
56+
// ⬇️ ตั้งอายุคุกกี้ตาม remember
57+
const maxAge = !!remember ? COOKIE_MAX_AGE_REMEMBER_MS : COOKIE_MAX_AGE_MS;
58+
// const maxAge = !!remember ? COOKIE_MAX_AGE_TEST_MS : COOKIE_MAX_AGE_MS; // ⬅️ สำหรับทดสอบ
59+
res.cookie(COOKIE_NAME, token, { ...cookieBase, maxAge });
4660

4761
return res.json({ message: 'Login successful', success: true, user });
4862
} catch (err) {
@@ -126,28 +140,23 @@ export async function register(req: Request, res: Response, next: NextFunction)
126140
* @author Wanasart
127141
*/
128142
export async function me(req: Request, res: Response, next: NextFunction) {
129-
res.set({
130-
'Cache-Control': 'no-store',
131-
'Pragma': 'no-cache',
132-
'Vary': 'Cookie',
133-
});
143+
res.set({ 'Cache-Control': 'no-store', 'Pragma': 'no-cache', 'Vary': 'Cookie' });
134144

135145
try {
136-
const token = req.cookies?.access_token;
146+
const token = req.cookies?.[COOKIE_NAME]; // ⬅️ ใช้ COOKIE_NAME
137147
if (!token) return res.status(401).json({ error: 'Unauthenticated' });
138148

139-
const payload = verifySessionToken(token); // { id, role }
149+
const payload = verifySessionToken(token);
140150
const user = await getUserSafeById(payload.id);
141151
if (!user) return res.status(401).json({ error: 'User not found' });
142152

143-
// ส่งเฉพาะ field ที่ใช้แสดงผล
144153
return res.json({
145154
usr_id: user.usr_id,
146155
usr_username: user.usr_username,
147156
usr_email: user.usr_email,
148157
usr_role: user.usr_role,
149158
});
150-
} catch (err) {
159+
} catch {
151160
return res.status(401).json({ error: 'Invalid token' });
152161
}
153162
}

server/src/services/auth.service.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ import { UserRow, UserSafe } from '../models/users.model';
88

99
const JWT_SECRET = process.env.JWT_SECRET || 'dev-secret';
1010
const JWT_EXPIRES = process.env.JWT_EXPIRES || '1h';
11+
const JWT_EXPIRES_REMEMBER = process.env.JWT_EXPIRES_REMEMBER || '7d'; // ⬅️ เพิ่มบรรทัดนี้
1112
const BCRYPT_ROUNDS = Number(process.env.BCRYPT_ROUNDS) || 12;
13+
const JWT_EXPIRES_TEST = process.env.JWT_EXPIRES_TEST;
1214

1315
/**
1416
* สร้าง JWT session token จาก payload
@@ -18,9 +20,14 @@ const BCRYPT_ROUNDS = Number(process.env.BCRYPT_ROUNDS) || 12;
1820
*
1921
* @author Wanasart
2022
*/
21-
export function createSessionToken(payload: { id: number, role: string }) {
22-
return jwt.sign(payload, JWT_SECRET, { expiresIn: JWT_EXPIRES });
23-
}
23+
export function createSessionToken(
24+
payload: { id: number; role: string },
25+
opts?: { remember?: boolean; expiresIn?: string | number }
26+
) {
27+
const expiresIn = opts?.expiresIn ?? (opts?.remember ? JWT_EXPIRES_REMEMBER : JWT_EXPIRES);
28+
// const expiresIn = opts?.expiresIn ?? (opts?.remember ? JWT_EXPIRES_TEST : JWT_EXPIRES); // ⬅️ สำหรับทดสอบ
29+
return jwt.sign(payload, JWT_SECRET, { expiresIn });
30+
}
2431

2532
/**
2633
* ตรวจสอบความถูกต้องของ JWT session token
@@ -61,7 +68,7 @@ function toUserSafe(user: UserRow): UserSafe {
6168
*
6269
* @author Wanasart
6370
*/
64-
export async function authenticateUser(usernameOrEmail: string, password: string) {
71+
export async function authenticateUser(usernameOrEmail: string, password: string, remember: boolean = false): Promise<UserSafe> {
6572
// console.log(`Authenticating user: ${usernameOrEmail} with password: ${password}`);
6673
const { rows } = await pool.query<UserRow>(`
6774
SELECT * FROM users

0 commit comments

Comments
 (0)