4 Commits

Author SHA1 Message Date
Sebastian 77f3babfc0 chore(deps): update dependency jsdom to v30
Build Test / test (pull_request) Successful in 53s
JS Unit Tests / test (pull_request) Successful in 1m8s
PHP Integration Tests / Integration Tests (pull_request) Failing after 1m45s
PHP Unit Tests / test (pull_request) Successful in 1m54s
2026-07-29 03:01:53 +00:00
Sebastian f4edaade10 fix: primary address saving
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
2026-07-28 21:03:31 -04:00
Sebastian 8624ee9d83 fix: disable auto complete
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
2026-07-28 20:52:46 -04:00
Sebastian 98f5f85242 refactor: migrate to scoped execution contexts
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
2026-07-27 00:52:29 -04:00
10 changed files with 75 additions and 66 deletions
Generated
+7 -7
View File
@@ -1201,16 +1201,16 @@
},
{
"name": "phpunit/phpunit",
"version": "12.5.32",
"version": "12.5.31",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "c02591dd7840ed124a98d7770753329ad28e9f8f"
"reference": "0608d157a284f15cc73b99a3327eff06b66a176d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c02591dd7840ed124a98d7770753329ad28e9f8f",
"reference": "c02591dd7840ed124a98d7770753329ad28e9f8f",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0608d157a284f15cc73b99a3327eff06b66a176d",
"reference": "0608d157a284f15cc73b99a3327eff06b66a176d",
"shasum": ""
},
"require": {
@@ -1279,7 +1279,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
"source": "https://github.com/sebastianbergmann/phpunit/tree/12.5.32"
"source": "https://github.com/sebastianbergmann/phpunit/tree/12.5.31"
},
"funding": [
{
@@ -1287,7 +1287,7 @@
"type": "other"
}
],
"time": "2026-07-25T06:54:13+00:00"
"time": "2026-07-06T14:54:16+00:00"
},
{
"name": "sebastian/cli-parser",
@@ -2315,5 +2315,5 @@
"platform-overrides": {
"php": "8.3"
},
"plugin-api-version": "2.9.0"
"plugin-api-version": "2.6.0"
}
+3 -3
View File
@@ -13,7 +13,7 @@ use KTXM\ProviderImap\Providers\Provider;
use KTXM\ProviderImap\Providers\Service;
use KTXM\ProviderImap\Providers\ServiceIdentityBasic;
use KTXM\ProviderImap\Providers\ServiceLocation;
use KTXC\SessionTenant;
use KTXC\Context\TenantContext;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
@@ -41,7 +41,7 @@ class ConnectCommand extends Command
{
public function __construct(
private readonly Provider $provider,
private readonly SessionTenant $sessionTenant,
private readonly TenantContext $tenantContext,
) {
parent::__construct();
}
@@ -186,7 +186,7 @@ class ConnectCommand extends Command
// ── Persist ──────────────────────────────────────────────────────────
$this->sessionTenant->configureById($tenantId);
$this->tenantContext->resolveIdentifier($tenantId);
$label = $io->ask('Service label', $username);
if ($label) {
+4 -4
View File
@@ -11,7 +11,7 @@ namespace KTXM\ProviderImap\Console;
use KTXM\ProviderImap\Providers\Provider;
use KTXM\ProviderImap\Providers\Service;
use KTXC\SessionTenant;
use KTXC\Context\TenantContext;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
@@ -37,7 +37,7 @@ class DisconnectCommand extends Command
{
public function __construct(
private readonly Provider $provider,
private readonly SessionTenant $sessionTenant,
private readonly TenantContext $tenantContext,
) {
parent::__construct();
}
@@ -86,7 +86,7 @@ class DisconnectCommand extends Command
$userId = (string) ($input->getOption('user') ?? '');
if ($tenantId !== '' && $userId !== '') {
$this->sessionTenant->configureById($tenantId);
$this->tenantContext->resolveIdentifier($tenantId);
$services = $this->provider->serviceList($tenantId, $userId);
if (empty($services)) {
@@ -130,7 +130,7 @@ class DisconnectCommand extends Command
}
// ── Fetch service for display ────────────────────────────────────────
$this->sessionTenant->configureById($tenantId);
$this->tenantContext->resolveIdentifier($tenantId);
$service = $this->provider->serviceFetch($tenantId, $userId, $serviceId);
if ($service === null) {
+3 -3
View File
@@ -14,7 +14,7 @@ use KTXM\ProviderImap\Providers\Service;
use KTXM\ProviderImap\Providers\ServiceIdentityBasic;
use KTXM\ProviderImap\Providers\ServiceLocation;
use KTXM\ProviderImap\Service\Discovery;
use KTXC\SessionTenant;
use KTXC\Context\TenantContext;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
@@ -43,7 +43,7 @@ class DiscoverCommand extends Command
public function __construct(
private readonly Provider $provider,
private readonly Discovery $discovery,
private readonly SessionTenant $sessionTenant,
private readonly TenantContext $tenantContext,
) {
parent::__construct();
}
@@ -210,7 +210,7 @@ class DiscoverCommand extends Command
// ── Persist ──────────────────────────────────────────────────────────
$this->sessionTenant->configureById($tenantId);
$this->tenantContext->resolveIdentifier($tenantId);
$label = $io->ask('Service label', $address);
if ($label) {
+4 -4
View File
@@ -9,7 +9,7 @@ declare(strict_types=1);
namespace KTXM\ProviderImap\Console;
use KTXC\SessionTenant;
use KTXC\Context\TenantContext;
use KTXM\ProviderImap\Client\Command\SelectCommand;
use KTXM\ProviderImap\Client\FetchOptions;
use KTXM\ProviderImap\Client\FetchTarget;
@@ -41,7 +41,7 @@ class TestCommand extends Command
{
public function __construct(
private readonly Provider $provider,
private readonly SessionTenant $sessionTenant,
private readonly TenantContext $tenantContext,
) {
parent::__construct();
}
@@ -108,7 +108,7 @@ class TestCommand extends Command
return Command::FAILURE;
}
$this->sessionTenant->configureById($tenantId);
$this->tenantContext->resolveIdentifier($tenantId);
$service = $this->provider->serviceFetch($tenantId, $userId, $serviceId);
if ($service === null) {
@@ -269,7 +269,7 @@ class TestCommand extends Command
return;
}
$this->sessionTenant->configureById($tenantId);
$this->tenantContext->resolveIdentifier($tenantId);
$services = $this->provider->serviceList($tenantId, $userId);
if ($services === []) {
+3 -2
View File
@@ -200,8 +200,9 @@ class Service implements ServiceBaseInterface, ServiceMutableInterface, ServiceC
if (isset($data[self::PROPERTY_IDENTITY])) {
$this->setIdentity($this->freshIdentity(null, $data[self::PROPERTY_IDENTITY]));
}
if (isset($data[self::PROPERTY_PRIMARY_ADDRESS]) && is_string($data[self::PROPERTY_PRIMARY_ADDRESS])) {
$this->setPrimaryAddress(new Address($data[self::PROPERTY_PRIMARY_ADDRESS]));
if (isset($data[self::PROPERTY_PRIMARY_ADDRESS])) {
$value = $data[self::PROPERTY_PRIMARY_ADDRESS];
$this->setPrimaryAddress(is_array($value) ? Address::fromArray($value) : new Address((string)$value));
}
if (isset($data[self::PROPERTY_SECONDARY_ADDRESSES]) && is_array($data[self::PROPERTY_SECONDARY_ADDRESSES])) {
$this->setSecondaryAddresses(array_map(
+1 -2
View File
@@ -11,7 +11,6 @@ namespace KTXM\ProviderImap\Service\Remote;
use DateTimeImmutable;
use Generator;
use KTXC\Server;
use KTXC\Logger\PlainFileLogger;
use KTXM\ProviderImap\Client\Client as ImapClient;
use KTXM\ProviderImap\Client\Command\AppendCommand;
@@ -132,7 +131,7 @@ class RemoteMailService
return null;
}
$logDir = Server::getInstance()?->logDir() ?? __DIR__ . '/../../../../../var/log';
$logDir = dirname(__DIR__, 5) . '/var/log';
return new PlainFileLogger($logDir . '/' . $channel, $this->service->identifier());
}
+47 -38
View File
@@ -19,7 +19,7 @@
"@vitest/coverage-v8": "^4.1.6",
"@vue/test-utils": "^2.4.10",
"@vue/tsconfig": "^0.9.0",
"jsdom": "^29.1.1",
"jsdom": "^30.0.0",
"typescript": "~6.0.0",
"vite": "^8.0.0",
"vitest": "^4.1.6",
@@ -27,48 +27,38 @@
}
},
"node_modules/@asamuzakjp/css-color": {
"version": "5.1.11",
"version": "6.0.5",
"resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-6.0.5.tgz",
"integrity": "sha512-mbhpPMmnw/kwW19aRNmSUl1QzLbdGo1SCuE49BT98MNwqF6zaHb3o2owssFc/PEO/4t2UjqtCNwocuDtJornzA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@asamuzakjp/generational-cache": "^1.0.1",
"@csstools/css-calc": "^3.2.0",
"@csstools/css-color-parser": "^4.1.0",
"@csstools/css-calc": "^3.2.1",
"@csstools/css-color-parser": "^4.1.9",
"@csstools/css-parser-algorithms": "^4.0.0",
"@csstools/css-tokenizer": "^4.0.0"
"@csstools/css-tokenizer": "^4.0.0",
"lru-cache": "^11.5.2"
},
"engines": {
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
"node": "^22.13.0 || >=24.0.0"
}
},
"node_modules/@asamuzakjp/dom-selector": {
"version": "7.1.1",
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-8.3.0.tgz",
"integrity": "sha512-UJLfKXBhrc8i1vH2eJXuYQMwlsLKWFw3O+CPqXSuVEiikeAim3UgrfWX0k4tA/X8cRFM8iZ7OaqBokFGbYusdg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@asamuzakjp/generational-cache": "^1.0.1",
"@asamuzakjp/nwsapi": "^2.3.9",
"bidi-js": "^1.0.3",
"css-tree": "^3.2.1",
"is-potential-custom-element-name": "^1.0.1"
"is-potential-custom-element-name": "^1.0.1",
"lru-cache": "^11.5.2"
},
"engines": {
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
"node": "^22.13.0 || >=24.0.0"
}
},
"node_modules/@asamuzakjp/generational-cache": {
"version": "1.0.1",
"dev": true,
"license": "MIT",
"engines": {
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
}
},
"node_modules/@asamuzakjp/nwsapi": {
"version": "2.3.9",
"dev": true,
"license": "MIT"
},
"node_modules/@babel/generator": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-8.0.0.tgz",
@@ -1640,37 +1630,39 @@
"license": "MIT"
},
"node_modules/jsdom": {
"version": "29.1.1",
"version": "30.0.0",
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-30.0.0.tgz",
"integrity": "sha512-JQHfRGmmKmaZoUAvIgff5jjG/0SzTQlGz8c7t72KzBzo8ZULEjAjnYE0sNwBOUA4QtWwYE2xoYitg8NFsmiYxA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@asamuzakjp/css-color": "^5.1.11",
"@asamuzakjp/dom-selector": "^7.1.1",
"@asamuzakjp/css-color": "^6.0.5",
"@asamuzakjp/dom-selector": "^8.2.5",
"@bramus/specificity": "^2.4.2",
"@csstools/css-syntax-patches-for-csstree": "^1.1.3",
"@exodus/bytes": "^1.15.0",
"@csstools/css-syntax-patches-for-csstree": "^1.1.6",
"@exodus/bytes": "^1.15.1",
"css-tree": "^3.2.1",
"data-urls": "^7.0.0",
"decimal.js": "^10.6.0",
"html-encoding-sniffer": "^6.0.0",
"is-potential-custom-element-name": "^1.0.1",
"lru-cache": "^11.3.5",
"lru-cache": "^11.5.2",
"parse5": "^8.0.1",
"saxes": "^6.0.0",
"symbol-tree": "^3.2.4",
"tough-cookie": "^6.0.1",
"undici": "^7.25.0",
"tough-cookie": "^6.0.2",
"undici": "^8.7.0",
"w3c-xmlserializer": "^5.0.0",
"webidl-conversions": "^8.0.1",
"whatwg-mimetype": "^5.0.0",
"whatwg-url": "^16.0.1",
"whatwg-url": "^17.1.0",
"xml-name-validator": "^5.0.0"
},
"engines": {
"node": "^20.19.0 || ^22.13.0 || >=24.0.0"
"node": "^22.22.2 || ^24.15.0 || >=26.0.0"
},
"peerDependencies": {
"canvas": "^3.0.0"
"canvas": "^3.2.3"
},
"peerDependenciesMeta": {
"canvas": {
@@ -1678,6 +1670,21 @@
}
}
},
"node_modules/jsdom/node_modules/whatwg-url": {
"version": "17.1.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-17.1.0.tgz",
"integrity": "sha512-3GeworPmc2ZfEEHP7lEbUfBX/L75wdEsi0rLNhXcXxnoN5jyq0SL5gCy06SGW2cyTIZdTvWIDQNQoza++vKeaw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@exodus/bytes": "^1.15.1",
"tr46": "^6.0.0",
"webidl-conversions": "^8.0.1"
},
"engines": {
"node": "^22.14.0 || >=24.0.0"
}
},
"node_modules/jsesc": {
"version": "3.1.0",
"license": "MIT",
@@ -2640,11 +2647,13 @@
"license": "MIT"
},
"node_modules/undici": {
"version": "7.28.0",
"version": "8.9.0",
"resolved": "https://registry.npmjs.org/undici/-/undici-8.9.0.tgz",
"integrity": "sha512-aWZpUj7XoGonMClx4gdDRfgBjqeA+F473aDmROQQbM9n6PRfK/u1q/a0X4wMTgcHfT8H6fpbt98PFuDUwFg2YA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=20.18.1"
"node": ">=22.19.0"
}
},
"node_modules/unplugin": {
+1 -1
View File
@@ -31,7 +31,7 @@
"vue-tsc": "^3.0.5",
"@vitest/coverage-v8": "^4.1.6",
"@vue/test-utils": "^2.4.10",
"jsdom": "^29.1.1",
"jsdom": "^30.0.0",
"vitest": "^4.1.6"
}
}
+2 -2
View File
@@ -115,7 +115,7 @@ function sameIdentity(a: ServiceIdentity | null, b: ServiceIdentity | null): boo
variant="outlined"
prepend-inner-icon="mdi-account"
class="mb-4"
autocomplete="username"
autocomplete="off"
autocorrect="off"
autocapitalize="none"
:rules="[rules.required]"
@@ -130,7 +130,7 @@ function sameIdentity(a: ServiceIdentity | null, b: ServiceIdentity | null): boo
variant="outlined"
prepend-inner-icon="mdi-lock"
class="mb-4"
autocomplete="current-password"
autocomplete="new-password"
:rules="[rules.required]"
/>
</div>