Add single-user password utils (#9)
- Constrain images to reading viewport
This commit is contained in:
		
							parent
							
								
									0df40f3cfd
								
							
						
					
					
						commit
						9611893da3
					
				@ -28,3 +28,17 @@ function cli_title(string $title): void {
 | 
			
		||||
    printfn('  | %s | %s |', $title, $appTitle);
 | 
			
		||||
    printfn($dashes . PHP_EOL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Capitalize the first letter of the given string
 | 
			
		||||
 *
 | 
			
		||||
 * @param string $value The string to be capitalized
 | 
			
		||||
 * @return string The given string with the first letter capitalized
 | 
			
		||||
 */
 | 
			
		||||
function init_cap(string $value): string {
 | 
			
		||||
    return match (strlen($value)) {
 | 
			
		||||
        0       => "",
 | 
			
		||||
        1       => strtoupper($value),
 | 
			
		||||
        default => strtoupper(substr($value, 0, 1)) . substr($value, 1),
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -245,7 +245,7 @@ class Feed {
 | 
			
		||||
        $code   = curl_getinfo($feedReq, CURLINFO_RESPONSE_CODE);
 | 
			
		||||
        if ($error) {
 | 
			
		||||
            $result['error'] = $error;
 | 
			
		||||
        } else if ($code == 200) {
 | 
			
		||||
        } elseif ($code == 200) {
 | 
			
		||||
            $parsed = self::parseFeed($feedContent);
 | 
			
		||||
            if (array_key_exists('error', $parsed)) {
 | 
			
		||||
                $result['error'] = $parsed['error'];
 | 
			
		||||
@ -398,7 +398,7 @@ class Feed {
 | 
			
		||||
        $feedExtract = self::retrieveFeed($url);
 | 
			
		||||
        if (array_key_exists('error', $feedExtract)) return $feedExtract;
 | 
			
		||||
 | 
			
		||||
        $feed = $feedExtract['ok'];
 | 
			
		||||
        $feed  = $feedExtract['ok'];
 | 
			
		||||
        $query = $db->prepare(<<<'SQL'
 | 
			
		||||
            INSERT INTO feed (user_id, url, title, updated_on, checked_on)
 | 
			
		||||
            VALUES (:user, :url, :title, :updated, :checked)
 | 
			
		||||
 | 
			
		||||
@ -18,7 +18,7 @@ class Security {
 | 
			
		||||
    public const string SINGLE_USER_EMAIL = 'solouser@example.com';
 | 
			
		||||
 | 
			
		||||
    /** @var string The password for the single user with no password */
 | 
			
		||||
    private const string SINGLE_USER_PASSWORD = 'no-password-required';
 | 
			
		||||
    public const string SINGLE_USER_PASSWORD = 'no-password-required';
 | 
			
		||||
 | 
			
		||||
    /** @var string The password algorithm to use for our passwords */
 | 
			
		||||
    public const string PW_ALGORITHM = PASSWORD_DEFAULT;
 | 
			
		||||
@ -82,11 +82,16 @@ class Security {
 | 
			
		||||
     * @param SQLite3 $db The database connection to use to verify the user's credentials
 | 
			
		||||
     */
 | 
			
		||||
    public static function logOnUser(string $email, string $password, ?string $returnTo, SQLite3 $db): void {
 | 
			
		||||
        if ($email == self::SINGLE_USER_EMAIL) {
 | 
			
		||||
            add_error('Invalid credentials; log on unsuccessful');
 | 
			
		||||
            return;
 | 
			
		||||
        if (SECURITY_MODEL == self::SINGLE_USER_WITH_PASSWORD) {
 | 
			
		||||
            $dbEmail = self::SINGLE_USER_EMAIL;
 | 
			
		||||
        } else {
 | 
			
		||||
            if ($email == self::SINGLE_USER_EMAIL) {
 | 
			
		||||
                add_error('Invalid credentials; log on unsuccessful');
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            $dbEmail = $email;
 | 
			
		||||
        }
 | 
			
		||||
        $user = self::findUserByEmail($email, $db);
 | 
			
		||||
        $user = self::findUserByEmail($dbEmail, $db);
 | 
			
		||||
        if ($user) self::verifyPassword($user, $password, $returnTo, $db);
 | 
			
		||||
        add_error('Invalid credentials; log on unsuccessful');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -61,6 +61,13 @@ article {
 | 
			
		||||
        border-radius: .5rem;
 | 
			
		||||
        background-color: white;
 | 
			
		||||
        padding: .5rem;
 | 
			
		||||
 | 
			
		||||
        img {
 | 
			
		||||
            max-width: 100%;
 | 
			
		||||
            object-fit: contain;
 | 
			
		||||
            height: unset;
 | 
			
		||||
            width: unset;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
input[type=url],
 | 
			
		||||
 | 
			
		||||
@ -43,12 +43,10 @@ function add_info(string $message): void {
 | 
			
		||||
 * @param string $title The title of the page being displayed
 | 
			
		||||
 */
 | 
			
		||||
function page_head(string $title): void {
 | 
			
		||||
    if (str_ends_with(FRC_VERSION, '.0.0')) {
 | 
			
		||||
        $version = substr(FRC_VERSION, 0, strlen(FRC_VERSION) - 4);
 | 
			
		||||
    } elseif (str_ends_with(FRC_VERSION, '.0')) {
 | 
			
		||||
        $version = substr(FRC_VERSION, 0, strlen(FRC_VERSION) - 2);
 | 
			
		||||
    } else {
 | 
			
		||||
        $version = FRC_VERSION;
 | 
			
		||||
    $version = match (true) {
 | 
			
		||||
        str_ends_with(FRC_VERSION, '.0.0') => substr(FRC_VERSION, 0, strlen(FRC_VERSION) - 4),
 | 
			
		||||
        str_ends_with(FRC_VERSION, '.0')   => substr(FRC_VERSION, 0, strlen(FRC_VERSION) - 2),
 | 
			
		||||
        default                            => FRC_VERSION
 | 
			
		||||
    } ?>
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html lang=en>
 | 
			
		||||
 | 
			
		||||
@ -20,7 +20,7 @@ switch ($argv[1]) {
 | 
			
		||||
            printfn('Missing parameters: set-password requires e-mail and password');
 | 
			
		||||
            exit(-1);
 | 
			
		||||
        }
 | 
			
		||||
        set_password();
 | 
			
		||||
        set_password($argv[2], $argv[3]);
 | 
			
		||||
        break;
 | 
			
		||||
    case 'delete-user':
 | 
			
		||||
        if ($argc < 3) {
 | 
			
		||||
@ -29,6 +29,16 @@ switch ($argv[1]) {
 | 
			
		||||
        }
 | 
			
		||||
        delete_user($argv[2]);
 | 
			
		||||
        break;
 | 
			
		||||
    case 'set-single-password':
 | 
			
		||||
        if ($argc < 3) {
 | 
			
		||||
            printfn('Missing parameters: set-single-password requires a new password');
 | 
			
		||||
            exit(-1);
 | 
			
		||||
        }
 | 
			
		||||
        set_password(Security::SINGLE_USER_EMAIL, $argv[2]);
 | 
			
		||||
        break;
 | 
			
		||||
    case 'reset-single-password':
 | 
			
		||||
        set_password(Security::SINGLE_USER_EMAIL, Security::SINGLE_USER_PASSWORD);
 | 
			
		||||
        break;
 | 
			
		||||
    case 'migrate-single-user':
 | 
			
		||||
        if ($argc < 4) {
 | 
			
		||||
            printfn('Missing parameters: migrate-single-user requires e-mail and password');
 | 
			
		||||
@ -57,7 +67,12 @@ function display_help(): void {
 | 
			
		||||
    printfn('     Sets the password for the given user');
 | 
			
		||||
    printfn(' - delete-user [e-mail]');
 | 
			
		||||
    printfn('     Deletes a user and all their data' . PHP_EOL);
 | 
			
		||||
    printfn('To assist with migrating from single-user to multi-user mode:');
 | 
			
		||||
    printfn('To assist with changing from single-user to single-user-with-password mode:');
 | 
			
		||||
    printfn(' - set-single-password [password]');
 | 
			
		||||
    printfn('     Sets the password for the single-user mode user');
 | 
			
		||||
    printfn(' - reset-single-password');
 | 
			
		||||
    printfn('     Resets the single-user mode user\'s password to its default' . PHP_EOL);
 | 
			
		||||
    printfn('To assist with changing from single-user to multi-user mode:');
 | 
			
		||||
    printfn(' - migrate-single-user [e-mail] [password]');
 | 
			
		||||
    printfn('     Changes the e-mail address and password for the single-user mode user');
 | 
			
		||||
    printfn(' - remove-single-user');
 | 
			
		||||
@ -89,25 +104,36 @@ function add_user(): void {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get the way we will refer to the user against whom action is being taken
 | 
			
		||||
 *
 | 
			
		||||
 * @param string $email The e-mail address of the user
 | 
			
		||||
 * @return string The string to use when displaying results
 | 
			
		||||
 */
 | 
			
		||||
function display_user(string $email): string {
 | 
			
		||||
    return $email == Security::SINGLE_USER_EMAIL ? 'single-user mode user' : "user \"$email\"";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Set a user's password
 | 
			
		||||
 */
 | 
			
		||||
function set_password(): void {
 | 
			
		||||
    global $argv;
 | 
			
		||||
 | 
			
		||||
function set_password(string $email, string $password): void {
 | 
			
		||||
    $db = Data::getConnection();
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
        $displayUser = display_user($email);
 | 
			
		||||
 | 
			
		||||
        // Ensure this user exists
 | 
			
		||||
        $user = Security::findUserByEmail($argv[2], $db);
 | 
			
		||||
        $user = Security::findUserByEmail($email, $db);
 | 
			
		||||
        if (!$user) {
 | 
			
		||||
            printfn('No user exists with e-mail address "%s"', $argv[2]);
 | 
			
		||||
            printfn('No %s exists', $displayUser);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Security::updatePassword($argv[2], $argv[3], $db);
 | 
			
		||||
        Security::updatePassword($email, $password, $db);
 | 
			
		||||
 | 
			
		||||
        printfn('User "%s" password set to "%s" successfully', $argv[2], $argv[3]);
 | 
			
		||||
        $msg = $email == Security::SINGLE_USER_EMAIL && $password == Security::SINGLE_USER_PASSWORD
 | 
			
		||||
            ? 'reset' : sprintf('set to "%s"', $password);
 | 
			
		||||
        printfn('%s password %s successfully', init_cap($displayUser), $msg);
 | 
			
		||||
    } finally {
 | 
			
		||||
        $db->close();
 | 
			
		||||
    }
 | 
			
		||||
@ -123,7 +149,7 @@ function delete_user(string $email): void {
 | 
			
		||||
    $db = Data::getConnection();
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
        $displayUser = $email == Security::SINGLE_USER_EMAIL ? 'single-user mode user' : "user \"$email\"";
 | 
			
		||||
        $displayUser = display_user($email);
 | 
			
		||||
 | 
			
		||||
        // Get the ID for the provided e-mail address
 | 
			
		||||
        $user = Security::findUserByEmail($email, $db);
 | 
			
		||||
@ -159,7 +185,7 @@ function delete_user(string $email): void {
 | 
			
		||||
        $userDelete->bindValue(':user', $user['id']);
 | 
			
		||||
        $userDelete->execute();
 | 
			
		||||
 | 
			
		||||
        printfn(strtoupper(substr($displayUser, 0, 1)) . substr($displayUser, 1) . ' deleted successfully');
 | 
			
		||||
        printfn('%s deleted successfully', init_cap($displayUser));
 | 
			
		||||
    } finally {
 | 
			
		||||
        $db->close();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user