YahnisElsts / plugin-update-checker

A custom update checker for WordPress plugins. Useful if you don't want to host your project in the official WP repository, but would still like it to support automatic updates. Despite the name, it also works with themes.
MIT License
2.22k stars 403 forks source link

Personal Access Tokens are removed, any way to fix this? #479

Open websitecareio opened 2 years ago

websitecareio commented 2 years ago

Github have relased a new security update, causing any access token that is in a repository to be removed from the accounts (to avoid people from sharing the tokens).

But with plugin update checker, a token is required to update private repositories. and therefore the token must be in the files, causing the token to be deleted when placing the files in the repository.

My current solution is the following: A separate account is invited to my private plugins, and have its own generated token. The token is then MD5 hashed and decoded like this:

$myUpdateChecker->setAuthentication(my_decode($token)); // decode that fetches the correct value.

But is there any better way to do this?

cocodedesigns commented 2 years ago

The way I've done it is not to save a token in the script at all. Instead, I have a field on an options page where you can save the token instead, and then call it into the function when you need it. I use CMB2 (means I can throw together options pages in minutes), so my function goes:

function git_token(){

    // Call the option key from the database
    $option = get_option('apikeys');

    // If the key is saved, use it as the value for $token.  If it is not, use an empty string as the value instead
    $token = ( isset( $option['_git_token'] ) ? $option['_git_token'] : '' );

    // Return $token
    return $token;

}

And the authentication key is called with $checkTheme->setAuthentication( git_token() );

An advantage of this solution is that if you have a client on, say, an annual contract, and you are developing your own themes or plugins for them, you give them a unique token from GitHub and set it to expire after a year. If they renew, they continue to get updates to the theme/plugin with a new token. If they don't, the token won't work. Yes, that means you have to create more tokens (I'm open to ways of making this less complicated but allows me the same level of control), and it's not the most elegant way of doing it, but it also means you're able to add and change the token without changing the code so you can just leave it as it is.

Be interesting to see what other methods there are.

websitecareio commented 2 years ago

The way I've done it is not to save a token in the script at all. Instead, I have a field on an options page where you can save the token instead, and then call it into the function when you need it. I use CMB2 (means I can throw together options pages in minutes), so my function goes:

function git_token(){

    // Call the option key from the database
    $option = get_option('apikeys');

    // If the key is saved, use it as the value for $token.  If it is not, use an empty string as the value instead
    $token = ( isset( $option['_git_token'] ) ? $option['_git_token'] : '' );

    // Return $token
    return $token;

}

And the authentication key is called with $checkTheme->setAuthentication( git_token() );

An advantage of this solution is that if you have a client on, say, an annual contract, and you are developing your own themes or plugins for them, you give them a unique token from GitHub and set it to expire after a year. If they renew, they continue to get updates to the theme/plugin with a new token. If they don't, the token won't work. Yes, that means you have to create more tokens (I'm open to ways of making this less complicated but allows me the same level of control), and it's not the most elegant way of doing it, but it also means you're able to add and change the token without changing the code so you can just leave it as it is.

Be interesting to see what other methods there are.

Not a bad solution you got there, might be the way I want to do it too. Because i do have some plugins where multiple clients are using them.

YahnisElsts commented 2 years ago

Whether you use a personal access token or something else, putting that information in the plugin files would still lead to the same security concerns. However, if you want to use a private repository, and you also want to let users get updates directly from that repository, you will have to provide the authentication data to the user somehow.

I think the approach suggested by @cocodedesigns is a good option if you don't want to get into more complex solutions like generating custom license keys for clients and routing update requests through your own server.

swinggraphics commented 1 year ago

And the authentication key is called with $checkTheme->setAuthentication( git_token() );

Does this mean editing Plugin Update Checker? Or is there a way to extend its functionality without modifying it?

NM. I read the readme more carefully and understand now that $checkTheme is just cocodedesigns's version of $myUpdateChecker, which goes in my plugin file, so no edits needed to Plugin Update Checker itself. 👍