move api to sub-dir
This commit is contained in:
2
web/api/.gitignore
vendored
Normal file
2
web/api/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
config.php
|
||||
.verify_accesstoken
|
47
web/api/ack.php
Normal file
47
web/api/ack.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
include_once 'model.php';
|
||||
|
||||
$INPUT = array_merge($_GET, $_POST);
|
||||
|
||||
|
||||
if (!isset($INPUT['user_id'])) die(json_encode(['success' => false, 'errid'=>101, 'message' => 'Missing parameter [[user_id]]']));
|
||||
if (!isset($INPUT['user_key'])) die(json_encode(['success' => false, 'errid'=>102, 'message' => 'Missing parameter [[user_key]]']));
|
||||
if (!isset($INPUT['scn_msg_id'])) die(json_encode(['success' => false, 'errid'=>103, 'message' => 'Missing parameter [[scn_msg_id]]']));
|
||||
|
||||
$user_id = $INPUT['user_id'];
|
||||
$user_key = $INPUT['user_key'];
|
||||
$scn_msg_id = $INPUT['scn_msg_id'];
|
||||
|
||||
//----------------------
|
||||
|
||||
$pdo = getDatabase();
|
||||
|
||||
$stmt = $pdo->prepare('SELECT user_id, user_key, quota_today, is_pro, quota_day, fcm_token FROM users WHERE user_id = :uid LIMIT 1');
|
||||
$stmt->execute(['uid' => $user_id]);
|
||||
$datas = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if (count($datas)<=0) die(json_encode(['success' => false, 'errid'=>201, 'message' => 'User not found']));
|
||||
$data = $datas[0];
|
||||
|
||||
if ($data === null) die(json_encode(['success' => false, 'errid'=>202, 'message' => 'User not found']));
|
||||
if ($data['user_id'] !== (int)$user_id) die(json_encode(['success' => false, 'errid'=>203, 'message' => 'UserID not found']));
|
||||
if ($data['user_key'] !== $user_key) die(json_encode(['success' => false, 'errid'=>204, 'message' => 'Authentification failed']));
|
||||
|
||||
$stmt = $pdo->prepare('SELECT ack FROM messages WHERE scn_message_id=:smid AND sender_user_id=:uid LIMIT 1');
|
||||
$stmt->execute(['smid' => $scn_msg_id, 'uid' => $user_id]);
|
||||
$datas = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if (count($datas)<=0) die(json_encode(['success' => false, 'errid'=>301, 'message' => 'Message not found']));
|
||||
|
||||
$stmt = $pdo->prepare('UPDATE messages SET ack=1 WHERE scn_message_id=:smid AND sender_user_id=:uid');
|
||||
$stmt->execute(['smid' => $scn_msg_id, 'uid' => $user_id]);
|
||||
|
||||
echo json_encode(
|
||||
[
|
||||
'success' => true,
|
||||
'prev_ack' => $datas[0]['ack'],
|
||||
'new_ack' => 1,
|
||||
'message' => 'ok'
|
||||
]);
|
||||
return 0;
|
44
web/api/info.php
Normal file
44
web/api/info.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
include_once 'model.php';
|
||||
|
||||
$INPUT = array_merge($_GET, $_POST);
|
||||
|
||||
|
||||
if (!isset($INPUT['user_id'])) die(json_encode(['success' => false, 'errid'=>101, 'message' => 'Missing parameter [[user_id]]']));
|
||||
if (!isset($INPUT['user_key'])) die(json_encode(['success' => false, 'errid'=>102, 'message' => 'Missing parameter [[user_key]]']));
|
||||
|
||||
$user_id = $INPUT['user_id'];
|
||||
$user_key = $INPUT['user_key'];
|
||||
|
||||
//----------------------
|
||||
|
||||
$pdo = getDatabase();
|
||||
|
||||
$stmt = $pdo->prepare('SELECT user_id, user_key, quota_today, is_pro, quota_day, fcm_token FROM users WHERE user_id = :uid LIMIT 1');
|
||||
$stmt->execute(['uid' => $user_id]);
|
||||
|
||||
$datas = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
if (count($datas)<=0) die(json_encode(['success' => false, 'errid'=>201, 'message' => 'User not found']));
|
||||
$data = $datas[0];
|
||||
|
||||
if ($data === null) die(json_encode(['success' => false, 'errid'=>202, 'message' => 'User not found']));
|
||||
if ($data['user_id'] !== (int)$user_id) die(json_encode(['success' => false, 'errid'=>203, 'message' => 'UserID not found']));
|
||||
if ($data['user_key'] !== $user_key) die(json_encode(['success' => false, 'errid'=>204, 'message' => 'Authentification failed']));
|
||||
|
||||
$quota = $data['quota_today'];
|
||||
$is_pro = $data['is_pro'];
|
||||
|
||||
if ($data['quota_day'] === null || $data['quota_day'] !== date("Y-m-d")) $quota=0;
|
||||
|
||||
echo json_encode(
|
||||
[
|
||||
'success' => true,
|
||||
'user_id' => $user_id,
|
||||
'quota' => $quota,
|
||||
'quota_max' => Statics::quota_max($is_pro),
|
||||
'is_pro' => $is_pro,
|
||||
'fcm_token_set' => ($data['fcm_token'] != null),
|
||||
'message' => 'ok'
|
||||
]);
|
||||
return 0;
|
BIN
web/api/lib/httpful.phar
Normal file
BIN
web/api/lib/httpful.phar
Normal file
Binary file not shown.
256
web/api/model.php
Normal file
256
web/api/model.php
Normal file
@@ -0,0 +1,256 @@
|
||||
<?php
|
||||
|
||||
include('lib/httpful.phar');
|
||||
|
||||
class ERR
|
||||
{
|
||||
const NO_ERROR = 0000;
|
||||
|
||||
const MISSING_UID = 1101;
|
||||
const MISSING_TOK = 1102;
|
||||
const MISSING_TITLE = 1103;
|
||||
const INVALID_PRIO = 1104;
|
||||
const REQ_METHOD = 1105;
|
||||
|
||||
const NO_TITLE = 1201;
|
||||
const TITLE_TOO_LONG = 1202;
|
||||
const CONTENT_TOO_LONG = 1203;
|
||||
const USR_MSG_ID_TOO_LONG = 1204;
|
||||
|
||||
const USER_NOT_FOUND = 1301;
|
||||
const USER_AUTH_FAILED = 1302;
|
||||
|
||||
const NO_DEVICE_LINKED = 1401;
|
||||
|
||||
const QUOTA_REACHED = 2101;
|
||||
|
||||
const FIREBASE_COM_FAILED = 9901;
|
||||
const FIREBASE_COM_ERRORED = 9902;
|
||||
const INTERNAL_EXCEPTION = 9903;
|
||||
}
|
||||
|
||||
class Statics
|
||||
{
|
||||
public static $DB = NULL;
|
||||
public static $CFG = NULL;
|
||||
|
||||
public static function quota_max($is_pro) { return $is_pro ? 1000 : 50; }
|
||||
}
|
||||
|
||||
function getConfig()
|
||||
{
|
||||
if (Statics::$CFG !== NULL) return Statics::$CFG;
|
||||
|
||||
return Statics::$CFG = require "config.php";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param String $msg
|
||||
* @param Exception $e
|
||||
*/
|
||||
function reportError($msg, $e = null)
|
||||
{
|
||||
if ($e != null) $msg = ($msg."\n\n[[EXCEPTION]]\n" . $e . "\n" . $e->getMessage() . "\n" . $e->getTraceAsString());
|
||||
|
||||
$subject = "SCN_Server has encountered an Error at " . date("Y-m-d H:i:s") . "] ";
|
||||
|
||||
$content = "";
|
||||
|
||||
$content .= 'HTTP_HOST: ' . ParamServerOrUndef('HTTP_HOST') . "\n";
|
||||
$content .= 'REQUEST_URI: ' . ParamServerOrUndef('REQUEST_URI') . "\n";
|
||||
$content .= 'TIME: ' . date('Y-m-d H:i:s') . "\n";
|
||||
$content .= 'REMOTE_ADDR: ' . ParamServerOrUndef('REMOTE_ADDR') . "\n";
|
||||
$content .= 'HTTP_X_FORWARDED_FOR: ' . ParamServerOrUndef('HTTP_X_FORWARDED_FOR') . "\n";
|
||||
$content .= 'HTTP_USER_AGENT: ' . ParamServerOrUndef('HTTP_USER_AGENT') . "\n";
|
||||
$content .= 'MESSAGE:' . "\n" . $msg . "\n";
|
||||
$content .= '$_GET:' . "\n" . print_r($_GET, true) . "\n";
|
||||
$content .= '$_POST:' . "\n" . print_r($_POST, true) . "\n";
|
||||
$content .= '$_FILES:' . "\n" . print_r($_FILES, true) . "\n";
|
||||
|
||||
if (getConfig()['error_reporting']['send-mail']) sendMail($subject, $content, getConfig()['error_reporting']['email-error-target'], getConfig()['error_reporting']['email-error-sender']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $subject
|
||||
* @param string $content
|
||||
* @param string $to
|
||||
* @param string $from
|
||||
*/
|
||||
function sendMail($subject, $content, $to, $from) {
|
||||
mail($to, $subject, $content, 'From: ' . $from);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $idx
|
||||
* @return string
|
||||
*/
|
||||
function ParamServerOrUndef($idx) {
|
||||
return isset($_SERVER[$idx]) ? $_SERVER[$idx] : 'NOT_SET';
|
||||
}
|
||||
|
||||
function getDatabase()
|
||||
{
|
||||
if (Statics::$DB !== NULL) return Statics::$DB;
|
||||
|
||||
$_config = getConfig()['database'];
|
||||
|
||||
$dsn = "mysql:host=" . $_config['host'] . ";dbname=" . $_config['database'] . ";charset=utf8";
|
||||
$opt = [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
PDO::ATTR_EMULATE_PREPARES => false,
|
||||
];
|
||||
|
||||
return Statics::$DB = new PDO($dsn, $_config['user'], $_config['password'], $opt);
|
||||
}
|
||||
|
||||
function generateRandomAuthKey()
|
||||
{
|
||||
$random = '';
|
||||
for ($i = 0; $i < 64; $i++)
|
||||
|
||||
try {
|
||||
switch (random_int(1, 3)) {
|
||||
case 1:
|
||||
$random .= chr(random_int(ord('0'), ord('9')));
|
||||
break;
|
||||
case 2:
|
||||
$random .= chr(random_int(ord('A'), ord('Z')));
|
||||
break;
|
||||
case 3:
|
||||
$random .= chr(random_int(ord('a'), ord('z')));
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
die(json_encode(['success' => false, 'message' => 'Internal error - no randomness']));
|
||||
}
|
||||
return $random;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $url
|
||||
* @param $body
|
||||
* @param $header
|
||||
* @return array|object|string
|
||||
* @throws \Httpful\Exception\ConnectionErrorException
|
||||
* @throws Exception
|
||||
*/
|
||||
function sendPOST($url, $body, $header)
|
||||
{
|
||||
$builder = \Httpful\Request::post($url);
|
||||
|
||||
$builder->body($body);
|
||||
|
||||
foreach ($header as $k => $v) $builder->addHeader($k, $v);
|
||||
|
||||
$response = $builder->send();
|
||||
|
||||
if ($response->code != 200) throw new Exception("Repsponse code: " . $response->code);
|
||||
|
||||
return $response->raw_body;
|
||||
}
|
||||
|
||||
function verifyOrderToken($tok)
|
||||
{
|
||||
// https://developers.google.com/android-publisher/api-ref/purchases/products/get
|
||||
|
||||
try
|
||||
{
|
||||
$package = getConfig()['verify_api']['package_name'];
|
||||
$product = getConfig()['verify_api']['product_id'];
|
||||
$acctoken = getConfig()['verify_api']['accesstoken'];
|
||||
|
||||
if ($acctoken == '' || $acctoken == null || $acctoken == false) $acctoken = refreshVerifyToken();
|
||||
|
||||
$url = 'https://www.googleapis.com/androidpublisher/v3/applications/'.$package.'/purchases/products/'.$product.'/tokens/'.$tok.'?access_token='.$acctoken;
|
||||
$response = $builder = \Httpful\Request::get($url)->send();
|
||||
$obj = json_decode($response->raw_body, true);
|
||||
|
||||
if ($response->code != 401 && ($obj === null || $obj === false))
|
||||
{
|
||||
reportError('verify-token returned NULL');
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($response->code == 401 || isset($obj['error']) && isset($obj['error']['code']) && $obj['error']['code'] == 401) // "Invalid Credentials" -- refresh acces_token
|
||||
{
|
||||
$acctoken = refreshVerifyToken();
|
||||
|
||||
$url = 'https://www.googleapis.com/androidpublisher/v3/applications/'.$package.'/purchases/products/'.$product.'/tokens/'.$tok.'?access_token='.$acctoken;
|
||||
$response = $builder = \Httpful\Request::get($url)->send();
|
||||
$obj = json_decode($response->raw_body, true);
|
||||
|
||||
if ($obj === null || $obj === false)
|
||||
{
|
||||
reportError('verify-token returned NULL');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($obj['purchaseState']) && $obj['purchaseState'] === 0) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
reportError("VerifyOrder token threw exception", $e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** @throws Exception */
|
||||
function refreshVerifyToken()
|
||||
{
|
||||
$url = 'https://accounts.google.com/o/oauth2/token'.
|
||||
'?grant_type=refresh_token'.
|
||||
'&refresh_token='.getConfig()['verify_api']['refreshtoken'].
|
||||
'&client_id='.getConfig()['verify_api']['clientid'].
|
||||
'&client_secret='.getConfig()['verify_api']['clientsecret'];
|
||||
|
||||
$json = sendPOST($url, "", []);
|
||||
$obj = json_decode($json, true);
|
||||
file_put_contents('.verify_accesstoken', $obj['access_token']);
|
||||
|
||||
return $obj['access_token'];
|
||||
}
|
||||
|
||||
function api_return($http_code, $message)
|
||||
{
|
||||
http_response_code($http_code);
|
||||
echo $message;
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param String $str
|
||||
* @param String[] $path
|
||||
* @return mixed|null
|
||||
*/
|
||||
function try_json($str, $path)
|
||||
{
|
||||
try
|
||||
{
|
||||
$o = json_decode($str, true);
|
||||
foreach ($path as $p) $o = $o[$p];
|
||||
return $o;
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
//#################################################################################################################
|
||||
|
||||
if (getConfig()['global']['prod']) {
|
||||
ini_set('display_errors', 0);
|
||||
ini_set('log_errors', 1);
|
||||
} else {
|
||||
error_reporting(E_STRICT);
|
||||
ini_set('display_errors', 1);
|
||||
}
|
||||
|
||||
//#################################################################################################################
|
52
web/api/register.php
Normal file
52
web/api/register.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
include_once 'model.php';
|
||||
|
||||
$INPUT = array_merge($_GET, $_POST);
|
||||
|
||||
if (!isset($INPUT['fcm_token'])) die(json_encode(['success' => false, 'message' => 'Missing parameter [[fcm_token]]']));
|
||||
if (!isset($INPUT['pro'])) die(json_encode(['success' => false, 'message' => 'Missing parameter [[pro]]']));
|
||||
if (!isset($INPUT['pro_token'])) die(json_encode(['success' => false, 'message' => 'Missing parameter [[pro_token]]']));
|
||||
|
||||
$fcmtoken = $INPUT['fcm_token'];
|
||||
$ispro = $INPUT['pro'] == 'true';
|
||||
$pro_token = $INPUT['pro_token'];
|
||||
$user_key = generateRandomAuthKey();
|
||||
|
||||
$pdo = getDatabase();
|
||||
|
||||
$pdo->beginTransaction();
|
||||
|
||||
if ($ispro)
|
||||
{
|
||||
if (!verifyOrderToken($pro_token))
|
||||
{
|
||||
$pdo->rollBack();
|
||||
die(json_encode(['success' => false, 'message' => 'Purchase token could not be verified']));
|
||||
}
|
||||
|
||||
$stmt = $pdo->prepare('UPDATE users SET is_pro=0, pro_token=NULL WHERE user_id <> :uid AND pro_token = :ptk');
|
||||
$stmt->execute(['uid' => $user_id, 'ptk' => $pro_token]);
|
||||
}
|
||||
|
||||
$stmt = $pdo->prepare('INSERT INTO users (user_key, fcm_token, is_pro, pro_token, timestamp_accessed) VALUES (:key, :token, :bpro, :spro, NOW())');
|
||||
$stmt->execute(['key' => $user_key, 'token' => $fcmtoken, 'bpro' => $ispro, 'spro' => $ispro ? $pro_token : null]);
|
||||
$user_id = $pdo->lastInsertId('user_id');
|
||||
|
||||
$stmt = $pdo->prepare('UPDATE users SET fcm_token=NULL WHERE user_id <> :uid AND fcm_token=:ft');
|
||||
$stmt->execute(['uid' => $user_id, 'ft' => $fcm_token]);
|
||||
|
||||
$pdo->commit();
|
||||
|
||||
echo json_encode(
|
||||
[
|
||||
'success' => true,
|
||||
'user_id' => $user_id,
|
||||
'user_key' => $user_key,
|
||||
'quota' => 0,
|
||||
'quota_max' => Statics::quota_max($ispro),
|
||||
'is_pro' => $ispro,
|
||||
'message' => 'New user registered'
|
||||
]);
|
||||
|
||||
return 0;
|
37
web/api/schema.sql
Normal file
37
web/api/schema.sql
Normal file
@@ -0,0 +1,37 @@
|
||||
DROP TABLE IF EXISTS `users`;
|
||||
CREATE TABLE `users`
|
||||
(
|
||||
`user_id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`user_key` VARCHAR(64) NOT NULL,
|
||||
`fcm_token` VARCHAR(256) NULL DEFAULT NULL,
|
||||
`messages_sent` INT(11) NOT NULL DEFAULT '0',
|
||||
`timestamp_created` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`timestamp_accessed` DATETIME NULL DEFAULT NULL,
|
||||
|
||||
`quota_today` INT(11) NOT NULL DEFAULT '0',
|
||||
`quota_day` DATE NULL DEFAULT NULL,
|
||||
|
||||
`is_pro` BIT NOT NULL DEFAULT 0,
|
||||
`pro_token` VARCHAR(256) NULL DEFAULT NULL,
|
||||
|
||||
PRIMARY KEY (`user_id`)
|
||||
);
|
||||
|
||||
DROP TABLE IF EXISTS `messages`;
|
||||
CREATE TABLE `messages`
|
||||
(
|
||||
`scn_message_id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`sender_user_id` INT(11) NOT NULL,
|
||||
|
||||
`timestamp` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`ack` BIT NOT NULL DEFAULT 0,
|
||||
|
||||
`title` VARCHAR(256) NOT NULL,
|
||||
`content` VARCHAR(12288) NULL,
|
||||
`priority` INT(11) NOT NULL,
|
||||
|
||||
`fcm_message_id` VARCHAR(256) NULL,
|
||||
`usr_message_id` VARCHAR(256) NULL,
|
||||
|
||||
PRIMARY KEY (`scn_message_id`)
|
||||
);
|
179
web/api/send.php
Normal file
179
web/api/send.php
Normal file
@@ -0,0 +1,179 @@
|
||||
<?php
|
||||
|
||||
include_once 'model.php';
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//sleep(1);
|
||||
//------------------------------------------------------------------
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') api_return(400, json_encode(['success' => false, 'error' => ERR::REQ_METHOD, 'errhighlight' => -1, 'message' => 'Invalid request method (must be POST)']));
|
||||
|
||||
$INPUT = array_merge($_GET, $_POST);
|
||||
|
||||
if (!isset($INPUT['user_id'])) api_return(400, json_encode(['success' => false, 'error' => ERR::MISSING_UID, 'errhighlight' => 101, 'message' => 'Missing parameter [[user_id]]']));
|
||||
if (!isset($INPUT['user_key'])) api_return(400, json_encode(['success' => false, 'error' => ERR::MISSING_TOK, 'errhighlight' => 102, 'message' => 'Missing parameter [[user_token]]']));
|
||||
if (!isset($INPUT['title'])) api_return(400, json_encode(['success' => false, 'error' => ERR::MISSING_TITLE, 'errhighlight' => 103, 'message' => 'Missing parameter [[title]]']));
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
||||
|
||||
$user_id = $INPUT['user_id'];
|
||||
$user_key = $INPUT['user_key'];
|
||||
$message = $INPUT['title'];
|
||||
$content = isset($INPUT['content']) ? $INPUT['content'] : '';
|
||||
$priority = isset($INPUT['priority']) ? $INPUT['priority'] : '1';
|
||||
$usrmsgid = isset($INPUT['msg_id']) ? $INPUT['msg_id'] : null;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
||||
if ($priority !== '0' && $priority !== '1' && $priority !== '2') api_return(400, json_encode(['success' => false, 'error' => ERR::INVALID_PRIO, 'errhighlight' => 105, 'message' => 'Invalid priority']));
|
||||
|
||||
if (strlen(trim($message)) == 0) api_return(400, json_encode(['success' => false, 'error' => ERR::NO_TITLE, 'errhighlight' => 103, 'message' => 'No title specified']));
|
||||
if (strlen($message) > 120) api_return(400, json_encode(['success' => false, 'error' => ERR::TITLE_TOO_LONG, 'errhighlight' => 103, 'message' => 'Title too long (120 characters)']));
|
||||
if (strlen($content) > 10000) api_return(400, json_encode(['success' => false, 'error' => ERR::CONTENT_TOO_LONG, 'errhighlight' => 104, 'message' => 'Content too long (10000 characters)']));
|
||||
if ($usrmsgid != null && strlen($usrmsgid) > 64) api_return(400, json_encode(['success' => false, 'error' => ERR::USR_MSG_ID_TOO_LONG, 'errhighlight' => -1, 'message' => 'MessageID too long (64 characters)']));
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
||||
$pdo = getDatabase();
|
||||
|
||||
$stmt = $pdo->prepare('SELECT user_id, user_key, fcm_token, messages_sent, quota_today, is_pro, quota_day FROM users WHERE user_id = :uid LIMIT 1');
|
||||
$stmt->execute(['uid' => $user_id]);
|
||||
|
||||
$datas = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
if (count($datas)<=0) die(json_encode(['success' => false, 'error' => ERR::USER_NOT_FOUND, 'errhighlight' => 101, 'message' => 'User not found']));
|
||||
$data = $datas[0];
|
||||
|
||||
if ($data === null) api_return(401, json_encode(['success' => false, 'error' => ERR::USER_NOT_FOUND, 'errhighlight' => 101, 'message' => 'User not found']));
|
||||
if ($data['user_id'] !== (int)$user_id) api_return(401, json_encode(['success' => false, 'error' => ERR::USER_NOT_FOUND, 'errhighlight' => 101, 'message' => 'UserID not found']));
|
||||
if ($data['user_key'] !== $user_key) api_return(401, json_encode(['success' => false, 'error' => ERR::USER_AUTH_FAILED, 'errhighlight' => 102, 'message' => 'Authentification failed']));
|
||||
|
||||
$fcm = $data['fcm_token'];
|
||||
|
||||
$new_quota = $data['quota_today'] + 1;
|
||||
if ($data['quota_day'] === null || $data['quota_day'] !== date("Y-m-d")) $new_quota=1;
|
||||
if ($new_quota > Statics::quota_max($data['is_pro'])) api_return(403, json_encode(['success' => false, 'error' => ERR::QUOTA_REACHED, 'errhighlight' => -1, 'message' => 'Daily quota reached ('.Statics::quota_max($data['is_pro']).')']));
|
||||
|
||||
if ($fcm == null || $fcm == '' || $fcm == false)
|
||||
{
|
||||
api_return(412, json_encode(['success' => false, 'error' => ERR::NO_DEVICE_LINKED, 'errhighlight' => -1, 'message' => 'No device linked with this account']));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
||||
if ($usrmsgid != null)
|
||||
{
|
||||
$stmt = $pdo->prepare('SELECT scn_message_id FROM messages WHERE sender_user_id=:uid AND usr_message_id IS NOT NULL AND usr_message_id=:umid LIMIT 1');
|
||||
$stmt->execute(['uid' => $user_id, 'umid' => $usrmsgid]);
|
||||
|
||||
if (count($stmt->fetchAll(PDO::FETCH_ASSOC))>0)
|
||||
{
|
||||
api_return(200, json_encode(
|
||||
[
|
||||
'success' => true,
|
||||
'message' => 'Message already sent',
|
||||
'suppress_send' => true,
|
||||
'response' => '',
|
||||
'messagecount' => $data['messages_sent']+1,
|
||||
'quota' => $data['quota_today'],
|
||||
'is_pro' => $data['is_pro'],
|
||||
'quota_max' => Statics::quota_max($data['is_pro']),
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
||||
$pdo->beginTransaction();
|
||||
|
||||
|
||||
$stmt = $pdo->prepare('INSERT INTO messages (sender_user_id, title, content, priority, fcm_message_id, usr_message_id) VALUES (:suid, :t, :c, :p, :fmid, :umid)');
|
||||
$stmt->execute(
|
||||
[
|
||||
'suid' => $user_id,
|
||||
't' => $message,
|
||||
'c' => $content,
|
||||
'p' => $priority,
|
||||
'fmid' => null,
|
||||
'umid' => $usrmsgid,
|
||||
]);
|
||||
|
||||
$scn_msg_id = $pdo->lastInsertId();
|
||||
|
||||
$url = "https://fcm.googleapis.com/fcm/send";
|
||||
$payload = json_encode(
|
||||
[
|
||||
'to' => $fcm,
|
||||
//'dry_run' => true,
|
||||
'android' => [ 'priority' => 'high' ],
|
||||
//'notification' =>
|
||||
//[
|
||||
// 'title' => $message,
|
||||
// 'body' => $content,
|
||||
//],
|
||||
'data' =>
|
||||
[
|
||||
'title' => $message,
|
||||
'body' => $content,
|
||||
'priority' => $priority,
|
||||
'timestamp' => time(),
|
||||
'usr_msg_id' => $usrmsgid,
|
||||
'scn_msg_id' => $scn_msg_id,
|
||||
]
|
||||
]);
|
||||
$header=
|
||||
[
|
||||
'Authorization' => 'key=' . getConfig()['firebase']['server_key'],
|
||||
'Content-Type' => 'application/json',
|
||||
];
|
||||
|
||||
try
|
||||
{
|
||||
$httpresult = sendPOST($url, $payload, $header);
|
||||
|
||||
if (try_json($httpresult, ['success']) != 1)
|
||||
{
|
||||
reportError("FCM communication failed (success_1 <> true)\n\n".$httpresult);
|
||||
$pdo->rollBack();
|
||||
api_return(500, json_encode(['success' => false, 'error' => ERR::FIREBASE_COM_ERRORED, 'errhighlight' => -1, 'message' => 'Communication with firebase service failed.']));
|
||||
}
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
reportError("FCM communication failed", $e);
|
||||
$pdo->rollBack();
|
||||
api_return(500, json_encode(['success' => false, 'error' => ERR::FIREBASE_COM_FAILED, 'errhighlight' => -1, 'message' => 'Communication with firebase service failed.'."\n\n".'Exception: ' . $e->getMessage()]));
|
||||
}
|
||||
|
||||
$stmt = $pdo->prepare('UPDATE users SET timestamp_accessed=NOW(), messages_sent=messages_sent+1, quota_today=:q, quota_day=NOW() WHERE user_id = :uid');
|
||||
$stmt->execute(['uid' => $user_id, 'q' => $new_quota]);
|
||||
|
||||
$stmt = $pdo->prepare('UPDATE messages SET fcm_message_id=:fmid WHERE scn_message_id=:smid');
|
||||
$stmt->execute([ 'fmid' => try_json($httpresult, ['results', 0, 'message_id']), 'smid' => $scn_msg_id ]);
|
||||
|
||||
$pdo->commit();
|
||||
|
||||
api_return(200, json_encode(
|
||||
[
|
||||
'success' => true,
|
||||
'error' => ERR::NO_ERROR,
|
||||
'errhighlight' => -1,
|
||||
'message' => 'Message sent',
|
||||
'suppress_send' => false,
|
||||
'response' => $httpresult,
|
||||
'messagecount' => $data['messages_sent']+1,
|
||||
'quota' => $new_quota,
|
||||
'is_pro' => $data['is_pro'],
|
||||
'quota_max' => Statics::quota_max($data['is_pro']),
|
||||
'scn_msg_id' => $scn_msg_id,
|
||||
]));
|
||||
}
|
||||
catch (Exception $mex)
|
||||
{
|
||||
reportError("Root try-catch triggered", $mex);
|
||||
if ($pdo->inTransaction()) $pdo->rollBack();
|
||||
api_return(500, json_encode(['success' => false, 'error' => ERR::INTERNAL_EXCEPTION, 'errhighlight' => -1, 'message' => 'PHP script threw exception.'."\n\n".'Exception: ' . $e->getMessage()]));
|
||||
}
|
75
web/api/update.php
Normal file
75
web/api/update.php
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
include_once 'model.php';
|
||||
|
||||
$INPUT = array_merge($_GET, $_POST);
|
||||
|
||||
|
||||
if (!isset($INPUT['user_id'])) die(json_encode(['success' => false, 'message' => 'Missing parameter [[user_id]]']));
|
||||
if (!isset($INPUT['user_key'])) die(json_encode(['success' => false, 'message' => 'Missing parameter [[user_key]]']));
|
||||
|
||||
$user_id = $INPUT['user_id'];
|
||||
$user_key = $INPUT['user_key'];
|
||||
$fcm_token = isset($INPUT['fcm_token']) ? $INPUT['fcm_token'] : null;
|
||||
|
||||
//----------------------
|
||||
|
||||
$pdo = getDatabase();
|
||||
|
||||
$stmt = $pdo->prepare('SELECT user_id, user_key, quota_today, quota_day, is_pro FROM users WHERE user_id = :uid LIMIT 1');
|
||||
$stmt->execute(['uid' => $user_id]);
|
||||
|
||||
$datas = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
if (count($datas)<=0) die(json_encode(['success' => false, 'message' => 'User not found']));
|
||||
$data = $datas[0];
|
||||
|
||||
if ($data === null) die(json_encode(['success' => false, 'message' => 'User not found']));
|
||||
if ($data['user_id'] !== (int)$user_id) die(json_encode(['success' => false, 'message' => 'UserID not found']));
|
||||
if ($data['user_key'] !== $user_key) die(json_encode(['success' => false, 'message' => 'Authentification failed']));
|
||||
|
||||
$quota = $data['quota_today'];
|
||||
$is_pro = $data['is_pro'];
|
||||
|
||||
$new_userkey = generateRandomAuthKey();
|
||||
|
||||
if ($fcm_token === null)
|
||||
{
|
||||
// only gen new user_secret
|
||||
|
||||
$stmt = $pdo->prepare('UPDATE users SET timestamp_accessed=NOW(), user_key=:at WHERE user_id = :uid');
|
||||
$stmt->execute(['uid' => $user_id, 'at' => $new_userkey]);
|
||||
|
||||
echo json_encode(
|
||||
[
|
||||
'success' => true,
|
||||
'user_id' => $user_id,
|
||||
'user_key' => $new_userkey,
|
||||
'quota' => $quota,
|
||||
'quota_max'=> Statics::quota_max($data['is_pro']),
|
||||
'is_pro' => $is_pro,
|
||||
'message' => 'user updated'
|
||||
]);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// update fcm and gen new user_secret
|
||||
|
||||
$stmt = $pdo->prepare('UPDATE users SET timestamp_accessed=NOW(), fcm_token=:ft, user_key=:at WHERE user_id = :uid');
|
||||
$stmt->execute(['uid' => $user_id, 'ft' => $fcm_token, 'at' => $new_userkey]);
|
||||
|
||||
$stmt = $pdo->prepare('UPDATE users SET fcm_token=NULL WHERE user_id <> :uid AND fcm_token=:ft');
|
||||
$stmt->execute(['uid' => $user_id, 'ft' => $fcm_token]);
|
||||
|
||||
echo json_encode(
|
||||
[
|
||||
'success' => true,
|
||||
'user_id' => $user_id,
|
||||
'user_key' => $new_userkey,
|
||||
'quota' => $quota,
|
||||
'quota_max'=> Statics::quota_max($data['is_pro']),
|
||||
'is_pro' => $is_pro,
|
||||
'message' => 'user updated'
|
||||
]);
|
||||
return 0;
|
||||
}
|
76
web/api/upgrade.php
Normal file
76
web/api/upgrade.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
include_once 'model.php';
|
||||
|
||||
$INPUT = array_merge($_GET, $_POST);
|
||||
|
||||
|
||||
if (!isset($INPUT['user_id'])) die(json_encode(['success' => false, 'message' => 'Missing parameter [[user_id]]']));
|
||||
if (!isset($INPUT['user_key'])) die(json_encode(['success' => false, 'message' => 'Missing parameter [[user_key]]']));
|
||||
if (!isset($INPUT['pro'])) die(json_encode(['success' => false, 'message' => 'Missing parameter [[pro]]']));
|
||||
if (!isset($INPUT['pro_token'])) die(json_encode(['success' => false, 'message' => 'Missing parameter [[pro_token]]']));
|
||||
|
||||
$user_id = $INPUT['user_id'];
|
||||
$user_key = $INPUT['user_key'];
|
||||
$ispro = $INPUT['pro'] == 'true';
|
||||
$pro_token = $INPUT['pro_token'];
|
||||
|
||||
//----------------------
|
||||
|
||||
$pdo = getDatabase();
|
||||
|
||||
$stmt = $pdo->prepare('SELECT user_id, user_key, quota_today, quota_day, is_pro, pro_token FROM users WHERE user_id = :uid LIMIT 1');
|
||||
$stmt->execute(['uid' => $user_id]);
|
||||
|
||||
$datas = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
if (count($datas)<=0) die(json_encode(['success' => false, 'message' => 'User not found']));
|
||||
$data = $datas[0];
|
||||
|
||||
if ($data === null) die(json_encode(['success' => false, 'message' => 'User not found']));
|
||||
if ($data['user_id'] !== (int)$user_id) die(json_encode(['success' => false, 'message' => 'UserID not found']));
|
||||
if ($data['user_key'] !== $user_key) die(json_encode(['success' => false, 'message' => 'Authentification failed']));
|
||||
|
||||
if ($ispro)
|
||||
{
|
||||
// set pro=true
|
||||
|
||||
if ($data['pro_token'] != $pro_token)
|
||||
{
|
||||
if (!verifyOrderToken($pro_token)) die(json_encode(['success' => false, 'message' => 'Purchase token could not be verified']));
|
||||
}
|
||||
|
||||
$stmt = $pdo->prepare('UPDATE users SET timestamp_accessed=NOW(), is_pro=1, pro_token=:ptk WHERE user_id = :uid');
|
||||
$stmt->execute(['uid' => $user_id, 'ptk' => $pro_token]);
|
||||
|
||||
$stmt = $pdo->prepare('UPDATE users SET is_pro=0, pro_token=NULL WHERE user_id <> :uid AND pro_token = :ptk');
|
||||
$stmt->execute(['uid' => $user_id, 'ptk' => $pro_token]);
|
||||
|
||||
echo json_encode(
|
||||
[
|
||||
'success' => true,
|
||||
'user_id' => $user_id,
|
||||
'quota' => $data['quota_today'],
|
||||
'quota_max'=> Statics::quota_max(true),
|
||||
'is_pro' => true,
|
||||
'message' => 'user updated'
|
||||
]);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// set pro=false
|
||||
|
||||
$stmt = $pdo->prepare('UPDATE users SET timestamp_accessed=NOW(), is_pro=0, pro_token=NULL WHERE user_id = :uid');
|
||||
$stmt->execute(['uid' => $user_id]);
|
||||
|
||||
echo json_encode(
|
||||
[
|
||||
'success' => true,
|
||||
'user_id' => $user_id,
|
||||
'quota' => $data['quota_today'],
|
||||
'quota_max'=> Statics::quota_max(false),
|
||||
'is_pro' => false,
|
||||
'message' => 'user updated'
|
||||
]);
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user