secutorpro commited on
Commit
cd8250c
·
verified ·
1 Parent(s): ef3b247

jwt login + middleware

Browse files
Files changed (1) hide show
  1. server/src/auth.js +19 -16
server/src/auth.js CHANGED
@@ -7,41 +7,44 @@ import path from 'node:path';
7
  import db from './db.js';
8
 
9
  const DATA_DIR = process.env.DATA_DIR || path.join(process.cwd(), 'data');
10
- fs.mkdirSync(DATA_DIR, { recursive: true });
11
 
12
- function loadSecret() {
13
- if (process.env.JWT_SECRET) return process.env.JWT_SECRET;
14
  const file = path.join(DATA_DIR, 'jwt-secret');
15
- if (fs.existsSync(file)) return fs.readFileSync(file, 'utf8').trim();
16
- const secret = crypto.randomBytes(32).toString('hex');
17
- fs.writeFileSync(file, secret, { mode: 0o600 });
18
- return secret;
 
19
  }
 
20
 
21
- export const JWT_SECRET = loadSecret();
22
-
23
- const r = Router();
24
 
25
- r.post('/login', (req, res) => {
26
  const { username, password } = req.body || {};
27
  const u = db.prepare('SELECT * FROM users WHERE username = ?').get(String(username || ''));
28
  if (!u || !bcrypt.compareSync(String(password || ''), u.password_hash)) {
29
- return res.status(401).json({ error: 'Invalid username or password' });
30
  }
31
- const token = jwt.sign({ sub: u.id, username: u.username, role: u.role }, JWT_SECRET, { expiresIn: '12h' });
32
  res.json({ token, user: { id: u.id, username: u.username, role: u.role } });
33
  });
34
 
 
 
 
 
35
  export function requireAuth(req, res, next) {
36
  const header = req.headers.authorization || '';
37
  const token = header.startsWith('Bearer ') ? header.slice(7) : null;
38
  if (!token) return res.status(401).json({ error: 'Missing token' });
39
  try {
40
- req.user = jwt.verify(token, JWT_SECRET);
41
  next();
42
  } catch {
43
- res.status(401).json({ error: 'Invalid or expired token' });
44
  }
45
  }
46
 
47
- export default r;
 
7
  import db from './db.js';
8
 
9
  const DATA_DIR = process.env.DATA_DIR || path.join(process.cwd(), 'data');
 
10
 
11
+ let secret = process.env.JWT_SECRET;
12
+ if (!secret) {
13
  const file = path.join(DATA_DIR, 'jwt-secret');
14
+ if (fs.existsSync(file)) secret = fs.readFileSync(file, 'utf8').trim();
15
+ else {
16
+ secret = crypto.randomBytes(32).toString('hex');
17
+ fs.writeFileSync(file, secret);
18
+ }
19
  }
20
+ export { secret };
21
 
22
+ const router = Router();
 
 
23
 
24
+ router.post('/login', (req, res) => {
25
  const { username, password } = req.body || {};
26
  const u = db.prepare('SELECT * FROM users WHERE username = ?').get(String(username || ''));
27
  if (!u || !bcrypt.compareSync(String(password || ''), u.password_hash)) {
28
+ return res.status(401).json({ error: 'Invalid credentials' });
29
  }
30
+ const token = jwt.sign({ sub: u.id, username: u.username, role: u.role }, secret, { expiresIn: '12h' });
31
  res.json({ token, user: { id: u.id, username: u.username, role: u.role } });
32
  });
33
 
34
+ router.get('/me', requireAuth, (req, res) => {
35
+ res.json({ id: req.user.sub, username: req.user.username, role: req.user.role });
36
+ });
37
+
38
  export function requireAuth(req, res, next) {
39
  const header = req.headers.authorization || '';
40
  const token = header.startsWith('Bearer ') ? header.slice(7) : null;
41
  if (!token) return res.status(401).json({ error: 'Missing token' });
42
  try {
43
+ req.user = jwt.verify(token, secret);
44
  next();
45
  } catch {
46
+ res.status(401).json({ error: 'Invalid token' });
47
  }
48
  }
49
 
50
+ export default router;