@nathapp/na-cli 1.0.0-rc.10 → 1.0.0-rc.11

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.
Files changed (163) hide show
  1. package/.npm/_cacache/index-v5/05/34/1929926becc54c1f69c0921ab74c461c1777ab3d43213900acd4779dbf27 +1 -1
  2. package/.npm/_cacache/index-v5/0b/57/19385728919a097d1777ef98285f6cdfca14b66511276b641ec4a3af64bc +1 -1
  3. package/.npm/_cacache/index-v5/0b/90/c147816be94e86ed9bbb4b9e20409e4791a8991fcfd41d7a44489dedd29b +1 -1
  4. package/.npm/_cacache/index-v5/0b/ac/1bc19a224468b5a9e4382b946d33bb4c236306c2cefe190e5e2db1ded98a +1 -1
  5. package/.npm/_cacache/index-v5/12/6d/f094b1c476935fbda8814b43ee001b439b1f793c265ee5bd97d566143fb4 +1 -1
  6. package/.npm/_cacache/index-v5/12/80/c192e66daf6ba49f528ae81b986857735e6d257bdf4b0b1758eb795cae9b +1 -1
  7. package/.npm/_cacache/index-v5/13/32/a5865acd35ae515cde972c2d6cbff2863e694975883870de78b62a80f30e +1 -1
  8. package/.npm/_cacache/index-v5/14/33/be443b6e6c3ef0ff8f09987bc62d5ef9e61259f3331c422182f6bb74fdeb +1 -1
  9. package/.npm/_cacache/index-v5/14/f7/87042931e5944467d47331c350feb4384bf9143ab6ceebf7108a55905843 +1 -1
  10. package/.npm/_cacache/index-v5/14/fa/f87baceab26935686548c742091e7014930673bc1f077574c54c4c6c2d2d +1 -1
  11. package/.npm/_cacache/index-v5/15/26/abf1072208668be6e34a4311ad25f34fc908c21abc17ef01b5836cef1879 +1 -1
  12. package/.npm/_cacache/index-v5/1a/fd/532a4c7bf52c908d567ded2bb11b0f3282f0733d0d079a5291c2f72e0077 +1 -1
  13. package/.npm/_cacache/index-v5/1b/15/2ed036cc76081b7f1bfb3aa59d491eb3b3602c9381ec8d81435ceecf56b5 +1 -1
  14. package/.npm/_cacache/index-v5/27/b7/7f36d855e73b72c900bef7ba44a2a553de3d77b218493b4ddb6ae6fce516 +1 -1
  15. package/.npm/_cacache/index-v5/27/cc/afd4aa090b087c509f17e75196209f498c916da50ee4e9f26bd8424fd6f7 +1 -1
  16. package/.npm/_cacache/index-v5/2d/80/b5e9ca2e40744e7fa089861626d2a29c62363c01729964f4cf0c3e8ee632 +1 -1
  17. package/.npm/_cacache/index-v5/2d/ed/7f785cb92982f557fdc81aec4081952ce428eb449dd91fa0867b6676fa17 +1 -1
  18. package/.npm/_cacache/index-v5/2e/30/64338ba8469bd5c48ab7843f9d06a83992a346cfd592194af9c6d4d6dc48 +1 -1
  19. package/.npm/_cacache/index-v5/2e/a8/503d5f11e5dcde5786e3973ff160d2acc4736af22f9cd5a883c26adc7824 +1 -1
  20. package/.npm/_cacache/index-v5/30/98/41b0d8db0052e964e4843260ec8a0b12f2541721317cd5ee90b07b6a4d59 +1 -1
  21. package/.npm/_cacache/index-v5/31/64/15cefe5f3b923ebb9c684b37db7451ccf335632aab377fa3c730ec2e79cd +1 -1
  22. package/.npm/_cacache/index-v5/31/ac/4d241faeb3fea9ec8318fd93dd55eb70a87cc8a6e3f849ccef9863882b4b +3 -3
  23. package/.npm/_cacache/index-v5/31/ca/a8c3ab0670811a3887ede187dcd3856d14272349a18f6844f7c8007cc05e +1 -1
  24. package/.npm/_cacache/index-v5/34/a0/f70f68dcf9baef2ff21f29fdd206513fe5b10736be36ddd2f65a654a8f23 +1 -1
  25. package/.npm/_cacache/index-v5/34/f7/8879c3cd1412a0890461590276aa13d0344cb4e09494a4b3d854a7c7660a +1 -1
  26. package/.npm/_cacache/index-v5/35/e5/adb97753b463aa67dc9f26f39e8a52f68bf467cf1187509be7da174c057d +1 -1
  27. package/.npm/_cacache/index-v5/37/53/b5dccfb634beb6de718b268b6434849f27d3cf60d426dc19472a642a3f01 +1 -1
  28. package/.npm/_cacache/index-v5/38/2e/fe53691fa43d2f5ac447c8a2431535ec49118be55bf483c6362d4f72c79b +1 -1
  29. package/.npm/_cacache/index-v5/3c/f6/26a7f7dccb969c764b8bdecb3667023c64bc1159e674fbeeca633c54964c +1 -1
  30. package/.npm/_cacache/index-v5/3d/dd/3e8c6b6c875addf2057fb5fa152fff0fab217f78a8e51c0aa457a925bf12 +1 -1
  31. package/.npm/_cacache/index-v5/3e/77/916dd3c99bb6e83a0217305b0a2a541f122d977edcb92fa6b58eed796c17 +1 -1
  32. package/.npm/_cacache/index-v5/40/62/d04e75208dec117f72a95a5989f81fac7565a530fd22f70ea5e3abc377c3 +2 -2
  33. package/.npm/_cacache/index-v5/42/89/e110619623b1c9111a6392de4b1a62a904fb08d0601f87b9c8e1d493f5d6 +1 -1
  34. package/.npm/_cacache/index-v5/46/5b/f3ce50d3f54a5d65ac316d3c71ef8a8f8bdb072b6dfabc2c69018c3e942a +1 -1
  35. package/.npm/_cacache/index-v5/48/17/0ecf04bc0839b23c609ec7bfea9d339fa2cc3ee5982716cf7465ffaea675 +1 -1
  36. package/.npm/_cacache/index-v5/53/aa/b41f4759346e1d3b6651322d78c7983a4a546cdd6c18c3eb56c944571e4b +1 -1
  37. package/.npm/_cacache/index-v5/57/4d/cdafdfd03e43ca95652cbbb0b23bbbbeef3e16fa307726cb2ae8a5658531 +1 -1
  38. package/.npm/_cacache/index-v5/58/c9/9f8c27572bf3034e8fa9cc74fc00878e45fa7d75d4570d4430e82bfb5ef3 +1 -1
  39. package/.npm/_cacache/index-v5/5a/8c/47e273da29b52c911f59eca44c62faa84be4bb59b1de259ba100ff968559 +1 -1
  40. package/.npm/_cacache/index-v5/5e/89/be4afbbaa5c56c070a74790be14bd112b9e1b3f251324d766264b2c5f880 +1 -1
  41. package/.npm/_cacache/index-v5/5e/e7/453bd89145eccf9d67f5797fb09e5a017b5b13f1ac45cb7b70bda45940ec +2 -2
  42. package/.npm/_cacache/index-v5/5f/57/67c3b0c63ea4198903509c050bb99de2eabd6a2fba583067c4f587dc25f7 +1 -1
  43. package/.npm/_cacache/index-v5/60/8c/b74a2ae1c6978d635a1a21438c553d956a762176742b2749d09db964bf4d +1 -1
  44. package/.npm/_cacache/index-v5/68/6b/1f834b2ea43c7a9d1ffd80eb09f9d44af0895dc31dc3955d4b4c797ea825 +1 -1
  45. package/.npm/_cacache/index-v5/6d/61/c9e7e8446341cea439547eb023fbf47c954ba932e6944a3fd50413c1e861 +1 -1
  46. package/.npm/_cacache/index-v5/6d/b3/82949bd186224f1f51cb3fabdad6a93aa6a64c685b395a36f0a34af15119 +1 -1
  47. package/.npm/_cacache/index-v5/6f/d8/170c71ac7185da1b8040f10243c7294ff9a667a27fffc3479ba2f222f014 +1 -1
  48. package/.npm/_cacache/index-v5/74/d3/f9a4984e5548c5f72b3dc858046781cc3a892b34b6b7e7c353fbc93aa060 +1 -1
  49. package/.npm/_cacache/index-v5/75/ec/5dd4c902abf3f9ae589620cd4fd5b6ccfe045b8abdfbfa050d1a5ba8c01e +1 -1
  50. package/.npm/_cacache/index-v5/77/be/4d3f23909fd5905444d34cb0ce78d5bf6ce157670ae6ed614389a2027d18 +1 -1
  51. package/.npm/_cacache/index-v5/7d/8f/423d7e791f7fedd6bef784f0f467761c619f209ce9c788f08b63e968a880 +1 -1
  52. package/.npm/_cacache/index-v5/80/da/c34ca077ec2051cad25b3313e4e75ff4ad2dc2b12a9c250cb9545c0adc4b +1 -1
  53. package/.npm/_cacache/index-v5/84/d7/a5acf52705a1beb66603196f4bc44e583052d0f1d5a23dfb5316da1811d3 +1 -1
  54. package/.npm/_cacache/index-v5/86/7a/c59a43ec4985d34346e5714968f7220d176ea3a61b55464a7fecae01ac47 +1 -1
  55. package/.npm/_cacache/index-v5/87/55/e56d34b37c3170079064597cabb288d076b0d0468eaba3b8a0cf8686ce1f +1 -1
  56. package/.npm/_cacache/index-v5/8a/c9/c10bf71d66461aba0899e81d7a146332c45dbbacb1693c38fc2e4e578e39 +3 -3
  57. package/.npm/_cacache/index-v5/8a/ee/e3e86b627c10a9fc4ed610c15792507293ba1c14e7ba839e22aec609f1e0 +1 -1
  58. package/.npm/_cacache/index-v5/8b/ee/c2ea22c4bf9c5ddcd0333850e543442de3364478847c7ebc382b1ff3a70d +2 -2
  59. package/.npm/_cacache/index-v5/8c/2d/fc95c0f3896963b4fe4b745b6d2bbc04a2a75f31f108ff740215559617f0 +1 -1
  60. package/.npm/_cacache/index-v5/8e/95/715914a073e3319f22dfec7ffac9df9f293d150c0d6723a60ce08ab7f735 +1 -1
  61. package/.npm/_cacache/index-v5/92/a4/7b5bd924b74993fc2b0de1a458842881545ca2cc22f6bc104a0db4fafdab +1 -1
  62. package/.npm/_cacache/index-v5/96/3a/a15f6c4dc3aeb3fd89c0b7a8c3ba58cb31a9b72c98e3b11a8ef1647b537f +1 -1
  63. package/.npm/_cacache/index-v5/96/b2/def9b882b950a49a7096d71afd5fce3a6a9454795fc060b1901e41d44620 +1 -1
  64. package/.npm/_cacache/index-v5/98/64/01faddae5e2bf199c5f8953942897841c5634b1800e246226ea5489f4584 +1 -1
  65. package/.npm/_cacache/index-v5/99/a9/8e746181ef13bc400da207da412881206f4d2004d75453373f6ee7b25ffa +1 -1
  66. package/.npm/_cacache/index-v5/9a/fc/baddd71f459a50b3c710a007fa7d59fa62febef98033b7331374bf02db64 +1 -1
  67. package/.npm/_cacache/index-v5/9b/55/1bc87872916d09156d5c7056d7ac2b245e7a7638b817eb3dbeafa9d33be8 +1 -1
  68. package/.npm/_cacache/index-v5/9b/b8/d45062af43674e433f967d20768d308ed6ce195be6acadfb7cfd21d11e67 +1 -1
  69. package/.npm/_cacache/index-v5/9c/0e/3faaf557a9613fb7f09b5cecc63ebe78da10371a1f2f58b636f8dcb9a914 +1 -1
  70. package/.npm/_cacache/index-v5/9c/b1/fff150691ce095677426e98bb894621ce4a88097d4b2c5c342224e1852ae +1 -1
  71. package/.npm/_cacache/index-v5/9d/eb/0927bbd589e18b447a3726f591019d6728da728f603e77a1ded3f78dc6eb +1 -1
  72. package/.npm/_cacache/index-v5/9f/43/3636172cbc03abf2262c921f9f71572e6b049aa3db8c65d166bcfe5aca5f +1 -1
  73. package/.npm/_cacache/index-v5/a0/9e/5b7b95cdee86846e4fbe92c9e16e0e7f337c77d2c12de9778522b15bed2e +1 -1
  74. package/.npm/_cacache/index-v5/a1/ff/6532bc014331c9b572482a4bd805bf54a7ff8b4ca179b1c811aff3dec690 +1 -1
  75. package/.npm/_cacache/index-v5/a7/11/13f3c5864a7e9d12ca50a19b99d77d88fbcebb1ceb7455eb7ff77f158b64 +1 -1
  76. package/.npm/_cacache/index-v5/aa/9b/8b6d9e0f45dde1c6af2a4fc211f9b3a74f14041dc04a8a20490a478660b2 +1 -1
  77. package/.npm/_cacache/index-v5/aa/c4/489c0e6a9e4cbd64a8acd4fbfda113e9dfdd114f464830471fda53fff0cd +1 -1
  78. package/.npm/_cacache/index-v5/ab/47/d7a88d46cb8996b726bc7ed9280b5eea26889ab7c848149032a6e8911e4b +1 -1
  79. package/.npm/_cacache/index-v5/ac/4c/71e880f5d5c742e0e3807e7f3c398e920dd019bbf723586f0a7342715580 +1 -1
  80. package/.npm/_cacache/index-v5/ac/86/c0732592365d753d382502d91754a3c88f8b20e22cc25a0327beb9429687 +1 -1
  81. package/.npm/_cacache/index-v5/b0/9b/1a1d76c3ad82dd54353bb8ac8397667df4c5db97e42abf0de3fab68065bb +1 -1
  82. package/.npm/_cacache/index-v5/b3/b3/05a8af0a671c32b41850c1223429fe74449cfcb4c7cac54a9c7c213dfcae +3 -3
  83. package/.npm/_cacache/index-v5/b3/ba/fbf7da5c8eb06d9cc72143e3d36d7f701447b4e0a221c40d4960e06c7296 +1 -1
  84. package/.npm/_cacache/index-v5/b5/5f/1a200e91b7580c5893016e1b1397b6a076ff51cc7c5d382c3b1f1e52edd5 +1 -1
  85. package/.npm/_cacache/index-v5/b6/a8/3bf06da815e92239da2bd4ef7322819b458ee23ae8db9f02dc9a3dca722f +1 -1
  86. package/.npm/_cacache/index-v5/b7/38/992d3e6c01fc9098d137f7dbccfcaa5f5124ba9c487e582e6e0d83f99d30 +1 -1
  87. package/.npm/_cacache/index-v5/b7/d6/b5986a5f5d44d726090a94a22a8dff7a7c391df4a4fa4862bb50b1da196b +1 -1
  88. package/.npm/_cacache/index-v5/ba/d5/f7d95a8e3571758f8b5d095a21909a8f6cdfe7fd2349f7f72b2801eef079 +1 -1
  89. package/.npm/_cacache/index-v5/bb/8a/9c0052bb21f628e48a1e8d25084ee4adb402eba28c747d0299ebf4c3185d +1 -1
  90. package/.npm/_cacache/index-v5/be/a3/c0779c8e0be92c748c91a7dad4e6f0fe57ba0158b6bb1bcfddd8fc56c934 +1 -1
  91. package/.npm/_cacache/index-v5/be/c2/aa68eca6cebd477430ae24727732ec08ee9fc9ef2482df77932eb2f413d9 +1 -1
  92. package/.npm/_cacache/index-v5/bf/7c/375aec77f76404d91225e72006a0105b2a6ec04bb02cfa365ebcd4a0232b +1 -1
  93. package/.npm/_cacache/index-v5/c0/15/8b360dbe06b62052f2a43702140af0bca66e2e4064d7d2016efb4a2a149a +1 -1
  94. package/.npm/_cacache/index-v5/c2/a4/488f71f39bc65742422faf2c74e3b330852ef2192dbb3198fed044e60c20 +1 -1
  95. package/.npm/_cacache/index-v5/c4/89/38b2ab5b89326ead12dbed7a2076caa44d1207dd6cdb3f9f93273843dcf5 +1 -1
  96. package/.npm/_cacache/index-v5/c4/ac/4511be3eecea50ee9cadc09a612f9be8598d7b29d5c8b1253c75fa283cc5 +1 -1
  97. package/.npm/_cacache/index-v5/c5/2d/90031096314e15f4fcc35c804c2180f88214a7851b531aa27bd64064f740 +1 -1
  98. package/.npm/_cacache/index-v5/c7/5e/2acc90bb8fd9d3150354ec8b2f7e7cc2c8e0e59efd575a1963f1ca66cbed +1 -1
  99. package/.npm/_cacache/index-v5/c9/f5/c4a24d8834c4e9523cc24e10c6db63876e3eecdb2cf33762b159e3a1e92f +1 -1
  100. package/.npm/_cacache/index-v5/cc/2d/3cc1e00b73d00c921b8f8c92faaae480a160fc63637ba7b098518db79e02 +1 -1
  101. package/.npm/_cacache/index-v5/cf/56/427919eefb09afe942b12902069325293191afa7d59ff0f2b016c402b4ec +1 -1
  102. package/.npm/_cacache/index-v5/d3/ba/564670f99cd2d757d1ac6209834faf1ce9a94ed856243cf090249d9b2b38 +1 -1
  103. package/.npm/_cacache/index-v5/d5/f4/0913a74f5e223a4fe6108493dd3b03c2d47259df459926160659513c9ad3 +1 -1
  104. package/.npm/_cacache/index-v5/dd/03/456ce7d8bffee20c3acf7e18ef6501b637d59a6fa3fa7bac5ed160b6be3f +1 -1
  105. package/.npm/_cacache/index-v5/e3/6a/b90e45414a9e52cdf1e4a96698065357795b9400d7af079b0a75ee8fd76d +1 -1
  106. package/.npm/_cacache/index-v5/e7/16/c0952e37a6a02b506441a59ee6b0e7fa873a515247763df9dddd162bbcf0 +1 -1
  107. package/.npm/_cacache/index-v5/e8/50/601e38974398787a5a8a8b8d835e29447814cd68ff6fe2e9629738e124c6 +1 -1
  108. package/.npm/_cacache/index-v5/ee/47/02714e9e61ca394444a92772fe85340de8bd216b58f59e1af25d5618303f +1 -1
  109. package/.npm/_cacache/index-v5/ef/74/026f830458505ca7ae44dac678900360af24ed6e76521eb12df5fadcf26f +1 -1
  110. package/.npm/_cacache/index-v5/f1/75/91238e32e2ac4d9c4976deec39a2e6ca85c0c678a4466a50ca4412272a7c +1 -1
  111. package/.npm/_cacache/index-v5/f2/1f/c662626ec8eafafa54476678b9f71799a74ee368f2b7845a6ec9f9174a4d +3 -3
  112. package/.npm/_cacache/index-v5/f5/a4/ca599571c5bcfc5351ca53c418a6cd9d162539528b1ed87a692a1677020e +1 -1
  113. package/.npm/_cacache/index-v5/f6/18/16e565c66306149a0b31bb2af01babb55bd65ef7cb85a8a11d486d933b60 +1 -1
  114. package/.npm/_cacache/index-v5/f8/f5/f04b833fa130e113a9093088ad108d8cf9b2b1d5a0336e48cbf0916b8686 +1 -1
  115. package/.npm/_cacache/index-v5/fa/88/31cbd6ca584e75edf3642c6f8b079c1f2b5eca1d7b2780ce2e86c24f1e84 +1 -1
  116. package/.npm/_cacache/index-v5/fb/ae/46c38299837b3b4dcee9dc45854a6901355864326b4e64c730727ca1c88a +1 -1
  117. package/.npm/_cacache/index-v5/fc/1c/958fc085ebdc42fa37d4985cba976a5cca21f678c751c968f8fe9b259455 +1 -1
  118. package/.npm/_cacache/index-v5/fd/2e/6ead8880f4d02a536a570e21b13b4e7c9700082833e556cd53e9e92bfd1b +1 -1
  119. package/.npm/_cacache/index-v5/fd/46/fa56121e15b7f090f8050d0c954bbc9452e4c7ddde82777b2e00552c4220 +1 -1
  120. package/README.md +3 -2
  121. package/dist/templates/mxw-base-api-express/.dockerignore +2 -0
  122. package/dist/templates/mxw-base-api-express/.env +10 -0
  123. package/dist/templates/mxw-base-api-express/.gitlab-ci.yml +155 -0
  124. package/dist/templates/mxw-base-api-express/.nvmrc +1 -0
  125. package/dist/templates/mxw-base-api-express/Dockerfile +14 -0
  126. package/dist/templates/mxw-base-api-express/Makefile +84 -0
  127. package/dist/templates/mxw-base-api-express/README.md +71 -0
  128. package/dist/templates/mxw-base-api-express/package.json +55 -0
  129. package/dist/templates/mxw-base-api-express/src/app-service.test.ts +94 -0
  130. package/dist/templates/mxw-base-api-express/src/app-service.ts +498 -0
  131. package/dist/templates/mxw-base-api-express/src/auth/auth-user.test.ts +215 -0
  132. package/dist/templates/mxw-base-api-express/src/auth/auth-user.ts +86 -0
  133. package/dist/templates/mxw-base-api-express/src/auth/auth.ts +81 -0
  134. package/dist/templates/mxw-base-api-express/src/core-service.ts +72 -0
  135. package/dist/templates/mxw-base-api-express/src/crud.ts +84 -0
  136. package/dist/templates/mxw-base-api-express/src/http-handler.ts +71 -0
  137. package/dist/templates/mxw-base-api-express/src/server.ts +54 -0
  138. package/dist/templates/mxw-base-api-express/src/test.ts +38 -0
  139. package/dist/templates/mxw-base-api-express/src/utils/api-utilities.ts +52 -0
  140. package/dist/templates/mxw-base-api-express/src/utils/file-utilities.ts +55 -0
  141. package/dist/templates/mxw-base-api-express/tsconfig.json +32 -0
  142. package/package.json +1 -1
  143. package/templates/mxw-base-api-express/.dockerignore +2 -0
  144. package/templates/mxw-base-api-express/.env +10 -0
  145. package/templates/mxw-base-api-express/.gitlab-ci.yml +155 -0
  146. package/templates/mxw-base-api-express/.nvmrc +1 -0
  147. package/templates/mxw-base-api-express/Dockerfile +14 -0
  148. package/templates/mxw-base-api-express/Makefile +84 -0
  149. package/templates/mxw-base-api-express/README.md +71 -0
  150. package/templates/mxw-base-api-express/package.json +55 -0
  151. package/templates/mxw-base-api-express/src/app-service.test.ts +94 -0
  152. package/templates/mxw-base-api-express/src/app-service.ts +498 -0
  153. package/templates/mxw-base-api-express/src/auth/auth-user.test.ts +215 -0
  154. package/templates/mxw-base-api-express/src/auth/auth-user.ts +86 -0
  155. package/templates/mxw-base-api-express/src/auth/auth.ts +81 -0
  156. package/templates/mxw-base-api-express/src/core-service.ts +72 -0
  157. package/templates/mxw-base-api-express/src/crud.ts +84 -0
  158. package/templates/mxw-base-api-express/src/http-handler.ts +71 -0
  159. package/templates/mxw-base-api-express/src/server.ts +54 -0
  160. package/templates/mxw-base-api-express/src/test.ts +38 -0
  161. package/templates/mxw-base-api-express/src/utils/api-utilities.ts +52 -0
  162. package/templates/mxw-base-api-express/src/utils/file-utilities.ts +55 -0
  163. package/templates/mxw-base-api-express/tsconfig.json +32 -0
