@jmlq/auth 0.0.1-alpha.1

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 (332) hide show
  1. package/README.md +306 -0
  2. package/dist/examples/bcrypt-password-hasher.example.d.ts +3 -0
  3. package/dist/examples/bcrypt-password-hasher.example.js +78 -0
  4. package/dist/examples/entity-object.example.d.ts +39 -0
  5. package/dist/examples/entity-object.example.js +411 -0
  6. package/dist/examples/factory-auth-service-example.d.ts +3 -0
  7. package/dist/examples/factory-auth-service-example.js +84 -0
  8. package/dist/examples/index.example.d.ts +12 -0
  9. package/dist/examples/index.example.js +171 -0
  10. package/dist/examples/jwt-algoritm.example.d.ts +47 -0
  11. package/dist/examples/jwt-algoritm.example.js +447 -0
  12. package/dist/examples/jwt-token-generator.example.d.ts +6 -0
  13. package/dist/examples/jwt-token-generator.example.js +49 -0
  14. package/dist/examples/jwt-verifier.example.d.ts +3 -0
  15. package/dist/examples/jwt-verifier.example.js +80 -0
  16. package/dist/examples/password-policy.example.d.ts +7 -0
  17. package/dist/examples/password-policy.example.js +57 -0
  18. package/dist/examples/service-jwt-token.example.d.ts +3 -0
  19. package/dist/examples/service-jwt-token.example.js +154 -0
  20. package/dist/examples/service-token-session.example.d.ts +3 -0
  21. package/dist/examples/service-token-session.example.js +139 -0
  22. package/dist/examples/use-case-login-with-password.example.d.ts +6 -0
  23. package/dist/examples/use-case-login-with-password.example.js +105 -0
  24. package/dist/examples/use-case-logout.example.d.ts +7 -0
  25. package/dist/examples/use-case-logout.example.js +134 -0
  26. package/dist/examples/use-case-refresh-token.example.d.ts +11 -0
  27. package/dist/examples/use-case-refresh-token.example.js +164 -0
  28. package/dist/examples/use-case-register-user.example.d.ts +9 -0
  29. package/dist/examples/use-case-register-user.example.js +110 -0
  30. package/dist/index.d.ts +1 -0
  31. package/dist/index.js +17 -0
  32. package/dist/src/application/dtos/index.d.ts +4 -0
  33. package/dist/src/application/dtos/index.js +20 -0
  34. package/dist/src/application/dtos/login.dto.d.ts +9 -0
  35. package/dist/src/application/dtos/login.dto.js +2 -0
  36. package/dist/src/application/dtos/logout.dto.d.ts +7 -0
  37. package/dist/src/application/dtos/logout.dto.js +2 -0
  38. package/dist/src/application/dtos/refresh-token.dto.d.ts +7 -0
  39. package/dist/src/application/dtos/refresh-token.dto.js +2 -0
  40. package/dist/src/application/dtos/register-user.dto.d.ts +16 -0
  41. package/dist/src/application/dtos/register-user.dto.js +2 -0
  42. package/dist/src/application/factories/auth-service.factory.d.ts +5 -0
  43. package/dist/src/application/factories/auth-service.factory.js +51 -0
  44. package/dist/src/application/factories/index.d.ts +1 -0
  45. package/dist/src/application/factories/index.js +17 -0
  46. package/dist/src/application/index.d.ts +3 -0
  47. package/dist/src/application/index.js +19 -0
  48. package/dist/src/application/use-cases/index.d.ts +4 -0
  49. package/dist/src/application/use-cases/index.js +20 -0
  50. package/dist/src/application/use-cases/login-with-password.use-case.d.ts +9 -0
  51. package/dist/src/application/use-cases/login-with-password.use-case.js +36 -0
  52. package/dist/src/application/use-cases/logout.use-case.d.ts +7 -0
  53. package/dist/src/application/use-cases/logout.use-case.js +22 -0
  54. package/dist/src/application/use-cases/refresh-token.use-case.d.ts +7 -0
  55. package/dist/src/application/use-cases/refresh-token.use-case.js +23 -0
  56. package/dist/src/application/use-cases/register-user.use-case.d.ts +10 -0
  57. package/dist/src/application/use-cases/register-user.use-case.js +37 -0
  58. package/dist/src/domain/entities/credential.entity.d.ts +78 -0
  59. package/dist/src/domain/entities/credential.entity.js +92 -0
  60. package/dist/src/domain/entities/index.d.ts +2 -0
  61. package/dist/src/domain/entities/index.js +18 -0
  62. package/dist/src/domain/entities/user.entity.d.ts +97 -0
  63. package/dist/src/domain/entities/user.entity.js +116 -0
  64. package/dist/src/domain/errors/auth-domain-error.d.ts +82 -0
  65. package/dist/src/domain/errors/auth-domain-error.js +112 -0
  66. package/dist/src/domain/errors/auth.errors.d.ts +56 -0
  67. package/dist/src/domain/errors/auth.errors.js +76 -0
  68. package/dist/src/domain/errors/identity.errors.d.ts +34 -0
  69. package/dist/src/domain/errors/identity.errors.js +82 -0
  70. package/dist/src/domain/errors/index.d.ts +2 -0
  71. package/dist/src/domain/errors/index.js +18 -0
  72. package/dist/src/domain/index.d.ts +6 -0
  73. package/dist/src/domain/index.js +22 -0
  74. package/dist/src/domain/object-values/email.d.ts +37 -0
  75. package/dist/src/domain/object-values/email.js +56 -0
  76. package/dist/src/domain/object-values/hashed-password.d.ts +28 -0
  77. package/dist/src/domain/object-values/hashed-password.js +73 -0
  78. package/dist/src/domain/object-values/id.d.ts +8 -0
  79. package/dist/src/domain/object-values/id.js +28 -0
  80. package/dist/src/domain/object-values/index.d.ts +5 -0
  81. package/dist/src/domain/object-values/index.js +13 -0
  82. package/dist/src/domain/object-values/permission.d.ts +15 -0
  83. package/dist/src/domain/object-values/permission.js +57 -0
  84. package/dist/src/domain/object-values/role.d.ts +25 -0
  85. package/dist/src/domain/object-values/role.js +108 -0
  86. package/dist/src/domain/ports/auth/password-hasher.d.ts +7 -0
  87. package/dist/src/domain/ports/auth/password-hasher.js +2 -0
  88. package/dist/src/domain/ports/auth/password-policy-config.port.d.ts +0 -0
  89. package/dist/src/domain/ports/auth/password-policy-config.port.js +10 -0
  90. package/dist/src/domain/ports/auth/password-policy.port.d.ts +10 -0
  91. package/dist/src/domain/ports/auth/password-policy.port.js +2 -0
  92. package/dist/src/domain/ports/config/auth-config.port.d.ts +19 -0
  93. package/dist/src/domain/ports/config/auth-config.port.js +3 -0
  94. package/dist/src/domain/ports/index.d.ts +9 -0
  95. package/dist/src/domain/ports/index.js +25 -0
  96. package/dist/src/domain/ports/jwt/factory/signature-strategy-factory.port.d.ts +14 -0
  97. package/dist/src/domain/ports/jwt/factory/signature-strategy-factory.port.js +2 -0
  98. package/dist/src/domain/ports/jwt/payload/jwt-payload.port.d.ts +12 -0
  99. package/dist/src/domain/ports/jwt/payload/jwt-payload.port.js +2 -0
  100. package/dist/src/domain/ports/jwt/signature-strategy-factory.port.d.ts +14 -0
  101. package/dist/src/domain/ports/jwt/signature-strategy-factory.port.js +2 -0
  102. package/dist/src/domain/ports/jwt/signature-strategy.d.ts +30 -0
  103. package/dist/src/domain/ports/jwt/signature-strategy.js +4 -0
  104. package/dist/src/domain/ports/jwt/signature-strategy.port.d.ts +31 -0
  105. package/dist/src/domain/ports/jwt/signature-strategy.port.js +4 -0
  106. package/dist/src/domain/ports/jwt/strategy/signature-strategy.port.d.ts +31 -0
  107. package/dist/src/domain/ports/jwt/strategy/signature-strategy.port.js +4 -0
  108. package/dist/src/domain/ports/repository/credential.repository.d.ts +10 -0
  109. package/dist/src/domain/ports/repository/credential.repository.js +2 -0
  110. package/dist/src/domain/ports/repository/index.d.ts +2 -0
  111. package/dist/src/domain/ports/repository/index.js +18 -0
  112. package/dist/src/domain/ports/repository/user.repository.d.ts +13 -0
  113. package/dist/src/domain/ports/repository/user.repository.js +2 -0
  114. package/dist/src/domain/ports/token/token-session.port.d.ts +7 -0
  115. package/dist/src/domain/ports/token/token-session.port.js +2 -0
  116. package/dist/src/domain/ports/token/token.service.port.d.ts +9 -0
  117. package/dist/src/domain/ports/token/token.service.port.js +2 -0
  118. package/dist/src/domain/props/create-payload-props.port.d.ts +0 -0
  119. package/dist/src/domain/props/create-payload-props.port.js +8 -0
  120. package/dist/src/domain/props/entities/credential.props.d.ts +8 -0
  121. package/dist/src/domain/props/entities/credential.props.js +2 -0
  122. package/dist/src/domain/props/entities/index.d.ts +2 -0
  123. package/dist/src/domain/props/entities/index.js +18 -0
  124. package/dist/src/domain/props/entities/user.props.d.ts +10 -0
  125. package/dist/src/domain/props/entities/user.props.js +2 -0
  126. package/dist/src/domain/props/index.d.ts +2 -0
  127. package/dist/src/domain/props/index.js +18 -0
  128. package/dist/src/domain/props/jwt/create-payload.props.d.ts +9 -0
  129. package/dist/src/domain/props/jwt/create-payload.props.js +2 -0
  130. package/dist/src/domain/props/jwt/generate-access-token.props.d.ts +8 -0
  131. package/dist/src/domain/props/jwt/generate-access-token.props.js +2 -0
  132. package/dist/src/domain/props/jwt/generate-refresh-token.props.d.ts +8 -0
  133. package/dist/src/domain/props/jwt/generate-refresh-token.props.js +2 -0
  134. package/dist/src/domain/props/jwt/generate-token.props.d.ts +10 -0
  135. package/dist/src/domain/props/jwt/generate-token.props.js +2 -0
  136. package/dist/src/domain/props/jwt/index.d.ts +5 -0
  137. package/dist/src/domain/props/jwt/index.js +21 -0
  138. package/dist/src/domain/props/jwt/jwt-subject.d.ts +7 -0
  139. package/dist/src/domain/props/jwt/jwt-subject.js +2 -0
  140. package/dist/src/domain/props/jwt/jwt-user.d.ts +7 -0
  141. package/dist/src/domain/props/jwt/jwt-user.js +2 -0
  142. package/dist/src/domain/props/services/generate-access-token.props.d.ts +8 -0
  143. package/dist/src/domain/props/services/generate-access-token.props.js +2 -0
  144. package/dist/src/domain/props/services/generate-refresh-token.props.d.ts +8 -0
  145. package/dist/src/domain/props/services/generate-refresh-token.props.js +2 -0
  146. package/dist/src/domain/props/services/index.d.ts +2 -0
  147. package/dist/src/domain/props/services/index.js +18 -0
  148. package/dist/src/domain/services/index.d.ts +1 -0
  149. package/dist/src/domain/services/index.js +17 -0
  150. package/dist/src/domain/services/password-policy.service.d.ts +8 -0
  151. package/dist/src/domain/services/password-policy.service.js +29 -0
  152. package/dist/src/domain/services/token.service.port.d.ts +9 -0
  153. package/dist/src/domain/services/token.service.port.js +2 -0
  154. package/dist/src/index.d.ts +78 -0
  155. package/dist/src/index.js +94 -0
  156. package/dist/src/infrastructure/index.d.ts +5 -0
  157. package/dist/src/infrastructure/index.js +21 -0
  158. package/dist/src/infrastructure/jwt/factory/index.d.ts +1 -0
  159. package/dist/src/infrastructure/jwt/factory/index.js +17 -0
  160. package/dist/src/infrastructure/jwt/factory/signature-strategy.factory.d.ts +21 -0
  161. package/dist/src/infrastructure/jwt/factory/signature-strategy.factory.js +61 -0
  162. package/dist/src/infrastructure/jwt/index.d.ts +3 -0
  163. package/dist/src/infrastructure/jwt/index.js +19 -0
  164. package/dist/src/infrastructure/jwt/signature-strategy.factory.d.ts +21 -0
  165. package/dist/src/infrastructure/jwt/signature-strategy.factory.js +61 -0
  166. package/dist/src/infrastructure/jwt/strategies/ecdsa-signature-strategy.d.ts +47 -0
  167. package/dist/src/infrastructure/jwt/strategies/ecdsa-signature-strategy.js +124 -0
  168. package/dist/src/infrastructure/jwt/strategies/ecdsa-signature.strategy.d.ts +47 -0
  169. package/dist/src/infrastructure/jwt/strategies/ecdsa-signature.strategy.js +124 -0
  170. package/dist/src/infrastructure/jwt/strategies/hmac-signature-strategy.d.ts +54 -0
  171. package/dist/src/infrastructure/jwt/strategies/hmac-signature-strategy.js +129 -0
  172. package/dist/src/infrastructure/jwt/strategies/hmac-signature.strategy.d.ts +54 -0
  173. package/dist/src/infrastructure/jwt/strategies/hmac-signature.strategy.js +129 -0
  174. package/dist/src/infrastructure/jwt/strategies/index.d.ts +3 -0
  175. package/dist/src/infrastructure/jwt/strategies/index.js +19 -0
  176. package/dist/src/infrastructure/jwt/strategies/rsa-signature-strategy.d.ts +47 -0
  177. package/dist/src/infrastructure/jwt/strategies/rsa-signature-strategy.js +124 -0
  178. package/dist/src/infrastructure/jwt/strategies/rsa-signature.strategy.d.ts +47 -0
  179. package/dist/src/infrastructure/jwt/strategies/rsa-signature.strategy.js +124 -0
  180. package/dist/src/infrastructure/jwt/token/actions/jwt-token-generator.d.ts +57 -0
  181. package/dist/src/infrastructure/jwt/token/actions/jwt-token-generator.js +123 -0
  182. package/dist/src/infrastructure/jwt/token/actions/jwt-token-verifier.d.ts +59 -0
  183. package/dist/src/infrastructure/jwt/token/actions/jwt-token-verifier.js +100 -0
  184. package/dist/src/infrastructure/jwt/token/index.d.ts +5 -0
  185. package/dist/src/infrastructure/jwt/token/index.js +21 -0
  186. package/dist/src/infrastructure/jwt/token/jwt-signer.d.ts +33 -0
  187. package/dist/src/infrastructure/jwt/token/jwt-signer.js +46 -0
  188. package/dist/src/infrastructure/jwt/token/jwt-token-parser.d.ts +29 -0
  189. package/dist/src/infrastructure/jwt/token/jwt-token-parser.js +57 -0
  190. package/dist/src/infrastructure/jwt/token/jwt-token-validator.d.ts +32 -0
  191. package/dist/src/infrastructure/jwt/token/jwt-token-validator.js +77 -0
  192. package/dist/src/infrastructure/jwt/token/tools/jwt-signer.d.ts +33 -0
  193. package/dist/src/infrastructure/jwt/token/tools/jwt-signer.js +46 -0
  194. package/dist/src/infrastructure/jwt/token/tools/jwt-token-parser.d.ts +30 -0
  195. package/dist/src/infrastructure/jwt/token/tools/jwt-token-parser.js +57 -0
  196. package/dist/src/infrastructure/jwt/token/tools/jwt-token-validator.d.ts +32 -0
  197. package/dist/src/infrastructure/jwt/token/tools/jwt-token-validator.js +77 -0
  198. package/dist/src/infrastructure/repositories/index.d.ts +1 -0
  199. package/dist/src/infrastructure/repositories/index.js +17 -0
  200. package/dist/src/infrastructure/repositories/test/in-memory-credential.repository.d.ts +12 -0
  201. package/dist/src/infrastructure/repositories/test/in-memory-credential.repository.js +68 -0
  202. package/dist/src/infrastructure/repositories/test/in-memory-token-session.repository.d.ts +67 -0
  203. package/dist/src/infrastructure/repositories/test/in-memory-token-session.repository.js +128 -0
  204. package/dist/src/infrastructure/repositories/test/in-memory-user.repository.d.ts +11 -0
  205. package/dist/src/infrastructure/repositories/test/in-memory-user.repository.js +49 -0
  206. package/dist/src/infrastructure/repositories/test/index.d.ts +2 -0
  207. package/dist/src/infrastructure/repositories/test/index.js +18 -0
  208. package/dist/src/infrastructure/security/bcrypt-password-hasher.d.ts +6 -0
  209. package/dist/src/infrastructure/security/bcrypt-password-hasher.js +19 -0
  210. package/dist/src/infrastructure/security/index.d.ts +1 -0
  211. package/dist/src/infrastructure/security/index.js +17 -0
  212. package/dist/src/infrastructure/services/default-token-session.service.d.ts +18 -0
  213. package/dist/src/infrastructure/services/default-token-session.service.js +88 -0
  214. package/dist/src/infrastructure/services/index.d.ts +2 -0
  215. package/dist/src/infrastructure/services/index.js +18 -0
  216. package/dist/src/infrastructure/services/jwt-token.service.d.ts +15 -0
  217. package/dist/src/infrastructure/services/jwt-token.service.js +44 -0
  218. package/dist/src/infrastructure/services/simple-jwt-token.service.d.ts +15 -0
  219. package/dist/src/infrastructure/services/simple-jwt-token.service.js +46 -0
  220. package/dist/src/infrastructure/services/token-session.service.d.ts +24 -0
  221. package/dist/src/infrastructure/services/token-session.service.js +131 -0
  222. package/dist/src/infrastructure/types/auth-service-container.d.ts +14 -0
  223. package/dist/src/infrastructure/types/auth-service-container.js +2 -0
  224. package/dist/src/infrastructure/types/index.d.ts +1 -0
  225. package/dist/src/infrastructure/types/index.js +17 -0
  226. package/dist/src/shared/constants/index.d.ts +1 -0
  227. package/dist/src/shared/constants/index.js +17 -0
  228. package/dist/src/shared/constants/jwt-algorithms.d.ts +17 -0
  229. package/dist/src/shared/constants/jwt-algorithms.js +23 -0
  230. package/dist/src/shared/encoders/base64-url-encoder.d.ts +29 -0
  231. package/dist/src/shared/encoders/base64-url-encoder.js +45 -0
  232. package/dist/src/shared/encoders/index.d.ts +1 -0
  233. package/dist/src/shared/encoders/index.js +17 -0
  234. package/dist/src/shared/index.d.ts +4 -0
  235. package/dist/src/shared/index.js +20 -0
  236. package/dist/src/shared/types/index.d.ts +1 -0
  237. package/dist/src/shared/types/index.js +17 -0
  238. package/dist/src/shared/types/jwt.d.ts +25 -0
  239. package/dist/src/shared/types/jwt.js +2 -0
  240. package/dist/src/shared/types/jwt.types.d.ts +39 -0
  241. package/dist/src/shared/types/jwt.types.js +2 -0
  242. package/dist/src/shared/utils/index.d.ts +1 -0
  243. package/dist/src/shared/utils/index.js +17 -0
  244. package/dist/src/shared/utils/time-parser.d.ts +28 -0
  245. package/dist/src/shared/utils/time-parser.js +76 -0
  246. package/dist/tests/application/factory/auth-service-factory.spec.d.ts +1 -0
  247. package/dist/tests/application/factory/auth-service-factory.spec.js +97 -0
  248. package/dist/tests/application/use-cases/login-with-password.integration.spec.d.ts +1 -0
  249. package/dist/tests/application/use-cases/login-with-password.integration.spec.js +140 -0
  250. package/dist/tests/application/use-cases/logout-use-case.spec.d.ts +1 -0
  251. package/dist/tests/application/use-cases/logout-use-case.spec.js +40 -0
  252. package/dist/tests/application/use-cases/refresh-token-use-case.spec.d.ts +1 -0
  253. package/dist/tests/application/use-cases/refresh-token-use-case.spec.js +116 -0
  254. package/dist/tests/application/use-cases/register-user.usecase.spec.d.ts +1 -0
  255. package/dist/tests/application/use-cases/register-user.usecase.spec.js +151 -0
  256. package/dist/tests/domain/entities/credential.spec.d.ts +1 -0
  257. package/dist/tests/domain/entities/credential.spec.js +93 -0
  258. package/dist/tests/domain/entities/user.spec.d.ts +1 -0
  259. package/dist/tests/domain/entities/user.spec.js +93 -0
  260. package/dist/tests/domain/object-values/email.spec.d.ts +1 -0
  261. package/dist/tests/domain/object-values/email.spec.js +77 -0
  262. package/dist/tests/domain/object-values/hashed-password.spec.d.ts +1 -0
  263. package/dist/tests/domain/object-values/hashed-password.spec.js +54 -0
  264. package/dist/tests/domain/object-values/id.spec.d.ts +1 -0
  265. package/dist/tests/domain/object-values/id.spec.js +48 -0
  266. package/dist/tests/domain/object-values/permission.spec.d.ts +1 -0
  267. package/dist/tests/domain/object-values/permission.spec.js +75 -0
  268. package/dist/tests/domain/object-values/role.spec.d.ts +1 -0
  269. package/dist/tests/domain/object-values/role.spec.js +139 -0
  270. package/dist/tests/domain/services/default-password-policy.spec.d.ts +1 -0
  271. package/dist/tests/domain/services/default-password-policy.spec.js +69 -0
  272. package/dist/tests/doman/entities/credential.spec.d.ts +1 -0
  273. package/dist/tests/doman/entities/credential.spec.js +93 -0
  274. package/dist/tests/doman/entities/user.spec.d.ts +1 -0
  275. package/dist/tests/doman/entities/user.spec.js +93 -0
  276. package/dist/tests/doman/object-values/email.spec.d.ts +1 -0
  277. package/dist/tests/doman/object-values/email.spec.js +77 -0
  278. package/dist/tests/doman/object-values/hashed-password.spec.d.ts +1 -0
  279. package/dist/tests/doman/object-values/hashed-password.spec.js +54 -0
  280. package/dist/tests/doman/object-values/id.spec.d.ts +1 -0
  281. package/dist/tests/doman/object-values/id.spec.js +48 -0
  282. package/dist/tests/doman/object-values/permission.spec.d.ts +1 -0
  283. package/dist/tests/doman/object-values/permission.spec.js +75 -0
  284. package/dist/tests/doman/object-values/role.spec.d.ts +1 -0
  285. package/dist/tests/doman/object-values/role.spec.js +139 -0
  286. package/dist/tests/helpers/make-jwt-subject.d.ts +7 -0
  287. package/dist/tests/helpers/make-jwt-subject.js +16 -0
  288. package/dist/tests/helpers/make-jwt-user.d.ts +7 -0
  289. package/dist/tests/helpers/make-jwt-user.js +16 -0
  290. package/dist/tests/helpers/make-user.d.ts +2 -0
  291. package/dist/tests/helpers/make-user.js +15 -0
  292. package/dist/tests/infrastructure/jwt/signature-strategy-factory.spec.d.ts +1 -0
  293. package/dist/tests/infrastructure/jwt/signature-strategy-factory.spec.js +127 -0
  294. package/dist/tests/infrastructure/jwt/strategies/ecdsa-signature-strategy.spec.d.ts +1 -0
  295. package/dist/tests/infrastructure/jwt/strategies/ecdsa-signature-strategy.spec.js +157 -0
  296. package/dist/tests/infrastructure/jwt/strategies/hmac-signature-strategy.spec.d.ts +1 -0
  297. package/dist/tests/infrastructure/jwt/strategies/hmac-signature-strategy.spec.js +150 -0
  298. package/dist/tests/infrastructure/jwt/strategies/rsa-signature-strategy..spec.d.ts +1 -0
  299. package/dist/tests/infrastructure/jwt/strategies/rsa-signature-strategy..spec.js +156 -0
  300. package/dist/tests/infrastructure/jwt/token/actions/jwt-token-generator.spec.d.ts +1 -0
  301. package/dist/tests/infrastructure/jwt/token/actions/jwt-token-generator.spec.js +179 -0
  302. package/dist/tests/infrastructure/jwt/token/actions/jwt-token-verifier.spec.d.ts +1 -0
  303. package/dist/tests/infrastructure/jwt/token/actions/jwt-token-verifier.spec.js +142 -0
  304. package/dist/tests/infrastructure/jwt/token/jwt-signer.spec.d.ts +1 -0
  305. package/dist/tests/infrastructure/jwt/token/jwt-signer.spec.js +125 -0
  306. package/dist/tests/infrastructure/jwt/token/jwt-token-parser.spec.d.ts +1 -0
  307. package/dist/tests/infrastructure/jwt/token/jwt-token-parser.spec.js +116 -0
  308. package/dist/tests/infrastructure/jwt/token/jwt-token-validator.spec.d.ts +1 -0
  309. package/dist/tests/infrastructure/jwt/token/jwt-token-validator.spec.js +88 -0
  310. package/dist/tests/infrastructure/jwt/token/tools/jwt-signer.spec.d.ts +1 -0
  311. package/dist/tests/infrastructure/jwt/token/tools/jwt-signer.spec.js +126 -0
  312. package/dist/tests/infrastructure/jwt/token/tools/jwt-token-parser.spec.d.ts +1 -0
  313. package/dist/tests/infrastructure/jwt/token/tools/jwt-token-parser.spec.js +116 -0
  314. package/dist/tests/infrastructure/jwt/token/tools/jwt-token-validator.spec.d.ts +1 -0
  315. package/dist/tests/infrastructure/jwt/token/tools/jwt-token-validator.spec.js +88 -0
  316. package/dist/tests/infrastructure/security/security/bcrypt-password-hasher.spec.d.ts +1 -0
  317. package/dist/tests/infrastructure/security/security/bcrypt-password-hasher.spec.js +37 -0
  318. package/dist/tests/infrastructure/services/jwt-token-service.spec.d.ts +1 -0
  319. package/dist/tests/infrastructure/services/jwt-token-service.spec.js +145 -0
  320. package/dist/tests/infrastructure/services/token-session.service.spec.d.ts +1 -0
  321. package/dist/tests/infrastructure/services/token-session.service.spec.js +269 -0
  322. package/dist/tests/shared/constants/jwt-algorithms.spec.d.ts +1 -0
  323. package/dist/tests/shared/constants/jwt-algorithms.spec.js +27 -0
  324. package/dist/tests/shared/encoders/base64-url-encoder.spec.d.ts +1 -0
  325. package/dist/tests/shared/encoders/base64-url-encoder.spec.js +70 -0
  326. package/dist/tests/shared/utils/time-parser.spec.d.ts +1 -0
  327. package/dist/tests/shared/utils/time-parser.spec.js +80 -0
  328. package/dist/utils/index.d.ts +1 -0
  329. package/dist/utils/index.js +17 -0
  330. package/dist/utils/time-parser.d.ts +28 -0
  331. package/dist/utils/time-parser.js +76 -0
  332. package/package.json +48 -0
