8 || !is_bool($state['automatic_stopped']) || ($state['automatic_stopped'] ? 0 !== $state['next_attempt_at'] : (0 === $state['attempt_count'] && $state['next_attempt_at'] < 1)) || !Akkedli_Connector_State::is_valid_backup($state['legacy_backup']) || !Akkedli_V2_Callback_URL::is_canonical($state['callback_url'])) { return false; } try { $secret = Akkedli_V2_Crypto::base64url_decode($state['secret']); } catch (Throwable $error) { unset($error); return false; } return 32 === strlen($secret); } public static function pending(array $credentials, array $backup, $now) { return array('schema_version' => 1, 'mode' => 'v2_pending', 'credential_id' => $credentials['credential_id'], 'secret' => $credentials['secret'], 'protocol_version' => 1, 'callback_url' => $credentials['callback_url'], 'legacy_backup' => $backup, 'poll_started_at' => $now, 'next_attempt_at' => $now + 45, 'attempt_count' => 0, 'automatic_stopped' => false); } public static function verified(array $pending) { $state = array('schema_version' => 1, 'mode' => 'v2', 'credential_id' => $pending['credential_id'], 'secret' => $pending['secret'], 'protocol_version' => 1, 'outbox_recovery_pending' => true); $legacy = $pending['legacy_backup']['api_key']; if ($legacy['present'] && '' !== $legacy['value']) { $state['legacy_callback_key'] = $legacy['value']; } return $state; } public static function failed(array $pending) { return array('schema_version' => 1, 'mode' => 'v2_failed', 'legacy_backup' => $pending['legacy_backup']); } public static function authority_lost($credential_id) { $state = Akkedli_Connector_State::load(); if (!is_string($credential_id) || !is_array($state) || 'v2' !== $state['mode'] || !hash_equals($credential_id, $state['credential_id'])) return false; $failed = array('schema_version' => 1, 'mode' => 'v2_failed', 'legacy_backup' => Akkedli_Connector_State::create_legacy_backup()); return Akkedli_Connector_State::replace($failed, $state); } }