init
This commit is contained in:
@@ -19,21 +19,69 @@ class IngestService
|
||||
/**
|
||||
* Stable device id — currently only from payload `d` / `f`.
|
||||
* Other fields will be added when confirmed in live traffic.
|
||||
*
|
||||
* `/api/user/check` multipart sends an encoded form of the same id
|
||||
* (see {@see normalizeDeviceKey}); JSON routes send the 16-hex form.
|
||||
*/
|
||||
public function extractDeviceKey(?array $payload): ?string
|
||||
{
|
||||
if (! is_array($payload)) {
|
||||
return null;
|
||||
}
|
||||
foreach (['d', 'f'] as $key) {
|
||||
if (! empty($payload[$key]) && is_string($payload[$key])) {
|
||||
return substr($payload[$key], 0, 64);
|
||||
$candidates = [];
|
||||
if (isset($payload['form']) && is_array($payload['form'])) {
|
||||
$candidates[] = $payload['form']['d'] ?? null;
|
||||
$candidates[] = $payload['form']['f'] ?? null;
|
||||
}
|
||||
$candidates[] = $payload['d'] ?? null;
|
||||
$candidates[] = $payload['f'] ?? null;
|
||||
|
||||
foreach ($candidates as $value) {
|
||||
if (! empty($value) && is_string($value)) {
|
||||
return self::normalizeDeviceKey(substr($value, 0, 64));
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map `/check` multipart `d`/`f` onto the JSON-route device id.
|
||||
*
|
||||
* Live photo upload encodes: hex(ascii(nibbleSwap(byteReverse(json_d)))).
|
||||
* Example: JSON `000430C910E8E526` ↔ check `36323545384530313943303334303030`.
|
||||
* Plain 16-hex (and non-matching strings) pass through unchanged.
|
||||
*/
|
||||
public static function normalizeDeviceKey(?string $key): ?string
|
||||
{
|
||||
if ($key === null || $key === '') {
|
||||
return $key;
|
||||
}
|
||||
|
||||
if (! preg_match('/^[0-9a-fA-F]{32}$/', $key)) {
|
||||
return $key;
|
||||
}
|
||||
|
||||
$ascii = hex2bin($key);
|
||||
if (! is_string($ascii) || ! preg_match('/^[0-9A-Fa-f]{16}$/', $ascii)) {
|
||||
return $key;
|
||||
}
|
||||
|
||||
$raw = hex2bin($ascii);
|
||||
if ($raw === false || strlen($raw) !== 8) {
|
||||
return $key;
|
||||
}
|
||||
|
||||
$rev = strrev($raw);
|
||||
$out = '';
|
||||
for ($i = 0; $i < 8; $i++) {
|
||||
$b = ord($rev[$i]);
|
||||
$out .= sprintf('%02X', (($b & 0x0F) << 4) | (($b & 0xF0) >> 4));
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Campaign / channel id from reporting traffic.
|
||||
*
|
||||
@@ -70,7 +118,9 @@ class IngestService
|
||||
|
||||
public function upsertDevice(Request $request, ?array $payload, ?string $deviceKey = null): ?Device
|
||||
{
|
||||
$deviceKey ??= $this->extractDeviceKey($payload);
|
||||
$deviceKey = $deviceKey !== null
|
||||
? self::normalizeDeviceKey(substr($deviceKey, 0, 64))
|
||||
: $this->extractDeviceKey($payload);
|
||||
if (! $deviceKey) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user