auth0-extensions/auth0-source-control-extension-tools

View on GitHub
src/auth0/handlers/clientGrants.js

Summary

Maintainability
A
1 hr
Test Coverage
import DefaultHandler, { order } from './default';
import { convertClientNamesToIds } from '../../utils';

export const schema = {
  type: 'array',
  items: {
    type: 'object',
    properties: {
      client_id: { type: 'string' },
      audience: { type: 'string' },
      scope: {
        type: 'array',
        items: { type: 'string' },
        uniqueItems: true
      }
    },
    required: [ 'client_id', 'scope', 'audience' ]
  }
};

export default class ClientHandler extends DefaultHandler {
  constructor(config) {
    super({
      ...config,
      type: 'clientGrants',
      id: 'id',
      identifiers: [ 'id', [ 'client_id', 'audience' ] ],
      stripUpdateFields: [ 'audience', 'client_id' ]
    });
  }

  objString(item) {
    return super.objString({ id: item.id, client_id: item.client_id, audience: item.audience });
  }

  async getType() {
    if (this.existing) {
      return this.existing;
    }
    this.existing = await this.client.clientGrants.getAll({ paginate: true });

    // Always filter out the client we are using to access Auth0 Management API
    // As it could cause problems if the grants are deleted or updated etc
    const currentClient = this.config('AUTH0_CLIENT_ID');

    this.existing = this.existing.filter((grant) => grant.client_id !== currentClient);

    return this.existing;
  }

  // Run after clients are updated so we can convert client_id names to id's
  @order('60')
  async processChanges(assets) {
    const { clientGrants } = assets;

    // Do nothing if not set
    if (!clientGrants) return;

    const clients = await this.client.clients.getAll({ paginate: true });
    const excludedClientsByNames = (assets.exclude && assets.exclude.clients) || [];
    const excludedClients = convertClientNamesToIds(excludedClientsByNames, clients);

    // Convert clients by name to the id
    const formatted = assets.clientGrants.map((clientGrant) => {
      const grant = { ...clientGrant };
      const found = clients.find((c) => c.name === grant.client_id);
      if (found) grant.client_id = found.client_id;
      return grant;
    });

    // Always filter out the client we are using to access Auth0 Management API
    const currentClient = this.config('AUTH0_CLIENT_ID');

    const {
      del, update, create, conflicts
    } = await this.calcChanges({ ...assets, clientGrants: formatted });

    const filterGrants = (list) => {
      if (excludedClients.length) {
        return list.filter((item) => item.client_id !== currentClient && ![ ...excludedClientsByNames, ...excludedClients ].includes(item.client_id));
      }

      return list.filter((item) => item.client_id !== currentClient);
    };

    const changes = {
      del: filterGrants(del),
      update: filterGrants(update),
      create: filterGrants(create),
      conflicts: filterGrants(conflicts)
    };

    await super.processChanges(assets, {
      ...changes
    });
  }
}