claude-flow-novice 2.15.11 → 2.16.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/.claude/cfn-extras/agents/cfn-v3-coordinator.md +517 -0
- package/.claude/commands/cfn-loop-cli.md +158 -464
- package/.claude/commands/cfn-loop-trigger.md +114 -0
- package/.claude/hooks/cfn-invoke-post-edit-ts.sh +100 -0
- package/.claude/hooks/cfn-invoke-post-edit-ts.sh.backup +78 -0
- package/.claude/hooks/cfn-invoke-post-edit.sh +22 -0
- package/.claude/hooks/cfn-invoke-post-edit.sh.backup +87 -0
- package/.claude/hooks/cfn-invoke-pre-edit-ts.sh +116 -0
- package/.claude/hooks/cfn-invoke-pre-edit-ts.sh.backup +94 -0
- package/.claude/hooks/cfn-invoke-pre-edit.sh +22 -0
- package/.claude/hooks/cfn-invoke-pre-edit.sh.backup +88 -0
- package/.claude/skills/cfn-agent-spawning/SKILL.md +48 -1
- package/.claude/skills/cfn-agent-spawning/SKILL.md.backup +135 -0
- package/.claude/skills/cfn-agent-spawning/TYPESCRIPT_MIGRATION.md +567 -0
- package/.claude/skills/cfn-agent-spawning/check-dependencies.sh +22 -0
- package/.claude/skills/{cfn-redis-coordination/check-dependencies.sh → cfn-agent-spawning/check-dependencies.sh.backup} +3 -5
- package/.claude/skills/cfn-agent-spawning/get-agent-provider-env.sh +22 -0
- package/.claude/skills/cfn-agent-spawning/get-agent-provider-env.sh.backup +127 -0
- package/.claude/skills/cfn-agent-spawning/parse-agent-provider.sh +22 -0
- package/.claude/skills/cfn-agent-spawning/parse-agent-provider.sh.backup +59 -0
- package/.claude/skills/cfn-agent-spawning/spawn-agent-wrapper.sh +63 -0
- package/.claude/skills/cfn-agent-spawning/spawn-agent-wrapper.sh.backup +41 -0
- package/.claude/skills/cfn-agent-spawning/spawn-agent.sh +26 -1
- package/.claude/skills/cfn-agent-spawning/spawn-templates.sh +22 -0
- package/.claude/skills/cfn-agent-spawning/spawn-templates.sh.backup +613 -0
- package/.claude/skills/cfn-agent-spawning/spawn-worker.sh +22 -0
- package/.claude/skills/cfn-agent-spawning/spawn-worker.sh.backup +176 -0
- package/.claude/skills/cfn-loop-orchestration/.backups/unknown/1763619700_33aff4a69b99159e4e849107ebc4d09f/metadata.json +8 -0
- package/.claude/skills/cfn-loop-orchestration/.backups/unknown/1763619700_33aff4a69b99159e4e849107ebc4d09f/original +271 -0
- package/.claude/skills/cfn-loop-orchestration/.backups/unknown/1763619700_33aff4a69b99159e4e849107ebc4d09f/revert.sh +7 -0
- package/.claude/skills/cfn-loop-orchestration/.backups/unknown/1763671642_06496e8c399a79db08167cc00ed4b31e/metadata.json +8 -0
- package/.claude/skills/cfn-loop-orchestration/.backups/unknown/1763671642_06496e8c399a79db08167cc00ed4b31e/original +325 -0
- package/.claude/skills/cfn-loop-orchestration/.backups/unknown/1763671642_06496e8c399a79db08167cc00ed4b31e/revert.sh +7 -0
- package/.claude/skills/cfn-loop-orchestration/CLI_IMPLEMENTATION_SUMMARY.md +330 -0
- package/.claude/skills/cfn-loop-orchestration/CONFIGURATION_IMPROVEMENTS.md +318 -0
- package/.claude/skills/cfn-loop-orchestration/CONTEXT_LOOKUP_MIGRATION.md +308 -0
- package/.claude/skills/cfn-loop-orchestration/CONTEXT_LOOKUP_QUICK_START.md +378 -0
- package/.claude/skills/cfn-loop-orchestration/E2E_VALIDATION_REPORT.md +262 -0
- package/.claude/skills/cfn-loop-orchestration/IMPLEMENTATION_SUMMARY.md +319 -519
- package/.claude/skills/cfn-loop-orchestration/NORTH_STAR_E2E_REPORT.md +299 -0
- package/.claude/skills/cfn-loop-orchestration/NORTH_STAR_EXECUTION_SUMMARY.md +403 -0
- package/.claude/skills/cfn-loop-orchestration/NORTH_STAR_INDEX.md +323 -0
- package/.claude/skills/cfn-loop-orchestration/SKILL.md +159 -48
- package/.claude/skills/cfn-loop-orchestration/SPAWN_AGENTS_IMPLEMENTATION.md +188 -0
- package/.claude/skills/cfn-loop-orchestration/TEST_COVERAGE_REPORT.md +335 -0
- package/.claude/skills/cfn-loop-orchestration/TEST_COVERAGE_SUMMARY.md +456 -0
- package/.claude/skills/cfn-loop-orchestration/TYPESCRIPT_INTEGRATION_REPORT.md +709 -0
- package/.claude/skills/cfn-loop-orchestration/TYPESCRIPT_INTEGRATION_SUMMARY.md +257 -0
- package/.claude/skills/cfn-loop-orchestration/VALIDATION_REPORT.md +572 -0
- package/.claude/skills/cfn-loop-orchestration/VALIDATION_SUMMARY.txt +196 -0
- package/.claude/skills/cfn-loop-orchestration/VALIDATOR_MODULE_GUIDE.md +526 -0
- package/.claude/skills/cfn-loop-orchestration/archive/legacy-bash/README.md +167 -0
- package/.claude/skills/cfn-loop-orchestration/archive/legacy-bash/orchestrate-enhanced.sh +548 -0
- package/{claude-assets/skills/cfn-loop-orchestration → .claude/skills/cfn-loop-orchestration/archive/legacy-bash}/orchestrate-wrapper.sh +11 -1
- package/.claude/skills/cfn-loop-orchestration/archive/legacy-bash/orchestrate.sh +182 -0
- package/.claude/skills/cfn-loop-orchestration/e2e-validation-fixed.js +240 -0
- package/.claude/skills/cfn-loop-orchestration/e2e-validation.js +213 -0
- package/.claude/skills/cfn-loop-orchestration/package-lock.json +3 -0
- package/.claude/skills/cfn-loop-orchestration/package.json +4 -0
- package/.claude/skills/cfn-loop-orchestration/run-north-star-e2e.ts +210 -0
- package/.claude/skills/cfn-loop-orchestration/src/cli/orchestrator-cli.ts +396 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/CONFIDENCE_AGGREGATOR.md +564 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/CONFIDENCE_AGGREGATOR_QUICK_REF.md +241 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/CONTEXT_INJECTOR_IMPLEMENTATION.md +375 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/CONTEXT_INJECTOR_QUICK_REFERENCE.md +362 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/CONTEXT_INJECTOR_README.md +307 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/CONTEXT_INJECTOR_USAGE_GUIDE.md +508 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/confidence-aggregator.ts +473 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/consensus.ts +1 -1
- package/.claude/skills/cfn-loop-orchestration/src/helpers/context-injector.ts +349 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/context-lookup.ts +486 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/deliverable-verifier.ts +6 -2
- package/.claude/skills/cfn-loop-orchestration/src/helpers/gate-check.ts +1 -1
- package/.claude/skills/cfn-loop-orchestration/src/helpers/product-owner-decision.ts +316 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/spawn-agents.ts +357 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/validator.ts +276 -0
- package/.claude/skills/cfn-loop-orchestration/src/index.ts +2 -0
- package/.claude/skills/cfn-loop-orchestration/src/orchestrate.ts +743 -2
- package/.claude/skills/cfn-loop-orchestration/src/types.ts +56 -0
- package/.claude/skills/cfn-loop-orchestration/test-cli.sh +92 -0
- package/.claude/skills/cfn-loop-orchestration/test-typescript-integration.sh +442 -0
- package/.claude/skills/cfn-loop-orchestration/tests/agent-spawner.test.ts +124 -0
- package/.claude/skills/cfn-loop-orchestration/tests/confidence-aggregator.test.ts +604 -0
- package/.claude/skills/cfn-loop-orchestration/tests/context-injector.test.ts +561 -0
- package/.claude/skills/cfn-loop-orchestration/tests/context-lookup.test.ts +661 -0
- package/.claude/skills/cfn-loop-orchestration/tests/deliverable-verifier.test.ts +2 -2
- package/.claude/skills/cfn-loop-orchestration/tests/gate-check-edge-cases.test.ts +422 -0
- package/.claude/skills/cfn-loop-orchestration/tests/gate-checker.test.ts +276 -0
- package/.claude/skills/cfn-loop-orchestration/tests/logger.test.ts +291 -0
- package/.claude/skills/cfn-loop-orchestration/tests/north-star-e2e.test.ts +334 -0
- package/.claude/skills/cfn-loop-orchestration/tests/redis-coordinator.test.ts +321 -0
- package/.claude/skills/cfn-loop-orchestration/tests/spawn-agents.test.ts +284 -0
- package/.claude/skills/cfn-loop-orchestration/tests/validator.test.ts +643 -0
- package/.claude/skills/cfn-loop-validation/IMPLEMENTATION_SUMMARY.md +672 -0
- package/.claude/skills/cfn-loop-validation/INDEX.md +531 -0
- package/.claude/skills/cfn-loop-validation/README_TYPESCRIPT.md +454 -0
- package/.claude/skills/cfn-loop-validation/SKILL.md +48 -1
- package/.claude/skills/cfn-loop-validation/SKILL.md.backup +353 -0
- package/.claude/skills/cfn-loop-validation/SKILL_TYPESCRIPT.md +782 -0
- package/.claude/skills/cfn-loop-validation/VAPOR_DETECTION_EXAMPLES.md +598 -0
- package/.claude/skills/cfn-loop-validation/check-dependencies.sh +22 -0
- package/{claude-assets/skills/cfn-redis-coordination/check-dependencies.sh → .claude/skills/cfn-loop-validation/check-dependencies.sh.backup} +4 -5
- package/.claude/skills/cfn-loop-validation/detect-vapor.sh +59 -0
- package/.claude/skills/cfn-loop-validation/detect-vapor.sh.backup +37 -0
- package/.claude/skills/cfn-loop-validation/dist/.tsbuildinfo +1 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/detect-vapor.d.ts +14 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/detect-vapor.d.ts.map +1 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/detect-vapor.js +185 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/detect-vapor.js.map +1 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/validate-deliverables.d.ts +14 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/validate-deliverables.d.ts.map +1 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/validate-deliverables.js +176 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/validate-deliverables.js.map +1 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/validate-gate.d.ts +19 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/validate-gate.d.ts.map +1 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/validate-gate.js +123 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/validate-gate.js.map +1 -0
- package/.claude/skills/cfn-loop-validation/dist/types.d.ts +156 -0
- package/.claude/skills/cfn-loop-validation/dist/types.d.ts.map +1 -0
- package/.claude/skills/cfn-loop-validation/dist/types.js +66 -0
- package/.claude/skills/cfn-loop-validation/dist/types.js.map +1 -0
- package/.claude/skills/cfn-loop-validation/dist/validator.d.ts +85 -0
- package/.claude/skills/cfn-loop-validation/dist/validator.d.ts.map +1 -0
- package/.claude/skills/cfn-loop-validation/dist/validator.js +411 -0
- package/.claude/skills/cfn-loop-validation/dist/validator.js.map +1 -0
- package/.claude/skills/cfn-loop-validation/orchestrate-cfn-loop.sh +22 -0
- package/.claude/skills/cfn-loop-validation/orchestrate-cfn-loop.sh.backup +252 -0
- package/.claude/skills/cfn-loop-validation/package.json +93 -0
- package/.claude/skills/cfn-loop-validation/src/cli/detect-vapor.ts +177 -0
- package/.claude/skills/cfn-loop-validation/src/cli/validate-deliverables.ts +161 -0
- package/.claude/skills/cfn-loop-validation/src/cli/validate-gate.ts +139 -0
- package/.claude/skills/cfn-loop-validation/src/types.ts +215 -0
- package/.claude/skills/cfn-loop-validation/src/validator.ts +503 -0
- package/.claude/skills/cfn-loop-validation/tests/validator.test.ts +537 -0
- package/.claude/skills/{cfn-redis-coordination → cfn-loop-validation}/tsconfig.json +34 -31
- package/.claude/skills/cfn-loop-validation/validate-deliverables.sh +59 -0
- package/.claude/skills/cfn-loop-validation/validate-deliverables.sh.backup +37 -0
- package/.claude/skills/cfn-loop-validation/validate-gate.sh +63 -0
- package/.claude/skills/cfn-loop-validation/validate-gate.sh.backup +41 -0
- package/.claude/skills/cfn-loop-validation/validate-iteration.sh +22 -0
- package/.claude/skills/cfn-loop-validation/validate-iteration.sh.backup +134 -0
- package/.claude/skills/cfn-product-owner-decision/SKILL.md +479 -147
- package/.claude/skills/cfn-product-owner-decision/TYPESCRIPT_IMPLEMENTATION.md +653 -0
- package/{claude-assets/skills/cfn-product-owner-decision → .claude/skills/cfn-product-owner-decision/archive/legacy-bash}/execute-decision.sh +24 -2
- package/.claude/skills/pre-edit-backup/SKILL.md +324 -0
- package/.claude/skills/pre-edit-backup/SKILL.md.backup +277 -0
- package/.claude/skills/pre-edit-backup/backup.sh +22 -0
- package/.claude/skills/pre-edit-backup/backup.sh.backup +107 -0
- package/claude-assets/agents/cfn-dev-team/coordinators/cfn-frontend-coordinator.md +1 -0
- package/claude-assets/agents/cfn-dev-team/coordinators/consensus-builder.md +1 -0
- package/claude-assets/agents/cfn-dev-team/coordinators/handoff-coordinator.md +1 -0
- package/claude-assets/agents/cfn-dev-team/coordinators/multi-sprint-coordinator.md +1 -0
- package/claude-assets/agents/cfn-dev-team/dev-ops/devops-engineer.md +10 -0
- package/claude-assets/agents/cfn-dev-team/dev-ops/docker-specialist.md +56 -33
- package/claude-assets/agents/cfn-dev-team/dev-ops/kubernetes-specialist.md +46 -36
- package/claude-assets/agents/cfn-dev-team/dev-ops/monitoring-specialist.md +9 -0
- package/claude-assets/agents/cfn-dev-team/developers/api-gateway-specialist.md +17 -17
- package/claude-assets/agents/cfn-dev-team/developers/backend-developer.md +40 -58
- package/claude-assets/agents/cfn-dev-team/developers/data/data-engineer.md +18 -20
- package/claude-assets/agents/cfn-dev-team/developers/database/database-architect.md +19 -28
- package/claude-assets/agents/cfn-dev-team/developers/frontend/mobile-dev.md +15 -19
- package/claude-assets/agents/cfn-dev-team/developers/frontend/react-frontend-engineer.md +15 -10
- package/claude-assets/agents/cfn-dev-team/developers/frontend/typescript-specialist.md +15 -10
- package/claude-assets/agents/cfn-dev-team/developers/frontend/ui-designer.md +15 -25
- package/claude-assets/agents/cfn-dev-team/developers/graphql-specialist.md +17 -21
- package/claude-assets/agents/cfn-dev-team/developers/rust-developer.md +17 -21
- package/claude-assets/agents/cfn-dev-team/product-owners/product-owner.md +1 -5
- package/claude-assets/agents/cfn-dev-team/reviewers/code-reviewer.md +20 -51
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/code-quality-validator.md +22 -71
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/perf-analyzer.md +21 -64
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/performance-benchmarker.md +22 -67
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/security-specialist.md +23 -67
- package/claude-assets/agents/cfn-dev-team/testers/api-testing-specialist.md +7 -35
- package/claude-assets/agents/cfn-dev-team/testers/chaos-engineering-specialist.md +8 -37
- package/claude-assets/agents/cfn-dev-team/testers/contract-tester.md +16 -54
- package/claude-assets/agents/cfn-dev-team/testers/integration-tester.md +17 -55
- package/claude-assets/agents/cfn-dev-team/testers/interaction-tester.md +9 -37
- package/claude-assets/agents/cfn-dev-team/testers/load-testing-specialist.md +17 -55
- package/claude-assets/agents/cfn-dev-team/testers/mutation-testing-specialist.md +17 -48
- package/claude-assets/agents/cfn-dev-team/testers/playwright-tester.md +8 -37
- package/claude-assets/agents/cfn-dev-team/testers/tester.md +7 -27
- package/claude-assets/agents/cfn-dev-team/utility/analyst.md +12 -28
- package/claude-assets/agents/cfn-dev-team/utility/code-booster.md +13 -13
- package/claude-assets/agents/cfn-dev-team/utility/context-curator.md +7 -2
- package/claude-assets/agents/cfn-dev-team/utility/epic-creator.md +5 -10
- package/claude-assets/agents/cfn-dev-team/utility/memory-leak-specialist.md +120 -714
- package/claude-assets/agents/cfn-dev-team/utility/researcher.md +12 -21
- package/claude-assets/agents/cfn-dev-team/utility/z-ai-specialist.md +146 -572
- package/claude-assets/agents/custom/cfn-docker-expert.md +102 -0
- package/claude-assets/agents/custom/cfn-loops-cli-expert.md +129 -0
- package/claude-assets/cfn-extras/agents/cfn-v3-coordinator.md +517 -0
- package/claude-assets/commands/cfn-loop-cli.md +158 -464
- package/claude-assets/commands/cfn-loop-trigger.md +114 -0
- package/claude-assets/hooks/SKILL.md +518 -0
- package/claude-assets/hooks/SKILL.md.backup +471 -0
- package/claude-assets/hooks/cfn-invoke-post-edit-ts.sh +100 -0
- package/claude-assets/hooks/cfn-invoke-post-edit-ts.sh.backup +78 -0
- package/claude-assets/hooks/cfn-invoke-post-edit.sh +22 -0
- package/claude-assets/hooks/cfn-invoke-post-edit.sh.backup +87 -0
- package/claude-assets/hooks/cfn-invoke-pre-edit-ts.sh +116 -0
- package/claude-assets/hooks/cfn-invoke-pre-edit-ts.sh.backup +94 -0
- package/claude-assets/hooks/cfn-invoke-pre-edit.sh +22 -0
- package/claude-assets/hooks/cfn-invoke-pre-edit.sh.backup +88 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/DELIVERABLES.md +409 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/IMPLEMENTATION_SUMMARY.md +396 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/INTEGRATION_GUIDE.md +308 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/QUICK_REFERENCE.md +239 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/SKILL.md +107 -1
- package/claude-assets/skills/cfn-agent-selection-with-fallback/SKILL.md.backup +302 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/TYPESCRIPT_MIGRATION.md +295 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/dist/agent-selector.cjs +297 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/dist/agent-selector.js +297 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/dist/cli.cjs +96 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/dist/cli.js +96 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/select-agents-ts.sh +45 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/select-agents-ts.sh.backup +23 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/select-agents.sh +22 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/select-agents.sh.backup +173 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/src/agent-selector.test.ts +357 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/src/agent-selector.ts +350 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/src/cli.ts +74 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/task-classifier.sh +22 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/task-classifier.sh.backup +71 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/tsconfig.json +18 -0
- package/claude-assets/skills/cfn-agent-spawning/SKILL.md +48 -1
- package/claude-assets/skills/cfn-agent-spawning/SKILL.md.backup +135 -0
- package/claude-assets/skills/cfn-agent-spawning/TYPESCRIPT_MIGRATION.md +567 -0
- package/claude-assets/skills/cfn-agent-spawning/check-dependencies.sh +22 -0
- package/claude-assets/skills/cfn-agent-spawning/check-dependencies.sh.backup +30 -0
- package/claude-assets/skills/cfn-agent-spawning/get-agent-provider-env.sh +22 -0
- package/claude-assets/skills/cfn-agent-spawning/get-agent-provider-env.sh.backup +127 -0
- package/claude-assets/skills/cfn-agent-spawning/parse-agent-provider.sh +22 -0
- package/claude-assets/skills/cfn-agent-spawning/parse-agent-provider.sh.backup +59 -0
- package/claude-assets/skills/cfn-agent-spawning/spawn-agent-wrapper.sh +63 -0
- package/claude-assets/skills/cfn-agent-spawning/spawn-agent-wrapper.sh.backup +41 -0
- package/claude-assets/skills/cfn-agent-spawning/spawn-agent.sh +26 -1
- package/claude-assets/skills/cfn-agent-spawning/spawn-templates.sh +22 -0
- package/claude-assets/skills/cfn-agent-spawning/spawn-templates.sh.backup +613 -0
- package/claude-assets/skills/cfn-agent-spawning/spawn-worker.sh +22 -0
- package/claude-assets/skills/cfn-agent-spawning/spawn-worker.sh.backup +176 -0
- package/claude-assets/skills/cfn-coordination/agent-completion.sh.backup +36 -0
- package/claude-assets/skills/cfn-coordination/coordination-signal.sh.backup +36 -0
- package/claude-assets/skills/cfn-coordination/coordination-wait.sh.backup +36 -0
- package/claude-assets/skills/cfn-dependency-ingestion/README.md +101 -0
- package/claude-assets/skills/cfn-dependency-ingestion/SKILL.md +369 -0
- package/claude-assets/skills/cfn-dependency-ingestion/build.sh +23 -0
- package/claude-assets/skills/cfn-dependency-ingestion/dist/ingest-dependencies.js +478 -0
- package/claude-assets/skills/cfn-dependency-ingestion/ingest-dependencies.sh +295 -0
- package/claude-assets/skills/cfn-dependency-ingestion/src/ingest-dependencies.ts +563 -0
- package/claude-assets/skills/cfn-loop-orchestration/.backups/unknown/1763619700_33aff4a69b99159e4e849107ebc4d09f/metadata.json +8 -0
- package/claude-assets/skills/cfn-loop-orchestration/.backups/unknown/1763619700_33aff4a69b99159e4e849107ebc4d09f/original +271 -0
- package/claude-assets/skills/cfn-loop-orchestration/.backups/unknown/1763619700_33aff4a69b99159e4e849107ebc4d09f/revert.sh +7 -0
- package/claude-assets/skills/cfn-loop-orchestration/.backups/unknown/1763671642_06496e8c399a79db08167cc00ed4b31e/metadata.json +8 -0
- package/claude-assets/skills/cfn-loop-orchestration/.backups/unknown/1763671642_06496e8c399a79db08167cc00ed4b31e/original +325 -0
- package/claude-assets/skills/cfn-loop-orchestration/.backups/unknown/1763671642_06496e8c399a79db08167cc00ed4b31e/revert.sh +7 -0
- package/claude-assets/skills/cfn-loop-orchestration/CLI_IMPLEMENTATION_SUMMARY.md +330 -0
- package/claude-assets/skills/cfn-loop-orchestration/CONFIGURATION_IMPROVEMENTS.md +318 -0
- package/claude-assets/skills/cfn-loop-orchestration/CONTEXT_LOOKUP_MIGRATION.md +308 -0
- package/claude-assets/skills/cfn-loop-orchestration/CONTEXT_LOOKUP_QUICK_START.md +378 -0
- package/claude-assets/skills/cfn-loop-orchestration/E2E_VALIDATION_REPORT.md +262 -0
- package/claude-assets/skills/cfn-loop-orchestration/IMPLEMENTATION_SUMMARY.md +319 -519
- package/claude-assets/skills/cfn-loop-orchestration/NORTH_STAR_E2E_REPORT.md +299 -0
- package/claude-assets/skills/cfn-loop-orchestration/NORTH_STAR_EXECUTION_SUMMARY.md +403 -0
- package/claude-assets/skills/cfn-loop-orchestration/NORTH_STAR_INDEX.md +323 -0
- package/claude-assets/skills/cfn-loop-orchestration/SKILL.md +159 -48
- package/claude-assets/skills/cfn-loop-orchestration/SPAWN_AGENTS_IMPLEMENTATION.md +188 -0
- package/claude-assets/skills/cfn-loop-orchestration/TEST_COVERAGE_REPORT.md +335 -0
- package/claude-assets/skills/cfn-loop-orchestration/TEST_COVERAGE_SUMMARY.md +456 -0
- package/claude-assets/skills/cfn-loop-orchestration/TYPESCRIPT_INTEGRATION_REPORT.md +709 -0
- package/claude-assets/skills/cfn-loop-orchestration/TYPESCRIPT_INTEGRATION_SUMMARY.md +257 -0
- package/claude-assets/skills/cfn-loop-orchestration/VALIDATION_REPORT.md +572 -0
- package/claude-assets/skills/cfn-loop-orchestration/VALIDATION_SUMMARY.txt +196 -0
- package/claude-assets/skills/cfn-loop-orchestration/VALIDATOR_MODULE_GUIDE.md +526 -0
- package/claude-assets/skills/cfn-loop-orchestration/archive/legacy-bash/README.md +167 -0
- package/claude-assets/skills/cfn-loop-orchestration/archive/legacy-bash/orchestrate-enhanced.sh +548 -0
- package/{.claude/skills/cfn-loop-orchestration → claude-assets/skills/cfn-loop-orchestration/archive/legacy-bash}/orchestrate-wrapper.sh +11 -1
- package/claude-assets/skills/cfn-loop-orchestration/archive/legacy-bash/orchestrate.sh +182 -0
- package/claude-assets/skills/cfn-loop-orchestration/e2e-validation-fixed.js +240 -0
- package/claude-assets/skills/cfn-loop-orchestration/e2e-validation.js +213 -0
- package/claude-assets/skills/cfn-loop-orchestration/package-lock.json +3 -0
- package/claude-assets/skills/cfn-loop-orchestration/package.json +4 -0
- package/claude-assets/skills/cfn-loop-orchestration/run-north-star-e2e.ts +210 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/cli/orchestrator-cli.ts +396 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/CONFIDENCE_AGGREGATOR.md +564 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/CONFIDENCE_AGGREGATOR_QUICK_REF.md +241 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/CONTEXT_INJECTOR_IMPLEMENTATION.md +375 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/CONTEXT_INJECTOR_QUICK_REFERENCE.md +362 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/CONTEXT_INJECTOR_README.md +307 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/CONTEXT_INJECTOR_USAGE_GUIDE.md +508 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/confidence-aggregator.ts +473 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/consensus.ts +1 -1
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/context-injector.ts +349 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/context-lookup.ts +486 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/deliverable-verifier.ts +6 -2
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/gate-check.ts +1 -1
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/product-owner-decision.ts +316 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/spawn-agents.ts +357 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/validator.ts +276 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/index.ts +2 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/orchestrate.ts +743 -2
- package/claude-assets/skills/cfn-loop-orchestration/src/types.ts +56 -0
- package/claude-assets/skills/cfn-loop-orchestration/test-cli.sh +92 -0
- package/claude-assets/skills/cfn-loop-orchestration/test-typescript-integration.sh +442 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/agent-spawner.test.ts +124 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/confidence-aggregator.test.ts +604 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/context-injector.test.ts +561 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/context-lookup.test.ts +661 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/deliverable-verifier.test.ts +2 -2
- package/claude-assets/skills/cfn-loop-orchestration/tests/gate-check-edge-cases.test.ts +422 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/gate-checker.test.ts +276 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/logger.test.ts +291 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/north-star-e2e.test.ts +334 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/redis-coordinator.test.ts +321 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/spawn-agents.test.ts +284 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/validator.test.ts +643 -0
- package/claude-assets/skills/cfn-loop-output-processing/.eslintrc.json +33 -0
- package/claude-assets/skills/cfn-loop-output-processing/DELIVERY_SUMMARY.txt +462 -0
- package/claude-assets/skills/cfn-loop-output-processing/DEPRECATION_NOTICE.md +183 -0
- package/claude-assets/skills/cfn-loop-output-processing/EXAMPLES.md +609 -0
- package/claude-assets/skills/cfn-loop-output-processing/IMPLEMENTATION_SUMMARY.md +418 -0
- package/claude-assets/skills/cfn-loop-output-processing/INDEX.md +531 -0
- package/claude-assets/skills/cfn-loop-output-processing/MIGRATION.md +362 -0
- package/claude-assets/skills/cfn-loop-output-processing/README.md +114 -0
- package/claude-assets/skills/cfn-loop-output-processing/SKILL.md +633 -0
- package/{.claude/skills/cfn-docker-redis-coordination → claude-assets/skills/cfn-loop-output-processing}/jest.config.js +7 -15
- package/claude-assets/skills/cfn-loop-output-processing/package.json +50 -0
- package/claude-assets/skills/cfn-loop-output-processing/src/cli/process-loop2.ts +195 -0
- package/claude-assets/skills/cfn-loop-output-processing/src/cli/process-loop3.ts +157 -0
- package/claude-assets/skills/cfn-loop-output-processing/src/output-processor.ts +632 -0
- package/claude-assets/skills/cfn-loop-output-processing/tests/output-processor.test.ts +617 -0
- package/claude-assets/skills/{cfn-docker-redis-coordination → cfn-loop-output-processing}/tsconfig.json +16 -7
- package/claude-assets/skills/cfn-loop-validation/IMPLEMENTATION_SUMMARY.md +672 -0
- package/claude-assets/skills/cfn-loop-validation/INDEX.md +531 -0
- package/claude-assets/skills/cfn-loop-validation/README_TYPESCRIPT.md +454 -0
- package/claude-assets/skills/cfn-loop-validation/SKILL.md +48 -1
- package/claude-assets/skills/cfn-loop-validation/SKILL.md.backup +353 -0
- package/claude-assets/skills/cfn-loop-validation/SKILL_TYPESCRIPT.md +782 -0
- package/claude-assets/skills/cfn-loop-validation/VAPOR_DETECTION_EXAMPLES.md +598 -0
- package/claude-assets/skills/cfn-loop-validation/check-dependencies.sh +22 -0
- package/claude-assets/skills/cfn-loop-validation/check-dependencies.sh.backup +31 -0
- package/claude-assets/skills/cfn-loop-validation/detect-vapor.sh +59 -0
- package/claude-assets/skills/cfn-loop-validation/detect-vapor.sh.backup +37 -0
- package/claude-assets/skills/cfn-loop-validation/dist/.tsbuildinfo +1 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/detect-vapor.d.ts +14 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/detect-vapor.d.ts.map +1 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/detect-vapor.js +185 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/detect-vapor.js.map +1 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/validate-deliverables.d.ts +14 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/validate-deliverables.d.ts.map +1 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/validate-deliverables.js +176 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/validate-deliverables.js.map +1 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/validate-gate.d.ts +19 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/validate-gate.d.ts.map +1 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/validate-gate.js +123 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/validate-gate.js.map +1 -0
- package/claude-assets/skills/cfn-loop-validation/dist/types.d.ts +156 -0
- package/claude-assets/skills/cfn-loop-validation/dist/types.d.ts.map +1 -0
- package/claude-assets/skills/cfn-loop-validation/dist/types.js +66 -0
- package/claude-assets/skills/cfn-loop-validation/dist/types.js.map +1 -0
- package/claude-assets/skills/cfn-loop-validation/dist/validator.d.ts +85 -0
- package/claude-assets/skills/cfn-loop-validation/dist/validator.d.ts.map +1 -0
- package/claude-assets/skills/cfn-loop-validation/dist/validator.js +411 -0
- package/claude-assets/skills/cfn-loop-validation/dist/validator.js.map +1 -0
- package/claude-assets/skills/cfn-loop-validation/orchestrate-cfn-loop.sh +22 -0
- package/claude-assets/skills/cfn-loop-validation/orchestrate-cfn-loop.sh.backup +252 -0
- package/claude-assets/skills/cfn-loop-validation/package.json +93 -0
- package/claude-assets/skills/cfn-loop-validation/src/cli/detect-vapor.ts +177 -0
- package/claude-assets/skills/cfn-loop-validation/src/cli/validate-deliverables.ts +161 -0
- package/claude-assets/skills/cfn-loop-validation/src/cli/validate-gate.ts +139 -0
- package/claude-assets/skills/cfn-loop-validation/src/types.ts +215 -0
- package/claude-assets/skills/cfn-loop-validation/src/validator.ts +503 -0
- package/claude-assets/skills/cfn-loop-validation/tests/validator.test.ts +537 -0
- package/claude-assets/skills/{cfn-redis-coordination → cfn-loop-validation}/tsconfig.json +34 -31
- package/claude-assets/skills/cfn-loop-validation/validate-deliverables.sh +59 -0
- package/claude-assets/skills/cfn-loop-validation/validate-deliverables.sh.backup +37 -0
- package/claude-assets/skills/cfn-loop-validation/validate-gate.sh +63 -0
- package/claude-assets/skills/cfn-loop-validation/validate-gate.sh.backup +41 -0
- package/claude-assets/skills/cfn-loop-validation/validate-iteration.sh +22 -0
- package/claude-assets/skills/cfn-loop-validation/validate-iteration.sh.backup +134 -0
- package/claude-assets/skills/cfn-product-owner-decision/SKILL.md +479 -147
- package/claude-assets/skills/cfn-product-owner-decision/TYPESCRIPT_IMPLEMENTATION.md +653 -0
- package/{.claude/skills/cfn-product-owner-decision → claude-assets/skills/cfn-product-owner-decision/archive/legacy-bash}/execute-decision.sh +24 -2
- package/claude-assets/skills/cfn-provider-routing/README.md +129 -0
- package/claude-assets/skills/cfn-provider-routing/SKILL.md +192 -0
- package/claude-assets/skills/cfn-provider-routing/resolve-provider-model.ts +223 -0
- package/claude-assets/skills/pre-edit-backup/SKILL.md +324 -0
- package/claude-assets/skills/pre-edit-backup/SKILL.md.backup +277 -0
- package/claude-assets/skills/pre-edit-backup/backup.sh +22 -0
- package/claude-assets/skills/pre-edit-backup/backup.sh.backup +107 -0
- package/dist/agents/agent-loader.js +146 -165
- package/dist/agents/agent-loader.js.map +1 -1
- package/dist/api/auth-endpoints.js +415 -0
- package/dist/api/auth-endpoints.js.map +1 -0
- package/dist/api/task-endpoints.js +562 -0
- package/dist/api/task-endpoints.js.map +1 -0
- package/dist/backend/server.js +418 -0
- package/dist/backend/server.js.map +1 -0
- package/dist/cfn-loop/product-owner/decision-parser.js +356 -0
- package/dist/cfn-loop/product-owner/decision-parser.js.map +1 -0
- package/dist/cfn-loop/product-owner/index.js +1 -0
- package/dist/cfn-loop/product-owner/index.js.map +1 -1
- package/dist/cli/agent-command.js +1 -1
- package/dist/cli/agent-command.js.map +1 -1
- package/dist/cli/agent-completion.js +273 -0
- package/dist/cli/agent-completion.js.map +1 -0
- package/dist/cli/agent-prompt-builder.js +83 -48
- package/dist/cli/agent-prompt-builder.js.map +1 -1
- package/dist/cli/agent-spawner.js +499 -0
- package/dist/cli/agent-spawner.js.map +1 -0
- package/dist/cli/anthropic-client.js +10 -3
- package/dist/cli/anthropic-client.js.map +1 -1
- package/dist/cli/config-manager.js +91 -109
- package/dist/cli/index.js +11 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/parse-decision-cli.js +268 -0
- package/dist/cli/parse-decision-cli.js.map +1 -0
- package/dist/cli/post-edit-hook.js +83 -0
- package/dist/cli/post-edit-hook.js.map +1 -0
- package/dist/cli/pre-edit-hook.js +77 -0
- package/dist/cli/pre-edit-hook.js.map +1 -0
- package/dist/cli/spawn-agent-cli.js +209 -0
- package/dist/cli/spawn-agent-cli.js.map +1 -0
- package/dist/coordination/coordination-wrapper.js +383 -0
- package/dist/coordination/coordination-wrapper.js.map +1 -0
- package/dist/coordination/store-success-criteria.js +68 -0
- package/dist/coordination/store-success-criteria.js.map +1 -0
- package/dist/coordination/store-task-context.js +65 -0
- package/dist/coordination/store-task-context.js.map +1 -0
- package/dist/hooks/backup-manager.js +273 -0
- package/dist/hooks/backup-manager.js.map +1 -0
- package/dist/hooks/post-edit-validator.js +388 -0
- package/dist/hooks/post-edit-validator.js.map +1 -0
- package/dist/integration/index.js +19 -0
- package/dist/integration/index.js.map +1 -0
- package/dist/integration/task-mode-adapter.js +297 -0
- package/dist/integration/task-mode-adapter.js.map +1 -0
- package/dist/integration/trigger-dev-client.js +253 -0
- package/dist/integration/trigger-dev-client.js.map +1 -0
- package/dist/integration/trigger-dev-webhooks.js +362 -0
- package/dist/integration/trigger-dev-webhooks.js.map +1 -0
- package/dist/lib/path-validator.js +14 -5
- package/dist/lib/path-validator.js.map +1 -1
- package/dist/lib/redis-queue-manager.js +5 -1
- package/dist/lib/redis-queue-manager.js.map +1 -1
- package/dist/middleware/authentication.js +317 -0
- package/dist/middleware/authentication.js.map +1 -0
- package/dist/services/authentication.js +669 -0
- package/dist/services/authentication.js.map +1 -0
- package/dist/services/session-management.js +436 -0
- package/dist/services/session-management.js.map +1 -0
- package/dist/services/skill-deployment.js +8 -6
- package/dist/services/skill-deployment.js.map +1 -1
- package/dist/services/user-service.js +710 -0
- package/dist/services/user-service.js.map +1 -0
- package/dist/types/trigger-dev-events.d.js +10 -0
- package/dist/types/trigger-dev-events.d.js.map +1 -0
- package/docs/README.md +240 -0
- package/package.json +13 -4
- package/scripts/compare-workflow-performance.sh +556 -0
- package/scripts/migrate-to-optimized-workflows.sh +438 -0
- package/scripts/organize-docs.sh +338 -0
- package/scripts/trigger-dev-setup.sh +267 -0
- package/.claude/skills/cfn-docker-redis-coordination/MIGRATION_SUMMARY.md +0 -348
- package/.claude/skills/cfn-docker-redis-coordination/README.md +0 -294
- package/.claude/skills/cfn-docker-redis-coordination/SKILL.md +0 -435
- package/.claude/skills/cfn-docker-redis-coordination/coordinate.sh +0 -650
- package/.claude/skills/cfn-docker-redis-coordination/coordinate.sh.backup-1763145142 +0 -641
- package/.claude/skills/cfn-docker-redis-coordination/package-lock.json +0 -5259
- package/.claude/skills/cfn-docker-redis-coordination/package.json +0 -40
- package/.claude/skills/cfn-docker-redis-coordination/src/coordinator.ts +0 -801
- package/.claude/skills/cfn-docker-redis-coordination/src/index.ts +0 -42
- package/.claude/skills/cfn-docker-redis-coordination/src/types.ts +0 -351
- package/.claude/skills/cfn-docker-redis-coordination/tests/coordinator.test.ts +0 -1464
- package/.claude/skills/cfn-docker-redis-coordination/tsconfig.json +0 -30
- package/.claude/skills/cfn-loop-orchestration/helpers/auto-tune-timeouts.sh +0 -228
- package/.claude/skills/cfn-loop-orchestration/helpers/consensus-ts.sh +0 -104
- package/.claude/skills/cfn-loop-orchestration/helpers/consensus.sh +0 -94
- package/.claude/skills/cfn-loop-orchestration/helpers/context-injection.sh +0 -142
- package/.claude/skills/cfn-loop-orchestration/helpers/context-lookup.sh +0 -359
- package/.claude/skills/cfn-loop-orchestration/helpers/deliverable-verifier-ts.sh +0 -123
- package/.claude/skills/cfn-loop-orchestration/helpers/deliverable-verifier.sh +0 -71
- package/.claude/skills/cfn-loop-orchestration/helpers/gate-check.sh +0 -56
- package/.claude/skills/cfn-loop-orchestration/helpers/iteration-manager-ts.sh +0 -89
- package/.claude/skills/cfn-loop-orchestration/helpers/iteration-manager.sh +0 -87
- package/.claude/skills/cfn-loop-orchestration/helpers/orchestrate-ts.sh +0 -104
- package/.claude/skills/cfn-loop-orchestration/helpers/parse-test-results.sh +0 -56
- package/.claude/skills/cfn-loop-orchestration/helpers/spawn-agents.sh +0 -290
- package/.claude/skills/cfn-loop-orchestration/helpers/timeout-calculator-ts.sh +0 -47
- package/.claude/skills/cfn-loop-orchestration/helpers/timeout-calculator.sh +0 -51
- package/.claude/skills/cfn-loop-orchestration/orchestrate.sh +0 -1345
- package/.claude/skills/cfn-redis-coordination/AGENT_LOGGING.md +0 -280
- package/.claude/skills/cfn-redis-coordination/BZPOPMIN_FIX_SUMMARY.md +0 -209
- package/.claude/skills/cfn-redis-coordination/CENTRALIZED_REDIS_WRAPPER.md +0 -319
- package/.claude/skills/cfn-redis-coordination/agent-log.sh.bak +0 -124
- package/.claude/skills/cfn-redis-coordination/config.json +0 -61
- package/.claude/skills/cfn-redis-coordination/demos/phase4-wake-queue-test-report.md +0 -82
- package/.claude/skills/cfn-redis-coordination/demos/test-bzpopmin-fix.sh +0 -274
- package/.claude/skills/cfn-redis-coordination/demos/test-cancel-swarm.sh +0 -0
- package/.claude/skills/cfn-redis-coordination/docs/migration/PHASE_3_REDIS_COORDINATION_COMPLETION_REPORT.md +0 -553
- package/.claude/skills/cfn-redis-coordination/jest.config.js +0 -23
- package/.claude/skills/cfn-redis-coordination/package-lock.json +0 -5272
- package/.claude/skills/cfn-redis-coordination/package.json +0 -45
- package/.claude/skills/cfn-redis-coordination/src/agent-logger.ts +0 -446
- package/.claude/skills/cfn-redis-coordination/src/agent-recovery.ts +0 -454
- package/.claude/skills/cfn-redis-coordination/src/completion-reporter.ts +0 -396
- package/.claude/skills/cfn-redis-coordination/src/context-manager.ts +0 -327
- package/.claude/skills/cfn-redis-coordination/src/index.ts +0 -82
- package/.claude/skills/cfn-redis-coordination/src/mode-detector.ts +0 -155
- package/.claude/skills/cfn-redis-coordination/src/redis/redis-client.ts +0 -305
- package/.claude/skills/cfn-redis-coordination/src/redis/redis-functions.ts +0 -283
- package/.claude/skills/cfn-redis-coordination/src/redis-client.ts +0 -654
- package/.claude/skills/cfn-redis-coordination/src/result-collector.ts +0 -437
- package/.claude/skills/cfn-redis-coordination/src/swarm-manager.ts +0 -494
- package/.claude/skills/cfn-redis-coordination/src/task-analyzer.ts +0 -404
- package/.claude/skills/cfn-redis-coordination/src/task-executor.ts +0 -423
- package/.claude/skills/cfn-redis-coordination/src/types.ts +0 -235
- package/.claude/skills/cfn-redis-coordination/src/waiting-coordinator.ts +0 -587
- package/.claude/skills/cfn-redis-coordination/store-success-criteria.sh +0 -85
- package/.claude/skills/cfn-redis-coordination/test-connection-attempts.js +0 -70
- package/.claude/skills/cfn-redis-coordination/test-mode-simple.js +0 -121
- package/.claude/skills/cfn-redis-coordination/test-redis-check.js +0 -84
- package/.claude/skills/cfn-redis-coordination/test-task-mode-redis.cjs +0 -391
- package/.claude/skills/cfn-redis-coordination/tests/coordination.test.ts +0 -788
- package/.claude/skills/cfn-redis-coordination/update-all-scripts.sh +0 -67
- package/claude-assets/agents/cfn-dev-team/coordinators/cfn-v3-coordinator.md +0 -980
- package/claude-assets/agents/typescript-specialist.md +0 -280
- package/claude-assets/skills/cfn-docker-redis-coordination/MIGRATION_SUMMARY.md +0 -348
- package/claude-assets/skills/cfn-docker-redis-coordination/README.md +0 -294
- package/claude-assets/skills/cfn-docker-redis-coordination/SKILL.md +0 -435
- package/claude-assets/skills/cfn-docker-redis-coordination/coordinate.sh +0 -650
- package/claude-assets/skills/cfn-docker-redis-coordination/coordinate.sh.backup-1763145142 +0 -641
- package/claude-assets/skills/cfn-docker-redis-coordination/jest.config.js +0 -37
- package/claude-assets/skills/cfn-docker-redis-coordination/package-lock.json +0 -5259
- package/claude-assets/skills/cfn-docker-redis-coordination/package.json +0 -40
- package/claude-assets/skills/cfn-docker-redis-coordination/src/coordinator.ts +0 -801
- package/claude-assets/skills/cfn-docker-redis-coordination/src/index.ts +0 -42
- package/claude-assets/skills/cfn-docker-redis-coordination/src/types.ts +0 -351
- package/claude-assets/skills/cfn-docker-redis-coordination/tests/coordinator.test.ts +0 -1464
- package/claude-assets/skills/cfn-loop-orchestration/helpers/auto-tune-timeouts.sh +0 -228
- package/claude-assets/skills/cfn-loop-orchestration/helpers/consensus-ts.sh +0 -104
- package/claude-assets/skills/cfn-loop-orchestration/helpers/consensus.sh +0 -94
- package/claude-assets/skills/cfn-loop-orchestration/helpers/context-injection.sh +0 -142
- package/claude-assets/skills/cfn-loop-orchestration/helpers/context-lookup.sh +0 -359
- package/claude-assets/skills/cfn-loop-orchestration/helpers/deliverable-verifier-ts.sh +0 -123
- package/claude-assets/skills/cfn-loop-orchestration/helpers/deliverable-verifier.sh +0 -71
- package/claude-assets/skills/cfn-loop-orchestration/helpers/gate-check.sh +0 -56
- package/claude-assets/skills/cfn-loop-orchestration/helpers/iteration-manager-ts.sh +0 -89
- package/claude-assets/skills/cfn-loop-orchestration/helpers/iteration-manager.sh +0 -87
- package/claude-assets/skills/cfn-loop-orchestration/helpers/orchestrate-ts.sh +0 -104
- package/claude-assets/skills/cfn-loop-orchestration/helpers/parse-test-results.sh +0 -56
- package/claude-assets/skills/cfn-loop-orchestration/helpers/spawn-agents.sh +0 -290
- package/claude-assets/skills/cfn-loop-orchestration/helpers/timeout-calculator-ts.sh +0 -47
- package/claude-assets/skills/cfn-loop-orchestration/helpers/timeout-calculator.sh +0 -51
- package/claude-assets/skills/cfn-loop-orchestration/orchestrate.sh +0 -1345
- package/claude-assets/skills/cfn-redis-cleanup/cleanup-redis.sh +0 -130
- package/claude-assets/skills/cfn-redis-coordination/AGENT_LOGGING.md +0 -280
- package/claude-assets/skills/cfn-redis-coordination/BZPOPMIN_FIX_SUMMARY.md +0 -209
- package/claude-assets/skills/cfn-redis-coordination/CENTRALIZED_REDIS_WRAPPER.md +0 -319
- package/claude-assets/skills/cfn-redis-coordination/agent-log.sh.bak +0 -124
- package/claude-assets/skills/cfn-redis-coordination/config.json +0 -61
- package/claude-assets/skills/cfn-redis-coordination/demos/phase4-wake-queue-test-report.md +0 -82
- package/claude-assets/skills/cfn-redis-coordination/demos/test-bzpopmin-fix.sh +0 -274
- package/claude-assets/skills/cfn-redis-coordination/demos/test-cancel-swarm.sh +0 -0
- package/claude-assets/skills/cfn-redis-coordination/docs/migration/PHASE_3_REDIS_COORDINATION_COMPLETION_REPORT.md +0 -553
- package/claude-assets/skills/cfn-redis-coordination/jest.config.js +0 -23
- package/claude-assets/skills/cfn-redis-coordination/package-lock.json +0 -5272
- package/claude-assets/skills/cfn-redis-coordination/package.json +0 -45
- package/claude-assets/skills/cfn-redis-coordination/src/agent-logger.ts +0 -446
- package/claude-assets/skills/cfn-redis-coordination/src/agent-recovery.ts +0 -454
- package/claude-assets/skills/cfn-redis-coordination/src/completion-reporter.ts +0 -396
- package/claude-assets/skills/cfn-redis-coordination/src/context-manager.ts +0 -327
- package/claude-assets/skills/cfn-redis-coordination/src/index.ts +0 -82
- package/claude-assets/skills/cfn-redis-coordination/src/mode-detector.ts +0 -155
- package/claude-assets/skills/cfn-redis-coordination/src/redis/redis-client.ts +0 -305
- package/claude-assets/skills/cfn-redis-coordination/src/redis/redis-functions.ts +0 -283
- package/claude-assets/skills/cfn-redis-coordination/src/redis-client.ts +0 -654
- package/claude-assets/skills/cfn-redis-coordination/src/result-collector.ts +0 -437
- package/claude-assets/skills/cfn-redis-coordination/src/swarm-manager.ts +0 -494
- package/claude-assets/skills/cfn-redis-coordination/src/task-analyzer.ts +0 -404
- package/claude-assets/skills/cfn-redis-coordination/src/task-executor.ts +0 -423
- package/claude-assets/skills/cfn-redis-coordination/src/types.ts +0 -235
- package/claude-assets/skills/cfn-redis-coordination/src/waiting-coordinator.ts +0 -587
- package/claude-assets/skills/cfn-redis-coordination/store-success-criteria.sh +0 -85
- package/claude-assets/skills/cfn-redis-coordination/test-connection-attempts.js +0 -70
- package/claude-assets/skills/cfn-redis-coordination/test-mode-simple.js +0 -121
- package/claude-assets/skills/cfn-redis-coordination/test-redis-check.js +0 -84
- package/claude-assets/skills/cfn-redis-coordination/test-task-mode-redis.cjs +0 -391
- package/claude-assets/skills/cfn-redis-coordination/tests/coordination.test.ts +0 -788
- package/claude-assets/skills/cfn-redis-coordination/update-all-scripts.sh +0 -67
- package/claude-assets/skills/cfn-redis-data-extraction/SKILL.md +0 -442
- package/claude-assets/skills/cfn-redis-data-extraction/extract.sh +0 -306
- package/dist/coordination/index.js +0 -25
- package/dist/coordination/index.js.map +0 -1
- package/docs/BUG_19_MEMORY_LEAK_TASK_MODE.md +0 -405
- package/docs/MEMORY_CLEANUP_GUIDE.md +0 -358
- package/docs/MEMORY_LEAK_FIX_SUMMARY.md +0 -322
- package/docs/REDIS_CLEANUP_EXECUTIVE_SUMMARY.md +0 -319
- package/docs/REDIS_CLEANUP_VERIFICATION_REPORT.md +0 -574
- /package/.claude/skills/cfn-loop-orchestration/{inject-loop-context.sh → archive/legacy-bash/inject-loop-context.sh} +0 -0
- /package/.claude/skills/cfn-loop-orchestration/{monitor-execution.sh → archive/legacy-bash/monitor-execution.sh} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{agent-log.sh → agent-log.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{agent-recovery.sh → agent-recovery.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{analyze-task-complexity.sh → analyze-task-complexity.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/bash-wrappers/{store-context.sh → store-context.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{cancel-swarm.sh → cancel-swarm.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{cfn-loop-exec.sh → cfn-loop-exec.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{cfn-loop-relaunch.sh → cfn-loop-relaunch.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{collect-confidence-scores.sh → collect-confidence-scores.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{collect-results.sh → collect-results.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{complete-swarm.sh → complete-swarm.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{get-context.sh → get-context.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{get-success-criteria.sh → get-success-criteria.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{invoke-waiting-mode.sh → invoke-waiting-mode.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{redis-cli-wrapper.sh → redis-cli-wrapper.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{redis-functions.sh → redis-functions.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{report-completion.sh → report-completion.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{store-context.sh → store-context.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-loop-orchestration/{inject-loop-context.sh → archive/legacy-bash/inject-loop-context.sh} +0 -0
- /package/claude-assets/skills/cfn-loop-orchestration/{monitor-execution.sh → archive/legacy-bash/monitor-execution.sh} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{agent-log.sh → agent-log.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{agent-recovery.sh → agent-recovery.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{analyze-task-complexity.sh → analyze-task-complexity.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/bash-wrappers/{store-context.sh → store-context.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{cancel-swarm.sh → cancel-swarm.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{cfn-loop-exec.sh → cfn-loop-exec.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{cfn-loop-relaunch.sh → cfn-loop-relaunch.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{collect-confidence-scores.sh → collect-confidence-scores.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{collect-results.sh → collect-results.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{complete-swarm.sh → complete-swarm.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{get-context.sh → get-context.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{get-success-criteria.sh → get-success-criteria.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{invoke-waiting-mode.sh → invoke-waiting-mode.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{redis-cli-wrapper.sh → redis-cli-wrapper.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{redis-functions.sh → redis-functions.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{report-completion.sh → report-completion.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{store-context.sh → store-context.sh.backup} +0 -0
|
@@ -0,0 +1,710 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User Service
|
|
3
|
+
*
|
|
4
|
+
* Comprehensive user management service with authentication, authorization,
|
|
5
|
+
* and security features for the CFN Loop system.
|
|
6
|
+
*/ import { v4 as uuidv4 } from 'uuid';
|
|
7
|
+
import { UserRole, UserStatus } from '../types/user.js';
|
|
8
|
+
import { PasswordUtils, JWTUtils, AuthRateLimit } from '../middleware/authentication.js';
|
|
9
|
+
import { AuthMiddleware, RBACEnforcer } from '../middleware/auth-middleware.js';
|
|
10
|
+
import { createLogger } from '../lib/logging.js';
|
|
11
|
+
import { StandardError, ErrorCode } from '../lib/errors.js';
|
|
12
|
+
const logger = createLogger('user-service');
|
|
13
|
+
/**
|
|
14
|
+
* User Service Class
|
|
15
|
+
*
|
|
16
|
+
* Manages user lifecycle, authentication, and authorization.
|
|
17
|
+
*/ export class UserService {
|
|
18
|
+
db;
|
|
19
|
+
authMiddleware;
|
|
20
|
+
rbacEnforcer;
|
|
21
|
+
config;
|
|
22
|
+
constructor(db, config){
|
|
23
|
+
this.db = db;
|
|
24
|
+
this.config = config;
|
|
25
|
+
this.authMiddleware = new AuthMiddleware(config.jwtSecret);
|
|
26
|
+
this.rbacEnforcer = new RBACEnforcer(this.authMiddleware);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Initialize the user service
|
|
30
|
+
* Creates necessary tables and indexes if they don't exist
|
|
31
|
+
*/ async initialize() {
|
|
32
|
+
try {
|
|
33
|
+
const sqliteAdapter = this.db.getAdapter('sqlite');
|
|
34
|
+
// Create users table
|
|
35
|
+
await sqliteAdapter.execute(`
|
|
36
|
+
CREATE TABLE IF NOT EXISTS users (
|
|
37
|
+
id TEXT PRIMARY KEY,
|
|
38
|
+
username TEXT UNIQUE NOT NULL,
|
|
39
|
+
email TEXT UNIQUE NOT NULL,
|
|
40
|
+
role TEXT NOT NULL DEFAULT 'user',
|
|
41
|
+
status TEXT NOT NULL DEFAULT 'pending_verification',
|
|
42
|
+
password_hash TEXT NOT NULL,
|
|
43
|
+
salt TEXT NOT NULL,
|
|
44
|
+
profile_json TEXT NOT NULL,
|
|
45
|
+
privacy_json TEXT NOT NULL,
|
|
46
|
+
preferences_json TEXT NOT NULL,
|
|
47
|
+
security_json TEXT NOT NULL,
|
|
48
|
+
stats_json TEXT NOT NULL,
|
|
49
|
+
created_at INTEGER NOT NULL,
|
|
50
|
+
updated_at INTEGER NOT NULL,
|
|
51
|
+
last_login_at INTEGER,
|
|
52
|
+
email_verified_at INTEGER,
|
|
53
|
+
phone_verified_at INTEGER
|
|
54
|
+
)
|
|
55
|
+
`);
|
|
56
|
+
// Create refresh tokens table
|
|
57
|
+
await sqliteAdapter.execute(`
|
|
58
|
+
CREATE TABLE IF NOT EXISTS refresh_tokens (
|
|
59
|
+
id TEXT PRIMARY KEY,
|
|
60
|
+
user_id TEXT NOT NULL,
|
|
61
|
+
token_hash TEXT NOT NULL,
|
|
62
|
+
expires_at INTEGER NOT NULL,
|
|
63
|
+
created_at INTEGER NOT NULL,
|
|
64
|
+
last_used_at INTEGER,
|
|
65
|
+
is_revoked BOOLEAN DEFAULT FALSE,
|
|
66
|
+
FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE
|
|
67
|
+
)
|
|
68
|
+
`);
|
|
69
|
+
// Create password reset tokens table
|
|
70
|
+
await sqliteAdapter.execute(`
|
|
71
|
+
CREATE TABLE IF NOT EXISTS password_reset_tokens (
|
|
72
|
+
id TEXT PRIMARY KEY,
|
|
73
|
+
user_id TEXT NOT NULL,
|
|
74
|
+
token_hash TEXT NOT NULL,
|
|
75
|
+
expires_at INTEGER NOT NULL,
|
|
76
|
+
created_at INTEGER NOT NULL,
|
|
77
|
+
used_at INTEGER,
|
|
78
|
+
FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE
|
|
79
|
+
)
|
|
80
|
+
`);
|
|
81
|
+
// Create email verification tokens table
|
|
82
|
+
await sqliteAdapter.execute(`
|
|
83
|
+
CREATE TABLE IF NOT EXISTS email_verification_tokens (
|
|
84
|
+
id TEXT PRIMARY KEY,
|
|
85
|
+
user_id TEXT NOT NULL,
|
|
86
|
+
email TEXT NOT NULL,
|
|
87
|
+
token_hash TEXT NOT NULL,
|
|
88
|
+
expires_at INTEGER NOT NULL,
|
|
89
|
+
created_at INTEGER NOT NULL,
|
|
90
|
+
verified_at INTEGER,
|
|
91
|
+
FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE
|
|
92
|
+
)
|
|
93
|
+
`);
|
|
94
|
+
// Create indexes
|
|
95
|
+
await sqliteAdapter.execute('CREATE INDEX IF NOT EXISTS idx_users_email ON users (email)');
|
|
96
|
+
await sqliteAdapter.execute('CREATE INDEX IF NOT EXISTS idx_users_username ON users (username)');
|
|
97
|
+
await sqliteAdapter.execute('CREATE INDEX IF NOT EXISTS idx_users_role ON users (role)');
|
|
98
|
+
await sqliteAdapter.execute('CREATE INDEX IF NOT EXISTS idx_users_status ON users (status)');
|
|
99
|
+
await sqliteAdapter.execute('CREATE INDEX IF NOT EXISTS idx_refresh_tokens_user_id ON refresh_tokens (user_id)');
|
|
100
|
+
await sqliteAdapter.execute('CREATE INDEX IF NOT EXISTS idx_refresh_tokens_expires_at ON refresh_tokens (expires_at)');
|
|
101
|
+
logger.info('User service initialized successfully');
|
|
102
|
+
} catch (error) {
|
|
103
|
+
logger.error('Failed to initialize user service:', error);
|
|
104
|
+
throw new StandardError(ErrorCode.INTERNAL_ERROR, 'Failed to initialize user service', {}, error);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Register a new user
|
|
109
|
+
*/ async register(request) {
|
|
110
|
+
const { username, email, password, firstName, lastName, displayName } = request;
|
|
111
|
+
try {
|
|
112
|
+
// Validate input
|
|
113
|
+
this.validateEmail(email);
|
|
114
|
+
this.validateUsername(username);
|
|
115
|
+
this.validatePassword(password);
|
|
116
|
+
// Check if user already exists
|
|
117
|
+
const existingUser = await this.findUserByEmailOrUsername(email, username);
|
|
118
|
+
if (existingUser) {
|
|
119
|
+
throw new StandardError(ErrorCode.CONFLICT, existingUser.email === email ? 'Email already registered' : 'Username already taken', {
|
|
120
|
+
field: existingUser.email === email ? 'email' : 'username'
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
// Hash password
|
|
124
|
+
const salt = await PasswordUtils.generateSalt();
|
|
125
|
+
const passwordHash = await PasswordUtils.hashPassword(password, this.config.bcryptRounds);
|
|
126
|
+
// Create user
|
|
127
|
+
const now = Math.floor(Date.now() / 1000);
|
|
128
|
+
const userId = uuidv4();
|
|
129
|
+
const user = {
|
|
130
|
+
id: userId,
|
|
131
|
+
username,
|
|
132
|
+
email,
|
|
133
|
+
role: UserRole.USER,
|
|
134
|
+
status: this.config.emailVerificationRequired ? UserStatus.PENDING_VERIFICATION : UserStatus.ACTIVE,
|
|
135
|
+
profile: {
|
|
136
|
+
firstName,
|
|
137
|
+
lastName,
|
|
138
|
+
displayName: displayName || `${firstName} ${lastName}`
|
|
139
|
+
},
|
|
140
|
+
privacy: {
|
|
141
|
+
profileVisibility: 'public',
|
|
142
|
+
allowFriendRequests: true,
|
|
143
|
+
allowMessages: true,
|
|
144
|
+
allowStoryTagging: true,
|
|
145
|
+
allowLocationSharing: false,
|
|
146
|
+
showOnlineStatus: true
|
|
147
|
+
},
|
|
148
|
+
preferences: {
|
|
149
|
+
theme: 'auto',
|
|
150
|
+
language: 'en',
|
|
151
|
+
timezone: 'UTC',
|
|
152
|
+
emailNotifications: true,
|
|
153
|
+
pushNotifications: true,
|
|
154
|
+
autoSaveStories: true,
|
|
155
|
+
storyVisibilityDefault: 'private'
|
|
156
|
+
},
|
|
157
|
+
security: {
|
|
158
|
+
email,
|
|
159
|
+
emailVerified: !this.config.emailVerificationRequired,
|
|
160
|
+
twoFactorEnabled: false,
|
|
161
|
+
loginAttempts: 0
|
|
162
|
+
},
|
|
163
|
+
stats: {
|
|
164
|
+
storiesCount: 0,
|
|
165
|
+
friendsCount: 0,
|
|
166
|
+
followersCount: 0,
|
|
167
|
+
followingCount: 0
|
|
168
|
+
},
|
|
169
|
+
createdAt: new Date(now * 1000),
|
|
170
|
+
updatedAt: new Date(now * 1000)
|
|
171
|
+
};
|
|
172
|
+
// Save user to database
|
|
173
|
+
await this.saveUser(user, passwordHash, salt);
|
|
174
|
+
// Create email verification token if required
|
|
175
|
+
if (this.config.emailVerificationRequired) {
|
|
176
|
+
await this.createEmailVerificationToken(userId, email);
|
|
177
|
+
}
|
|
178
|
+
// Generate tokens
|
|
179
|
+
const tokens = await this.generateAuthTokens(user);
|
|
180
|
+
// Log user registration
|
|
181
|
+
logger.info('User registered successfully', {
|
|
182
|
+
userId,
|
|
183
|
+
username,
|
|
184
|
+
email
|
|
185
|
+
});
|
|
186
|
+
return {
|
|
187
|
+
user: this.toPublicUser(user),
|
|
188
|
+
tokens
|
|
189
|
+
};
|
|
190
|
+
} catch (error) {
|
|
191
|
+
if (error instanceof StandardError) {
|
|
192
|
+
throw error;
|
|
193
|
+
}
|
|
194
|
+
logger.error('User registration failed:', error);
|
|
195
|
+
throw new StandardError(ErrorCode.INTERNAL_ERROR, 'User registration failed', {}, error);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Authenticate user and generate tokens
|
|
200
|
+
*/ async login(request) {
|
|
201
|
+
const { email, password, rememberMe } = request;
|
|
202
|
+
try {
|
|
203
|
+
// Check rate limiting
|
|
204
|
+
if (AuthRateLimit.hasExceededAttempts(email, this.config.maxLoginAttempts, this.config.loginLockoutMs)) {
|
|
205
|
+
throw new StandardError(ErrorCode.TOO_MANY_REQUESTS, 'Too many login attempts. Please try again later.', {
|
|
206
|
+
retryAfter: Math.ceil(this.config.loginLockoutMs / 1000)
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
// Find user by email
|
|
210
|
+
const user = await this.findUserByEmail(email);
|
|
211
|
+
if (!user) {
|
|
212
|
+
AuthRateLimit.hasExceededAttempts(email, this.config.maxLoginAttempts, this.config.loginLockoutMs);
|
|
213
|
+
throw new StandardError(ErrorCode.NOT_FOUND, 'Invalid email or password');
|
|
214
|
+
}
|
|
215
|
+
// Check user status
|
|
216
|
+
if (user.status === UserStatus.SUSPENDED) {
|
|
217
|
+
throw new StandardError(ErrorCode.FORBIDDEN, 'Account suspended. Please contact support.');
|
|
218
|
+
}
|
|
219
|
+
if (user.status === UserStatus.INACTIVE) {
|
|
220
|
+
throw new StandardError(ErrorCode.FORBIDDEN, 'Account inactive. Please contact support.');
|
|
221
|
+
}
|
|
222
|
+
// Get user credentials
|
|
223
|
+
const credentials = await this.getUserCredentials(user.id);
|
|
224
|
+
if (!credentials) {
|
|
225
|
+
throw new StandardError(ErrorCode.INTERNAL_ERROR, 'User credentials not found');
|
|
226
|
+
}
|
|
227
|
+
// Verify password
|
|
228
|
+
const isPasswordValid = await PasswordUtils.comparePassword(password, credentials.passwordHash);
|
|
229
|
+
if (!isPasswordValid) {
|
|
230
|
+
AuthRateLimit.hasExceededAttempts(email, this.config.maxLoginAttempts, this.config.loginLockoutMs);
|
|
231
|
+
// Update failed login attempts
|
|
232
|
+
await this.updateFailedLoginAttempts(user.id, user.security.loginAttempts + 1);
|
|
233
|
+
throw new StandardError(ErrorCode.NOT_FOUND, 'Invalid email or password');
|
|
234
|
+
}
|
|
235
|
+
// Clear failed login attempts
|
|
236
|
+
AuthRateLimit.clearAttempts(email);
|
|
237
|
+
await this.updateFailedLoginAttempts(user.id, 0);
|
|
238
|
+
// Update last login
|
|
239
|
+
await this.updateLastLogin(user.id);
|
|
240
|
+
// Generate tokens
|
|
241
|
+
const tokens = await this.generateAuthTokens(user, rememberMe);
|
|
242
|
+
// Log successful login
|
|
243
|
+
logger.info('User logged in successfully', {
|
|
244
|
+
userId: user.id,
|
|
245
|
+
email
|
|
246
|
+
});
|
|
247
|
+
return {
|
|
248
|
+
user: this.toPublicUser(user),
|
|
249
|
+
accessToken: tokens.accessToken,
|
|
250
|
+
refreshToken: tokens.refreshToken,
|
|
251
|
+
expiresIn: tokens.expiresIn
|
|
252
|
+
};
|
|
253
|
+
} catch (error) {
|
|
254
|
+
if (error instanceof StandardError) {
|
|
255
|
+
throw error;
|
|
256
|
+
}
|
|
257
|
+
logger.error('Login failed:', error);
|
|
258
|
+
throw new StandardError(ErrorCode.INTERNAL_ERROR, 'Login failed', {}, error);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Refresh access token using refresh token
|
|
263
|
+
*/ async refreshToken(refreshToken) {
|
|
264
|
+
try {
|
|
265
|
+
// Validate refresh token
|
|
266
|
+
const payload = JWTUtils.verifyToken(refreshToken, this.config.jwtSecret);
|
|
267
|
+
if (payload.type !== 'refresh') {
|
|
268
|
+
throw new StandardError(ErrorCode.INVALID_TOKEN, 'Invalid refresh token');
|
|
269
|
+
}
|
|
270
|
+
// Check if refresh token exists and is not revoked
|
|
271
|
+
const tokenRecord = await this.findRefreshToken(payload.jti, payload.userId);
|
|
272
|
+
if (!tokenRecord || tokenRecord.isRevoked) {
|
|
273
|
+
throw new StandardError(ErrorCode.INVALID_TOKEN, 'Invalid or revoked refresh token');
|
|
274
|
+
}
|
|
275
|
+
// Find user
|
|
276
|
+
const user = await this.findUserById(payload.userId);
|
|
277
|
+
if (!user) {
|
|
278
|
+
throw new StandardError(ErrorCode.NOT_FOUND, 'User not found');
|
|
279
|
+
}
|
|
280
|
+
// Check user status
|
|
281
|
+
if (user.status !== UserStatus.ACTIVE) {
|
|
282
|
+
throw new StandardError(ErrorCode.FORBIDDEN, 'Account is not active');
|
|
283
|
+
}
|
|
284
|
+
// Revoke old refresh token
|
|
285
|
+
await this.revokeRefreshToken(payload.jti);
|
|
286
|
+
// Generate new tokens
|
|
287
|
+
const tokens = await this.generateAuthTokens(user);
|
|
288
|
+
// Update last used timestamp
|
|
289
|
+
await this.updateRefreshTokenLastUsed(payload.jti);
|
|
290
|
+
logger.info('Token refreshed successfully', {
|
|
291
|
+
userId: user.id
|
|
292
|
+
});
|
|
293
|
+
return tokens;
|
|
294
|
+
} catch (error) {
|
|
295
|
+
if (error instanceof StandardError) {
|
|
296
|
+
throw error;
|
|
297
|
+
}
|
|
298
|
+
logger.error('Token refresh failed:', error);
|
|
299
|
+
throw new StandardError(ErrorCode.INTERNAL_ERROR, 'Token refresh failed', {}, error);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Logout user and revoke tokens
|
|
304
|
+
*/ async logout(refreshToken) {
|
|
305
|
+
try {
|
|
306
|
+
// Validate refresh token
|
|
307
|
+
const payload = JWTUtils.decodeToken(refreshToken);
|
|
308
|
+
if (!payload || payload.type !== 'refresh') {
|
|
309
|
+
return; // Invalid token, just return success
|
|
310
|
+
}
|
|
311
|
+
// Revoke refresh token
|
|
312
|
+
if (payload.jti) {
|
|
313
|
+
await this.revokeRefreshToken(payload.jti);
|
|
314
|
+
}
|
|
315
|
+
logger.info('User logged out successfully', {
|
|
316
|
+
userId: payload.userId
|
|
317
|
+
});
|
|
318
|
+
} catch (error) {
|
|
319
|
+
logger.error('Logout failed:', error);
|
|
320
|
+
// Don't throw error on logout to prevent client issues
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Get user by ID
|
|
325
|
+
*/ async getUserById(userId) {
|
|
326
|
+
try {
|
|
327
|
+
const user = await this.findUserById(userId);
|
|
328
|
+
return user ? this.toPublicUser(user) : null;
|
|
329
|
+
} catch (error) {
|
|
330
|
+
logger.error('Failed to get user by ID:', error);
|
|
331
|
+
return null;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Update user profile
|
|
336
|
+
*/ async updateUserProfile(userId, updates) {
|
|
337
|
+
try {
|
|
338
|
+
const user = await this.findUserById(userId);
|
|
339
|
+
if (!user) {
|
|
340
|
+
throw new StandardError(ErrorCode.NOT_FOUND, 'User not found');
|
|
341
|
+
}
|
|
342
|
+
// Update user
|
|
343
|
+
const updatedUser = {
|
|
344
|
+
...user,
|
|
345
|
+
profile: {
|
|
346
|
+
...user.profile,
|
|
347
|
+
...updates.profile
|
|
348
|
+
},
|
|
349
|
+
privacy: {
|
|
350
|
+
...user.privacy,
|
|
351
|
+
...updates.privacy
|
|
352
|
+
},
|
|
353
|
+
preferences: {
|
|
354
|
+
...user.preferences,
|
|
355
|
+
...updates.preferences
|
|
356
|
+
},
|
|
357
|
+
updatedAt: new Date()
|
|
358
|
+
};
|
|
359
|
+
await this.saveUser(updatedUser);
|
|
360
|
+
logger.info('User profile updated successfully', {
|
|
361
|
+
userId
|
|
362
|
+
});
|
|
363
|
+
return this.toPublicUser(updatedUser);
|
|
364
|
+
} catch (error) {
|
|
365
|
+
if (error instanceof StandardError) {
|
|
366
|
+
throw error;
|
|
367
|
+
}
|
|
368
|
+
logger.error('Failed to update user profile:', error);
|
|
369
|
+
throw new StandardError(ErrorCode.INTERNAL_ERROR, 'Failed to update user profile', {}, error);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Change user password
|
|
374
|
+
*/ async changePassword(userId, currentPassword, newPassword) {
|
|
375
|
+
try {
|
|
376
|
+
// Validate new password
|
|
377
|
+
this.validatePassword(newPassword);
|
|
378
|
+
// Get current credentials
|
|
379
|
+
const credentials = await this.getUserCredentials(userId);
|
|
380
|
+
if (!credentials) {
|
|
381
|
+
throw new StandardError(ErrorCode.NOT_FOUND, 'User not found');
|
|
382
|
+
}
|
|
383
|
+
// Verify current password
|
|
384
|
+
const isCurrentPasswordValid = await PasswordUtils.comparePassword(currentPassword, credentials.passwordHash);
|
|
385
|
+
if (!isCurrentPasswordValid) {
|
|
386
|
+
throw new StandardError(ErrorCode.VALIDATION_FAILED, 'Current password is incorrect');
|
|
387
|
+
}
|
|
388
|
+
// Hash new password
|
|
389
|
+
const salt = await PasswordUtils.generateSalt();
|
|
390
|
+
const newPasswordHash = await PasswordUtils.hashPassword(newPassword, this.config.bcryptRounds);
|
|
391
|
+
// Update password
|
|
392
|
+
await this.updateUserPassword(userId, newPasswordHash, salt);
|
|
393
|
+
// Revoke all refresh tokens for this user
|
|
394
|
+
await this.revokeAllUserRefreshTokens(userId);
|
|
395
|
+
logger.info('Password changed successfully', {
|
|
396
|
+
userId
|
|
397
|
+
});
|
|
398
|
+
} catch (error) {
|
|
399
|
+
if (error instanceof StandardError) {
|
|
400
|
+
throw error;
|
|
401
|
+
}
|
|
402
|
+
logger.error('Failed to change password:', error);
|
|
403
|
+
throw new StandardError(ErrorCode.INTERNAL_ERROR, 'Failed to change password', {}, error);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Validate JWT token and return user context
|
|
408
|
+
*/ async validateToken(token) {
|
|
409
|
+
try {
|
|
410
|
+
return this.authMiddleware.validateToken(token);
|
|
411
|
+
} catch (error) {
|
|
412
|
+
throw new StandardError(ErrorCode.INVALID_TOKEN, 'Invalid authentication token', {}, error);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Check if user has permission for an operation
|
|
417
|
+
*/ async checkPermission(userContext, operation) {
|
|
418
|
+
try {
|
|
419
|
+
return this.rbacEnforcer.hasPermission(userContext, operation);
|
|
420
|
+
} catch (error) {
|
|
421
|
+
logger.error('Permission check failed:', error);
|
|
422
|
+
return false;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Enforce permission check - throws if user lacks permission
|
|
427
|
+
*/ async enforcePermission(userContext, operation, skillId) {
|
|
428
|
+
try {
|
|
429
|
+
this.rbacEnforcer.enforcePermission(userContext, operation, skillId);
|
|
430
|
+
} catch (error) {
|
|
431
|
+
if (error instanceof StandardError) {
|
|
432
|
+
throw error;
|
|
433
|
+
}
|
|
434
|
+
throw new StandardError(ErrorCode.FORBIDDEN, 'Permission check failed', {}, error);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
// Private helper methods
|
|
438
|
+
validateEmail(email) {
|
|
439
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
440
|
+
if (!emailRegex.test(email)) {
|
|
441
|
+
throw new StandardError(ErrorCode.VALIDATION_FAILED, 'Invalid email format');
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
validateUsername(username) {
|
|
445
|
+
if (username.length < 3 || username.length > 30) {
|
|
446
|
+
throw new StandardError(ErrorCode.VALIDATION_FAILED, 'Username must be between 3 and 30 characters');
|
|
447
|
+
}
|
|
448
|
+
const usernameRegex = /^[a-zA-Z0-9_-]+$/;
|
|
449
|
+
if (!usernameRegex.test(username)) {
|
|
450
|
+
throw new StandardError(ErrorCode.VALIDATION_FAILED, 'Username can only contain letters, numbers, underscores, and hyphens');
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
validatePassword(password) {
|
|
454
|
+
if (!PasswordUtils.validatePasswordStrength(password)) {
|
|
455
|
+
throw new StandardError(ErrorCode.VALIDATION_FAILED, 'Password must be at least 8 characters long and contain uppercase, lowercase, number, and special character');
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
async generateAuthTokens(user, rememberMe = false) {
|
|
459
|
+
const expiresIn = rememberMe ? '30d' : this.config.jwtExpiration;
|
|
460
|
+
const refreshExpiresIn = rememberMe ? '90d' : this.config.refreshExpiration;
|
|
461
|
+
// Generate access token
|
|
462
|
+
const accessTokenPayload = {
|
|
463
|
+
userId: user.id,
|
|
464
|
+
email: user.email,
|
|
465
|
+
role: user.role,
|
|
466
|
+
type: 'access'
|
|
467
|
+
};
|
|
468
|
+
const accessToken = JWTUtils.generateToken(accessTokenPayload, this.config.jwtSecret, expiresIn);
|
|
469
|
+
// Generate refresh token
|
|
470
|
+
const refreshTokenId = uuidv4();
|
|
471
|
+
const refreshTokenPayload = {
|
|
472
|
+
userId: user.id,
|
|
473
|
+
email: user.email,
|
|
474
|
+
role: user.role,
|
|
475
|
+
type: 'refresh',
|
|
476
|
+
jti: refreshTokenId
|
|
477
|
+
};
|
|
478
|
+
const refreshToken = JWTUtils.generateToken(refreshTokenPayload, this.config.jwtSecret, refreshExpiresIn);
|
|
479
|
+
// Save refresh token to database
|
|
480
|
+
const now = Math.floor(Date.now() / 1000);
|
|
481
|
+
const refreshTokenHash = await PasswordUtils.hashPassword(refreshToken, 10);
|
|
482
|
+
const expiresAt = now + (rememberMe ? 90 * 24 * 60 * 60 : 7 * 24 * 60 * 60); // 90 days or 7 days
|
|
483
|
+
await this.saveRefreshToken(refreshTokenId, user.id, refreshTokenHash, expiresAt);
|
|
484
|
+
// Calculate expiresIn in seconds
|
|
485
|
+
const expiresInSeconds = rememberMe ? 30 * 24 * 60 * 60 : 24 * 60 * 60; // 30 days or 24 hours
|
|
486
|
+
return {
|
|
487
|
+
accessToken,
|
|
488
|
+
refreshToken,
|
|
489
|
+
expiresIn: expiresInSeconds
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
toPublicUser(user) {
|
|
493
|
+
return {
|
|
494
|
+
id: user.id,
|
|
495
|
+
username: user.username,
|
|
496
|
+
email: user.email,
|
|
497
|
+
role: user.role,
|
|
498
|
+
status: user.status,
|
|
499
|
+
profile: {
|
|
500
|
+
displayName: user.profile.displayName,
|
|
501
|
+
firstName: user.profile.firstName,
|
|
502
|
+
lastName: user.profile.lastName,
|
|
503
|
+
bio: user.profile.bio,
|
|
504
|
+
avatar: user.profile.avatar
|
|
505
|
+
},
|
|
506
|
+
security: {
|
|
507
|
+
emailVerified: user.security.emailVerified,
|
|
508
|
+
twoFactorEnabled: user.security.twoFactorEnabled
|
|
509
|
+
}
|
|
510
|
+
};
|
|
511
|
+
}
|
|
512
|
+
// Database helper methods
|
|
513
|
+
async findUserById(userId) {
|
|
514
|
+
const adapter = this.db.getAdapter('sqlite');
|
|
515
|
+
const row = await adapter.get('SELECT * FROM users WHERE id = ?', [
|
|
516
|
+
userId
|
|
517
|
+
]);
|
|
518
|
+
return row ? this.rowToUser(row) : null;
|
|
519
|
+
}
|
|
520
|
+
async findUserByEmail(email) {
|
|
521
|
+
const adapter = this.db.getAdapter('sqlite');
|
|
522
|
+
const row = await adapter.get('SELECT * FROM users WHERE email = ?', [
|
|
523
|
+
email
|
|
524
|
+
]);
|
|
525
|
+
return row ? this.rowToUser(row) : null;
|
|
526
|
+
}
|
|
527
|
+
async findUserByEmailOrUsername(email, username) {
|
|
528
|
+
const adapter = this.db.getAdapter('sqlite');
|
|
529
|
+
const row = await adapter.get('SELECT * FROM users WHERE email = ? OR username = ?', [
|
|
530
|
+
email,
|
|
531
|
+
username
|
|
532
|
+
]);
|
|
533
|
+
return row ? this.rowToUser(row) : null;
|
|
534
|
+
}
|
|
535
|
+
async getUserCredentials(userId) {
|
|
536
|
+
const adapter = this.db.getAdapter('sqlite');
|
|
537
|
+
const row = await adapter.get('SELECT password_hash, salt FROM users WHERE id = ?', [
|
|
538
|
+
userId
|
|
539
|
+
]);
|
|
540
|
+
return row ? {
|
|
541
|
+
passwordHash: row.password_hash,
|
|
542
|
+
salt: row.salt
|
|
543
|
+
} : null;
|
|
544
|
+
}
|
|
545
|
+
async saveUser(user, passwordHash, salt) {
|
|
546
|
+
const adapter = this.db.getAdapter('sqlite');
|
|
547
|
+
const now = Math.floor(Date.now() / 1000);
|
|
548
|
+
await adapter.execute(`
|
|
549
|
+
INSERT OR REPLACE INTO users (
|
|
550
|
+
id, username, email, role, status, password_hash, salt,
|
|
551
|
+
profile_json, privacy_json, preferences_json, security_json, stats_json,
|
|
552
|
+
created_at, updated_at, last_login_at, email_verified_at, phone_verified_at
|
|
553
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
554
|
+
`, [
|
|
555
|
+
user.id,
|
|
556
|
+
user.username,
|
|
557
|
+
user.email,
|
|
558
|
+
user.role,
|
|
559
|
+
user.status,
|
|
560
|
+
passwordHash,
|
|
561
|
+
salt,
|
|
562
|
+
JSON.stringify(user.profile),
|
|
563
|
+
JSON.stringify(user.privacy),
|
|
564
|
+
JSON.stringify(user.preferences),
|
|
565
|
+
JSON.stringify(user.security),
|
|
566
|
+
JSON.stringify(user.stats),
|
|
567
|
+
Math.floor(user.createdAt.getTime() / 1000),
|
|
568
|
+
now,
|
|
569
|
+
user.updatedAt ? Math.floor(user.updatedAt.getTime() / 1000) : now,
|
|
570
|
+
user.security.emailVerifiedAt ? Math.floor(user.security.emailVerifiedAt.getTime() / 1000) : null,
|
|
571
|
+
user.security.phoneVerifiedAt ? Math.floor(user.security.phoneVerifiedAt.getTime() / 1000) : null
|
|
572
|
+
]);
|
|
573
|
+
}
|
|
574
|
+
async updateFailedLoginAttempts(userId, attempts) {
|
|
575
|
+
const adapter = this.db.getAdapter('sqlite');
|
|
576
|
+
const lockedUntil = attempts >= this.config.maxLoginAttempts ? Math.floor(Date.now() / 1000) + Math.floor(this.config.loginLockoutMs / 1000) : null;
|
|
577
|
+
await adapter.execute(`
|
|
578
|
+
UPDATE users
|
|
579
|
+
SET security_json = json_set(
|
|
580
|
+
json_set(security_json, '$.loginAttempts', ?),
|
|
581
|
+
'$.lockedUntil',
|
|
582
|
+
?
|
|
583
|
+
)
|
|
584
|
+
WHERE id = ?
|
|
585
|
+
`, [
|
|
586
|
+
attempts,
|
|
587
|
+
lockedUntil,
|
|
588
|
+
userId
|
|
589
|
+
]);
|
|
590
|
+
}
|
|
591
|
+
async updateLastLogin(userId) {
|
|
592
|
+
const adapter = this.db.getAdapter('sqlite');
|
|
593
|
+
const now = Math.floor(Date.now() / 1000);
|
|
594
|
+
await adapter.execute(`
|
|
595
|
+
UPDATE users
|
|
596
|
+
SET last_login_at = ?, updated_at = ?
|
|
597
|
+
WHERE id = ?
|
|
598
|
+
`, [
|
|
599
|
+
now,
|
|
600
|
+
now,
|
|
601
|
+
userId
|
|
602
|
+
]);
|
|
603
|
+
}
|
|
604
|
+
async updateRefreshTokenLastUsed(tokenId) {
|
|
605
|
+
const adapter = this.db.getAdapter('sqlite');
|
|
606
|
+
const now = Math.floor(Date.now() / 1000);
|
|
607
|
+
await adapter.execute(`
|
|
608
|
+
UPDATE refresh_tokens
|
|
609
|
+
SET last_used_at = ?
|
|
610
|
+
WHERE id = ?
|
|
611
|
+
`, [
|
|
612
|
+
now,
|
|
613
|
+
tokenId
|
|
614
|
+
]);
|
|
615
|
+
}
|
|
616
|
+
async saveRefreshToken(tokenId, userId, tokenHash, expiresAt) {
|
|
617
|
+
const adapter = this.db.getAdapter('sqlite');
|
|
618
|
+
const now = Math.floor(Date.now() / 1000);
|
|
619
|
+
await adapter.execute(`
|
|
620
|
+
INSERT INTO refresh_tokens (id, user_id, token_hash, expires_at, created_at)
|
|
621
|
+
VALUES (?, ?, ?, ?, ?)
|
|
622
|
+
`, [
|
|
623
|
+
tokenId,
|
|
624
|
+
userId,
|
|
625
|
+
tokenHash,
|
|
626
|
+
expiresAt,
|
|
627
|
+
now
|
|
628
|
+
]);
|
|
629
|
+
}
|
|
630
|
+
async findRefreshToken(tokenId, userId) {
|
|
631
|
+
const adapter = this.db.getAdapter('sqlite');
|
|
632
|
+
const row = await adapter.get('SELECT id, is_revoked FROM refresh_tokens WHERE id = ? AND user_id = ? AND expires_at > ?', [
|
|
633
|
+
tokenId,
|
|
634
|
+
userId,
|
|
635
|
+
Math.floor(Date.now() / 1000)
|
|
636
|
+
]);
|
|
637
|
+
return row;
|
|
638
|
+
}
|
|
639
|
+
async revokeRefreshToken(tokenId) {
|
|
640
|
+
const adapter = this.db.getAdapter('sqlite');
|
|
641
|
+
await adapter.execute('UPDATE refresh_tokens SET is_revoked = TRUE WHERE id = ?', [
|
|
642
|
+
tokenId
|
|
643
|
+
]);
|
|
644
|
+
}
|
|
645
|
+
async revokeAllUserRefreshTokens(userId) {
|
|
646
|
+
const adapter = this.db.getAdapter('sqlite');
|
|
647
|
+
await adapter.execute('UPDATE refresh_tokens SET is_revoked = TRUE WHERE user_id = ?', [
|
|
648
|
+
userId
|
|
649
|
+
]);
|
|
650
|
+
}
|
|
651
|
+
async updateUserPassword(userId, passwordHash, salt) {
|
|
652
|
+
const adapter = this.db.getAdapter('sqlite');
|
|
653
|
+
const now = Math.floor(Date.now() / 1000);
|
|
654
|
+
await adapter.execute(`
|
|
655
|
+
UPDATE users
|
|
656
|
+
SET password_hash = ?, salt = ?, updated_at = ?,
|
|
657
|
+
security_json = json_set(security_json, '$.lastPasswordChange', ?)
|
|
658
|
+
WHERE id = ?
|
|
659
|
+
`, [
|
|
660
|
+
passwordHash,
|
|
661
|
+
salt,
|
|
662
|
+
now,
|
|
663
|
+
now,
|
|
664
|
+
userId
|
|
665
|
+
]);
|
|
666
|
+
}
|
|
667
|
+
async createEmailVerificationToken(userId, email) {
|
|
668
|
+
const adapter = this.db.getAdapter('sqlite');
|
|
669
|
+
const tokenId = uuidv4();
|
|
670
|
+
const token = uuidv4();
|
|
671
|
+
const tokenHash = await PasswordUtils.hashPassword(token, 10);
|
|
672
|
+
const expiresAt = Math.floor(Date.now() / 1000) + 24 * 60 * 60; // 24 hours
|
|
673
|
+
await adapter.execute(`
|
|
674
|
+
INSERT INTO email_verification_tokens (id, user_id, email, token_hash, expires_at, created_at)
|
|
675
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
676
|
+
`, [
|
|
677
|
+
tokenId,
|
|
678
|
+
userId,
|
|
679
|
+
email,
|
|
680
|
+
tokenHash,
|
|
681
|
+
expiresAt,
|
|
682
|
+
Math.floor(Date.now() / 1000)
|
|
683
|
+
]);
|
|
684
|
+
// In a real implementation, send email with token
|
|
685
|
+
logger.info('Email verification token created', {
|
|
686
|
+
userId,
|
|
687
|
+
email,
|
|
688
|
+
token
|
|
689
|
+
});
|
|
690
|
+
}
|
|
691
|
+
rowToUser(row) {
|
|
692
|
+
return {
|
|
693
|
+
id: row.id,
|
|
694
|
+
username: row.username,
|
|
695
|
+
email: row.email,
|
|
696
|
+
role: row.role,
|
|
697
|
+
status: row.status,
|
|
698
|
+
profile: JSON.parse(row.profile_json),
|
|
699
|
+
privacy: JSON.parse(row.privacy_json),
|
|
700
|
+
preferences: JSON.parse(row.preferences_json),
|
|
701
|
+
security: JSON.parse(row.security_json),
|
|
702
|
+
stats: JSON.parse(row.stats_json),
|
|
703
|
+
createdAt: new Date(row.created_at * 1000),
|
|
704
|
+
updatedAt: new Date(row.updated_at * 1000)
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
export default UserService;
|
|
709
|
+
|
|
710
|
+
//# sourceMappingURL=user-service.js.map
|