feat: Implement the core InterNetX DDNS updater application with API, services, middleware, Docker support, and a detailed README.

This commit is contained in:
2026-01-26 19:53:31 +01:00
parent bba71a7272
commit 11d2c1fce2
19 changed files with 1739 additions and 2 deletions

View File

@@ -0,0 +1,98 @@
const express = require('express');
const router = express.Router();
const ddnsService = require('../services/ddns.service');
const authenticate = require('../middleware/auth.middleware');
const { validate, updateSchema } = require('../middleware/validation.middleware');
const { updateLimiter } = require('../middleware/rateLimiter.middleware');
const { getClientIP } = require('../utils/ipHelper');
const { logger } = require('../utils/logger');
/**
* GET/POST /update
* Update DNS record for router DDNS
*
* Query/Body Parameters:
* - hostname: Full hostname (e.g., "home.ddns.netstack.berlin")
* - myip: IPv4 address (optional)
* - myipv6: IPv6 address (optional)
* - token: Authentication token
*/
router.all('/update',
updateLimiter,
validate(updateSchema),
authenticate,
async (req, res) => {
try {
const { hostname, myip, myipv6 } = req.validatedData;
const clientIP = getClientIP(req);
// Use provided IPs or fallback to client IP
let ipv4 = myip;
let ipv6 = myipv6;
// If no IP provided, use client IP (auto-detect version)
if (!ipv4 && !ipv6) {
const { detectIPVersion } = require('../utils/ipHelper');
const version = detectIPVersion(clientIP);
if (version === 'ipv4') {
ipv4 = clientIP;
} else if (version === 'ipv6') {
ipv6 = clientIP;
}
}
logger.info('DDNS update request', {
hostname,
ipv4,
ipv6,
clientIP,
token: req.tokenPrefix,
});
// Update DNS record
const result = await ddnsService.updateDNSRecord(hostname, ipv4, ipv6);
if (!result.success) {
logger.error('DDNS update failed', {
hostname,
error: result.error,
});
return res.status(500).json({
status: 'error',
message: result.error || 'Failed to update DNS record',
});
}
// Success response
logger.info('DDNS update successful', {
hostname,
results: result.results,
});
res.json({
status: 'success',
message: 'DNS record updated successfully',
hostname,
updates: result.results.map(r => ({
type: r.type,
action: r.action,
value: r.record?.value,
})),
});
} catch (error) {
logger.error('Unexpected error in update endpoint', {
error: error.message,
stack: error.stack,
});
res.status(500).json({
status: 'error',
message: 'An unexpected error occurred',
});
}
}
);
module.exports = router;