{"id":18407,"library":"hapi-auth-any","title":"hapi-auth-any","description":"A hapi.js plugin that combines multiple authentication strategies (including those based on the same scheme) and succeeds if any one of them passes. v2.0.0 requires Node >=18 and @hapi/hapi 21.x. Unlike hapi's built-in strategy mode, which only works with different schemes, this allows combining strategies of the same scheme (e.g., multiple Basic auth strategies). Only returns credentials from the first passing strategy. Throws an AggregateError on failure, preserving individual errors.","status":"active","version":"2.0.0","language":"javascript","source_language":"en","source_url":"https://github.com/jscheffner/hapi-auth-any","tags":["javascript","hapi","hapijs","hapi.js","auth","authentication","access","credentials","scope"],"install":[{"cmd":"npm install hapi-auth-any","lang":"bash","label":"npm"},{"cmd":"yarn add hapi-auth-any","lang":"bash","label":"yarn"},{"cmd":"pnpm add hapi-auth-any","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"peer dependency – plugin requires hapi v21.x","package":"@hapi/hapi","optional":false}],"imports":[{"note":"ESM-only since v2 (Node >=18). Use import syntax.","wrong":"const authAny = require('hapi-auth-any')","symbol":"default","correct":"import authAny from 'hapi-auth-any'"},{"note":"CommonJS require works only in v1.x. For v2.x, use ESM import.","wrong":null,"symbol":"default","correct":"const authAny = require('hapi-auth-any')"},{"note":"The plugin is the default export. Options are passed to server.auth.strategy, not to register.","wrong":"server.register({ plugin: authAny, options: {} })","symbol":"plugin","correct":"await server.register(authAny)"}],"quickstart":{"code":"import Hapi from '@hapi/hapi';\nimport authAny from 'hapi-auth-any';\nimport Basic from '@hapi/basic';\n\nconst server = Hapi.server({ port: 8080 });\n\nawait server.register([authAny, Basic]);\n\nserver.auth.strategy('simple', 'basic', {\n  validate: (request, username, password) => {\n    return { isValid: username === 'admin' && password === 'secret', credentials: { user: username } };\n  }\n});\n\nserver.auth.strategy('team', 'basic', {\n  validate: (request, username, password) => {\n    return { isValid: username === 'team' && password === 'pass', credentials: { user: username } };\n  }\n});\n\nserver.auth.strategy('any', 'any', {\n  strategies: ['simple', 'team']\n});\n\nserver.route({\n  method: 'GET',\n  path: '/',\n  options: { auth: 'any' },\n  handler: (request, h) => {\n    return `Authenticated as ${request.auth.credentials.user}`;\n  }\n});\n\nawait server.start();\nconsole.log('Server running on %s', server.info.uri);","lang":"javascript","description":"Registers hapi-auth-any with two Basic strategies and authenticates a route if either succeeds."},"warnings":[{"fix":"Upgrade Node.js to 18 or later.","message":"v2.0.0 drops support for Node.js 14 and 16. Requires Node >=18.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Upgrade @hapi/hapi to 21.x.","message":"v2.0.0 drops support for Hapi 19 and 20. Requires @hapi/hapi 21.x.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Access individual errors via err.errors instead of iterating the AggregateError itself.","message":"v2.0.0 throws a native AggregateError instead of third-party one. The errors property is now an array, not iterable.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Use Node 10 or later; for Node >=18, use v2.","message":"v1.0.0 drops support for Node 8. Requires Node >=10.","severity":"deprecated","affected_versions":">=1.0.0 <2.0.0"}],"env_vars":null,"last_verified":"2026-04-25T00:00:00.000Z","next_check":"2026-07-24T00:00:00.000Z","problems":[{"fix":"Ensure server.auth.strategy('any', 'any', { strategies: ['strategy1', 'strategy2'] });","cause":"The strategies option passed to server.auth.strategy is missing, not an array, or contains non-string items.","error":"Error: hapi-auth-any: strategies option must be an array of strings"},{"fix":"Check that at least one strategy can authenticate the request, or handle missing credentials in the handler.","cause":"The route's auth mode is set to 'any' but none of the combined strategies succeeded, so request.auth.credentials is undefined.","error":"TypeError: Cannot read properties of undefined (reading 'credentials')"},{"fix":"First register the combined strategy: server.auth.strategy('any', 'any', { strategies: [...] });","cause":"The 'any' strategy was not registered via server.auth.strategy before it was used in a route.","error":"AssertionError: Unsupported authentication strategy 'any'"},{"fix":"Upgrade @hapi/hapi to version 21.x.","cause":"Using an older version of @hapi/hapi with hapi-auth-any v2.","error":"Error: hapi-auth-any requires @hapi/hapi 21.x"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}