@spinajs/rbac-http-user 2.0.502 → 2.0.505
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/lib/cjs/2fa/Default2FaToken.d.ts +8 -0
- package/lib/cjs/2fa/Default2FaToken.d.ts.map +1 -1
- package/lib/cjs/2fa/Default2FaToken.js +25 -3
- package/lib/cjs/2fa/Default2FaToken.js.map +1 -1
- package/lib/cjs/actions/2fa.d.ts +22 -3
- package/lib/cjs/actions/2fa.d.ts.map +1 -1
- package/lib/cjs/actions/2fa.js +44 -3
- package/lib/cjs/actions/2fa.js.map +1 -1
- package/lib/cjs/config/rbac-http.d.ts.map +1 -1
- package/lib/cjs/config/rbac-http.js +6 -0
- package/lib/cjs/config/rbac-http.js.map +1 -1
- package/lib/cjs/controllers/LoginController.d.ts.map +1 -1
- package/lib/cjs/controllers/LoginController.js +10 -1
- package/lib/cjs/controllers/LoginController.js.map +1 -1
- package/lib/cjs/controllers/TwoFactorAuthController.d.ts +13 -3
- package/lib/cjs/controllers/TwoFactorAuthController.d.ts.map +1 -1
- package/lib/cjs/controllers/TwoFactorAuthController.js +32 -6
- package/lib/cjs/controllers/TwoFactorAuthController.js.map +1 -1
- package/lib/cjs/controllers/TwoFactorAuthUserController.d.ts +71 -4
- package/lib/cjs/controllers/TwoFactorAuthUserController.d.ts.map +1 -1
- package/lib/cjs/controllers/TwoFactorAuthUserController.js +136 -16
- package/lib/cjs/controllers/TwoFactorAuthUserController.js.map +1 -1
- package/lib/cjs/policies/2FaPolicy.d.ts.map +1 -1
- package/lib/cjs/policies/2FaPolicy.js +27 -6
- package/lib/cjs/policies/2FaPolicy.js.map +1 -1
- package/lib/mjs/2fa/Default2FaToken.d.ts +8 -0
- package/lib/mjs/2fa/Default2FaToken.d.ts.map +1 -1
- package/lib/mjs/2fa/Default2FaToken.js +25 -3
- package/lib/mjs/2fa/Default2FaToken.js.map +1 -1
- package/lib/mjs/actions/2fa.d.ts +22 -3
- package/lib/mjs/actions/2fa.d.ts.map +1 -1
- package/lib/mjs/actions/2fa.js +41 -3
- package/lib/mjs/actions/2fa.js.map +1 -1
- package/lib/mjs/config/rbac-http.d.ts.map +1 -1
- package/lib/mjs/config/rbac-http.js +6 -0
- package/lib/mjs/config/rbac-http.js.map +1 -1
- package/lib/mjs/controllers/LoginController.d.ts.map +1 -1
- package/lib/mjs/controllers/LoginController.js +10 -1
- package/lib/mjs/controllers/LoginController.js.map +1 -1
- package/lib/mjs/controllers/TwoFactorAuthController.d.ts +13 -3
- package/lib/mjs/controllers/TwoFactorAuthController.d.ts.map +1 -1
- package/lib/mjs/controllers/TwoFactorAuthController.js +35 -9
- package/lib/mjs/controllers/TwoFactorAuthController.js.map +1 -1
- package/lib/mjs/controllers/TwoFactorAuthUserController.d.ts +71 -4
- package/lib/mjs/controllers/TwoFactorAuthUserController.d.ts.map +1 -1
- package/lib/mjs/controllers/TwoFactorAuthUserController.js +140 -20
- package/lib/mjs/controllers/TwoFactorAuthUserController.js.map +1 -1
- package/lib/mjs/policies/2FaPolicy.d.ts.map +1 -1
- package/lib/mjs/policies/2FaPolicy.js +26 -5
- package/lib/mjs/policies/2FaPolicy.js.map +1 -1
- package/lib/tsconfig.cjs.tsbuildinfo +1 -1
- package/lib/tsconfig.mjs.tsbuildinfo +1 -1
- package/package.json +15 -15
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LoginController.js","sourceRoot":"","sources":["../../../src/controllers/LoginController.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACpG,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACzI,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAElF,OAAO,EAAE,YAAY,EAAE,IAAI,IAAI,YAAY,EAAE,OAAO,IAAI,eAAe,EAAE,SAAS,EAAE,WAAW,EAAmC,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAClL,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,OAAO,EAAE,aAAa,EAAkB,MAAM,cAAc,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAGnE;;;;;GAKG;AAEI,IAAM,eAAe,GAArB,MAAM,eAAgB,SAAQ,cAAc;IA2BjD;;;;;;;;;OASG;IAGU,AAAN,KAAK,CAAC,KAAK,CAAiB,MAAY,EAAe,IAAY,EAAU,WAAyB;QAC3G,IAAI,CAAC;YAEH,0DAA0D;YAC1D,2BAA2B;YAC3B,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;gBACnB,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC1C,CAAC;YAED,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,WAAW,CAAC,KAAK,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;YAClE,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;YAElC,IAAI,MAAsB,CAAC;YAE3B,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YAEpC,8DAA8D;YAC9D,oEAAoE;YACpE,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAClC,IAAI,UAAU,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;YAC7C,CAAC;YAED,8BAA8B;YAC9B,sEAAsE;YACtE,+EAA+E;YAC/E,yDAAyD;YACzD,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YACjC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;YAEzB,MAAM,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC,CAAC;YAEnF,IAAI,IAAI,CAAC,sBAAsB,IAAI,CAAC,mBAAmB,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"LoginController.js","sourceRoot":"","sources":["../../../src/controllers/LoginController.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACpG,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACzI,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAElF,OAAO,EAAE,YAAY,EAAE,IAAI,IAAI,YAAY,EAAE,OAAO,IAAI,eAAe,EAAE,SAAS,EAAE,WAAW,EAAmC,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAClL,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,OAAO,EAAE,aAAa,EAAkB,MAAM,cAAc,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAGnE;;;;;GAKG;AAEI,IAAM,eAAe,GAArB,MAAM,eAAgB,SAAQ,cAAc;IA2BjD;;;;;;;;;OASG;IAGU,AAAN,KAAK,CAAC,KAAK,CAAiB,MAAY,EAAe,IAAY,EAAU,WAAyB;QAC3G,IAAI,CAAC;YAEH,0DAA0D;YAC1D,2BAA2B;YAC3B,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;gBACnB,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC1C,CAAC;YAED,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,WAAW,CAAC,KAAK,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;YAClE,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;YAElC,IAAI,MAAsB,CAAC;YAE3B,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YAEpC,8DAA8D;YAC9D,oEAAoE;YACpE,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAClC,IAAI,UAAU,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;YAC7C,CAAC;YAED,8BAA8B;YAC9B,sEAAsE;YACtE,+EAA+E;YAC/E,yDAAyD;YACzD,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YACjC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;YAEzB,MAAM,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC,CAAC;YAEnF,0DAA0D;YAC1D,6DAA6D;YAC7D,qEAAqE;YACrE,+EAA+E;YAC/E,sEAAsE;YACtE,gEAAgE;YAChE,wEAAwE;YACxE,sEAAsE;YACtE,iBAAiB;YACjB,IAAI,IAAI,CAAC,oBAAoB,IAAI,IAAI,CAAC,sBAAsB,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBACrF,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,mCAAmC,EAAE;oBACnD,IAAI,EAAE,IAAI,CAAC,IAAI;iBAChB,CAAC,CAAC;gBAEH,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;gBACtC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;gBAExC,MAAM,GAAG,EAAE,qBAAqB,EAAE,IAAI,EAAE,CAAC;YAC3C,CAAC;iBACI,IAAI,IAAI,CAAC,oBAAoB,IAAI,mBAAmB,EAAE,CAAC;gBAE1D,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,8BAA8B,EAAE;oBAC9C,IAAI,EAAE,IAAI,CAAC,IAAI;iBAChB,CAAC,CAAC;gBAEH,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;gBACtC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;gBAExC,MAAM,GAAG,EAAE,qBAAqB,EAAE,IAAI,EAAE,CAAC;YAC3C,CAAC;iBAAM,CAAC;gBAEN,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;gBAErC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,iCAAiC,EAAE;oBACjD,IAAI,EAAE,IAAI,CAAC,IAAI;iBAChB,CAAC,CAAC;gBAEH,MAAM,GAAG,mBAAmB,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;YAC1D,CAAC;YAED,uEAAuE;YACvE,0EAA0E;YAC1E,0DAA0D;YAC1D,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAEzC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE;gBAChC,sEAAsE;gBACtE,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,SAAS,CAAC;gBACzC,IAAI,EAAE,IAAI,CAAC,IAAI;aAChB,CAAC,CAAC;YAEH,OAAO,IAAI,EAAE,CAAC,MAAM,EAAE;gBACpB,QAAQ,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBAE9C,qEAAqE;gBACrE,6DAA6D;gBAC7D,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;aACxD,CAAC,CAAC;QAEL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,yEAAyE;YACzE,wEAAwE;YACxE,wEAAwE;YACxE,yEAAyE;YACzE,kEAAkE;YAClE,qEAAqE;YACrE,8CAA8C;YAC9C,MAAM,aAAa,GAAG,GAAG,YAAY,SAAS,IAAI,GAAG,YAAY,eAAe,CAAC;YAEjF,IAAI,CAAC,aAAa,EAAE,CAAC;gBACnB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAY,EAAE,iCAAiC,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC;gBACrF,MAAM,GAAG,CAAC;YACZ,CAAC;YAED,MAAM,MAAM,GAAG,GAAG,YAAY,SAAS,CAAC,CAAC,CAAC,uBAAuB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,oBAAoB,CAAC;YAE/G,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAY,EAAE,oBAAoB,WAAW,EAAE,KAAK,KAAK,MAAM,EAAE,CAAC,CAAC;YAElF,OAAO,IAAI,YAAY,CAAC;gBACtB,KAAK,EAAE;oBACL,IAAI,EAAE,eAAe;oBACrB,OAAO,EAAE,6BAA6B;iBACvC;aACF,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;;;;;;;;;;;OAYG;IAGU,AAAN,KAAK,CAAC,MAAM,CAAc,IAAY,EAAqB,OAAiB,EAAkB,IAAU;QAC7G,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,IAAI,EAAE,EAAE,CAAC;QAClB,CAAC;QAED,uEAAuE;QACvE,wEAAwE;QACxE,kCAAkC;QAClC,iEAAiE;QACjE,gDAAgD;QAChD,0EAA0E;QAC1E,sBAAsB;QACtB,wEAAwE;QACxE,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC;QAC/D,MAAM,MAAM,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;QAErE,MAAM,GAAG,GAAmB,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QACzE,KAAK,MAAM,OAAO,IAAI,MAAM,EAAE,CAAC;YAC7B,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACzC,IAAI,MAAM,EAAE,CAAC;gBACX,OAAO,IAAI,EAAE,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,EAAE;oBACjC,QAAQ,EAAE,MAAM,CAAC,OAAO,IAAI,EAAE;oBAC9B,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,EAAE;iBAC9B,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,oEAAoE;QACpE,qEAAqE;QACrE,OAAO,IAAI,EAAE,EAAE,CAAC;IAClB,CAAC;IAED;;;;;;;;;OASG;IAGU,AAAN,KAAK,CAAC,MAAM,CAAiB,IAAU,EAAiB,UAAkB,EAAqB,OAAiB;QAErH,OAAO,IAAI,EAAE,CAAC;YACZ,GAAG,IAAI,CAAC,sBAAsB,CAAC,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC;YAEzD,yEAAyE;YACzE,uEAAuE;YACvE,uEAAuE;YACvE,yEAAyE;YACzE,yDAAyD;YACzD,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,UAAU,EAAE,UAAU,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;YACxC,UAAU,EAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAyB,IAAI,IAAI;YAE3E,gEAAgE;YAChE,0EAA0E;YAC1E,uEAAuE;YACvE,kEAAkE;SACrC,CAAC,CAAC;IACnC,CAAC;CACF,CAAA;AA3OW;IADT,UAAU,EAAE;8BACY,aAAa;sDAAC;AAG7B;IADT,iBAAiB,CAAC,WAAW,CAAC;8BACP,YAAY;qDAAC;AAG3B;IADT,iBAAiB,CAAC,cAAc,CAAC;8BACP,eAAe;wDAAC;AAKjC;IAHT,MAAM,CAAC,4BAA4B,EAAE;QACpC,YAAY,EAAE,KAAK;KACpB,CAAC;;6DACsC;AAM9B;IAHT,MAAM,CAAC,8BAA8B,EAAE;QACtC,YAAY,EAAE,KAAK;KACpB,CAAC;;+DACwC;AAGhC;IADT,UAAU,CAAC,oBAAoB,CAAC;8BACP,oBAAoB;uDAAC;AAGrC;IADT,UAAU,CAAC,aAAa,CAAC;8BACZ,aAAa;2CAAC;AAcf;IAFZ,IAAI,EAAE;IACN,mBAAmB,EAAE;IACF,WAAA,YAAY,EAAE,CAAA;IAAgB,WAAA,SAAS,EAAE,CAAA;IAAgB,WAAA,IAAI,EAAE,CAAA;;qCAAxC,IAAI,UAAkD,YAAY;;4CAqH5G;AAiBY;IAFZ,IAAI,EAAE;IACN,MAAM,CAAC,YAAY,CAAC;IACA,WAAA,SAAS,EAAE,CAAA;IAAgB,WAAA,eAAe,EAAE,CAAA;IAAqB,WAAA,YAAY,EAAE,CAAA;;qDAAO,IAAI;;6CA8B9G;AAcY;IAFZ,GAAG,EAAE;IACL,MAAM,CAAC,YAAY,CAAC;IACA,WAAA,YAAY,EAAE,CAAA;IAAc,WAAA,WAAW,EAAE,CAAA;IAAsB,WAAA,eAAe,EAAE,CAAA;;qCAA3D,IAAI;;6CAmB7C;AA5OU,eAAe;IAD3B,QAAQ,CAAC,MAAM,CAAC;GACJ,eAAe,CA6O3B"}
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { TokenDto } from './../dto/token-dto.js';
|
|
2
2
|
import { BaseController, Ok, ForbiddenResponse } from '@spinajs/http';
|
|
3
3
|
import { ISession, SessionProvider, User as UserModel, AccessControl } from '@spinajs/rbac';
|
|
4
|
-
import { IEnable2faResponse, IUserWithGrants } from '@spinajs/rbac-http';
|
|
4
|
+
import { IEnable2faResponse, IUserWithGrants, TwoFactorAuthConfig } from '@spinajs/rbac-http';
|
|
5
5
|
import { SessionCookieFactory } from '../services/SessionCookies.js';
|
|
6
6
|
/**
|
|
7
7
|
* Two-factor authentication during login.
|
|
8
8
|
*
|
|
9
9
|
* These routes serve the narrow window between a successful password check and
|
|
10
10
|
* full authorization: the session is `Logged` but not `Authorized` and carries
|
|
11
|
-
* the `TwoFactorAuth` marker. Both class policies
|
|
12
|
-
* closes the moment
|
|
11
|
+
* the `TwoFactorAuth` marker. Both class policies are passed to one `@Policy`
|
|
12
|
+
* call, so they are combined with AND and the window closes the moment
|
|
13
|
+
* verification succeeds. `TwoFacRouteEnabled` also enforces the system-wide
|
|
14
|
+
* switch, by way of the `TwoFactorAuthEnabled` it extends.
|
|
13
15
|
*
|
|
14
16
|
* Managing a TOTP device outside that window — enrolling for the first time, or
|
|
15
17
|
* turning 2FA off — lives on {@link TwoFactorAuthUserController} under
|
|
@@ -24,6 +26,7 @@ export declare class TwoFactorAuthController extends BaseController {
|
|
|
24
26
|
protected SessionProvider: SessionProvider;
|
|
25
27
|
protected SessionCookies: SessionCookieFactory;
|
|
26
28
|
protected AC: AccessControl;
|
|
29
|
+
protected TwoFactorConfig: TwoFactorAuthConfig;
|
|
27
30
|
/**
|
|
28
31
|
* Set up two-factor authentication during login
|
|
29
32
|
* Generates a TOTP secret for a user who must enrol before continuing — the state
|
|
@@ -53,5 +56,12 @@ export declare class TwoFactorAuthController extends BaseController {
|
|
|
53
56
|
* verification without a TOTP/DB setup.
|
|
54
57
|
*/
|
|
55
58
|
protected verifyTwoFactorToken(user: UserModel, token: string): Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* Store the TOTP secret without switching 2fa on. Wrapped in a protected
|
|
61
|
+
* method for the same reason as {@link verifyTwoFactorToken}.
|
|
62
|
+
*/
|
|
63
|
+
protected enrol(user: UserModel): Promise<unknown>;
|
|
64
|
+
/** Switch 2fa on for an account whose secret was just verified. */
|
|
65
|
+
protected activateEnrolment(user: UserModel): Promise<unknown>;
|
|
56
66
|
}
|
|
57
67
|
//# sourceMappingURL=TwoFactorAuthController.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TwoFactorAuthController.d.ts","sourceRoot":"","sources":["../../../src/controllers/TwoFactorAuthController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAY,EAAE,EAAQ,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACtF,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,IAAI,IAAI,SAAS,EAAE,aAAa,EAAqB,MAAM,eAAe,CAAC;AAO/G,OAAO,EAA6B,kBAAkB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"TwoFactorAuthController.d.ts","sourceRoot":"","sources":["../../../src/controllers/TwoFactorAuthController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAY,EAAE,EAAQ,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACtF,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,IAAI,IAAI,SAAS,EAAE,aAAa,EAAqB,MAAM,eAAe,CAAC;AAO/G,OAAO,EAA6B,kBAAkB,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAIzH,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAGrE;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAEa,uBAAwB,SAAQ,cAAc;IAEzD,SAAS,CAAC,eAAe,EAAE,eAAe,CAAC;IAG3C,SAAS,CAAC,cAAc,EAAE,oBAAoB,CAAC;IAG/C,SAAS,CAAC,EAAE,EAAE,aAAa,CAAC;IAG5B,SAAS,CAAC,eAAe,EAAE,mBAAmB,CAAC;IAE/C;;;;;;;;;;;OAWG;IAEU,QAAQ,CAAS,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAc9E;IAED;;;;;;;;OAQG;IAEU,WAAW,CAAS,MAAM,EAAE,SAAS,EAAU,KAAK,EAAE,QAAQ,EAAa,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,EAAE,CAAC,eAAe,CAAC,GAAG,iBAAiB,CAAC,CA8C3J;IAED;;;;OAIG;IACH,SAAS,CAAC,oBAAoB,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5E;IAED;;;OAGG;IACH,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAEjD;IAED,mEAAmE;IACnE,SAAS,CAAC,iBAAiB,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAE7D;CAEF"}
|
|
@@ -16,11 +16,11 @@ import { SessionProvider, User as UserModel, AccessControl, regenerateSession }
|
|
|
16
16
|
import { Session } from '@spinajs/rbac-http';
|
|
17
17
|
import { Body, Policy } from '@spinajs/http';
|
|
18
18
|
import { TwoFacRouteEnabled } from '../policies/2FaPolicy.js';
|
|
19
|
-
import { AutoinjectService } from '@spinajs/configuration';
|
|
19
|
+
import { AutoinjectService, Config } from '@spinajs/configuration';
|
|
20
20
|
import { Autoinject } from '@spinajs/di';
|
|
21
21
|
import { User, NotAuthorizedPolicy } from '@spinajs/rbac-http';
|
|
22
|
-
import { auth2Fa,
|
|
23
|
-
import {
|
|
22
|
+
import { auth2Fa, activateUser2Fa, beginUser2FaEnrolment } from '../actions/2fa.js';
|
|
23
|
+
import { BadRequest } from '@spinajs/exceptions';
|
|
24
24
|
import { TWO_FA_METATADATA_KEYS } from '../2fa/Default2FaToken.js';
|
|
25
25
|
import { SessionCookieFactory } from '../services/SessionCookies.js';
|
|
26
26
|
import { activeRoleOf, buildUserWithGrants } from '../services/grants.js';
|
|
@@ -29,8 +29,10 @@ import { activeRoleOf, buildUserWithGrants } from '../services/grants.js';
|
|
|
29
29
|
*
|
|
30
30
|
* These routes serve the narrow window between a successful password check and
|
|
31
31
|
* full authorization: the session is `Logged` but not `Authorized` and carries
|
|
32
|
-
* the `TwoFactorAuth` marker. Both class policies
|
|
33
|
-
* closes the moment
|
|
32
|
+
* the `TwoFactorAuth` marker. Both class policies are passed to one `@Policy`
|
|
33
|
+
* call, so they are combined with AND and the window closes the moment
|
|
34
|
+
* verification succeeds. `TwoFacRouteEnabled` also enforces the system-wide
|
|
35
|
+
* switch, by way of the `TwoFactorAuthEnabled` it extends.
|
|
34
36
|
*
|
|
35
37
|
* Managing a TOTP device outside that window — enrolling for the first time, or
|
|
36
38
|
* turning 2FA off — lives on {@link TwoFactorAuthUserController} under
|
|
@@ -56,9 +58,13 @@ let TwoFactorAuthController = class TwoFactorAuthController extends BaseControll
|
|
|
56
58
|
*/
|
|
57
59
|
async setup2fa(user) {
|
|
58
60
|
if (user.Metadata[TWO_FA_METATADATA_KEYS.ENABLED]) {
|
|
59
|
-
throw new
|
|
61
|
+
throw new BadRequest(`User ${user.Uuid} already has 2fa enabled`);
|
|
60
62
|
}
|
|
61
|
-
|
|
63
|
+
// Re-running setup on an account that already started enrolling is allowed:
|
|
64
|
+
// it replaces an unconfirmed secret, which is exactly how a user who lost
|
|
65
|
+
// the QR gets a new one. There is nothing to steal — the caller could reach
|
|
66
|
+
// the same state from scratch.
|
|
67
|
+
const result = await this.enrol(user);
|
|
62
68
|
return new Ok({
|
|
63
69
|
otp: result,
|
|
64
70
|
});
|
|
@@ -75,6 +81,12 @@ let TwoFactorAuthController = class TwoFactorAuthController extends BaseControll
|
|
|
75
81
|
async verifyToken(logged, token, session) {
|
|
76
82
|
try {
|
|
77
83
|
await this.verifyTwoFactorToken(logged, token.Token);
|
|
84
|
+
// A pending enrolment (secret stored, `2fa:enabled` unset) becomes real
|
|
85
|
+
// here and nowhere else — this is the first moment the user has proven
|
|
86
|
+
// possession of the device.
|
|
87
|
+
if (!logged.Metadata[TWO_FA_METATADATA_KEYS.ENABLED]) {
|
|
88
|
+
await this.activateEnrolment(logged);
|
|
89
|
+
}
|
|
78
90
|
// 2fa complete, mark as authorized
|
|
79
91
|
// fron now on user is considered authorized
|
|
80
92
|
session.Data.set('Authorized', true);
|
|
@@ -116,6 +128,17 @@ let TwoFactorAuthController = class TwoFactorAuthController extends BaseControll
|
|
|
116
128
|
verifyTwoFactorToken(user, token) {
|
|
117
129
|
return auth2Fa(user, token);
|
|
118
130
|
}
|
|
131
|
+
/**
|
|
132
|
+
* Store the TOTP secret without switching 2fa on. Wrapped in a protected
|
|
133
|
+
* method for the same reason as {@link verifyTwoFactorToken}.
|
|
134
|
+
*/
|
|
135
|
+
enrol(user) {
|
|
136
|
+
return beginUser2FaEnrolment(user);
|
|
137
|
+
}
|
|
138
|
+
/** Switch 2fa on for an account whose secret was just verified. */
|
|
139
|
+
activateEnrolment(user) {
|
|
140
|
+
return activateUser2Fa(user);
|
|
141
|
+
}
|
|
119
142
|
};
|
|
120
143
|
__decorate([
|
|
121
144
|
AutoinjectService('rbac.session'),
|
|
@@ -129,6 +152,10 @@ __decorate([
|
|
|
129
152
|
Autoinject(AccessControl),
|
|
130
153
|
__metadata("design:type", AccessControl)
|
|
131
154
|
], TwoFactorAuthController.prototype, "AC", void 0);
|
|
155
|
+
__decorate([
|
|
156
|
+
Config('rbac.twoFactorAuth'),
|
|
157
|
+
__metadata("design:type", Object)
|
|
158
|
+
], TwoFactorAuthController.prototype, "TwoFactorConfig", void 0);
|
|
132
159
|
__decorate([
|
|
133
160
|
Post('2fa/setup'),
|
|
134
161
|
__param(0, User()),
|
|
@@ -147,8 +174,7 @@ __decorate([
|
|
|
147
174
|
], TwoFactorAuthController.prototype, "verifyToken", null);
|
|
148
175
|
TwoFactorAuthController = __decorate([
|
|
149
176
|
BasePath('auth'),
|
|
150
|
-
Policy(TwoFacRouteEnabled)
|
|
151
|
-
Policy(NotAuthorizedPolicy)
|
|
177
|
+
Policy([TwoFacRouteEnabled, NotAuthorizedPolicy])
|
|
152
178
|
], TwoFactorAuthController);
|
|
153
179
|
export { TwoFactorAuthController };
|
|
154
180
|
//# sourceMappingURL=TwoFactorAuthController.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TwoFactorAuthController.js","sourceRoot":"","sources":["../../../src/controllers/TwoFactorAuthController.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACtF,OAAO,EAAY,eAAe,EAAE,IAAI,IAAI,SAAS,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAC/G,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAE7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"TwoFactorAuthController.js","sourceRoot":"","sources":["../../../src/controllers/TwoFactorAuthController.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,27 @@
|
|
|
1
|
-
import { BaseController, Ok, Unauthorized } from '@spinajs/http';
|
|
1
|
+
import { BaseController, ForbiddenResponse, Ok, Unauthorized } from '@spinajs/http';
|
|
2
2
|
import { PasswordProvider, SessionProvider, User as UserModel } from '@spinajs/rbac';
|
|
3
3
|
import type { ISession } from '@spinajs/rbac';
|
|
4
|
-
import { IEnable2faResponse } from '@spinajs/rbac-http';
|
|
4
|
+
import { IEnable2faResponse, TwoFactorAuthConfig } from '@spinajs/rbac-http';
|
|
5
5
|
import { ConfirmPasswordDto } from '../dto/confirm-password-dto.js';
|
|
6
|
+
import { TokenDto } from '../dto/token-dto.js';
|
|
6
7
|
import { SessionCookieFactory } from '../services/SessionCookies.js';
|
|
7
8
|
/** Whether the authenticated user currently has a TOTP device enrolled. */
|
|
8
9
|
export interface ITwoFactorStatus {
|
|
9
10
|
Enabled: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* A secret was issued but never confirmed. The account is not protected — the
|
|
13
|
+
* distinction exists so the UI can say "you started this" rather than
|
|
14
|
+
* "you have no 2fa".
|
|
15
|
+
*/
|
|
16
|
+
Pending: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Whether 2FA is switched on system-wide (`rbac.twoFactorAuth.enabled`). The
|
|
19
|
+
* frontend hides its 2FA controls when this is false. Reading the status is
|
|
20
|
+
* deliberately left ungated by the switch so this can be reported at all —
|
|
21
|
+
* the mutating routes are the ones that refuse with 403
|
|
22
|
+
* `E_2FA_SYSTEM_DISABLED`.
|
|
23
|
+
*/
|
|
24
|
+
SystemEnabled: boolean;
|
|
10
25
|
}
|
|
11
26
|
/**
|
|
12
27
|
* Self-service two-factor authentication.
|
|
@@ -22,12 +37,20 @@ export interface ITwoFactorStatus {
|
|
|
22
37
|
* not be enough to attach an attacker-controlled authenticator or to strip the
|
|
23
38
|
* second factor off the account.
|
|
24
39
|
*
|
|
40
|
+
* The system-wide switch (`rbac.twoFactorAuth.enabled`) is enforced by
|
|
41
|
+
* `TwoFactorAuthEnabled`, passed to `@Permission` on each mutating route so it
|
|
42
|
+
* shares a policy group with the permission check and is therefore required
|
|
43
|
+
* rather than merely offered as an alternative. It is deliberately NOT a class
|
|
44
|
+
* policy: `status` stays readable while the switch is off, which is how the
|
|
45
|
+
* frontend learns to hide its 2FA controls.
|
|
46
|
+
*
|
|
25
47
|
* @tags Two-Factor Settings
|
|
26
48
|
*/
|
|
27
49
|
export declare class TwoFactorAuthUserController extends BaseController {
|
|
28
50
|
protected PasswordProvider: PasswordProvider;
|
|
29
51
|
protected SessionProvider: SessionProvider;
|
|
30
52
|
protected SessionCookies: SessionCookieFactory;
|
|
53
|
+
protected TwoFactorConfig: TwoFactorAuthConfig;
|
|
31
54
|
/**
|
|
32
55
|
* Get own two-factor status
|
|
33
56
|
* Reports whether the authenticated user currently has a TOTP device enrolled.
|
|
@@ -41,6 +64,8 @@ export declare class TwoFactorAuthUserController extends BaseController {
|
|
|
41
64
|
* Enable own two-factor authentication
|
|
42
65
|
* Generates a TOTP secret for the authenticated user and returns the OTP provisioning
|
|
43
66
|
* URI to scan with an authenticator app. Requires the account password to be re-entered.
|
|
67
|
+
* 2FA stays off until the new code is confirmed with `POST /user/2fa/confirm` — a caller
|
|
68
|
+
* that stops after this call leaves the account unprotected, believing it is enrolled.
|
|
44
69
|
* @security cookieAuth
|
|
45
70
|
* @returns {IEnable2faResponse} OTP provisioning URI to scan with an authenticator app
|
|
46
71
|
* @response 400 Two-factor authentication is already enabled for this user
|
|
@@ -48,6 +73,17 @@ export declare class TwoFactorAuthUserController extends BaseController {
|
|
|
48
73
|
* @response 403 Forbidden — insufficient permissions
|
|
49
74
|
*/
|
|
50
75
|
enable(user: UserModel, confirmation: ConfirmPasswordDto, session: ISession): Promise<Ok<IEnable2faResponse> | Unauthorized>;
|
|
76
|
+
/**
|
|
77
|
+
* Confirm own two-factor enrolment
|
|
78
|
+
* Verifies a code generated from the secret handed out by `POST /user/2fa/enable`
|
|
79
|
+
* or `POST /user/2fa/reset`, and only then switches 2FA on.
|
|
80
|
+
* @security cookieAuth
|
|
81
|
+
* @response 200 Two-factor authentication is now active
|
|
82
|
+
* @response 400 There is no pending enrolment to confirm
|
|
83
|
+
* @response 401 Unauthorized — valid session required
|
|
84
|
+
* @response 403 Invalid or expired TOTP code
|
|
85
|
+
*/
|
|
86
|
+
confirm(user: UserModel, token: TokenDto, session: ISession): Promise<Ok | ForbiddenResponse>;
|
|
51
87
|
/**
|
|
52
88
|
* Disable own two-factor authentication
|
|
53
89
|
* Removes the TOTP secret and disables 2FA for the authenticated user.
|
|
@@ -59,6 +95,34 @@ export declare class TwoFactorAuthUserController extends BaseController {
|
|
|
59
95
|
* @response 403 Forbidden — insufficient permissions
|
|
60
96
|
*/
|
|
61
97
|
disable(user: UserModel, confirmation: ConfirmPasswordDto, session: ISession): Promise<Ok | Unauthorized>;
|
|
98
|
+
/**
|
|
99
|
+
* Reset own two-factor authentication
|
|
100
|
+
* Removes the current TOTP device and issues a new secret in a single request,
|
|
101
|
+
* returning the provisioning URI to scan. 2FA stays off until the new code is
|
|
102
|
+
* confirmed with `POST /user/2fa/confirm`. Requires the account password.
|
|
103
|
+
*
|
|
104
|
+
* Folding disable-then-enable into one request removes the client-side gap
|
|
105
|
+
* where abandoning the flow between the two calls could strand the account
|
|
106
|
+
* without a second factor. It does not remove the server-side one: if
|
|
107
|
+
* `enrol` fails after `unenrol` already removed the old device, the account
|
|
108
|
+
* is left with no device at all — there is nothing to roll back to, since
|
|
109
|
+
* the old secret is already gone. That leaves the account in the ordinary
|
|
110
|
+
* `none` state, which every route here already handles: `GET /user/2fa`
|
|
111
|
+
* reports it and `POST /user/2fa/enable` starts a fresh enrolment.
|
|
112
|
+
*
|
|
113
|
+
* A caller who abandons before confirming is left password-only — the same
|
|
114
|
+
* gap as `enable`. The only built-in recovery is `rbac.twoFactorAuth.forceUser`
|
|
115
|
+
* pushing the account back through enrolment at next login, and this package's
|
|
116
|
+
* own default for that flag is `false` (see `src/config/rbac-http.ts`), so a
|
|
117
|
+
* consumer that has not set it will see the downgrade become silent and
|
|
118
|
+
* permanent rather than recovered.
|
|
119
|
+
* @security cookieAuth
|
|
120
|
+
* @returns {IEnable2faResponse} OTP provisioning URI to scan with an authenticator app
|
|
121
|
+
* @response 400 There is no two-factor device to reset
|
|
122
|
+
* @response 401 Unauthorized — valid session required, or password invalid
|
|
123
|
+
* @response 403 Forbidden — insufficient permissions
|
|
124
|
+
*/
|
|
125
|
+
reset(user: UserModel, confirmation: ConfirmPasswordDto, session: ISession): Promise<Ok<IEnable2faResponse> | Unauthorized>;
|
|
62
126
|
/**
|
|
63
127
|
* Rotates the session id after the account's authentication requirements
|
|
64
128
|
* changed, and returns the response options carrying the new cookie.
|
|
@@ -83,10 +147,13 @@ export declare class TwoFactorAuthUserController extends BaseController {
|
|
|
83
147
|
}[];
|
|
84
148
|
}>;
|
|
85
149
|
/**
|
|
86
|
-
*
|
|
87
|
-
* the module-level action so tests can stub it without a
|
|
150
|
+
* Store the TOTP secret and return the provisioning URI, leaving 2fa off until
|
|
151
|
+
* confirmed. Wraps the module-level action so tests can stub it without a
|
|
152
|
+
* TOTP/DB setup.
|
|
88
153
|
*/
|
|
89
154
|
protected enrol(user: UserModel): Promise<unknown>;
|
|
155
|
+
/** Verify a code against the pending secret and switch 2fa on. */
|
|
156
|
+
protected confirmEnrolment(user: UserModel, token: string): Promise<unknown>;
|
|
90
157
|
/** Clear the TOTP secret. Wrapped for the same reason as {@link enrol}. */
|
|
91
158
|
protected unenrol(user: UserModel): Promise<unknown>;
|
|
92
159
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TwoFactorAuthUserController.d.ts","sourceRoot":"","sources":["../../../src/controllers/TwoFactorAuthUserController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,
|
|
1
|
+
{"version":3,"file":"TwoFactorAuthUserController.d.ts","sourceRoot":"","sources":["../../../src/controllers/TwoFactorAuthUserController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAkB,iBAAiB,EAAO,EAAE,EAAgB,YAAY,EAAE,MAAM,eAAe,CAAC;AACvH,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,IAAI,IAAI,SAAS,EAAqB,MAAM,eAAe,CAAC;AACxG,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAG9C,OAAO,EAAoB,kBAAkB,EAAoD,mBAAmB,EAAQ,MAAM,oBAAoB,CAAC;AAEvJ,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAKrE,2EAA2E;AAC3E,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IAEjB;;;;OAIG;IACH,OAAO,EAAE,OAAO,CAAC;IAEjB;;;;;;OAMG;IACH,aAAa,EAAE,OAAO,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAGa,2BAA4B,SAAQ,cAAc;IAE7D,SAAS,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;IAG7C,SAAS,CAAC,eAAe,EAAE,eAAe,CAAC;IAG3C,SAAS,CAAC,cAAc,EAAE,oBAAoB,CAAC;IAG/C,SAAS,CAAC,eAAe,EAAE,mBAAmB,CAAC;IAE/C;;;;;;;OAOG;IAGU,MAAM,CAAS,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAQ1E;IAED;;;;;;;;;;;OAWG;IAGU,MAAM,CAAS,IAAI,EAAE,SAAS,EAAU,YAAY,EAAE,kBAAkB,EAAqB,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,EAAE,CAAC,kBAAkB,CAAC,GAAG,YAAY,CAAC,CAiB3K;IAED;;;;;;;;;OASG;IAGU,OAAO,CAAS,IAAI,EAAE,SAAS,EAAU,KAAK,EAAE,QAAQ,EAAqB,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,EAAE,GAAG,iBAAiB,CAAC,CA+B5I;IAED;;;;;;;;;OASG;IAGU,OAAO,CAAS,IAAI,EAAE,SAAS,EAAU,YAAY,EAAE,kBAAkB,EAAqB,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,EAAE,GAAG,YAAY,CAAC,CAYxJ;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IAGU,KAAK,CAAS,IAAI,EAAE,SAAS,EAAU,YAAY,EAAE,kBAAkB,EAAqB,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,EAAE,CAAC,kBAAkB,CAAC,GAAG,YAAY,CAAC,CAc1K;IAED;;;;;;;;;OASG;IACH,UAAgB,MAAM,CAAC,OAAO,EAAE,QAAQ;;;;;;;;;;;;OAWvC;IAED;;;;OAIG;IACH,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAEjD;IAED,kEAAkE;IAClE,SAAS,CAAC,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAE3E;IAED,2EAA2E;IAC3E,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAEnD;IAED;;;OAGG;IACH,UAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,YAAY,CAAC,CAY/F;CACF"}
|
|
@@ -10,17 +10,18 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
10
10
|
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
11
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
12
|
};
|
|
13
|
-
import { BaseController, BasePath, Body, Get, Ok, Policy, Post, Unauthorized } from '@spinajs/http';
|
|
13
|
+
import { BaseController, BasePath, Body, ForbiddenResponse, Get, Ok, Policy, Post, Unauthorized } from '@spinajs/http';
|
|
14
14
|
import { PasswordProvider, SessionProvider, User as UserModel, regenerateSession } from '@spinajs/rbac';
|
|
15
15
|
import { Autoinject } from '@spinajs/di';
|
|
16
|
-
import { AutoinjectService } from '@spinajs/configuration';
|
|
16
|
+
import { AutoinjectService, Config } from '@spinajs/configuration';
|
|
17
17
|
import { AuthorizedPolicy, Permission, Resource, Session as SessionRouteArg, User } from '@spinajs/rbac-http';
|
|
18
|
-
import {
|
|
19
|
-
import { TwoFactorAuthEnabled } from '../policies/2FaPolicy.js';
|
|
18
|
+
import { BadRequest } from '@spinajs/exceptions';
|
|
20
19
|
import { ConfirmPasswordDto } from '../dto/confirm-password-dto.js';
|
|
20
|
+
import { TokenDto } from '../dto/token-dto.js';
|
|
21
21
|
import { SessionCookieFactory } from '../services/SessionCookies.js';
|
|
22
|
-
import {
|
|
22
|
+
import { beginUser2FaEnrolment, confirmUser2Fa, disableUser2Fa } from '../actions/2fa.js';
|
|
23
23
|
import { TWO_FA_METATADATA_KEYS } from '../2fa/Default2FaToken.js';
|
|
24
|
+
import { TwoFactorAuthEnabled } from '../policies/2FaPolicy.js';
|
|
24
25
|
/**
|
|
25
26
|
* Self-service two-factor authentication.
|
|
26
27
|
*
|
|
@@ -35,6 +36,13 @@ import { TWO_FA_METATADATA_KEYS } from '../2fa/Default2FaToken.js';
|
|
|
35
36
|
* not be enough to attach an attacker-controlled authenticator or to strip the
|
|
36
37
|
* second factor off the account.
|
|
37
38
|
*
|
|
39
|
+
* The system-wide switch (`rbac.twoFactorAuth.enabled`) is enforced by
|
|
40
|
+
* `TwoFactorAuthEnabled`, passed to `@Permission` on each mutating route so it
|
|
41
|
+
* shares a policy group with the permission check and is therefore required
|
|
42
|
+
* rather than merely offered as an alternative. It is deliberately NOT a class
|
|
43
|
+
* policy: `status` stays readable while the switch is off, which is how the
|
|
44
|
+
* frontend learns to hide its 2FA controls.
|
|
45
|
+
*
|
|
38
46
|
* @tags Two-Factor Settings
|
|
39
47
|
*/
|
|
40
48
|
let TwoFactorAuthUserController = class TwoFactorAuthUserController extends BaseController {
|
|
@@ -47,12 +55,19 @@ let TwoFactorAuthUserController = class TwoFactorAuthUserController extends Base
|
|
|
47
55
|
* @response 403 Forbidden — insufficient permissions
|
|
48
56
|
*/
|
|
49
57
|
async status(user) {
|
|
50
|
-
|
|
58
|
+
const enabled = Boolean(user.Metadata[TWO_FA_METATADATA_KEYS.ENABLED]);
|
|
59
|
+
return new Ok({
|
|
60
|
+
Enabled: enabled,
|
|
61
|
+
Pending: !enabled && Boolean(user.Metadata[TWO_FA_METATADATA_KEYS.TOKEN]),
|
|
62
|
+
SystemEnabled: this.TwoFactorConfig?.enabled !== false,
|
|
63
|
+
});
|
|
51
64
|
}
|
|
52
65
|
/**
|
|
53
66
|
* Enable own two-factor authentication
|
|
54
67
|
* Generates a TOTP secret for the authenticated user and returns the OTP provisioning
|
|
55
68
|
* URI to scan with an authenticator app. Requires the account password to be re-entered.
|
|
69
|
+
* 2FA stays off until the new code is confirmed with `POST /user/2fa/confirm` — a caller
|
|
70
|
+
* that stops after this call leaves the account unprotected, believing it is enrolled.
|
|
56
71
|
* @security cookieAuth
|
|
57
72
|
* @returns {IEnable2faResponse} OTP provisioning URI to scan with an authenticator app
|
|
58
73
|
* @response 400 Two-factor authentication is already enabled for this user
|
|
@@ -61,20 +76,58 @@ let TwoFactorAuthUserController = class TwoFactorAuthUserController extends Base
|
|
|
61
76
|
*/
|
|
62
77
|
async enable(user, confirmation, session) {
|
|
63
78
|
if (user.Metadata[TWO_FA_METATADATA_KEYS.ENABLED]) {
|
|
64
|
-
throw new
|
|
79
|
+
throw new BadRequest(`User ${user.Uuid} already has 2fa enabled`);
|
|
65
80
|
}
|
|
66
81
|
const confirmed = await this.confirmPassword(user, confirmation.Password);
|
|
67
82
|
if (confirmed !== true) {
|
|
68
83
|
return confirmed;
|
|
69
84
|
}
|
|
70
|
-
//
|
|
71
|
-
//
|
|
72
|
-
// the
|
|
73
|
-
//
|
|
74
|
-
// themselves out and needs an administrator 2FA reset to recover.
|
|
85
|
+
// The secret is stored but 2fa stays OFF until `POST /user/2fa/confirm`
|
|
86
|
+
// accepts a code generated from it. A user who never scans is left pending,
|
|
87
|
+
// which the login check treats exactly like having no device — no lockout,
|
|
88
|
+
// and the next attempt simply issues a new secret.
|
|
75
89
|
const result = await this.enrol(user);
|
|
76
90
|
return new Ok({ otp: result }, await this.rotate(session));
|
|
77
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Confirm own two-factor enrolment
|
|
94
|
+
* Verifies a code generated from the secret handed out by `POST /user/2fa/enable`
|
|
95
|
+
* or `POST /user/2fa/reset`, and only then switches 2FA on.
|
|
96
|
+
* @security cookieAuth
|
|
97
|
+
* @response 200 Two-factor authentication is now active
|
|
98
|
+
* @response 400 There is no pending enrolment to confirm
|
|
99
|
+
* @response 401 Unauthorized — valid session required
|
|
100
|
+
* @response 403 Invalid or expired TOTP code
|
|
101
|
+
*/
|
|
102
|
+
async confirm(user, token, session) {
|
|
103
|
+
// `activate()` never clears the stored token, so an already-enabled
|
|
104
|
+
// account still has one and would otherwise be able to call this route
|
|
105
|
+
// again with a currently-valid code. Only the pending state — a token
|
|
106
|
+
// without 2fa being enabled yet — is an enrolment left to confirm.
|
|
107
|
+
if (user.Metadata[TWO_FA_METATADATA_KEYS.ENABLED] || !user.Metadata[TWO_FA_METATADATA_KEYS.TOKEN]) {
|
|
108
|
+
throw new BadRequest(`User ${user.Uuid} has no pending 2fa enrolment`);
|
|
109
|
+
}
|
|
110
|
+
try {
|
|
111
|
+
await this.confirmEnrolment(user, token.Token);
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
// `confirmUser2Fa` throws `Unauthorized` for a rejected code — the only
|
|
115
|
+
// case this route should report as "wrong code". Anything else (a
|
|
116
|
+
// database outage during activation, for instance) must surface as a
|
|
117
|
+
// 500, not be misreported to the user as a bad code.
|
|
118
|
+
if (!(err instanceof Unauthorized)) {
|
|
119
|
+
throw err;
|
|
120
|
+
}
|
|
121
|
+
this._log.warn(`2fa confirmation rejected for ${user.Uuid}`, { error: err });
|
|
122
|
+
return new ForbiddenResponse({
|
|
123
|
+
error: { code: 'E_2FA_FAILED', message: '2fa check failed' },
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
// No password here on purpose: the password was confirmed by the enable or
|
|
127
|
+
// reset call that issued this secret, and the code is itself the proof this
|
|
128
|
+
// route exists to demand.
|
|
129
|
+
return new Ok(null, await this.rotate(session));
|
|
130
|
+
}
|
|
78
131
|
/**
|
|
79
132
|
* Disable own two-factor authentication
|
|
80
133
|
* Removes the TOTP secret and disables 2FA for the authenticated user.
|
|
@@ -87,7 +140,7 @@ let TwoFactorAuthUserController = class TwoFactorAuthUserController extends Base
|
|
|
87
140
|
*/
|
|
88
141
|
async disable(user, confirmation, session) {
|
|
89
142
|
if (!user.Metadata[TWO_FA_METATADATA_KEYS.ENABLED]) {
|
|
90
|
-
throw new
|
|
143
|
+
throw new BadRequest(`User ${user.Uuid} already has 2fa disabled`);
|
|
91
144
|
}
|
|
92
145
|
const confirmed = await this.confirmPassword(user, confirmation.Password);
|
|
93
146
|
if (confirmed !== true) {
|
|
@@ -96,6 +149,45 @@ let TwoFactorAuthUserController = class TwoFactorAuthUserController extends Base
|
|
|
96
149
|
await this.unenrol(user);
|
|
97
150
|
return new Ok(null, await this.rotate(session));
|
|
98
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* Reset own two-factor authentication
|
|
154
|
+
* Removes the current TOTP device and issues a new secret in a single request,
|
|
155
|
+
* returning the provisioning URI to scan. 2FA stays off until the new code is
|
|
156
|
+
* confirmed with `POST /user/2fa/confirm`. Requires the account password.
|
|
157
|
+
*
|
|
158
|
+
* Folding disable-then-enable into one request removes the client-side gap
|
|
159
|
+
* where abandoning the flow between the two calls could strand the account
|
|
160
|
+
* without a second factor. It does not remove the server-side one: if
|
|
161
|
+
* `enrol` fails after `unenrol` already removed the old device, the account
|
|
162
|
+
* is left with no device at all — there is nothing to roll back to, since
|
|
163
|
+
* the old secret is already gone. That leaves the account in the ordinary
|
|
164
|
+
* `none` state, which every route here already handles: `GET /user/2fa`
|
|
165
|
+
* reports it and `POST /user/2fa/enable` starts a fresh enrolment.
|
|
166
|
+
*
|
|
167
|
+
* A caller who abandons before confirming is left password-only — the same
|
|
168
|
+
* gap as `enable`. The only built-in recovery is `rbac.twoFactorAuth.forceUser`
|
|
169
|
+
* pushing the account back through enrolment at next login, and this package's
|
|
170
|
+
* own default for that flag is `false` (see `src/config/rbac-http.ts`), so a
|
|
171
|
+
* consumer that has not set it will see the downgrade become silent and
|
|
172
|
+
* permanent rather than recovered.
|
|
173
|
+
* @security cookieAuth
|
|
174
|
+
* @returns {IEnable2faResponse} OTP provisioning URI to scan with an authenticator app
|
|
175
|
+
* @response 400 There is no two-factor device to reset
|
|
176
|
+
* @response 401 Unauthorized — valid session required, or password invalid
|
|
177
|
+
* @response 403 Forbidden — insufficient permissions
|
|
178
|
+
*/
|
|
179
|
+
async reset(user, confirmation, session) {
|
|
180
|
+
if (!user.Metadata[TWO_FA_METATADATA_KEYS.ENABLED] && !user.Metadata[TWO_FA_METATADATA_KEYS.TOKEN]) {
|
|
181
|
+
throw new BadRequest(`User ${user.Uuid} has no 2fa to reset`);
|
|
182
|
+
}
|
|
183
|
+
const confirmed = await this.confirmPassword(user, confirmation.Password);
|
|
184
|
+
if (confirmed !== true) {
|
|
185
|
+
return confirmed;
|
|
186
|
+
}
|
|
187
|
+
await this.unenrol(user);
|
|
188
|
+
const result = await this.enrol(user);
|
|
189
|
+
return new Ok({ otp: result }, await this.rotate(session));
|
|
190
|
+
}
|
|
99
191
|
/**
|
|
100
192
|
* Rotates the session id after the account's authentication requirements
|
|
101
193
|
* changed, and returns the response options carrying the new cookie.
|
|
@@ -117,11 +209,16 @@ let TwoFactorAuthUserController = class TwoFactorAuthUserController extends Base
|
|
|
117
209
|
};
|
|
118
210
|
}
|
|
119
211
|
/**
|
|
120
|
-
*
|
|
121
|
-
* the module-level action so tests can stub it without a
|
|
212
|
+
* Store the TOTP secret and return the provisioning URI, leaving 2fa off until
|
|
213
|
+
* confirmed. Wraps the module-level action so tests can stub it without a
|
|
214
|
+
* TOTP/DB setup.
|
|
122
215
|
*/
|
|
123
216
|
enrol(user) {
|
|
124
|
-
return
|
|
217
|
+
return beginUser2FaEnrolment(user);
|
|
218
|
+
}
|
|
219
|
+
/** Verify a code against the pending secret and switch 2fa on. */
|
|
220
|
+
confirmEnrolment(user, token) {
|
|
221
|
+
return confirmUser2Fa(user, token);
|
|
125
222
|
}
|
|
126
223
|
/** Clear the TOTP secret. Wrapped for the same reason as {@link enrol}. */
|
|
127
224
|
unenrol(user) {
|
|
@@ -154,6 +251,10 @@ __decorate([
|
|
|
154
251
|
Autoinject(SessionCookieFactory),
|
|
155
252
|
__metadata("design:type", SessionCookieFactory)
|
|
156
253
|
], TwoFactorAuthUserController.prototype, "SessionCookies", void 0);
|
|
254
|
+
__decorate([
|
|
255
|
+
Config('rbac.twoFactorAuth'),
|
|
256
|
+
__metadata("design:type", Object)
|
|
257
|
+
], TwoFactorAuthUserController.prototype, "TwoFactorConfig", void 0);
|
|
157
258
|
__decorate([
|
|
158
259
|
Get('2fa'),
|
|
159
260
|
Permission(['readOwn']),
|
|
@@ -164,7 +265,7 @@ __decorate([
|
|
|
164
265
|
], TwoFactorAuthUserController.prototype, "status", null);
|
|
165
266
|
__decorate([
|
|
166
267
|
Post('2fa/enable'),
|
|
167
|
-
Permission(['updateOwn']),
|
|
268
|
+
Permission(['updateOwn'], TwoFactorAuthEnabled),
|
|
168
269
|
__param(0, User()),
|
|
169
270
|
__param(1, Body()),
|
|
170
271
|
__param(2, SessionRouteArg()),
|
|
@@ -172,9 +273,19 @@ __decorate([
|
|
|
172
273
|
__metadata("design:paramtypes", [UserModel, ConfirmPasswordDto, Object]),
|
|
173
274
|
__metadata("design:returntype", Promise)
|
|
174
275
|
], TwoFactorAuthUserController.prototype, "enable", null);
|
|
276
|
+
__decorate([
|
|
277
|
+
Post('2fa/confirm'),
|
|
278
|
+
Permission(['updateOwn'], TwoFactorAuthEnabled),
|
|
279
|
+
__param(0, User()),
|
|
280
|
+
__param(1, Body()),
|
|
281
|
+
__param(2, SessionRouteArg()),
|
|
282
|
+
__metadata("design:type", Function),
|
|
283
|
+
__metadata("design:paramtypes", [UserModel, TokenDto, Object]),
|
|
284
|
+
__metadata("design:returntype", Promise)
|
|
285
|
+
], TwoFactorAuthUserController.prototype, "confirm", null);
|
|
175
286
|
__decorate([
|
|
176
287
|
Post('2fa/disable'),
|
|
177
|
-
Permission(['updateOwn']),
|
|
288
|
+
Permission(['updateOwn'], TwoFactorAuthEnabled),
|
|
178
289
|
__param(0, User()),
|
|
179
290
|
__param(1, Body()),
|
|
180
291
|
__param(2, SessionRouteArg()),
|
|
@@ -182,11 +293,20 @@ __decorate([
|
|
|
182
293
|
__metadata("design:paramtypes", [UserModel, ConfirmPasswordDto, Object]),
|
|
183
294
|
__metadata("design:returntype", Promise)
|
|
184
295
|
], TwoFactorAuthUserController.prototype, "disable", null);
|
|
296
|
+
__decorate([
|
|
297
|
+
Post('2fa/reset'),
|
|
298
|
+
Permission(['updateOwn'], TwoFactorAuthEnabled),
|
|
299
|
+
__param(0, User()),
|
|
300
|
+
__param(1, Body()),
|
|
301
|
+
__param(2, SessionRouteArg()),
|
|
302
|
+
__metadata("design:type", Function),
|
|
303
|
+
__metadata("design:paramtypes", [UserModel, ConfirmPasswordDto, Object]),
|
|
304
|
+
__metadata("design:returntype", Promise)
|
|
305
|
+
], TwoFactorAuthUserController.prototype, "reset", null);
|
|
185
306
|
TwoFactorAuthUserController = __decorate([
|
|
186
307
|
BasePath('user'),
|
|
187
308
|
Resource('user'),
|
|
188
|
-
Policy(AuthorizedPolicy)
|
|
189
|
-
Policy(TwoFactorAuthEnabled)
|
|
309
|
+
Policy(AuthorizedPolicy)
|
|
190
310
|
], TwoFactorAuthUserController);
|
|
191
311
|
export { TwoFactorAuthUserController };
|
|
192
312
|
//# sourceMappingURL=TwoFactorAuthUserController.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TwoFactorAuthUserController.js","sourceRoot":"","sources":["../../../src/controllers/TwoFactorAuthUserController.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"TwoFactorAuthUserController.js","sourceRoot":"","sources":["../../../src/controllers/TwoFactorAuthUserController.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"2FaPolicy.d.ts","sourceRoot":"","sources":["../../../src/policies/2FaPolicy.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"2FaPolicy.d.ts","sourceRoot":"","sources":["../../../src/policies/2FaPolicy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAGzD;;;;;;GAMG;AACH,qBAAa,oBAAqB,SAAQ,UAAU;IAElD,SAAS,CAAC,eAAe,EAAE,mBAAmB,CAAC;IAExC,SAAS,IAAI,OAAO,CAE1B;IAEY,OAAO,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CA2BlD;CACF;AAED;;;;;;;;;GASG;AACH,qBAAa,kBAAmB,SAAQ,oBAAoB;IAC7C,OAAO,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAejD;CACF"}
|