EmailShadowUserResolver
Default {@see ResolvesShadowUser}: link-by-core-id, adopt-by-email, provision-on-miss, against a single configured Eloquent model.
Resolution order (idempotent):
{$idColumn} = $principal->id→ sync drift, return.LOWER({$emailColumn}) = email→ stamp the link, return. (Adopts pre-existing local accounts on first federated login — the Phase-B “import existing users” path needs no batch job.)- create a fresh row (when
create_missing), with an unusable random password when the schema requires one — local password login is dead for federated users by design.
Column names + model come from config/vauth.php (bridge.*).
Apps with richer needs (role mapping into a local enum, multiple
user types, org gating) implement the interface themselves.
Methods
__construct()
function __construct( private readonly string $model, private readonly string $idColumn = 'ven_user_id', private readonly string $emailColumn = 'email', private readonly ?string $nameColumn = 'name', private readonly bool $createMissing = true, private readonly bool $setRandomPassword = true, // Soft-delete handling (config: bridge.with_trashed / bridge.on_trashed). // withTrashed includes soft-deleted rows in the link/adopt lookups so a // returning soft-deleted user is recognized instead of hitting a // UNIQUE(email) collision on re-provision. onTrashed: deny | restore | adopt. private readonly bool $withTrashed = false, private readonly string $onTrashed = 'deny',)Parameters
$model—class-string<Model>
newQuery()
function newQuery(): \Illuminate\Database\Eloquent\BuilderA fresh query for the model, including soft-deleted rows when
withTrashed is on and the model supports it.
handleTrashed()
function handleTrashed(Authenticatable $local): AuthenticatableAnnotations
@varModel $model / $model = new $this->model(); $query = $model->newQuery(); if ($this->withTrashed && method_exists($model, ‘withTrashed’)) { $query = $model->newQuery()->withTrashed(); } return $query; } /* Apply the configured policy to a matched, soft-deleted row. Returns the (possibly restored) model, or throws ShadowUserDenied when policy = deny.