HEX
Server: Apache
System: Linux www3.pit.tblive.com 5.14.0-687.38.1.el9_8.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Aug 12 17:19:12 EDT 2026 x86_64
User: awaldron (1020)
PHP: 8.1.34
Disabled: exec,passthru,shell_exec,system
Upload Files
File: /home/awaldron/_phpassport/api.pennhillspassport.com/v1/auth.php
<?php

//**********************************************************************************************************//
// Method: POST
// Endpoint: user
// Params: email, password
function post_v1_auth_user( $args, $body, $uid, $is_admin, $db ) {
    $rules = [
        'lname' => 'req',
        'fname' => 'req',
        'email' => 'req,email',
        'password' => 'req',
        'admin' => 'req',
    ];
    validate_body( $body, $rules );

    $ins = "INSERT INTO users (lname, fname, email, password_hash, orig_pw, active, created_at, updated_at) VALUES 
            ( '".$body['lname']."', '".$body['fname']."', '".$body['email']."', '".password_hash($body['password'], PASSWORD_BCRYPT)."', '".$body['password']."', 1, ".time().", ".time()." )";
    
    $user_id = -1;
    if ($result = $db->query($ins)) {
        $user_id = qVal($db, "SELECT MAX(user_id) FROM users");
        
        foreach ($body['channels'] as $c) {
	        $db->query("INSERT INTO channel_admins (channel_id, user_id) VALUES (".$c.", ".$user_id.")");
		}
    }
    
    if ($user_id !== -1) {    
        response(200, ['success'=>true,'user_id'=>$user_id]);
    } else {
        response(400, ['success'=>false,'errors'=>[$db->error]]);
    }
}


 //**********************************************************************************************************//
// Method: POST
// Endpoint: user
// Params: email, password
function put_v1_auth_user( $args, $body, $uid, $is_admin, $db ) {
    $rules = [
        'user_id' => 'req',
        'lname' => 'req',
        'fname' => 'req',
        'email' => 'req,email',
        'admin' => 'req',
    ];
    validate_body( $body, $rules );
    
    $upd = "UPDATE users SET ";
    $upd .= "lname = '".$body['lname']."', ";
    $upd .= "fname = '".$body['fname']."', ";
    $upd .= "email = '".$body['email']."', ";
    $upd .= "active = ".$body['active'].", ";
    $upd .= "updated_at = ".time()." ";
    $upd .= "WHERE user_id=".$body['user_id'];

	$db->query( $upd );
	
	$db->query("DELETE FROM channel_admins WHERE user_id=".$body['user_id']);

    foreach ($body['channels'] as $c) {
        if (!empty($c)) $db->query("INSERT INTO channel_admins (channel_id, user_id) VALUES (".$c.", ".$body['user_id'].")");
	}
    
	response(200, ['success'=>true,'user_id'=>$body['user_id']]);

}


 //**********************************************************************************************************//
// Method: DELETE
// Endpoint: user
// Params: userId

function delete_v1_auth_user( $args, $body, $uid, $is_admin, $db ) {
    
    if (!isset($args[0])) {
	    response(200, ['success'=>false,'errors'=>['No user id.']]);

    }
   	else if ($is_admin) {
	   	$db->query("UPDATE users SET active=0 WHERE user_id=".$args[0]);
	   	response(200, ['success'=>true,'message'=>'User deleted successfully.']);
	}
	else {
		response(200, ['success'=>false,'errors'=>['Only sysadmins can delete users.']]);
	}
}


//**********************************************************************************************************//
// Method: GET
// Endpoint: pwhash
// Params: pw
function get_v1_auth_pwhash( $args, $body, $uid, $is_admin, $db ) {
    echo password_hash($args[0], PASSWORD_BCRYPT);
}


//**********************************************************************************************************//
// Method: PUT
// Endpoint: user
// Params: oldpw, pw1, pw2
function put_v1_auth_setpw( $args, $body, $uid, $is_admin, $db ) {
    $rules = [
        'user_id' => 'req',
        'oldpw' => 'req',
        'pw1' => 'req',
        'pw2' => 'req',
    ];
    validate_body( $body, $rules );

    if ($body['pw1'] !== $body['pw2']) {
        response(200, ['success'=>false,'errors'=>['Passwords do not match.']]);
    }
    else {
        // check old password
        $user = qRow( $db, "SELECT * FROM users WHERE user_id='".$body['user_id']."'" );
        $valid_login = password_verify($body['oldpw'], $user['password_hash']);

        if ($valid_login) {
            // update password
            $db->query("UPDATE users SET password_hash='".password_hash($body['pw1'], PASSWORD_BCRYPT)."' WHERE user_id=".$body['user_id']);
            response(200, ['success'=>true]);
        } else {
            response(200, ['success'=>false,'errors'=>['Current password is incorrect.']]);
        }
    }
}


