Files
provider_jmapc/lib/Service/Remote/RemoteService.php
T
Sebastian 152a8141d0 fix: logging
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
2026-07-29 21:20:05 -04:00

239 lines
6.9 KiB
PHP

<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: Sebastian Krupinski <krupinski01@gmail.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace KTXM\ProviderJmapc\Service\Remote;
use GuzzleHttp\Client as HttpClient;
use GuzzleHttp\Psr7\HttpFactory;
use JmapClient\Authentication\Basic;
use JmapClient\Client as JmapClient;
use KTXF\Security\Crypto;
use KTXF\Resource\Provider\ResourceServiceIdentityBasic;
use KTXF\Resource\Provider\ResourceServiceLocationUri;
use KTXM\ProviderJmapc\Providers\Mail\Service as MailService;
use KTXM\ProviderJmapc\Providers\Contacts\Service as ContactsService;
use KTXM\ProviderJmapc\Providers\Events\Service as EventsService;
use KTXM\ProviderJmapc\Providers\Tasks\Service as TasksService;
use KTXM\ProviderJmapc\Providers\Document\Service as FilesService;
use KTXM\ProviderJmapc\Service\Remote\FM\RemoteContactsServiceFM;
use KTXM\ProviderJmapc\Service\Remote\FM\RemoteCoreServiceFM;
use KTXM\ProviderJmapc\Service\Remote\FM\RemoteEventsServiceFM;
class RemoteService {
static string $clientTransportAgent = 'KtrixJMAP/1.0 (1.0; x64)';
//public static string $clientTransportAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:130.0) Gecko/20100101 Firefox/130.0';
/**
* Initialize remote data store client
*
* @since Release 1.0.0
*/
public static function freshClient(MailService|FilesService $service): JmapClient {
$location = $service->getLocation();
$identity = $service->getIdentity();
// location
if ($location instanceof ResourceServiceLocationUri === false) {
throw new \InvalidArgumentException('Service location is not a valid URI');
}
// The JMAP client accepts transport abstractions only. Guzzle supplies the
// PSR-18 client, while HttpFactory supplies both required PSR-17 factories.
$httpFactory = new HttpFactory();
$client = new JmapClient(
transportClient: new HttpClient([
'verify' => $location->getVerifyPeer(),
]),
requestFactory: $httpFactory,
streamFactory: $httpFactory,
);
$client->setTransportAgent(self::$clientTransportAgent);
$client->configureTransportMode($location->getScheme());
$client->setHost($location->getHost() . ':' . $location->getPort());
if (!empty($location->getPath())) {
$client->setDiscoveryPath($location->getPath());
}
// authentication
if (($identity instanceof ResourceServiceIdentityBasic) === false) {
throw new \InvalidArgumentException('Service identity is not a valid Basic or Bearer authentication');
}
if ($identity instanceof ResourceServiceIdentityBasic) {
$client->setAuthentication(new Basic(
$identity->getIdentity(),
$identity->getSecret()
));
}
// debugging
if ($service->getDebug()) {
$logDirectory = dirname(__DIR__, 5) . '/var/logs/jmap';
if (!is_dir($logDirectory) && !mkdir($logDirectory, 0775, true) && !is_dir($logDirectory)) {
throw new \RuntimeException(sprintf('Unable to create JMAP log directory: %s', $logDirectory));
}
$logFile = $logDirectory . '/' . $service->identifier() . '.json';
$client->configureTransportLogState(true);
$client->configureTransportLogLocation($logFile);
}
// return
return $client;
}
/**
* Destroys remote data store client (Jmap Client)
*
* @since Release 1.0.0
*/
public static function destroyClient(JmapClient $Client): void {
// destroy remote data store client
$Client = null;
}
/**
* Appropriate Mail Service for Connection
*
* @since Release 1.0.0
*/
public static function coreService(JmapClient $Client, ?string $dataAccount = null): RemoteCoreService {
// determine if client is connected
if (!$Client->sessionStatus()) {
$Client->connect();
}
// construct service based on capabilities
if ($Client->sessionCapable('https://www.fastmail.com/dev/user', false)) {
//$service = new RemoteCoreServiceFM();
} else {
$service = new RemoteCoreService();
}
$service->initialize($Client, $dataAccount);
return $service;
}
/**
* Appropriate Mail Service for Connection
*
* @since Release 1.0.0
*/
public static function mailService(JmapClient $Client, ?string $dataAccount = null): RemoteMailService {
// determine if client is connected
if (!$Client->sessionStatus()) {
$Client->connect();
}
$service = new RemoteMailService();
$service->initialize($Client, $dataAccount);
return $service;
}
/**
* Appropriate Contacts Service for Connection
*
* @since Release 1.0.0
*/
public static function contactsService(JmapClient $Client, ?string $dataAccount = null): RemoteContactsService {
// determine if client is connected
if (!$Client->sessionStatus()) {
$Client->connect();
}
// construct service based on capabilities
if ($Client->sessionCapable('https://www.fastmail.com/dev/contacts', false)) {
$service = new RemoteContactsServiceFM();
} else {
$service = new RemoteContactsService();
}
$service->initialize($Client, $dataAccount);
return $service;
}
/**
* Appropriate Events Service for Connection
*
* @since Release 1.0.0
*/
public static function eventsService(JmapClient $Client, ?string $dataAccount = null): RemoteEventsService {
// determine if client is connected
if (!$Client->sessionStatus()) {
$Client->connect();
}
// construct service based on capabilities
if ($Client->sessionCapable('https://www.fastmail.com/dev/calendars', false)) {
$service = new RemoteEventsServiceFM();
} else {
$service = new RemoteEventsService();
}
$service->initialize($Client, $dataAccount);
return $service;
}
/**
* Appropriate Tasks Service for Connection
*
* @since Release 1.0.0
*/
public static function tasksService(JmapClient $Client, ?string $dataAccount = null): RemoteTasksService {
// determine if client is connected
if (!$Client->sessionStatus()) {
$Client->connect();
}
$service = new RemoteTasksService();
$service->initialize($Client, $dataAccount);
return $service;
}
/**
* Appropriate Documents Service for Connection
*
* @since Release 1.0.0
*/
public static function documentsService(JmapClient $Client, ?string $dataAccount = null): RemoteFilesService {
// determine if client is connected
if (!$Client->sessionStatus()) {
$Client->connect();
}
$service = new RemoteFilesService();
$service->initialize($Client, $dataAccount);
return $service;
}
public static function cookieStoreRetrieve(mixed $id, Crypto $crypto): ?array {
$file = sys_get_temp_dir() . DIRECTORY_SEPARATOR . (string)$id . '.jmapc';
if (!file_exists($file)) {
return null;
}
$data = file_get_contents($file);
$data = $crypto->decrypt($data);
if (!empty($data)) {
return json_decode($data, true);
}
return null;
}
public static function cookieStoreDeposit(mixed $id, array $value, Crypto $crypto): void {
if (empty($value)) {
return;
}
$data = $crypto->encrypt(json_encode($value));
$file = sys_get_temp_dir() . DIRECTORY_SEPARATOR . (string)$id . '.jmapc';
file_put_contents($file, $data);
}
}