u
This commit is contained in:
@@ -22,16 +22,16 @@ const apiLog = createLogger('api');
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
async function loadRoutes(app, basePath = '') {
|
||||
async function registerRoutes(app, basePath = '') {
|
||||
const routesDir = path.join(__dirname, 'routes');
|
||||
|
||||
async function walk(dir) {
|
||||
async function registerRouteFilesRecursively(dir) {
|
||||
for (const file of fs.readdirSync(dir)) {
|
||||
const fullPath = path.join(dir, file);
|
||||
const stat = fs.statSync(fullPath);
|
||||
|
||||
if (stat.isDirectory()) {
|
||||
await walk(fullPath);
|
||||
await registerRouteFilesRecursively(fullPath);
|
||||
} else if (file.endsWith('.js')) {
|
||||
const routeModule = await import(pathToFileURL(fullPath).href);
|
||||
if (routeModule.register) {
|
||||
@@ -41,17 +41,17 @@ async function loadRoutes(app, basePath = '') {
|
||||
}
|
||||
}
|
||||
|
||||
await walk(routesDir);
|
||||
await registerRouteFilesRecursively(routesDir);
|
||||
}
|
||||
|
||||
let server;
|
||||
let httpsServer;
|
||||
let starting;
|
||||
let startedAt;
|
||||
let startupPromise;
|
||||
let serverStartedAt;
|
||||
|
||||
const PRIVATE_HOST_REGEX = /^(127\.0\.0\.1|localhost|192\.168\.\d{1,3}\.\d{1,3}|10\.\d{1,3}\.\d{1,3}\.\d{1,3}|172\.(1[6-9]|2\d|3[01])\.\d{1,3}\.\d{1,3})$/;
|
||||
const LOCAL_PRIVATE_HOST_PATTERN = /^(127\.0\.0\.1|localhost|192\.168\.\d{1,3}\.\d{1,3}|10\.\d{1,3}\.\d{1,3}\.\d{1,3}|172\.(1[6-9]|2\d|3[01])\.\d{1,3}\.\d{1,3})$/;
|
||||
|
||||
function isAllowedOrigin(origin) {
|
||||
function isAllowedCorsOrigin(origin) {
|
||||
if (!origin) return false;
|
||||
if (env.corsOrigins.includes(origin)) return true;
|
||||
try {
|
||||
@@ -59,7 +59,7 @@ function isAllowedOrigin(origin) {
|
||||
if (u.hostname === 'quixpos.com' || u.hostname.endsWith('.quixpos.com')) {
|
||||
return true;
|
||||
}
|
||||
if (PRIVATE_HOST_REGEX.test(u.hostname)) {
|
||||
if (LOCAL_PRIVATE_HOST_PATTERN.test(u.hostname)) {
|
||||
return true;
|
||||
}
|
||||
} catch {
|
||||
@@ -101,7 +101,7 @@ function corsMiddleware(req, res, next) {
|
||||
return next();
|
||||
}
|
||||
|
||||
if (origin && isAllowedOrigin(origin)) {
|
||||
if (origin && isAllowedCorsOrigin(origin)) {
|
||||
res.setHeader('Access-Control-Allow-Origin', origin);
|
||||
res.setHeader('Vary', 'Origin');
|
||||
res.setHeader('Access-Control-Allow-Credentials', 'true');
|
||||
@@ -120,7 +120,7 @@ function corsMiddleware(req, res, next) {
|
||||
next();
|
||||
}
|
||||
|
||||
async function createApi() {
|
||||
async function buildApiApp() {
|
||||
const app = express();
|
||||
|
||||
app.use((req, res, next) => {
|
||||
@@ -136,14 +136,14 @@ async function createApi() {
|
||||
app.use(loggerMiddleware);
|
||||
app.use(authMiddleware);
|
||||
|
||||
if (startedAt) {
|
||||
if (serverStartedAt) {
|
||||
app.use((req, res, next) => {
|
||||
res.setHeader('X-Server-Started-At', startedAt);
|
||||
res.setHeader('X-Server-Started-At', serverStartedAt);
|
||||
next();
|
||||
});
|
||||
}
|
||||
|
||||
await loadRoutes(app, '/api');
|
||||
await registerRoutes(app, '/api');
|
||||
app.use('/v1', v1Router);
|
||||
app.use('/api/v1', v1Router);
|
||||
|
||||
@@ -166,7 +166,7 @@ async function createApi() {
|
||||
return app;
|
||||
}
|
||||
|
||||
function listenServer(instance, port, protocol) {
|
||||
function listenOnPort(instance, port, protocol) {
|
||||
return new Promise((resolve, reject) => {
|
||||
instance.once('listening', () => {
|
||||
resolve();
|
||||
@@ -196,18 +196,18 @@ export async function startApi() {
|
||||
if (server || httpsServer) {
|
||||
return server;
|
||||
}
|
||||
if (starting) {
|
||||
return starting;
|
||||
if (startupPromise) {
|
||||
return startupPromise;
|
||||
}
|
||||
|
||||
starting = (async () => {
|
||||
startupPromise = (async () => {
|
||||
await ensureConnection();
|
||||
|
||||
startedAt = new Date().toISOString();
|
||||
const app = await createApi();
|
||||
serverStartedAt = new Date().toISOString();
|
||||
const app = await buildApiApp();
|
||||
|
||||
const httpInstance = http.createServer(app);
|
||||
await listenServer(httpInstance, env.port, 'HTTP');
|
||||
await listenOnPort(httpInstance, env.port, 'HTTP');
|
||||
server = httpInstance;
|
||||
apiLog.info(`API listening on port ${env.port} (HTTP)`);
|
||||
|
||||
@@ -215,7 +215,7 @@ export async function startApi() {
|
||||
try {
|
||||
const tls = await getOrCreateCert();
|
||||
const httpsInstance = https.createServer(tls, app);
|
||||
await listenServer(httpsInstance, env.httpsPort, 'HTTPS');
|
||||
await listenOnPort(httpsInstance, env.httpsPort, 'HTTPS');
|
||||
httpsServer = httpsInstance;
|
||||
apiLog.info(`API listening on port ${env.httpsPort} (HTTPS self-signed)`);
|
||||
} catch (err) {
|
||||
@@ -227,9 +227,9 @@ export async function startApi() {
|
||||
})();
|
||||
|
||||
try {
|
||||
return await starting;
|
||||
return await startupPromise;
|
||||
} finally {
|
||||
starting = undefined;
|
||||
startupPromise = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user