-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.js
More file actions
95 lines (76 loc) · 3.2 KB
/
server.js
File metadata and controls
95 lines (76 loc) · 3.2 KB
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
88
89
90
91
92
93
94
95
const express = require('express');
const path = require('path');
const Database = require('better-sqlite3');
const QRCode = require('qrcode');
const { nanoid } = require('nanoid');
const app = express();
const PORT = process.env.PORT || 3000;
const BASE_URL = process.env.BASE_URL || `http://localhost:${PORT}`;
// --- Database setup ---
const db = new Database(path.join(__dirname, 'qrcodes.db'));
db.pragma('journal_mode = WAL');
db.exec(`
CREATE TABLE IF NOT EXISTS qrcodes (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
destination_url TEXT NOT NULL,
scans INTEGER DEFAULT 0,
created_at TEXT DEFAULT (datetime('now')),
updated_at TEXT DEFAULT (datetime('now'))
)
`);
// --- Middleware ---
app.use(express.json());
app.use(express.static(path.join(__dirname, 'public')));
// --- Redirect route (this is what the QR codes point to) ---
app.get('/r/:id', (req, res) => {
const row = db.prepare('SELECT destination_url FROM qrcodes WHERE id = ?').get(req.params.id);
if (!row) return res.status(404).send('QR code not found');
db.prepare('UPDATE qrcodes SET scans = scans + 1 WHERE id = ?').run(req.params.id);
res.redirect(302, row.destination_url);
});
// --- API routes ---
// List all QR codes
app.get('/api/qrcodes', (req, res) => {
const rows = db.prepare('SELECT * FROM qrcodes ORDER BY created_at DESC').all();
res.json(rows);
});
// Create a new QR code
app.post('/api/qrcodes', async (req, res) => {
const { name, destination_url } = req.body;
if (!name || !destination_url) {
return res.status(400).json({ error: 'name and destination_url are required' });
}
const id = nanoid(8);
db.prepare('INSERT INTO qrcodes (id, name, destination_url) VALUES (?, ?, ?)').run(id, name, destination_url);
const redirectUrl = `${BASE_URL}/r/${id}`;
const qrDataUrl = await QRCode.toDataURL(redirectUrl, { width: 400, margin: 2 });
res.status(201).json({ id, name, destination_url, redirect_url: redirectUrl, qr_data_url: qrDataUrl });
});
// Get QR code image
app.get('/api/qrcodes/:id/image', async (req, res) => {
const row = db.prepare('SELECT id FROM qrcodes WHERE id = ?').get(req.params.id);
if (!row) return res.status(404).json({ error: 'Not found' });
const redirectUrl = `${BASE_URL}/r/${row.id}`;
const qrDataUrl = await QRCode.toDataURL(redirectUrl, { width: 400, margin: 2 });
res.json({ qr_data_url: qrDataUrl });
});
// Update destination URL
app.put('/api/qrcodes/:id', (req, res) => {
const { name, destination_url } = req.body;
const row = db.prepare('SELECT * FROM qrcodes WHERE id = ?').get(req.params.id);
if (!row) return res.status(404).json({ error: 'Not found' });
db.prepare(`UPDATE qrcodes SET name = ?, destination_url = ?, updated_at = datetime('now') WHERE id = ?`)
.run(name || row.name, destination_url || row.destination_url, req.params.id);
res.json({ success: true });
});
// Delete a QR code
app.delete('/api/qrcodes/:id', (req, res) => {
const result = db.prepare('DELETE FROM qrcodes WHERE id = ?').run(req.params.id);
if (result.changes === 0) return res.status(404).json({ error: 'Not found' });
res.json({ success: true });
});
// --- Start server ---
app.listen(PORT, () => {
console.log(`QR Generator running at ${BASE_URL}`);
});