* @link https://TheTempusProject.com * @license https://opensource.org/licenses/MIT [MIT LICENSE] */ namespace TheTempusProject\Models; use TheTempusProject\Bedrock\Functions\Check; use TheTempusProject\Canary\Bin\Canary as Debug; use TheTempusProject\Classes\DatabaseModel; use TheTempusProject\Bedrock\Classes\Config; use TheTempusProject\TheTempusProject as App; class Token extends DatabaseModel { public $tableName = 'tokens'; public $modelVersion = '1.0'; public $configName = 'api'; public $databaseMatrix = [ [ 'name', 'varchar', '128' ], [ 'token_type', 'varchar', '8' ], [ 'notes', 'text', '' ], [ 'token', 'varchar', '64' ], [ 'secret', 'varchar', '256' ], [ 'createdAt', 'int', '10' ], [ 'createdBy', 'int', '10' ], [ 'expiresAt', 'int', '10' ], ]; public $searchFields = [ 'name', 'token', ]; public $permissionMatrix = [ 'addAppToken' => [ 'pretty' => 'Add Application Tokens', 'default' => false, ], 'addAppToken' => [ 'pretty' => 'Add Personal Tokens', 'default' => false, ], ]; public $configMatrix = [ 'apiAccessApp' => [ 'type' => 'radio', 'pretty' => 'Enable Api Access for Personal Tokens.', 'default' => true, ], 'apiAccessPersonal' => [ 'type' => 'radio', 'pretty' => 'Enable Api Access for Personal Tokens.', 'default' => true, ], 'AppAccessTokenExpiration' => [ 'type' => 'text', 'pretty' => 'How long before app tokens expire (in seconds)', 'default' => 2592000, ], 'UserAccessTokenExpiration' => [ 'type' => 'text', 'pretty' => 'How long before user tokens expire (in seconds)', 'default' => 604800, ], ]; public function create( $name, $note, $token_type = 'app' ) { if ( 'app' == $token_type ) { $expiration = Config::getValue( 'api/AppAccessTokenExpiration' ); if ( empty( $expiration ) ) { $expiration = $this->configMatrix['AppAccessTokenExpiration']['default']; } } else { $expiration = Config::getValue( 'api/UserAccessTokenExpiration' ); if ( empty( $expiration ) ) { $expiration = $this->configMatrix['UserAccessTokenExpiration']['default']; } } $expireTime = time() + $expiration; $fields = [ 'name' => $name, 'notes' => $note, 'token_type' => $token_type, 'createdBy' => App::$activeUser->ID, 'createdAt' => time(), 'expiresAt' => $expireTime, 'token' => generateToken(), 'secret' => generateRandomString(256), ]; if ( self::$db->insert( $this->tableName, $fields ) ) { return true; } return false; } public function findOrCreateUserToken( $user_id, $refresh = false ) { $test = $this->findUserToken( $user_id ); if ( ! empty( $test ) ) { if ( ! empty( $refresh ) ) { $token = $this->refresh( $test->ID, 'user' ); } else { $token = $test->token; } return $token; } $expiration = Config::getValue( 'api/UserAccessTokenExpiration' ); if ( empty( $expiration ) ) { $expiration = $this->configMatrix['UserAccessTokenExpiration']['default']; } $expireTime = time() + $expiration; $token = generateToken(); $fields = [ 'name' => 'Browser Token', 'notes' => 'findOrCreateUserToken', 'token_type' => 'user', 'createdBy' => $user_id, 'createdAt' => time(), 'expiresAt' => $expireTime, 'token' => $token, 'secret' => generateRandomString(256), ]; if ( self::$db->insert( $this->tableName, $fields ) ) { return $token; } return false; } public function update( $id, $name, $note, $token_type = 'app' ) { $fields = [ 'name' => $name, 'notes' => $note, 'token_type' => $token_type, ]; if ( self::$db->update( $this->tableName, $id, $fields ) ) { return true; } return false; } public function refresh( $id, $token_type = 'app' ) { if ( 'app' == $token_type ) { $expiration = Config::getValue( 'api/AppAccessTokenExpiration' ); if ( empty( $expiration ) ) { $expiration = $this->configMatrix['AppAccessTokenExpiration']['default']; } } else { $expiration = Config::getValue( 'api/UserAccessTokenExpiration' ); if ( empty( $expiration ) ) { $expiration = $this->configMatrix['UserAccessTokenExpiration']['default']; } } $expireTime = time() + $expiration; $token = generateToken(); $fields = [ 'expiresAt' => $expireTime, 'token' => $token, ]; if ( self::$db->update( $this->tableName, $id, $fields ) ) { return $token; } return false; } public function findByforwardedUrl( $url ) { if ( !Check::url( $url ) ) { Debug::warn( "Invalid forwarded_url: $url" ); return false; } $routeData = self::$db->get( $this->tableName, [ 'forwarded_url', '=', $url ] ); if ( !$routeData->count() ) { Debug::warn( "Could not find route by forwarded url: $url" ); return false; } return $this->filter( $routeData->first() ); } public function findByToken( $token ) { $data = self::$db->get( $this->tableName, [ 'token', '=', $token ] ); if ( ! $data->count() ) { return false; } return $data->first(); } public function findBySecret( $secret ) { $data = self::$db->get( $this->tableName, [ 'secret', '=', $secret ] ); if ( ! $data->count() ) { return false; } return $data->first(); } public function findUserToken( $user_id ) { $data = self::$db->get( $this->tableName, [ 'createdBy', '=', $user_id, 'AND', 'token_type', '=', 'user' ] ); if ( ! $data->count() ) { return false; } return $data->first(); } }