@@ -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 /**
0 commit comments