true, 'data' => $value, ), JSON_UNESCAPED_SLASHES), $callback_url) : false; } public static function parse($body, $callback_url, $limit = 4096) { if (!is_string($body) || strlen($body) >= $limit) { return false; } $value = Akkedli_V2_Strict_JSON::decode($body, array('success', 'data'), array('credential_id', 'secret', 'protocol_version', 'callback_url', 'binding_status')); if (!is_array($value) || true !== $value['success'] || 1 !== $value['data']['protocol_version'] || 'pending' !== $value['data']['binding_status'] || !is_string($value['data']['credential_id']) || !is_string($value['data']['secret']) || !is_string($value['data']['callback_url']) || !preg_match('/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/D', $value['data']['credential_id']) || !Akkedli_V2_Callback_URL::is_canonical($value['data']['callback_url']) || !Akkedli_V2_Callback_URL::same_target($callback_url, $value['data']['callback_url'])) { return false; } try { $secret = Akkedli_V2_Crypto::base64url_decode($value['data']['secret']); } catch (Throwable $error) { unset($error); return false; } $valid = 32 === strlen($secret); unset($secret); return $valid ? $value['data'] : false; } }