@@ -0,0 +1,156 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const crypto = __importStar(require("crypto"));
37
+ const infrastructure_1 = require("src/infrastructure");
38
+ const shared_1 = require("src/shared");
39
+ describe("RcaSignatureStrategy", () => {
40
+ // 🔑 Función auxiliar para generar un par de claves RSA
41
+ const makeKeys = (modulusLength = 2048) => crypto.generateKeyPairSync("rsa", {
42
+ modulusLength, // Tamaño de la clave (bits)
43
+ publicKeyEncoding: { type: "spki", format: "pem" },
44
+ privateKeyEncoding: { type: "pkcs8", format: "pem" },
45
+ });
46
+ // Datos base para firmar
47
+ const baseData = "header.payload";
48
+ // Vectores de prueba para cada algoritmo HMAC
49
+ const vectors = [
50
+ { alg: shared_1.algorithms.rsa.RS256, hash: "sha256" },
51
+ { alg: shared_1.algorithms.rsa.RS384, hash: "sha384" },
52
+ { alg: shared_1.algorithms.rsa.RS512, hash: "sha512" },
53
+ ];
54
+ // Casos positivos
55
+ it.each(vectors)("sign/verify OK para %s", ({ alg }) => {
56
+ // Genera par de claves
57
+ const { publicKey, privateKey } = makeKeys(2048);
58
+ // Crea la estrategia
59
+ const encoder = new shared_1.Base64UrlEncoder();
60
+ // Crea la estrategia
61
+ const strat = new infrastructure_1.RsaSignatureStrategy(alg, encoder);
62
+ // Firma
63
+ const sig = strat.sign(baseData, privateKey);
64
+ // Debe ser Base64URL (sin +, /, =)
65
+ expect(sig).toMatch(/^[A-Za-z0-9\-_]+$/);
66
+ // verify OK con los mismos datos/clave
67
+ expect(strat.verify(baseData, sig, publicKey)).toBe(true);
68
+ });
69
+ // Casos negativos
70
+ it.each(vectors)("verify=false si los datos se alteran (%s)", ({ alg }) => {
71
+ // Genera par de claves
72
+ const { publicKey, privateKey } = makeKeys();
73
+ // Crea la estrategia
74
+ const encoder = new shared_1.Base64UrlEncoder();
75
+ // Crea la estrategia
76
+ const strat = new infrastructure_1.RsaSignatureStrategy(alg, encoder);
77
+ // Firma
78
+ const sig = strat.sign(baseData, privateKey);
79
+ // verify debe fallar si se alteran los datos
80
+ expect(strat.verify(baseData + ".tampered", sig, publicKey)).toBe(false);
81
+ });
82
+ // Casos negativos - firma alterada
83
+ it.each(vectors)("verify=false si la firma se altera (%s)", ({ alg }) => {
84
+ // Genera par de claves
85
+ const { publicKey, privateKey } = makeKeys();
86
+ // Crea la estrategia
87
+ const encoder = new shared_1.Base64UrlEncoder();
88
+ // Crea la estrategia
89
+ const strat = new infrastructure_1.RsaSignatureStrategy(alg, encoder);
90
+ // Firma
91
+ const sig = strat.sign(baseData, privateKey);
92
+ // Decodificamos a base64 estándar y luego a bytes
93
+ const stdB64 = encoder.decode(sig);
94
+ const buf = Buffer.from(stdB64, "base64");
95
+ // Flip de un byte en el medio (afecta r/s con alta probabilidad)
96
+ const i = Math.floor(buf.length / 2);
97
+ buf[i] ^= 0x01;
98
+ // Re-encode a base64url para pasar por la API pública de la estrategia
99
+ const tampered = encoder.encode(Buffer.from(buf).toString("base64"));
100
+ expect(strat.verify(baseData, tampered, publicKey)).toBe(false);
101
+ });
102
+ // Pruebas adicionales
103
+ it("getSupportedAlgorithm() devuelve el algoritmo configurado", () => {
104
+ // Crea la estrategia
105
+ const encoder = new shared_1.Base64UrlEncoder();
106
+ // Crea la estrategia
107
+ const strat = new infrastructure_1.RsaSignatureStrategy(shared_1.algorithms.rsa.RS256, encoder);
108
+ // Debe devolver el algoritmo configurado
109
+ expect(strat.getSupportedAlgorithm()).toBe("RS256");
110
+ });
111
+ // Casos de error - algoritmo no soportado
112
+ it("sign lanza y verify devuelve false para algoritmo no soportado", () => {
113
+ // Crea la estrategia con un algoritmo inválido
114
+ const badAlg = "RS999";
115
+ // Crea la estrategia
116
+ const encoder = new shared_1.Base64UrlEncoder();
117
+ // Crea la estrategia
118
+ const strat = new infrastructure_1.RsaSignatureStrategy(badAlg, encoder);
119
+ // Genera par de claves válidas
120
+ const { publicKey, privateKey } = makeKeys(2048);
121
+ // sign debe lanzar error
122
+ expect(() => strat.sign(baseData, privateKey)).toThrow(/Unsupported RSA algorithm/i);
123
+ // verify debe devolver false
124
+ expect(strat.verify(baseData, "abc", publicKey)).toBe(false);
125
+ });
126
+ // Prueba que se usa el encoder correctamente
127
+ it("usa el encoder para encode (sign) y decode (verify)", () => {
128
+ // Mocks del encoder
129
+ const encoder = {
130
+ encode: jest.fn((b64) => b64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "")),
131
+ decode: jest.fn((b64url) => {
132
+ const pad = b64url.length % 4;
133
+ let std = b64url.replace(/-/g, "+").replace(/_/g, "/");
134
+ if (pad)
135
+ std += "=".repeat(4 - pad);
136
+ return std;
137
+ }),
138
+ };
139
+ // Genera par de claves válidas
140
+ const { publicKey, privateKey } = makeKeys(2048);
141
+ // Crea la estrategia
142
+ const strat = new infrastructure_1.RsaSignatureStrategy(shared_1.algorithms.rsa.RS256, encoder);
143
+ // Firma
144
+ const sig = strat.sign(baseData, privateKey);
145
+ // Verifica que se llamó al encoder
146
+ expect(encoder.encode).toHaveBeenCalledTimes(1);
147
+ // El resultado debe ser string
148
+ expect(typeof sig).toBe("string");
149
+ // Verifica
150
+ const ok = strat.verify(baseData, sig, publicKey);
151
+ // Verifica que se llamó al decoder
152
+ expect(encoder.decode).toHaveBeenCalledTimes(1);
153
+ // El resultado debe ser true
154
+ expect(ok).toBe(true);
155
+ });
156
+ });
@@ -0,0 +1,179 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ // Mocks
4
+ jest.mock("src/shared", () => {
5
+ // Mantiene el resto del módulo original
6
+ const actual = jest.requireActual("src/shared");
7
+ return {
8
+ // Mantiene todo lo anterior
9
+ ...actual,
10
+ // Mockeamos solo TimeParser
11
+ TimeParser: {
12
+ parseToMilliseconds: jest.fn(),
13
+ },
14
+ };
15
+ });
16
+ const infrastructure_1 = require("src/infrastructure");
17
+ const shared_1 = require("src/shared");
18
+ const make_jwt_user_1 = require("../../../../helpers/make-jwt-user");
19
+ // Types: Simplificados para test no necesitamos toda la implementación solo la firma del método sign()
20
+ // y el encoder Base64UrlEncoder
21
+ // type JwtSigner = { sign: (input: string, secret: string) => string };
22
+ // type Base64UrlEncoder = { encode: (input: string) => string };
23
+ // Config type para los tests
24
+ // type JwtTokenServiceConfig = {
25
+ // accessTokenSecret: string;
26
+ // refreshTokenSecret: string;
27
+ // accessTokenExpirationMs: number;
28
+ // refreshTokenExpirationMs: number;
29
+ // issuer: string;
30
+ // audience: string;
31
+ // algorithm?: string;
32
+ // };
33
+ const FIXED_NOW_MS = Date.UTC(2025, 0, 1, 0, 0, 0, 0);
34
+ const FIXED_NOW_SECONDS = Math.floor(FIXED_NOW_MS / 1000);
35
+ // encoder como jest.fn para poder leer mock.calls
36
+ const encoderMock = {
37
+ encode: jest.fn((input) => {
38
+ if (input.includes('"typ":"JWT"'))
39
+ return "encodedHeader";
40
+ return "encodedPayload";
41
+ }),
42
+ decode: function (str) {
43
+ throw new Error("Function not implemented.");
44
+ },
45
+ };
46
+ // signer como jest.fn para poder leer mock.calls
47
+ const signerMock = {
48
+ sign: jest.fn().mockImplementation((data, key, algorithm) => {
49
+ return `signed(${data})`;
50
+ }),
51
+ verifySignature: jest.fn().mockImplementation((data, signature, key) => {
52
+ return signature === `signed(${data})`;
53
+ }),
54
+ };
55
+ // Config base para los tests
56
+ const baseConfig = {
57
+ accessTokenSecret: "ACCESS_SECRET_ABC",
58
+ refreshTokenSecret: "REFRESH_SECRET_DEF",
59
+ accessTokenExpirationMs: 60 * 60 * 1000, // 1h
60
+ refreshTokenExpirationMs: 7 * 24 * 60 * 60 * 1000, // 7d
61
+ issuer: "my-issuer",
62
+ audience: "my-audience",
63
+ algorithm: "HS256",
64
+ };
65
+ // Util: normaliza roles a string[]
66
+ function normalizeRole(r) {
67
+ if (typeof r === "string")
68
+ return r;
69
+ if (r && typeof r === "object") {
70
+ const o = r;
71
+ return String(o.role ?? o.name ?? o.value);
72
+ }
73
+ return String(r);
74
+ }
75
+ // Regex simple para UUID v4 (aceptable para test)
76
+ const UUID_V4 = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
77
+ describe("JwtTokenGenerator", () => {
78
+ // la instancia a testear
79
+ let generator;
80
+ // fija la fecha actual para tests consistentes
81
+ beforeAll(() => {
82
+ jest.useFakeTimers().setSystemTime(FIXED_NOW_MS);
83
+ });
84
+ // resetea mocks y crea nueva instancia antes de cada test
85
+ beforeEach(() => {
86
+ jest.clearAllMocks();
87
+ generator = new infrastructure_1.JwtTokenGenerator(encoderMock, signerMock);
88
+ });
89
+ // restaura timers reales
90
+ afterAll(() => {
91
+ jest.useRealTimers();
92
+ });
93
+ // Testea generación de Access Token
94
+ test("generateAccessToken: usa accessTokenSecret y expiración por defecto del config cuando no hay expiresIn", () => {
95
+ // crea un user de prueba
96
+ const user = (0, make_jwt_user_1.makeJwtSubject)();
97
+ // genera el token
98
+ const token = generator.generateAccessToken({
99
+ user: user,
100
+ config: { ...baseConfig, algorithm: "HS256" },
101
+ });
102
+ expect(signerMock.sign).toHaveBeenCalledWith("encodedHeader.encodedPayload", baseConfig.accessTokenSecret, baseConfig.algorithm);
103
+ expect(token).toBe("encodedHeader.encodedPayload.signed(encodedHeader.encodedPayload)");
104
+ const encodeCalls = encoderMock.encode.mock.calls;
105
+ const payloadJson = encodeCalls[1][0];
106
+ const payload = JSON.parse(payloadJson);
107
+ // jti no debe ser fijo: validamos que sea string y UUID-ish
108
+ expect(typeof payload.jti).toBe("string");
109
+ // Si tu runtime no garantiza v4, cambia a expect.any(String)
110
+ expect(payload.jti).toMatch(UUID_V4);
111
+ // normalizamos roles y comparamos
112
+ const roleNames = payload.roles.map(normalizeRole);
113
+ expect(roleNames).toEqual(["ADMIN", "USER"]);
114
+ expect(payload).toMatchObject({
115
+ sub: "user-123",
116
+ customClaims: {},
117
+ iat: FIXED_NOW_SECONDS,
118
+ exp: FIXED_NOW_SECONDS + 60 * 60,
119
+ iss: "my-issuer",
120
+ aud: "my-audience",
121
+ });
122
+ const headerJson = encodeCalls[0][0];
123
+ const header = JSON.parse(headerJson);
124
+ expect(header).toEqual({ alg: "HS256", typ: "JWT" });
125
+ });
126
+ test("generateAccessToken: respeta expiresIn string (usa TimeParser.parseToMilliseconds)", () => {
127
+ const user = (0, make_jwt_user_1.makeJwtSubject)();
128
+ shared_1.TimeParser.parseToMilliseconds.mockReturnValueOnce(15 * 60 * 1000); // 15m
129
+ const token = generator.generateAccessToken({
130
+ user: user,
131
+ config: baseConfig,
132
+ expiresIn: "15m",
133
+ customClaims: { plan: "pro" },
134
+ });
135
+ expect(token).toBe("encodedHeader.encodedPayload.signed(encodedHeader.encodedPayload)");
136
+ expect(shared_1.TimeParser.parseToMilliseconds).toHaveBeenCalledWith("15m");
137
+ const payloadJson = encoderMock.encode.mock.calls[1][0];
138
+ const payload = JSON.parse(payloadJson);
139
+ const roleNames = payload.roles.map(normalizeRole);
140
+ expect(roleNames).toEqual(["ADMIN", "USER"]);
141
+ expect(payload.exp).toBe(FIXED_NOW_SECONDS + 15 * 60);
142
+ expect(payload.customClaims).toEqual({ plan: "pro" });
143
+ });
144
+ test("generateRefreshToken: usa refreshTokenSecret y expiración por defecto de refresh", () => {
145
+ const user = (0, make_jwt_user_1.makeJwtSubject)();
146
+ const token = generator.generateRefreshToken({
147
+ user: user,
148
+ config: { ...baseConfig, algorithm: "ES256" },
149
+ });
150
+ expect(signerMock.sign).toHaveBeenCalledWith("encodedHeader.encodedPayload", baseConfig.refreshTokenSecret, "ES256");
151
+ expect(token).toBe("encodedHeader.encodedPayload.signed(encodedHeader.encodedPayload)");
152
+ const headerJson = encoderMock.encode.mock.calls[0][0];
153
+ const header = JSON.parse(headerJson);
154
+ expect(header).toEqual({ alg: "ES256", typ: "JWT" });
155
+ const payloadJson = encoderMock.encode.mock.calls[1][0];
156
+ const payload = JSON.parse(payloadJson);
157
+ expect(payload.exp).toBe(FIXED_NOW_SECONDS + 7 * 24 * 60 * 60);
158
+ });
159
+ test("cuando no hay customClaims en props, se usa {}", () => {
160
+ const user = (0, make_jwt_user_1.makeJwtSubject)();
161
+ generator.generateAccessToken({
162
+ user: user,
163
+ config: baseConfig,
164
+ });
165
+ const payloadJson = encoderMock.encode.mock.calls[1][0];
166
+ const payload = JSON.parse(payloadJson);
167
+ expect(payload.customClaims).toEqual({});
168
+ });
169
+ test("firma exactamente 'header.payload' y concatena '.signature'", () => {
170
+ const user = (0, make_jwt_user_1.makeJwtSubject)();
171
+ const token = generator.generateAccessToken({
172
+ user: user,
173
+ config: baseConfig,
174
+ });
175
+ expect(signerMock.sign).toHaveBeenCalledTimes(1);
176
+ expect(signerMock.sign).toHaveBeenCalledWith("encodedHeader.encodedPayload", baseConfig.accessTokenSecret, baseConfig.algorithm);
177
+ expect(token).toBe("encodedHeader.encodedPayload.signed(encodedHeader.encodedPayload)");
178
+ });
179
+ });
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const errors_1 = require("src/domain/errors");
4
+ const infrastructure_1 = require("src/infrastructure");
5
+ describe("JwtTokenVerifier", () => {
6
+ let signer;
7
+ let parser;
8
+ let verifier;
9
+ let config;
10
+ const algorithm = "HS256";
11
+ const NOW_MS = Date.UTC(2025, 0, 1, 0, 0, 0); // 2025-01-01T00:00:00Z
12
+ const NOW_SECONDS = Math.floor(NOW_MS / 1000);
13
+ beforeAll(() => {
14
+ jest.useFakeTimers().setSystemTime(NOW_MS);
15
+ });
16
+ beforeEach(() => {
17
+ signer = {
18
+ verifySignature: jest.fn(),
19
+ };
20
+ parser = {
21
+ extractParts: jest.fn(),
22
+ parseAndValidatePayload: jest.fn(),
23
+ parsePayload: jest.fn(),
24
+ };
25
+ verifier = new infrastructure_1.JwtTokenVerifier(signer, // no nos importa la implementación real aquí
26
+ parser, algorithm);
27
+ config = {
28
+ accessTokenSecret: "ACCESS_SECRET",
29
+ refreshTokenSecret: "REFRESH_SECRET",
30
+ accessTokenExpirationMs: 15 * 60 * 1000,
31
+ refreshTokenExpirationMs: 7 * 24 * 60 * 60 * 1000,
32
+ issuer: "test-issuer",
33
+ audience: "test-audience",
34
+ algorithm: "HS256",
35
+ };
36
+ });
37
+ afterAll(() => {
38
+ jest.useRealTimers();
39
+ });
40
+ test("verifyAccessToken: firma válida y token no expirado devuelve payload normalizado", () => {
41
+ const token = "headerPart.payloadPart.signaturePart";
42
+ parser.extractParts.mockReturnValue([
43
+ "headerPart",
44
+ "payloadPart",
45
+ "signaturePart",
46
+ ]);
47
+ const rawPayload = {
48
+ sub: "user-123",
49
+ roles: [{ role: "ADMIN" }, { role: "USER" }],
50
+ customClaims: { foo: "bar" },
51
+ iat: NOW_SECONDS,
52
+ exp: NOW_SECONDS + 60 * 60, // +1h
53
+ jti: "jti-123",
54
+ iss: "test-issuer",
55
+ aud: "test-audience",
56
+ };
57
+ signer.verifySignature.mockReturnValue(true);
58
+ parser.parseAndValidatePayload.mockReturnValue(rawPayload);
59
+ const result = verifier.verifyAccessToken(token, config);
60
+ // Verifica que use el accessTokenSecret
61
+ expect(signer.verifySignature).toHaveBeenCalledWith("headerPart.payloadPart", "signaturePart", "ACCESS_SECRET", "HS256");
62
+ expect(parser.extractParts).toHaveBeenCalledWith(token);
63
+ expect(parser.parseAndValidatePayload).toHaveBeenCalledWith("payloadPart");
64
+ // Verifica el payload normalizado
65
+ expect(result).toEqual({
66
+ sub: "user-123",
67
+ roles: [
68
+ {
69
+ role: "ADMIN",
70
+ },
71
+ {
72
+ role: "USER",
73
+ },
74
+ ],
75
+ customClaims: { foo: "bar" },
76
+ iat: rawPayload.iat,
77
+ exp: rawPayload.exp,
78
+ jti: rawPayload.jti,
79
+ iss: rawPayload.iss,
80
+ aud: rawPayload.aud,
81
+ });
82
+ });
83
+ test("verifyRefreshToken: usa refreshTokenSecret para verificar la firma", () => {
84
+ const token = "h.p.s";
85
+ parser.extractParts.mockReturnValue(["h64", "p64", "s64"]);
86
+ signer.verifySignature.mockReturnValue(true);
87
+ parser.parseAndValidatePayload.mockReturnValue({
88
+ userId: "user-123",
89
+ role: [],
90
+ customClaims: {},
91
+ iat: NOW_SECONDS,
92
+ exp: NOW_SECONDS + 10,
93
+ jti: "jti",
94
+ iss: "test-issuer",
95
+ aud: "test-audience",
96
+ });
97
+ verifier.verifyRefreshToken(token, config);
98
+ expect(signer.verifySignature).toHaveBeenCalledWith("h64.p64", "s64", "REFRESH_SECRET", "HS256");
99
+ });
100
+ test("verifyAccessToken: firma inválida lanza InvalidSignatureError", () => {
101
+ const token = "h.p.s";
102
+ parser.extractParts.mockReturnValue(["h64", "p64", "s64"]);
103
+ signer.verifySignature.mockReturnValue(false);
104
+ expect(() => verifier.verifyAccessToken(token, config)).toThrow(errors_1.InvalidSignatureError);
105
+ // No debería intentar parsear el payload si la firma es inválida
106
+ expect(parser.parseAndValidatePayload).not.toHaveBeenCalled();
107
+ });
108
+ test("verifyAccessToken: token expirado lanza TokenExpiredError", () => {
109
+ const token = "h.p.s";
110
+ parser.extractParts.mockReturnValue(["h64", "p64", "s64"]);
111
+ signer.verifySignature.mockReturnValue(true);
112
+ const expiredPayload = {
113
+ userId: "user-123",
114
+ role: ["USER"],
115
+ customClaims: {},
116
+ iat: NOW_SECONDS - 10,
117
+ exp: NOW_SECONDS - 1, // ya expirado
118
+ jti: "jti-expired",
119
+ iss: "test-issuer",
120
+ aud: "test-audience",
121
+ };
122
+ parser.parseAndValidatePayload.mockReturnValue(expiredPayload);
123
+ expect(() => verifier.verifyAccessToken(token, config)).toThrow(errors_1.TokenExpiredError);
124
+ });
125
+ test("getTokenExpiration: devuelve la fecha basada en el exp del payload", () => {
126
+ const token = "header.payload.signature";
127
+ parser.parsePayload.mockReturnValue({
128
+ // Solo necesitamos exp aquí
129
+ exp: NOW_SECONDS + 3600,
130
+ iat: NOW_SECONDS,
131
+ jti: "jti",
132
+ iss: "iss",
133
+ aud: "aud",
134
+ sub: "user-123",
135
+ roles: [],
136
+ customClaims: {},
137
+ });
138
+ const expiresAt = verifier.getTokenExpiration(token);
139
+ expect(parser.parsePayload).toHaveBeenCalledWith(token);
140
+ expect(expiresAt.getTime()).toBe((NOW_SECONDS + 3600) * 1000);
141
+ });
142
+ });
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const jwt_1 = require("src/infrastructure/jwt");
4
+ const token_1 = require("src/infrastructure/jwt/token");
5
+ const shared_1 = require("src/shared");
6
+ // ────────────────────────────────────────────────────────────────
7
+ // Mock de SignatureStrategyFactory y su comportamiento
8
+ // ────────────────────────────────────────────────────────────────
9
+ jest.mock("src/infrastructure/jwt/signature-strategy.factory");
10
+ describe("JwtSigner", () => {
11
+ // Variables comunes para las pruebas
12
+ let signer;
13
+ let factoryMock;
14
+ let encoder;
15
+ // ────────────────────────────────────────────────────────────────
16
+ // Configuración antes de cada prueba
17
+ // ────────────────────────────────────────────────────────────────
18
+ beforeEach(() => {
19
+ // Instancia real del codificador
20
+ encoder = new shared_1.Base64UrlEncoder();
21
+ // Mock de factory.create() → devuelve una estrategia con sign/verify falsos
22
+ factoryMock = {
23
+ create: jest.fn(),
24
+ };
25
+ // Forzar el constructor de SignatureStrategyFactory para devolver nuestro mock
26
+ jwt_1.SignatureStrategyFactory.mockImplementation(() => factoryMock);
27
+ // Crea la instancia de JwtSigner que vamos a probar
28
+ signer = new token_1.JwtSigner(encoder);
29
+ });
30
+ // Limpia los mocks después de cada prueba
31
+ afterEach(() => {
32
+ jest.clearAllMocks();
33
+ });
34
+ // ────────────────────────────────────────────────────────────────
35
+ // sign()
36
+ // ────────────────────────────────────────────────────────────────
37
+ describe("sign", () => {
38
+ // Prueba básica de firma
39
+ test("firma datos usando la estrategia devuelta por la fábrica", () => {
40
+ // Prepara la estrategia mock
41
+ const fakeSignature = "signed-data";
42
+ const mockStrategy = { sign: jest.fn().mockReturnValue(fakeSignature) };
43
+ factoryMock.create.mockReturnValue(mockStrategy);
44
+ // Llama al método a probar
45
+ const result = signer.sign("header.payload", "secret-key", "HS256");
46
+ // Verificaciones
47
+ // Asegura que la fábrica fue llamada con el algoritmo correcto
48
+ expect(factoryMock.create).toHaveBeenCalledWith("HS256");
49
+ // Asegura que la estrategia firmó los datos correctamente
50
+ expect(mockStrategy.sign).toHaveBeenCalledWith("header.payload", "secret-key");
51
+ // Asegura que el resultado es el esperado
52
+ expect(result).toBe(fakeSignature);
53
+ });
54
+ // Prueba el valor por defecto del algoritmo
55
+ test("usa 'HS256' como algoritmo por defecto si no se especifica", () => {
56
+ // Prepara la estrategia mock
57
+ const mockStrategy = { sign: jest.fn().mockReturnValue("sig") };
58
+ factoryMock.create.mockReturnValue(mockStrategy);
59
+ // Llama al método sin especificar algoritmo
60
+ signer.sign("abc.def", "key");
61
+ // Verifica que se usó el algoritmo por defecto
62
+ expect(factoryMock.create).toHaveBeenCalledWith("HS256");
63
+ // Asegura que la estrategia fue llamada una vez
64
+ expect(mockStrategy.sign).toHaveBeenCalledTimes(1);
65
+ });
66
+ });
67
+ // ────────────────────────────────────────────────────────────────
68
+ // verifySignature()
69
+ // ────────────────────────────────────────────────────────────────
70
+ describe("verifySignature", () => {
71
+ // Prueba básica de verificación
72
+ test("verifica correctamente usando la estrategia devuelta por la fábrica", () => {
73
+ // Prepara la estrategia mock
74
+ const mockStrategy = { verify: jest.fn().mockReturnValue(true) };
75
+ factoryMock.create.mockReturnValue(mockStrategy);
76
+ // Llama al método a probar
77
+ const result = signer.verifySignature("header.payload", "signature", "secret", "HS512");
78
+ // Verificaciones
79
+ // Asegura que la fábrica fue llamada con el algoritmo correcto
80
+ expect(factoryMock.create).toHaveBeenCalledWith("HS512");
81
+ // Asegura que la estrategia verificó los datos correctamente
82
+ expect(mockStrategy.verify).toHaveBeenCalledWith("header.payload", "signature", "secret");
83
+ // Asegura que el resultado es el esperado
84
+ expect(result).toBe(true);
85
+ });
86
+ // Prueba cuando la verificación falla
87
+ test("retorna false si verify devuelve false", () => {
88
+ // Prepara la estrategia mock
89
+ const mockStrategy = { verify: jest.fn().mockReturnValue(false) };
90
+ factoryMock.create.mockReturnValue(mockStrategy);
91
+ // Llama al método a probar
92
+ const result = signer.verifySignature("data", "sig", "key");
93
+ // Verifica que el resultado sea false
94
+ expect(result).toBe(false);
95
+ });
96
+ // Prueba el valor por defecto del algoritmo
97
+ test("usa 'HS256' como algoritmo por defecto si no se pasa parámetro", () => {
98
+ // Prepara la estrategia mock
99
+ const mockStrategy = { verify: jest.fn().mockReturnValue(true) };
100
+ factoryMock.create.mockReturnValue(mockStrategy);
101
+ // Llama al método sin especificar algoritmo
102
+ signer.verifySignature("abc.def", "sig", "key");
103
+ // Verifica que se usó el algoritmo por defecto
104
+ expect(factoryMock.create).toHaveBeenCalledWith("HS256");
105
+ // Asegura que la estrategia fue llamada una vez
106
+ expect(mockStrategy.verify).toHaveBeenCalledTimes(1);
107
+ });
108
+ });
109
+ // ────────────────────────────────────────────────────────────────
110
+ // integración mínima (sin mock) - opcional
111
+ // ────────────────────────────────────────────────────────────────
112
+ describe("integración mínima", () => {
113
+ // Prueba que JwtSigner crea una instancia real de SignatureStrategyFactory
114
+ test("crea internamente una instancia real de SignatureStrategyFactory", () => {
115
+ // Borra el historial de llamadas acumulado por el beforeEach del describe padre
116
+ jwt_1.SignatureStrategyFactory.mockClear();
117
+ // Crea una nueva instancia de JwtSigner
118
+ const localSigner = new token_1.JwtSigner(encoder);
119
+ // Verifica que se creó una instancia de JwtSigner y que la fábrica fue instanciada
120
+ expect(localSigner).toBeInstanceOf(token_1.JwtSigner);
121
+ // Asegura que el constructor de SignatureStrategyFactory fue llamado una vez
122
+ expect(jwt_1.SignatureStrategyFactory).toHaveBeenCalledTimes(1);
123
+ });
124
+ });
125
+ });