Verify apiKey ownership to safely take DB fast path for SourceAppwrite

This commit is contained in:
Prem Palanisamy
2026-05-22 09:22:01 +01:00
parent 507f9d6c6c
commit e35cfa928a
+22 -2
View File
@@ -204,17 +204,37 @@ class Migrations extends Action
if (! empty($credentials['projectId'])) {
$this->sourceProject = $this->dbForPlatform->getDocument('projects', $credentials['projectId']);
// For Appwrite -> Appwrite, "project exists locally with this id" is not
// enough to take the DB fast path: a destination project deliberately
// created with the source's projectId (to preserve cross-references like
// createdBy/userId) would collide. Verify the user-supplied apiKey actually
// belongs to the local project — only then is it safe to read direct.
$isLocalSource = false;
if (
$source === SourceAppwrite::getName()
&& $destination === DestinationAppwrite::getName()
&& !$this->sourceProject->isEmpty()
&& !empty($credentials['apiKey'])
) {
$keyDoc = $this->dbForPlatform->findOne('keys', [
Query::equal('secret', [$credentials['apiKey']]),
Query::equal('projectInternalId', [$this->sourceProject->getSequence()]),
]);
$isLocalSource = $keyDoc !== false && !$keyDoc->isEmpty();
}
$sourceRegion = $this->sourceProject->getAttribute('region', 'default');
$destinationRegion = $this->project->getAttribute('region', 'default');
$useAppwriteApiSource = $source === SourceAppwrite::getName()
&& $destination === DestinationAppwrite::getName()
&& ($this->sourceProject->isEmpty() || $sourceRegion !== $destinationRegion);
&& (!$isLocalSource || $sourceRegion !== $destinationRegion);
if (! $useAppwriteApiSource) {
if ($this->sourceProject->isEmpty()) {
throw new Exception(Exception::MIGRATION_SOURCE_PROJECT_NOT_FOUND);
}
$projectDB = call_user_func($this->getProjectDB, $this->sourceProject);
} elseif ($this->sourceProject->isEmpty()) {
} elseif (!$isLocalSource) {
// External source — processMigration defaults missing endpoint/apiKey to this
// instance, which would silently self-call with the destination's key. Require
// explicit credentials so the failure mode is clear.