ryu-js / plugins /federations.js
randydev's picture
Upload federations.js
7bf9990 verified
import express from 'express';
import axios from 'axios';
import { TelegramUseLog } from '../lib/all.js';
import { Database } from '../database/database.js';
import { authenticateApiKey, apiLimiter } from '../middleware/midware.js';
import { Federation } from '../models.js';
const FedsRoutes = express.Router();
const dbClient = new Database("AkenoXJs");
const db = dbClient.collection("api_keys");
async function updateIP(apiKey, newIP) {
await db.updateOne(
{ key: apiKey },
{ $addToSet: { ip_addresses: newIP } }
);
}
/**
* @swagger
* /api/v2/federation/newfed:
* post:
* summary: Create a new federation
* tags: [Federation]
* description: Creates a new federation with a unique name and owner.
* security:
* - apiKeyAuth: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* name:
* type: string
* description: The unique name of the federation.
* owner:
* type: integer
* description: The user ID of the federation owner.
* parameters:
* - in: header
* name: x-api-key
* required: true
* description: API key for authentication.
* schema:
* type: string
* responses:
* 200:
* description: Federation created successfully.
* content:
* application/json:
* schema:
* type: object
* properties:
* message:
* type: string
* example: Federation created successfully
* federation:
* type: object
* properties:
* name:
* type: string
* owner:
* type: integer
* banned_users:
* type: array
* items:
* type: integer
* sub_federations:
* type: array
* items:
* type: string
* 400:
* description: Federation already exists or missing parameters.
* 500:
* description: Internal server error.
*/
FedsRoutes.post("/api/v2/federation/newfed", authenticateApiKey, apiLimiter, async (req, res) => {
try {
const apiKey = req.headers['x-api-key'];
const userAgent = req.headers['user-agent'];
const xForwardedFor = req.headers['x-forwarded-for'];
const xRealIP = req.headers['x-real-ip'];
const cfConnectingIP = req.headers['cf-connecting-ip'];
let realIP = req.ip;
if (xForwardedFor) {
realIP = xForwardedFor.split(',')[0].trim();
} else if (xRealIP) {
realIP = xRealIP;
} else if (cfConnectingIP) {
realIP = cfConnectingIP;
}
req.realIP = realIP;
console.log(`🔍 Captured IPs:`, { xForwardedFor, xRealIP, cfConnectingIP, realIP });
const keyDoc = await db.findOne({ key: apiKey });
if (!keyDoc) {
return res.status(403).json({ error: "Invalid API Key." });
}
const { name, owner } = req.body;
const existing = await Federation.findOne({ name });
if (existing) return res.status(200).json({ error: "Federation already exists" });
await updateIP(apiKey, realIP);
await TelegramUseLog(
keyDoc.owner,
keyDoc.key,
`Accessed: ${req.path}\nRealIP: ${realIP}\nUser-Agent: ${userAgent}`
);
const federation = new Federation({ name, owner, banned_users: [], sub_federations: [] });
await federation.save();
res.json({ message: "Federation created successfully", federation });
} catch (err) {
console.log(err.message);
res.status(500).json({ error: err.message });
}
});
/**
* @swagger
* /api/v2/federation/subfed:
* post:
* summary: Add a sub-federation
* tags: [Federation]
* description: Adds a federation as a sub-federation under a parent federation.
* security:
* - apiKeyAuth: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* parent_uuid:
* type: string
* description: UUID of the parent federation.
* child_uuid:
* type: string
* description: UUID of the child federation to be added as a sub-federation.
* parameters:
* - in: header
* name: x-api-key
* required: true
* description: API key for authentication.
* schema:
* type: string
* responses:
* 200:
* description: Sub-federation added successfully.
* content:
* application/json:
* schema:
* type: object
* properties:
* message:
* type: string
* example: "Federation ChildName is now a sub-federation of ParentName"
* 404:
* description: Parent or child federation not found.
* 500:
* description: Internal server error.
*/
FedsRoutes.post("/api/v2/federation/subfed", authenticateApiKey, apiLimiter, async (req, res) => {
try {
const apiKey = req.headers['x-api-key'];
const userAgent = req.headers['user-agent'];
const xForwardedFor = req.headers['x-forwarded-for'];
const xRealIP = req.headers['x-real-ip'];
const cfConnectingIP = req.headers['cf-connecting-ip'];
let realIP = req.ip;
if (xForwardedFor) {
realIP = xForwardedFor.split(',')[0].trim();
} else if (xRealIP) {
realIP = xRealIP;
} else if (cfConnectingIP) {
realIP = cfConnectingIP;
}
req.realIP = realIP;
console.log(`🔍 Captured IPs:`, { xForwardedFor, xRealIP, cfConnectingIP, realIP });
const keyDoc = await db.findOne({ key: apiKey });
if (!keyDoc) {
return res.status(403).json({ error: "Invalid API Key." });
}
const { parent_uuid, child_uuid } = req.body;
const parent = await Federation.findOne({ uuid: parent_uuid });
const child = await Federation.findOne({ uuid: child_uuid });
if (!parent || !child) return res.status(404).json({ error: "Federation not found" });
if (!parent.sub_federations.includes(child.uuid)) {
parent.sub_federations.push(child.uuid);
await parent.save();
}
await updateIP(apiKey, realIP);
await TelegramUseLog(
keyDoc.owner,
keyDoc.key,
`Accessed: ${req.path}\nRealIP: ${realIP}\nUser-Agent: ${userAgent}`
);
res.json({ message: `Federation ${child.name} is now a sub-federation of ${parent.name}` });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
/**
* @swagger
* /api/v2/federation/getfed/{uuid}:
* get:
* summary: Check Federation Info
* tags: [Federation]
* parameters:
* - in: path
* name: uuid
* required: true
* description: Check uuid to info
* schema:
* type: string
* - in: header
* name: x-api-key
* required: true
* description: API key for authentication
* schema:
* type: string
* responses:
* 200:
* description: Returns
*/
FedsRoutes.get("/api/v2/federation/getfed/:uuid", authenticateApiKey, apiLimiter, async (req, res) => {
try {
const apiKey = req.headers['x-api-key'];
const userAgent = req.headers['user-agent'];
const xForwardedFor = req.headers['x-forwarded-for'];
const xRealIP = req.headers['x-real-ip'];
const cfConnectingIP = req.headers['cf-connecting-ip'];
let realIP = req.ip;
if (xForwardedFor) {
realIP = xForwardedFor.split(',')[0].trim();
} else if (xRealIP) {
realIP = xRealIP;
} else if (cfConnectingIP) {
realIP = cfConnectingIP;
}
req.realIP = realIP;
console.log(`🔍 Captured IPs:`, { xForwardedFor, xRealIP, cfConnectingIP, realIP });
const keyDoc = await db.findOne({ key: apiKey });
if (!keyDoc) {
return res.status(403).json({ error: "Invalid API Key." });
}
const federation = await Federation.findOne({ uuid: req.params.uuid });
if (!federation) return res.status(404).json({ error: "Federation not found" });
const subFeds = await Federation.find({ uuid: { $in: federation.sub_federations } });
await updateIP(apiKey, realIP);
await TelegramUseLog(
keyDoc.owner,
keyDoc.key,
`Accessed: ${req.path}\nRealIP: ${realIP}\nUser-Agent: ${userAgent}`
);
res.json({ federation, sub_federations: subFeds });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
/**
* @swagger
* /api/v2/federation/unban:
* post:
* summary: Unban a user in a federation
* tags: [Federation]
* description: Removes a user from the banned list of a specified federation.
* security:
* - apiKeyAuth: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* name:
* type: string
* description: Name of the federation where the user will be unbanned.
* user_id:
* type: integer
* description: User ID to be unbanned.
* parameters:
* - in: header
* name: x-api-key
* required: true
* description: API key for authentication.
* schema:
* type: string
* responses:
* 200:
* description: User unbanned successfully.
* content:
* application/json:
* schema:
* type: object
* properties:
* success:
* type: boolean
* example: true
* message:
* type: string
* example: "User 12345 unbanned from federation FederationName."
* 400:
* description: Missing federation name or user ID.
* 404:
* description: Federation not found.
* 500:
* description: Internal server error.
*/
FedsRoutes.post('/api/v2/federation/unban', authenticateApiKey, async (req, res) => {
try {
const apiKey = req.headers['x-api-key'];
const userAgent = req.headers['user-agent'];
const xForwardedFor = req.headers['x-forwarded-for'];
const xRealIP = req.headers['x-real-ip'];
const cfConnectingIP = req.headers['cf-connecting-ip'];
let realIP = req.ip;
if (xForwardedFor) {
realIP = xForwardedFor.split(',')[0].trim();
} else if (xRealIP) {
realIP = xRealIP;
} else if (cfConnectingIP) {
realIP = cfConnectingIP;
}
req.realIP = realIP;
console.log(`🔍 Captured IPs:`, { xForwardedFor, xRealIP, cfConnectingIP, realIP });
const keyDoc = await db.findOne({ key: apiKey });
if (!keyDoc) {
return res.status(403).json({ error: "Invalid API Key." });
}
const { name, user_id } = req.body;
if (!name || !user_id || isNaN(user_id)) {
return res.status(400).json({ error: "Federation name and valid user ID required" });
}
const federation = await Federation.findOne({ name });
if (!federation) {
return res.status(404).json({ error: "Federation not found." });
}
federation.banned_users = federation.banned_users.filter(id => Number(id) !== Number(user_id));
await federation.save();
await Federation.updateMany(
{ uuid: { $in: federation.sub_federations } },
{ $pull: { banned_users: Number(user_id) } }
);
await updateIP(apiKey, realIP);
await TelegramUseLog(
keyDoc.owner,
keyDoc.key,
`Accessed: ${req.path}\nRealIP: ${realIP}\nUser-Agent: ${userAgent}`
);
res.json({ success: true, message: `User ${user_id} unbanned from ${name} and its sub-federations.` });
} catch (error) {
res.status(500).json({ error: `Failed to unban user: ${error.message}` });
}
});
/**
* @swagger
* /api/v2/federation/ban:
* post:
* summary: Ban a user in a federation
* tags: [Federation]
* description: Bans a user in the specified federation and all its sub-federations.
* security:
* - apiKeyAuth: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* federation_uuid:
* type: string
* description: UUID of the federation where the user will be banned.
* user_id:
* type: integer
* description: User ID to be banned.
* parameters:
* - in: header
* name: x-api-key
* required: true
* description: API key for authentication.
* schema:
* type: string
* responses:
* 200:
* description: User banned successfully.
* content:
* application/json:
* schema:
* type: object
* properties:
* message:
* type: string
* example: "User 12345 banned in FederationName and all its sub-federations"
* 404:
* description: Federation not found.
* 500:
* description: Internal server error.
*/
FedsRoutes.post("/api/v2/federation/ban", authenticateApiKey, apiLimiter, async (req, res) => {
try {
const apiKey = req.headers['x-api-key'];
const userAgent = req.headers['user-agent'];
const xForwardedFor = req.headers['x-forwarded-for'];
const xRealIP = req.headers['x-real-ip'];
const cfConnectingIP = req.headers['cf-connecting-ip'];
let realIP = req.ip;
if (xForwardedFor) {
realIP = xForwardedFor.split(',')[0].trim();
} else if (xRealIP) {
realIP = xRealIP;
} else if (cfConnectingIP) {
realIP = cfConnectingIP;
}
req.realIP = realIP;
console.log(`🔍 Captured IPs:`, { xForwardedFor, xRealIP, cfConnectingIP, realIP });
const keyDoc = await db.findOne({ key: apiKey });
if (!keyDoc) {
return res.status(403).json({ error: "Invalid API Key." });
}
const { federation_uuid, user_id } = req.body;
if (!federation_uuid || !user_id || isNaN(user_id)) {
return res.status(400).json({ error: "Federation UUID and valid user ID required" });
}
const federation = await Federation.findOne({ uuid: federation_uuid });
if (!federation) return res.status(404).json({ error: "Federation not found" });
if (!federation.banned_users.includes(Number(user_id))) {
federation.banned_users.push(Number(user_id));
await federation.save();
}
await Federation.updateMany(
{ uuid: { $in: federation.sub_federations } },
{ $addToSet: { banned_users: Number(user_id) } }
);
await updateIP(apiKey, realIP);
await TelegramUseLog(
keyDoc.owner,
keyDoc.key,
`Accessed: ${req.path}\nRealIP: ${realIP}\nUser-Agent: ${userAgent}`
);
res.json({ message: `User ${user_id} banned in ${federation.name} and all its sub-federations.` });
console.log(user_id);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
/**
* @swagger
* /api/v2/federation/ban-check:
* post:
* summary: Check if a user is banned in a federation
* tags: [Federation]
* description: Checks whether a user is banned in a specific federation using UUID and user ID.
* security:
* - apiKeyAuth: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* federation_uuid:
* type: string
* description: UUID of the federation.
* user_id:
* type: integer
* description: User ID to check.
* parameters:
* - in: header
* name: x-api-key
* required: true
* description: API key for authentication.
* schema:
* type: string
* responses:
* 200:
* description: Ban status of the user in the federation.
* content:
* application/json:
* schema:
* type: object
* properties:
* federation:
* type: string
* example: "AkenoX Federation"
* user_id:
* type: integer
* example: 12345
* is_banned:
* type: boolean
* example: true
* 400:
* description: Missing federation UUID or invalid user ID.
* 404:
* description: Federation not found.
* 500:
* description: Internal server error.
*/
FedsRoutes.post("/api/v2/federation/ban-check", authenticateApiKey, async (req, res) => {
try {
const apiKey = req.headers['x-api-key'];
const userAgent = req.headers['user-agent'];
const xForwardedFor = req.headers['x-forwarded-for'];
const xRealIP = req.headers['x-real-ip'];
const cfConnectingIP = req.headers['cf-connecting-ip'];
let realIP = req.ip;
if (xForwardedFor) {
realIP = xForwardedFor.split(',')[0].trim();
} else if (xRealIP) {
realIP = xRealIP;
} else if (cfConnectingIP) {
realIP = cfConnectingIP;
}
req.realIP = realIP;
console.log(`🔍 Captured IPs:`, { xForwardedFor, xRealIP, cfConnectingIP, realIP });
const keyDoc = await db.findOne({ key: apiKey });
if (!keyDoc) {
return res.status(403).json({ error: "Invalid API Key." });
}
const { federation_uuid, user_id } = req.body;
if (!federation_uuid || !user_id || isNaN(user_id)) {
return res.status(400).json({ error: "Federation UUID and valid user ID required." });
}
const federation = await Federation.findOne({ uuid: federation_uuid });
if (!federation) {
return res.status(404).json({ error: "Federation not found." });
}
const isBanned = federation.banned_users.includes(user_id);
await updateIP(apiKey, realIP);
await TelegramUseLog(
keyDoc.owner,
keyDoc.key,
`Accessed: ${req.path}\nRealIP: ${realIP}\nUser-Agent: ${userAgent}`
);
res.json({
federation: federation.name,
user_id,
is_banned: isBanned
});
} catch (error) {
res.status(500).json({ error: `Failed to check ban status: ${error.message}` });
}
});
/**
* @swagger
* /api/v2/federation/fedstats:
* get:
* summary: Get Federation Statistics
* tags: [Federation]
* description: Retrieve the statistics of a federation, including total banned users and sub-federations.
* parameters:
* - in: query
* name: uuid
* required: true
* description: UUID of the federation to check stats for.
* schema:
* type: string
* - in: header
* name: x-api-key
* required: true
* description: API key for authentication.
* schema:
* type: string
* responses:
* 200:
* description: Federation statistics retrieved successfully.
* content:
* application/json:
* schema:
* type: object
* properties:
* success:
* type: boolean
* example: true
* stats:
* type: object
* properties:
* federation_name:
* type: string
* example: "Example Federation"
* total_banned_users:
* type: integer
* example: 10
* total_sub_federations:
* type: integer
* example: 3
* owner:
* type: number
* example: 123456789
* 400:
* description: Missing or invalid federation UUID.
* 404:
* description: Federation not found.
* 500:
* description: Internal server error.
*/
FedsRoutes.get("/api/v2/federation/fedstats", authenticateApiKey, async (req, res) => {
try {
const apiKey = req.headers['x-api-key'];
const userAgent = req.headers['user-agent'];
const xForwardedFor = req.headers['x-forwarded-for'];
const xRealIP = req.headers['x-real-ip'];
const cfConnectingIP = req.headers['cf-connecting-ip'];
let realIP = req.ip;
if (xForwardedFor) {
realIP = xForwardedFor.split(',')[0].trim();
} else if (xRealIP) {
realIP = xRealIP;
} else if (cfConnectingIP) {
realIP = cfConnectingIP;
}
req.realIP = realIP;
console.log(`🔍 Captured IPs:`, { xForwardedFor, xRealIP, cfConnectingIP, realIP });
const keyDoc = await db.findOne({ key: apiKey });
if (!keyDoc) {
return res.status(403).json({ error: "Invalid API Key." });
}
const { uuid } = req.query;
if (!uuid) {
return res.status(400).json({ error: "Federation UUID is required" });
}
const federation = await Federation.findOne({ uuid });
if (!federation) {
return res.status(404).json({ error: "Federation not found" });
}
const stats = {
federation_name: federation.name,
total_banned_users: federation.banned_users.length,
total_sub_federations: federation.sub_federations.length,
owner: federation.owner,
};
await updateIP(apiKey, realIP);
await TelegramUseLog(
keyDoc.owner,
keyDoc.key,
`Accessed: ${req.path}\nRealIP: ${realIP}\nUser-Agent: ${userAgent}`
);
res.json({ success: true, stats });
} catch (error) {
res.status(500).json({ error: `Failed to fetch federation stats: ${error.message}` });
}
});
/**
* @swagger
* /api/v2/federation/unsubfed:
* post:
* summary: Unsubscribe a Sub-Federation
* tags: [Federation]
* description: Remove a sub-federation from a parent federation.
* security:
* - apiKeyAuth: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* parent_uuid:
* type: string
* description: UUID of the parent federation.
* child_uuid:
* type: string
* description: UUID of the sub-federation to be removed.
* parameters:
* - in: header
* name: x-api-key
* required: true
* description: API key for authentication.
* schema:
* type: string
* responses:
* 200:
* description: Sub-federation successfully removed.
* content:
* application/json:
* schema:
* type: object
* properties:
* message:
* type: string
* example: "Federation SubFed has been unsubscribed from ParentFed."
* 400:
* description: Missing or invalid federation UUIDs.
* 404:
* description: Federation not found.
* 500:
* description: Internal server error.
*/
FedsRoutes.post("/api/v2/federation/unsubfed", authenticateApiKey, apiLimiter, async (req, res) => {
try {
const apiKey = req.headers['x-api-key'];
const userAgent = req.headers['user-agent'];
const xForwardedFor = req.headers['x-forwarded-for'];
const xRealIP = req.headers['x-real-ip'];
const cfConnectingIP = req.headers['cf-connecting-ip'];
let realIP = req.ip;
if (xForwardedFor) {
realIP = xForwardedFor.split(',')[0].trim();
} else if (xRealIP) {
realIP = xRealIP;
} else if (cfConnectingIP) {
realIP = cfConnectingIP;
}
req.realIP = realIP;
console.log(`🔍 Captured IPs:`, { xForwardedFor, xRealIP, cfConnectingIP, realIP });
const keyDoc = await db.findOne({ key: apiKey });
if (!keyDoc) {
return res.status(403).json({ error: "Invalid API Key." });
}
const { parent_uuid, child_uuid } = req.body;
if (!parent_uuid || !child_uuid) {
return res.status(400).json({ error: "Both parent and child federation UUIDs are required." });
}
const parent = await Federation.findOne({ uuid: parent_uuid });
const child = await Federation.findOne({ uuid: child_uuid });
if (!parent || !child) {
return res.status(404).json({ error: "Federation not found." });
}
parent.sub_federations = parent.sub_federations.filter(uuid => uuid !== child_uuid);
await parent.save();
await updateIP(apiKey, realIP);
await TelegramUseLog(
keyDoc.owner,
keyDoc.key,
`Accessed: ${req.path}\nRealIP: ${realIP}\nUser-Agent: ${userAgent}`
);
res.json({ message: `Federation ${child.name} has been unsubscribed from ${parent.name}` });
} catch (error) {
res.status(500).json({ error: `Failed to unsubscribe sub-federation: ${error.message}` });
}
});
/**
* @swagger
* /api/v2/federation/renamefed:
* post:
* summary: Rename a Federation
* tags: [Federation]
* description: Change the name of an existing federation.
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* federation_uuid:
* type: string
* description: UUID of the federation to be renamed.
* new_name:
* type: string
* description: The new name for the federation.
* parameters:
* - in: header
* name: x-api-key
* required: true
* description: API key for authentication.
* schema:
* type: string
* responses:
* 200:
* description: Federation successfully renamed.
* content:
* application/json:
* schema:
* type: object
* properties:
* message:
* type: string
* example: "Federation renamed to NewFedName successfully."
* 400:
* description: Missing parameters or federation name already exists.
* 404:
* description: Federation not found.
* 500:
* description: Internal server error.
*/
FedsRoutes.post("/api/v2/federation/renamefed", authenticateApiKey, apiLimiter, async (req, res) => {
try {
const apiKey = req.headers['x-api-key'];
const userAgent = req.headers['user-agent'];
const xForwardedFor = req.headers['x-forwarded-for'];
const xRealIP = req.headers['x-real-ip'];
const cfConnectingIP = req.headers['cf-connecting-ip'];
let realIP = req.ip;
if (xForwardedFor) {
realIP = xForwardedFor.split(',')[0].trim();
} else if (xRealIP) {
realIP = xRealIP;
} else if (cfConnectingIP) {
realIP = cfConnectingIP;
}
req.realIP = realIP;
console.log(`🔍 Captured IPs:`, { xForwardedFor, xRealIP, cfConnectingIP, realIP });
const keyDoc = await db.findOne({ key: apiKey });
if (!keyDoc) {
return res.status(403).json({ error: "Invalid API Key." });
}
const { federation_uuid, new_name } = req.body;
if (!federation_uuid || !new_name) {
return res.status(400).json({ error: "Federation UUID and new name are required." });
}
const federation = await Federation.findOne({ uuid: federation_uuid });
if (!federation) {
return res.status(404).json({ error: "Federation not found." });
}
const existingFederation = await Federation.findOne({ name: new_name });
if (existingFederation) {
return res.status(400).json({ error: "Federation name already exists." });
}
federation.name = new_name;
await federation.save();
await updateIP(apiKey, realIP);
await TelegramUseLog(
keyDoc.owner,
keyDoc.key,
`Accessed: ${req.path}\nRealIP: ${realIP}\nUser-Agent: ${userAgent}`
);
res.json({ message: `Federation renamed to ${new_name} successfully.` });
} catch (error) {
res.status(500).json({ error: `Failed to rename federation: ${error.message}` });
}
});
export { FedsRoutes };