@ibgib/node-gib 0.0.9 → 0.0.13

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 (329) hide show
  1. package/dist/assumptions.respec.mjs.map +1 -1
  2. package/dist/email/aws/aws-sigv4-helper.d.mts +26 -0
  3. package/dist/email/aws/aws-sigv4-helper.d.mts.map +1 -0
  4. package/dist/email/aws/aws-sigv4-helper.mjs +94 -0
  5. package/dist/email/aws/aws-sigv4-helper.mjs.map +1 -0
  6. package/dist/email/aws/email-receiver-aws.d.mts +13 -0
  7. package/dist/email/aws/email-receiver-aws.d.mts.map +1 -0
  8. package/dist/email/aws/email-receiver-aws.mjs +97 -0
  9. package/dist/email/aws/email-receiver-aws.mjs.map +1 -0
  10. package/dist/email/aws/email-sender-aws.d.mts +23 -0
  11. package/dist/email/aws/email-sender-aws.d.mts.map +1 -0
  12. package/dist/email/aws/email-sender-aws.mjs +106 -0
  13. package/dist/email/aws/email-sender-aws.mjs.map +1 -0
  14. package/dist/email/aws/index.d.mts +7 -0
  15. package/dist/email/aws/index.d.mts.map +1 -0
  16. package/dist/email/aws/index.mjs +7 -0
  17. package/dist/email/aws/index.mjs.map +1 -0
  18. package/dist/email/email-constants.d.mts +15 -0
  19. package/dist/email/email-constants.d.mts.map +1 -0
  20. package/dist/email/email-constants.mjs +15 -0
  21. package/dist/email/email-constants.mjs.map +1 -0
  22. package/dist/email/email-helpers.d.mts +35 -0
  23. package/dist/email/email-helpers.d.mts.map +1 -0
  24. package/dist/email/email-helpers.mjs +144 -0
  25. package/dist/email/email-helpers.mjs.map +1 -0
  26. package/dist/email/email-receiver.d.mts +12 -0
  27. package/dist/email/email-receiver.d.mts.map +1 -0
  28. package/dist/email/email-receiver.mjs +23 -0
  29. package/dist/email/email-receiver.mjs.map +1 -0
  30. package/dist/email/email-sender.d.mts +13 -0
  31. package/dist/email/email-sender.d.mts.map +1 -0
  32. package/dist/email/email-sender.mjs +35 -0
  33. package/dist/email/email-sender.mjs.map +1 -0
  34. package/dist/email/email-service.respec.d.mts +2 -0
  35. package/dist/email/email-service.respec.d.mts.map +1 -0
  36. package/dist/email/email-service.respec.mjs +115 -0
  37. package/dist/email/email-service.respec.mjs.map +1 -0
  38. package/dist/email/email-types.d.mts +53 -0
  39. package/dist/email/email-types.d.mts.map +1 -0
  40. package/dist/email/email-types.mjs +5 -0
  41. package/dist/email/email-types.mjs.map +1 -0
  42. package/dist/email/index.d.mts +11 -0
  43. package/dist/email/index.d.mts.map +1 -0
  44. package/dist/email/index.mjs +11 -0
  45. package/dist/email/index.mjs.map +1 -0
  46. package/dist/email/mock/email-sender-mock.d.mts +20 -0
  47. package/dist/email/mock/email-sender-mock.d.mts.map +1 -0
  48. package/dist/email/mock/email-sender-mock.mjs +47 -0
  49. package/dist/email/mock/email-sender-mock.mjs.map +1 -0
  50. package/dist/email/mock/index.d.mts +5 -0
  51. package/dist/email/mock/index.d.mts.map +1 -0
  52. package/dist/email/mock/index.mjs +5 -0
  53. package/dist/email/mock/index.mjs.map +1 -0
  54. package/dist/index.d.mts +13 -0
  55. package/dist/index.d.mts.map +1 -0
  56. package/dist/index.mjs +14 -0
  57. package/dist/index.mjs.map +1 -0
  58. package/dist/respec-gib.node.mjs +3 -4
  59. package/dist/respec-gib.node.mjs.map +1 -1
  60. package/dist/serve-gib/bootstrap-helper.d.mts +27 -0
  61. package/dist/serve-gib/bootstrap-helper.d.mts.map +1 -0
  62. package/dist/serve-gib/bootstrap-helper.mjs +116 -0
  63. package/dist/serve-gib/bootstrap-helper.mjs.map +1 -0
  64. package/dist/serve-gib/bootstrap-helper.respec.d.mts +2 -0
  65. package/dist/serve-gib/bootstrap-helper.respec.d.mts.map +1 -0
  66. package/dist/serve-gib/bootstrap-helper.respec.mjs +85 -0
  67. package/dist/serve-gib/bootstrap-helper.respec.mjs.map +1 -0
  68. package/dist/serve-gib/constants.d.mts +2 -0
  69. package/dist/serve-gib/constants.d.mts.map +1 -0
  70. package/dist/serve-gib/constants.mjs +2 -0
  71. package/dist/serve-gib/constants.mjs.map +1 -0
  72. package/dist/serve-gib/handlers/api/debug/ws-echo.handler.d.mts +39 -0
  73. package/dist/serve-gib/handlers/api/debug/ws-echo.handler.d.mts.map +1 -0
  74. package/dist/serve-gib/handlers/api/debug/ws-echo.handler.mjs +99 -0
  75. package/dist/serve-gib/handlers/api/debug/ws-echo.handler.mjs.map +1 -0
  76. package/dist/serve-gib/handlers/api/email/email-inbound.handler.d.mts +25 -0
  77. package/dist/serve-gib/handlers/api/email/email-inbound.handler.d.mts.map +1 -0
  78. package/dist/serve-gib/handlers/api/email/email-inbound.handler.mjs +54 -0
  79. package/dist/serve-gib/handlers/api/email/email-inbound.handler.mjs.map +1 -0
  80. package/dist/serve-gib/handlers/api/email/email-outbound.handler.d.mts +24 -0
  81. package/dist/serve-gib/handlers/api/email/email-outbound.handler.d.mts.map +1 -0
  82. package/dist/serve-gib/handlers/api/email/email-outbound.handler.mjs +72 -0
  83. package/dist/serve-gib/handlers/api/email/email-outbound.handler.mjs.map +1 -0
  84. package/dist/serve-gib/handlers/api/health.handler.d.mts +14 -0
  85. package/dist/serve-gib/handlers/api/health.handler.d.mts.map +1 -0
  86. package/dist/serve-gib/handlers/api/health.handler.mjs +21 -0
  87. package/dist/serve-gib/handlers/api/health.handler.mjs.map +1 -0
  88. package/dist/serve-gib/handlers/api/health.respec.d.mts +2 -0
  89. package/dist/serve-gib/handlers/api/health.respec.d.mts.map +1 -0
  90. package/dist/serve-gib/handlers/api/health.respec.mjs +47 -0
  91. package/dist/serve-gib/handlers/api/health.respec.mjs.map +1 -0
  92. package/dist/serve-gib/handlers/api/ibgib/ibgib-handler-types.d.mts +41 -0
  93. package/dist/serve-gib/handlers/api/ibgib/ibgib-handler-types.d.mts.map +1 -0
  94. package/dist/serve-gib/handlers/api/ibgib/ibgib-handler-types.mjs +34 -0
  95. package/dist/serve-gib/handlers/api/ibgib/ibgib-handler-types.mjs.map +1 -0
  96. package/dist/serve-gib/handlers/api/ibgib/ibgib.handler.d.mts +26 -0
  97. package/dist/serve-gib/handlers/api/ibgib/ibgib.handler.d.mts.map +1 -0
  98. package/dist/serve-gib/handlers/api/ibgib/ibgib.handler.mjs +179 -0
  99. package/dist/serve-gib/handlers/api/ibgib/ibgib.handler.mjs.map +1 -0
  100. package/dist/serve-gib/handlers/api/keystone/keystone-check-email.handler.d.mts +23 -0
  101. package/dist/serve-gib/handlers/api/keystone/keystone-check-email.handler.d.mts.map +1 -0
  102. package/dist/serve-gib/handlers/api/keystone/keystone-check-email.handler.mjs +52 -0
  103. package/dist/serve-gib/handlers/api/keystone/keystone-check-email.handler.mjs.map +1 -0
  104. package/dist/serve-gib/handlers/api/keystone/keystone-evolve.handler.d.mts +44 -0
  105. package/dist/serve-gib/handlers/api/keystone/keystone-evolve.handler.d.mts.map +1 -0
  106. package/dist/serve-gib/handlers/api/keystone/keystone-evolve.handler.mjs +127 -0
  107. package/dist/serve-gib/handlers/api/keystone/keystone-evolve.handler.mjs.map +1 -0
  108. package/dist/serve-gib/handlers/api/keystone/keystone-genesis.handler.d.mts +45 -0
  109. package/dist/serve-gib/handlers/api/keystone/keystone-genesis.handler.d.mts.map +1 -0
  110. package/dist/serve-gib/handlers/api/keystone/keystone-genesis.handler.mjs +159 -0
  111. package/dist/serve-gib/handlers/api/keystone/keystone-genesis.handler.mjs.map +1 -0
  112. package/dist/serve-gib/handlers/api/keystone/keystone-get.handler.d.mts +25 -0
  113. package/dist/serve-gib/handlers/api/keystone/keystone-get.handler.d.mts.map +1 -0
  114. package/dist/serve-gib/handlers/api/keystone/keystone-get.handler.mjs +183 -0
  115. package/dist/serve-gib/handlers/api/keystone/keystone-get.handler.mjs.map +1 -0
  116. package/dist/serve-gib/handlers/api/keystone/keystone-get.respec.d.mts +2 -0
  117. package/dist/serve-gib/handlers/api/keystone/keystone-get.respec.d.mts.map +1 -0
  118. package/dist/serve-gib/handlers/api/keystone/keystone-get.respec.mjs +98 -0
  119. package/dist/serve-gib/handlers/api/keystone/keystone-get.respec.mjs.map +1 -0
  120. package/dist/serve-gib/handlers/api/keystone/keystone-handler-types.d.mts +22 -0
  121. package/dist/serve-gib/handlers/api/keystone/keystone-handler-types.d.mts.map +1 -0
  122. package/dist/serve-gib/handlers/api/keystone/keystone-handler-types.mjs +19 -0
  123. package/dist/serve-gib/handlers/api/keystone/keystone-handler-types.mjs.map +1 -0
  124. package/dist/serve-gib/handlers/api/keystone/keystone-lookup.handler.d.mts +19 -0
  125. package/dist/serve-gib/handlers/api/keystone/keystone-lookup.handler.d.mts.map +1 -0
  126. package/dist/serve-gib/handlers/api/keystone/keystone-lookup.handler.mjs +82 -0
  127. package/dist/serve-gib/handlers/api/keystone/keystone-lookup.handler.mjs.map +1 -0
  128. package/dist/serve-gib/handlers/api/keystone/keystone-post.handler.d.mts +20 -0
  129. package/dist/serve-gib/handlers/api/keystone/keystone-post.handler.d.mts.map +1 -0
  130. package/dist/serve-gib/handlers/api/keystone/keystone-post.handler.mjs +77 -0
  131. package/dist/serve-gib/handlers/api/keystone/keystone-post.handler.mjs.map +1 -0
  132. package/dist/serve-gib/handlers/api/keystone/keystone-post.respec.d.mts +2 -0
  133. package/dist/serve-gib/handlers/api/keystone/keystone-post.respec.d.mts.map +1 -0
  134. package/dist/serve-gib/handlers/api/keystone/keystone-post.respec.mjs +131 -0
  135. package/dist/serve-gib/handlers/api/keystone/keystone-post.respec.mjs.map +1 -0
  136. package/dist/serve-gib/handlers/api/keystone/sso-config.handler.d.mts +23 -0
  137. package/dist/serve-gib/handlers/api/keystone/sso-config.handler.d.mts.map +1 -0
  138. package/dist/serve-gib/handlers/api/keystone/sso-config.handler.mjs +62 -0
  139. package/dist/serve-gib/handlers/api/keystone/sso-config.handler.mjs.map +1 -0
  140. package/dist/serve-gib/handlers/api/keystone/sso-link.handler.d.mts +23 -0
  141. package/dist/serve-gib/handlers/api/keystone/sso-link.handler.d.mts.map +1 -0
  142. package/dist/serve-gib/handlers/api/keystone/sso-link.handler.mjs +118 -0
  143. package/dist/serve-gib/handlers/api/keystone/sso-link.handler.mjs.map +1 -0
  144. package/dist/serve-gib/handlers/api/keystone/sso-login.handler.d.mts +24 -0
  145. package/dist/serve-gib/handlers/api/keystone/sso-login.handler.d.mts.map +1 -0
  146. package/dist/serve-gib/handlers/api/keystone/sso-login.handler.mjs +160 -0
  147. package/dist/serve-gib/handlers/api/keystone/sso-login.handler.mjs.map +1 -0
  148. package/dist/serve-gib/handlers/error-handler.d.mts +14 -0
  149. package/dist/serve-gib/handlers/error-handler.d.mts.map +1 -0
  150. package/dist/serve-gib/handlers/error-handler.mjs +35 -0
  151. package/dist/serve-gib/handlers/error-handler.mjs.map +1 -0
  152. package/dist/serve-gib/handlers/handler-base.d.mts +129 -0
  153. package/dist/serve-gib/handlers/handler-base.d.mts.map +1 -0
  154. package/dist/serve-gib/handlers/handler-base.mjs +402 -0
  155. package/dist/serve-gib/handlers/handler-base.mjs.map +1 -0
  156. package/dist/serve-gib/handlers/static-handler.d.mts +17 -0
  157. package/dist/serve-gib/handlers/static-handler.d.mts.map +1 -0
  158. package/dist/serve-gib/handlers/static-handler.mjs +85 -0
  159. package/dist/serve-gib/handlers/static-handler.mjs.map +1 -0
  160. package/dist/serve-gib/handlers/ws/sync-upgrade-handler-base.d.mts +35 -0
  161. package/dist/serve-gib/handlers/ws/sync-upgrade-handler-base.d.mts.map +1 -0
  162. package/dist/serve-gib/handlers/ws/sync-upgrade-handler-base.mjs +219 -0
  163. package/dist/serve-gib/handlers/ws/sync-upgrade-handler-base.mjs.map +1 -0
  164. package/dist/serve-gib/handlers/ws/sync-upgrade.handler.d.mts +21 -0
  165. package/dist/serve-gib/handlers/ws/sync-upgrade.handler.d.mts.map +1 -0
  166. package/dist/serve-gib/handlers/ws/sync-upgrade.handler.mjs +21 -0
  167. package/dist/serve-gib/handlers/ws/sync-upgrade.handler.mjs.map +1 -0
  168. package/dist/serve-gib/handlers/ws/ws-helper.d.mts +29 -0
  169. package/dist/serve-gib/handlers/ws/ws-helper.d.mts.map +1 -0
  170. package/dist/serve-gib/handlers/ws/ws-helper.mjs +195 -0
  171. package/dist/serve-gib/handlers/ws/ws-helper.mjs.map +1 -0
  172. package/dist/serve-gib/handlers/ws/ws-types.d.mts +32 -0
  173. package/dist/serve-gib/handlers/ws/ws-types.d.mts.map +1 -0
  174. package/dist/serve-gib/handlers/ws/ws-types.mjs +2 -0
  175. package/dist/serve-gib/handlers/ws/ws-types.mjs.map +1 -0
  176. package/dist/serve-gib/identity-index/identity-index-constants.d.mts +4 -0
  177. package/dist/serve-gib/identity-index/identity-index-constants.d.mts.map +1 -0
  178. package/dist/serve-gib/identity-index/identity-index-constants.mjs +4 -0
  179. package/dist/serve-gib/identity-index/identity-index-constants.mjs.map +1 -0
  180. package/dist/serve-gib/identity-index/identity-index-helpers.d.mts +35 -0
  181. package/dist/serve-gib/identity-index/identity-index-helpers.d.mts.map +1 -0
  182. package/dist/serve-gib/identity-index/identity-index-helpers.mjs +69 -0
  183. package/dist/serve-gib/identity-index/identity-index-helpers.mjs.map +1 -0
  184. package/dist/serve-gib/identity-index/identity-index-service.d.mts +41 -0
  185. package/dist/serve-gib/identity-index/identity-index-service.d.mts.map +1 -0
  186. package/dist/serve-gib/identity-index/identity-index-service.mjs +86 -0
  187. package/dist/serve-gib/identity-index/identity-index-service.mjs.map +1 -0
  188. package/dist/serve-gib/identity-index/identity-index-service.respec.d.mts +2 -0
  189. package/dist/serve-gib/identity-index/identity-index-service.respec.d.mts.map +1 -0
  190. package/dist/serve-gib/identity-index/identity-index-service.respec.mjs +109 -0
  191. package/dist/serve-gib/identity-index/identity-index-service.respec.mjs.map +1 -0
  192. package/dist/serve-gib/identity-index/identity-index-types.d.mts +31 -0
  193. package/dist/serve-gib/identity-index/identity-index-types.d.mts.map +1 -0
  194. package/dist/serve-gib/identity-index/identity-index-types.mjs +2 -0
  195. package/dist/serve-gib/identity-index/identity-index-types.mjs.map +1 -0
  196. package/dist/serve-gib/index.d.mts +50 -0
  197. package/dist/serve-gib/index.d.mts.map +1 -0
  198. package/dist/serve-gib/index.mjs +80 -0
  199. package/dist/serve-gib/index.mjs.map +1 -0
  200. package/dist/serve-gib/keystone-schema-helpers.d.mts +50 -0
  201. package/dist/serve-gib/keystone-schema-helpers.d.mts.map +1 -0
  202. package/dist/serve-gib/keystone-schema-helpers.mjs +99 -0
  203. package/dist/serve-gib/keystone-schema-helpers.mjs.map +1 -0
  204. package/dist/serve-gib/keystone-schema-helpers.respec.d.mts +2 -0
  205. package/dist/serve-gib/keystone-schema-helpers.respec.d.mts.map +1 -0
  206. package/dist/serve-gib/keystone-schema-helpers.respec.mjs +68 -0
  207. package/dist/serve-gib/keystone-schema-helpers.respec.mjs.map +1 -0
  208. package/dist/serve-gib/metaspace-nodeindexedspace/metaspace-nodeindexedspace.d.mts +38 -0
  209. package/dist/serve-gib/metaspace-nodeindexedspace/metaspace-nodeindexedspace.d.mts.map +1 -0
  210. package/dist/serve-gib/metaspace-nodeindexedspace/metaspace-nodeindexedspace.mjs +85 -0
  211. package/dist/serve-gib/metaspace-nodeindexedspace/metaspace-nodeindexedspace.mjs.map +1 -0
  212. package/dist/serve-gib/path-constants.d.mts +102 -0
  213. package/dist/serve-gib/path-constants.d.mts.map +1 -0
  214. package/dist/serve-gib/path-constants.mjs +107 -0
  215. package/dist/serve-gib/path-constants.mjs.map +1 -0
  216. package/dist/serve-gib/path-helper.d.mts +23 -0
  217. package/dist/serve-gib/path-helper.d.mts.map +1 -0
  218. package/dist/serve-gib/path-helper.mjs +107 -0
  219. package/dist/serve-gib/path-helper.mjs.map +1 -0
  220. package/dist/serve-gib/path-helper.respec.d.mts +2 -0
  221. package/dist/serve-gib/path-helper.respec.d.mts.map +1 -0
  222. package/dist/serve-gib/path-helper.respec.mjs +83 -0
  223. package/dist/serve-gib/path-helper.respec.mjs.map +1 -0
  224. package/dist/serve-gib/serve-gib-helpers.d.mts +14 -0
  225. package/dist/serve-gib/serve-gib-helpers.d.mts.map +1 -0
  226. package/dist/serve-gib/serve-gib-helpers.mjs +30 -0
  227. package/dist/serve-gib/serve-gib-helpers.mjs.map +1 -0
  228. package/dist/serve-gib/serve-gib-v1.d.mts +40 -0
  229. package/dist/serve-gib/serve-gib-v1.d.mts.map +1 -0
  230. package/dist/serve-gib/serve-gib-v1.mjs +157 -0
  231. package/dist/serve-gib/serve-gib-v1.mjs.map +1 -0
  232. package/dist/serve-gib/serve-gib.respec.d.mts +2 -0
  233. package/dist/serve-gib/serve-gib.respec.d.mts.map +1 -0
  234. package/dist/serve-gib/serve-gib.respec.mjs +85 -0
  235. package/dist/serve-gib/serve-gib.respec.mjs.map +1 -0
  236. package/dist/serve-gib/server-constants.d.mts +3 -0
  237. package/dist/serve-gib/server-constants.d.mts.map +1 -0
  238. package/dist/serve-gib/server-constants.mjs +3 -0
  239. package/dist/serve-gib/server-constants.mjs.map +1 -0
  240. package/dist/serve-gib/types.d.mts +94 -0
  241. package/dist/serve-gib/types.d.mts.map +1 -0
  242. package/dist/serve-gib/types.mjs +7 -0
  243. package/dist/serve-gib/types.mjs.map +1 -0
  244. package/dist/witness/space/metaspace/metaspace-nodespace/metaspace-nodespace-helper.mjs.map +1 -1
  245. package/dist/witness/space/metaspace/metaspace-nodespace/metaspace-nodespace.d.mts +5 -0
  246. package/dist/witness/space/metaspace/metaspace-nodespace/metaspace-nodespace.d.mts.map +1 -1
  247. package/dist/witness/space/metaspace/metaspace-nodespace/metaspace-nodespace.mjs +37 -0
  248. package/dist/witness/space/metaspace/metaspace-nodespace/metaspace-nodespace.mjs.map +1 -1
  249. package/dist/witness/space/node-filesystem-space/node-filesystem-space-helper.mjs +1 -1
  250. package/dist/witness/space/node-filesystem-space/node-filesystem-space-helper.mjs.map +1 -1
  251. package/dist/witness/space/node-filesystem-space/node-filesystem-space-types.d.mts.map +1 -1
  252. package/dist/witness/space/node-filesystem-space/node-filesystem-space-v1.d.mts.map +1 -1
  253. package/dist/witness/space/node-filesystem-space/node-filesystem-space-v1.mjs.map +1 -1
  254. package/dist/witness/space/node-filesystem-space/node-indexed-filesystem-space/node-indexed-filesystem-space-v1.d.mts.map +1 -1
  255. package/dist/witness/space/node-filesystem-space/node-indexed-filesystem-space/respec/testSpace_createAndInit.node-indexed-filesystem-space-v1.respec.mjs.map +1 -1
  256. package/dist/witness/space/node-filesystem-space/node-indexed-filesystem-space/respec/testSpace_persistTransformResult.node-indexed-filesystem-space-v1.respec.mjs.map +1 -1
  257. package/dist/witness/space/node-filesystem-space/node-indexed-filesystem-space/respec/testSpace_putGetDelete.node-indexed-filesystem-space-v1.respec.mjs.map +1 -1
  258. package/dist/witness/space/node-filesystem-space/node-indexed-filesystem-space/respec/testSpace_registerNewIbGib_GetLatest.node-indexed-filesystem-space-v1.respec.mjs.map +1 -1
  259. package/dist/witness/space/node-filesystem-space/respec/testSpace_createAndInit.node-filesystem-space-v1.respec.mjs.map +1 -1
  260. package/dist/witness/space/node-filesystem-space/respec/testSpace_persistTransformResult.node-filesystem-space-v1.respec.mjs.map +1 -1
  261. package/dist/witness/space/node-filesystem-space/respec/testSpace_putGetDelete.node-filesystem-space-v1.respec.mjs.map +1 -1
  262. package/dist/witness/space/node-filesystem-space/respec/testSpace_registerNewIbGib_GetLatest.node-filesystem-space-v1.respec.mjs.map +1 -1
  263. package/package.json +2 -2
  264. package/src/email/aws/aws-sigv4-helper.mts +139 -0
  265. package/src/email/aws/email-receiver-aws.mts +107 -0
  266. package/src/email/aws/email-sender-aws.mts +130 -0
  267. package/src/email/aws/index.mts +7 -0
  268. package/src/email/email-constants.mts +18 -0
  269. package/src/email/email-helpers.mts +160 -0
  270. package/src/email/email-receiver.mts +29 -0
  271. package/src/email/email-sender.mts +44 -0
  272. package/src/email/email-service.respec.mts +134 -0
  273. package/src/email/email-types.mts +59 -0
  274. package/src/email/index.mts +11 -0
  275. package/src/email/mock/email-sender-mock.mts +54 -0
  276. package/src/email/mock/index.mts +5 -0
  277. package/src/index.mts +41 -0
  278. package/src/respec-gib.node.mts +4 -5
  279. package/src/serve-gib/CHANGELOG.md +34 -0
  280. package/src/serve-gib/README.md +77 -0
  281. package/src/serve-gib/SERVE_REFACTOR_IMPLEMENTATION.md +112 -0
  282. package/src/serve-gib/bootstrap-helper.mts +141 -0
  283. package/src/serve-gib/bootstrap-helper.respec.mts +100 -0
  284. package/src/serve-gib/constants.mts +1 -0
  285. package/src/serve-gib/handlers/api/debug/ws-echo.handler.mts +105 -0
  286. package/src/serve-gib/handlers/api/email/email-inbound.handler.mts +67 -0
  287. package/src/serve-gib/handlers/api/email/email-outbound.handler.mts +82 -0
  288. package/src/serve-gib/handlers/api/health.handler.mts +23 -0
  289. package/src/serve-gib/handlers/api/health.respec.mts +51 -0
  290. package/src/serve-gib/handlers/api/ibgib/ibgib-handler-types.mts +49 -0
  291. package/src/serve-gib/handlers/api/ibgib/ibgib.handler.mts +176 -0
  292. package/src/serve-gib/handlers/api/keystone/keystone-check-email.handler.mts +60 -0
  293. package/src/serve-gib/handlers/api/keystone/keystone-evolve.handler.mts +150 -0
  294. package/src/serve-gib/handlers/api/keystone/keystone-genesis.handler.mts +171 -0
  295. package/src/serve-gib/handlers/api/keystone/keystone-get.handler.mts +198 -0
  296. package/src/serve-gib/handlers/api/keystone/keystone-get.respec.mts +106 -0
  297. package/src/serve-gib/handlers/api/keystone/keystone-handler-types.mts +29 -0
  298. package/src/serve-gib/handlers/api/keystone/keystone-lookup.handler.mts +95 -0
  299. package/src/serve-gib/handlers/api/keystone/keystone-post.handler.mts +75 -0
  300. package/src/serve-gib/handlers/api/keystone/keystone-post.respec.mts +130 -0
  301. package/src/serve-gib/handlers/api/keystone/sso-config.handler.mts +66 -0
  302. package/src/serve-gib/handlers/api/keystone/sso-link.handler.mts +140 -0
  303. package/src/serve-gib/handlers/api/keystone/sso-login.handler.mts +190 -0
  304. package/src/serve-gib/handlers/error-handler.mts +36 -0
  305. package/src/serve-gib/handlers/handler-base.mts +383 -0
  306. package/src/serve-gib/handlers/static-handler.mts +83 -0
  307. package/src/serve-gib/handlers/ws/sync-upgrade-handler-base.mts +233 -0
  308. package/src/serve-gib/handlers/ws/sync-upgrade.handler.mts +24 -0
  309. package/src/serve-gib/handlers/ws/ws-helper.mts +216 -0
  310. package/src/serve-gib/handlers/ws/ws-types.mts +53 -0
  311. package/src/serve-gib/identity-index/identity-index-constants.mts +3 -0
  312. package/src/serve-gib/identity-index/identity-index-helpers.mts +85 -0
  313. package/src/serve-gib/identity-index/identity-index-service.mts +109 -0
  314. package/src/serve-gib/identity-index/identity-index-service.respec.mts +135 -0
  315. package/src/serve-gib/identity-index/identity-index-types.mts +33 -0
  316. package/src/serve-gib/index.mts +92 -0
  317. package/src/serve-gib/keystone-schema-helpers.mts +120 -0
  318. package/src/serve-gib/keystone-schema-helpers.respec.mts +85 -0
  319. package/src/serve-gib/metaspace-nodeindexedspace/metaspace-nodeindexedspace.mts +109 -0
  320. package/src/serve-gib/path-constants.mts +119 -0
  321. package/src/serve-gib/path-helper.mts +101 -0
  322. package/src/serve-gib/path-helper.respec.mts +99 -0
  323. package/src/serve-gib/serve-gib-helpers.mts +32 -0
  324. package/src/serve-gib/serve-gib-v1.mts +172 -0
  325. package/src/serve-gib/serve-gib.respec.mts +90 -0
  326. package/src/serve-gib/server-constants.mts +2 -0
  327. package/src/serve-gib/types.mts +102 -0
  328. package/src/witness/space/metaspace/metaspace-nodespace/metaspace-nodespace.mts +41 -0
  329. package/src/witness/space/node-filesystem-space/node-filesystem-space-helper.mts +1 -1
