diff --git a/.gitignore b/.gitignore
index b1ba4f8..2144e90 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,5 @@
.idea/
server/vendor/
build/
+
+server/config/config.php
diff --git a/logs/.htaccess b/logs/.htaccess
new file mode 100644
index 0000000..b9db1c1
--- /dev/null
+++ b/logs/.htaccess
@@ -0,0 +1,30 @@
+#
+# SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+# SPDX-License-Identifier: AGPL-3.0-or-later
+#
+
+# Section for Apache 2.4 to 2.6
+
+ Require all denied
+
+
+ Order Allow,Deny
+ Deny from all
+ Satisfy All
+
+
+# Section for Apache 2.2
+
+
+
+ Order Allow,Deny
+ Deny from all
+
+ Satisfy All
+
+
+
+# Section for Apache 2.2 to 2.6
+
+ IndexIgnore *
+
diff --git a/server/config/config.sample.php b/server/config/config.sample.php
index 5d2bd45..ea8f0da 100755
--- a/server/config/config.sample.php
+++ b/server/config/config.sample.php
@@ -19,8 +19,16 @@
// error verbose
'ERROR_VERBOSE' => true,
- // logfile
- 'LOG' => '/tmp/lookup.log',
+ // *MUST* ensure that log file is stored in a folder made not available to the outside world
+ 'LOG' => [
+ 'ENABLED' => true,
+ 'LEVEL' => 0,
+ 'FILE' => __DIR__ . '/../../logs/lookup.log',
+ 'FILE_MODE' => 0640,
+ 'DATE_FORMAT' => 'Y-m-d H:i:s',
+ 'DATE_TIMEZONE' => 'UTC',
+ 'HIDE_BACKTRACE' => false,
+ ],
// replication logfile
'REPLICATION_LOG' => '/tmp/lookup_replication.log',
diff --git a/server/index.php b/server/index.php
index 4bcc195..3951a10 100644
--- a/server/index.php
+++ b/server/index.php
@@ -6,30 +6,29 @@
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
-
namespace LookupServer;
-
use LookupServer\Validator\Email;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
require __DIR__ . '/init.php';
-if (!isset($app) || !isset($container)) {
+if (!isset($app, $container)) {
return;
}
$r_head = function (ServerRequestInterface $request, ResponseInterface $response, array $args) {
+ $this->get('LoggerService')->debug('HEAD/GET request');
return $response->withHeader('X-Version', VERSION);
};
$app->map(['HEAD', 'GET'], '/', $r_head);
$app->map(['HEAD', 'GET'], '/index.php', $r_head);
+$app->map(['HEAD', 'GET'], '/index.php/', $r_head);
$r_search = function (ServerRequestInterface $request, ResponseInterface $response, array $args) {
/** @var UserManager $userManager */
$userManager = $this->get('UserManager');
-
return $userManager->search($request, $response, $args);
};
$app->get('/users', $r_search);
@@ -38,58 +37,46 @@
$r_register = function (ServerRequestInterface $request, ResponseInterface $response, array $args) {
/** @var UserManager $userManager */
$userManager = $this->get('UserManager');
-
return $userManager->register($request, $response, $args);
};
$app->post('/users', $r_register);
$app->post('/index.php/users', $r_register);
-
$r_delete = function (ServerRequestInterface $request, ResponseInterface $response, array $args) {
/** @var UserManager $userManager */
$userManager = $this->get('UserManager');
-
return $userManager->delete($request, $response, $args);
};
$app->delete('/users', $r_delete);
$app->delete('/index.php/users', $r_delete);
-
$r_batchDetails = function (ServerRequestInterface $request, ResponseInterface $response, array $args) {
/** @var UserManager $userManager */
$userManager = $this->get('UserManager');
-
return $userManager->batchDetails($request, $response, $args);
};
$app->get('/gs/users', $r_batchDetails);
$app->get('/index.php/gs/users', $r_batchDetails);
-
$r_batchRegister = function (ServerRequestInterface $request, ResponseInterface $response, array $args) {
/** @var UserManager $userManager */
$userManager = $this->get('UserManager');
-
return $userManager->batchRegister($request, $response, $args);
};
$app->post('/gs/users', $r_batchRegister);
$app->post('/index.php/gs/users', $r_batchRegister);
-
$r_batchDelete = function (ServerRequestInterface $request, ResponseInterface $response, array $args) {
/** @var UserManager $userManager */
$userManager = $this->get('UserManager');
-
return $userManager->batchDelete($request, $response, $args);
};
$app->delete('/gs/users', $r_batchDelete);
$app->delete('/index.php/gs/users', $r_batchDelete);
-
-
$r_instances = function (ServerRequestInterface $request, ResponseInterface $response, array $args) {
/** @var InstanceManager $instanceManager */
$instanceManager = $this->get('InstanceManager');
-
return $instanceManager->getInstances($request, $response);
};
$app->get('/gs/instances', $r_instances);
@@ -100,34 +87,24 @@
$r_validateEmail = function (ServerRequestInterface $request, ResponseInterface $response, array $args) {
/** @var Email $emailValidator */
$emailValidator = $this->get('EmailValidator');
-
return $emailValidator->validate($request, $response, $args);
};
$app->get('/validate/email/{token}', $r_validateEmail);
$app->get('/index.php/validate/email/{token}', $r_validateEmail);
-
$r_status = function (ServerRequestInterface $request, ResponseInterface $response, array $args) {
- $response->getBody()->write(
- json_encode(
- ['version' => VERSION]
- )
- );
-
+ $response->getBody()->write(json_encode(['version' => VERSION], JSON_THROW_ON_ERROR));
return $response;
};
$app->get('/status', $r_status);
$app->get('/index.php/status', $r_status);
-
$r_export = function (ServerRequestInterface $request, ResponseInterface $response, array $args) {
/** @var Replication $replication */
$replication = $this->get('Replication');
-
return $replication->export($request, $response, $args);
};
$app->get('/replication', $r_export);
$app->get('/index.php/replication', $r_export);
-
$app->run();
diff --git a/server/init.php b/server/init.php
index 3de11ff..2626e35 100644
--- a/server/init.php
+++ b/server/init.php
@@ -6,18 +6,14 @@
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
-
namespace LookupServer;
-
use DI\Container;
use LookupServer\Service\DependenciesService;
use Slim\Factory\AppFactory;
-
define('VERSION', '1.1.2');
-
require __DIR__ . '/vendor/autoload.php';
$container = new Container();
@@ -34,4 +30,3 @@
return new DependenciesService($c->get('Settings'));
});
$container->get('DependenciesService')->initContainer($container, $app);
-
diff --git a/server/lib/Exceptions/LoggerException.php b/server/lib/Exceptions/LoggerException.php
new file mode 100644
index 0000000..1f5c8a2
--- /dev/null
+++ b/server/lib/Exceptions/LoggerException.php
@@ -0,0 +1,14 @@
+logFile === null) {
+ $path = $this->settings['settings']['log']['file'] ?? '';
+ if ($path === '') {
+ throw new LoggerException('log disabled');
+ }
+ $this->logFile = $path;
+ }
+ return $this->logFile;
+ }
+
+ public function write(string $entry): void {
+ try {
+ $handle = @fopen($this->getLogFile(), 'a');
+ } catch (LoggerException) {
+ return;
+ }
+
+ if ($this->logFileMode === null) {
+ $this->logFileMode = $this->settings['settings']['log']['file_mode'] ?? 0640;
+ }
+
+ if ($this->logFileMode > 0 && is_file($this->logFile) && (fileperms($this->logFile) & 0777) !== $this->logFileMode) {
+ @chmod($this->logFile, $this->logFileMode);
+ }
+
+ if ($handle) {
+ fwrite($handle, $entry . "\n");
+ fclose($handle);
+ } else {
+ error_log($entry);
+ }
+ }
+}
diff --git a/server/lib/Replication.php b/server/lib/Replication.php
index 844f934..98cf76d 100644
--- a/server/lib/Replication.php
+++ b/server/lib/Replication.php
@@ -10,6 +10,7 @@
namespace LookupServer;
use GuzzleHttp\Client;
+use LookupServer\Service\LoggerService;
use LookupServer\Service\SecurityService;
use PDO;
use Psr\Http\Message\ResponseInterface;
@@ -22,7 +23,9 @@ class Replication {
public function __construct(
private PDO $db,
private SecurityService $securityService,
- private array $replicationHosts) {
+ private array $replicationHosts,
+ private LoggerService $logger,
+ ) {
}
diff --git a/server/lib/Service/DependenciesService.php b/server/lib/Service/DependenciesService.php
index 4868532..6c204a2 100644
--- a/server/lib/Service/DependenciesService.php
+++ b/server/lib/Service/DependenciesService.php
@@ -13,6 +13,7 @@
use DI\Container;
use Exception;
use LookupServer\InstanceManager;
+use LookupServer\Logger\LogFile;
use LookupServer\Replication;
use LookupServer\SignatureHandler;
use LookupServer\Tools\Traits\TArrayTools;
@@ -38,6 +39,18 @@ public function __construct(array $settings = []) {
* @param App $app
*/
public function initContainer(Container $container, App $app): void {
+ $container->set('LogFile', function (Container $c) {
+ return new LogFile(
+ $c->get('Settings'),
+ );
+ });
+
+ $container->set('LoggerService', function (Container $c) {
+ return new LoggerService(
+ $c->get('Settings'),
+ $c->get('LogFile'),
+ );
+ });
$container->set('db', function (Container $c) {
$db = $this->getArray('settings.db', $c->get('Settings'));
@@ -56,15 +69,18 @@ public function initContainer(Container $container, App $app): void {
});
$container->set('SecurityService', function (Container $c) {
- $settings = $c->get('Settings');
- return new SecurityService($settings);
+ return new SecurityService(
+ $c->get('Settings'),
+ $c->get('LoggerService'),
+ );
});
$container->set('InstanceManager', function (Container $c) {
return new InstanceManager(
$c->get('db'),
$c->get('SecurityService'),
- $this->getArray('settings.instances', $c->get('Settings'))
+ $this->getArray('settings.instances', $c->get('Settings')),
+ $c->get('LoggerService'),
);
});
@@ -76,13 +92,15 @@ public function initContainer(Container $container, App $app): void {
$c->get('TwitterValidator'),
$c->get('InstanceManager'),
$c->get('SignatureHandler'),
- $c->get('SecurityService')
+ $c->get('SecurityService'),
+ $c->get('LoggerService'),
);
});
-
- $container->set('SignatureHandler', function () {
- return new SignatureHandler();
+ $container->set('SignatureHandler', function (Container $c) {
+ return new SignatureHandler(
+ $c->get('LoggerService'),
+ );
});
$container->set('TwitterOAuth', function (Container $c) {
@@ -93,33 +111,35 @@ public function initContainer(Container $container, App $app): void {
$this->get('settings.twitter.consumer_key', $settings),
$this->get('settings.twitter.consumer_secret', $settings),
$this->get('settings.twitter.access_token', $settings),
- $this->get('settings.twitter.access_token_secret', $settings)
+ $this->get('settings.twitter.access_token_secret', $settings),
);
});
-
$container->set('EmailValidator', function (Container $c) use ($app) {
$settings = $c->get('Settings');
-
return new Email(
$c->get('db'),
$app->getRouteCollector()->getRouteParser(),
$this->get('settings.host', $settings),
$this->get('settings.emailfrom', $settings),
$c->get('SecurityService'),
+ $c->get('LoggerService'),
);
});
$container->set('WebsiteValidator', function (Container $c) {
- return new Website($c->get('SignatureHandler'));
+ return new Website(
+ $c->get('SignatureHandler'),
+ $c->get('LoggerService'),
+ );
});
-
$container->set('TwitterValidator', function (Container $c) {
return new Twitter(
$c->get('TwitterOAuth'),
$c->get('SignatureHandler'),
- $c->get('db')
+ $c->get('db'),
+ $c->get('LoggerService'),
);
});
@@ -129,7 +149,8 @@ public function initContainer(Container $container, App $app): void {
return new Replication(
$c->get('db'),
$c->get('SecurityService'),
- $this->getArray('settings.replication_hosts', $settings)
+ $this->getArray('settings.replication_hosts', $settings),
+ $c->get('LoggerService'),
);
});
}
diff --git a/server/lib/Service/LoggerService.php b/server/lib/Service/LoggerService.php
new file mode 100644
index 0000000..ede0e51
--- /dev/null
+++ b/server/lib/Service/LoggerService.php
@@ -0,0 +1,201 @@
+log(0, $message, $context);
+ }
+
+ public function info(string|Stringable $message, array $context = array()): void {
+ $this->log(1, $message, $context);
+ }
+
+ public function notice(string|Stringable $message, array $context = []): void {
+ $this->log(2, $message, $context);
+ }
+
+ public function warning(string|Stringable $message, array $context = []): void {
+ $this->log(3, $message, $context);
+ }
+
+ public function error(string|Stringable $message, array $context = []): void {
+ $this->log(4, $message, $context);
+ }
+
+ public function critical(string|Stringable $message, array $context = []): void {
+ $this->log(5, $message, $context);
+ }
+
+ public function alert(string|Stringable $message, array $context = []): void {
+ $this->log(6, $message, $context);
+ }
+
+ public function emergency(string|Stringable $message, array $context = []): void {
+ $this->log(7, $message, $context);
+ }
+
+ public function log($level, string|Stringable $message, array $context = []): void {
+ if (($this->settings['settings']['log']['enabled'] ?? false) !== true) {
+ return;
+ }
+
+ if (!$this->fitLogLevel($level)) {
+ return;
+ }
+
+ $this->write($level, (string)$message, $context);
+ }
+
+ private function write(int $level, string $message, array $context = []): void {
+ $this->logFile->write($this->generateCompleteData($level, $message, $context));
+ }
+
+ private function fitLogLevel(int $level): bool {
+ try {
+ $logLevel = $this->getLogLevel();
+ } catch (LoggerException $e) {
+ $this->write(6, 'cannot extract log level', ['exception' => $e]);
+ $logLevel = 2;
+ }
+ return ($level >= $logLevel);
+ }
+
+ /**
+ * @throws LoggerException if level is set but not an integer
+ */
+ private function getLogLevel(): int {
+ $logLevel = $this->settings['settings']['log']['level'] ?? 2;
+ if (is_int($logLevel)) {
+ return $logLevel;
+ }
+ throw new LoggerException('misconfigured log_level');
+ }
+
+ private function generateCompleteData(int $level, string $message, array $context = []): string {
+ $format = $this->settings['settings']['log']['date_format'] ?? DateTimeInterface::ATOM;
+ $logTimeZone = $this->settings['settings']['log']['date_timezone'] ?? 'UTC';
+
+ try {
+ $timezone = new DateTimeZone($logTimeZone);
+ } catch (\Exception) {
+ $timezone = new DateTimeZone('UTC');
+ }
+
+ $time = DateTime::createFromFormat('U.u', number_format(microtime(true), 4, '.', ''));
+ if ($time !== false) {
+ $time->setTimezone($timezone);
+ } else {
+ $time = new DateTime('now', $timezone);
+ }
+ $time = $time->format($format);
+
+ [$reqId, $method, $url, $remoteAddr, $userAgent] = $this->getRequestDetails();
+ $version = VERSION;
+
+ $entry = compact(
+ 'reqId',
+ 'level',
+ 'time',
+ 'remoteAddr',
+ 'method',
+ 'url',
+ 'message',
+ 'userAgent',
+ 'version'
+ );
+
+ return $this->convertToSafeJson($this->applyContext($entry, $context));
+ }
+
+ private function getRequestDetails(): array {
+ if ($this->request === null) {
+ $serverRequestCreator = ServerRequestCreatorFactory::create();
+ $this->request = $serverRequestCreator->createServerRequestFromGlobals();
+ $this->requestId = $this->generateUniqueId();
+ }
+
+ return [
+ $this->requestId,
+ $_SERVER['REQUEST_METHOD'],
+ $_SERVER['REQUEST_URI'],
+ $_SERVER['REMOTE_ADDR'],
+ $_SERVER['HTTP_USER_AGENT']
+ ];
+ }
+
+ private function generateUniqueId(): string {
+ $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
+ $length = 12;
+
+ $charsLength = strlen($chars) - 1;
+ $randomString = '';
+ while ($length > 0) {
+ $randomString .= $chars[random_int(0, $charsLength)];
+ $length--;
+ }
+ return $randomString;
+ }
+
+ public function convertToSafeJson(array $data): string {
+ // ensure data are UTF-8 compliant
+ foreach ($data as $key => $value) {
+ if (is_string($value)) {
+ try {
+ json_encode($value, JSON_THROW_ON_ERROR | JSON_UNESCAPED_SLASHES);
+ } catch (JsonException) {
+ $data[$key] = mb_convert_encoding($value, 'UTF-8', mb_detect_encoding($value));
+ }
+ }
+ }
+
+ return json_encode($data, JSON_PARTIAL_OUTPUT_ON_ERROR | JSON_UNESCAPED_SLASHES);
+ }
+
+ public function applyContext(array $entry, array $context): array {
+ $exception = $context['exception'] ?? null;
+ if ($exception instanceof Throwable) {
+ $context['exception'] = [
+ 'exception' => get_class($exception),
+ 'file' => $exception->getFile(),
+ 'line' => $exception->getLine(),
+ 'message' => $exception->getMessage(),
+ 'code' => $exception->getCode(),
+ 'trace' => (($this->settings['settings']['log']['hide_backtrace'] ?? false) !== true) ? $exception->getTrace() : null,
+ ];
+ }
+
+ return array_merge($entry, $context);
+ }
+}
diff --git a/server/lib/Service/SecurityService.php b/server/lib/Service/SecurityService.php
index 803cfb5..59652e8 100644
--- a/server/lib/Service/SecurityService.php
+++ b/server/lib/Service/SecurityService.php
@@ -14,7 +14,10 @@
class SecurityService {
use TArrayTools;
- public function __construct(private array $settings = []) {
+ public function __construct(
+ private array $settings,
+ private readonly LoggerService $logger,
+ ) {
}
public function isGlobalScale(): bool {
diff --git a/server/lib/SignatureHandler.php b/server/lib/SignatureHandler.php
index aa33995..cf07cb7 100644
--- a/server/lib/SignatureHandler.php
+++ b/server/lib/SignatureHandler.php
@@ -13,10 +13,16 @@
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use LookupServer\Exceptions\SignedRequestException;
+use LookupServer\Service\LoggerService;
use Psr\Http\Message\ServerRequestInterface as Request;
class SignatureHandler {
+ public function __construct(
+ private LoggerService $logger,
+ ) {
+ }
+
/**
* check signature of incoming request
*
diff --git a/server/lib/UserManager.php b/server/lib/UserManager.php
index f850cea..cfe6d1b 100644
--- a/server/lib/UserManager.php
+++ b/server/lib/UserManager.php
@@ -9,6 +9,7 @@
use Exception;
use GuzzleHttp\Exception\GuzzleException;
+use LookupServer\Service\LoggerService;
use LookupServer\Service\SecurityService;
use LookupServer\Tools\Traits\TArrayTools;
use LookupServer\Validator\Email;
@@ -28,11 +29,11 @@ public function __construct(
private Twitter $twitterValidator,
private InstanceManager $instanceManager,
private SignatureHandler $signatureHandler,
- private SecurityService $securityService
+ private SecurityService $securityService,
+ private readonly LoggerService $logger,
) {
}
-
/**
* @param string $input
*
@@ -57,6 +58,8 @@ public function search(Request $request, Response $response, array $args = []):
$params = $request->getQueryParams();
$search = urldecode($params['search'] ?? '');
+ $this->logger->info('Search request', ['search' => $search, 'params' => $params]);
+
if ($search === '') {
return $response->withStatus(400);
}
@@ -411,6 +414,7 @@ public function register(Request $request, Response $response, array $args = [])
|| !isset($body['message']['data']['federationId'])
|| !isset($body['signature'])
|| !isset($body['message']['timestamp'])) {
+ $this->logger->warning('Invalid registration request - missing required fields');
return $response->withStatus(400);
}
@@ -419,17 +423,19 @@ public function register(Request $request, Response $response, array $args = [])
try {
$verified = $this->signatureHandler->verify($cloudId, $body['message'], $body['signature']);
} catch (Exception $e) {
+ $this->logger->error('Registration signature verification failed', ['cloudId' => $cloudId, 'exception' => $e]);
return $response->withStatus(400);
}
if ($verified) {
- $result =
- $this->insertOrUpdate($cloudId, $body['message']['data'], $body['message']['timestamp']);
+ $result = $this->insertOrUpdate($cloudId, $body['message']['data'], $body['message']['timestamp']);
if ($result === false) {
+ $this->logger->warning('Registration rejected - timestamp too old', ['cloudId' => $cloudId]);
return $response->withStatus(403);
}
+ $this->logger->info('User registered/updated successfully', ['cloudId' => $cloudId]);
} else {
- // ERROR OUT
+ $this->logger->error('Registration signature invalid', ['cloudId' => $cloudId]);
return $response->withStatus(403);
}
@@ -542,16 +548,19 @@ public function delete(Request $request, Response $response, array $args = []):
try {
$verified = $this->signatureHandler->verify($cloudId, $body['message'], $body['signature']);
} catch (Exception $e) {
+ $this->logger->error('Delete signature verification failed', ['cloudId' => $cloudId, 'exception' => $e]);
return $response->withStatus(400);
}
if ($verified) {
$result = $this->deleteDBRecord($cloudId);
if ($result === false) {
+ $this->logger->info('Delete failed - user not found', ['cloudId' => $cloudId]);
return $response->withStatus(404);
}
+ $this->logger->info('User deleted successfully', ['cloudId' => $cloudId]);
} else {
- // ERROR OUT
+ $this->logger->error('Delete signature invalid', ['cloudId' => $cloudId]);
return $response->withStatus(403);
}
diff --git a/server/lib/Validator/Email.php b/server/lib/Validator/Email.php
index c351c2b..4af9ad4 100644
--- a/server/lib/Validator/Email.php
+++ b/server/lib/Validator/Email.php
@@ -10,6 +10,7 @@
namespace LookupServer\Validator;
use Exception;
+use LookupServer\Service\LoggerService;
use LookupServer\Service\SecurityService;
use PDO;
use Psr\Http\Message\ResponseInterface as Response;
@@ -24,6 +25,7 @@ public function __construct(
private string $host,
private string $from,
private SecurityService $securityService,
+ private LoggerService $logger,
) {
}
diff --git a/server/lib/Validator/Twitter.php b/server/lib/Validator/Twitter.php
index dde1524..bd4b7dd 100644
--- a/server/lib/Validator/Twitter.php
+++ b/server/lib/Validator/Twitter.php
@@ -12,26 +12,17 @@
use Abraham\TwitterOAuth\TwitterOAuth;
use Exception;
+use LookupServer\Service\LoggerService;
use LookupServer\SignatureHandler;
use PDO;
class Twitter {
-
- private TwitterOAuth $twitterOAuth;
- private SignatureHandler $signatureHandler;
- private PDO $db;
-
- /**
- * Twitter constructor.
- *
- * @param TwitterOAuth $twitterOAuth
- * @param SignatureHandler $signatureHandler
- * @param PDO $db
- */
- public function __construct(TwitterOAuth $twitterOAuth, SignatureHandler $signatureHandler, PDO $db) {
- $this->twitterOAuth = $twitterOAuth;
- $this->signatureHandler = $signatureHandler;
- $this->db = $db;
+ public function __construct(
+ private TwitterOAuth $twitterOAuth,
+ private SignatureHandler $signatureHandler,
+ private PDO $db,
+ private LoggerService $logger,
+ ) {
}
/**
diff --git a/server/lib/Validator/Website.php b/server/lib/Validator/Website.php
index 971f6a6..8c43b6c 100644
--- a/server/lib/Validator/Website.php
+++ b/server/lib/Validator/Website.php
@@ -11,14 +11,15 @@
use Exception;
+use LookupServer\Service\LoggerService;
use LookupServer\SignatureHandler;
class Website {
- private SignatureHandler $signatureHandler;
-
- public function __construct(SignatureHandler $signatureHandler) {
- $this->signatureHandler = $signatureHandler;
+ public function __construct(
+ private SignatureHandler $signatureHandler,
+ private LoggerService $logger,
+ ) {
}
/**
diff --git a/server/src/config.php b/server/src/config.php
index 6f848f3..62713c8 100644
--- a/server/src/config.php
+++ b/server/src/config.php
@@ -18,6 +18,15 @@
'dbname' => $CONFIG['DB']['db'] ?? 'lookup',
],
'host' => $CONFIG['PUBLIC_URL'] ?? 'http://dev/nextcloud/lookup-server',
+ 'log' => [
+ 'enabled' => $CONFIG['LOG']['ENABLED'] ?? false,
+ 'level' => $CONFIG['LOG']['LEVEL'] ?? 2,
+ 'file' => $CONFIG['LOG']['FILE'] ?? '/tmp/lookup.log',
+ 'file_mode' => $CONFIG['LOG']['FILE_MODE'] ?? 0640,
+ 'date_format' => $CONFIG['LOG']['DATE_FORMAT'] ?? 'Y-m-d H:i:s',
+ 'date_timezone' => $CONFIG['LOG']['DATE_TIMEZONE'] ?? 'UTC',
+ 'hide_backtrace' => $CONFIG['LOG']['HIDE_BACKTRACE'] ?? false,
+ ],
'emailfrom' => $CONFIG['EMAIL_SENDER'] ?? 'admin@example.com',
'replication_auth' => $CONFIG['REPLICATION_AUTH'] ?? '',
'replication_hosts' => $CONFIG['REPLICATION_HOSTS'] ?? '',
@@ -29,6 +38,6 @@
'access_token' => $CONFIG['TWITTER']['ACCESS_TOKEN'] ?? '',
'access_token_secret' => $CONFIG['TWITTER']['ACCESS_TOKEN_SECRET'] ?? '',
],
- 'instances' => $CONFIG['INSTANCES'] ?? []
+ 'instances' => $CONFIG['INSTANCES'] ?? [],
]
];