Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
@doodle/doodle-node-cli / src / apis / keycloak.js
Size: Mime:
const fetch = require('fetch-everywhere');
const { errorHandler, responseHandler } = require('./fetch');
const { getKeycloakClientSecret } = require('./vault');
const { DOODLE_ENVS } = require('../constants');

/**
 * Get the JWT for the Keycloak user.
 *
 * @param {String} target - the target to look for the token (staging, devbox, etc)
 * @param {String} username - the email address of the user
 * @param {String} password - the user's password
 * @returns {Promise}
 */
const getTokenForUser = async (target, username, password) => {
  const keycloakClientSecret = await getKeycloakClientSecret(target);

  const { keycloakAuthUrl } = DOODLE_ENVS[target];

  const headers = {
    'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
  };

  const body = new URLSearchParams({
    grant_type: 'password',
    client_id: 'doodle-node-cli',
    client_secret: keycloakClientSecret,
    username,
    password,
  });

  const url = `${keycloakAuthUrl}/realms/doodle/protocol/openid-connect/token`;

  return fetch(url, { method: 'POST', headers, body })
    .then(responseHandler)
    .catch(errorHandler);
};

/**
 * Use the Admin API to fetch a specific user info.
 *
 * @param {String} target - the target to look for the token (staging, devbox, etc)
 * @param {String} userEmail - the email address for the user
 * @param {String} serviceAccessToken - The service account token
 * @returns {Promise}
 */
const getKeycloakUserInfo = (target, userEmail, serviceAccessToken) => {
  const headers = {
    Authorization: `Bearer ${serviceAccessToken}`,
    'Content-Type': 'application/json',
  };

  const { keycloakInternalAuthUrl } = DOODLE_ENVS[target];

  const url = `${keycloakInternalAuthUrl}/admin/realms/doodle/users?email=${encodeURIComponent(userEmail)}&first=0`;

  return fetch(url, { method: 'GET', headers })
    .then(responseHandler)
    .catch(errorHandler);
};

/**
 * Get the Keycloak Service Account Token.
 *
 * @param {String} target - the target to look for the token (staging, devbox, etc)
 * @returns {Promise}
 */
const getServiceAccount = async target => {
  const keycloakClientSecret = await getKeycloakClientSecret(target);

  const { keycloakAuthUrl } = DOODLE_ENVS[target];

  const headers = {
    'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
  };

  const body = new URLSearchParams({
    grant_type: 'client_credentials',
    client_id: 'doodle-node-cli',
    scope: 'offline_access',
    client_secret: keycloakClientSecret,
  });

  const url = `${keycloakAuthUrl}/realms/doodle/protocol/openid-connect/token`;

  return fetch(url, { method: 'POST', headers, body })
    .then(responseHandler)
    .catch(errorHandler);
};

/**
 * Create a new Keycloak User with the ADMIN API
 * @param {String} target - staging, devbox, etc
 * @param {String} email - The email address to use
 * @param {String} firstName - The user's first name
 * @param {String} lastName - The user's last name
 * @param {String} serviceAccessToken - The service account token
 * @returns {Promise}
 */
const createNewKeycloakUser = (target, email, firstName, lastName, serviceAccessToken) => {
  const headers = {
    Authorization: `Bearer ${serviceAccessToken}`,
    'Content-Type': 'application/json',
  };

  const payload = {
    attributes: { locale: ['en'] },
    email,
    emailVerified: true,
    enabled: true,
    firstName,
    lastName,
  };

  const { keycloakInternalAuthUrl } = DOODLE_ENVS[target];
  const url = `${keycloakInternalAuthUrl}/admin/realms/doodle/users`;

  return fetch(url, { method: 'POST', headers, body: JSON.stringify(payload) })
    .then(responseHandler)
    .catch(errorHandler);
};

/**
 * Set a password for a Keycloak user.
 *
 * @param {String} target - staging, devbox, etc
 * @param {String} kcUserId - The userId for the KC user
 * @param {String} password - The password to set
 * @param {String} serviceAccessToken - The service account token
 * @returns {Promise}
 */
const setPasswordForKeycloakUser = (target, kcUserId, password, serviceAccessToken) => {
  const headers = {
    Authorization: `Bearer ${serviceAccessToken}`,
    'Content-Type': 'application/json',
  };

  const payload = {
    temporary: false,
    type: 'password',
    value: password,
  };

  const { keycloakInternalAuthUrl } = DOODLE_ENVS[target];
  const url = `${keycloakInternalAuthUrl}/admin/realms/doodle/users/${kcUserId}/reset-password`;

  return fetch(url, { method: 'PUT', headers, body: JSON.stringify(payload) })
    .then(responseHandler)
    .catch(errorHandler);
};

module.exports = {
  getKeycloakUserInfo,
  setPasswordForKeycloakUser,
  createNewKeycloakUser,
  getTokenForUser,
  getServiceAccount,
};