Skip to content

Commit 95dcbb9

Browse files
authored
Merge pull request #158 from utopia-php/user_push_target_migration
2 parents a27c3c6 + e70a698 commit 95dcbb9

File tree

3 files changed

+89
-2
lines changed

3 files changed

+89
-2
lines changed

src/Migration/Destinations/Appwrite.php

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1264,6 +1264,10 @@ public function importAuthResource(Resource $resource): Resource
12641264
$this->users->updateLabels($resource->getId(), $resource->getLabels());
12651265
}
12661266

1267+
if (!empty($resource->getTargets())) {
1268+
$this->importUserTargets($resource->getId(), $resource->getTargets());
1269+
}
1270+
12671271
break;
12681272
case Resource::TYPE_TEAM:
12691273
/** @var Team $resource */
@@ -1722,6 +1726,54 @@ public function importSiteResource(Resource $resource): Resource
17221726
return $resource;
17231727
}
17241728

1729+
/**
1730+
* Import user targets not auto-created by the server (e.g. push).
1731+
* providerInternalId is resolved later in createProvider().
1732+
*
1733+
* @param array<array<string, mixed>> $targets
1734+
*/
1735+
protected function importUserTargets(string $userId, array $targets): void
1736+
{
1737+
$userDoc = null;
1738+
1739+
foreach ($targets as $target) {
1740+
switch ($target['providerType'] ?? '') {
1741+
case 'email':
1742+
case 'sms':
1743+
// Auto-created by the server when a user is created with an email/phone
1744+
break;
1745+
case 'push':
1746+
$userDoc ??= $this->dbForProject->getDocument('users', $userId);
1747+
1748+
$createdAt = $this->normalizeDateTime($target['$createdAt'] ?? null);
1749+
$updatedAt = $this->normalizeDateTime($target['$updatedAt'] ?? null, $createdAt);
1750+
1751+
$this->dbForProject->createDocument('targets', new UtopiaDocument([
1752+
'$id' => $target['$id'],
1753+
'$createdAt' => $createdAt,
1754+
'$updatedAt' => $updatedAt,
1755+
'$permissions' => [
1756+
Permission::read(Role::user($userId)),
1757+
Permission::update(Role::user($userId)),
1758+
Permission::delete(Role::user($userId)),
1759+
],
1760+
'userId' => $userId,
1761+
'userInternalId' => $userDoc->getSequence(),
1762+
'providerType' => $target['providerType'],
1763+
'providerId' => $target['providerId'] ?? null,
1764+
'identifier' => $target['identifier'],
1765+
'name' => $target['name'] ?? null,
1766+
'expired' => $target['expired'] ?? false,
1767+
]));
1768+
break;
1769+
}
1770+
}
1771+
1772+
if ($userDoc !== null) {
1773+
$this->dbForProject->purgeCachedDocument('users', $userId);
1774+
}
1775+
}
1776+
17251777
/**
17261778
* @throws AppwriteException
17271779
* @throws \Exception
@@ -1845,6 +1897,26 @@ protected function createProvider(Provider $resource): void
18451897
),
18461898
default => throw new \Exception('Unknown provider: ' . $resource->getProvider()),
18471899
};
1900+
1901+
// Resolve providerInternalId for push targets that were written during GROUP_AUTH
1902+
// before the provider existed on the destination.
1903+
$provider = $this->dbForProject->getDocument('providers', $id);
1904+
$targets = $this->dbForProject->find('targets', [
1905+
Query::equal('providerId', [$id]),
1906+
Query::isNull('providerInternalId'),
1907+
]);
1908+
1909+
$userIds = [];
1910+
1911+
foreach ($targets as $target) {
1912+
$target->setAttribute('providerInternalId', $provider->getSequence());
1913+
$this->dbForProject->updateDocument('targets', $target->getId(), $target);
1914+
$userIds[$target->getAttribute('userId')] = true;
1915+
}
1916+
1917+
foreach (array_keys($userIds) as $userId) {
1918+
$this->dbForProject->purgeCachedDocument('users', $userId);
1919+
}
18481920
}
18491921

18501922
/**

src/Migration/Resources/Auth/User.php

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class User extends Resource
1919
* @param bool $phoneVerified
2020
* @param bool $disabled
2121
* @param array<string, mixed> $preferences
22+
* @param array<array<string, mixed>> $targets
2223
*/
2324
public function __construct(
2425
string $id,
@@ -31,7 +32,8 @@ public function __construct(
3132
private readonly bool $emailVerified = false,
3233
private readonly bool $phoneVerified = false,
3334
private readonly bool $disabled = false,
34-
private readonly array $preferences = []
35+
private readonly array $preferences = [],
36+
private readonly array $targets = [],
3537
) {
3638
$this->id = $id;
3739
}
@@ -53,7 +55,8 @@ public static function fromArray(array $array): self
5355
$array['emailVerified'] ?? false,
5456
$array['phoneVerified'] ?? false,
5557
$array['disabled'] ?? false,
56-
$array['preferences'] ?? []
58+
$array['preferences'] ?? [],
59+
$array['targets'] ?? [],
5760
);
5861
}
5962

@@ -74,6 +77,7 @@ public function jsonSerialize(): array
7477
'phoneVerified' => $this->phoneVerified,
7578
'disabled' => $this->disabled,
7679
'preferences' => $this->preferences,
80+
'targets' => $this->targets,
7781
];
7882
}
7983

@@ -172,4 +176,14 @@ public function getPreferences(): array
172176
{
173177
return $this->preferences;
174178
}
179+
180+
/**
181+
* Get Targets
182+
*
183+
* @return array<array<string, mixed>>
184+
*/
185+
public function getTargets(): array
186+
{
187+
return $this->targets;
188+
}
175189
}

src/Migration/Sources/Appwrite.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,7 @@ private function exportUsers(int $batchSize): void
617617
$user['phoneVerification'] ?? false,
618618
!$user['status'],
619619
$user['prefs'] ?? [],
620+
$user['targets'] ?? [],
620621
);
621622

622623
$lastDocument = $user['$id'];

0 commit comments

Comments
 (0)