verdaccio添加自定义插件

396 阅读1分钟

编写插件

如何生成插件模板,可以看官网教程

自定义一个鉴权插件

简单定义一个鉴权插件,只有当npm包的publish组中包含当前用户所在的用户组时,允许发布和撤销发布该npm包。

import { getInternalError } from '@verdaccio/commons-api';
/**
 * Custom Verdaccio Authenticate Plugin.
 */
class AuthCustomPlugin {
    constructor(config, options) {
        this.logger = options.logger;
        /** 
        * 这里对应config.yaml插件下面配置的字段
        * auth:
        *   authgroup: 
        *      test: test test-bot
        *  config = { test: "test test-bot" }
        */
        this.test = config.test;
        return this;
    }
    /**
     * Authenticate an user.
     * @param user user to log
     * @param password provided password
     * @param cb callback function
     */
    authenticate(user, password, cb) {
        if (this.test) {
            cb(null, ['group-test']);
        }
        else {
            cb(getInternalError("error, try again"), false);
        }
    }
    /**
     * Triggered on each access request
     * @param user
     * @param pkg
     * @param cb
     */
    allow_access(user, pkg, cb) {
        // allow all users to access all packages
        cb(null, true);
    }
    /**
     * Triggered on each publish request
     * @param user
     * @param pkg
     * @param cb
     */
    allow_publish(user, pkg, cb) {
        const userGroups = user.groups || [];
        const hasPublishAccess = userGroups.some((group) => pkg?.publish?.includes(group));
        if (hasPublishAccess) {
            this.logger.debug({ name: user.name }, '@{name} has been granted to publish');
            cb(null, true);
        }
        else {
            this.logger.error({ name: user.name }, '@{name} is not allowed to publish this package');
            cb(getInternalError("error, try again"), false);
        }
    }
    allow_unpublish(user, pkg, cb) {
        const userGroups = user.groups || [];
        const hasPublishAccess = userGroups.some((group) => pkg?.publish?.includes(group));
        if (hasPublishAccess) {
            this.logger.debug({ name: user.name }, '@{name} has been granted to publish');
            cb(null, true);
        }
        else {
            this.logger.error({ name: user.name }, '@{name} is not allowed to publish this package');
            cb(getInternalError("error, try again"), false);
        }
    }
}

安装插件

这里假设我们的插件npm包名为verdaccio-authgroup,需要在verdaccio安装的目录下面安装插件,否则启动verdaccio时会报无法识别插件的问题。例如verdaccio安装在/nvm/v16.18.1/node_modules/verdaccio这个目录,那么在该目录下面执行下面的命令:

npm install verdaccio-authgroup

config.yaml配置

安装完自定义插件后,还需要在verdaccio目录下的config.yaml文件中编写自定义插件的配置。

web:
  title: Verdaccio
  
auth:
  htpasswd:
    file: ./htpasswd
  # 自定义插件在这里声明,如果你的包名为verdaccio-authgroup,插件名要写成authgroup
  authgroup:
    test: test test-bot # 声明test组的成员

#...

packages:
  '@*/*':
    # scoped packages
    access: $all
    publish: $authenticated
    unpublish: $authenticated
    proxy: npmjs

  'test-package':
  # 这里配置只允许test-bot进行publish,unpublish操作
    access: $all 
    publish: test-bot
    unpublish: test-bot
    proxy: npmjs

最后

重启verdaccio即可应用上插件