1"use strict";(globalThis.webpackChunk_verdaccio_website=globalThis.webpackChunk_verdaccio_website||[]).push([[7327],{33644:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>a,contentTitle:()=>s,default:()=>p,frontMatter:()=>c,metadata:()=>t,toc:()=>o});const t=JSON.parse('{"id":"plugin-middleware","title":"Middleware Plugin","description":"What\'s a Middleware Plugin?","source":"@site/docs/plugin-middleware.md","sourceDirName":".","slug":"/plugin-middleware","permalink":"/docs/plugin-middleware","draft":false,"unlisted":false,"editUrl":"https://github.com/verdaccio/website/edit/master/website/docs/plugin-middleware.md","tags":[],"version":"current","lastUpdatedBy":"verdacciopack","lastUpdatedAt":1789720860000,"frontMatter":{"id":"plugin-middleware","title":"Middleware Plugin"},"sidebar":"docs","previous":{"title":"Authentication Plugin","permalink":"/docs/plugin-auth"},"next":{"title":"Storage Plugin","permalink":"/docs/plugin-storage"}}');var r=i(8265),d=i(92233);const c={id:"plugin-middleware",title:"Middleware Plugin"},s=void 0,a={},o=[{value:"What's a Middleware Plugin?",id:"whats-a-middleware-plugin",level:2},{value:"API",id:"api",level:3},{value:"<code>register_middlewares</code>",id:"register_middlewares",level:3},{value:"Overwriting HTTP Security Headers {#overwrite-http-security-headers]",id:"overwriting-http-security-headers-overwrite-http-security-headers",level:2},{value:"Generate a middleware plugin",id:"generate-a-middleware-plugin",level:2},{value:"List Community Middleware Plugins",id:"list-community-middleware-plugins",level:3}];function l(e){const n={a:"a",blockquote:"blockquote",code:"code",em:"em",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,d.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h2,{id:"whats-a-middleware-plugin",children:"What's a Middleware Plugin?"}),"\n",(0,r.jsx)(n.p,{children:"Middleware plugins have the capability to modify the API (web and cli) layer, either adding new endpoints or intercepting requests."}),"\n",(0,r.jsx)(n.h3,{id:"api",children:"API"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-typescript",children:"interface IPluginMiddleware<T> extends IPlugin<T> {\n register_middlewares(app: any, auth: IBasicAuth<T>, storage: IStorageManager<T>): void;\n}\n"})}),"\n",(0,r.jsx)(n.h3,{id:"register_middlewares",children:(0,r.jsx)(n.code,{children:"register_middlewares"})}),"\n",(0,r.jsxs)(n.p,{children:["The method provide full access to the authentification and storage via ",(0,r.jsx)(n.code,{children:"auth"})," and ",(0,r.jsx)(n.code,{children:"storage"}),". ",(0,r.jsx)(n.code,{children:"app"})," is the express application that allows you to add new endpoints."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-typescript",children:"public register_middlewares(\n app: Application,\n auth: IBasicAuth<CustomConfig>,\n storage: IStorageManager<CustomConfig>\n ): void {\n const router = Router();\n router.post(\n '/custom-endpoint',\n (req: Request, res: Response & { report_error?: Function }, next: NextFunction): void => {\n const encryptedString = auth.aesEncrypt(Buffer.from(this.foo, 'utf8'));\n res.setHeader('X-Verdaccio-Token-Plugin', encryptedString.toString());\n next();\n }\n );\n app.use('/-/npm/something-new', router);\n }\n"})}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"auth"})," and ",(0,r.jsx)(n.code,{children:"storage"})," are instances and can be extended, but we don't recommend this approach unless is well founded."]}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsxs)(n.p,{children:["A good example of a middleware plugin is the ",(0,r.jsx)(n.a,{href:"https://github.com/verdaccio/monorepo/tree/master/plugins/audit",children:"verdaccio-audit"}),"."]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"overwriting-http-security-headers-overwrite-http-security-headers",children:"Overwriting HTTP Security Headers {#overwrite-http-security-headers]"}),"\n",(0,r.jsx)(n.p,{children:"By default, Verdaccio sets the following HTTP headers. If you have other security requirements, you can overwrite these settings using a middleware plugin (Verdaccio 6.2.5 or higher)."}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Header"}),(0,r.jsx)(n.th,{children:"Verdaccio Setting"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Content-Security-Policy"}),(0,r.jsx)(n.td,{children:"connect-src 'self'"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"X-Content-Type-Options"}),(0,r.jsx)(n.td,{children:"nosniff"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"X-Frame-Options"}),(0,r.jsx)(n.td,{children:"deny"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"X-XSS-Protection"}),(0,r.jsx)(n.td,{children:"1; mode=block"})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"generate-a-middleware-plugin",children:"Generate a middleware plugin"}),"\n",(0,r.jsxs)(n.p,{children:["For detailed info check our ",(0,r.jsx)(n.a,{href:"plugin-generator",children:"plugin generator page"}),". Run the ",(0,r.jsx)(n.code,{children:"yo"})," command in your terminal and follow the steps."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"\u279c yo verdaccio-plugin\n\nJust found a `.yo-rc.json` in a parent directory.\nSetting the project root at: /Users/user/verdaccio_yo_generator\n\n _-----_ \u256d\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256e\n | | \u2502 Welcome to \u2502\n |--(o)--| \u2502 generator-verdaccio-plug \u2502\n `---------\xb4 \u2502 in plugin generator! \u2502\n ( _\xb4U`_ ) \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256f\n /___A___\\ /\n | ~ |\n __'.___.'__\n \xb4 ` |\xb0 \xb4 Y `\n\n? What is the name of your plugin? custom-endpoint\n? Select Language typescript\n? What kind of plugin you want to create? middleware\n? Please, describe your plugin awesome middleware plugin\n? GitHub username or organization myusername\n? Author's Name Juan Picado\n? Author's Email [email protected]\n? Key your keywords (comma to split) verdaccio,plugin,middleware,awesome,verdaccio-plugin\n create verdaccio-plugin-custom-endpoint/package.json\n create verdaccio-plugin-custom-endpoint/.gitignore\n create verdaccio-plugin-custom-endpoint/.npmignore\n create verdaccio-plugin-custom-endpoint/jest.config.js\n create verdaccio-plugin-custom-endpoint/.babelrc\n create verdaccio-plugin-custom-endpoint/.travis.yml\n create verdaccio-plugin-custom-endpoint/README.md\n create verdaccio-plugin-custom-endpoint/.eslintrc\n create verdaccio-plugin-custom-endpoint/.eslintignore\n create verdaccio-plugin-custom-endpoint/src/index.ts\n create verdaccio-plugin-custom-endpoint/index.ts\n create verdaccio-plugin-custom-endpoint/tsconfig.json\n create verdaccio-plugin-custom-endpoint/types/index.ts\n create verdaccio-plugin-custom-endpoint/.editorconfig\n\nI'm all done. Running npm install for you to install the required dependencies. If this fails, try running the command yourself.\n\n\n\u2e28 \u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2e29 \u280b fetchMetadata: sill pacote range manifest for @babel/plugin-syntax-jsx@^7.7.4 fetc\n"})}),"\n",(0,r.jsx)(n.p,{children:"After the install finish, access to your project scalfold."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:'\u279c cd verdaccio-plugin-auth-service-name\n\u279c cat package.json\n\n {\n "name": "verdaccio-plugin-custom-endpoint",\n "version": "0.0.1",\n "description": "awesome middleware plugin",\n ...\n'})}),"\n",(0,r.jsx)(n.p,{children:"The middleware are registrered after built-in endpoints, thus, it is not possible to override the implemented ones."}),"\n",(0,r.jsx)(n.h3,{id:"list-community-middleware-plugins",children:"List Community Middleware Plugins"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://github.com/verdaccio/verdaccio-audit",children:"verdaccio-audit"}),": verdaccio plugin for ",(0,r.jsx)(n.em,{children:"npm audit"})," cli support (built-in) (compatible since 3.x)"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://github.com/ahoracek/verdaccio-profile-api",children:"verdaccio-profile-api"}),": verdaccio plugin for ",(0,r.jsx)(n.em,{children:"npm profile"})," cli support and ",(0,r.jsx)(n.em,{children:"npm profile set password"})," for ",(0,r.jsx)(n.em,{children:"verdaccio-htpasswd"})," based authentificaton"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://github.com/honzahommer/verdaccio-https",children:"verdaccio-https"})," Verdaccio middleware plugin to redirect to https if x-forwarded-proto header is set"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://github.com/tavvy/verdaccio-badges",children:"verdaccio-badges"})," A verdaccio plugin to provide a version badge generator endpoint"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://github.com/freight-hub/verdaccio-openmetrics",children:"verdaccio-openmetrics"})," Verdaccio plugin exposing an OpenMetrics/Prometheus endpoint with health and traffic metrics"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://github.com/juanpicado/verdaccio-sentry",children:"verdaccio-sentry"})," sentry loggin errors"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://github.com/PaddeK/verdaccio-pacman",children:"verdaccio-pacman"})," Verdaccio Middleware Plugin to manage tags and versions of packages"]}),"\n"]}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,d.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},92233:(e,n,i)=>{i.d(n,{R:()=>c,x:()=>s});var t=i(70141);const r={},d=t.createContext(r);function c(e){const n=t.useContext(d);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),t.createElement(d.Provider,{value:n},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.