@mappoh/nova 0.1.16

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 (383) hide show
  1. package/dist/animation/parallax.d.ts +23 -0
  2. package/dist/animation/parallax.d.ts.map +1 -0
  3. package/dist/animation/parallax.js +96 -0
  4. package/dist/animation/parallax.js.map +1 -0
  5. package/dist/animation/scroll-animate.d.ts +30 -0
  6. package/dist/animation/scroll-animate.d.ts.map +1 -0
  7. package/dist/animation/scroll-animate.js +65 -0
  8. package/dist/animation/scroll-animate.js.map +1 -0
  9. package/dist/animation/scroll-observer.d.ts +32 -0
  10. package/dist/animation/scroll-observer.d.ts.map +1 -0
  11. package/dist/animation/scroll-observer.js +63 -0
  12. package/dist/animation/scroll-observer.js.map +1 -0
  13. package/dist/animation/smooth-scroll.d.ts +47 -0
  14. package/dist/animation/smooth-scroll.d.ts.map +1 -0
  15. package/dist/animation/smooth-scroll.js +169 -0
  16. package/dist/animation/smooth-scroll.js.map +1 -0
  17. package/dist/animation/text-reveal.d.ts +30 -0
  18. package/dist/animation/text-reveal.d.ts.map +1 -0
  19. package/dist/animation/text-reveal.js +164 -0
  20. package/dist/animation/text-reveal.js.map +1 -0
  21. package/dist/animation/ticker.d.ts +32 -0
  22. package/dist/animation/ticker.d.ts.map +1 -0
  23. package/dist/animation/ticker.js +62 -0
  24. package/dist/animation/ticker.js.map +1 -0
  25. package/dist/canvas/dot-grid.d.ts +50 -0
  26. package/dist/canvas/dot-grid.d.ts.map +1 -0
  27. package/dist/canvas/dot-grid.js +123 -0
  28. package/dist/canvas/dot-grid.js.map +1 -0
  29. package/dist/canvas/noise.d.ts +33 -0
  30. package/dist/canvas/noise.d.ts.map +1 -0
  31. package/dist/canvas/noise.js +241 -0
  32. package/dist/canvas/noise.js.map +1 -0
  33. package/dist/canvas/particles.d.ts +44 -0
  34. package/dist/canvas/particles.d.ts.map +1 -0
  35. package/dist/canvas/particles.js +138 -0
  36. package/dist/canvas/particles.js.map +1 -0
  37. package/dist/canvas/sequence.d.ts +43 -0
  38. package/dist/canvas/sequence.d.ts.map +1 -0
  39. package/dist/canvas/sequence.js +162 -0
  40. package/dist/canvas/sequence.js.map +1 -0
  41. package/dist/component/bind.d.ts +25 -0
  42. package/dist/component/bind.d.ts.map +1 -0
  43. package/dist/component/bind.js +28 -0
  44. package/dist/component/bind.js.map +1 -0
  45. package/dist/component/component.d.ts +76 -0
  46. package/dist/component/component.d.ts.map +1 -0
  47. package/dist/component/component.js +219 -0
  48. package/dist/component/component.js.map +1 -0
  49. package/dist/component/connect.d.ts +60 -0
  50. package/dist/component/connect.d.ts.map +1 -0
  51. package/dist/component/connect.js +115 -0
  52. package/dist/component/connect.js.map +1 -0
  53. package/dist/component/html.d.ts +35 -0
  54. package/dist/component/html.d.ts.map +1 -0
  55. package/dist/component/html.js +51 -0
  56. package/dist/component/html.js.map +1 -0
  57. package/dist/component/hydrate.d.ts +37 -0
  58. package/dist/component/hydrate.d.ts.map +1 -0
  59. package/dist/component/hydrate.js +242 -0
  60. package/dist/component/hydrate.js.map +1 -0
  61. package/dist/component/index.d.ts +9 -0
  62. package/dist/component/index.d.ts.map +1 -0
  63. package/dist/component/index.js +6 -0
  64. package/dist/component/index.js.map +1 -0
  65. package/dist/component/template.d.ts +30 -0
  66. package/dist/component/template.d.ts.map +1 -0
  67. package/dist/component/template.js +469 -0
  68. package/dist/component/template.js.map +1 -0
  69. package/dist/css/gradient-text.d.ts +40 -0
  70. package/dist/css/gradient-text.d.ts.map +1 -0
  71. package/dist/css/gradient-text.js +90 -0
  72. package/dist/css/gradient-text.js.map +1 -0
  73. package/dist/css/index.d.ts +3 -0
  74. package/dist/css/index.d.ts.map +1 -0
  75. package/dist/css/index.js +2 -0
  76. package/dist/css/index.js.map +1 -0
  77. package/dist/devtools/devtools.d.ts +27 -0
  78. package/dist/devtools/devtools.d.ts.map +1 -0
  79. package/dist/devtools/devtools.js +237 -0
  80. package/dist/devtools/devtools.js.map +1 -0
  81. package/dist/devtools/index.d.ts +3 -0
  82. package/dist/devtools/index.d.ts.map +1 -0
  83. package/dist/devtools/index.js +2 -0
  84. package/dist/devtools/index.js.map +1 -0
  85. package/dist/drag/drag.d.ts +38 -0
  86. package/dist/drag/drag.d.ts.map +1 -0
  87. package/dist/drag/drag.js +181 -0
  88. package/dist/drag/drag.js.map +1 -0
  89. package/dist/drag/index.d.ts +3 -0
  90. package/dist/drag/index.d.ts.map +1 -0
  91. package/dist/drag/index.js +2 -0
  92. package/dist/drag/index.js.map +1 -0
  93. package/dist/dropdown/dropdown.d.ts +55 -0
  94. package/dist/dropdown/dropdown.d.ts.map +1 -0
  95. package/dist/dropdown/dropdown.js +314 -0
  96. package/dist/dropdown/dropdown.js.map +1 -0
  97. package/dist/dropdown/group.d.ts +18 -0
  98. package/dist/dropdown/group.d.ts.map +1 -0
  99. package/dist/dropdown/group.js +119 -0
  100. package/dist/dropdown/group.js.map +1 -0
  101. package/dist/dropdown/index.d.ts +5 -0
  102. package/dist/dropdown/index.d.ts.map +1 -0
  103. package/dist/dropdown/index.js +3 -0
  104. package/dist/dropdown/index.js.map +1 -0
  105. package/dist/forms/form-engine.d.ts +91 -0
  106. package/dist/forms/form-engine.d.ts.map +1 -0
  107. package/dist/forms/form-engine.js +228 -0
  108. package/dist/forms/form-engine.js.map +1 -0
  109. package/dist/forms/index.d.ts +3 -0
  110. package/dist/forms/index.d.ts.map +1 -0
  111. package/dist/forms/index.js +2 -0
  112. package/dist/forms/index.js.map +1 -0
  113. package/dist/forms/validators.d.ts +20 -0
  114. package/dist/forms/validators.d.ts.map +1 -0
  115. package/dist/forms/validators.js +82 -0
  116. package/dist/forms/validators.js.map +1 -0
  117. package/dist/gallery/gallery.d.ts +66 -0
  118. package/dist/gallery/gallery.d.ts.map +1 -0
  119. package/dist/gallery/gallery.js +347 -0
  120. package/dist/gallery/gallery.js.map +1 -0
  121. package/dist/gallery/index.d.ts +3 -0
  122. package/dist/gallery/index.d.ts.map +1 -0
  123. package/dist/gallery/index.js +2 -0
  124. package/dist/gallery/index.js.map +1 -0
  125. package/dist/gesture/gesture.d.ts +44 -0
  126. package/dist/gesture/gesture.d.ts.map +1 -0
  127. package/dist/gesture/gesture.js +152 -0
  128. package/dist/gesture/gesture.js.map +1 -0
  129. package/dist/gesture/index.d.ts +3 -0
  130. package/dist/gesture/index.d.ts.map +1 -0
  131. package/dist/gesture/index.js +2 -0
  132. package/dist/gesture/index.js.map +1 -0
  133. package/dist/http/http.d.ts +44 -0
  134. package/dist/http/http.d.ts.map +1 -0
  135. package/dist/http/http.js +135 -0
  136. package/dist/http/http.js.map +1 -0
  137. package/dist/http/index.d.ts +3 -0
  138. package/dist/http/index.d.ts.map +1 -0
  139. package/dist/http/index.js +2 -0
  140. package/dist/http/index.js.map +1 -0
  141. package/dist/i18n/i18n.d.ts +28 -0
  142. package/dist/i18n/i18n.d.ts.map +1 -0
  143. package/dist/i18n/i18n.js +84 -0
  144. package/dist/i18n/i18n.js.map +1 -0
  145. package/dist/i18n/index.d.ts +3 -0
  146. package/dist/i18n/index.d.ts.map +1 -0
  147. package/dist/i18n/index.js +2 -0
  148. package/dist/i18n/index.js.map +1 -0
  149. package/dist/image/effects.d.ts +33 -0
  150. package/dist/image/effects.d.ts.map +1 -0
  151. package/dist/image/effects.js +236 -0
  152. package/dist/image/effects.js.map +1 -0
  153. package/dist/image/image.d.ts +83 -0
  154. package/dist/image/image.d.ts.map +1 -0
  155. package/dist/image/image.js +236 -0
  156. package/dist/image/image.js.map +1 -0
  157. package/dist/image/index.d.ts +5 -0
  158. package/dist/image/index.d.ts.map +1 -0
  159. package/dist/image/index.js +3 -0
  160. package/dist/image/index.js.map +1 -0
  161. package/dist/interaction/index.d.ts +3 -0
  162. package/dist/interaction/index.d.ts.map +1 -0
  163. package/dist/interaction/index.js +2 -0
  164. package/dist/interaction/index.js.map +1 -0
  165. package/dist/interaction/tilt.d.ts +30 -0
  166. package/dist/interaction/tilt.d.ts.map +1 -0
  167. package/dist/interaction/tilt.js +131 -0
  168. package/dist/interaction/tilt.js.map +1 -0
  169. package/dist/lazy/index.d.ts +3 -0
  170. package/dist/lazy/index.d.ts.map +1 -0
  171. package/dist/lazy/index.js +2 -0
  172. package/dist/lazy/index.js.map +1 -0
  173. package/dist/lazy/lazy.d.ts +42 -0
  174. package/dist/lazy/lazy.d.ts.map +1 -0
  175. package/dist/lazy/lazy.js +80 -0
  176. package/dist/lazy/lazy.js.map +1 -0
  177. package/dist/modal/index.d.ts +3 -0
  178. package/dist/modal/index.d.ts.map +1 -0
  179. package/dist/modal/index.js +2 -0
  180. package/dist/modal/index.js.map +1 -0
  181. package/dist/modal/modal.d.ts +39 -0
  182. package/dist/modal/modal.d.ts.map +1 -0
  183. package/dist/modal/modal.js +174 -0
  184. package/dist/modal/modal.js.map +1 -0
  185. package/dist/router/index.d.ts +3 -0
  186. package/dist/router/index.d.ts.map +1 -0
  187. package/dist/router/index.js +2 -0
  188. package/dist/router/index.js.map +1 -0
  189. package/dist/router/router.d.ts +80 -0
  190. package/dist/router/router.d.ts.map +1 -0
  191. package/dist/router/router.js +256 -0
  192. package/dist/router/router.js.map +1 -0
  193. package/dist/router/speculate.d.ts +28 -0
  194. package/dist/router/speculate.d.ts.map +1 -0
  195. package/dist/router/speculate.js +36 -0
  196. package/dist/router/speculate.js.map +1 -0
  197. package/dist/search/fuzzy.d.ts +16 -0
  198. package/dist/search/fuzzy.d.ts.map +1 -0
  199. package/dist/search/fuzzy.js +77 -0
  200. package/dist/search/fuzzy.js.map +1 -0
  201. package/dist/search/index.d.ts +5 -0
  202. package/dist/search/index.d.ts.map +1 -0
  203. package/dist/search/index.js +3 -0
  204. package/dist/search/index.js.map +1 -0
  205. package/dist/search/search.d.ts +56 -0
  206. package/dist/search/search.d.ts.map +1 -0
  207. package/dist/search/search.js +540 -0
  208. package/dist/search/search.js.map +1 -0
  209. package/dist/search/wasm.d.ts +35 -0
  210. package/dist/search/wasm.d.ts.map +1 -0
  211. package/dist/search/wasm.js +51 -0
  212. package/dist/search/wasm.js.map +1 -0
  213. package/dist/security/cors.d.ts +61 -0
  214. package/dist/security/cors.d.ts.map +1 -0
  215. package/dist/security/cors.js +174 -0
  216. package/dist/security/cors.js.map +1 -0
  217. package/dist/security/csp.d.ts +49 -0
  218. package/dist/security/csp.d.ts.map +1 -0
  219. package/dist/security/csp.js +143 -0
  220. package/dist/security/csp.js.map +1 -0
  221. package/dist/security/csrf.d.ts +47 -0
  222. package/dist/security/csrf.d.ts.map +1 -0
  223. package/dist/security/csrf.js +122 -0
  224. package/dist/security/csrf.js.map +1 -0
  225. package/dist/security/encrypt.d.ts +64 -0
  226. package/dist/security/encrypt.d.ts.map +1 -0
  227. package/dist/security/encrypt.js +129 -0
  228. package/dist/security/encrypt.js.map +1 -0
  229. package/dist/security/index.d.ts +21 -0
  230. package/dist/security/index.d.ts.map +1 -0
  231. package/dist/security/index.js +11 -0
  232. package/dist/security/index.js.map +1 -0
  233. package/dist/security/rate-limit.d.ts +57 -0
  234. package/dist/security/rate-limit.d.ts.map +1 -0
  235. package/dist/security/rate-limit.js +222 -0
  236. package/dist/security/rate-limit.js.map +1 -0
  237. package/dist/security/rbac.d.ts +84 -0
  238. package/dist/security/rbac.d.ts.map +1 -0
  239. package/dist/security/rbac.js +164 -0
  240. package/dist/security/rbac.js.map +1 -0
  241. package/dist/security/sanitize.d.ts +44 -0
  242. package/dist/security/sanitize.d.ts.map +1 -0
  243. package/dist/security/sanitize.js +230 -0
  244. package/dist/security/sanitize.js.map +1 -0
  245. package/dist/security/secure-store.d.ts +44 -0
  246. package/dist/security/secure-store.d.ts.map +1 -0
  247. package/dist/security/secure-store.js +164 -0
  248. package/dist/security/secure-store.js.map +1 -0
  249. package/dist/security/session.d.ts +76 -0
  250. package/dist/security/session.d.ts.map +1 -0
  251. package/dist/security/session.js +251 -0
  252. package/dist/security/session.js.map +1 -0
  253. package/dist/security/sri.d.ts +66 -0
  254. package/dist/security/sri.d.ts.map +1 -0
  255. package/dist/security/sri.js +159 -0
  256. package/dist/security/sri.js.map +1 -0
  257. package/dist/shortcuts/index.d.ts +3 -0
  258. package/dist/shortcuts/index.d.ts.map +1 -0
  259. package/dist/shortcuts/index.js +2 -0
  260. package/dist/shortcuts/index.js.map +1 -0
  261. package/dist/shortcuts/shortcuts.d.ts +43 -0
  262. package/dist/shortcuts/shortcuts.d.ts.map +1 -0
  263. package/dist/shortcuts/shortcuts.js +141 -0
  264. package/dist/shortcuts/shortcuts.js.map +1 -0
  265. package/dist/ssr/index.d.ts +3 -0
  266. package/dist/ssr/index.d.ts.map +1 -0
  267. package/dist/ssr/index.js +2 -0
  268. package/dist/ssr/index.js.map +1 -0
  269. package/dist/ssr/ssr.d.ts +62 -0
  270. package/dist/ssr/ssr.d.ts.map +1 -0
  271. package/dist/ssr/ssr.js +132 -0
  272. package/dist/ssr/ssr.js.map +1 -0
  273. package/dist/state/index.d.ts +5 -0
  274. package/dist/state/index.d.ts.map +1 -0
  275. package/dist/state/index.js +3 -0
  276. package/dist/state/index.js.map +1 -0
  277. package/dist/state/persistent.d.ts +31 -0
  278. package/dist/state/persistent.d.ts.map +1 -0
  279. package/dist/state/persistent.js +132 -0
  280. package/dist/state/persistent.js.map +1 -0
  281. package/dist/state/store.d.ts +31 -0
  282. package/dist/state/store.d.ts.map +1 -0
  283. package/dist/state/store.js +107 -0
  284. package/dist/state/store.js.map +1 -0
  285. package/dist/store/index.d.ts +3 -0
  286. package/dist/store/index.d.ts.map +1 -0
  287. package/dist/store/index.js +2 -0
  288. package/dist/store/index.js.map +1 -0
  289. package/dist/store/store.d.ts +36 -0
  290. package/dist/store/store.d.ts.map +1 -0
  291. package/dist/store/store.js +175 -0
  292. package/dist/store/store.js.map +1 -0
  293. package/dist/supabase/auth.d.ts +28 -0
  294. package/dist/supabase/auth.d.ts.map +1 -0
  295. package/dist/supabase/auth.js +47 -0
  296. package/dist/supabase/auth.js.map +1 -0
  297. package/dist/supabase/client.d.ts +18 -0
  298. package/dist/supabase/client.d.ts.map +1 -0
  299. package/dist/supabase/client.js +36 -0
  300. package/dist/supabase/client.js.map +1 -0
  301. package/dist/supabase/realtime.d.ts +22 -0
  302. package/dist/supabase/realtime.d.ts.map +1 -0
  303. package/dist/supabase/realtime.js +51 -0
  304. package/dist/supabase/realtime.js.map +1 -0
  305. package/dist/sw/index.d.ts +3 -0
  306. package/dist/sw/index.d.ts.map +1 -0
  307. package/dist/sw/index.js +2 -0
  308. package/dist/sw/index.js.map +1 -0
  309. package/dist/sw/sw.d.ts +49 -0
  310. package/dist/sw/sw.d.ts.map +1 -0
  311. package/dist/sw/sw.js +125 -0
  312. package/dist/sw/sw.js.map +1 -0
  313. package/dist/tabs/index.d.ts +3 -0
  314. package/dist/tabs/index.d.ts.map +1 -0
  315. package/dist/tabs/index.js +2 -0
  316. package/dist/tabs/index.js.map +1 -0
  317. package/dist/tabs/tabs.d.ts +34 -0
  318. package/dist/tabs/tabs.d.ts.map +1 -0
  319. package/dist/tabs/tabs.js +173 -0
  320. package/dist/tabs/tabs.js.map +1 -0
  321. package/dist/test/index.d.ts +3 -0
  322. package/dist/test/index.d.ts.map +1 -0
  323. package/dist/test/index.js +2 -0
  324. package/dist/test/index.js.map +1 -0
  325. package/dist/test/test.d.ts +37 -0
  326. package/dist/test/test.d.ts.map +1 -0
  327. package/dist/test/test.js +108 -0
  328. package/dist/test/test.js.map +1 -0
  329. package/dist/theme/index.d.ts +3 -0
  330. package/dist/theme/index.d.ts.map +1 -0
  331. package/dist/theme/index.js +2 -0
  332. package/dist/theme/index.js.map +1 -0
  333. package/dist/theme/theme.d.ts +40 -0
  334. package/dist/theme/theme.d.ts.map +1 -0
  335. package/dist/theme/theme.js +142 -0
  336. package/dist/theme/theme.js.map +1 -0
  337. package/dist/timeline/index.d.ts +3 -0
  338. package/dist/timeline/index.d.ts.map +1 -0
  339. package/dist/timeline/index.js +2 -0
  340. package/dist/timeline/index.js.map +1 -0
  341. package/dist/timeline/timeline.d.ts +44 -0
  342. package/dist/timeline/timeline.d.ts.map +1 -0
  343. package/dist/timeline/timeline.js +196 -0
  344. package/dist/timeline/timeline.js.map +1 -0
  345. package/dist/toast/index.d.ts +3 -0
  346. package/dist/toast/index.d.ts.map +1 -0
  347. package/dist/toast/index.js +2 -0
  348. package/dist/toast/index.js.map +1 -0
  349. package/dist/toast/toast.d.ts +31 -0
  350. package/dist/toast/toast.d.ts.map +1 -0
  351. package/dist/toast/toast.js +198 -0
  352. package/dist/toast/toast.js.map +1 -0
  353. package/dist/tooltip/index.d.ts +3 -0
  354. package/dist/tooltip/index.d.ts.map +1 -0
  355. package/dist/tooltip/index.js +2 -0
  356. package/dist/tooltip/index.js.map +1 -0
  357. package/dist/tooltip/tooltip.d.ts +27 -0
  358. package/dist/tooltip/tooltip.d.ts.map +1 -0
  359. package/dist/tooltip/tooltip.js +229 -0
  360. package/dist/tooltip/tooltip.js.map +1 -0
  361. package/dist/transition/index.d.ts +3 -0
  362. package/dist/transition/index.d.ts.map +1 -0
  363. package/dist/transition/index.js +2 -0
  364. package/dist/transition/index.js.map +1 -0
  365. package/dist/transition/transition.d.ts +31 -0
  366. package/dist/transition/transition.d.ts.map +1 -0
  367. package/dist/transition/transition.js +95 -0
  368. package/dist/transition/transition.js.map +1 -0
  369. package/dist/webgl/index.d.ts +3 -0
  370. package/dist/webgl/index.d.ts.map +1 -0
  371. package/dist/webgl/index.js +2 -0
  372. package/dist/webgl/index.js.map +1 -0
  373. package/dist/webgl/webgl.d.ts +49 -0
  374. package/dist/webgl/webgl.d.ts.map +1 -0
  375. package/dist/webgl/webgl.js +401 -0
  376. package/dist/webgl/webgl.js.map +1 -0
  377. package/package.json +269 -0
  378. package/styles/base/global.css +47 -0
  379. package/styles/base/reset.css +73 -0
  380. package/styles/tokens/colors.css +50 -0
  381. package/styles/tokens/spacing.css +46 -0
  382. package/styles/tokens/typography.css +37 -0
  383. package/styles/utilities/layout.css +46 -0
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Nova Engine — CORS (Cross-Origin Resource Sharing)
3
+ *
4
+ * Client-side CORS preflight validation, origin checking,
5
+ * request header management, and middleware-style guards
6
+ * for controlling cross-origin behavior.
7
+ */
8
+ export interface CORSOptions {
9
+ /** Allowed origins. Use '*' for any, or specific origins. Default: [location.origin] */
10
+ allowedOrigins?: string[] | '*';
11
+ /** Allowed HTTP methods. Default: ['GET','HEAD','POST','PUT','PATCH','DELETE','OPTIONS'] */
12
+ allowedMethods?: string[];
13
+ /** Allowed request headers. Default: common safe headers */
14
+ allowedHeaders?: string[];
15
+ /** Headers exposed to the client. Default: [] */
16
+ exposedHeaders?: string[];
17
+ /** Allow credentials (cookies, auth headers). Default: false */
18
+ credentials?: boolean;
19
+ /** Preflight cache duration in seconds. Default: 86400 (24h) */
20
+ maxAge?: number;
21
+ /** Called when an origin is blocked */
22
+ onBlocked?: (origin: string, reason: string) => void;
23
+ }
24
+ export interface CORSInstance {
25
+ /** Check if an origin is allowed */
26
+ isAllowed(origin: string): boolean;
27
+ /** Check if a method is allowed */
28
+ isMethodAllowed(method: string): boolean;
29
+ /** Check if a header is allowed */
30
+ isHeaderAllowed(header: string): boolean;
31
+ /** Validate a full request (origin + method + headers) */
32
+ validate(request: {
33
+ origin: string;
34
+ method: string;
35
+ headers?: string[];
36
+ }): CORSValidation;
37
+ /** Get CORS response headers for an origin */
38
+ headers(origin: string): Record<string, string>;
39
+ /** Get preflight (OPTIONS) response headers */
40
+ preflightHeaders(origin: string, requestMethod?: string, requestHeaders?: string[]): Record<string, string>;
41
+ /** Wrap fetch with CORS-aware defaults */
42
+ fetch(url: string, init?: RequestInit): Promise<Response>;
43
+ /** Add an origin to the allowlist at runtime */
44
+ addOrigin(origin: string): void;
45
+ /** Remove an origin from the allowlist */
46
+ removeOrigin(origin: string): void;
47
+ /** Get current configuration */
48
+ config(): Readonly<CORSOptions>;
49
+ }
50
+ export interface CORSValidation {
51
+ allowed: boolean;
52
+ reason?: string;
53
+ headers: Record<string, string>;
54
+ }
55
+ /** Check if a request would trigger a CORS preflight. */
56
+ export declare function wouldPreflight(method: string, headers?: Record<string, string>): boolean;
57
+ /** Parse an origin from a URL string. */
58
+ export declare function parseOrigin(url: string): string | null;
59
+ /** Create a CORS configuration instance. */
60
+ export declare function createCORS(options?: CORSOptions): CORSInstance;
61
+ //# sourceMappingURL=cors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../../src/security/cors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,WAAW;IAC1B,wFAAwF;IACxF,cAAc,CAAC,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;IAChC,4FAA4F;IAC5F,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,4DAA4D;IAC5D,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,iDAAiD;IACjD,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,gEAAgE;IAChE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACtD;AAED,MAAM,WAAW,YAAY;IAC3B,oCAAoC;IACpC,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IACnC,mCAAmC;IACnC,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IACzC,mCAAmC;IACnC,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IACzC,0DAA0D;IAC1D,QAAQ,CAAC,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,cAAc,CAAC;IAC1F,8CAA8C;IAC9C,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChD,+CAA+C;IAC/C,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5G,0CAA0C;IAC1C,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC1D,gDAAgD;IAChD,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,0CAA0C;IAC1C,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,gCAAgC;IAChC,MAAM,IAAI,QAAQ,CAAC,WAAW,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAyBD,yDAAyD;AACzD,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAcxF;AAED,yCAAyC;AACzC,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOtD;AAED,4CAA4C;AAC5C,wBAAgB,UAAU,CAAC,OAAO,GAAE,WAAgB,GAAG,YAAY,CA2IlE"}
@@ -0,0 +1,174 @@
1
+ /**
2
+ * Nova Engine — CORS (Cross-Origin Resource Sharing)
3
+ *
4
+ * Client-side CORS preflight validation, origin checking,
5
+ * request header management, and middleware-style guards
6
+ * for controlling cross-origin behavior.
7
+ */
8
+ const DEFAULT_ALLOWED_HEADERS = [
9
+ 'Accept',
10
+ 'Accept-Language',
11
+ 'Content-Language',
12
+ 'Content-Type',
13
+ 'Authorization',
14
+ 'X-Requested-With',
15
+ 'X-CSRF-Token',
16
+ ];
17
+ const DEFAULT_METHODS = ['GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'];
18
+ // Simple headers that don't trigger a preflight
19
+ const SIMPLE_HEADERS = new Set([
20
+ 'accept', 'accept-language', 'content-language', 'content-type',
21
+ ]);
22
+ const SIMPLE_CONTENT_TYPES = new Set([
23
+ 'application/x-www-form-urlencoded',
24
+ 'multipart/form-data',
25
+ 'text/plain',
26
+ ]);
27
+ /** Check if a request would trigger a CORS preflight. */
28
+ export function wouldPreflight(method, headers) {
29
+ // Non-simple methods trigger preflight
30
+ if (!['GET', 'HEAD', 'POST'].includes(method.toUpperCase()))
31
+ return true;
32
+ if (headers) {
33
+ for (const [key, value] of Object.entries(headers)) {
34
+ const lower = key.toLowerCase();
35
+ if (!SIMPLE_HEADERS.has(lower))
36
+ return true;
37
+ // Content-Type must be a simple type
38
+ if (lower === 'content-type' && !SIMPLE_CONTENT_TYPES.has(value.toLowerCase()))
39
+ return true;
40
+ }
41
+ }
42
+ return false;
43
+ }
44
+ /** Parse an origin from a URL string. */
45
+ export function parseOrigin(url) {
46
+ try {
47
+ const parsed = new URL(url);
48
+ return parsed.origin;
49
+ }
50
+ catch {
51
+ return null;
52
+ }
53
+ }
54
+ /** Create a CORS configuration instance. */
55
+ export function createCORS(options = {}) {
56
+ const allowedOrigins = options.allowedOrigins === '*'
57
+ ? '*'
58
+ : new Set(options.allowedOrigins ?? [location.origin]);
59
+ const allowedMethods = new Set((options.allowedMethods ?? DEFAULT_METHODS).map(m => m.toUpperCase()));
60
+ const allowedHeaders = new Set((options.allowedHeaders ?? DEFAULT_ALLOWED_HEADERS).map(h => h.toLowerCase()));
61
+ const exposedHeaders = options.exposedHeaders ?? [];
62
+ const credentials = options.credentials ?? false;
63
+ const maxAge = options.maxAge ?? 86400;
64
+ const onBlocked = options.onBlocked;
65
+ function checkOrigin(origin) {
66
+ if (allowedOrigins === '*')
67
+ return true;
68
+ return allowedOrigins.has(origin);
69
+ }
70
+ function checkMethod(method) {
71
+ return allowedMethods.has(method.toUpperCase());
72
+ }
73
+ function checkHeader(header) {
74
+ return allowedHeaders.has(header.toLowerCase());
75
+ }
76
+ function block(origin, reason) {
77
+ onBlocked?.(origin, reason);
78
+ return { allowed: false, reason, headers: {} };
79
+ }
80
+ const instance = {
81
+ isAllowed(origin) {
82
+ return checkOrigin(origin);
83
+ },
84
+ isMethodAllowed(method) {
85
+ return checkMethod(method);
86
+ },
87
+ isHeaderAllowed(header) {
88
+ return checkHeader(header);
89
+ },
90
+ validate(request) {
91
+ if (!checkOrigin(request.origin)) {
92
+ return block(request.origin, `Origin '${request.origin}' is not allowed`);
93
+ }
94
+ if (!checkMethod(request.method)) {
95
+ return block(request.origin, `Method '${request.method}' is not allowed`);
96
+ }
97
+ if (request.headers) {
98
+ for (const h of request.headers) {
99
+ if (!checkHeader(h)) {
100
+ return block(request.origin, `Header '${h}' is not allowed`);
101
+ }
102
+ }
103
+ }
104
+ return {
105
+ allowed: true,
106
+ headers: instance.headers(request.origin),
107
+ };
108
+ },
109
+ headers(origin) {
110
+ if (!checkOrigin(origin))
111
+ return {};
112
+ const h = {};
113
+ // When credentials are true, must echo specific origin (not *)
114
+ if (allowedOrigins === '*' && !credentials) {
115
+ h['Access-Control-Allow-Origin'] = '*';
116
+ }
117
+ else {
118
+ h['Access-Control-Allow-Origin'] = origin;
119
+ h['Vary'] = 'Origin';
120
+ }
121
+ if (credentials) {
122
+ h['Access-Control-Allow-Credentials'] = 'true';
123
+ }
124
+ if (exposedHeaders.length > 0) {
125
+ h['Access-Control-Expose-Headers'] = exposedHeaders.join(', ');
126
+ }
127
+ return h;
128
+ },
129
+ preflightHeaders(origin, _requestMethod, requestHeaders) {
130
+ const h = instance.headers(origin);
131
+ if (Object.keys(h).length === 0)
132
+ return h; // Origin blocked
133
+ h['Access-Control-Allow-Methods'] = [...allowedMethods].join(', ');
134
+ h['Access-Control-Allow-Headers'] = requestHeaders?.join(', ') ?? [...allowedHeaders].join(', ');
135
+ h['Access-Control-Max-Age'] = String(maxAge);
136
+ return h;
137
+ },
138
+ async fetch(url, init) {
139
+ const fetchInit = { ...init };
140
+ if (credentials) {
141
+ fetchInit.credentials = 'include';
142
+ }
143
+ // Ensure mode is cors for cross-origin requests
144
+ const targetOrigin = parseOrigin(url);
145
+ if (targetOrigin && targetOrigin !== location.origin) {
146
+ fetchInit.mode = 'cors';
147
+ }
148
+ return globalThis.fetch(url, fetchInit);
149
+ },
150
+ addOrigin(origin) {
151
+ if (allowedOrigins !== '*') {
152
+ allowedOrigins.add(origin);
153
+ }
154
+ },
155
+ removeOrigin(origin) {
156
+ if (allowedOrigins !== '*') {
157
+ allowedOrigins.delete(origin);
158
+ }
159
+ },
160
+ config() {
161
+ return Object.freeze({
162
+ allowedOrigins: allowedOrigins === '*' ? '*' : [...allowedOrigins],
163
+ allowedMethods: [...allowedMethods],
164
+ allowedHeaders: [...allowedHeaders],
165
+ exposedHeaders: [...exposedHeaders],
166
+ credentials,
167
+ maxAge,
168
+ onBlocked,
169
+ });
170
+ },
171
+ };
172
+ return instance;
173
+ }
174
+ //# sourceMappingURL=cors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cors.js","sourceRoot":"","sources":["../../src/security/cors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Nova Engine — Content Security Policy Builder
3
+ *
4
+ * Fluent API for constructing CSP headers and meta tags.
5
+ * Supports all CSP Level 3 directives, nonce generation,
6
+ * and report-only mode.
7
+ */
8
+ export type CSPDirective = 'default-src' | 'script-src' | 'style-src' | 'img-src' | 'font-src' | 'connect-src' | 'media-src' | 'object-src' | 'frame-src' | 'child-src' | 'worker-src' | 'manifest-src' | 'base-uri' | 'form-action' | 'frame-ancestors' | 'navigate-to' | 'report-uri' | 'report-to' | 'upgrade-insecure-requests' | 'block-all-mixed-content' | 'plugin-types' | 'sandbox' | 'require-trusted-types-for' | 'trusted-types';
9
+ export type CSPValue = "'self'" | "'none'" | "'unsafe-inline'" | "'unsafe-eval'" | "'strict-dynamic'" | "'unsafe-hashes'" | "'wasm-unsafe-eval'" | `'nonce-${string}'` | `'sha256-${string}'` | `'sha384-${string}'` | `'sha512-${string}'` | 'data:' | 'blob:' | 'mediastream:' | 'filesystem:' | 'https:' | 'http:' | '*' | string;
10
+ export interface CSPBuilder {
11
+ /** Add values to a directive */
12
+ add(directive: CSPDirective, ...values: CSPValue[]): CSPBuilder;
13
+ /** Set a directive (replaces existing values) */
14
+ set(directive: CSPDirective, ...values: CSPValue[]): CSPBuilder;
15
+ /** Remove a directive entirely */
16
+ remove(directive: CSPDirective): CSPBuilder;
17
+ /** Generate a nonce and add it to script-src and/or style-src */
18
+ nonce(directives?: CSPDirective[]): string;
19
+ /** Add a hash for inline script/style */
20
+ hash(directive: 'script-src' | 'style-src', algorithm: 'sha256' | 'sha384' | 'sha512', hash: string): CSPBuilder;
21
+ /** Enable report-only mode */
22
+ reportOnly(): CSPBuilder;
23
+ /** Set report-to endpoint */
24
+ reportTo(endpoint: string): CSPBuilder;
25
+ /** Build the CSP header string */
26
+ toString(): string;
27
+ /** Get the header name (Content-Security-Policy or Content-Security-Policy-Report-Only) */
28
+ headerName(): string;
29
+ /** Inject as a meta tag into the document */
30
+ injectMeta(): HTMLMetaElement;
31
+ /** Remove the injected meta tag */
32
+ removeMeta(): void;
33
+ /** Get all generated nonces */
34
+ nonces(): string[];
35
+ /** Clone this builder */
36
+ clone(): CSPBuilder;
37
+ }
38
+ /** Preset CSP policies for common use cases. */
39
+ export declare const CSPPresets: {
40
+ /** Strict: self only, no inline, no eval */
41
+ readonly strict: () => CSPBuilder;
42
+ /** Standard: self with HTTPS images and common CDNs */
43
+ readonly standard: () => CSPBuilder;
44
+ /** API app: self + specific API origins */
45
+ readonly api: (...origins: string[]) => CSPBuilder;
46
+ };
47
+ /** Create a Content Security Policy builder. */
48
+ export declare function createCSP(): CSPBuilder;
49
+ //# sourceMappingURL=csp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csp.d.ts","sourceRoot":"","sources":["../../src/security/csp.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,YAAY,GACpB,aAAa,GAAG,YAAY,GAAG,WAAW,GAAG,SAAS,GACtD,UAAU,GAAG,aAAa,GAAG,WAAW,GAAG,YAAY,GACvD,WAAW,GAAG,WAAW,GAAG,YAAY,GAAG,cAAc,GACzD,UAAU,GAAG,aAAa,GAAG,iBAAiB,GAC9C,aAAa,GAAG,YAAY,GAAG,WAAW,GAC1C,2BAA2B,GAAG,yBAAyB,GACvD,cAAc,GAAG,SAAS,GAAG,2BAA2B,GACxD,eAAe,CAAC;AAEpB,MAAM,MAAM,QAAQ,GAChB,QAAQ,GAAG,QAAQ,GAAG,iBAAiB,GAAG,eAAe,GACzD,kBAAkB,GAAG,iBAAiB,GAAG,oBAAoB,GAC7D,UAAU,MAAM,GAAG,GAAG,WAAW,MAAM,GAAG,GAAG,WAAW,MAAM,GAAG,GAAG,WAAW,MAAM,GAAG,GACxF,OAAO,GAAG,OAAO,GAAG,cAAc,GAAG,aAAa,GAClD,QAAQ,GAAG,OAAO,GAAG,GAAG,GACxB,MAAM,CAAC;AAEX,MAAM,WAAW,UAAU;IACzB,gCAAgC;IAChC,GAAG,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,MAAM,EAAE,QAAQ,EAAE,GAAG,UAAU,CAAC;IAChE,iDAAiD;IACjD,GAAG,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,MAAM,EAAE,QAAQ,EAAE,GAAG,UAAU,CAAC;IAChE,kCAAkC;IAClC,MAAM,CAAC,SAAS,EAAE,YAAY,GAAG,UAAU,CAAC;IAC5C,iEAAiE;IACjE,KAAK,CAAC,UAAU,CAAC,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC;IAC3C,yCAAyC;IACzC,IAAI,CAAC,SAAS,EAAE,YAAY,GAAG,WAAW,EAAE,SAAS,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,CAAC;IACjH,8BAA8B;IAC9B,UAAU,IAAI,UAAU,CAAC;IACzB,6BAA6B;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAAC;IACvC,kCAAkC;IAClC,QAAQ,IAAI,MAAM,CAAC;IACnB,2FAA2F;IAC3F,UAAU,IAAI,MAAM,CAAC;IACrB,6CAA6C;IAC7C,UAAU,IAAI,eAAe,CAAC;IAC9B,mCAAmC;IACnC,UAAU,IAAI,IAAI,CAAC;IACnB,+BAA+B;IAC/B,MAAM,IAAI,MAAM,EAAE,CAAC;IACnB,yBAAyB;IACzB,KAAK,IAAI,UAAU,CAAC;CACrB;AAED,gDAAgD;AAChD,eAAO,MAAM,UAAU;IACrB,4CAA4C;2BAClC,UAAU;IAapB,uDAAuD;6BAC3C,UAAU;IAWtB,2CAA2C;+BAC3B,MAAM,EAAE,KAAG,UAAU;CAW7B,CAAC;AAWX,gDAAgD;AAChD,wBAAgB,SAAS,IAAI,UAAU,CAiGtC"}
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Nova Engine — Content Security Policy Builder
3
+ *
4
+ * Fluent API for constructing CSP headers and meta tags.
5
+ * Supports all CSP Level 3 directives, nonce generation,
6
+ * and report-only mode.
7
+ */
8
+ /** Preset CSP policies for common use cases. */
9
+ export const CSPPresets = {
10
+ /** Strict: self only, no inline, no eval */
11
+ strict() {
12
+ return createCSP()
13
+ .set('default-src', "'none'")
14
+ .set('script-src', "'self'")
15
+ .set('style-src', "'self'")
16
+ .set('img-src', "'self'")
17
+ .set('font-src', "'self'")
18
+ .set('connect-src', "'self'")
19
+ .set('base-uri', "'self'")
20
+ .set('form-action', "'self'")
21
+ .set('frame-ancestors', "'none'");
22
+ },
23
+ /** Standard: self with HTTPS images and common CDNs */
24
+ standard() {
25
+ return createCSP()
26
+ .set('default-src', "'self'")
27
+ .set('script-src', "'self'")
28
+ .set('style-src', "'self'", "'unsafe-inline'")
29
+ .set('img-src', "'self'", 'https:', 'data:')
30
+ .set('font-src', "'self'", 'https:')
31
+ .set('connect-src', "'self'", 'https:')
32
+ .set('frame-ancestors', "'self'");
33
+ },
34
+ /** API app: self + specific API origins */
35
+ api(...origins) {
36
+ return createCSP()
37
+ .set('default-src', "'none'")
38
+ .set('script-src', "'self'")
39
+ .set('style-src', "'self'")
40
+ .set('img-src', "'self'", 'data:')
41
+ .set('font-src', "'self'")
42
+ .set('connect-src', "'self'", ...origins)
43
+ .set('base-uri', "'self'")
44
+ .set('form-action', "'self'");
45
+ },
46
+ };
47
+ function generateNonce() {
48
+ const bytes = new Uint8Array(16);
49
+ crypto.getRandomValues(bytes);
50
+ // Base64 encode
51
+ return btoa(String.fromCharCode(...bytes));
52
+ }
53
+ const META_ID = 'nova-csp-meta';
54
+ /** Create a Content Security Policy builder. */
55
+ export function createCSP() {
56
+ const directives = new Map();
57
+ let isReportOnly = false;
58
+ const generatedNonces = [];
59
+ let metaEl = null;
60
+ const builder = {
61
+ add(directive, ...values) {
62
+ if (!directives.has(directive))
63
+ directives.set(directive, new Set());
64
+ const set = directives.get(directive);
65
+ for (const v of values)
66
+ set.add(v);
67
+ return builder;
68
+ },
69
+ set(directive, ...values) {
70
+ directives.set(directive, new Set(values));
71
+ return builder;
72
+ },
73
+ remove(directive) {
74
+ directives.delete(directive);
75
+ return builder;
76
+ },
77
+ nonce(dirs) {
78
+ const n = generateNonce();
79
+ generatedNonces.push(n);
80
+ const targets = dirs ?? ['script-src', 'style-src'];
81
+ for (const d of targets) {
82
+ builder.add(d, `'nonce-${n}'`);
83
+ }
84
+ return n;
85
+ },
86
+ hash(directive, algorithm, hash) {
87
+ return builder.add(directive, `'${algorithm}-${hash}'`);
88
+ },
89
+ reportOnly() {
90
+ isReportOnly = true;
91
+ return builder;
92
+ },
93
+ reportTo(endpoint) {
94
+ return builder.set('report-to', endpoint);
95
+ },
96
+ toString() {
97
+ const parts = [];
98
+ for (const [directive, values] of directives) {
99
+ if (values.size === 0) {
100
+ parts.push(directive);
101
+ }
102
+ else {
103
+ parts.push(`${directive} ${[...values].join(' ')}`);
104
+ }
105
+ }
106
+ return parts.join('; ');
107
+ },
108
+ headerName() {
109
+ return isReportOnly ? 'Content-Security-Policy-Report-Only' : 'Content-Security-Policy';
110
+ },
111
+ injectMeta() {
112
+ builder.removeMeta();
113
+ metaEl = document.createElement('meta');
114
+ metaEl.id = META_ID;
115
+ metaEl.setAttribute('http-equiv', isReportOnly ? 'Content-Security-Policy-Report-Only' : 'Content-Security-Policy');
116
+ metaEl.setAttribute('content', builder.toString());
117
+ document.head.appendChild(metaEl);
118
+ return metaEl;
119
+ },
120
+ removeMeta() {
121
+ if (metaEl) {
122
+ metaEl.remove();
123
+ metaEl = null;
124
+ }
125
+ // Also remove any previously injected
126
+ document.getElementById(META_ID)?.remove();
127
+ },
128
+ nonces() {
129
+ return [...generatedNonces];
130
+ },
131
+ clone() {
132
+ const cloned = createCSP();
133
+ for (const [directive, values] of directives) {
134
+ cloned.set(directive, ...[...values]);
135
+ }
136
+ if (isReportOnly)
137
+ cloned.reportOnly();
138
+ return cloned;
139
+ },
140
+ };
141
+ return builder;
142
+ }
143
+ //# sourceMappingURL=csp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csp.js","sourceRoot":"","sources":["../../src/security/csp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Nova Engine — CSRF Protection
3
+ *
4
+ * Token generation, meta tag injection, automatic attachment
5
+ * to fetch/XHR requests, and double-submit cookie pattern.
6
+ */
7
+ export interface CSRFOptions {
8
+ /** Token header name. Default: 'X-CSRF-Token' */
9
+ headerName?: string;
10
+ /** Meta tag name to read/write token. Default: 'csrf-token' */
11
+ metaName?: string;
12
+ /** Cookie name for double-submit pattern. Default: '_csrf' */
13
+ cookieName?: string;
14
+ /** Token byte length (before hex encoding). Default: 32 */
15
+ tokenLength?: number;
16
+ /** Auto-attach token to all fetch requests. Default: true */
17
+ autoAttach?: boolean;
18
+ /** HTTP methods to protect. Default: ['POST','PUT','PATCH','DELETE'] */
19
+ protectedMethods?: string[];
20
+ /** Domains to include (skip for cross-origin). Default: same-origin only */
21
+ allowedOrigins?: string[];
22
+ }
23
+ export interface CSRFInstance {
24
+ /** Get the current token */
25
+ getToken(): string;
26
+ /** Generate a new token */
27
+ rotate(): string;
28
+ /** Inject token into a meta tag */
29
+ injectMeta(): void;
30
+ /** Read token from existing meta tag */
31
+ readMeta(): string | null;
32
+ /** Set token as a cookie (double-submit pattern) */
33
+ setCookie(options?: {
34
+ path?: string;
35
+ sameSite?: string;
36
+ secure?: boolean;
37
+ }): void;
38
+ /** Validate a token against the stored one */
39
+ validate(token: string): boolean;
40
+ /** Get headers object for manual fetch calls */
41
+ headers(): Record<string, string>;
42
+ /** Destroy — remove auto-attach, meta tag, etc. */
43
+ destroy(): void;
44
+ }
45
+ /** Create a CSRF protection instance. */
46
+ export declare function createCSRF(options?: CSRFOptions): CSRFInstance;
47
+ //# sourceMappingURL=csrf.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csrf.d.ts","sourceRoot":"","sources":["../../src/security/csrf.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,WAAW;IAC1B,iDAAiD;IACjD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8DAA8D;IAC9D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6DAA6D;IAC7D,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,4EAA4E;IAC5E,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,4BAA4B;IAC5B,QAAQ,IAAI,MAAM,CAAC;IACnB,2BAA2B;IAC3B,MAAM,IAAI,MAAM,CAAC;IACjB,mCAAmC;IACnC,UAAU,IAAI,IAAI,CAAC;IACnB,wCAAwC;IACxC,QAAQ,IAAI,MAAM,GAAG,IAAI,CAAC;IAC1B,oDAAoD;IACpD,SAAS,CAAC,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IAClF,8CAA8C;IAC9C,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IACjC,gDAAgD;IAChD,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,mDAAmD;IACnD,OAAO,IAAI,IAAI,CAAC;CACjB;AAiBD,yCAAyC;AACzC,wBAAgB,UAAU,CAAC,OAAO,GAAE,WAAgB,GAAG,YAAY,CAqHlE"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Nova Engine — CSRF Protection
3
+ *
4
+ * Token generation, meta tag injection, automatic attachment
5
+ * to fetch/XHR requests, and double-submit cookie pattern.
6
+ */
7
+ function generateToken(length) {
8
+ const bytes = new Uint8Array(length);
9
+ crypto.getRandomValues(bytes);
10
+ return Array.from(bytes, b => b.toString(16).padStart(2, '0')).join('');
11
+ }
12
+ function isSameOrigin(url) {
13
+ try {
14
+ const parsed = new URL(url, window.location.origin);
15
+ return parsed.origin === window.location.origin;
16
+ }
17
+ catch {
18
+ return true; // relative URLs are same-origin
19
+ }
20
+ }
21
+ /** Create a CSRF protection instance. */
22
+ export function createCSRF(options = {}) {
23
+ const { headerName = 'X-CSRF-Token', metaName = 'csrf-token', cookieName = '_csrf', tokenLength = 32, autoAttach = true, protectedMethods = ['POST', 'PUT', 'PATCH', 'DELETE'], allowedOrigins = [], } = options;
24
+ let token = generateToken(tokenLength);
25
+ const protectedSet = new Set(protectedMethods.map(m => m.toUpperCase()));
26
+ const originsSet = new Set(allowedOrigins);
27
+ // Monkey-patch fetch for auto-attach
28
+ let originalFetch = null;
29
+ function shouldProtect(url, method) {
30
+ if (!protectedSet.has(method.toUpperCase()))
31
+ return false;
32
+ if (isSameOrigin(url))
33
+ return true;
34
+ if (originsSet.size > 0) {
35
+ try {
36
+ const parsed = new URL(url, window.location.origin);
37
+ return originsSet.has(parsed.origin);
38
+ }
39
+ catch {
40
+ return false;
41
+ }
42
+ }
43
+ return false;
44
+ }
45
+ if (autoAttach) {
46
+ originalFetch = globalThis.fetch;
47
+ globalThis.fetch = function patchedFetch(input, init) {
48
+ const url = typeof input === 'string' ? input : input instanceof URL ? input.href : input.url;
49
+ const method = init?.method ?? 'GET';
50
+ if (shouldProtect(url, method)) {
51
+ const headers = new Headers(init?.headers);
52
+ headers.set(headerName, token);
53
+ return originalFetch.call(globalThis, input, { ...init, headers });
54
+ }
55
+ return originalFetch.call(globalThis, input, init);
56
+ };
57
+ }
58
+ const instance = {
59
+ getToken() {
60
+ return token;
61
+ },
62
+ rotate() {
63
+ token = generateToken(tokenLength);
64
+ // Update meta tag if it exists
65
+ const meta = document.querySelector(`meta[name="${metaName}"]`);
66
+ if (meta)
67
+ meta.setAttribute('content', token);
68
+ return token;
69
+ },
70
+ injectMeta() {
71
+ let meta = document.querySelector(`meta[name="${metaName}"]`);
72
+ if (!meta) {
73
+ meta = document.createElement('meta');
74
+ meta.setAttribute('name', metaName);
75
+ document.head.appendChild(meta);
76
+ }
77
+ meta.setAttribute('content', token);
78
+ },
79
+ readMeta() {
80
+ const meta = document.querySelector(`meta[name="${metaName}"]`);
81
+ if (meta) {
82
+ const val = meta.getAttribute('content');
83
+ if (val)
84
+ token = val;
85
+ return val;
86
+ }
87
+ return null;
88
+ },
89
+ setCookie(opts) {
90
+ const path = opts?.path ?? '/';
91
+ const sameSite = opts?.sameSite ?? 'Strict';
92
+ const secure = opts?.secure ?? (location.protocol === 'https:');
93
+ let cookie = `${cookieName}=${token}; Path=${path}; SameSite=${sameSite}`;
94
+ if (secure)
95
+ cookie += '; Secure';
96
+ document.cookie = cookie;
97
+ },
98
+ validate(candidate) {
99
+ if (candidate.length !== token.length)
100
+ return false;
101
+ // Constant-time comparison to prevent timing attacks
102
+ let result = 0;
103
+ for (let i = 0; i < candidate.length; i++) {
104
+ result |= candidate.charCodeAt(i) ^ token.charCodeAt(i);
105
+ }
106
+ return result === 0;
107
+ },
108
+ headers() {
109
+ return { [headerName]: token };
110
+ },
111
+ destroy() {
112
+ if (originalFetch) {
113
+ globalThis.fetch = originalFetch;
114
+ originalFetch = null;
115
+ }
116
+ const meta = document.querySelector(`meta[name="${metaName}"]`);
117
+ meta?.remove();
118
+ },
119
+ };
120
+ return instance;
121
+ }
122
+ //# sourceMappingURL=csrf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csrf.js","sourceRoot":"","sources":["../../src/security/csrf.ts"],"names":[],"mappings":"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"}