$data['email'] ?? null, 'expires_at' => now()->addDays((int) ($data['expires_in_days'] ?? 7)), 'created_at' => now(), ]); // Token gehasht speichern — Klartext nur in der URL (V05) $invitation->token = hash('sha256', $rawToken); $invitation->created_by = $admin->id; $invitation->save(); if (!empty($data['player_ids'])) { $invitation->players()->attach($data['player_ids']); } // raw_token für die URL-Generierung bereitstellen (nicht persistiert) $invitation->raw_token = $rawToken; return $invitation; } public function redeemInvitation(Invitation $invitation, array $userData): User { return DB::transaction(function () use ($invitation, $userData) { $user = User::create([ 'name' => $userData['name'], 'email' => $userData['email'], 'password' => $userData['password'], ]); $user->is_active = true; $user->role = UserRole::User; $user->save(); // Eltern-Kind-Zuordnungen aus der Einladung übernehmen foreach ($invitation->players as $player) { $user->children()->attach($player->id, [ 'created_at' => now(), ]); } $invitation->accepted_at = now(); $invitation->save(); return $user; }); } }