@@ -0,0 +1,215 @@
1
+ 'use strict';
2
+
3
+ import { describe, it, before, after, beforeEach, afterEach } from 'mocha';
4
+ import { expect } from 'chai';
5
+ import Sinon from "sinon";
6
+ import jwt from "jsonwebtoken";
7
+ import AuthUser from './auth-user';
8
+ import { CREDENTIAL_TYPE } from './auth';
9
+ import { errors } from 'mxw-libs-errors';
10
+
11
+ let sandbox: Sinon.SinonSandbox;
12
+ let clock: Sinon.SinonFakeTimers;
13
+
14
+ const JWT_SECRET = "secret";
15
+
16
+ describe('Suite: AuthUser', () => {
17
+ before(function () {
18
+ clock = Sinon.useFakeTimers({
19
+ now: new Date().getTime(),
20
+ shouldAdvanceTime: true
21
+ });
22
+ });
23
+
24
+ beforeEach(function () {
25
+ sandbox = Sinon.createSandbox();
26
+ });
27
+
28
+ afterEach(function () {
29
+ if (sandbox) {
30
+ sandbox.restore();
31
+ sandbox = undefined;
32
+ }
33
+ });
34
+
35
+ after(function () {
36
+ if (clock) {
37
+ clock.restore();
38
+ clock = undefined;
39
+ }
40
+ });
41
+
42
+ describe("Create credential", async () => {
43
+ it("Create token with minimum fields", async () => {
44
+ AuthUser.init(JWT_SECRET, "1m");
45
+
46
+ const token = AuthUser.Instance.createToken({
47
+ userId: 1,
48
+ type: CREDENTIAL_TYPE.USER,
49
+ username: "bean"
50
+ });
51
+
52
+ expect(token).is.a("string").lengthOf.greaterThan(0);
53
+ });
54
+
55
+ it("Create token with all fields", async () => {
56
+ AuthUser.init(JWT_SECRET, "1m");
57
+
58
+ const token = AuthUser.Instance.createToken({
59
+ id: 1,
60
+ userId: 1,
61
+ type: CREDENTIAL_TYPE.USER,
62
+ orgId: 100,
63
+ email: "bean@happy.com",
64
+ username: "bean"
65
+ });
66
+
67
+ expect(token).is.a("string").lengthOf.greaterThan(0);
68
+ });
69
+
70
+ it("Create token with missing field", async () => {
71
+ AuthUser.init(JWT_SECRET, "1m");
72
+
73
+ const fields = {
74
+ id: 1,
75
+ userId: 1,
76
+ type: CREDENTIAL_TYPE.USER,
77
+ orgId: 100,
78
+ email: "bean@happy.com",
79
+ username: "bean"
80
+ }
81
+
82
+ delete fields.userId;
83
+
84
+ try {
85
+ AuthUser.Instance.createToken(fields);
86
+ expect.fail("It should be failed");
87
+ }
88
+ catch (error) {
89
+ expect(error).has.property("code").eq(errors.PARAMETER_MISSING);
90
+ }
91
+ });
92
+ });
93
+
94
+ describe("Verify credential", async () => {
95
+ it("Verify token", async () => {
96
+ AuthUser.init(JWT_SECRET, "1m");
97
+
98
+ const token = AuthUser.Instance.createToken({
99
+ userId: 1,
100
+ type: CREDENTIAL_TYPE.USER,
101
+ username: "bean"
102
+ });
103
+
104
+ const credential = AuthUser.Instance.verifyToken(token, CREDENTIAL_TYPE.USER);
105
+
106
+ expect(credential).has.property("userId").is.a("number").eq(1);
107
+ expect(credential).has.property("type").is.a("number").eq(CREDENTIAL_TYPE.USER);
108
+ expect(credential).has.property("username").is.a("string").eq("bean");
109
+ });
110
+
111
+ it("Accept all token type", async () => {
112
+ AuthUser.init(JWT_SECRET, "1m");
113
+
114
+ const token = AuthUser.Instance.createToken({
115
+ userId: 1,
116
+ type: CREDENTIAL_TYPE.USER,
117
+ username: "bean"
118
+ });
119
+
120
+ const credential = AuthUser.Instance.verifyToken(token, null);
121
+
122
+ expect(credential).has.property("userId").is.a("number").eq(1);
123
+ expect(credential).has.property("type").is.a("number").eq(CREDENTIAL_TYPE.USER);
124
+ expect(credential).has.property("username").is.a("string").eq("bean");
125
+ });
126
+
127
+ it("Verify broken token", async () => {
128
+ const token = jwt.sign({
129
+ hello: "world"
130
+ }, JWT_SECRET, { expiresIn: "1m" });
131
+
132
+ try {
133
+ AuthUser.Instance.verifyToken(token, CREDENTIAL_TYPE.USER);
134
+ expect.fail("It should be failed");
135
+ }
136
+ catch (error) {
137
+ expect(error).has.property("code").eq(errors.PARAMETER_MISSING);
138
+ }
139
+ });
140
+
141
+ it("Verify invalid token", async () => {
142
+ try {
143
+ AuthUser.Instance.verifyToken("Trust me.. I am good", CREDENTIAL_TYPE.USER);
144
+ expect.fail("It should be failed");
145
+ }
146
+ catch (error) {
147
+ expect(error).has.property("code").eq(errors.INVALID_SIGNATURE);
148
+ }
149
+ });
150
+
151
+ it("Verify mismatched token type", async () => {
152
+ AuthUser.init(JWT_SECRET, "1m");
153
+
154
+ const token = AuthUser.Instance.createToken({
155
+ userId: 1,
156
+ type: CREDENTIAL_TYPE.USER,
157
+ username: "bean"
158
+ });
159
+
160
+ try {
161
+ AuthUser.Instance.verifyToken(token, CREDENTIAL_TYPE.GUEST);
162
+ expect.fail("It should be failed");
163
+ }
164
+ catch (error) {
165
+ expect(error).has.property("code").eq(errors.INVALID_FORMAT);
166
+ }
167
+ });
168
+
169
+ it("Verify invalid token type", async () => {
170
+ AuthUser.init(JWT_SECRET, "1m");
171
+
172
+ const stub = sandbox.stub(AuthUser.Instance as any, "checkCredential").callsFake((cred: Credential, type?: CREDENTIAL_TYPE) => {
173
+ return cred;
174
+ });
175
+
176
+ const token = AuthUser.Instance.createToken({
177
+ userId: 1,
178
+ type: 100,
179
+ username: "bean"
180
+ });
181
+
182
+ stub.restore();
183
+
184
+ try {
185
+ AuthUser.Instance.verifyToken(token, null);
186
+ expect.fail("It should be failed");
187
+ }
188
+ catch (error) {
189
+ expect(error).has.property("code").eq(errors.INVALID_FORMAT);
190
+ }
191
+ });
192
+
193
+ it("Verify expired token", async () => {
194
+ AuthUser.init(JWT_SECRET, "1m");
195
+
196
+ const token = AuthUser.Instance.createToken({
197
+ userId: 1,
198
+ type: CREDENTIAL_TYPE.USER,
199
+ username: "bean"
200
+ });
201
+
202
+ await clock.tickAsync(60000);
203
+
204
+ try {
205
+ const credential = AuthUser.Instance.verifyToken(token, CREDENTIAL_TYPE.USER);
206
+ expect.fail("It should be failed");
207
+ }
208
+ catch (error) {
209
+ expect(error).has.property("code").eq(errors.EXPIRED);
210
+ }
211
+ });
212
+
213
+ });
214
+
215
+ });
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+
3
+ import { allowNull, allowNullOrEmpty, checkFormat, checkNumber, checkString, isUndefinedOrNull, isUndefinedOrNullOrEmpty, notAllowNullOrEmpty } from "mxw-libs-utils";
4
+ import { errors, throwError } from "mxw-libs-errors";
5
+
6
+ import { BearerToken, CREDENTIAL_TYPE } from "./auth";
7
+
8
+ export * from "./auth";
9
+
10
+ export class Credential {
11
+ id?: number;
12
+ userId: number;
13
+ type: CREDENTIAL_TYPE;
14
+ orgId?: number;
15
+ email?: string;
16
+ username: string;
17
+ iat?: number;
18
+ exp?: number;
19
+
20
+ static check(cred: Credential, type: CREDENTIAL_TYPE) {
21
+ if (isUndefinedOrNullOrEmpty(cred)) {
22
+ throwError(errors.NOT_INITIALIZED, "Missing credential");
23
+ }
24
+
25
+ return checkFormat({
26
+ id: allowNull(checkNumber),
27
+ userId: notAllowNullOrEmpty(checkNumber),
28
+ type: function (value) {
29
+ const credType = checkNumber(value);
30
+
31
+ if (type === credType) {
32
+ return credType;
33
+ }
34
+ else {
35
+ if (isUndefinedOrNull(type)) {
36
+ for (const t in CREDENTIAL_TYPE) {
37
+ if (Number(t) === credType) {
38
+ return credType;
39
+ }
40
+ }
41
+ }
42
+ }
43
+
44
+ throwError(errors.INVALID_PARAMETER, "Invalid credential type", { credType });
45
+ },
46
+ orgId: allowNull(checkNumber),
47
+ email: allowNullOrEmpty(checkString),
48
+ username: notAllowNullOrEmpty(checkString),
49
+ iat: allowNull(checkNumber, undefined),
50
+ exp: allowNull(checkNumber, undefined)
51
+ }, cred) as Credential;
52
+ }
53
+ }
54
+
55
+ export class GuestCredential extends Credential {
56
+ static check(cred: GuestCredential) {
57
+ return super.check(cred, CREDENTIAL_TYPE.GUEST) as GuestCredential;
58
+ }
59
+ }
60
+
61
+ export class UserCredential extends Credential {
62
+ static check(cred: UserCredential) {
63
+ return super.check(cred, CREDENTIAL_TYPE.USER) as UserCredential;
64
+ }
65
+ }
66
+
67
+ export default class BasicAuth extends BearerToken<GuestCredential | UserCredential> {
68
+ private static self: BasicAuth;
69
+
70
+ constructor(secret: string, expiresIn: string, options?: any) {
71
+ super(secret, expiresIn, options);
72
+ }
73
+
74
+ public static get Instance() {
75
+ return this.self || throwError(errors.NOT_INITIALIZED, "BasicAuth initialization is required");
76
+ }
77
+
78
+ public static init(secret: string, expiresIn: string, options?: any) {
79
+ this.self = new BasicAuth(secret, expiresIn, options);
80
+ }
81
+
82
+ protected checkCredential(cred: GuestCredential | UserCredential, type?: CREDENTIAL_TYPE) {
83
+ return Credential.check(cred, type);
84
+ }
85
+
86
+ }
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+
3
+ import { allowNullOrEmpty, checkFormat, checkString, isUndefinedOrNullOrEmpty, notAllowNullOrEmpty } from "mxw-libs-utils";
4
+ import jwt, { SignOptions, VerifyOptions } from "jsonwebtoken";
5
+ import { describeError, errors, throwError } from "mxw-libs-errors";
6
+
7
+ export enum CREDENTIAL_TYPE {
8
+ GUEST = 0,
9
+ USER = 1,
10
+ }
11
+
12
+ export interface AuthCredential<C> {
13
+ cred: C;
14
+ checkCredential(type?: CREDENTIAL_TYPE): C;
15
+ auth(cred: C): AuthCredential<C>;
16
+ }
17
+
18
+ export abstract class BearerToken<C> {
19
+ private jwtSecret: string;
20
+ private signOptions: SignOptions;
21
+ private verifyOptions: VerifyOptions;
22
+
23
+ constructor(jwtSecret: string, jwtExpiresIn?: string, options?: any) {
24
+ const params: {
25
+ jwtSecret: string,
26
+ jwtExpiresIn?: string,
27
+ } = checkFormat({
28
+ jwtSecret: notAllowNullOrEmpty(checkString),
29
+ jwtExpiresIn: allowNullOrEmpty(checkString)
30
+ }, { jwtSecret, jwtExpiresIn });
31
+
32
+ this.signOptions = {};
33
+
34
+ if (params.jwtExpiresIn) {
35
+ this.signOptions.expiresIn = params.jwtExpiresIn;
36
+ }
37
+
38
+ this.verifyOptions = {};
39
+
40
+ if (!isUndefinedOrNullOrEmpty(options?.JWT_SIGN_ALGO)) {
41
+ this.signOptions.algorithm = options?.JWT_SIGN_ALGO;
42
+ this.verifyOptions.algorithms = [options?.JWT_SIGN_ALGO];
43
+ }
44
+
45
+ this.jwtSecret = params.jwtSecret;
46
+ }
47
+
48
+ protected abstract checkCredential(cred: C, type?: CREDENTIAL_TYPE): C;
49
+
50
+ public createToken(cred: C, overrides?: any) {
51
+ const payload = this.checkCredential(cred);
52
+
53
+ if (!this.signOptions.expiresIn) {
54
+ throwError(errors.NOT_INITIALIZED, "Session expiry is not initialized");
55
+ }
56
+
57
+ return jwt.sign({
58
+ ...overrides, ...payload
59
+ }, this.jwtSecret, this.signOptions);
60
+ }
61
+
62
+ public verifyToken(token: string, type: CREDENTIAL_TYPE) {
63
+ try {
64
+ const cred: any = jwt.verify(token, this.jwtSecret, this.verifyOptions) || throwError(errors.UNEXPECTED_MESSAGE, "Missing session", { token });
65
+ return this.checkCredential(cred, type);
66
+ }
67
+ catch (error) {
68
+ const { code, message } = describeError(error);
69
+
70
+ if (errors.INVALID_FORMAT == code) {
71
+ throwError(errors.INVALID_FORMAT, message, { token, error });
72
+ }
73
+
74
+ switch (error.name) {
75
+ case "TokenExpiredError": throwError(errors.EXPIRED, "Session expired", { token });
76
+ case "JsonWebTokenError": throwError(errors.INVALID_SIGNATURE, "Invalid token", { token });
77
+ }
78
+ throw error;
79
+ }
80
+ }
81
+ }
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ // for local development only
3
+ if (process.env.NODE_ENV == "local") require('dotenv').config()
4
+ import { CLogger, clog, levels } from "mxw-libs-clogger";
5
+ import { errors, throwError } from "mxw-libs-errors";
6
+ import { isUndefinedOrNull } from "mxw-libs-utils";
7
+ import AppService from "./app-service";
8
+
9
+ const { name, version } = require("../package.json");
10
+
11
+ export default class CoreService {
12
+ private static self: CoreService;
13
+
14
+ public static get Instance(): CoreService {
15
+ return this.self || throwError(errors.NOT_INITIALIZED, "CoreService initialization is required");
16
+ }
17
+
18
+ public static init(logLevel?: string) {
19
+ CLogger.Instance.init(levels.NORMAL);
20
+
21
+ if (isUndefinedOrNull(logLevel)) {
22
+ for (const [index, argv] of process.argv.entries()) {
23
+ if ("logLevel" == argv)
24
+ logLevel = process.argv[index + 1];
25
+ }
26
+ }
27
+
28
+ if (!isUndefinedOrNull(levels[logLevel])) {
29
+ CLogger.Instance.level = levels[logLevel];
30
+ }
31
+
32
+ const self = this.self = new this();
33
+
34
+ return self;
35
+ }
36
+
37
+ public static async term() {
38
+ try {
39
+ clog(levels.WARNING, "Service is terminating...");
40
+
41
+ if (this.self) {
42
+ // Terminate service
43
+ await AppService.term();
44
+
45
+ this.self = undefined;
46
+ }
47
+
48
+ clog(levels.WARNING, "Service is terminated");
49
+ }
50
+ catch (error) {
51
+ clog(levels.CRITICAL, "Service failed to terminate:", error);
52
+ throw error;
53
+ }
54
+ }
55
+
56
+ public async run() {
57
+ try {
58
+ clog(levels.WARNING, "Service", name, "(" + version + ") is starting...");
59
+
60
+ // Initialize service
61
+ const instance = await AppService.init();
62
+ const url = await instance.run();
63
+
64
+ clog(levels.WARNING, "Service is serving", url);
65
+ return this;
66
+ }
67
+ catch (error) {
68
+ clog(levels.CRITICAL, "Service failed to start:", error);
69
+ throw error;
70
+ }
71
+ }
72
+ }
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+
3
+ import { allowNull, checkFormat, checkNumber, renameKey } from "mxw-libs-utils";
4
+ import { AuthCredential, CREDENTIAL_TYPE } from "./auth/auth";
5
+
6
+ export * from "./auth/auth";
7
+
8
+ export class BaseList {
9
+ public static renameKey(obj: any, keys?: { [key: string]: string }) {
10
+ if (!keys) return { ...obj };
11
+
12
+ return renameKey({ ...obj }, (key) => {
13
+ if (keys[key]) {
14
+ return keys[key];
15
+ }
16
+ return key;
17
+ });
18
+ }
19
+
20
+ public static diff(rec: any, out: any) {
21
+ let diff = [];
22
+
23
+ for (const key in rec) {
24
+ if (undefined === out[key]) {
25
+ diff.push(key);
26
+ }
27
+ }
28
+ return diff;
29
+ }
30
+ }
31
+
32
+ class Pagination {
33
+ private _page: number;
34
+ private _pageSize: number;
35
+
36
+ constructor(page?: number, pageSize?: number) {
37
+ this.pagination(page, pageSize);
38
+ }
39
+
40
+ public pagination(page?: number, pageSize?: number) {
41
+ const params: {
42
+ page: number,
43
+ pageSize: number
44
+ } = checkFormat({
45
+ page: allowNull(checkNumber, this._page),
46
+ pageSize: allowNull(checkNumber, this._pageSize)
47
+ }, { page, pageSize });
48
+
49
+ this._page = params.page;
50
+ this._pageSize = params.pageSize;
51
+
52
+ return this;
53
+ }
54
+
55
+ public get page() {
56
+ return this._page;
57
+ }
58
+ public get pageSize() {
59
+ return this._pageSize;
60
+ }
61
+ }
62
+
63
+ export default abstract class CRUD<C, CI, UI, DI> extends Pagination implements AuthCredential<C>{
64
+ private _cred: C;
65
+
66
+ public abstract picklist(overrides?: any);
67
+ public abstract list(overrides?: any);
68
+ public abstract getDetail(id: number, overrides?: any);
69
+ public abstract create(params: CI);
70
+ public abstract update(params: UI);
71
+ public abstract delete(id: number | DI);
72
+
73
+ public abstract checkCredential(type?: CREDENTIAL_TYPE): C;
74
+
75
+ public auth(cred: C, type = CREDENTIAL_TYPE.USER) {
76
+ this._cred = cred;
77
+ this.checkCredential(type);
78
+ return this;
79
+ }
80
+
81
+ public get cred() {
82
+ return this._cred;
83
+ }
84
+ }
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+
3
+ import { Request, Response, NextFunction } from "express";
4
+ import { clog, levels } from "mxw-libs-clogger";
5
+ import { errors, throwError } from "mxw-libs-errors";
6
+
7
+ export const finalHandler = (req: Request, res: Response, next: NextFunction) => {
8
+ if (!res.headersSent) {
9
+ res.statusCode = 404;
10
+ throwError(errors.NOT_FOUND, "Resource not found");
11
+ }
12
+
13
+ resLog(null, req, res);
14
+ };
15
+
16
+ export const errorHandler = (error: any, req: Request, res: Response, next: NextFunction) => {
17
+ const { code, message } = errors.describeError(error);
18
+
19
+ let statusCode: number;
20
+
21
+ // Respect the status code that caller specified
22
+ if (200 !== res.statusCode) {
23
+ statusCode = res.statusCode;
24
+ }
25
+ else {
26
+ // Define the default status code that based on error code
27
+ switch (code) {
28
+ case errors.UNAUTHORISED:
29
+ case errors.EXPIRED:
30
+ statusCode = 401;
31
+ break;
32
+ case "TooManyRequests":
33
+ statusCode = 429;
34
+ break;
35
+ default:
36
+ statusCode = 500;
37
+ }
38
+ }
39
+
40
+ res.status(statusCode).send({
41
+ ret: code,
42
+ message
43
+ });
44
+
45
+ resLog(error, req, res);
46
+ };
47
+
48
+ const resLog = (error: any, req: Request, res: Response) => {
49
+ const ip = req.headers?.['x-forwarded-for'] || req.headers?.['x-real-ip'] || "0.0.0.0";
50
+
51
+ try {
52
+ const contentLength = res.getHeaders()["content-length"];
53
+
54
+ if (!error) {
55
+ if (!req["logExcluded"]) {
56
+ clog(levels.ERROR, `RES: ${req.method} ${req.url} HTTP/${req.httpVersion} @${ip}`,
57
+ `OK ${contentLength || "-"}, elapsed: ${res["elapsed"] + "ms" || "--"}`);
58
+ }
59
+ }
60
+ else {
61
+ const { code, message, reason } = errors.describeError(error);
62
+
63
+ clog(levels.ERROR, `RES: ${req.method} ${req.url} HTTP/${req.httpVersion} @${ip}`,
64
+ `${res.statusCode}: ${code || "?"}, ${contentLength || "-"}, elapsed: ${res["elapsed"] + "ms" || "--"}, ${reason || message || "Unknown error"}`);
65
+ }
66
+ }
67
+ catch (err) {
68
+ clog(levels.ERROR, `RES: ${req.method} ${req.url} HTTP/${req.httpVersion} @${ip}`,
69
+ `${res.statusCode}: ${"?"} -, elapsed: ${res["elapsed"] + "ms" || "--"}, ${error}`);
70
+ }
71
+ };
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+
3
+ import { CLogger, clog, levels } from "mxw-libs-clogger";
4
+ import CoreService from "./core-service"
5
+
6
+ CoreService.init().run().catch(async () => {
7
+ await CoreService.term().catch(() => { });
8
+ process.exit(-1);
9
+ });
10
+
11
+ async function exitHandler(cleanup = false) {
12
+ if (cleanup) {
13
+ await CoreService.term().catch(() => { });
14
+ }
15
+ }
16
+
17
+ //do something when app is closing
18
+ process.on("exit", exitHandler.bind(null, false));
19
+
20
+ //catches ctrl+c event
21
+ process.on("SIGINT", exitHandler.bind(null, true));
22
+
23
+ //catches SIGHUP (1) event to increase log depth (circled)
24
+ process.on("SIGHUP", () => {
25
+ CLogger.Instance.depth = null;
26
+ clog(levels.CRITICAL, "Logger depth:", CLogger.Instance.depth);
27
+ });
28
+
29
+ //catches SIGUSR1 (10) event to increase log width (circled)
30
+ process.on("SIGUSR1", () => {
31
+ CLogger.Instance.width = null;
32
+ clog(levels.CRITICAL, "Logger width:", CLogger.Instance.width);
33
+ });
34
+
35
+ //catches SIGUSR2 (12) event to increase log severity (circled)
36
+ process.on("SIGUSR2", () => {
37
+ CLogger.Instance.level = null;
38
+ clog(levels.CRITICAL, "Logger level:", CLogger.Instance.level);
39
+ });
40
+
41
+ //catches uncaught exceptions
42
+ process.on("uncaughtException", (error) => {
43
+ exitHandler.bind(null, true);
44
+ });
45
+
46
+ //catches unhandled rejection
47
+ process.on("unhandledRejection", (reason) => {
48
+ if (process.stderr.writable) {
49
+ process.stderr.write(`unhandledRejection: ${reason}`);
50
+ }
51
+ });
52
+
53
+ // listen for TERM signal .e.g. kill
54
+ process.on("SIGTERM", exitHandler.bind(null, true));
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+
3
+ import { expect } from 'chai';
4
+
5
+ export interface TARGET {
6
+ key: string;
7
+ type: string;
8
+ value: any;
9
+ }
10
+
11
+ export function assertValue(value: any, target: TARGET) {
12
+ if (null === target.value || undefined === target.value) {
13
+ if (!target.key) {
14
+ expect(value).is.not.exist;
15
+ }
16
+ else {
17
+ expect(value).has.property(target.key).is.not.exist;
18
+ }
19
+ }
20
+ else {
21
+ if ("object" === target.type) {
22
+ if (!target.key) {
23
+ expect(value).to.deep.equal(target.value);
24
+ }
25
+ else {
26
+ expect(value).has.property(target.key).to.deep.equal(target.value);
27
+ }
28
+ }
29
+ else {
30
+ if (!target.key) {
31
+ expect(value).is.a(target.type).is.eq(target.value);
32
+ }
33
+ else {
34
+ expect(value).has.property(target.key).is.a(target.type).is.eq(target.value);
35
+ }
36
+ }
37
+ }
38
+ }