forked from Stremio/stremio-web
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathhttp_server.js
executable file
·160 lines (132 loc) · 4.67 KB
/
http_server.js
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#!/usr/bin/env node
// Copyright (C) 2017-2023 Smart code 203358507
const INDEX_CACHE = 7200;
const ASSETS_CACHE = 2629744;
const HTTP_PORT = 8080;
const express = require('express');
const path = require('path');
const fs = require("node:fs");
const cookieParser = require("cookie-parser");
const build_path = path.resolve(__dirname, 'build');
const index_path = path.join(build_path, 'index.html');
const login_path = path.join(build_path, 'login.html');
const patched_marker = '<!-- CONFIG INJECTED -->';
const WEB_AUTH_KEY = process.env.WEB_AUTH_KEY;
if (!WEB_AUTH_KEY) {
console.error('WEB_AUTH_KEY is required to be set in the environment!');
process.exit(1);
}
console.log('WEB_AUTH_KEY:', WEB_AUTH_KEY);
const app = express();
app.use(cookieParser());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
fs.readFile(index_path, 'utf8', (err, html) => {
if (err) {
console.error('Failed to read index.html:', err);
process.exit(1);
}
if (!html.includes(patched_marker)) {
const runtimeConfig = {
API_ENDPOINT: process.env.API_ENDPOINT || 'https://api.strem.io',
API_KEY: process.env.API_KEY || null,
};
console.log('Patching index.html with runtimeConfig:', runtimeConfig);
const script = `<script>window.RUNTIME_CONFIG = ${JSON.stringify(runtimeConfig)};</script>`;
const injectedHtml = html.replace('</head>', `${script}\n${patched_marker}\n</head>`);
fs.writeFile(index_path, injectedHtml, 'utf8', (writeErr) => {
if (writeErr) {
console.error('Failed to patch index.html:', writeErr);
process.exit(1);
}
console.log('index.html patched successfully!');
});
} else {
console.log('index.html already patched, skipping...');
}
});
// ==========================
// Authentication Middleware
// ==========================
function webAuth(req, res, next) {
const authKey =
req.query.auth ||
req.cookies.authToken ||
req.headers['authorization']?.split(' ')[1];
if (authKey === WEB_AUTH_KEY) {
console.log('User authenticated successfully');
return next(); // Auth successful
}
console.log('Unauthorized access attempt to:', req.originalUrl);
res.redirect('/login'); // Redirect to login page if not authenticated
}() => console.info(`Server listening on port: ${HTTP_PORT}`);
// ==========================
// Check if authenticated
// ==========================
function checkAuth(req) {
const authKey =
req.cookies.authToken ||
req.headers['authorization']?.split(' ')[1];
return authKey === WEB_AUTH_KEY;
}
// ==========================
// Login Route - Handle POST
// ==========================
app.post('/api/login', (req, res) => {
const { auth_key } = req.body; // Correctly parsed form data
if (auth_key === WEB_AUTH_KEY) {
res.cookie('authToken', WEB_AUTH_KEY, { httpOnly: true });
console.log('Login successful');
return res.redirect('/');
}
console.log('Invalid login attempt');
res.status(401).send('Invalid Web Auth Key');
});
// ==========================
// Serve Login Page (GET /login)
// ==========================
app.get('/login', (req, res) => {
res.set('Cache-Control', 'no-store');
fs.readFile(login_path, 'utf8', (err, html) => {
if (err) {
console.error('Failed to load login.html:', err);
return res.status(500).send('Internal Server Error');
}
res.send(html);
});
});
// ==========================
// Protect Root (Serve index.html Only If Authenticated)
// ==========================
app.get('/', webAuth, (req, res) => {
res.sendFile(index_path);
});
// ==========================
// Serve Static Assets (JS/CSS) with conditional caching
// ==========================
app.use(express.static(build_path, {
setHeaders: (res, filePath) => {
const isAuthenticated = checkAuth(res.req);
if (filePath === index_path) {
if (isAuthenticated) {
res.set('Cache-Control', `public, max-age=${INDEX_CACHE}`);
} else {
res.set('Cache-Control', 'no-store');
}
} else {
res.set('Cache-Control', `public, max-age=${ASSETS_CACHE}`);
}
}
}));
// ==========================
// 404 Handler for Unknown Routes
// ==========================
app.all('*', (_req, res) => {
res.status(404).send('<h1>404! Page not found</h1>');
});
// ==========================
// Start the Server
// ==========================
app.listen(HTTP_PORT, () => {
console.info(`Server listening on port: ${HTTP_PORT}`);
});