Ctrl K
ComunidadGuías…

lib/personal-provider-settings.js

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
// Personal provider discovery and sign-in authority. No credential files are read.
var crypto = require('crypto');
var os = require('os');
var registry = require('./yoke/vendor-registry');
var protocol = require('./yoke/login-protocol');
var installRecipes = require('./yoke/provider-install-recipes');
var LIFETIME = 5 * 60 * 1000;
function attach(ctx) {
  var receipts = new WeakMap();
  function actor(ws) {
    if (!ws || ws.readyState !== 1 || ws._clayPaneActivation || ws._clayPane || ctx.clients && !ctx.clients.has(ws)) throw new Error('Open Personal settings in the connected workspace.');
    if (ctx.requestAccess && !ctx.requestAccess.canAccessProject(ws, ctx.slug)) throw new Error('Project access changed. Reopen Personal settings.');
    var users = ctx.usersModule;
    var user = ws._clayUser;
    if (users && users.isMultiUser() && (!user || !users.findUserById(user.id))) throw new Error('Sign in again to manage providers.');
    if (user && users && users.findUserById) user = users.findUserById(user.id);
    if (ws._clayUser && !user) throw new Error('This account is no longer available.');
    if (ctx.osUsers && (!user || !user.linuxUser)) throw new Error('Your mapped OS identity is unavailable.');
    var info = ctx.osUsers ? (ctx.resolveOsUserInfo ? ctx.resolveOsUserInfo(user.linuxUser) : ctx.getOsUserInfoForWs({ _clayUser: user })) : null;
    if (ctx.osUsers && (!info || !info.user || !info.home)) throw new Error('Your mapped OS identity is unavailable. Ask the server administrator to check the mapping.');
    return { accountName:user ? user.displayName || user.username || String(user.id) : 'Personal account', role: user ? user.role : 'admin', runtime: info || {user:os.userInfo().username,uid:os.userInfo().uid,gid:os.userInfo().gid,home:os.homedir()}, owner: user ? String(user.id) : 'default', identity: { linuxUser: info ? info.user : null, osUserInfo: info } };
  }
  function signature() {
    return JSON.stringify(Object.keys(registry.VENDOR_REGISTRY).map(function (id) {
      var info = registry.getVendorInfo(id);
      return [id, info.loginCommand, info.terminalLoginCommand, info.browserLoginCommand, info.oauthHosts, info.osUserIsolation, info.installRecipe];
    }));
  }
  function current(ws, receipt) {
    if (!receipt) return false;
    try { return Object.keys(receipt.registry).length === Object.keys(registry.VENDOR_REGISTRY).length && Object.keys(receipt.registry).every(function (id) { return receipt.registry[id] === registry.getVendorInfo(id) && receipt.resolvers[id] === registry.getVendorInfo(id).resolveExecutable; }) && receipt.commands === signature() && receipts.get(ws) === receipt && receipt.expires > Date.now() && JSON.stringify(actor(ws)) === receipt.actor; }
    catch (error) { return false; }
  }
  function catalog(ws, requestId) {
    var target = actor(ws);
    var receipt = { registry: Object.assign({}, registry.VENDOR_REGISTRY), resolvers: {}, commands: signature(), id: crypto.randomUUID(), actor: JSON.stringify(target), expires: Date.now() + LIFETIME };
    Object.keys(receipt.registry).forEach(function (id) { receipt.resolvers[id] = receipt.registry[id].resolveExecutable; });
    receipts.set(ws, receipt);
    var info = target.identity.osUserInfo;
    var scope = info ? 'Mapped OS account ' + info.user + ' · HOME ' + info.home :
      'Shared server OS account ' + os.userInfo().username + ' · HOME ' + os.homedir() + '. Provider credentials are shared by processes using this HOME; they are not isolated by Clay Studio account.';
    var rows = Object.keys(registry.VENDOR_REGISTRY).map(function (id) {
      var provider = registry.getVendorInfo(id);
      var supported = !ctx.osUsers || provider.osUserIsolation === true;
      var installed = null, reason = '';
      if (!supported) reason = 'This provider does not support mapped OS accounts in Clay Studio.';
      else {
        try { installed = !!provider.resolveExecutable({ user: target.identity.linuxUser }); }
        catch (error) { reason = 'Installation discovery failed. Check the server setup, then refresh status.'; }
      }
      var installReason = installRecipes.eligible(provider.installRecipe, target.runtime);
      if (!ctx.osUsers && target.role !== 'admin') installReason = 'Only the server administrator can install into the shared runtime HOME.';
      var login = false;
      try { protocol.command(id, false); login = true; } catch (error) {}
      var permitted = !ctx.requestAccess || ctx.requestAccess.hasPermission(ws, 'terminal');
      var canInstall = supported && installed === false && permitted && !installReason;
      return { id: id, name: provider.displayName, icon: provider.avatar, setupUrl: provider.setupUrl, installed: installed,
        authentication: 'unknown', tested: false, browser: !!provider.browserLoginCommand,
        canSignIn: supported && installed === true && login && permitted,
        canInstall: canInstall, installReason: installReason,
        reason: reason || (!permitted ? 'Terminal permission is required for provider installation and sign-in.' : ''),
        setup: canInstall ? 'Review the official installer for the runtime account shown above. Installation does not sign in or run a task.' : (installed === null ? (reason || 'Installation status is unknown. Refresh status before reviewing an installation.') : installReason || 'Review the registered installer before running it.') + ' Ask the server operator to install ' + provider.binaryName + ' for the runtime OS account shown above, using the provider’s official setup instructions. Then refresh status.',
        loginCommand: supported && permitted && login ? protocol.command(id, false) : null };
    });
    if (!current(ws, receipt)) throw new Error('Provider account context changed. Refresh status.');
    return { type: 'vendor_login_catalog', requestId: requestId, revision: receipt.id, owner: target.owner, accountName:target.accountName, runtime:Object.assign({shared:!info},target.runtime), scope: scope, providers: rows };
  }
  function resolve(ws, msg) {
    var receipt = receipts.get(ws), info = registry.getVendorInfo(msg.vendor);
    if (!current(ws, receipt) || msg.personalRequestId !== receipt.id || msg.sessionId || msg.workerAuthRequestId ||
        !info || ctx.osUsers && info.osUserIsolation !== true || ctx.requestAccess && !ctx.requestAccess.hasPermission(ws, 'terminal')) {
      throw new Error('Personal provider context expired or is no longer permitted. Refresh status before signing in.');
    }
    var target = actor(ws);
    if (!info.resolveExecutable({user:target.identity.linuxUser})) throw new Error('Install this provider for the runtime OS account, then refresh status.');
    return { identity: target.identity, validate: function (peer) {
      return peer === ws && current(ws, receipt) && (!ctx.requestAccess || ctx.requestAccess.hasPermission(ws, 'terminal'));
    } };
  }
  function resolveInstall(ws, msg) {
    var receipt = receipts.get(ws), provider = registry.getVendorInfo(msg.vendor);
    if (!current(ws, receipt) || msg.personalRequestId !== receipt.id || msg.sessionId || msg.workerAuthRequestId || !provider || ctx.osUsers && provider.osUserIsolation !== true || ctx.requestAccess && !ctx.requestAccess.hasPermission(ws, 'terminal')) throw new Error('Installation context expired or permission changed. Refresh status.');
    var target = actor(ws), recipe = provider.installRecipe;
    var reason = installRecipes.eligible(recipe, target.runtime);
    if (!ctx.osUsers && target.role !== 'admin') reason = 'Only the server administrator can install into the shared runtime HOME.';
    if (reason) throw new Error(reason);
    if (provider.resolveExecutable({user:target.identity.linuxUser})) throw new Error('This provider is already installed. Refresh status.');
    return { recipe:recipe, runtime:target.runtime, identity:target.identity, validate:function () {
      try { return current(ws, receipt) && provider === registry.getVendorInfo(msg.vendor) && recipe === provider.installRecipe && (!ctx.requestAccess || ctx.requestAccess.hasPermission(ws,'terminal')) && !installRecipes.eligible(recipe,actor(ws).runtime); } catch(error) { return false; }
    } };
  }
  return { catalog: catalog, resolve: resolve, resolveInstall:resolveInstall, release: function (ws) { receipts.delete(ws); } };
}
module.exports = { attach: attach };