@famir/database 0.0.2 → 0.0.4

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 (242) hide show
  1. package/README.md +187 -1
  2. package/dist/database.d.ts +0 -1
  3. package/dist/database.error.js +1 -1
  4. package/dist/database.error.js.map +1 -1
  5. package/dist/database.functions.d.ts +30 -25
  6. package/dist/database.functions.js +8 -8
  7. package/dist/database.functions.js.map +1 -1
  8. package/dist/database.js +0 -1
  9. package/dist/database.js.map +1 -1
  10. package/dist/database.keys.d.ts +2 -1
  11. package/dist/database.keys.js +6 -3
  12. package/dist/database.keys.js.map +1 -1
  13. package/dist/database.schemas.js +2 -2
  14. package/dist/database.schemas.js.map +1 -1
  15. package/dist/index.d.ts +1 -2
  16. package/dist/index.js +1 -2
  17. package/dist/index.js.map +1 -1
  18. package/dist/modules/base/index.js.map +1 -0
  19. package/dist/{repositories → modules}/base/redis-base.repository.d.ts +11 -9
  20. package/dist/modules/base/redis-base.repository.js +164 -0
  21. package/dist/modules/base/redis-base.repository.js.map +1 -0
  22. package/dist/{repositories → modules}/campaign/campaign.d.ts +4 -8
  23. package/dist/{repositories → modules}/campaign/campaign.functions.d.ts +7 -16
  24. package/dist/{repositories → modules}/campaign/campaign.functions.js +23 -36
  25. package/dist/modules/campaign/campaign.functions.js.map +1 -0
  26. package/dist/modules/campaign/campaign.js +3 -0
  27. package/dist/modules/campaign/campaign.js.map +1 -0
  28. package/dist/{models/campaign/campaign.d.ts → modules/campaign/campaign.models.d.ts} +3 -2
  29. package/dist/{models/campaign/campaign.js → modules/campaign/campaign.models.js} +6 -4
  30. package/dist/modules/campaign/campaign.models.js.map +1 -0
  31. package/dist/{repositories → modules}/campaign/campaign.schemas.d.ts +3 -2
  32. package/dist/modules/campaign/campaign.schemas.js +109 -0
  33. package/dist/modules/campaign/campaign.schemas.js.map +1 -0
  34. package/dist/{repositories → modules}/campaign/index.d.ts +1 -0
  35. package/dist/{repositories → modules}/campaign/index.js +1 -0
  36. package/dist/modules/campaign/index.js.map +1 -0
  37. package/dist/{repositories → modules}/campaign/redis-campaign.repository.d.ts +5 -6
  38. package/dist/{repositories → modules}/campaign/redis-campaign.repository.js +33 -34
  39. package/dist/modules/campaign/redis-campaign.repository.js.map +1 -0
  40. package/dist/modules/index.js.map +1 -0
  41. package/dist/{repositories → modules}/lure/index.d.ts +1 -0
  42. package/dist/{repositories → modules}/lure/index.js +1 -0
  43. package/dist/modules/lure/index.js.map +1 -0
  44. package/dist/{repositories → modules}/lure/lure.d.ts +1 -1
  45. package/dist/{repositories → modules}/lure/lure.functions.d.ts +2 -2
  46. package/dist/{repositories → modules}/lure/lure.functions.js +11 -11
  47. package/dist/modules/lure/lure.functions.js.map +1 -0
  48. package/dist/modules/lure/lure.js.map +1 -0
  49. package/dist/{models/lure/lure.js → modules/lure/lure.models.js} +1 -1
  50. package/dist/modules/lure/lure.models.js.map +1 -0
  51. package/dist/modules/lure/lure.schemas.js +32 -0
  52. package/dist/modules/lure/lure.schemas.js.map +1 -0
  53. package/dist/{repositories → modules}/lure/redis-lure.repository.d.ts +3 -3
  54. package/dist/{repositories → modules}/lure/redis-lure.repository.js +23 -10
  55. package/dist/modules/lure/redis-lure.repository.js.map +1 -0
  56. package/dist/{repositories → modules}/message/index.d.ts +1 -0
  57. package/dist/{repositories → modules}/message/index.js +1 -0
  58. package/dist/modules/message/index.js.map +1 -0
  59. package/dist/{repositories → modules}/message/message.d.ts +3 -3
  60. package/dist/{repositories → modules}/message/message.functions.d.ts +5 -4
  61. package/dist/{repositories → modules}/message/message.functions.js +12 -12
  62. package/dist/modules/message/message.functions.js.map +1 -0
  63. package/dist/modules/message/message.js.map +1 -0
  64. package/dist/{models/message/message.d.ts → modules/message/message.models.d.ts} +4 -4
  65. package/dist/{models/message/message.js → modules/message/message.models.js} +6 -6
  66. package/dist/modules/message/message.models.js.map +1 -0
  67. package/dist/modules/message/message.schemas.js +93 -0
  68. package/dist/modules/message/message.schemas.js.map +1 -0
  69. package/dist/{repositories → modules}/message/redis-message.repository.d.ts +6 -5
  70. package/dist/{repositories → modules}/message/redis-message.repository.js +17 -14
  71. package/dist/modules/message/redis-message.repository.js.map +1 -0
  72. package/dist/{repositories → modules}/proxy/index.d.ts +1 -0
  73. package/dist/{repositories → modules}/proxy/index.js +1 -0
  74. package/dist/modules/proxy/index.js.map +1 -0
  75. package/dist/{repositories → modules}/proxy/proxy.d.ts +1 -1
  76. package/dist/{repositories → modules}/proxy/proxy.functions.d.ts +2 -2
  77. package/dist/{repositories → modules}/proxy/proxy.functions.js +10 -10
  78. package/dist/modules/proxy/proxy.functions.js.map +1 -0
  79. package/dist/modules/proxy/proxy.js.map +1 -0
  80. package/dist/{models/proxy/proxy.js → modules/proxy/proxy.models.js} +1 -1
  81. package/dist/modules/proxy/proxy.models.js.map +1 -0
  82. package/dist/modules/proxy/proxy.schemas.js +23 -0
  83. package/dist/modules/proxy/proxy.schemas.js.map +1 -0
  84. package/dist/{repositories → modules}/proxy/redis-proxy.repository.d.ts +3 -3
  85. package/dist/{repositories → modules}/proxy/redis-proxy.repository.js +23 -10
  86. package/dist/modules/proxy/redis-proxy.repository.js.map +1 -0
  87. package/dist/{repositories → modules}/redirector/index.d.ts +1 -0
  88. package/dist/{repositories → modules}/redirector/index.js +1 -0
  89. package/dist/modules/redirector/index.js.map +1 -0
  90. package/dist/{repositories → modules}/redirector/redirector.d.ts +3 -1
  91. package/dist/{repositories → modules}/redirector/redirector.functions.d.ts +14 -3
  92. package/dist/{repositories → modules}/redirector/redirector.functions.js +38 -12
  93. package/dist/modules/redirector/redirector.functions.js.map +1 -0
  94. package/dist/modules/redirector/redirector.js.map +1 -0
  95. package/dist/{models/redirector/redirector.d.ts → modules/redirector/redirector.models.d.ts} +5 -1
  96. package/dist/{models/redirector/redirector.js → modules/redirector/redirector.models.js} +10 -2
  97. package/dist/modules/redirector/redirector.models.js.map +1 -0
  98. package/dist/modules/redirector/redirector.schemas.d.ts +7 -0
  99. package/dist/modules/redirector/redirector.schemas.js +51 -0
  100. package/dist/modules/redirector/redirector.schemas.js.map +1 -0
  101. package/dist/{repositories → modules}/redirector/redis-redirector.repository.d.ts +5 -3
  102. package/dist/{repositories → modules}/redirector/redis-redirector.repository.js +45 -9
  103. package/dist/modules/redirector/redis-redirector.repository.js.map +1 -0
  104. package/dist/{repositories → modules}/session/index.d.ts +1 -0
  105. package/dist/{repositories → modules}/session/index.js +1 -0
  106. package/dist/modules/session/index.js.map +1 -0
  107. package/dist/{repositories → modules}/session/redis-session.repository.d.ts +3 -3
  108. package/dist/{repositories → modules}/session/redis-session.repository.js +22 -13
  109. package/dist/modules/session/redis-session.repository.js.map +1 -0
  110. package/dist/{repositories → modules}/session/session.d.ts +1 -1
  111. package/dist/{repositories → modules}/session/session.functions.d.ts +3 -3
  112. package/dist/{repositories → modules}/session/session.functions.js +8 -8
  113. package/dist/modules/session/session.functions.js.map +1 -0
  114. package/dist/modules/session/session.js.map +1 -0
  115. package/dist/{models/session/session.d.ts → modules/session/session.models.d.ts} +6 -0
  116. package/dist/{models/session/session.js → modules/session/session.models.js} +1 -1
  117. package/dist/modules/session/session.models.js.map +1 -0
  118. package/dist/modules/session/session.schemas.d.ts +4 -0
  119. package/dist/modules/session/session.schemas.js +43 -0
  120. package/dist/modules/session/session.schemas.js.map +1 -0
  121. package/dist/{repositories → modules}/target/index.d.ts +1 -0
  122. package/dist/{repositories → modules}/target/index.js +1 -0
  123. package/dist/modules/target/index.js.map +1 -0
  124. package/dist/{repositories → modules}/target/redis-target.repository.d.ts +4 -4
  125. package/dist/{repositories → modules}/target/redis-target.repository.js +56 -35
  126. package/dist/modules/target/redis-target.repository.js.map +1 -0
  127. package/dist/{repositories → modules}/target/target.d.ts +2 -1
  128. package/dist/{repositories → modules}/target/target.functions.d.ts +15 -9
  129. package/dist/{repositories → modules}/target/target.functions.js +44 -38
  130. package/dist/modules/target/target.functions.js.map +1 -0
  131. package/dist/modules/target/target.js.map +1 -0
  132. package/dist/{models/target/target.d.ts → modules/target/target.models.d.ts} +6 -4
  133. package/dist/{models/target/target.js → modules/target/target.models.js} +11 -11
  134. package/dist/modules/target/target.models.js.map +1 -0
  135. package/dist/{repositories → modules}/target/target.schemas.d.ts +3 -1
  136. package/dist/modules/target/target.schemas.js +174 -0
  137. package/dist/modules/target/target.schemas.js.map +1 -0
  138. package/dist/redis-database-connector.d.ts +2 -1
  139. package/dist/redis-database-connector.js +12 -10
  140. package/dist/redis-database-connector.js.map +1 -1
  141. package/dist/redis-database-manager.d.ts +4 -3
  142. package/dist/redis-database-manager.js +16 -9
  143. package/dist/redis-database-manager.js.map +1 -1
  144. package/dist/redis-functions.d.ts +1 -1
  145. package/dist/redis-functions.js +30 -1455
  146. package/dist/redis-functions.js.map +1 -1
  147. package/package.json +17 -10
  148. package/dist/models/campaign/campaign.js.map +0 -1
  149. package/dist/models/campaign/index.d.ts +0 -1
  150. package/dist/models/campaign/index.js +0 -2
  151. package/dist/models/campaign/index.js.map +0 -1
  152. package/dist/models/index.d.ts +0 -7
  153. package/dist/models/index.js +0 -8
  154. package/dist/models/index.js.map +0 -1
  155. package/dist/models/lure/index.d.ts +0 -1
  156. package/dist/models/lure/index.js +0 -2
  157. package/dist/models/lure/index.js.map +0 -1
  158. package/dist/models/lure/lure.js.map +0 -1
  159. package/dist/models/message/index.d.ts +0 -1
  160. package/dist/models/message/index.js +0 -2
  161. package/dist/models/message/index.js.map +0 -1
  162. package/dist/models/message/message.js.map +0 -1
  163. package/dist/models/proxy/index.d.ts +0 -1
  164. package/dist/models/proxy/index.js +0 -2
  165. package/dist/models/proxy/index.js.map +0 -1
  166. package/dist/models/proxy/proxy.js.map +0 -1
  167. package/dist/models/redirector/index.d.ts +0 -1
  168. package/dist/models/redirector/index.js +0 -2
  169. package/dist/models/redirector/index.js.map +0 -1
  170. package/dist/models/redirector/redirector.js.map +0 -1
  171. package/dist/models/session/index.d.ts +0 -1
  172. package/dist/models/session/index.js +0 -2
  173. package/dist/models/session/index.js.map +0 -1
  174. package/dist/models/session/session.js.map +0 -1
  175. package/dist/models/target/index.d.ts +0 -1
  176. package/dist/models/target/index.js +0 -2
  177. package/dist/models/target/index.js.map +0 -1
  178. package/dist/models/target/target.js.map +0 -1
  179. package/dist/repositories/base/index.js.map +0 -1
  180. package/dist/repositories/base/redis-base.repository.js +0 -140
  181. package/dist/repositories/base/redis-base.repository.js.map +0 -1
  182. package/dist/repositories/campaign/campaign.functions.js.map +0 -1
  183. package/dist/repositories/campaign/campaign.js +0 -2
  184. package/dist/repositories/campaign/campaign.js.map +0 -1
  185. package/dist/repositories/campaign/campaign.schemas.js +0 -148
  186. package/dist/repositories/campaign/campaign.schemas.js.map +0 -1
  187. package/dist/repositories/campaign/index.js.map +0 -1
  188. package/dist/repositories/campaign/redis-campaign.repository.js.map +0 -1
  189. package/dist/repositories/index.js.map +0 -1
  190. package/dist/repositories/lure/index.js.map +0 -1
  191. package/dist/repositories/lure/lure.functions.js.map +0 -1
  192. package/dist/repositories/lure/lure.js.map +0 -1
  193. package/dist/repositories/lure/lure.schemas.js +0 -45
  194. package/dist/repositories/lure/lure.schemas.js.map +0 -1
  195. package/dist/repositories/lure/redis-lure.repository.js.map +0 -1
  196. package/dist/repositories/message/index.js.map +0 -1
  197. package/dist/repositories/message/message.functions.js.map +0 -1
  198. package/dist/repositories/message/message.js.map +0 -1
  199. package/dist/repositories/message/message.schemas.js +0 -160
  200. package/dist/repositories/message/message.schemas.js.map +0 -1
  201. package/dist/repositories/message/redis-message.repository.js.map +0 -1
  202. package/dist/repositories/proxy/index.js.map +0 -1
  203. package/dist/repositories/proxy/proxy.functions.js.map +0 -1
  204. package/dist/repositories/proxy/proxy.js.map +0 -1
  205. package/dist/repositories/proxy/proxy.schemas.js +0 -34
  206. package/dist/repositories/proxy/proxy.schemas.js.map +0 -1
  207. package/dist/repositories/proxy/redis-proxy.repository.js.map +0 -1
  208. package/dist/repositories/redirector/index.js.map +0 -1
  209. package/dist/repositories/redirector/redirector.functions.js.map +0 -1
  210. package/dist/repositories/redirector/redirector.js.map +0 -1
  211. package/dist/repositories/redirector/redirector.schemas.d.ts +0 -3
  212. package/dist/repositories/redirector/redirector.schemas.js +0 -51
  213. package/dist/repositories/redirector/redirector.schemas.js.map +0 -1
  214. package/dist/repositories/redirector/redis-redirector.repository.js.map +0 -1
  215. package/dist/repositories/session/index.js.map +0 -1
  216. package/dist/repositories/session/redis-session.repository.js.map +0 -1
  217. package/dist/repositories/session/session.functions.js.map +0 -1
  218. package/dist/repositories/session/session.js.map +0 -1
  219. package/dist/repositories/session/session.schemas.d.ts +0 -2
  220. package/dist/repositories/session/session.schemas.js +0 -44
  221. package/dist/repositories/session/session.schemas.js.map +0 -1
  222. package/dist/repositories/target/index.js.map +0 -1
  223. package/dist/repositories/target/redis-target.repository.js.map +0 -1
  224. package/dist/repositories/target/target.functions.js.map +0 -1
  225. package/dist/repositories/target/target.js.map +0 -1
  226. package/dist/repositories/target/target.schemas.js +0 -251
  227. package/dist/repositories/target/target.schemas.js.map +0 -1
  228. package/dist/{repositories → modules}/base/index.d.ts +0 -0
  229. package/dist/{repositories → modules}/base/index.js +0 -0
  230. package/dist/{repositories → modules}/index.d.ts +0 -0
  231. package/dist/{repositories → modules}/index.js +0 -0
  232. package/dist/{repositories → modules}/lure/lure.js +0 -0
  233. package/dist/{models/lure/lure.d.ts → modules/lure/lure.models.d.ts} +0 -0
  234. package/dist/{repositories → modules}/lure/lure.schemas.d.ts +1 -1
  235. package/dist/{repositories → modules}/message/message.js +0 -0
  236. package/dist/{repositories → modules}/message/message.schemas.d.ts +0 -0
  237. package/dist/{repositories → modules}/proxy/proxy.js +0 -0
  238. package/dist/{models/proxy/proxy.d.ts → modules/proxy/proxy.models.d.ts} +0 -0
  239. package/dist/{repositories → modules}/proxy/proxy.schemas.d.ts +1 -1
  240. /package/dist/{repositories → modules}/redirector/redirector.js +0 -0
  241. /package/dist/{repositories → modules}/session/session.js +0 -0
  242. /package/dist/{repositories → modules}/target/target.js +0 -0
