gina 0.5.26 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/README.md +34 -22
- package/ROADMAP.md +43 -16
- package/bin/cli +12 -1
- package/bin/gina-init +15 -1
- package/framework/v0.6.0/VERSION +1 -0
- package/framework/{v0.5.26 → v0.6.0}/core/asset/plugin/dist/vendor/gina/js/gina.js +36 -1
- package/framework/v0.6.0/core/asset/plugin/dist/vendor/gina/js/gina.min.js +601 -0
- package/framework/v0.6.0/core/asset/plugin/dist/vendor/gina/js/gina.min.js.br +0 -0
- package/framework/v0.6.0/core/asset/plugin/dist/vendor/gina/js/gina.min.js.gz +0 -0
- package/framework/{v0.5.26 → v0.6.0}/core/connectors/couchbase/lib/session-store.v3.js +52 -84
- package/framework/{v0.5.26 → v0.6.0}/core/connectors/couchbase/lib/session-store.v4.js +58 -84
- package/framework/{v0.5.26 → v0.6.0}/core/connectors/mongodb/lib/session-store.js +5 -2
- package/framework/{v0.5.26 → v0.6.0}/core/connectors/redis/lib/session-store.js +5 -2
- package/framework/{v0.5.26 → v0.6.0}/core/connectors/scylladb/lib/session-store.js +5 -2
- package/framework/{v0.5.26 → v0.6.0}/core/connectors/sqlite/lib/session-store.js +17 -3
- package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/session/src/main.js +142 -9
- package/framework/{v0.5.26 → v0.6.0}/core/router.js +101 -11
- package/framework/{v0.5.26 → v0.6.0}/core/server.js +91 -1
- package/framework/{v0.5.26 → v0.6.0}/core/template/conf/settings.json +3 -0
- package/framework/v0.6.0/lib/audit/src/main.js +916 -0
- package/framework/v0.6.0/lib/authn/package.json +7 -0
- package/framework/v0.6.0/lib/authn/src/lockout.js +615 -0
- package/framework/v0.6.0/lib/authn/src/main.js +899 -0
- package/framework/v0.6.0/lib/authn/src/totp.js +418 -0
- package/framework/v0.6.0/lib/cmd/audit/arguments.json +5 -0
- package/framework/v0.6.0/lib/cmd/audit/help.txt +50 -0
- package/framework/v0.6.0/lib/cmd/audit/verify.js +294 -0
- package/framework/{v0.5.26 → v0.6.0}/lib/cmd/framework/init.js +11 -0
- package/framework/{v0.5.26 → v0.6.0}/lib/cmd/framework/tail.js +5 -1
- package/framework/{v0.5.26 → v0.6.0}/lib/cmd/gina.1.md +1 -0
- package/framework/{v0.5.26 → v0.6.0}/lib/index.js +13 -0
- package/framework/{v0.5.26 → v0.6.0}/lib/logger/src/containers/file/index.js +11 -1
- package/framework/{v0.5.26 → v0.6.0}/lib/logger/src/containers/mq/speaker.js +8 -1
- package/framework/v0.6.0/lib/net-locality/package.json +17 -0
- package/framework/v0.6.0/lib/net-locality/src/main.js +174 -0
- package/framework/{v0.5.26 → v0.6.0}/lib/nunjucks-filters/src/main.js +13 -0
- package/framework/{v0.5.26 → v0.6.0}/lib/routing/src/main.js +36 -1
- package/framework/{v0.5.26 → v0.6.0}/lib/swig-filters/src/main.js +13 -0
- package/framework/{v0.5.26 → v0.6.0}/package.json +1 -1
- package/gna.js +4 -4
- package/llms.txt +19 -2
- package/package.json +3 -3
- package/schema/connectors.json +2 -3
- package/schema/settings.json +101 -0
- package/types/index.d.ts +4 -0
- package/framework/v0.5.26/VERSION +0 -1
- package/framework/v0.5.26/core/asset/plugin/dist/vendor/gina/js/gina.min.js +0 -599
- package/framework/v0.5.26/core/asset/plugin/dist/vendor/gina/js/gina.min.js.br +0 -0
- package/framework/v0.5.26/core/asset/plugin/dist/vendor/gina/js/gina.min.js.gz +0 -0
- package/framework/v0.5.26/lib/audit/src/main.js +0 -456
- /package/framework/{v0.5.26 → v0.6.0}/AUTHORS +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/LICENSE +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/asset/html/nolayout.html +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/asset/html/static.html +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/asset/img/android-chrome-192x192.png +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/asset/img/android-chrome-512x512.png +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/asset/img/apple-touch-icon.png +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/asset/img/favicon-16x16.png +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/asset/img/favicon-32x32.png +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/asset/img/favicon.ico +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/asset/plugin/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/asset/plugin/dist/vendor/gina/beemaster/beemaster.css +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/asset/plugin/dist/vendor/gina/beemaster/beemaster.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/asset/plugin/dist/vendor/gina/beemaster/index.html +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/asset/plugin/dist/vendor/gina/css/gina.min.css +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/asset/plugin/dist/vendor/gina/css/gina.min.css.br +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/asset/plugin/dist/vendor/gina/css/gina.min.css.gz +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/asset/plugin/dist/vendor/gina/html/statusbar.html +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/asset/plugin/dist/vendor/gina/html/statusbar.html.br +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/asset/plugin/dist/vendor/gina/html/statusbar.html.gz +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/asset/plugin/dist/vendor/gina/inspector/have_heart_one-webfont.woff2 +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/asset/plugin/dist/vendor/gina/inspector/index.html +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/asset/plugin/dist/vendor/gina/inspector/inspector.css +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/asset/plugin/dist/vendor/gina/inspector/inspector.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/asset/plugin/dist/vendor/gina/inspector/logo.svg +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js.br +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js.gz +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/config.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/connectors/ai/index.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/connectors/ai/lib/connector.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/connectors/couchbase/index.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/connectors/couchbase/lib/connector.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/connectors/couchbase/lib/connector.v3.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/connectors/couchbase/lib/connector.v4.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/connectors/couchbase/lib/n1ql.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/connectors/couchbase/lib/session-store.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/connectors/mongodb/index.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/connectors/mongodb/lib/connector.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/connectors/mongodb/lib/job-store.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/connectors/mongodb/lib/pipeline-loader.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/connectors/mysql/index.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/connectors/mysql/lib/connector.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/connectors/postgresql/index.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/connectors/postgresql/lib/connector.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/connectors/redis/index.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/connectors/redis/lib/connector.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/connectors/redis/lib/job-store.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/connectors/redis/lib/render-cache-store.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/connectors/scylladb/index.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/connectors/scylladb/lib/connector.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/connectors/sql-parser.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/connectors/sqlite/index.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/connectors/sqlite/lib/connector.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/connectors/sqlite/lib/job-store.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/content.encoding +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/controller/controller.framework.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/controller/controller.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/controller/controller.render-json.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/controller/controller.render-nunjucks-async.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/controller/controller.render-nunjucks.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/controller/controller.render-stream.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/controller/controller.render-swig-async.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/controller/controller.render-swig.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/controller/controller.render-v1.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/controller/index.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/controller/inspector-window-emit.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/controller/release-banner.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/dev/index.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/dev/lib/class.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/dev/lib/factory.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/dev/lib/tools.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/gna.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/locales/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/locales/currency.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/locales/dist/language/en.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/locales/dist/language/fr.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/locales/dist/region/en.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/locales/dist/region/fr.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/locales/index.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/mime.types +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/model/entity.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/model/index.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/model/template/entityFactory.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/model/template/index.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/index.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/csrf/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/csrf/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/csrf/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/coep/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/coep/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/coep/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/coop/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/coop/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/coop/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/corp/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/corp/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/corp/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/csp/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/csp/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/csp/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/hide-powered-by/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/hide-powered-by/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/hide-powered-by/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/hsts/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/hsts/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/hsts/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/origin-agent-cluster/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/origin-agent-cluster/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/origin-agent-cluster/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/referrer-policy/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/referrer-policy/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/referrer-policy/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/x-content-type-options/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/x-content-type-options/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/x-content-type-options/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/x-dns-prefetch-control/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/x-dns-prefetch-control/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/x-dns-prefetch-control/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/x-download-options/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/x-download-options/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/x-download-options/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/x-frame-options/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/x-frame-options/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/x-frame-options/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/x-permitted-cross-domain-policies/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/x-permitted-cross-domain-policies/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/x-permitted-cross-domain-policies/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/x-xss-protection/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/x-xss-protection/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/security-headers/x-xss-protection/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/session/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/session/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/storage/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/storage/build.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/storage/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/storage/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/validator/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/validator/build.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/validator/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/validator/src/form-validator.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/plugins/lib/validator/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/server.express.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/server.isaac.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/status.codes +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/_gitignore +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/boilerplate/bundle/config/app.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/boilerplate/bundle/config/connectors.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/boilerplate/bundle/config/routing.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/boilerplate/bundle/config/settings.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/boilerplate/bundle/config/settings.server.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/boilerplate/bundle/config/templates.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/boilerplate/bundle/config/watchers.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/boilerplate/bundle/controllers/controller.content.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/boilerplate/bundle/controllers/controller.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/boilerplate/bundle/controllers/setup.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/boilerplate/bundle/index.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/boilerplate/bundle/locales/en.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/boilerplate/bundle_namespace/controllers/controller.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/boilerplate/bundle_public/css/default.css +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/boilerplate/bundle_public/css/home.css +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/boilerplate/bundle_public/css/vendor/readme.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/boilerplate/bundle_public/favicon.ico +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/boilerplate/bundle_public/js/components/x-checklist.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/boilerplate/bundle_public/js/vendor/readme.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/boilerplate/bundle_public/manifest.webmanifest +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/boilerplate/bundle_public/readme.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/boilerplate/bundle_public/sw.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/boilerplate/bundle_templates/handlers/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/boilerplate/bundle_templates/html/content/homepage.html +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/boilerplate/bundle_templates/html/includes/error-msg-noscript.html +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/boilerplate/bundle_templates/html/includes/error-msg-outdated-browser.html +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/boilerplate/bundle_templates/html/includes/x-checklist.html +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/boilerplate/bundle_templates/html/layouts/main.html +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/command/gina.bat.tpl +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/command/gina.tpl +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/conf/env.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/conf/manifest.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/conf/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/conf/statics.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/conf/templates.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/error/client/json/401.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/error/client/json/403.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/error/client/json/404.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/error/server/html/50x.html +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/error/server/json/500.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/error/server/json/503.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/core/template/extensions/logger/config.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/helpers/console.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/helpers/context.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/helpers/data/LICENSE +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/helpers/data/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/helpers/data/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/helpers/data/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/helpers/dateFormat.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/helpers/index.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/helpers/json/LICENSE +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/helpers/json/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/helpers/json/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/helpers/json/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/helpers/path.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/helpers/plugins/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/helpers/plugins/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/helpers/plugins/src/api-error.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/helpers/plugins/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/helpers/prototypes.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/helpers/task.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/helpers/text.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/admin/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/admin/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/archiver/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/archiver/build.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/archiver/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/archiver/src/dep/jszip.min.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/archiver/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/async/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/async/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/audit/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/audit-store.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/authz-gate/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/authz-gate/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cache/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cache/build.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cache/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cache/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/aliases.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/bundle/add.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/bundle/arguments.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/bundle/build.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/bundle/copy.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/bundle/cp.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/bundle/help.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/bundle/help.txt +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/bundle/inc/name-rewrite.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/bundle/list.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/bundle/man.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/bundle/mcp-start.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/bundle/mcp.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/bundle/oas.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/bundle/openapi.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/bundle/remove.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/bundle/rename.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/bundle/restart.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/bundle/rm.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/bundle/start.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/bundle/status.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/bundle/stop.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/bundle/types.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/cache/arguments.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/cache/clear.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/cache/help.txt +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/cache/stats.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/connector/add.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/connector/arguments.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/connector/help.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/connector/help.txt +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/connector/infer.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/connector/list.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/connector/migrate.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/connector/models.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/connector/remove.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/connector/rm.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/connector/test.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/container/arguments.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/container/help.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/container/help.txt +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/container/man.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/container/ps.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/container/stop.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/controller/add.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/controller/arguments.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/controller/help.txt +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/controller/inc/args.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/controller/inc/namespace.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/controller/inc/reference-rewrite.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/controller/inc/reference-scan.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/controller/inc/scaffold.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/controller/remove.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/controller/rename.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/controller/rm.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/env/add.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/env/get.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/env/help.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/env/help.txt +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/env/link-dev.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/env/list.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/env/remove.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/env/rm.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/env/set.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/env/unset.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/env/use.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/framework/add.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/framework/arguments.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/framework/build.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/framework/dot.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/framework/get.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/framework/help.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/framework/help.txt +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/framework/link-node-modules.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/framework/link.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/framework/list.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/framework/man.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/framework/msg.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/framework/open.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/framework/remove.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/framework/reset.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/framework/restart.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/framework/set.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/framework/start.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/framework/status.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/framework/stop.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/framework/update.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/framework/version.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/gina-dev.1.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/gina-framework.1.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/helper.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/i18n/add.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/i18n/arguments.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/i18n/export.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/i18n/help.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/i18n/help.txt +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/i18n/import.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/i18n/scan.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/image/_host.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/image/arguments.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/image/build.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/image/help.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/image/help.txt +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/image/list.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/image/man.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/image/rm.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/image/run.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/index.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/inspector/help.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/inspector/help.txt +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/inspector/open.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/man-render.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/minion/arguments.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/minion/help.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/minion/help.txt +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/minion/kill.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/minion/list.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/msg.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/port/help.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/port/help.txt +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/port/inc/scan.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/port/list.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/port/reset.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/port/set.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/project/add.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/project/arguments.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/project/backup.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/project/build.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/project/help.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/project/help.txt +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/project/import.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/project/list.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/project/man.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/project/move.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/project/remove.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/project/rename.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/project/restart.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/project/restore.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/project/rm.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/project/start.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/project/status.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/project/stop.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/protocol/arguments.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/protocol/help.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/protocol/help.txt +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/protocol/list.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/protocol/remove.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/protocol/set.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/scope/add.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/scope/help.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/scope/help.txt +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/scope/link-local.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/scope/link-production.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/scope/list.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/scope/remove.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/scope/rm.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/scope/use.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/secrets/arguments.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/secrets/check.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/secrets/help.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/secrets/help.txt +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/secrets/scan.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/service/help.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/service/help.txt +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/service/list.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/service/man.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/service/start.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd/view/add.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd-status-format/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cmd-status-format/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/collection/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/collection/build.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/collection/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/collection/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/config.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/connector-config/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/connector-config/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/connector-error/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/connector-error/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/connector-registry/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/connector-registry/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cron/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cron/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/cron/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/domain/LICENSE +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/domain/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/domain/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/domain/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/dto/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/dto/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/dto-pipe/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/dto-pipe/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/dto-types/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/dto-types/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/generator/index.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/i18n/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/i18n/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/image-build/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/image-build/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/inherits/LICENSE +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/inherits/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/inherits/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/inherits/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/inspector-events/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/inspector-events/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/inspector-redact/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/inspector-redact/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/instrument/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/instrument/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/job/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/job/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/job-store.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/json-config-header/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/json-config-header/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/logger/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/logger/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/logger/src/containers/default/index.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/logger/src/containers/file/lib/logrotator/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/logger/src/containers/file/lib/logrotator/index.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/logger/src/containers/mq/index.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/logger/src/containers/mq/listener.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/logger/src/helper.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/logger/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/math/index.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/mcp-dispatch/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/mcp-dispatch/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/mcp-http/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/mcp-http/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/mcp-server/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/mcp-server/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/merge/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/merge/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/merge/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/metrics/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/metrics/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/model.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/nunjucks-filters/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/nunjucks-filters/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/nunjucks-resolver/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/nunjucks-resolver/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/proc.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/release-watch/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/release-watch/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/render-cache/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/render-cache/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/render-cache-store.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/routing/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/routing/build.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/routing/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/routing/src/radix.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/routing-introspect/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/routing-introspect/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/secrets/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/secrets/src/backends/env.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/secrets/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/session-store.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/shell.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/state.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/swig-filters/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/swig-filters/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/swig-resolver/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/swig-resolver/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/template-loaders/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/template-loaders/src/loaders/http.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/template-loaders/src/loaders/memory.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/template-loaders/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/url/README.md +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/url/index.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/url/routing.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/uuid/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/uuid/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/validator.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/watcher/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/watcher/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/ws-framing/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/ws-framing/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/ws-query/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/ws-query/src/main.js +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/ws-session/package.json +0 -0
- /package/framework/{v0.5.26 → v0.6.0}/lib/ws-session/src/main.js +0 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "authn",
|
|
3
|
+
"description": "Authentication hardening primitives (#COMPLY3): password hashing + verification, password-policy validation, account lockout, and TOTP helpers. Hooks and helpers — never an identity provider",
|
|
4
|
+
"version": "0.0.1",
|
|
5
|
+
"private": true,
|
|
6
|
+
"main": "src/main"
|
|
7
|
+
}
|
|
@@ -0,0 +1,615 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of the gina package.
|
|
3
|
+
* Copyright (c) 2009-2026 Rhinostone <contact@gina.io>
|
|
4
|
+
*
|
|
5
|
+
* For the full copyright and license information, please view the LICENSE
|
|
6
|
+
* file that was distributed with this source code.
|
|
7
|
+
*/
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Account lockout (#COMPLY3) — the credential-stuffing brake.
|
|
12
|
+
*
|
|
13
|
+
* Counts consecutive failed attempts against a caller-chosen KEY and refuses
|
|
14
|
+
* further attempts once a threshold is crossed, for a fixed window. The key is
|
|
15
|
+
* the bundle's to choose: a user id, an email, an `email + ':' + ip` pair. Gina
|
|
16
|
+
* never derives it, because gina does not own the user record.
|
|
17
|
+
*
|
|
18
|
+
* **Distinct from rate limiting.** Lockout is per-ACCOUNT and counts credential
|
|
19
|
+
* failures — it stops an attacker working one account with many passwords.
|
|
20
|
+
* Rate limiting is per-CLIENT and counts requests — it stops an attacker
|
|
21
|
+
* working many accounts from one source. They defend different axes and neither
|
|
22
|
+
* substitutes for the other; gina ships this one, and request-rate limiting is
|
|
23
|
+
* tracked separately on the roadmap.
|
|
24
|
+
*
|
|
25
|
+
* **Defaults follow PCI-DSS v4.0.1 §8.3.4** — lock after not more than 10
|
|
26
|
+
* invalid attempts, for a minimum of 30 minutes (or until identity is confirmed
|
|
27
|
+
* out of band, which is {@link Lockout#reset}).
|
|
28
|
+
*
|
|
29
|
+
* **Normalise the key, or the threshold multiplies.** Counters are indexed by
|
|
30
|
+
* the exact string given. If the key comes from user input — an email typed
|
|
31
|
+
* into a form — then `a@x.com`, `A@x.com` and `a@X.com` are three separate
|
|
32
|
+
* counters, and an attacker gets the threshold once per spelling. Measured:
|
|
33
|
+
* three failures across those spellings against a threshold of three left the
|
|
34
|
+
* account unlocked. Pass `normalizeKey` (or lower-case it yourself) whenever
|
|
35
|
+
* the key is user-supplied. There is no safe default here — a user id or an
|
|
36
|
+
* opaque token may legitimately be case-sensitive, so gina will not guess.
|
|
37
|
+
*
|
|
38
|
+
* **State lives in memory by default**, which is per-process: two replicas keep
|
|
39
|
+
* independent counters, so an attacker distributing attempts across N replicas
|
|
40
|
+
* gets N times the threshold. That is a real and documented degradation, not a
|
|
41
|
+
* silent one — pass a shared `store` for multi-replica correctness. The store
|
|
42
|
+
* contract is deliberately the callback shape the job and audit store seams
|
|
43
|
+
* already use.
|
|
44
|
+
*
|
|
45
|
+
* **The memory store grows with distinct keys.** Every key an attacker invents
|
|
46
|
+
* costs an entry until its window expires (measured: 5000 keys, 5000 entries),
|
|
47
|
+
* so hostile traffic can inflate it. It is deliberately NOT capped: evicting
|
|
48
|
+
* entries under pressure would let an attacker flush a victim's counter by
|
|
49
|
+
* flooding, turning a memory bound into a lockout bypass — strictly worse than
|
|
50
|
+
* the memory it saves. Bound key CREATION upstream with request-rate limiting,
|
|
51
|
+
* or use a persistent store with its own eviction policy.
|
|
52
|
+
*
|
|
53
|
+
* @module lib/authn/lockout
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* var lockout = require('gina').lib.authn.createLockout();
|
|
57
|
+
*
|
|
58
|
+
* lockout.check(email, function (err, state) {
|
|
59
|
+
* if (state.locked) {
|
|
60
|
+
* return self.renderJSON({ error: 'too many attempts', retryAt: state.retryAt });
|
|
61
|
+
* }
|
|
62
|
+
* verify(function (ok) {
|
|
63
|
+
* if (!ok) { return lockout.recordFailure(email, function () { deny(); }); }
|
|
64
|
+
* lockout.recordSuccess(email, function () { self.req.login(user, done); });
|
|
65
|
+
* });
|
|
66
|
+
* });
|
|
67
|
+
*/
|
|
68
|
+
|
|
69
|
+
var DEFAULT_MAX_ATTEMPTS = 10; // PCI-DSS 8.3.4: "not more than 10"
|
|
70
|
+
var DEFAULT_LOCK_MS = 30 * 60000; // PCI-DSS 8.3.4: "minimum 30 minutes"
|
|
71
|
+
var DEFAULT_WINDOW_MS = 30 * 60000; // failures older than this stop counting
|
|
72
|
+
var DEFAULT_SWEEP_MS = 5 * 60000;
|
|
73
|
+
/** @constant {number} Upper bound on a lockout key, in characters. @inner @private */
|
|
74
|
+
var MAX_KEY_LENGTH = 512;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Build the default in-process store.
|
|
78
|
+
*
|
|
79
|
+
* Entries expire lazily on read (so a stale record can never authorise or
|
|
80
|
+
* refuse anything) and are swept periodically only to bound memory. The sweep
|
|
81
|
+
* timer is `unref`'d — it must never be the reason a process stays alive.
|
|
82
|
+
*
|
|
83
|
+
* @param {number} sweepMs - sweep interval in ms.
|
|
84
|
+
* @returns {{get: function, set: function, del: function, close: function, _map: Map}}
|
|
85
|
+
* @inner
|
|
86
|
+
* @private
|
|
87
|
+
*/
|
|
88
|
+
function createMemoryStore(sweepMs) {
|
|
89
|
+
var map = new Map();
|
|
90
|
+
var timer = null;
|
|
91
|
+
|
|
92
|
+
function alive(entry, now) {
|
|
93
|
+
if (!entry) {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
if (typeof entry.expiresAt === 'number' && entry.expiresAt <= now) {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
return entry;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function arm() {
|
|
103
|
+
if (timer) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
timer = setInterval(function () {
|
|
107
|
+
var now = Date.now();
|
|
108
|
+
map.forEach(function (entry, key) {
|
|
109
|
+
if (!alive(entry, now)) {
|
|
110
|
+
map.delete(key);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
if (map.size === 0 && timer) {
|
|
114
|
+
clearInterval(timer);
|
|
115
|
+
timer = null;
|
|
116
|
+
}
|
|
117
|
+
}, sweepMs);
|
|
118
|
+
if (timer && typeof timer.unref === 'function') {
|
|
119
|
+
timer.unref();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return {
|
|
124
|
+
get: function (key, cb) {
|
|
125
|
+
var entry = alive(map.get(key), Date.now());
|
|
126
|
+
if (!entry) {
|
|
127
|
+
map.delete(key);
|
|
128
|
+
}
|
|
129
|
+
process.nextTick(function () { cb(null, entry || null); });
|
|
130
|
+
},
|
|
131
|
+
set: function (key, entry, cb) {
|
|
132
|
+
map.set(key, entry);
|
|
133
|
+
arm();
|
|
134
|
+
process.nextTick(function () { cb(null); });
|
|
135
|
+
},
|
|
136
|
+
del: function (key, cb) {
|
|
137
|
+
map.delete(key);
|
|
138
|
+
process.nextTick(function () { cb(null); });
|
|
139
|
+
},
|
|
140
|
+
close: function () {
|
|
141
|
+
if (timer) {
|
|
142
|
+
clearInterval(timer);
|
|
143
|
+
timer = null;
|
|
144
|
+
}
|
|
145
|
+
map.clear();
|
|
146
|
+
},
|
|
147
|
+
_map: map
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Validate a caller-supplied store against the contract.
|
|
153
|
+
*
|
|
154
|
+
* @param {object} store
|
|
155
|
+
* @returns {void}
|
|
156
|
+
* @throws {Error} when a required method is missing.
|
|
157
|
+
* @inner
|
|
158
|
+
* @private
|
|
159
|
+
*/
|
|
160
|
+
function assertStore(store) {
|
|
161
|
+
[ 'get', 'set', 'del' ].forEach(function (m) {
|
|
162
|
+
if (typeof store[m] !== 'function') {
|
|
163
|
+
throw new Error('[gina authn] lockout store must implement get(key, cb), set(key, entry, cb) and del(key, cb) — missing: ' + m);
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Serialize operations on one key.
|
|
170
|
+
*
|
|
171
|
+
* The counter update is a read-modify-write across an asynchronous store call,
|
|
172
|
+
* and that is not atomic: without this, N failures arriving in the same tick all
|
|
173
|
+
* read the same entry, all compute `attempts = 1`, and all write it — so an
|
|
174
|
+
* attacker who sends attempts CONCURRENTLY rather than sequentially never
|
|
175
|
+
* crosses the threshold. Measured before this guard existed: 20 concurrent
|
|
176
|
+
* failures against a threshold of 5 recorded 1 attempt and did not lock.
|
|
177
|
+
*
|
|
178
|
+
* Queued FIFO per key, so one account under attack cannot delay another. The
|
|
179
|
+
* queue is per-key and drains to nothing, so it holds no memory between bursts.
|
|
180
|
+
*
|
|
181
|
+
* @param {Map} chains - the engine's per-key queue map.
|
|
182
|
+
* @param {string} key
|
|
183
|
+
* @param {function} fn - receives `release`, must call it exactly once.
|
|
184
|
+
* @returns {void}
|
|
185
|
+
* @inner
|
|
186
|
+
* @private
|
|
187
|
+
*/
|
|
188
|
+
function withKeyLock(chains, key, fn) {
|
|
189
|
+
function run(f) {
|
|
190
|
+
var released = false;
|
|
191
|
+
function release() {
|
|
192
|
+
if (released) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
released = true;
|
|
196
|
+
var q = chains.get(key);
|
|
197
|
+
if (q && q.length > 0) {
|
|
198
|
+
run(q.shift());
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
chains.delete(key);
|
|
202
|
+
}
|
|
203
|
+
// A store that throws SYNCHRONOUSLY would otherwise never reach its
|
|
204
|
+
// callback, so release would never fire: the key kept a live queue and
|
|
205
|
+
// every later operation on it waited forever — the login request hung
|
|
206
|
+
// with no response AND the counter froze, so the account could never
|
|
207
|
+
// lock again. Store recovery did not clear it. Releasing before
|
|
208
|
+
// rethrowing keeps the failure loud without stranding the key.
|
|
209
|
+
try {
|
|
210
|
+
f(release);
|
|
211
|
+
} catch (err) {
|
|
212
|
+
release();
|
|
213
|
+
throw err;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
var queue = chains.get(key);
|
|
218
|
+
if (queue) {
|
|
219
|
+
queue.push(fn);
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
chains.set(key, []);
|
|
223
|
+
run(fn);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Reject a key that cannot index a counter.
|
|
228
|
+
*
|
|
229
|
+
* @param {*} key
|
|
230
|
+
* @returns {?Error}
|
|
231
|
+
* @inner
|
|
232
|
+
* @private
|
|
233
|
+
*/
|
|
234
|
+
function checkKey(key) {
|
|
235
|
+
if (typeof key !== 'string' || key.length === 0) {
|
|
236
|
+
return new Error('[gina authn] lockout key must be a non-empty string (a user id, an email, or an `email:ip` pair — your choice, gina does not derive it)');
|
|
237
|
+
}
|
|
238
|
+
// The key is attacker-supplied in the shape the docs suggest (an email), it
|
|
239
|
+
// is retained for the whole window, and it is written verbatim into the
|
|
240
|
+
// auth.lockout audit record — so an uncapped key inflates both the store and
|
|
241
|
+
// the trail. Measured uncapped: a 1,000,006-character key was accepted.
|
|
242
|
+
if (key.length > MAX_KEY_LENGTH) {
|
|
243
|
+
return new Error('[gina authn] lockout key exceeds ' + MAX_KEY_LENGTH + ' characters — reject it in your form validation before it reaches the lockout engine');
|
|
244
|
+
}
|
|
245
|
+
return null;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* @typedef {object} LockoutState
|
|
250
|
+
* @property {boolean} locked - true when further attempts must be refused.
|
|
251
|
+
* @property {number} attempts - consecutive failures currently counted.
|
|
252
|
+
* @property {number} remaining - attempts left before locking (0 once locked).
|
|
253
|
+
* @property {?number} retryAt - epoch ms when the lock lifts, or `null` when not locked.
|
|
254
|
+
*/
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Create a lockout engine.
|
|
258
|
+
*
|
|
259
|
+
* @param {object} [options]
|
|
260
|
+
* @param {number} [options.maxAttempts=10] - consecutive failures before locking.
|
|
261
|
+
* @param {number} [options.lockMs=1800000] - how long a lock holds (30 min).
|
|
262
|
+
* @param {number} [options.windowMs=1800000] - failures older than this stop counting.
|
|
263
|
+
* @param {number} [options.sweepMs=300000] - memory-store sweep interval.
|
|
264
|
+
* @param {object} [options.store] - shared store; `{get, set, del[, close]}`, callback-shaped.
|
|
265
|
+
* @param {function} [options.normalizeKey] - `fn(key) -> key`, applied before every lookup. Use it whenever the key is user-supplied, or case variance multiplies the threshold.
|
|
266
|
+
* @param {boolean} [options.audit=true] - emit an `auth.lockout` audit record on the transition into locked.
|
|
267
|
+
* @returns {object} the engine — `check` / `recordFailure` / `recordSuccess` / `reset` / `close`.
|
|
268
|
+
* @throws {Error} on an invalid option or an incomplete store.
|
|
269
|
+
* @memberof module:lib/authn
|
|
270
|
+
*
|
|
271
|
+
* @example <caption>Multi-replica: back it with a shared store</caption>
|
|
272
|
+
* var lockout = lib.authn.createLockout({ store: myRedisBackedStore });
|
|
273
|
+
*
|
|
274
|
+
* @example <caption>Keying on an email — normalise, or the threshold multiplies</caption>
|
|
275
|
+
* var lockout = lib.authn.createLockout({
|
|
276
|
+
* normalizeKey: function (k) { return k.trim().toLowerCase(); }
|
|
277
|
+
* });
|
|
278
|
+
*/
|
|
279
|
+
function createLockout(options) {
|
|
280
|
+
options = options || {};
|
|
281
|
+
|
|
282
|
+
function num(name, fallback) {
|
|
283
|
+
if (typeof options[name] === 'undefined') {
|
|
284
|
+
return fallback;
|
|
285
|
+
}
|
|
286
|
+
var v = options[name];
|
|
287
|
+
if (typeof v !== 'number' || !isFinite(v) || v <= 0) {
|
|
288
|
+
throw new Error('[gina authn] createLockout: `' + name + '` must be a positive number — got: ' + JSON.stringify(v));
|
|
289
|
+
}
|
|
290
|
+
return v;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
var maxAttempts = num('maxAttempts', DEFAULT_MAX_ATTEMPTS);
|
|
294
|
+
var lockMs = num('lockMs', DEFAULT_LOCK_MS);
|
|
295
|
+
var windowMs = num('windowMs', DEFAULT_WINDOW_MS);
|
|
296
|
+
var sweepMs = num('sweepMs', DEFAULT_SWEEP_MS);
|
|
297
|
+
var auditOn = options.audit !== false;
|
|
298
|
+
|
|
299
|
+
if (Math.floor(maxAttempts) !== maxAttempts) {
|
|
300
|
+
throw new Error('[gina authn] createLockout: `maxAttempts` must be a whole number — got: ' + JSON.stringify(options.maxAttempts));
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
var normalizeKeyWarned = false;
|
|
304
|
+
var normalizeKey = options.normalizeKey;
|
|
305
|
+
if (typeof normalizeKey !== 'undefined' && typeof normalizeKey !== 'function') {
|
|
306
|
+
throw new Error('[gina authn] createLockout: `normalizeKey` must be a function — got: ' + JSON.stringify(options.normalizeKey));
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Apply the caller's key normaliser, if any. A normaliser that throws or
|
|
311
|
+
* returns a non-string is ignored rather than allowed to break a login.
|
|
312
|
+
*
|
|
313
|
+
* @param {string} key
|
|
314
|
+
* @returns {string}
|
|
315
|
+
* @inner
|
|
316
|
+
* @private
|
|
317
|
+
*/
|
|
318
|
+
function norm(key) {
|
|
319
|
+
if (!normalizeKey) {
|
|
320
|
+
return key;
|
|
321
|
+
}
|
|
322
|
+
try {
|
|
323
|
+
var out = normalizeKey(key);
|
|
324
|
+
return (typeof out === 'string' && out.length > 0) ? out : key;
|
|
325
|
+
} catch (err) {
|
|
326
|
+
// Falling back to the raw key keeps a buggy normaliser from breaking
|
|
327
|
+
// logins — but silently, it also restores the split-counter
|
|
328
|
+
// multiplier the normaliser existed to close. Say so once.
|
|
329
|
+
if (!normalizeKeyWarned) {
|
|
330
|
+
normalizeKeyWarned = true;
|
|
331
|
+
try {
|
|
332
|
+
console.error('[gina authn] lockout normalizeKey threw — falling back to the RAW key, so case/whitespace variants of it now count separately: ' + (err.message || err));
|
|
333
|
+
} catch (e2) { /* never escalate */ }
|
|
334
|
+
}
|
|
335
|
+
return key;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
var store = options.store;
|
|
340
|
+
if (store) {
|
|
341
|
+
assertStore(store);
|
|
342
|
+
} else {
|
|
343
|
+
store = createMemoryStore(sweepMs);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Per-key operation queues — see {@link withKeyLock}.
|
|
348
|
+
*
|
|
349
|
+
* In-process only. With a SHARED store across replicas each process
|
|
350
|
+
* serializes its own operations, so concurrent failures can still be lost
|
|
351
|
+
* BETWEEN replicas: the ceiling degrades to roughly `maxAttempts` per
|
|
352
|
+
* replica, the same bound the memory store already carries. A store whose
|
|
353
|
+
* backend offers an atomic increment closes that too; the contract does not
|
|
354
|
+
* require one, so this is documented rather than assumed away.
|
|
355
|
+
*
|
|
356
|
+
* @type {Map<string, Array<function>>}
|
|
357
|
+
* @inner
|
|
358
|
+
* @private
|
|
359
|
+
*/
|
|
360
|
+
var chains = new Map();
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Project a stored entry into the caller-facing state.
|
|
364
|
+
*
|
|
365
|
+
* @param {?object} entry
|
|
366
|
+
* @param {number} now
|
|
367
|
+
* @returns {LockoutState}
|
|
368
|
+
* @inner
|
|
369
|
+
* @private
|
|
370
|
+
*/
|
|
371
|
+
function toState(entry, now) {
|
|
372
|
+
if (!entry) {
|
|
373
|
+
return { locked: false, attempts: 0, remaining: maxAttempts, retryAt: null };
|
|
374
|
+
}
|
|
375
|
+
if (typeof entry.lockedUntil === 'number' && entry.lockedUntil > now) {
|
|
376
|
+
return { locked: true, attempts: entry.attempts, remaining: 0, retryAt: entry.lockedUntil };
|
|
377
|
+
}
|
|
378
|
+
// The lock has lapsed, or the last failure fell out of the window: the
|
|
379
|
+
// counter starts over. Reading a lapsed entry must never report locked.
|
|
380
|
+
if (typeof entry.lockedUntil === 'number' || (now - entry.lastFailureAt) > windowMs) {
|
|
381
|
+
return { locked: false, attempts: 0, remaining: maxAttempts, retryAt: null };
|
|
382
|
+
}
|
|
383
|
+
return {
|
|
384
|
+
locked : false,
|
|
385
|
+
attempts : entry.attempts,
|
|
386
|
+
remaining : Math.max(0, maxAttempts - entry.attempts),
|
|
387
|
+
retryAt : null
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Emit the lockout audit record. Wholly contained — an audit failure must
|
|
393
|
+
* never change an authentication outcome (the `emitAuthzDenied` shape).
|
|
394
|
+
*
|
|
395
|
+
* @param {string} key
|
|
396
|
+
* @param {object} entry
|
|
397
|
+
* @returns {void}
|
|
398
|
+
* @inner
|
|
399
|
+
* @private
|
|
400
|
+
*/
|
|
401
|
+
function emitLocked(key, entry) {
|
|
402
|
+
if (!auditOn) {
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
try {
|
|
406
|
+
var audit = require('../../audit');
|
|
407
|
+
if (!audit || typeof audit.write !== 'function' || (typeof audit.isEnabled === 'function' && !audit.isEnabled())) {
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
// The key IS the record's value here — "which account was locked out"
|
|
411
|
+
// is the question an assessor asks (PCI-DSS 10.2.4, invalid logical-
|
|
412
|
+
// access attempts). It is usually an email or a user id; that
|
|
413
|
+
// identifiability is the point, and the audit trail is already the
|
|
414
|
+
// place where actor identity is recorded.
|
|
415
|
+
audit.write('auth.lockout', {
|
|
416
|
+
meta: {
|
|
417
|
+
key : key,
|
|
418
|
+
attempts : entry.attempts,
|
|
419
|
+
lockedUntil : entry.lockedUntil
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
} catch (err) {
|
|
423
|
+
try {
|
|
424
|
+
console.error('[gina authn] lockout audit event failed (the lockout itself is unaffected): ' + (err.message || err));
|
|
425
|
+
} catch (e2) { /* never escalate */ }
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
return {
|
|
430
|
+
/**
|
|
431
|
+
* Read the current state without recording anything.
|
|
432
|
+
*
|
|
433
|
+
* Call it BEFORE verifying a credential, so a locked account never
|
|
434
|
+
* reaches the KDF.
|
|
435
|
+
*
|
|
436
|
+
* @param {string} key - the account key.
|
|
437
|
+
* @param {function} cb - `cb(err, state)`.
|
|
438
|
+
* @returns {void}
|
|
439
|
+
*/
|
|
440
|
+
check: function (key, cb) {
|
|
441
|
+
if (typeof cb !== 'function') {
|
|
442
|
+
throw new Error('[gina authn] lockout.check(key, cb) requires a callback function');
|
|
443
|
+
}
|
|
444
|
+
var keyErr = checkKey(key);
|
|
445
|
+
if (keyErr) {
|
|
446
|
+
return process.nextTick(function () { cb(keyErr); });
|
|
447
|
+
}
|
|
448
|
+
store.get(norm(key), function (err, entry) {
|
|
449
|
+
if (err) {
|
|
450
|
+
return cb(err);
|
|
451
|
+
}
|
|
452
|
+
cb(null, toState(entry, Date.now()));
|
|
453
|
+
});
|
|
454
|
+
},
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
* Record one failed attempt.
|
|
458
|
+
*
|
|
459
|
+
* Returns the state AFTER the failure, so a caller can surface
|
|
460
|
+
* `remaining` or `retryAt` immediately. Emits one `auth.lockout` audit
|
|
461
|
+
* record on the transition into locked — not per attempt.
|
|
462
|
+
*
|
|
463
|
+
* @param {string} key - the account key.
|
|
464
|
+
* @param {function} cb - `cb(err, state)`.
|
|
465
|
+
* @returns {void}
|
|
466
|
+
*/
|
|
467
|
+
recordFailure: function (key, cb) {
|
|
468
|
+
if (typeof cb !== 'function') {
|
|
469
|
+
throw new Error('[gina authn] lockout.recordFailure(key, cb) requires a callback function');
|
|
470
|
+
}
|
|
471
|
+
var keyErr = checkKey(key);
|
|
472
|
+
if (keyErr) {
|
|
473
|
+
return process.nextTick(function () { cb(keyErr); });
|
|
474
|
+
}
|
|
475
|
+
key = norm(key);
|
|
476
|
+
withKeyLock(chains, key, function (release) {
|
|
477
|
+
var now = Date.now();
|
|
478
|
+
store.get(key, function (err, entry) {
|
|
479
|
+
if (err) {
|
|
480
|
+
release();
|
|
481
|
+
return cb(err);
|
|
482
|
+
}
|
|
483
|
+
// An ACTIVE lock is terminal until it lapses: recording over it
|
|
484
|
+
// would rebuild the entry with lockedUntil:null and free the
|
|
485
|
+
// account early. Measured before this guard, with lockMs 60min
|
|
486
|
+
// and windowMs 30min, one failure at t+31min turned
|
|
487
|
+
// {locked:true} into {locked:false, attempts:1} — so the
|
|
488
|
+
// effective lock was silently min(lockMs, windowMs) and a caller
|
|
489
|
+
// that records every failure without consulting check() first
|
|
490
|
+
// (which the API invites — recordFailure documents no
|
|
491
|
+
// precondition) got 43x the intended guesses at lockMs=24h.
|
|
492
|
+
if (entry && typeof entry.lockedUntil === 'number' && entry.lockedUntil > now) {
|
|
493
|
+
release();
|
|
494
|
+
return cb(null, toState(entry, now));
|
|
495
|
+
}
|
|
496
|
+
var attempts = 1;
|
|
497
|
+
if (entry
|
|
498
|
+
&& typeof entry.lastFailureAt === 'number'
|
|
499
|
+
&& (now - entry.lastFailureAt) <= windowMs
|
|
500
|
+
&& !(typeof entry.lockedUntil === 'number' && entry.lockedUntil <= now)
|
|
501
|
+
) {
|
|
502
|
+
attempts = entry.attempts + 1;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
var fresh = {
|
|
506
|
+
attempts : attempts,
|
|
507
|
+
lastFailureAt : now,
|
|
508
|
+
lockedUntil : null,
|
|
509
|
+
expiresAt : now + windowMs
|
|
510
|
+
};
|
|
511
|
+
var justLocked = false;
|
|
512
|
+
if (attempts >= maxAttempts) {
|
|
513
|
+
fresh.lockedUntil = now + lockMs;
|
|
514
|
+
fresh.expiresAt = fresh.lockedUntil;
|
|
515
|
+
// Only a transition emits: an attacker hammering a locked
|
|
516
|
+
// account must not be able to flood the trail.
|
|
517
|
+
justLocked = !(entry && typeof entry.lockedUntil === 'number' && entry.lockedUntil > now);
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
store.set(key, fresh, function (setErr) {
|
|
521
|
+
// Release BEFORE the callback: the next queued attempt must
|
|
522
|
+
// not wait on consumer code, and a consumer that throws must
|
|
523
|
+
// not strand the key's queue forever.
|
|
524
|
+
release();
|
|
525
|
+
if (setErr) {
|
|
526
|
+
return cb(setErr);
|
|
527
|
+
}
|
|
528
|
+
if (justLocked) {
|
|
529
|
+
emitLocked(key, fresh);
|
|
530
|
+
}
|
|
531
|
+
cb(null, toState(fresh, now));
|
|
532
|
+
});
|
|
533
|
+
});
|
|
534
|
+
});
|
|
535
|
+
},
|
|
536
|
+
|
|
537
|
+
/**
|
|
538
|
+
* Clear the counter after a successful authentication.
|
|
539
|
+
*
|
|
540
|
+
* @param {string} key - the account key.
|
|
541
|
+
* @param {function} cb - `cb(err)`.
|
|
542
|
+
* @returns {void}
|
|
543
|
+
*/
|
|
544
|
+
recordSuccess: function (key, cb) {
|
|
545
|
+
if (typeof cb !== 'function') {
|
|
546
|
+
throw new Error('[gina authn] lockout.recordSuccess(key, cb) requires a callback function');
|
|
547
|
+
}
|
|
548
|
+
var keyErr = checkKey(key);
|
|
549
|
+
if (keyErr) {
|
|
550
|
+
return process.nextTick(function () { cb(keyErr); });
|
|
551
|
+
}
|
|
552
|
+
// Serialized with recordFailure: a delete that lands between a
|
|
553
|
+
// concurrent failure's read and its write would otherwise be
|
|
554
|
+
// resurrected by that write.
|
|
555
|
+
key = norm(key);
|
|
556
|
+
withKeyLock(chains, key, function (release) {
|
|
557
|
+
store.del(key, function (err) {
|
|
558
|
+
release();
|
|
559
|
+
cb(err);
|
|
560
|
+
});
|
|
561
|
+
});
|
|
562
|
+
},
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* Lift a lock administratively — the "until the user's identity is
|
|
566
|
+
* confirmed" half of PCI-DSS 8.3.4.
|
|
567
|
+
*
|
|
568
|
+
* @param {string} key - the account key.
|
|
569
|
+
* @param {function} cb - `cb(err)`.
|
|
570
|
+
* @returns {void}
|
|
571
|
+
*/
|
|
572
|
+
reset: function (key, cb) {
|
|
573
|
+
if (typeof cb !== 'function') {
|
|
574
|
+
throw new Error('[gina authn] lockout.reset(key, cb) requires a callback function');
|
|
575
|
+
}
|
|
576
|
+
var keyErr = checkKey(key);
|
|
577
|
+
if (keyErr) {
|
|
578
|
+
return process.nextTick(function () { cb(keyErr); });
|
|
579
|
+
}
|
|
580
|
+
key = norm(key);
|
|
581
|
+
withKeyLock(chains, key, function (release) {
|
|
582
|
+
store.del(key, function (err) {
|
|
583
|
+
release();
|
|
584
|
+
cb(err);
|
|
585
|
+
});
|
|
586
|
+
});
|
|
587
|
+
},
|
|
588
|
+
|
|
589
|
+
/**
|
|
590
|
+
* Release the memory store's sweep timer. No-op for a caller-supplied
|
|
591
|
+
* store that exposes no `close`.
|
|
592
|
+
*
|
|
593
|
+
* @returns {void}
|
|
594
|
+
*/
|
|
595
|
+
close: function () {
|
|
596
|
+
if (typeof store.close === 'function') {
|
|
597
|
+
store.close();
|
|
598
|
+
}
|
|
599
|
+
},
|
|
600
|
+
|
|
601
|
+
/** @private test seam */
|
|
602
|
+
_store: store,
|
|
603
|
+
/** @private test seam — the per-key queues; must drain to empty. */
|
|
604
|
+
_chains: chains,
|
|
605
|
+
/** @private test seam */
|
|
606
|
+
_config: { maxAttempts: maxAttempts, lockMs: lockMs, windowMs: windowMs }
|
|
607
|
+
};
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
module.exports = {
|
|
611
|
+
createLockout : createLockout,
|
|
612
|
+
_createMemoryStore : createMemoryStore,
|
|
613
|
+
_DEFAULT_MAX_ATTEMPTS : DEFAULT_MAX_ATTEMPTS,
|
|
614
|
+
_DEFAULT_LOCK_MS : DEFAULT_LOCK_MS
|
|
615
|
+
};
|