File size: 3,412 Bytes
8798c7e
 
 
b3b21e2
8798c7e
 
b3b21e2
8798c7e
e34feda
8798c7e
e34feda
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b3b21e2
 
 
e34feda
 
 
b3b21e2
 
8798c7e
b3b21e2
 
 
 
8798c7e
e34feda
8798c7e
e34feda
b3b21e2
8798c7e
 
 
 
 
 
b3b21e2
8798c7e
 
b3b21e2
8798c7e
 
b3b21e2
8798c7e
 
b3b21e2
 
8798c7e
 
 
 
 
e34feda
 
 
 
 
b3b21e2
 
 
 
 
8798c7e
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
const express = require('express');
const multer = require('multer');
const cors = require('cors');
const { decodeFromImageBuffer } = require('./decoder'); // Import our logic

const app = express();
const PORT = process.env.PORT || 7860;

// --- 1. SECURE CORS CONFIGURATION ---

// Define the list of allowed client origins from an environment variable.
// This allows you to change the allowed origins without changing the code.
// The variable should be a comma-separated list of URLs.
const allowedOrigins = process.env.ALLOWED_ORIGINS ? process.env.ALLOWED_ORIGINS.split(',') : [];

const corsOptions = {
  origin: (origin, callback) => {
    // 'origin' will be undefined for server-to-server requests or curl.
    // Allow requests with no origin OR if the origin is in our whitelist.
    if (!origin || allowedOrigins.indexOf(origin) !== -1) {
      callback(null, true);
    } else {
      // If the origin is not in the whitelist, reject the request.
      callback(new Error(`Not allowed by CORS. Origin: ${origin}`));
    }
  },
  methods: ['GET', 'POST'], // Allow only specific methods
};

// Use the configured CORS middleware
app.use(cors(corsOptions));


// --- 2. HEALTH CHECK ENDPOINT ---
app.get('/', (req, res) => {
    res.status(200).json({ 
        status: 'ok', 
        message: 'Secure Decoder API is running.',
        // Also report which origins are allowed, for easy debugging.
        allowed_origins: allowedOrigins.length > 0 ? allowedOrigins : "None configured (check ALLOWED_ORIGINS secret)."
    });
});

const upload = multer({
    storage: multer.memoryStorage(),
    limits: { fileSize: 5 * 1024 * 1024 }, // 5MB limit
});

// --- 3. DECODE API ENDPOINT ---
app.post('/api/decode', upload.single('authImage'), async (req, res) => {
    console.log(`Received a request to /api/decode from origin: ${req.get('origin') || 'unknown'}`);

    const privateKey = process.env.PLUGIN_PRIVATE_KEY;
    if (!privateKey) {
        console.error("FATAL: PLUGIN_PRIVATE_KEY secret is not set in the Space settings.");
        return res.status(500).json({ error: 'Server is not configured with a private key.' });
    }
    if (!req.file) {
        console.log("Request failed: No image file provided.");
        return res.status(400).json({ error: 'No image file provided. Please upload a file with the key "authImage".' });
    }

    try {
        const credentials = await decodeFromImageBuffer(req.file.buffer, privateKey);
        console.log("Successfully decoded data.");
        res.json({ success: true, data: credentials });
    } catch (error) {
        console.error("Decryption failed:", error.message);
        res.status(400).json({ success: false, error: `Decryption failed: ${error.message}` });
    }
});

app.listen(PORT, () => {
    console.log(`Secure decoder API listening on port ${PORT}`);
    if (allowedOrigins.length > 0) {
        console.log(`CORS whitelist enabled for the following origins: ${allowedOrigins.join(', ')}`);
    } else {
        console.warn("WARNING: No CORS origins are whitelisted. Set the ALLOWED_ORIGINS secret. All cross-origin requests will be blocked.");
    }
    if (!process.env.PLUGIN_PRIVATE_KEY) {
        console.warn("WARNING: PLUGIN_PRIVATE_KEY environment variable is not set. The /api/decode endpoint will fail.");
    } else {
        console.log("PLUGIN_PRIVATE_KEY secret has been loaded successfully.");
    }
});