Add INTERNAL_API_KEY authentication for error_log_api; update all services to send key
This commit is contained in:
@@ -0,0 +1,41 @@
|
|||||||
|
# Database
|
||||||
|
POSTGRES_HOST=localhost
|
||||||
|
POSTGRES_PORT=5432
|
||||||
|
POSTGRES_DB=transit_db
|
||||||
|
POSTGRES_USER_AUTH=auth_user
|
||||||
|
POSTGRES_PASSWORD_AUTH=change_me
|
||||||
|
POSTGRES_USER_EMPLOYEE=employee_user
|
||||||
|
POSTGRES_PASSWORD_EMPLOYEE=change_me
|
||||||
|
POSTGRES_USER_TRANSIT=transit_user
|
||||||
|
POSTGRES_PASSWORD_TRANSIT=change_me
|
||||||
|
POSTGRES_USER_LOGGER=logger_user
|
||||||
|
POSTGRES_PASSWORD_LOGGER=change_me
|
||||||
|
|
||||||
|
# Auth
|
||||||
|
JWT_SECRET=change_me_in_production
|
||||||
|
ADMIN_USER_CODES=1234,5678
|
||||||
|
DEV_BYPASS=0
|
||||||
|
|
||||||
|
# Internal service-to-service authentication
|
||||||
|
INTERNAL_API_KEY=generate_strong_random_string_here
|
||||||
|
|
||||||
|
# Error Log API URL (used by services to forward errors)
|
||||||
|
ERROR_LOG_API_URL=https://error.xtransit.testinstance.nl/error_log
|
||||||
|
|
||||||
|
# Monitoring UI (runtime config)
|
||||||
|
AUTH_API=https://auth.xtransit.testinstance.nl
|
||||||
|
EMPLOYEE_API=https://employees.xtransit.testinstance.nl
|
||||||
|
TRANSIT_API=https://transit.xtransit.testinstance.nl
|
||||||
|
ERROR_LOG_API=https://error.xtransit.testinstance.nl
|
||||||
|
ADMIN_UI=https://admin.xtransit.testinstance.nl
|
||||||
|
|
||||||
|
# Transit API
|
||||||
|
DEV_MOCK=0
|
||||||
|
|
||||||
|
# Registry
|
||||||
|
REGISTRY_HOST=gitea.testinstance.nl
|
||||||
|
IMAGE_NAMESPACE=sven/the-transit-project
|
||||||
|
IMAGE_TAG=latest
|
||||||
|
|
||||||
|
# Portainer webhook for auto-deploy
|
||||||
|
PORTAINER_WEBHOOK_URL=
|
||||||
+4
-1
@@ -39,7 +39,10 @@ async function reportError({ partofservice, error }) {
|
|||||||
try {
|
try {
|
||||||
await fetch(ERROR_LOG_API_URL, {
|
await fetch(ERROR_LOG_API_URL, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"x-internal-api-key": process.env.INTERNAL_API_KEY || "",
|
||||||
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
service: "auth_api",
|
service: "auth_api",
|
||||||
partofservice,
|
partofservice,
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ services:
|
|||||||
PG_USER: ${POSTGRES_USER_LOGGER}
|
PG_USER: ${POSTGRES_USER_LOGGER}
|
||||||
PG_PASS: ${POSTGRES_PASSWORD_LOGGER}
|
PG_PASS: ${POSTGRES_PASSWORD_LOGGER}
|
||||||
ERROR_LOG_API_URL: ${ERROR_LOG_API_URL:-https://error.xtransit.testinstance.nl/error_log}
|
ERROR_LOG_API_URL: ${ERROR_LOG_API_URL:-https://error.xtransit.testinstance.nl/error_log}
|
||||||
|
INTERNAL_API_KEY: ${INTERNAL_API_KEY}
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
auth_api:
|
auth_api:
|
||||||
@@ -31,6 +32,7 @@ services:
|
|||||||
ADMIN_USER_CODES: ${ADMIN_USER_CODES}
|
ADMIN_USER_CODES: ${ADMIN_USER_CODES}
|
||||||
DEV_BYPASS: ${DEV_BYPASS:-0}
|
DEV_BYPASS: ${DEV_BYPASS:-0}
|
||||||
ERROR_LOG_API_URL: ${ERROR_LOG_API_URL:-https://error.xtransit.testinstance.nl/error_log}
|
ERROR_LOG_API_URL: ${ERROR_LOG_API_URL:-https://error.xtransit.testinstance.nl/error_log}
|
||||||
|
INTERNAL_API_KEY: ${INTERNAL_API_KEY}
|
||||||
depends_on:
|
depends_on:
|
||||||
- error_log_api
|
- error_log_api
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -48,6 +50,7 @@ services:
|
|||||||
PG_USER: ${POSTGRES_USER_EMPLOYEE}
|
PG_USER: ${POSTGRES_USER_EMPLOYEE}
|
||||||
PG_PASS: ${POSTGRES_PASSWORD_EMPLOYEE}
|
PG_PASS: ${POSTGRES_PASSWORD_EMPLOYEE}
|
||||||
ERROR_LOG_API_URL: ${ERROR_LOG_API_URL:-https://error.xtransit.testinstance.nl/error_log}
|
ERROR_LOG_API_URL: ${ERROR_LOG_API_URL:-https://error.xtransit.testinstance.nl/error_log}
|
||||||
|
INTERNAL_API_KEY: ${INTERNAL_API_KEY}
|
||||||
depends_on:
|
depends_on:
|
||||||
- error_log_api
|
- error_log_api
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -67,6 +70,7 @@ services:
|
|||||||
PG_PASS: ${POSTGRES_PASSWORD_TRANSIT}
|
PG_PASS: ${POSTGRES_PASSWORD_TRANSIT}
|
||||||
DEV_MOCK: ${DEV_MOCK:-0}
|
DEV_MOCK: ${DEV_MOCK:-0}
|
||||||
ERROR_LOG_API_URL: ${ERROR_LOG_API_URL:-https://error.xtransit.testinstance.nl/error_log}
|
ERROR_LOG_API_URL: ${ERROR_LOG_API_URL:-https://error.xtransit.testinstance.nl/error_log}
|
||||||
|
INTERNAL_API_KEY: ${INTERNAL_API_KEY}
|
||||||
depends_on:
|
depends_on:
|
||||||
- error_log_api
|
- error_log_api
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|||||||
@@ -35,7 +35,10 @@ async function reportError({ partofservice, error }) {
|
|||||||
try {
|
try {
|
||||||
await fetch(ERROR_LOG_API_URL, {
|
await fetch(ERROR_LOG_API_URL, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"x-internal-api-key": process.env.INTERNAL_API_KEY || "",
|
||||||
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
service: "employee_api",
|
service: "employee_api",
|
||||||
partofservice,
|
partofservice,
|
||||||
|
|||||||
+20
-2
@@ -32,6 +32,21 @@ const app = express();
|
|||||||
app.use(express.json({ limit: "64kb" }));
|
app.use(express.json({ limit: "64kb" }));
|
||||||
app.use(cors());
|
app.use(cors());
|
||||||
|
|
||||||
|
const INTERNAL_API_KEY = process.env.INTERNAL_API_KEY || "";
|
||||||
|
|
||||||
|
function requireInternalKey(req, res, next) {
|
||||||
|
const key = req.headers["x-internal-api-key"];
|
||||||
|
if (!INTERNAL_API_KEY) {
|
||||||
|
log("error", "INTERNAL_API_KEY not configured on server");
|
||||||
|
return res.status(500).json({ error: "server misconfiguration" });
|
||||||
|
}
|
||||||
|
if (!key || key !== INTERNAL_API_KEY) {
|
||||||
|
log("warn", "Unauthorized error_log attempt", { ip: req.ip, path: req.originalUrl });
|
||||||
|
return res.status(401).json({ error: "unauthorized" });
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
|
||||||
const ERROR_LOG_API_URL =
|
const ERROR_LOG_API_URL =
|
||||||
process.env.ERROR_LOG_API_URL ||
|
process.env.ERROR_LOG_API_URL ||
|
||||||
"https://error.xtransit.testinstance.nl/error_log";
|
"https://error.xtransit.testinstance.nl/error_log";
|
||||||
@@ -48,7 +63,10 @@ async function reportError({ partofservice, error }) {
|
|||||||
try {
|
try {
|
||||||
await fetch(ERROR_LOG_API_URL, {
|
await fetch(ERROR_LOG_API_URL, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"x-internal-api-key": process.env.INTERNAL_API_KEY || "",
|
||||||
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
service: "error_log_api",
|
service: "error_log_api",
|
||||||
partofservice,
|
partofservice,
|
||||||
@@ -142,7 +160,7 @@ app.get("/health", async (_req, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
app.post("/error_log", async (req, res) => {
|
app.post("/error_log", requireInternalKey, async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const service = req.body?.service;
|
const service = req.body?.service;
|
||||||
const partofservice =
|
const partofservice =
|
||||||
|
|||||||
@@ -38,7 +38,10 @@ async function reportError({ partofservice, error }) {
|
|||||||
try {
|
try {
|
||||||
await fetch(ERROR_LOG_API_URL, {
|
await fetch(ERROR_LOG_API_URL, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"x-internal-api-key": process.env.INTERNAL_API_KEY || "",
|
||||||
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
service: "transit_api",
|
service: "transit_api",
|
||||||
partofservice,
|
partofservice,
|
||||||
|
|||||||
Reference in New Issue
Block a user