diff --git a/web/includes/vision.php b/web/includes/vision.php
index 45365a0..58751ec 100644
--- a/web/includes/vision.php
+++ b/web/includes/vision.php
@@ -1,76 +1,65 @@
&machine_id=&hostname=
*/
-define('VISION_API_URL', 'https://vision.copydev.fr/api');
-define('VISION_APP_ID', 'copymail');
+define('VISION_LICENSE_URL', 'https://vision.copydev.fr/api/license.php');
+define('VISION_PRODUCT', 'copymail');
+
+function vision_machine_id(): string {
+ $id = cfg('vision_machine_id', '');
+ if (!$id) {
+ $id = strtolower('copymail-' . bin2hex(random_bytes(6)));
+ cfg_set('vision_machine_id', $id);
+ }
+ return $id;
+}
function vision_check(): array {
- $keyprog = cfg('vision_keyprog', '');
- if (!$keyprog) {
- return ['valid' => false, 'msg' => 'Clé Vision non configurée.'];
+ $key = cfg('vision_license_key', '');
+ if (!$key) {
+ return ['valid' => false, 'msg' => 'Licence non configurée.', 'unconfigured' => true];
}
- $payload = [
- 'app' => VISION_APP_ID,
- 'keyprog' => $keyprog,
- 'version' => cfg('app_version', '1.0'),
- 'hostname' => cfg('hostname', gethostname()),
- 'ip' => $_SERVER['SERVER_ADDR'] ?? '',
- ];
+ $url = VISION_LICENSE_URL . '?' . http_build_query([
+ 'key' => $key,
+ 'machine_id' => vision_machine_id(),
+ 'hostname' => cfg('hostname', gethostname()),
+ ]);
$ctx = stream_context_create(['http' => [
- 'method' => 'POST',
- 'header' => "Content-Type: application/json\r\n",
- 'content' => json_encode($payload),
+ 'method' => 'GET',
'timeout' => 5,
'ignore_errors' => true,
]]);
- $resp = @file_get_contents(VISION_API_URL . '/check', false, $ctx);
+ $resp = @file_get_contents($url, false, $ctx);
+
if ($resp === false) {
- return ['valid' => true, 'msg' => 'Vision injoignable — mode dégradé.'];
+ // Vision injoignable — on vérifie le délai offline autorisé
+ $lastOk = (int)cfg('vision_last_ok', '0');
+ $timeout = (int)cfg('vision_offline_timeout', '72');
+ $elapsed = (time() - $lastOk) / 3600;
+ if ($lastOk && $elapsed < $timeout) {
+ return ['valid' => true, 'msg' => "Vision injoignable (mode dégradé, {$timeout}h max)", 'degraded' => true];
+ }
+ return ['valid' => false, 'msg' => 'Vision injoignable et délai offline dépassé.'];
}
$data = json_decode($resp, true);
- return [
- 'valid' => (bool)($data['valid'] ?? false),
- 'msg' => $data['message'] ?? '',
- 'config' => $data['config'] ?? [],
- ];
-}
-function vision_push_config(array $config): void {
- // Applique la config reçue depuis Vision en BDD
- foreach ($config as $key => $value) {
- cfg_set($key, $value);
+ if (!empty($data['valid'])) {
+ cfg_set('vision_last_ok', (string)time());
+ cfg_set('vision_offline_timeout', (string)($data['offline_timeout_hours'] ?? 72));
+ return [
+ 'valid' => true,
+ 'client' => $data['client'] ?? '',
+ 'product' => $data['product'] ?? '',
+ 'expires' => $data['expires_at'] ?? null,
+ 'devices' => $data['max_devices'] ?? 1,
+ ];
}
-}
-
-function vision_register(): bool {
- $keyprog = cfg('vision_keyprog', '');
- if (!$keyprog) return false;
-
- $payload = [
- 'app' => VISION_APP_ID,
- 'keyprog' => $keyprog,
- 'hostname' => cfg('hostname', gethostname()),
- 'domain' => cfg('domain', ''),
- 'version' => cfg('app_version', '1.0'),
- 'accounts' => (int)db()->query('SELECT COUNT(*) FROM accounts WHERE active=1')->fetchColumn(),
- ];
-
- $ctx = stream_context_create(['http' => [
- 'method' => 'POST',
- 'header' => "Content-Type: application/json\r\n",
- 'content' => json_encode($payload),
- 'timeout' => 5,
- 'ignore_errors' => true,
- ]]);
-
- $resp = @file_get_contents(VISION_API_URL . '/register', false, $ctx);
- return $resp !== false;
+
+ return ['valid' => false, 'msg' => $data['message'] ?? 'Licence invalide.'];
}