Add SportPath auth APIs and training content foundation
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
interface OtpProvider
|
||||
{
|
||||
public function send(string $phoneE164, string $code): void;
|
||||
}
|
||||
|
||||
/** Minimal HTTP JSON adapter. Map request fields to the selected vendor contract only after confirmation. */
|
||||
final class ConfiguredHttpOtpProvider implements OtpProvider
|
||||
{
|
||||
public function send(string $phoneE164, string $code): void
|
||||
{
|
||||
AppConfig::loadEnvironment();
|
||||
if (getenv('OTP_ENABLED') !== 'true') {
|
||||
throw new RuntimeException('OTP provider is disabled');
|
||||
}
|
||||
if (AppConfig::required('OTP_PROVIDER') !== 'generic_json') {
|
||||
throw new RuntimeException('Configure a supported OTP provider adapter before enabling delivery');
|
||||
}
|
||||
$url = AppConfig::required('OTP_API_URL');
|
||||
$apiKey = AppConfig::required('OTP_API_KEY');
|
||||
if (!filter_var($url, FILTER_VALIDATE_URL) || parse_url($url, PHP_URL_SCHEME) !== 'https') {
|
||||
throw new RuntimeException('OTP endpoint must use HTTPS');
|
||||
}
|
||||
if (!function_exists('curl_init')) {
|
||||
throw new RuntimeException('The cURL extension is required for OTP delivery');
|
||||
}
|
||||
|
||||
$sender = getenv('OTP_SENDER_ID') ?: '';
|
||||
$message = getenv('OTP_MESSAGE_TEMPLATE') ?: 'رمز التحقق الخاص بك هو {code}';
|
||||
if (strpos($message, '{code}') === false) {
|
||||
throw new RuntimeException('OTP message template must include {code}');
|
||||
}
|
||||
$payload = json_encode([
|
||||
'to' => $phoneE164,
|
||||
'sender' => $sender,
|
||||
'message' => str_replace('{code}', $code, $message),
|
||||
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
if ($payload === false) {
|
||||
throw new RuntimeException('Unable to encode OTP request');
|
||||
}
|
||||
$handle = curl_init($url);
|
||||
curl_setopt_array($handle, [
|
||||
CURLOPT_POST => true,
|
||||
CURLOPT_POSTFIELDS => $payload,
|
||||
CURLOPT_HTTPHEADER => ['Content-Type: application/json', 'Authorization: Bearer ' . $apiKey],
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_CONNECTTIMEOUT => 5,
|
||||
CURLOPT_TIMEOUT => 12,
|
||||
CURLOPT_PROTOCOLS => CURLPROTO_HTTPS,
|
||||
]);
|
||||
$response = curl_exec($handle);
|
||||
$status = (int) curl_getinfo($handle, CURLINFO_RESPONSE_CODE);
|
||||
$error = curl_error($handle);
|
||||
curl_close($handle);
|
||||
if ($response === false || $status < 200 || $status >= 300) {
|
||||
error_log('OTP delivery failed; HTTP ' . $status . '; transport error: ' . $error);
|
||||
throw new RuntimeException('OTP provider rejected the request');
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user