HEX
Server: nginx
System: Linux pool195-106-36.bur.atomicsites.net 6.12.57+deb12-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.12.57-1~bpo12+1 (2025-11-17) x86_64
User: (0)
PHP: 8.3.32
Disabled: pcntl_fork
Upload Files
File: /wordpress/plugins/wp-cloud-client/1.1.0/src/Access/LoginTokenManager.php
<?php

declare(strict_types=1);

namespace VPlugins\WPCloudClient\Access;

class LoginTokenManager {

	private const TRANSIENT_PREFIX = 'wpcc_login_token_';
	private const DEFAULT_TTL      = 300; // 5 minutes

	/**
	 * Generate a single-use login token for a user.
	 *
	 * @param int $userId The user ID to generate a token for.
	 * @param int $ttl    Time-to-live in seconds for the token.
	 * @return array{token: string, expires_at: int}
	 */
	public function create( int $userId, int $ttl = self::DEFAULT_TTL ): array {
		$token     = bin2hex( random_bytes( 32 ) );
		$expiresAt = time() + $ttl;

		set_transient(
			self::TRANSIENT_PREFIX . $token,
			[
				'user_id'    => $userId,
				'expires_at' => $expiresAt,
			],
			$ttl
		);

		return [
			'token'      => $token,
			'expires_at' => $expiresAt,
		];
	}

	/**
	 * Validate and consume a login token. Returns user ID or null.
	 *
	 * @param string $token The login token to consume.
	 * @return ?int The user ID, or null if the token is invalid.
	 */
	public function consume( string $token ): ?int {
		$key  = self::TRANSIENT_PREFIX . $token;
		$data = get_transient( $key );

		if ( ! is_array( $data ) || empty( $data['user_id'] ) ) {
			return null;
		}

		// Single-use: delete immediately
		delete_transient( $key );

		// Check expiry (transient TTL handles this too, but double-check)
		if ( isset( $data['expires_at'] ) && time() > $data['expires_at'] ) {
			return null;
		}

		return (int) $data['user_id'];
	}
}