build icon indicating copy to clipboard operation
build copied to clipboard

[Plugin idea] Auth0 custom domain + callback url updater

Open DavidWells opened this issue 5 years ago β€’ 10 comments

When using auth0, you have to hardcode the URLs that your auth0 instance will use. This causes issues with auth flows not working with Netlify deploy previews.

With a build plugin, you could automatically set the deploy preview URLs as the allowed URLs in the auth0 client settings using the https://auth0.com/docs/api/management/v2 ref

https://auth0.com/docs/api/management/v2#!/Clients/patch_clients_by_id

This would allow auth flows to work even in a Netlify preview url context.

(Optionally the plugin could remove older preview URLs from the list to clean itself up.)


Context: Without this, it's not possible to fully test applications with auth flows while using auth0

DavidWells avatar Jan 06 '20 19:01 DavidWells

I'm definitely digging this idea, having the same exact problem right now.

This would require to

  • have the user add a AUTH0_CLIENT_ID and AUTH0_MANAGEMENT_API_TOKEN in the environment variables

  • send a GET request to /api/v2/clients/{id} to get the values of the callbackURLs and allowedURLs

  • send a PATCH request to /api/v2/clients/{id} with the added URL

The caveats I see : does the AUTH0_MANAGEMENT_API_TOKEN has to be refreshed ?

romainbessugesmeusy avatar May 01 '20 08:05 romainbessugesmeusy

/* eslint-disable no-console */
const path = require('path');
require('dotenv').config({
  path: path.resolve(process.cwd(), `.env.${process.env.CONTEXT}`),
});
const { ManagementClient } = require('auth0');

module.exports = {
  onInit: ({ utils }) => {
    console.info(`πŸ”‘ Auth0 Plugin startup πŸ”‘`);
    const tab = '   ';
    const requiredEnvVariables = [
      'AUTH0_MANAGEMENT_API_TOKEN',
      'AUTH0_DOMAIN',
      'AUTH0_CLIENT_ID',
      'AUTH0_CALLBACK_PATHNAMES',
      'AUTH0_LOGOUT_PATHNAMES',
      'DEPLOY_URL',
    ];
    const missingEnvVariables = requiredEnvVariables.filter(
      envVar => typeof process.env[envVar] === 'undefined',
    );

    if (missingEnvVariables.length > 0) {
      utils.build.failPlugin(
        `${tab} ☠️ Missing environment variables: ${missingEnvVariables.join(
          ', ',
        )}`,
      );
    }

    return new Promise(resolve => {
      const url = process.env.DEPLOY_URL;
      console.log(`${tab} 🧭 Deploy Preview URL should be:`, url);
      const management = new ManagementClient({
        token: process.env.AUTH0_MANAGEMENT_API_TOKEN,
        domain: process.env.AUTH0_DOMAIN,
      });

      management.clients
        .get({ client_id: process.env.AUTH0_CLIENT_ID })
        .then(client => {
          console.info(`${tab} πŸ— Retrieved Auth0 client:`, client.name);
          if (client.allowed_clients.indexOf(url) === -1) {
            console.info(`${tab} URL has not yet been added to Auth0 Client`);
            const payload = {
              allowed_clients: client.allowed_clients.concat([url]),
              web_origins: client.allowed_clients.concat([url]),
              allowed_origins: client.allowed_clients.concat([url]),
              callbacks: client.callbacks.concat(
                process.env.AUTH0_CALLBACK_PATHNAMES.split(',').map(
                  pathname => `${url}/${pathname}`,
                ),
              ),
              allowed_logout_urls: client.callbacks.concat(
                process.env.AUTH0_LOGOUT_PATHNAMES.split(',').map(
                  pathname => `${url}/${pathname}`,
                ),
              ),
            };
            management.clients.update(
              { client_id: process.env.AUTH0_CLIENT_ID },
              payload,
              (updateError, updatedClient) => {
                if (updateError) {
                  utils.build.failPlugin(
                    `${tab} ☠️ Something wrong happened while trying to patch Auth0 Client`,
                  );
                } else {
                  console.log(`${tab} 🍾 Successfully patched Auth0 Client.`);
                  console.log(
                    `${tab} Allowed URLS:`,
                    updatedClient.allowed_clients,
                  );
                }
                resolve();
              },
            );
          } else {
            console.info(
              `${tab} πŸ‘ URL has already been added to Auth0 Client`,
            );
            resolve();
          }
        });
    });
  },
};

Here's what I came up with. It seems to be working on our Deploy Previews as on our Production Deploys. Feel free to create an official plugin and re-use this code !

romainbessugesmeusy avatar May 01 '20 12:05 romainbessugesmeusy

This is fantastic @romainbessugesmeusy! Nice work.

Are you planning on publishing this to npm? πŸ˜ƒ

DavidWells avatar May 01 '20 18:05 DavidWells

Thank you for your kind words! I fear I won’t be able to maintain such a project and I probably won’t be doing a service to the community by doing it poorly. Feel free to publish it yourself if you want. Cheers and stay safe

romainbessugesmeusy avatar May 01 '20 18:05 romainbessugesmeusy

@romainbessugesmeusy, Thanks for sharing this and allowing the code for re-use. Even if you can't maintain something like this, it's kind of you to share with the community after finding a solution.

talves avatar May 01 '20 19:05 talves

Latest netlify-build broke local plugins so I add to publish it. https://www.npmjs.com/package/netlify-plugin-auth0-patch-urls

romainbessugesmeusy avatar May 27 '20 13:05 romainbessugesmeusy

Latest netlify-build broke local plugins so I add to publish it. https://www.npmjs.com/package/netlify-plugin-auth0-patch-urls

Just added 2 PRs to the repo. Thanks for sharing this with the community

tnovau avatar May 29 '20 21:05 tnovau

Last one, to allow the DEPLOY PRIME URL :+1:

tnovau avatar May 29 '20 22:05 tnovau

Would it be possible to remove the preview URL when the PR is closed? Auth0 has a limit of 100(?) URLs and we open ~10 PRs per repo per week on my team.

I know you can do this with webhooks, was curious if you can do it with a plugin.

cvburgess avatar Aug 09 '21 18:08 cvburgess

Fortunately, I think changes to wildcards by Auth0 mean that predictable subdomains can be added to the allowlist. Their docs^1 now say:

A wildcard may be prefixed and/or suffixed with additional valid hostname characters. https://prefix-*-suffix.example.com will work.

So for Netlify deploy previews, I am hoping I can configure Auth0 with an allowed URL of something like:

https://deploy-preview-*--my-awesome-app.netlify.app/

However, I admit I have not yet tried this to get proof of concept!

nebbles avatar Jun 07 '22 18:06 nebbles

This issue has been automatically marked as stale because it has not had activity in 1 year. It will be closed in 14 days if no further activity occurs. Thanks!

github-actions[bot] avatar Jun 08 '23 14:06 github-actions[bot]

This issue was closed because it had no activity for over 1 year.

github-actions[bot] avatar Jun 23 '23 14:06 github-actions[bot]