//**********************************************************************************************************//
// Method: POST
// Endpoint: token
// Params: email, password
function post_v1_auth_token( $args, $body, $uid, $is_admin, $db ) {
    $rules = [
        'email' => 'req,email',
        'password' => 'req',
    ];
    validate_body( $body, $rules );

    $sql = "SELECT user_id, email, admin, password_hash, lname, fname, active, created_at, updated_at FROM users WHERE email='".$body['email']."'";
    $user = qRow( $db, $sql );

    $valid_login = !empty($user['user_id']);
    if ($valid_login) {
        $valid_login = password_verify($body['password'], $user['password_hash']);
    }

    if ($valid_login && $user['active']) {
        $token = new_token( $db, $user['user_id'] );
        $user['token'] = $token['token'];
        $user['token_expires'] = $token['expires'];
        $user['token_created'] = $token['created'];
        unset($user['password_hash']);
        response(200, ['success' => true, 'user' => $user]);

    } else if ($valid_login && !$user['active']) {
        response(401, ['success'=>false,'errors'=>['Account is deactivated.']]);

    } else {
        response(401, ['success'=>false,'errors'=>['Email / password combo is invalid.']]);
    }
}


//**********************************************************************************************************//
// Method: GET
// Endpoint: user
// Params: none
// Description: Returns user associated with an active token
function get_v1_auth_user( $args, $body, $uid, $is_admin, $db ) {
    validate_token( $uid );

    $sql = "SELECT * FROM users as u,
                          tokens as t 
            WHERE t.token='".$_SERVER['HTTP_AUTHORIZATION']."' AND t.user_id=u.user_id";
    $user = qRow( $db, $sql );

    $user['token_expires'] = $user['expires'];
    $user['token_created'] = $user['created'];
    unset($user['password_hash']);
    unset($user['token_id']);
    unset($user['expires']);
    unset($user['created']);

    response(200, ['success' => true, 'user' => $user]);
}


//**********************************************************************************************************//
// Method: GET
// Endpoint: users
// Params: none
// Description: Returns user associated with an active token
function get_v1_auth_users( $args, $body, $uid, $is_admin, $db ) {
    validate_token( $uid );

    $sql = "
        SELECT
            u.user_id AS user_id,
            u.lname,
            u.fname,
            u.email,
            u.admin,
            u.active,
            u.created_at,
            u.updated_at,
            c.id AS channel_id,
            c.name AS channel_name,
            c.short_name,
            c.slug,
            c.avatar,
            c.color_light,
            c.color_dark
        FROM users AS u
        LEFT JOIN channel_admins AS ca
            ON u.user_id = ca.user_id
        LEFT JOIN channels AS c
            ON c.id = ca.channel_id
        WHERE u.active = 1
        ORDER BY u.lname ASC, u.fname ASC
    ";
    $users = qSet( $db, $sql );
    
    $u = [];
    $ctr = -1;
    $curr_user = 0;
    
    foreach ($users as $user) {
	    if ($curr_user !== $user['user_id']) {
		    $ctr++;
		    $u[$ctr] = [
			    'user_id' => $user['user_id'],
			    'lname' => $user['lname'],
			    'fname' => $user['fname'],
			    'email' => $user['email'],
			    'admin' => $user['admin'],
			    'active' => $user['active'],
			    'created_at' => $user['created_at'],
			    'updated_at' => $user['updated_at'],
			    'channels' => []			    
		    ];
		    $curr_user = $user['user_id'];
	    }
	    $u[$ctr]['channels'][] = [
		    'id' => $user['channel_id'],
		    'name' => $user['channel_name'],
		    'short_name' => $user['short_name'],
		    'slug' => $user['slug'],
		    'avatar' => $user['avatar'],
		    'color_light' => $user['color_light'],
		    'color_dark' => $user['color_dark'],
	    ];
    }


    response(200, ['success' => true, 'users' => $u]);
}


//**********************************************************************************************************//
// Method: GET
// Endpoint: channels
// Params: none
// Description: Returns all channels in system
function get_v1_auth_channels( $args, $body, $uid, $is_admin, $db ) {
    //validate_token( $uid );

    $sql = "SELECT * FROM channels ORDER BY name ASC";
    $channels = qSet( $db, $sql );

    response(200, ['success' => true, 'channels' => $channels]);
}


