152a8141d0
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
239 lines
6.9 KiB
PHP
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);
|
|
|
|
}
|
|
|
|
}
|