@@ -0,0 +1,109 @@
1
+ import * as fs from 'fs/promises';
2
+ import { IbGibAddr } from '@ibgib/ts-gib/dist/types.mjs';
3
+ import { DEFAULT_IDENTITY_INDEX_SALT } from './identity-index-constants.mjs';
4
+ import { getIdentityEmailHash, getShardedIndexPath } from './identity-index-helpers.mjs';
5
+ import { IdentityIndexRecord, IdentityIndexServiceOptions, RegisterEmailIndexResult } from './identity-index-types.mjs';
6
+
7
+ /**
8
+ * Service managing atomic, sharded identity index files for backwards email -> primary identity tjpAddr lookups.
9
+ */
10
+ export class IdentityIndexService {
11
+ private baseDir: string;
12
+ private salt: string;
13
+
14
+ constructor({ baseDir, salt }: IdentityIndexServiceOptions) {
15
+ if (!baseDir) { throw new Error('baseDir must be provided to IdentityIndexService.'); }
16
+ this.baseDir = baseDir;
17
+ this.salt = salt || process.env.IDENTITY_INDEX_SALT || DEFAULT_IDENTITY_INDEX_SALT;
18
+ }
19
+
20
+ /**
21
+ * Registers an email to a primary identity tjpAddr.
22
+ * Uses atomic OS file creation (`flag: 'wx'`) to guarantee single-server ACID uniqueness.
23
+ * Throws `duplicate_identity_409` error if email is already registered.
24
+ */
25
+ async registerEmailIndex({
26
+ email,
27
+ tjpAddr,
28
+ }: {
29
+ email: string;
30
+ tjpAddr: IbGibAddr;
31
+ }): Promise<RegisterEmailIndexResult> {
32
+ const emailHash = await getIdentityEmailHash({ email, salt: this.salt });
33
+ const { folderPath, filePath } = getShardedIndexPath({ baseDir: this.baseDir, emailHash });
34
+
35
+ await fs.mkdir(folderPath, { recursive: true });
36
+
37
+ const record: IdentityIndexRecord = {
38
+ tjpAddr,
39
+ createdAt: Date.now(),
40
+ };
41
+
42
+ try {
43
+ await fs.writeFile(filePath, JSON.stringify(record, null, 2), { flag: 'wx' });
44
+ return { emailHash, filePath, record };
45
+ } catch (error: any) {
46
+ if (error.code === 'EEXIST') {
47
+ throw new Error(`Email is already registered (E: duplicate_identity_409)`);
48
+ }
49
+ throw error;
50
+ }
51
+ }
52
+
53
+ /**
54
+ * Retrieves the registered `IdentityIndexRecord` for an email address.
55
+ * Returns `undefined` if email is not indexed.
56
+ */
57
+ async getEmailIndex({
58
+ email,
59
+ }: {
60
+ email: string;
61
+ }): Promise<IdentityIndexRecord | undefined> {
62
+ const emailHash = await getIdentityEmailHash({ email, salt: this.salt });
63
+ return this.getEmailIndexByHash({ emailHash });
64
+ }
65
+
66
+ /**
67
+ * Retrieves the registered `IdentityIndexRecord` directly by `emailHash`.
68
+ * Returns `undefined` if hash file does not exist.
69
+ */
70
+ async getEmailIndexByHash({
71
+ emailHash,
72
+ }: {
73
+ emailHash: string;
74
+ }): Promise<IdentityIndexRecord | undefined> {
75
+ const { filePath } = getShardedIndexPath({ baseDir: this.baseDir, emailHash });
76
+ try {
77
+ const content = await fs.readFile(filePath, 'utf8');
78
+ const record: IdentityIndexRecord = JSON.parse(content);
79
+ return record;
80
+ } catch (error: any) {
81
+ if (error.code === 'ENOENT') {
82
+ return undefined;
83
+ }
84
+ throw error;
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Unindexes an email address (deletes the index JSON file).
90
+ * Returns `true` if unindexed, or `false` if file did not exist.
91
+ */
92
+ async unregisterEmailIndex({
93
+ email,
94
+ }: {
95
+ email: string;
96
+ }): Promise<boolean> {
97
+ const emailHash = await getIdentityEmailHash({ email, salt: this.salt });
98
+ const { filePath } = getShardedIndexPath({ baseDir: this.baseDir, emailHash });
99
+ try {
100
+ await fs.unlink(filePath);
101
+ return true;
102
+ } catch (error: any) {
103
+ if (error.code === 'ENOENT') {
104
+ return false;
105
+ }
106
+ throw error;
107
+ }
108
+ }
109
+ }
@@ -0,0 +1,135 @@
1
+ import * as fs from 'fs/promises';
2
+ import * as path from 'path';
3
+ import { respecfully, iReckon, ifWe } from '@ibgib/helper-gib/dist/respec-gib/respec-gib.mjs';
4
+ import { IdentityIndexService } from './identity-index-service.mjs';
5
+ import { normalizeEmail, getIdentityEmailHash, getShardedIndexPath, validateEmail } from './identity-index-helpers.mjs';
6
+
7
+ const sir = `[${import.meta.url}]`;
8
+ const TEST_SALT = 'test_salt_12345';
9
+ const TEST_BASE_DIR = path.join(process.cwd(), 'test-data-identity-index');
10
+
11
+ await respecfully(sir, 'IdentityIndexService & Helpers', async () => {
12
+
13
+ // Cleanup test data directory before & after tests
14
+ const cleanupDir = async () => {
15
+ try {
16
+ await fs.rm(TEST_BASE_DIR, { recursive: true, force: true });
17
+ } catch { /* ignore */ }
18
+ };
19
+
20
+ await cleanupDir();
21
+
22
+ await ifWe(sir, 'normalize email strings correctly', async () => {
23
+ iReckon(sir, normalizeEmail(' Alice@Example.com ')).willEqual('alice@example.com');
24
+ iReckon(sir, normalizeEmail('BOB@DOMAIN.ORG')).willEqual('bob@domain.org');
25
+ iReckon(sir, normalizeEmail('')).willEqual('');
26
+ });
27
+
28
+ await ifWe(sir, 'validate email addresses accurately using validateEmail', async () => {
29
+ // Valid emails
30
+ iReckon(sir, validateEmail({ email: 'user@example.com' }).length).willEqual(0);
31
+ iReckon(sir, validateEmail({ email: 'user+tag@sub.domain.co.uk' }).length).willEqual(0);
32
+ iReckon(sir, validateEmail({ email: ' alice@company.org ' }).length).willEqual(0);
33
+
34
+ // Invalid emails
35
+ iReckon(sir, validateEmail({ email: '' }).length > 0).isGonnaBeTrue();
36
+ iReckon(sir, validateEmail({ email: ' ' }).length > 0).isGonnaBeTrue();
37
+ iReckon(sir, validateEmail({ email: null }).length > 0).isGonnaBeTrue();
38
+ iReckon(sir, validateEmail({ email: undefined }).length > 0).isGonnaBeTrue();
39
+ iReckon(sir, validateEmail({ email: 'no-at-sign.com' }).length > 0).isGonnaBeTrue();
40
+ iReckon(sir, validateEmail({ email: 'user@no-dot' }).length > 0).isGonnaBeTrue();
41
+ iReckon(sir, validateEmail({ email: 'user @space.com' }).length > 0).isGonnaBeTrue();
42
+ iReckon(sir, validateEmail({ email: '@domain.com' }).length > 0).isGonnaBeTrue();
43
+ });
44
+
45
+ await ifWe(sir, 'calculate consistent SHA256 email hashes with salt', async () => {
46
+ const hash1 = await getIdentityEmailHash({ email: 'Alice@Example.com', salt: TEST_SALT });
47
+ const hash2 = await getIdentityEmailHash({ email: 'alice@example.com', salt: TEST_SALT });
48
+ iReckon(sir, hash1).willEqual(hash2);
49
+ iReckon(sir, hash1.length > 30).isGonnaBeTrue();
50
+
51
+ const diffSaltHash = await getIdentityEmailHash({ email: 'alice@example.com', salt: 'different_salt' });
52
+ iReckon(sir, hash1).not.willEqual(diffSaltHash);
53
+ });
54
+
55
+ await ifWe(sir, 'calculate sharded folder paths and truncated filenames', async () => {
56
+ const fullHash = 'abcdef1234567890abcdef1234567890';
57
+ const { folderPath, filePath, filename } = getShardedIndexPath({ baseDir: TEST_BASE_DIR, emailHash: fullHash });
58
+
59
+ const expectedSubfolder = path.join(TEST_BASE_DIR, 'email_hashes', 'ab', 'cd', 'ef');
60
+ iReckon(sir, folderPath).willEqual(expectedSubfolder);
61
+
62
+ // Filename strips the leading 6 chars ('abcdef')
63
+ iReckon(sir, filename).willEqual('1234567890abcdef1234567890.json');
64
+ iReckon(sir, filePath).willEqual(path.join(expectedSubfolder, '1234567890abcdef1234567890.json'));
65
+ });
66
+
67
+ await ifWe(sir, 'register an email index and read it back', async () => {
68
+ const service = new IdentityIndexService({ baseDir: TEST_BASE_DIR, salt: TEST_SALT });
69
+ const email = 'user1@example.com';
70
+ const tjpAddr = 'keystone^AF5BB54AE1254FB499C434A2915C6BA08BC1D53936E57D19D415EA17FA3CE475';
71
+
72
+ const result = await service.registerEmailIndex({ email, tjpAddr });
73
+ iReckon(sir, result.emailHash).isGonnaBeTruthy();
74
+ iReckon(sir, result.record.tjpAddr).willEqual(tjpAddr);
75
+ iReckon(sir, result.record.createdAt > 0).isGonnaBeTrue();
76
+
77
+ const retrieved = await service.getEmailIndex({ email });
78
+ iReckon(sir, retrieved).isGonnaBeTruthy();
79
+ iReckon(sir, retrieved!.tjpAddr).willEqual(tjpAddr);
80
+ });
81
+
82
+ await ifWe(sir, 'atomically reject duplicate email registration with duplicate_identity_409', async () => {
83
+ const service = new IdentityIndexService({ baseDir: TEST_BASE_DIR, salt: TEST_SALT });
84
+ const email = 'duplicate@example.com';
85
+ const tjpAddr1 = 'keystone^1111111111111111111111111111111111111111111111111111111111111111';
86
+ const tjpAddr2 = 'keystone^2222222222222222222222222222222222222222222222222222222222222222';
87
+
88
+ await service.registerEmailIndex({ email, tjpAddr: tjpAddr1 });
89
+
90
+ let duplicateCaught = false;
91
+ try {
92
+ await service.registerEmailIndex({ email, tjpAddr: tjpAddr2 });
93
+ } catch (error: any) {
94
+ if (error.message.includes('duplicate_identity_409')) {
95
+ duplicateCaught = true;
96
+ }
97
+ }
98
+
99
+ iReckon(sir, duplicateCaught).asTo('duplicate registration rejected via flag wx EEXIST').isGonnaBeTrue();
100
+ });
101
+
102
+ await ifWe(sir, 'support multiple email hashes pointing to the same identity tjpAddr', async () => {
103
+ const service = new IdentityIndexService({ baseDir: TEST_BASE_DIR, salt: TEST_SALT });
104
+ const primaryTjp = 'keystone^3333333333333333333333333333333333333333333333333333333333333333';
105
+
106
+ const email1 = 'personal@example.com';
107
+ const email2 = 'work@company.com';
108
+
109
+ await service.registerEmailIndex({ email: email1, tjpAddr: primaryTjp });
110
+ await service.registerEmailIndex({ email: email2, tjpAddr: primaryTjp });
111
+
112
+ const record1 = await service.getEmailIndex({ email: email1 });
113
+ const record2 = await service.getEmailIndex({ email: email2 });
114
+
115
+ iReckon(sir, record1!.tjpAddr).willEqual(primaryTjp);
116
+ iReckon(sir, record2!.tjpAddr).willEqual(primaryTjp);
117
+ });
118
+
119
+ await ifWe(sir, 'unregister an email index cleanly', async () => {
120
+ const service = new IdentityIndexService({ baseDir: TEST_BASE_DIR, salt: TEST_SALT });
121
+ const email = 'delete-me@example.com';
122
+ const tjpAddr = 'keystone^4444444444444444444444444444444444444444444444444444444444444444';
123
+
124
+ await service.registerEmailIndex({ email, tjpAddr });
125
+ iReckon(sir, await service.getEmailIndex({ email })).isGonnaBeTruthy();
126
+
127
+ const unindexed = await service.unregisterEmailIndex({ email });
128
+ iReckon(sir, unindexed).isGonnaBeTrue();
129
+
130
+ const retrievedAfter = await service.getEmailIndex({ email });
131
+ iReckon(sir, retrievedAfter).isGonnaBeUndefined();
132
+ });
133
+
134
+ await cleanupDir();
135
+ });
@@ -0,0 +1,33 @@
1
+ import { IbGibAddr } from '@ibgib/ts-gib/dist/types.mjs';
2
+
3
+ /**
4
+ * Record stored in the atomic sharded index JSON file.
5
+ */
6
+ export interface IdentityIndexRecord {
7
+ /** Primary identity keystone TJP address. */
8
+ tjpAddr: IbGibAddr;
9
+ /** Creation timestamp (Date.now()) in epoch milliseconds. */
10
+ createdAt: number;
11
+ }
12
+
13
+ /**
14
+ * Configuration options for initializing IdentityIndexService.
15
+ */
16
+ export interface IdentityIndexServiceOptions {
17
+ /** Base directory where index shards will be stored (e.g. `data/index`). */
18
+ baseDir: string;
19
+ /** Server salt for privacy email hashing. Defaults to `DEFAULT_IDENTITY_INDEX_SALT`. */
20
+ salt?: string;
21
+ }
22
+
23
+ /**
24
+ * Result returned upon successful email index registration.
25
+ */
26
+ export interface RegisterEmailIndexResult {
27
+ /** Privacy hash derived from normalizeEmail(email) + salt. */
28
+ emailHash: string;
29
+ /** Absolute filesystem path of the atomic index JSON file. */
30
+ filePath: string;
31
+ /** The index record stored in the file. */
32
+ record: IdentityIndexRecord;
33
+ }
@@ -0,0 +1,92 @@
1
+ /**
2
+ * @module serve-gib
3
+ *
4
+ * Minimalist, high-observability HTTP & WebSocket microframework for ibgib servers.
5
+ */
6
+
7
+ export * from './types.mjs';
8
+ export * from './constants.mjs';
9
+ export * from './path-constants.mjs';
10
+ export * from './path-helper.mjs';
11
+ export * from './bootstrap-helper.mjs';
12
+ export * from './serve-gib-helpers.mjs';
13
+ export * from './serve-gib-v1.mjs';
14
+ export * from './keystone-schema-helpers.mjs';
15
+ export * from './identity-index/identity-index-types.mjs';
16
+ export * from './identity-index/identity-index-constants.mjs';
17
+ export * from './identity-index/identity-index-helpers.mjs';
18
+ export * from './identity-index/identity-index-service.mjs';
19
+
20
+ // Handlers
21
+ export * from './handlers/handler-base.mjs';
22
+ export * from './handlers/static-handler.mjs';
23
+ export * from './handlers/error-handler.mjs';
24
+ export * from './handlers/api/health.handler.mjs';
25
+ export * from './handlers/api/ibgib/ibgib-handler-types.mjs';
26
+ export * from './handlers/api/ibgib/ibgib.handler.mjs';
27
+ export * from './handlers/api/keystone/keystone-handler-types.mjs';
28
+ export * from './handlers/api/keystone/keystone-genesis.handler.mjs';
29
+ export * from './handlers/api/keystone/keystone-evolve.handler.mjs';
30
+ export * from './handlers/api/keystone/keystone-post.handler.mjs';
31
+ export * from './handlers/api/keystone/keystone-get.handler.mjs';
32
+ export * from './handlers/api/keystone/keystone-lookup.handler.mjs';
33
+ export * from './handlers/api/keystone/keystone-check-email.handler.mjs';
34
+ export * from './handlers/api/keystone/sso-config.handler.mjs';
35
+ export * from './handlers/api/keystone/sso-link.handler.mjs';
36
+ export * from './handlers/api/keystone/sso-login.handler.mjs';
37
+ export * from './handlers/api/email/email-inbound.handler.mjs';
38
+ export * from './handlers/api/email/email-outbound.handler.mjs';
39
+ export * from './handlers/api/debug/ws-echo.handler.mjs';
40
+ export * from './handlers/ws/ws-types.mjs';
41
+ export * from './handlers/ws/ws-helper.mjs';
42
+ export * from './handlers/ws/sync-upgrade-handler-base.mjs';
43
+ export * from './handlers/ws/sync-upgrade.handler.mjs';
44
+
45
+ import { ServeGibHandler } from './types.mjs';
46
+ import { HealthHandler } from './handlers/api/health.handler.mjs';
47
+ import { IbGibHandler } from './handlers/api/ibgib/ibgib.handler.mjs';
48
+ import { KeystoneGenesisHandler } from './handlers/api/keystone/keystone-genesis.handler.mjs';
49
+ import { KeystoneEvolveHandler } from './handlers/api/keystone/keystone-evolve.handler.mjs';
50
+ import { KeystonePostHandler } from './handlers/api/keystone/keystone-post.handler.mjs';
51
+ import { KeystoneGetHandler } from './handlers/api/keystone/keystone-get.handler.mjs';
52
+ import { KeystoneLookupHandler } from './handlers/api/keystone/keystone-lookup.handler.mjs';
53
+ import { KeystoneCheckEmailHandler } from './handlers/api/keystone/keystone-check-email.handler.mjs';
54
+ import { SsoLinkHandler } from './handlers/api/keystone/sso-link.handler.mjs';
55
+ import { SsoLoginHandler } from './handlers/api/keystone/sso-login.handler.mjs';
56
+ import { SsoConfigHandler } from './handlers/api/keystone/sso-config.handler.mjs';
57
+ import { EmailInboundHandler } from './handlers/api/email/email-inbound.handler.mjs';
58
+ import { EmailOutboundHandler } from './handlers/api/email/email-outbound.handler.mjs';
59
+ import { StaticFileHandler } from './handlers/static-handler.mjs';
60
+
61
+ export interface StandardHandlersOptions {
62
+ /** Absolute path to the client SPA static assets directory. */
63
+ clientDir?: string;
64
+ }
65
+
66
+ /**
67
+ * Returns the standard pipeline array of ibgib HTTP request handlers for serve-gib.
68
+ */
69
+ export function getStandardServeGibHandlers(opts: StandardHandlersOptions = {}): ServeGibHandler<any, any>[] {
70
+ const handlers: ServeGibHandler<any, any>[] = [
71
+ new HealthHandler(),
72
+ new IbGibHandler(),
73
+ new KeystoneGenesisHandler(),
74
+ new KeystoneEvolveHandler(),
75
+ new KeystonePostHandler(),
76
+ new KeystoneGetHandler(),
77
+ new KeystoneLookupHandler(),
78
+ new KeystoneCheckEmailHandler(),
79
+ new SsoLinkHandler(),
80
+ new SsoLoginHandler(),
81
+ new SsoConfigHandler(),
82
+ new EmailInboundHandler(),
83
+ new EmailOutboundHandler(),
84
+ ];
85
+
86
+ if (opts.clientDir) {
87
+ handlers.push(new StaticFileHandler(opts.clientDir));
88
+ }
89
+
90
+ return handlers;
91
+ }
92
+
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Strict flatcase regex for individual tokens (username, role, deviceId, providerId).
3
+ * Lowercase alphanumeric characters only [a-z0-9], no hyphens or punctuation.
4
+ */
5
+ export const FLATCASE_TOKEN_REGEXP = /^[a-z0-9]+$/;
6
+
7
+ /**
8
+ * Validates if a string token is strict flatcase ([a-z0-9]+).
9
+ */
10
+ export function validateFlatcaseToken(token: string): boolean {
11
+ if (!token || typeof token !== 'string') { return false; }
12
+ return FLATCASE_TOKEN_REGEXP.test(token);
13
+ }
14
+
15
+ /**
16
+ * Sanitizes an input string to strict flatcase ([a-z0-9]).
17
+ */
18
+ export function sanitizeToken(input: string): string {
19
+ if (!input || typeof input !== 'string') { return ''; }
20
+ return input.toLowerCase().replace(/[^a-z0-9]/g, '');
21
+ }
22
+
23
+ /**
24
+ * Keystone Name Schema validation result.
25
+ */
26
+ export interface KeystoneNameSchemaResult {
27
+ valid: boolean;
28
+ type?: 'primary' | 'delegate';
29
+ username?: string;
30
+ role?: string;
31
+ deviceIdOrProviderId?: string;
32
+ error?: string;
33
+ }
34
+
35
+ /**
36
+ * Validates a keystone name string against the naming conventions:
37
+ * 1. Primary identity: `[username]` (e.g. `alice`)
38
+ * 2. Delegate: `[username]-[role]-[deviceIdOrProviderId]` (e.g. `alice-sync-browsera` or `alice-sync-google`)
39
+ *
40
+ * Enforces strict flatcase on all inner tokens (`[a-z0-9]+`).
41
+ */
42
+ export function validateKeystoneNameSchema(name: string): KeystoneNameSchemaResult {
43
+ if (!name || typeof name !== 'string') {
44
+ return { valid: false, error: 'Keystone name must be a non-empty string.' };
45
+ }
46
+
47
+ const parts = name.split('-');
48
+ if (parts.length === 1) {
49
+ const username = parts[0];
50
+ if (!validateFlatcaseToken(username)) {
51
+ return { valid: false, error: `Invalid primary username token '${username}'. Must be flatcase [a-z0-9]+.` };
52
+ }
53
+ return { valid: true, type: 'primary', username };
54
+ } else if (parts.length === 3) {
55
+ const [username, role, deviceIdOrProviderId] = parts;
56
+ if (!validateFlatcaseToken(username)) {
57
+ return { valid: false, error: `Invalid username token '${username}'. Must be flatcase [a-z0-9]+.` };
58
+ }
59
+ if (!validateFlatcaseToken(role)) {
60
+ return { valid: false, error: `Invalid role token '${role}'. Must be flatcase [a-z0-9]+.` };
61
+ }
62
+ if (!validateFlatcaseToken(deviceIdOrProviderId)) {
63
+ return { valid: false, error: `Invalid deviceId/providerId token '${deviceIdOrProviderId}'. Must be flatcase [a-z0-9]+.` };
64
+ }
65
+ return { valid: true, type: 'delegate', username, role, deviceIdOrProviderId };
66
+ } else {
67
+ return {
68
+ valid: false,
69
+ error: `Invalid keystone name format '${name}'. Expected '[username]' or '[username]-[role]-[deviceId]' (3 hyphen-separated flatcase tokens).`
70
+ };
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Challenge Pool ID Schema validation result.
76
+ */
77
+ export interface ChallengePoolIdSchemaResult {
78
+ valid: boolean;
79
+ isForeign?: boolean;
80
+ who?: string;
81
+ what?: string;
82
+ providerId?: string;
83
+ error?: string;
84
+ }
85
+
86
+ /**
87
+ * Validates a challenge pool ID string against pool conventions:
88
+ * 1. Native/User-Owned pool: single flatcase word (e.g. `manage`, `default`, `revoke`, `sync`, `connect`).
89
+ * 2. Custodial/Foreign pool: `custodian-[what]-[providerId]` (e.g. `custodian-manage-google`, `custodian-revoke-github`).
90
+ */
91
+ export function validateChallengePoolIdSchema(poolId: string): ChallengePoolIdSchemaResult {
92
+ if (!poolId || typeof poolId !== 'string') {
93
+ return { valid: false, error: 'Pool ID must be a non-empty string.' };
94
+ }
95
+
96
+ const parts = poolId.split('-');
97
+ if (parts.length === 1) {
98
+ if (!validateFlatcaseToken(parts[0])) {
99
+ return { valid: false, error: `Invalid native pool ID '${poolId}'. Must be flatcase [a-z0-9]+.` };
100
+ }
101
+ return { valid: true, isForeign: false };
102
+ } else if (parts.length === 3) {
103
+ const [who, what, providerId] = parts;
104
+ if (who !== 'custodian') {
105
+ return { valid: false, error: `Invalid foreign pool 'who' token '${who}'. Must be 'custodian'.` };
106
+ }
107
+ if (!['manage', 'sync', 'revoke'].includes(what)) {
108
+ return { valid: false, error: `Invalid foreign pool 'what' token '${what}'. Must be 'manage', 'sync', or 'revoke'.` };
109
+ }
110
+ if (!validateFlatcaseToken(providerId)) {
111
+ return { valid: false, error: `Invalid foreign pool providerId token '${providerId}'. Must be flatcase [a-z0-9]+.` };
112
+ }
113
+ return { valid: true, isForeign: true, who, what, providerId };
114
+ } else {
115
+ return {
116
+ valid: false,
117
+ error: `Invalid challenge pool ID '${poolId}'. Expected single flatcase word or 'custodian-[what]-[providerId]'.`
118
+ };
119
+ }
120
+ }
@@ -0,0 +1,85 @@
1
+ import { respecfully, iReckon, ifWe } from '@ibgib/helper-gib/dist/respec-gib/respec-gib.mjs';
2
+ import {
3
+ validateFlatcaseToken,
4
+ sanitizeToken,
5
+ validateKeystoneNameSchema,
6
+ validateChallengePoolIdSchema,
7
+ } from './keystone-schema-helpers.mjs';
8
+
9
+ const sir = `[${import.meta.url}]`;
10
+
11
+ await respecfully(sir, 'Keystone Schema Helpers', async () => {
12
+
13
+ await ifWe(sir, 'validate flatcase tokens accurately', async () => {
14
+ iReckon(sir, validateFlatcaseToken('alice')).isGonnaBeTrue();
15
+ iReckon(sir, validateFlatcaseToken('bobbobbins')).isGonnaBeTrue();
16
+ iReckon(sir, validateFlatcaseToken('dev123')).isGonnaBeTrue();
17
+ iReckon(sir, validateFlatcaseToken('google')).isGonnaBeTrue();
18
+
19
+ // Invalid: hyphens, uppercase, spaces, special chars
20
+ iReckon(sir, validateFlatcaseToken('alice-bob')).isGonnaBeFalse();
21
+ iReckon(sir, validateFlatcaseToken('Alice')).isGonnaBeFalse();
22
+ iReckon(sir, validateFlatcaseToken('user_name')).isGonnaBeFalse();
23
+ iReckon(sir, validateFlatcaseToken('user@domain')).isGonnaBeFalse();
24
+ iReckon(sir, validateFlatcaseToken('')).isGonnaBeFalse();
25
+ });
26
+
27
+ await ifWe(sir, 'sanitize tokens to clean flatcase', async () => {
28
+ iReckon(sir, sanitizeToken('Alice_Bob-123!')).willEqual('alicebob123');
29
+ iReckon(sir, sanitizeToken('user.name@example.com')).willEqual('usernameexamplecom');
30
+ iReckon(sir, sanitizeToken('GOOGLE-auth')).willEqual('googleauth');
31
+ });
32
+
33
+ await ifWe(sir, 'validate primary and delegate keystone names', async () => {
34
+ // Happy path primary identity
35
+ const resPrimary = validateKeystoneNameSchema('alice');
36
+ iReckon(sir, resPrimary.valid).isGonnaBeTrue();
37
+ iReckon(sir, resPrimary.type).willEqual('primary');
38
+ iReckon(sir, resPrimary.username).willEqual('alice');
39
+
40
+ // Happy path local device delegate
41
+ const resDelegateDev = validateKeystoneNameSchema('alice-sync-dev123');
42
+ iReckon(sir, resDelegateDev.valid).isGonnaBeTrue();
43
+ iReckon(sir, resDelegateDev.type).willEqual('delegate');
44
+ iReckon(sir, resDelegateDev.username).willEqual('alice');
45
+ iReckon(sir, resDelegateDev.role).willEqual('sync');
46
+ iReckon(sir, resDelegateDev.deviceIdOrProviderId).willEqual('dev123');
47
+
48
+ // Happy path SSO custodial delegate
49
+ const resDelegateSSO = validateKeystoneNameSchema('alice-sync-google');
50
+ iReckon(sir, resDelegateSSO.valid).isGonnaBeTrue();
51
+ iReckon(sir, resDelegateSSO.type).willEqual('delegate');
52
+ iReckon(sir, resDelegateSSO.username).willEqual('alice');
53
+ iReckon(sir, resDelegateSSO.role).willEqual('sync');
54
+ iReckon(sir, resDelegateSSO.deviceIdOrProviderId).willEqual('google');
55
+
56
+ // Sad paths: invalid token casing or hyphen counts
57
+ iReckon(sir, validateKeystoneNameSchema('alice-sync-dev-123').valid).isGonnaBeFalse(); // 4 parts
58
+ iReckon(sir, validateKeystoneNameSchema('Alice-sync-dev123').valid).isGonnaBeFalse(); // Uppercase
59
+ iReckon(sir, validateKeystoneNameSchema('alice_bob').valid).isGonnaBeFalse(); // Underscore not allowed in flatcase token
60
+ });
61
+
62
+ await ifWe(sir, 'validate native and foreign challenge pool IDs', async () => {
63
+ // Happy path native pools
64
+ const resManage = validateChallengePoolIdSchema('manage');
65
+ iReckon(sir, resManage.valid).isGonnaBeTrue();
66
+ iReckon(sir, resManage.isForeign).isGonnaBeFalse();
67
+
68
+ const resDefault = validateChallengePoolIdSchema('default');
69
+ iReckon(sir, resDefault.valid).isGonnaBeTrue();
70
+ iReckon(sir, resDefault.isForeign).isGonnaBeFalse();
71
+
72
+ // Happy path custodial foreign pool
73
+ const resForeign = validateChallengePoolIdSchema('custodian-manage-google');
74
+ iReckon(sir, resForeign.valid).isGonnaBeTrue();
75
+ iReckon(sir, resForeign.isForeign).isGonnaBeTrue();
76
+ iReckon(sir, resForeign.who).willEqual('custodian');
77
+ iReckon(sir, resForeign.what).willEqual('manage');
78
+ iReckon(sir, resForeign.providerId).willEqual('google');
79
+
80
+ // Sad paths: invalid who/what/providerId
81
+ iReckon(sir, validateChallengePoolIdSchema('user-manage-google').valid).isGonnaBeFalse(); // who must be 'custodian'
82
+ iReckon(sir, validateChallengePoolIdSchema('custodian-invalidverb-google').valid).isGonnaBeFalse(); // invalid verb
83
+ iReckon(sir, validateChallengePoolIdSchema('custodian-manage-Google').valid).isGonnaBeFalse(); // non-flatcase providerId
84
+ });
85
+ });