package/README.md CHANGED
@@ -1,4 +1,190 @@
1
1
  # @famir/database
2
2
 
3
- Famir database infrastructure service.
3
+ [![npm version](https://img.shields.io/npm/v/@famir/database.svg)](https://www.npmjs.com/package/@famir/database)
4
+ [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
4
5
 
6
+ Database infrastructure service.
7
+
8
+ ## Installation
9
+
10
+ ```sh
11
+ npm install @famir/database
12
+ ```
13
+
14
+ ## An Architectural Overview
15
+
16
+ This document describes the core data models used by the Famir framework from an architectural
17
+ perspective. These models are managed via Redis Functions to ensure data integrity and atomicity.
18
+
19
+ The models form a strict hierarchy, with a **Campaign** at the root, containing and orchestrating
20
+ all other resources.
21
+
22
+ ### Campaign
23
+
24
+ **Purpose:** The root of all resources. A Campaign represents a single, isolated mirroring
25
+ operation. It holds the primary configuration, cryptographic secrets, and aggregated statistics for
26
+ a project.
27
+
28
+ **Architectural Role:**
29
+
30
+ - **Container & Owner:** Owns every other model (Proxies, Targets, Redirectors, Lures, Sessions,
31
+ Messages). Deleting a campaign is possible only after deleting all related entities.
32
+ - **Locking Mechanism:** Acts as the root for a distributed lock. Any modification to a campaign or
33
+ any entity within it requires locking the parent Campaign. This prevents race conditions.
34
+ - **Uniqueness Scope:** Enforces global uniqueness for the campaign's public-facing `mirror_domain`
35
+ and its internal `session_cookie_name`.
36
+
37
+ **Key Relationships:**
38
+
39
+ - **Has many** `Proxy` entities (for handling traffic).
40
+ - **Has many** `Target` entities (for backend origin servers).
41
+ - **Has many** `Redirector` entities (for landing pages).
42
+ - **Has many** `Lure` entities (for specific URL paths).
43
+ - **Has many** `Session` entities (for client interactions).
44
+ - **Has many** `Message` entities (for HTTP transaction logs).
45
+
46
+ ### Proxy
47
+
48
+ **Purpose:** An egress endpoint. A Proxy defines how traffic from a mirrored site is routed outwards
49
+ to donor site via HTTP or SOCKS proxies.
50
+
51
+ **Architectural Role:**
52
+
53
+ - **Traffic Forwarder:** Acts as an upstream proxy server. When a Session is created, it is
54
+ dynamically assigned to one of the enabled Proxies.
55
+ - **Load Balancing Target:** The `Session` creation logic uses a random method of obtaining an
56
+ available Proxy from the set of enabled ones, providing simple load balancing and failover.
57
+ - **Lifecycle Management:** Proxies can be individually enabled or disabled. Disabling a proxy
58
+ prevents new sessions from using it. Existing sessions that attempt to re-authorize will be
59
+ automatically re-assigned to a different enabled proxy.
60
+
61
+ **Key Relationships:**
62
+
63
+ - **Belongs to a** `Campaign`.
64
+ - **Is used by many** `Session` entities.
65
+
66
+ ### Target
67
+
68
+ **Purpose:** The backend origin server. A Target defines the real website to be mirrored (e.g.,
69
+ `https://real-bank.com`). It is the source of truth for the content being impersonated.
70
+
71
+ **Architectural Role:**
72
+
73
+ - **Content Provider:** Contains full configuration for connecting to the donor (real) site,
74
+ including subdomains, ports, timeouts, and size limits.
75
+ - **Mirror Definition:** Defines the mapping from a public-facing mirror URL (e.g.,
76
+ `https://secure.bank.mirror-domain.com`) back to the original donor server's internal structure.
77
+ - **Lookup Hub:** The most critical role. When an HTTP request arrives at the mirror domain, Famir
78
+ uses a dedicated `target_mirror_hosts_key` to perform a direct O(1) lookup, instantly finding the
79
+ correct Target based on the requested `Host` header.
80
+
81
+ **Key Relationships:**
82
+
83
+ - **Belongs to a** `Campaign`.
84
+ - **Generates traffic logged as** `Message` entities.
85
+
86
+ ### Redirector
87
+
88
+ **Purpose:** A "landing page" rule. A Redirector represents a specific logical page or template
89
+ (e.g., a login page, an error page) that can be served to a victim.
90
+
91
+ **Architectural Role:**
92
+
93
+ - **Template Container:** Holds the content (e.g., an HTML page) associated with a specific phishing
94
+ step.
95
+ - **Dynamic Fields Container:** Can have arbitrary key-value `fields` attached to it, allowing for
96
+ flexible template injection (e.g., `error_message`, `return_url`).
97
+ - **Relationship Hub for Lures:** A Redirector does not have a public URL itself but serves as the
98
+ target for one or more `Lure` entities. Different Lures can point to the same Redirector.
99
+
100
+ **Key Relationships:**
101
+
102
+ - **Belongs to a** `Campaign`.
103
+ - **Is the parent of many** `Lure` entities. Deleting a Redirector requires its associated Lure
104
+ count to be zero.
105
+
106
+ ### Lure
107
+
108
+ **Purpose:** A specific, publicly accessible URL path (e.g., `/login`, `/reset-password`). A Lure is
109
+ the actual "phishing link" that a victim clicks.
110
+
111
+ **Architectural Role:**
112
+
113
+ - **Router:** The primary HTTP lookup mechanism. When a request arrives at a mirror domain, the
114
+ request's path (e.g., `/login`) is used as a key to instantly find the corresponding Lure via a
115
+ direct hash lookup.
116
+ - **Session Tracker:** Each Lure acts as a counter for the number of sessions that have been
117
+ "upgraded" (e.g., completed a login form) through that specific path.
118
+ - **Activation Switch:** Lures can be enabled or disabled. A disabled lure will not route traffic,
119
+ effectively turning off a specific phishing link without deleting its configuration.
120
+
121
+ **Key Relationships:**
122
+
123
+ - **Belongs to a** `Campaign`.
124
+ - **Points to a single** `Redirector`, which provides the content to serve.
125
+ - **Is the entry point for many** `Session` entities, incrementing its `session_count` when a
126
+ session is upgraded through it.
127
+
128
+ ### Session
129
+
130
+ **Purpose:** A client's browsing "visit". A Session represents an individual victim's interaction
131
+ with the mirror, from the first click to the end of their activity.
132
+
133
+ **Architectural Role:**
134
+
135
+ - **State Container:** Holds the entire state of a client's journey, including assigned `Proxy` and
136
+ a `secret` for authentication.
137
+ - **Dynamic Proxy Assignment:** On creation, a session is randomly assigned one of the campaign's
138
+ enabled proxies. If the assigned proxy becomes disabled, the session will be automatically
139
+ re-assigned to a working proxy the next time it is authorized.
140
+ - **Lifecycle via TTL:** Sessions have two Time-To-Live (TTL) periods:
141
+ 1. **Short TTL:** After creation, before authorization (e.g., user hasn't logged in yet).
142
+ 2. **Long TTL:** After successful authorization (e.g., user is logged in).
143
+ - **Upgrade Tracking:** Tracks if a session has been "upgraded" (e.g., submitted a login form),
144
+ linking it back to the specific `Lure` used.
145
+
146
+ **Key Relationships:**
147
+
148
+ - **Belongs to a** `Campaign`.
149
+ - **Is assigned to one** `Proxy` at a time.
150
+ - **Initiates one or more** `Message` entities (its HTTP requests/responses).
151
+
152
+ ### Message
153
+
154
+ **Purpose:** An immutable audit log entry. A Message represents a single HTTP transaction (request
155
+ and response) that passed through the mirror.
156
+
157
+ **Architectural Role:**
158
+
159
+ - **Forensic Record:** The lowest level of data, storing all technical details of an HTTP exchange:
160
+ method, URL, headers, body, status code, timing, and any errors.
161
+ - **Dummy Mode:** Supports creating a "dummy" message, which only increments counters without
162
+ storing any payload. This is useful for high-throughput logging where full details are not needed.
163
+ - **Automatic Expiration:** Messages are automatically deleted after a campaign-defined TTL,
164
+ preventing unbounded database growth.
165
+
166
+ **Key Relationships:**
167
+
168
+ - **Belongs to a** `Campaign`.
169
+ - **Originates from one** `Session`.
170
+ - **Is generated through one** `Proxy` and one `Target`.
171
+ - **Increments aggregated message counters on the Campaign, Proxy, Target, and Session.**
172
+
173
+ ### Summary of Interactions (Typical User Flow)
174
+
175
+ 1. A **Campaign** is created with a `mirror_domain` (e.g., `secure.bank.com`).
176
+ 2. **Target(s)** are defined to point to the real bank's website.
177
+ 3. A **Redirector** is created to hold a fake login page HTML.
178
+ 4. A **Lure** is created with the path `/login`, linked to the Redirector. The path `/login` is now
179
+ ready to serve the fake login page.
180
+ 5. **Proxy(s)** are created and enabled to forward traffic to the internet.
181
+ 6. A victim clicks a link to `https://secure.bank.com/login`.
182
+ - The **Lure** finds its `Redirector` via the `/login` path.
183
+ - A new **Session** is created for the victim and is randomly assigned an enabled **Proxy**.
184
+ 7. The victim submits their credentials. The **Session** is "upgraded" (marking the login as
185
+ complete), and this increments the **Lure's** `session_count`.
186
+ 8. Every HTTP request and response (e.g., GET login page, POST credentials) is stored as a
187
+ **Message**, linked to the **Session**, **Proxy**, and **Target**. All related counters are
188
+ atomically incremented.
189
+ 9. The **Campaign** provides a central view of all these activities through its aggregated counters
190
+ (`session_count`, `message_count`, etc.).
@@ -24,4 +24,3 @@ export interface RedisDatabaseConnectorOptions {
24
24
  export interface RedisDatabaseRepositoryOptions {
25
25
  prefix: string;
26
26
  }
27
- export declare const DATABASE_LOCK_TIMEOUT: number;
@@ -4,7 +4,7 @@ export class DatabaseError extends CommonError {
4
4
  constructor(message, options) {
5
5
  super(message, {
6
6
  cause: options.cause,
7
- context: options.context
7
+ context: options.context,
8
8
  });
9
9
  this.name = 'DatabaseError';
10
10
  this.code = options.code;
@@ -1 +1 @@
1
- {"version":3,"file":"database.error.js","sourceRoot":"","sources":["../src/database.error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAsB,MAAM,eAAe,CAAA;AAW/D,MAAM,OAAO,aAAc,SAAQ,WAAW;IAC5C,IAAI,CAAmB;IAEvB,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,OAAO,EAAE;YACb,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,OAAO,EAAE,OAAO,CAAC,OAAO;SACzB,CAAC,CAAA;QAEF,IAAI,CAAC,IAAI,GAAG,eAAe,CAAA;QAC3B,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAA;IAC1B,CAAC;CACF"}
1
+ {"version":3,"file":"database.error.js","sourceRoot":"","sources":["../src/database.error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAsB,MAAM,eAAe,CAAA;AAuB/D,MAAM,OAAO,aAAc,SAAQ,WAAW;IAE5C,IAAI,CAAmB;IAQvB,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,OAAO,EAAE;YACb,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,OAAO,EAAE,OAAO,CAAC,OAAO;SACzB,CAAC,CAAA;QAEF,IAAI,CAAC,IAAI,GAAG,eAAe,CAAA;QAC3B,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAA;IAC1B,CAAC;CACF"}
@@ -2,7 +2,7 @@ export declare const databaseFunctions: {
2
2
  readonly message: {
3
3
  readonly create_message: {
4
4
  readonly NUMBER_OF_KEYS: 5;
5
- readonly parseCommand: (parser: import("redis").CommandParser, prefix: string, campaignId: string, messageId: string, proxyId: string, targetId: string, sessionId: string, type: string, method: string, url: string, requestHeaders: string, requestBody: string, status: string, responseHeaders: string, responseBody: string, connection: string, payload: string, errors: string, processor: string, startTime: string, finishTime: string, createdAt: string) => void;
5
+ readonly parseCommand: (parser: import("redis").CommandParser, prefix: string, campaignId: string, messageId: string, proxyId: string, targetId: string, sessionId: string, type: string, method: string, url: string, requestHeaders: string, requestBody: string, status: number, responseHeaders: string, responseBody: string, connection: string, payload: string, errors: string, analyze: string, startTime: number, finishTime: number, createdAt: number) => void;
6
6
  readonly transformReply: () => unknown;
7
7
  };
8
8
  readonly create_dummy_message: {
@@ -24,7 +24,7 @@ export declare const databaseFunctions: {
24
24
  readonly session: {
25
25
  readonly create_session: {
26
26
  readonly NUMBER_OF_KEYS: 3;
27
- readonly parseCommand: (parser: import("redis").CommandParser, prefix: string, campaignId: string, sessionId: string, secret: string, createdAt: string) => void;
27
+ readonly parseCommand: (parser: import("redis").CommandParser, prefix: string, campaignId: string, sessionId: string, secret: string, createdAt: number) => void;
28
28
  readonly transformReply: () => unknown;
29
29
  };
30
30
  readonly read_session: {
@@ -34,7 +34,7 @@ export declare const databaseFunctions: {
34
34
  };
35
35
  readonly auth_session: {
36
36
  readonly NUMBER_OF_KEYS: 3;
37
- readonly parseCommand: (parser: import("redis").CommandParser, prefix: string, campaignId: string, sessionId: string, authorizedAt: string) => void;
37
+ readonly parseCommand: (parser: import("redis").CommandParser, prefix: string, campaignId: string, sessionId: string, authorizedAt: number) => void;
38
38
  readonly transformReply: () => unknown;
39
39
  };
40
40
  readonly upgrade_session: {
@@ -46,7 +46,7 @@ export declare const databaseFunctions: {
46
46
  readonly lure: {
47
47
  readonly create_lure: {
48
48
  readonly NUMBER_OF_KEYS: 6;
49
- readonly parseCommand: (parser: import("redis").CommandParser, prefix: string, campaignId: string, lureId: string, path: string, redirectorId: string, createdAt: string, lockSecret: string) => void;
49
+ readonly parseCommand: (parser: import("redis").CommandParser, prefix: string, campaignId: string, lureId: string, path: string, redirectorId: string, createdAt: number, lockSecret: string) => void;
50
50
  readonly transformReply: () => unknown;
51
51
  };
52
52
  readonly read_lure: {
@@ -83,7 +83,7 @@ export declare const databaseFunctions: {
83
83
  readonly redirector: {
84
84
  readonly create_redirector: {
85
85
  readonly NUMBER_OF_KEYS: 4;
86
- readonly parseCommand: (parser: import("redis").CommandParser, prefix: string, campaignId: string, redirectorId: string, page: string, createdAt: string, lockSecret: string) => void;
86
+ readonly parseCommand: (parser: import("redis").CommandParser, prefix: string, campaignId: string, redirectorId: string, page: string, createdAt: number, lockSecret: string) => void;
87
87
  readonly transformReply: () => unknown;
88
88
  };
89
89
  readonly read_redirector: {
@@ -92,7 +92,7 @@ export declare const databaseFunctions: {
92
92
  readonly transformReply: () => unknown;
93
93
  };
94
94
  readonly read_full_redirector: {
95
- readonly NUMBER_OF_KEYS: 2;
95
+ readonly NUMBER_OF_KEYS: 3;
96
96
  readonly parseCommand: (parser: import("redis").CommandParser, prefix: string, campaignId: string, redirectorId: string) => void;
97
97
  readonly transformReply: () => unknown;
98
98
  };
@@ -106,8 +106,18 @@ export declare const databaseFunctions: {
106
106
  readonly parseCommand: (parser: import("redis").CommandParser, prefix: string, campaignId: string, redirectorId: string, page: string | null, lockSecret: string) => void;
107
107
  readonly transformReply: () => unknown;
108
108
  };
109
- readonly delete_redirector: {
109
+ readonly append_redirector_field: {
110
110
  readonly NUMBER_OF_KEYS: 4;
111
+ readonly parseCommand: (parser: import("redis").CommandParser, prefix: string, campaignId: string, redirectorId: string, field: string, lockSecret: string) => void;
112
+ readonly transformReply: () => unknown;
113
+ };
114
+ readonly remove_redirector_field: {
115
+ readonly NUMBER_OF_KEYS: 4;
116
+ readonly parseCommand: (parser: import("redis").CommandParser, prefix: string, campaignId: string, redirectorId: string, field: string, lockSecret: string) => void;
117
+ readonly transformReply: () => unknown;
118
+ };
119
+ readonly delete_redirector: {
120
+ readonly NUMBER_OF_KEYS: 5;
111
121
  readonly parseCommand: (parser: import("redis").CommandParser, prefix: string, campaignId: string, redirectorId: string, lockSecret: string) => void;
112
122
  readonly transformReply: () => unknown;
113
123
  };
@@ -115,11 +125,11 @@ export declare const databaseFunctions: {
115
125
  readonly target: {
116
126
  readonly create_target: {
117
127
  readonly NUMBER_OF_KEYS: 7;
118
- readonly parseCommand: (parser: import("redis").CommandParser, prefix: string, campaignId: string, targetId: string, accessLevel: string, donorSecure: string, donorSub: string, donorDomain: string, donorPort: string, mirrorSecure: string, mirrorSub: string, mirrorPort: string, connectTimeout: string, simpleTimeout: string, streamTimeout: string, headersSizeLimit: string, bodySizeLimit: string, mainPage: string, notFoundPage: string, faviconIco: string, robotsTxt: string, sitemapXml: string, allowWebSockets: string, createdAt: string, lockSecret: string) => void;
128
+ readonly parseCommand: (parser: import("redis").CommandParser, prefix: string, campaignId: string, targetId: string, accessLevel: string, donorSecure: boolean, donorSub: string, donorDomain: string, donorPort: number, mirrorSecure: boolean, mirrorSub: string, mirrorPort: number, connectTimeout: number, simpleTimeout: number, streamTimeout: number, headersSizeLimit: number, bodySizeLimit: number, mainPage: string, notFoundPage: string, faviconIco: string, robotsTxt: string, sitemapXml: string, allowWebSockets: boolean, createdAt: number, lockSecret: string) => void;
119
129
  readonly transformReply: () => unknown;
120
130
  };
121
131
  readonly read_target: {
122
- readonly NUMBER_OF_KEYS: 3;
132
+ readonly NUMBER_OF_KEYS: 2;
123
133
  readonly parseCommand: (parser: import("redis").CommandParser, prefix: string, campaignId: string, targetId: string) => void;
124
134
  readonly transformReply: () => unknown;
125
135
  };
@@ -128,6 +138,11 @@ export declare const databaseFunctions: {
128
138
  readonly parseCommand: (parser: import("redis").CommandParser, prefix: string, campaignId: string, targetId: string) => void;
129
139
  readonly transformReply: () => unknown;
130
140
  };
141
+ readonly read_target_hosts: {
142
+ readonly NUMBER_OF_KEYS: 1;
143
+ readonly parseCommand: (parser: import("redis").CommandParser, prefix: string) => void;
144
+ readonly transformReply: () => unknown;
145
+ };
131
146
  readonly find_target_link: {
132
147
  readonly NUMBER_OF_KEYS: 1;
133
148
  readonly parseCommand: (parser: import("redis").CommandParser, prefix: string, mirrorHost: string) => void;
@@ -140,7 +155,7 @@ export declare const databaseFunctions: {
140
155
  };
141
156
  readonly update_target: {
142
157
  readonly NUMBER_OF_KEYS: 3;
143
- readonly parseCommand: (parser: import("redis").CommandParser, prefix: string, campaignId: string, targetId: string, connectTimeout: string | null, simpleTimeout: string | null, streamTimeout: string | null, headersSizeLimit: string | null, bodySizeLimit: string | null, mainPage: string | null, notFoundPage: string | null, faviconIco: string | null, robotsTxt: string | null, sitemapXml: string | null, allowWebSockets: string | null, lockSecret: string) => void;
158
+ readonly parseCommand: (parser: import("redis").CommandParser, prefix: string, campaignId: string, targetId: string, connectTimeout: number | null | undefined, simpleTimeout: number | null | undefined, streamTimeout: number | null | undefined, headersSizeLimit: number | null | undefined, bodySizeLimit: number | null | undefined, mainPage: string | null | undefined, notFoundPage: string | null | undefined, faviconIco: string | null | undefined, robotsTxt: string | null | undefined, sitemapXml: string | null | undefined, allowWebSockets: boolean | null | undefined, lockSecret: string) => void;
144
159
  readonly transformReply: () => unknown;
145
160
  };
146
161
  readonly enable_target: {
@@ -172,7 +187,7 @@ export declare const databaseFunctions: {
172
187
  readonly proxy: {
173
188
  readonly create_proxy: {
174
189
  readonly NUMBER_OF_KEYS: 5;
175
- readonly parseCommand: (parser: import("redis").CommandParser, prefix: string, campaignId: string, proxyId: string, url: string, createdAt: string, lockSecret: string) => void;
190
+ readonly parseCommand: (parser: import("redis").CommandParser, prefix: string, campaignId: string, proxyId: string, url: string, createdAt: number, lockSecret: string) => void;
176
191
  readonly transformReply: () => unknown;
177
192
  };
178
193
  readonly read_proxy: {
@@ -204,7 +219,7 @@ export declare const databaseFunctions: {
204
219
  readonly campaign: {
205
220
  readonly create_campaign: {
206
221
  readonly NUMBER_OF_KEYS: 4;
207
- readonly parseCommand: (parser: import("redis").CommandParser, prefix: string, campaignId: string, mirrorDomain: string, description: string, cryptSecret: string, landingUpgradePath: string, sessionCookieName: string, sessionExpire: string, newSessionExpire: string, messageExpire: string, createdAt: string) => void;
222
+ readonly parseCommand: (parser: import("redis").CommandParser, prefix: string, campaignId: string, mirrorDomain: string, description: string, cryptSecret: string, upgradeSessionPath: string, sessionCookieName: string, sessionExpire: number, newSessionExpire: number, messageExpire: number, createdAt: number) => void;
208
223
  readonly transformReply: () => unknown;
209
224
  };
210
225
  readonly read_campaign: {
@@ -213,20 +228,10 @@ export declare const databaseFunctions: {
213
228
  readonly transformReply: () => unknown;
214
229
  };
215
230
  readonly read_full_campaign: {
216
- readonly NUMBER_OF_KEYS: 6;
231
+ readonly NUMBER_OF_KEYS: 7;
217
232
  readonly parseCommand: (parser: import("redis").CommandParser, prefix: string, campaignId: string) => void;
218
233
  readonly transformReply: () => unknown;
219
234
  };
220
- readonly read_campaign_mirror_domains: {
221
- readonly NUMBER_OF_KEYS: 1;
222
- readonly parseCommand: (parser: import("redis").CommandParser, prefix: string) => void;
223
- readonly transformReply: () => unknown;
224
- };
225
- readonly read_campaign_session_cookie_names: {
226
- readonly NUMBER_OF_KEYS: 1;
227
- readonly parseCommand: (parser: import("redis").CommandParser, prefix: string) => void;
228
- readonly transformReply: () => unknown;
229
- };
230
235
  readonly read_campaign_index: {
231
236
  readonly NUMBER_OF_KEYS: 1;
232
237
  readonly parseCommand: (parser: import("redis").CommandParser, prefix: string) => void;
@@ -234,7 +239,7 @@ export declare const databaseFunctions: {
234
239
  };
235
240
  readonly lock_campaign: {
236
241
  readonly NUMBER_OF_KEYS: 2;
237
- readonly parseCommand: (parser: import("redis").CommandParser, prefix: string, campaignId: string, lockSecret: string, lockTimeout: string) => void;
242
+ readonly parseCommand: (parser: import("redis").CommandParser, prefix: string, campaignId: string, lockSecret: string, lockTimeout: number) => void;
238
243
  readonly transformReply: () => unknown;
239
244
  };
240
245
  readonly unlock_campaign: {
@@ -244,7 +249,7 @@ export declare const databaseFunctions: {
244
249
  };
245
250
  readonly update_campaign: {
246
251
  readonly NUMBER_OF_KEYS: 2;
247
- readonly parseCommand: (parser: import("redis").CommandParser, prefix: string, campaignId: string, description: string | null, sessionExpire: string | null, newSessionExpire: string | null, messageExpire: string | null, lockSecret: string) => void;
252
+ readonly parseCommand: (parser: import("redis").CommandParser, prefix: string, campaignId: string, description: string | null | undefined, sessionExpire: number | null | undefined, newSessionExpire: number | null | undefined, messageExpire: number | null | undefined, lockSecret: string) => void;
248
253
  readonly transformReply: () => unknown;
249
254
  };
250
255
  readonly delete_campaign: {
@@ -1,10 +1,10 @@
1
- import { campaignFunctions } from './repositories/campaign/campaign.functions.js';
2
- import { lureFunctions } from './repositories/lure/lure.functions.js';
3
- import { messageFunctions } from './repositories/message/message.functions.js';
4
- import { proxyFunctions } from './repositories/proxy/proxy.functions.js';
5
- import { redirectorFunctions } from './repositories/redirector/redirector.functions.js';
6
- import { sessionFunctions } from './repositories/session/session.functions.js';
7
- import { targetFunctions } from './repositories/target/target.functions.js';
1
+ import { campaignFunctions } from './modules/campaign/campaign.functions.js';
2
+ import { lureFunctions } from './modules/lure/lure.functions.js';
3
+ import { messageFunctions } from './modules/message/message.functions.js';
4
+ import { proxyFunctions } from './modules/proxy/proxy.functions.js';
5
+ import { redirectorFunctions } from './modules/redirector/redirector.functions.js';
6
+ import { sessionFunctions } from './modules/session/session.functions.js';
7
+ import { targetFunctions } from './modules/target/target.functions.js';
8
8
  export const databaseFunctions = {
9
9
  ...campaignFunctions,
10
10
  ...proxyFunctions,
@@ -12,6 +12,6 @@ export const databaseFunctions = {
12
12
  ...redirectorFunctions,
13
13
  ...lureFunctions,
14
14
  ...sessionFunctions,
15
- ...messageFunctions
15
+ ...messageFunctions,
16
16
  };
17
17
  //# sourceMappingURL=database.functions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"database.functions.js","sourceRoot":"","sources":["../src/database.functions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAA;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAA;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6CAA6C,CAAA;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAA;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mDAAmD,CAAA;AACvF,OAAO,EAAE,gBAAgB,EAAE,MAAM,6CAA6C,CAAA;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAA;AAE3E,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,GAAG,iBAAiB;IACpB,GAAG,cAAc;IACjB,GAAG,eAAe;IAClB,GAAG,mBAAmB;IACtB,GAAG,aAAa;IAChB,GAAG,gBAAgB;IACnB,GAAG,gBAAgB;CACX,CAAA"}
1
+ {"version":3,"file":"database.functions.js","sourceRoot":"","sources":["../src/database.functions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAA;AAC5E,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAA;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAA;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAA;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,8CAA8C,CAAA;AAClF,OAAO,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAA;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAA;AAQtE,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,GAAG,iBAAiB;IACpB,GAAG,cAAc;IACjB,GAAG,eAAe;IAClB,GAAG,mBAAmB;IACtB,GAAG,aAAa;IAChB,GAAG,gBAAgB;IACnB,GAAG,gBAAgB;CACX,CAAA"}
package/dist/database.js CHANGED
@@ -1,5 +1,4 @@
1
1
  export const DATABASE_CONNECTOR = Symbol('DatabaseConnector');
2
2
  export const DATABASE_MANAGER = Symbol('DatabaseManager');
3
3
  export const DATABASE_STATUS_CODES = ['OK', 'NOT_FOUND', 'CONFLICT', 'FORBIDDEN'];
4
- export const DATABASE_LOCK_TIMEOUT = 5 * 60 * 1000;
5
4
  //# sourceMappingURL=database.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"database.js","sourceRoot":"","sources":["../src/database.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC,mBAAmB,CAAC,CAAA;AAC7D,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAA;AA2BzD,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,CAAU,CAAA;AAgB1F,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAA"}
1
+ {"version":3,"file":"database.js","sourceRoot":"","sources":["../src/database.ts"],"names":[],"mappings":"AASA,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC,mBAAmB,CAAC,CAAA;AAQ7D,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAA;AA0EzD,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,CAAU,CAAA"}
@@ -11,9 +11,10 @@ export declare const targetKey: (prefix: string, campaignId: string, targetId: s
11
11
  export declare const targetLabelsKey: (prefix: string, campaignId: string, targetId: string) => string;
12
12
  export declare const targetDonorsKey: (prefix: string, campaignId: string) => string;
13
13
  export declare const targetMirrorsKey: (prefix: string, campaignId: string) => string;
14
- export declare const targetMirrorHostsKey: (prefix: string) => string;
15
14
  export declare const targetIndexKey: (prefix: string, campaignId: string) => string;
15
+ export declare const targetHostsKey: (prefix: string) => string;
16
16
  export declare const redirectorKey: (prefix: string, campaignId: string, redirectorId: string) => string;
17
+ export declare const redirectorFieldsKey: (prefix: string, campaignId: string, redirectorId: string) => string;
17
18
  export declare const redirectorIndexKey: (prefix: string, campaignId: string) => string;
18
19
  export declare const lureKey: (prefix: string, campaignId: string, lureId: string) => string;
19
20
  export declare const lurePathsKey: (prefix: string, campaignId: string) => string;
@@ -40,15 +40,18 @@ export const targetDonorsKey = (prefix, campaignId) => {
40
40
  export const targetMirrorsKey = (prefix, campaignId) => {
41
41
  return buildKey(prefix, 'target-mirrors', campaignId);
42
42
  };
43
- export const targetMirrorHostsKey = (prefix) => {
44
- return buildKey(prefix, 'target-mirror-hosts');
45
- };
46
43
  export const targetIndexKey = (prefix, campaignId) => {
47
44
  return buildKey(prefix, 'target-index', campaignId);
48
45
  };
46
+ export const targetHostsKey = (prefix) => {
47
+ return buildKey(prefix, 'target-hosts');
48
+ };
49
49
  export const redirectorKey = (prefix, campaignId, redirectorId) => {
50
50
  return buildKey(prefix, 'redirector', campaignId, redirectorId);
51
51
  };
52
+ export const redirectorFieldsKey = (prefix, campaignId, redirectorId) => {
53
+ return buildKey(prefix, 'redirector-fields', campaignId, redirectorId);
54
+ };
52
55
  export const redirectorIndexKey = (prefix, campaignId) => {
53
56
  return buildKey(prefix, 'redirector-index', campaignId);
54
57
  };
@@ -1 +1 @@
1
- {"version":3,"file":"database.keys.js","sourceRoot":"","sources":["../src/database.keys.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"database.keys.js","sourceRoot":"","sources":["../src/database.keys.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  export const configRedisDatabaseConnectionUrlSchema = {
2
- type: 'string'
2
+ type: 'string',
3
3
  };
4
4
  export const configRedisDatabasePrefixSchema = {
5
5
  type: 'string',
6
- default: 'famir'
6
+ default: 'famir',
7
7
  };
8
8
  //# sourceMappingURL=database.schemas.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"database.schemas.js","sourceRoot":"","sources":["../src/database.schemas.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,sCAAsC,GAA2B;IAC5E,IAAI,EAAE,QAAQ;CACN,CAAA;AAEV,MAAM,CAAC,MAAM,+BAA+B,GAA2B;IACrE,IAAI,EAAE,QAAQ;IACd,OAAO,EAAE,OAAO;CACR,CAAA"}
1
+ {"version":3,"file":"database.schemas.js","sourceRoot":"","sources":["../src/database.schemas.ts"],"names":[],"mappings":"AAQA,MAAM,CAAC,MAAM,sCAAsC,GAA2B;IAC5E,IAAI,EAAE,QAAQ;CACN,CAAA;AAQV,MAAM,CAAC,MAAM,+BAA+B,GAA2B;IACrE,IAAI,EAAE,QAAQ;IACd,OAAO,EAAE,OAAO;CACR,CAAA"}
package/dist/index.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  export * from './database.error.js';
2
2
  export * from './database.js';
3
3
  export * from './database.schemas.js';
4
- export * from './models/index.js';
4
+ export * from './modules/index.js';
5
5
  export * from './redis-database-connector.js';
6
6
  export * from './redis-database-manager.js';
7
- export * from './repositories/index.js';
package/dist/index.js CHANGED
@@ -1,8 +1,7 @@
1
1
  export * from './database.error.js';
2
2
  export * from './database.js';
3
3
  export * from './database.schemas.js';
4
- export * from './models/index.js';
4
+ export * from './modules/index.js';
5
5
  export * from './redis-database-connector.js';
6
6
  export * from './redis-database-manager.js';
7
- export * from './repositories/index.js';
8
7
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAA;AACnC,cAAc,eAAe,CAAA;AAC7B,cAAc,uBAAuB,CAAA;AACrC,cAAc,mBAAmB,CAAA;AACjC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,yBAAyB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAA;AACnC,cAAc,eAAe,CAAA;AAC7B,cAAc,uBAAuB,CAAA;AACrC,cAAc,oBAAoB,CAAA;AAClC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,6BAA6B,CAAA"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/modules/base/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAA"}
@@ -1,23 +1,25 @@
1
1
  import { Config } from '@famir/config';
2
2
  import { Logger } from '@famir/logger';
3
3
  import { Validator } from '@famir/validator';
4
- import { RedisDatabaseConfig, RedisDatabaseConnection, RedisDatabaseRepositoryOptions } from '../../database.js';
4
+ import { DatabaseConnector, DatabaseStatusCode, RedisDatabaseConfig, RedisDatabaseConnection, RedisDatabaseRepositoryOptions } from '../../database.js';
5
5
  export declare abstract class RedisBaseRepository {
6
6
  protected readonly validator: Validator;
7
+ protected readonly config: Config<RedisDatabaseConfig>;
7
8
  protected readonly logger: Logger;
8
- protected readonly connection: RedisDatabaseConnection;
9
+ protected readonly connector: DatabaseConnector;
9
10
  protected readonly repositoryName: string;
10
11
  protected readonly options: RedisDatabaseRepositoryOptions;
11
- constructor(validator: Validator, config: Config<RedisDatabaseConfig>, logger: Logger, connection: RedisDatabaseConnection, repositoryName: string);
12
+ protected readonly connection: RedisDatabaseConnection;
13
+ constructor(validator: Validator, config: Config<RedisDatabaseConfig>, logger: Logger, connector: DatabaseConnector, repositoryName: string);
14
+ protected encodeJson(obj: object): string;
15
+ protected decodeJson(str: string): unknown;
16
+ protected encodeBase64(buf: Buffer): string;
17
+ protected decodeBase64(str: string): Buffer;
12
18
  protected validateStringReply(value: unknown): asserts value is string;
13
19
  protected validateArrayReply(value: unknown): asserts value is unknown[];
14
20
  protected validateArrayStringsReply(value: unknown): asserts value is string[];
15
- protected handleStatusReply(value: unknown): string;
21
+ protected parseStatusReply(value: unknown): [DatabaseStatusCode, string];
16
22
  protected validateRawData<T>(schema: string, value: unknown): asserts value is T;
17
- protected decodeJson(value: string): unknown;
18
- protected encodeJson(value: object): string;
19
- protected decodeBase64(value: string): Buffer;
20
- protected encodeBase64(value: Buffer): string;
21
- protected raiseError(error: unknown, method: string, data: unknown): never;
23
+ protected raiseError(error: unknown, method: string, params: unknown): never;
22
24
  private buildOptions;
23
25
  }