//**********************************************************************************************************//
// Method: GET
// Endpoint: userchannels
// Params: none
// Description: Returns all channels in system
function get_v1_auth_userchannels( $args, $body, $uid, $is_admin, $db ) {
    validate_token( $uid );

    $sql = "SELECT * FROM channel_admins as uc, channels as c WHERE uc.user_id=".$uid." AND uc.channel_id=c.id ORDER BY name ASC";
    $channels = qSet( $db, $sql );

    response(200, ['success' => true, 'data' => $channels]);
}


//**********************************************************************************************************//
// Method: GET
// Endpoint: locations
// Params: none
// Description: Returns all membership plans in system
function get_v1_auth_locations( $args, $body, $uid, $is_admin, $db ) {
    validate_token( $uid );

    $sql = "SELECT * FROM locations ORDER BY name ASC";
    $plans = qSet( $db, $sql );

    response(200, ['success' => true, 'locations' => $plans]);
}



//**********************************************************************************************************//
// Method: POST
// Endpoint: pwreset
// Params: none
// Description: Send an email with the password reset link
function post_v1_auth_pwreset( $args, $body, $uid, $is_admin, $db ){
    $rules = [
        'email' => 'req,email',
    ];
    validate_body( $body, $rules );

    $user = qRow( $db, "SELECT u.*, m.* FROM users as u, members as m WHERE u.email='".$body['email']."' AND u.user_id=m.user_id");
    $user['reset_hash'] = generateHash(10);

    if ($user['user_id']) {
        try {
            $upd = "UPDATE users SET reset_hash='".$user['reset_hash']."' WHERE user_id=".$user['user_id'];
            $db->query($upd);

            $body['body'] = '
                <p>Someone requested a link to reset your password at the Penn Hills Community Development Corp members portal.</p>
                <p><b>Click this link to reset your password:</b>
                <br/><a href="https://members.pennhillscdc.org/pwreset-form/'.$user['reset_hash'].'">https://members.pennhillscdc.org/pwreset-form/'.$user['reset_hash'].'</a>
                </p>
                <p>If you did not request this password reset link, you can ignore this message.</p>
                <p>If you continue to receive these emails, please contact Alan Waldron at <a href="mailto:alan.waldron@pennhillscdc.org">alan.waldron@pennhillscdc.org</a></p>
            ';
            $body['subject'] = 'Reset Your Password';

            $email = get_email_template( $body, $user, 0 );

            $mail = new PHPMailer\PHPMailer\PHPMailer(true);
            $mail->isSMTP();
            $mail->SMTPOptions = array(
                'ssl' => array(
                    'verify_peer' => false,
                    'verify_peer_name' => false,
                    'allow_self_signed' => true
                )
            );
            $mail->Host = "mail.smtp2go.com";
            $mail->Port = "2525";
            $mail->SMTPAuth = true;
            $mail->SMTPSecure = 'tls';
            $mail->Username = "pennhillscdc";
            $mail->Password = "xVnXrJGR76RMycPL";

            $mail->setFrom("noreply@pennhillscdc.org", "Penn Hills CDC");
            $mail->AddAddress($user['email'], $user['fname'].' '.$user['lname']);

            $mail->isHTML(true);
            $mail->Subject = "PHCDC: Your Password Reset Link";
            $mail->Body = $email;

            $mail->send();

        } catch (Exception $e) {
            $errors[] = $mail->ErrorInfo;
        }

    }
    response(200, ['success' => true]);
}


//**********************************************************************************************************//
// Method: POST
// Endpoint: pwresetsubmit
// Params: none
// Description: Submit a new password in the reset flow
function post_v1_auth_pwresetsubmit( $args, $body, $uid, $is_admin, $db ) {
    $rules = [
        'password' => 'req',
        'reset_hash' => 'req',
    ];
    validate_body( $body, $rules );

    try {
        $upd = "UPDATE users SET password_hash='".password_hash($body['password'], PASSWORD_BCRYPT)."', reset_hash='' WHERE reset_hash='".$body['reset_hash']."'";
        $db->query($upd);
        response(200, ['success' => true]);
    }
    catch (Exception $e) {
        response(400, ['success' => false, 'error' => $e]);
    }


}


function pp( $arr ) {
    echo '<pre>', print_r($arr), '</pre>';
}