96 lines
2.7 KiB
PHP
96 lines
2.7 KiB
PHP
<?php
|
|
/**
|
|
* POST /api/hub/vcgateway/invites/create.php
|
|
*
|
|
* Create an invite link for VC Gateway.
|
|
* Requires agent auth (X-Agent-Address header).
|
|
*
|
|
* Body:
|
|
* Label string optional Human label (e.g. "Sequoia - Partner X")
|
|
* AllowedChannels int[] required Array of Hub_Channels.ID the visitor can read
|
|
* HostAddress string required Sprinter agent address for DM target
|
|
* ExpiresAt string optional ISO8601 expiration datetime (null = never)
|
|
* MaxUses int optional Max times this link can be used (0 = unlimited)
|
|
*
|
|
* Response:
|
|
* OK, ID, Token, InviteURL
|
|
*/
|
|
|
|
require_once __DIR__ . '/../helpers.php';
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
jsonResponse(['OK' => false, 'ERROR' => 'method_not_allowed'], 405);
|
|
}
|
|
|
|
$agentAddress = requireAgentAuth();
|
|
$body = readJsonBody();
|
|
|
|
// Validate required fields
|
|
$allowedChannels = $body['AllowedChannels'] ?? null;
|
|
$hostAddress = trim($body['HostAddress'] ?? '');
|
|
|
|
if (!is_array($allowedChannels) || empty($allowedChannels)) {
|
|
jsonResponse(['OK' => false, 'ERROR' => 'allowed_channels_required'], 400);
|
|
}
|
|
|
|
if (empty($hostAddress)) {
|
|
jsonResponse(['OK' => false, 'ERROR' => 'host_address_required'], 400);
|
|
}
|
|
|
|
// Validate all channel IDs exist
|
|
$channelIds = array_map('intval', $allowedChannels);
|
|
$placeholders = implode(',', array_fill(0, count($channelIds), '?'));
|
|
$channels = queryTimed(
|
|
"SELECT ID FROM Hub_Channels WHERE ID IN ($placeholders)",
|
|
$channelIds
|
|
);
|
|
|
|
$foundIds = array_column($channels, 'ID');
|
|
$missing = array_diff($channelIds, array_map('intval', $foundIds));
|
|
if (!empty($missing)) {
|
|
jsonResponse(['OK' => false, 'ERROR' => 'invalid_channel_ids', 'InvalidIDs' => array_values($missing)], 400);
|
|
}
|
|
|
|
// Optional fields
|
|
$label = trim($body['Label'] ?? '');
|
|
if (strlen($label) > 255) {
|
|
$label = substr($label, 0, 255);
|
|
}
|
|
|
|
$expiresAt = null;
|
|
if (!empty($body['ExpiresAt'])) {
|
|
$dt = strtotime($body['ExpiresAt']);
|
|
if ($dt === false || $dt <= time()) {
|
|
jsonResponse(['OK' => false, 'ERROR' => 'expires_at_must_be_future'], 400);
|
|
}
|
|
$expiresAt = date('Y-m-d H:i:s', $dt);
|
|
}
|
|
|
|
$maxUses = max(0, (int)($body['MaxUses'] ?? 0));
|
|
|
|
// Generate a URL-safe token
|
|
$token = bin2hex(random_bytes(24)); // 48 chars, URL-safe
|
|
|
|
queryTimed(
|
|
"INSERT INTO Hub_InviteLinks (Token, Label, AllowedChannels, HostAddress, ExpiresAt, MaxUses, CreatedBy)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?)",
|
|
[
|
|
$token,
|
|
$label,
|
|
json_encode($channelIds),
|
|
$hostAddress,
|
|
$expiresAt,
|
|
$maxUses,
|
|
$agentAddress,
|
|
]
|
|
);
|
|
|
|
$id = (int)lastInsertId();
|
|
$inviteUrl = baseUrl() . '/vc/' . $token;
|
|
|
|
jsonResponse([
|
|
'OK' => true,
|
|
'ID' => $id,
|
|
'Token' => $token,
|
|
'InviteURL' => $inviteUrl,
|
|
]);
|