| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348 |
- <?php
- namespace Models {
- require_once 'Models/User.class.php';
-
- require_once 'Tools/Crypto.class.php';
- class AccountInterface {
- //
- protected $DataInterface;
- /**
- *
- */
- public function __construct($DataInterface) {
- $this->DataInterface = $DataInterface;
- }
- /**
- * Get data required for signing up new account.
- */
- public function accountSignupGet($lang) {
- $statement = $this->DataInterface->DatabaseConnection->prepare(
- "SELECT *, name_$lang AS name FROM country ORDER BY name_$lang"
- );
- if(!$statement->execute()) {
- return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
- }
- $countries = $statement->fetchAll(\PDO::FETCH_ASSOC);
-
- return [
- 'result' => 'OK',
- 'countries' => $countries
- ];
- }
- /**
- *
- */
- public function accountResetPost($data) {
- $statement = $this->DataInterface->DatabaseConnection->prepare(
- "SELECT address FROM email WHERE type = 'postmaster'"
- );
- if(!$statement->execute()) {
- return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
- }
- $postmaster = $statement->fetchAll(\PDO::FETCH_ASSOC)[0]['address'];
- // user
- if (!filter_var($data['to'], FILTER_VALIDATE_EMAIL)) {
- return ['result' => 'ERROR', 'reason' => 'invalid_email'];
- }
- // Check email exists
- $statement = $this->DataInterface->DatabaseConnection->prepare(
- 'SELECT ID FROM user WHERE email = \''.$data['to'].'\''
- );
- $statement->execute();
- if(count($statement->fetchAll(\PDO::FETCH_ASSOC))==0) {
- return ['result' => 'ERROR', 'reason' => 'invalid_email'];
- }
- //
- $reset_token = \Tools\UUID::v4();
- $statement = $this->DataInterface->DatabaseConnection->prepare(
- 'UPDATE user SET password = \''.$reset_token.'\' WHERE email = \''.$data['to'].'\''
- );
- if(!$statement->execute()) {
- return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
- }
- //
- return [
- 'result' => 'OK',
- 'email' => $data['to'],
- 'sender' => $postmaster,
- 'reset_token' => $reset_token
- ];
- }
- /**
- *
- */
- public function accountReset2Post($data) {
- if (strlen($data['newPassword']) < 8 ||
- !preg_match("#[0-9]+#", $data['newPassword']) ||
- !preg_match("#[a-z]+#", $data['newPassword']) ||
- !preg_match("#[A-Z]+#", $data['newPassword'])) {
- return ['result' => 'ERROR', 'reason' => 'password_strength'];
- }
-
- $password = \Tools\Crypto::getHashPassword($data['newPassword']);
- $statement = $this->DataInterface->DatabaseConnection->prepare(
- "UPDATE user SET password = :newPassword WHERE password = :token"
- );
- $statement->bindParam(':newPassword', $password);
- $statement->bindParam(':token', $data['token']);
- if(!$statement->execute()) {
- return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
- }
- //
- return [
- 'result' => 'OK'
- ];
- }
- /**
- * Check data and create new account.
- */
- public function accountSignupPost($data) {
- $statement = $this->DataInterface->DatabaseConnection->prepare(
- "SELECT address FROM email WHERE type = 'postmaster'"
- );
- if(!$statement->execute()) {
- return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
- }
- $email = $statement->fetchAll(\PDO::FETCH_ASSOC)[0]['address'];
- // user
- if (!filter_var($data['user']['email'], FILTER_VALIDATE_EMAIL)) {
- return ['result' => 'ERROR', 'group' => 'user', 'reason' => 'email'];
- }
- // Check email exists
- $statement = $this->DataInterface->DatabaseConnection->prepare(
- 'SELECT ID FROM user WHERE email = \''.$data['user']['email'].'\' AND type = \'physician\''
- );
- $statement->execute();
- if(count($statement->fetchAll(\PDO::FETCH_ASSOC))!=0) {
- return ['result' => 'ERROR', 'reason' => 'duplicate_user'];
- }
- if (strlen($data['user']['password']) < 8 ||
- !preg_match("#[0-9]+#", $data['user']['password']) ||
- !preg_match("#[a-z]+#", $data['user']['password']) ||
- !preg_match("#[A-Z]+#", $data['user']['password'])) {
- return ['result' => 'ERROR', 'reason' => 'password_strength'];
- }
- if($data['user']['password'] != $data['user']['password2']) {
- return ['result' => 'ERROR', 'reason' => 'password_mismatch'];
- }
- if(empty($data['user']['firstname'])) {
- return ['result' => 'ERROR', 'group' => 'user', 'reason' => 'firstname'];
- }
- if(empty($data['user']['lastname'])) {
- return ['result' => 'ERROR', 'group' => 'user', 'reason' => 'lastname'];
- }
- if(empty($data['user']['phone'])) {
- return ['result' => 'ERROR', 'group' => 'user', 'reason' => 'phone'];
- }
- // organization
- if(empty($data['organization']['name'])) {
- return ['result' => 'ERROR', 'group' => 'organization', 'reason' => 'name'];
- }
- if(empty($data['organization']['country'])) {
- return ['result' => 'ERROR', 'group' => 'organization', 'reason' => 'country'];
- }
- if(empty($data['organization']['zip'])) {
- return ['result' => 'ERROR', 'group' => 'organization', 'reason' => 'zip'];
- }
- if(empty($data['organization']['city'])) {
- return ['result' => 'ERROR', 'group' => 'organization', 'reason' => 'city'];
- }
- if(empty($data['organization']['address'])) {
- return ['result' => 'ERROR', 'group' => 'organization', 'reason' => 'address'];
- }
- if(empty($data['organization']['phone'])) {
- return ['result' => 'ERROR', 'group' => 'organization', 'reason' => 'phone'];
- }
- // probe
- if(empty($data['probe']['brand'])) {
- return ['result' => 'ERROR', 'group' => 'probe', 'reason' => 'brand'];
- }
- if(empty($data['probe']['year'])) {
- $data['probe']['year'] = null;
- }
- if(empty($data['probe']['frequency'])) {
- return ['result' => 'ERROR', 'group' => 'probe', 'reason' => 'frequency'];
- }
- // validation
- if($data['validation']['terms'] != 'true') {
- return ['result' => 'ERROR', 'reason' => 'validation_terms'];
- }
- /*if($data['validation']['database'] != 'true') {
- return ['result' => 'ERROR', 'reason' => 'validation_database'];
- }*/
- // Begin transaction
- $this->DataInterface->DatabaseConnection->beginTransaction();
- // Insert user
- $statement = $this->DataInterface->DatabaseConnection->prepare(
- "INSERT INTO user(activation_token, activation_expire, password, firstname, lastname, email, phone, type) VALUES(:activation_token, :activation_expire, :password, :firstname, :lastname, :email, :phone, 'physician')"
- );
- $activation_token = \Tools\UUID::v4();
- $activation_expire = date('Y-m-d H:i:s', strtotime(date('Y-m-d H:i:s'). ' + 1 days'));
- $statement->bindParam(':activation_token', $activation_token);
- $statement->bindParam(':activation_expire', $activation_expire);
- $password = \Tools\Crypto::getHashPassword($data['user']['password']);
- $statement->bindParam(':password', $password);
- $statement->bindParam(':firstname', $data['user']['firstname']);
- $statement->bindParam(':lastname', $data['user']['lastname']);
- $statement->bindParam(':email', $data['user']['email']);
- $statement->bindParam(':phone', $data['user']['phone']);
- // Error check
- if(!$statement->execute()) {
- $this->DataInterface->DatabaseConnection->rollback();
- return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
- }
- $fk_user = $this->DataInterface->DatabaseConnection->lastInsertId();
- // Insert organization
- $statement = $this->DataInterface->DatabaseConnection->prepare(
- "INSERT INTO organization(fk_user, name, fk_country, zip, city, address, phone) VALUES(:fk_user, :name, :fk_country, :zip, :city, :address, :phone)"
- );
- $statement->bindParam(':fk_user', $fk_user);
- $statement->bindParam(':name', $data['organization']['name']);
- $statement->bindParam(':fk_country', $data['organization']['country']);
- $statement->bindParam(':zip', $data['organization']['zip']);
- $statement->bindParam(':city', $data['organization']['city']);
- $statement->bindParam(':address', $data['organization']['address']);
- $statement->bindParam(':phone', $data['organization']['phone']);
- // Error check
- if(!$statement->execute()) {
- $this->DataInterface->DatabaseConnection->rollback();
- return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
- }
- // Insert probe
- $statement = $this->DataInterface->DatabaseConnection->prepare(
- "INSERT INTO probe(fk_user, name, brand, type, year, frequency) VALUES(:fk_user, :name, :brand, :type, :year, :frequency)"
- );
- $statement->bindParam(':fk_user', $fk_user);
- $statement->bindParam(':name', $data['probe']['name']);
- $statement->bindParam(':brand', $data['probe']['brand']);
- $statement->bindParam(':type', $data['probe']['type']);
- $statement->bindParam(':year', $data['probe']['year']);
- $statement->bindParam(':frequency', $data['probe']['frequency']);
- // Error check
- if(!$statement->execute()) {
- $this->DataInterface->DatabaseConnection->rollback();
- return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
- }
- // Commit
- $this->DataInterface->DatabaseConnection->commit();
- return [
- 'result' => 'OK',
- 'data' => $data,
- 'activation_token' => $activation_token,
- 'email' => $data['user']['email'],
- 'sender' => $email
- ];
- }
- /**
- * Activate an account.
- */
- public function accountActivateGet($activation_token) {
- $statement = $this->DataInterface->DatabaseConnection->prepare(
- "SELECT ID FROM user WHERE activation_token = :activation_token"
- );
- $statement->bindParam(':activation_token', $activation_token);
- if(!$statement->execute()) {
- return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
- }
- if(count($statement->fetchAll(\PDO::FETCH_ASSOC))==0) {
- return ['result' => 'ERROR', 'reason' => 'invalid_token'];
- }
- // update account
- $statement = $this->DataInterface->DatabaseConnection->prepare(
- "UPDATE user SET activation = NOW() WHERE activation_token = :activation_token"
- );
- $statement->bindParam(':activation_token', $activation_token);
- if(!$statement->execute()) {
- return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
- }
- $statement->bindParam(':activation_token', $activation_token);
- return ['result' => 'OK'];
- }
- /**
- * Check login/password and create JWT token.
- */
- public function accountSigninPost(&$User, $data) {
- if($data['type']=='physician') {
- $typeSql = "AND type = 'physician'";
- }
- else { // 'ct'
- $typeSql = "AND (type = 'reader' OR type = 'investigator')";
- }
- $statement = $this->DataInterface->DatabaseConnection->prepare(
- "SELECT * FROM user WHERE activation IS NOT NULL AND active = 1 AND email = :email $typeSql"
- );
- $statement->bindParam(':email', $data['email']);
- if(!$statement->execute()) {
- return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
- }
- $results = $statement->fetchAll(\PDO::FETCH_ASSOC);
- if(count($results)){
- if(\Tools\Crypto::verify($data['password'], $results[0]['password'])) {
- // Generate JWT token
- $issuer_claim = \Config\Settings::getTokenIssuer();
- $audience_claim = \Config\Settings::getTokenAudience();
- $issuedat_claim = time(); // issued at
- $notbefore_claim = $issuedat_claim + \Config\Settings::getTokenNotBefore();
- $expire_claim = $issuedat_claim + \Config\Settings::getTokenExpiration();
- $token = array(
- "iss" => $issuer_claim,
- "aud" => $audience_claim,
- "iat" => $issuedat_claim,
- "nbf" => $notbefore_claim,
- "exp" => $expire_claim,
- "data" => array(
- "ID" => $results[0]['ID'],
- "firstname" => $results[0]['firstname'],
- "lastname" => $results[0]['lastname'],
- "email" => $results[0]['email'],
- "type" => $results[0]['type']
- )
- );
- $jwt = \Firebase\JWT\JWT::encode($token, \Config\Settings::getTokenPrivateKey());
- // OK
- return [
- "result" => "OK",
- "token" => $jwt,
- "expireAt" => $expire_claim,
- "username" => $data['email'],
- "store" => $data['store'],
- "type" => $results[0]['type']
- ];
- }
- return ['result' => 'ERROR', 'reason' => 'bad_password', 'message' => 'Invalid password'];
- }
- return ['result' => 'ERROR', 'reason' => 'unknown', 'message' => 'No such user'];
- }
- /**
- * Logout.
- */
- public function accountLogoutGet(&$User) {
- $User->logout();
- return ['result' => 'OK'];
- }
- }
- }
|