odac 0.9.0

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 (213) hide show
  1. package/.editorconfig +21 -0
  2. package/.github/workflows/auto-pr-description.yml +49 -0
  3. package/.github/workflows/release.yml +32 -0
  4. package/.github/workflows/test-coverage.yml +58 -0
  5. package/.husky/pre-commit +2 -0
  6. package/.kiro/steering/code-style.md +56 -0
  7. package/.kiro/steering/product.md +20 -0
  8. package/.kiro/steering/structure.md +77 -0
  9. package/.kiro/steering/tech.md +87 -0
  10. package/.prettierrc +10 -0
  11. package/.releaserc.js +134 -0
  12. package/AGENTS.md +84 -0
  13. package/CHANGELOG.md +181 -0
  14. package/CODE_OF_CONDUCT.md +83 -0
  15. package/CONTRIBUTING.md +63 -0
  16. package/LICENSE +661 -0
  17. package/README.md +57 -0
  18. package/SECURITY.md +26 -0
  19. package/bin/candy +10 -0
  20. package/bin/candypack +10 -0
  21. package/cli/index.js +3 -0
  22. package/cli/src/Cli.js +348 -0
  23. package/cli/src/Connector.js +93 -0
  24. package/cli/src/Monitor.js +416 -0
  25. package/core/Candy.js +87 -0
  26. package/core/Commands.js +239 -0
  27. package/core/Config.js +1094 -0
  28. package/core/Lang.js +52 -0
  29. package/core/Log.js +43 -0
  30. package/core/Process.js +26 -0
  31. package/docs/backend/01-overview/01-whats-in-the-candy-box.md +9 -0
  32. package/docs/backend/01-overview/02-super-handy-helper-functions.md +9 -0
  33. package/docs/backend/01-overview/03-development-server.md +79 -0
  34. package/docs/backend/02-structure/01-typical-project-layout.md +39 -0
  35. package/docs/backend/03-config/00-configuration-overview.md +214 -0
  36. package/docs/backend/03-config/01-database-connection.md +60 -0
  37. package/docs/backend/03-config/02-static-route-mapping-optional.md +20 -0
  38. package/docs/backend/03-config/03-request-timeout.md +11 -0
  39. package/docs/backend/03-config/04-environment-variables.md +227 -0
  40. package/docs/backend/03-config/05-early-hints.md +352 -0
  41. package/docs/backend/04-routing/01-basic-page-routes.md +28 -0
  42. package/docs/backend/04-routing/02-controller-less-view-routes.md +43 -0
  43. package/docs/backend/04-routing/03-api-and-data-routes.md +20 -0
  44. package/docs/backend/04-routing/04-authentication-aware-routes.md +48 -0
  45. package/docs/backend/04-routing/05-advanced-routing.md +14 -0
  46. package/docs/backend/04-routing/06-error-pages.md +101 -0
  47. package/docs/backend/04-routing/07-cron-jobs.md +149 -0
  48. package/docs/backend/05-controllers/01-how-to-build-a-controller.md +17 -0
  49. package/docs/backend/05-controllers/02-your-trusty-candy-assistant.md +20 -0
  50. package/docs/backend/05-controllers/03-controller-classes.md +93 -0
  51. package/docs/backend/05-forms/01-custom-forms.md +395 -0
  52. package/docs/backend/05-forms/02-automatic-database-insert.md +297 -0
  53. package/docs/backend/06-request-and-response/01-the-request-object-what-is-the-user-asking-for.md +96 -0
  54. package/docs/backend/06-request-and-response/02-sending-a-response-replying-to-the-user.md +40 -0
  55. package/docs/backend/07-views/01-the-view-directory.md +73 -0
  56. package/docs/backend/07-views/02-rendering-a-view.md +179 -0
  57. package/docs/backend/07-views/03-template-syntax.md +181 -0
  58. package/docs/backend/07-views/03-variables.md +328 -0
  59. package/docs/backend/07-views/04-request-data.md +231 -0
  60. package/docs/backend/07-views/05-conditionals.md +290 -0
  61. package/docs/backend/07-views/06-loops.md +353 -0
  62. package/docs/backend/07-views/07-translations.md +358 -0
  63. package/docs/backend/07-views/08-backend-javascript.md +398 -0
  64. package/docs/backend/07-views/09-comments.md +297 -0
  65. package/docs/backend/08-database/01-database-connection.md +99 -0
  66. package/docs/backend/08-database/02-using-mysql.md +322 -0
  67. package/docs/backend/09-validation/01-the-validator-service.md +424 -0
  68. package/docs/backend/10-authentication/01-user-logins-with-authjs.md +53 -0
  69. package/docs/backend/10-authentication/02-foiling-villains-with-csrf-protection.md +55 -0
  70. package/docs/backend/10-authentication/03-register.md +134 -0
  71. package/docs/backend/10-authentication/04-candy-register-forms.md +676 -0
  72. package/docs/backend/10-authentication/05-session-management.md +159 -0
  73. package/docs/backend/10-authentication/06-candy-login-forms.md +596 -0
  74. package/docs/backend/11-mail/01-the-mail-service.md +42 -0
  75. package/docs/backend/12-streaming/01-streaming-overview.md +300 -0
  76. package/docs/backend/13-utilities/01-candy-var.md +504 -0
  77. package/docs/frontend/01-overview/01-introduction.md +146 -0
  78. package/docs/frontend/02-ajax-navigation/01-quick-start.md +608 -0
  79. package/docs/frontend/02-ajax-navigation/02-configuration.md +370 -0
  80. package/docs/frontend/02-ajax-navigation/03-advanced-usage.md +519 -0
  81. package/docs/frontend/03-forms/01-form-handling.md +420 -0
  82. package/docs/frontend/04-api-requests/01-get-post.md +443 -0
  83. package/docs/frontend/05-streaming/01-client-streaming.md +163 -0
  84. package/docs/index.json +452 -0
  85. package/docs/server/01-installation/01-quick-install.md +19 -0
  86. package/docs/server/01-installation/02-manual-installation-via-npm.md +9 -0
  87. package/docs/server/02-get-started/01-core-concepts.md +7 -0
  88. package/docs/server/02-get-started/02-basic-commands.md +57 -0
  89. package/docs/server/02-get-started/03-cli-reference.md +276 -0
  90. package/docs/server/02-get-started/04-cli-quick-reference.md +102 -0
  91. package/docs/server/03-service/01-start-a-new-service.md +57 -0
  92. package/docs/server/03-service/02-delete-a-service.md +48 -0
  93. package/docs/server/04-web/01-create-a-website.md +36 -0
  94. package/docs/server/04-web/02-list-websites.md +9 -0
  95. package/docs/server/04-web/03-delete-a-website.md +29 -0
  96. package/docs/server/05-subdomain/01-create-a-subdomain.md +32 -0
  97. package/docs/server/05-subdomain/02-list-subdomains.md +33 -0
  98. package/docs/server/05-subdomain/03-delete-a-subdomain.md +41 -0
  99. package/docs/server/06-ssl/01-renew-an-ssl-certificate.md +34 -0
  100. package/docs/server/07-mail/01-create-a-mail-account.md +23 -0
  101. package/docs/server/07-mail/02-delete-a-mail-account.md +20 -0
  102. package/docs/server/07-mail/03-list-mail-accounts.md +20 -0
  103. package/docs/server/07-mail/04-change-account-password.md +23 -0
  104. package/eslint.config.mjs +120 -0
  105. package/framework/index.js +4 -0
  106. package/framework/src/Auth.js +309 -0
  107. package/framework/src/Candy.js +81 -0
  108. package/framework/src/Config.js +79 -0
  109. package/framework/src/Env.js +60 -0
  110. package/framework/src/Lang.js +57 -0
  111. package/framework/src/Mail.js +83 -0
  112. package/framework/src/Mysql.js +575 -0
  113. package/framework/src/Request.js +301 -0
  114. package/framework/src/Route/Cron.js +128 -0
  115. package/framework/src/Route/Internal.js +439 -0
  116. package/framework/src/Route.js +455 -0
  117. package/framework/src/Server.js +15 -0
  118. package/framework/src/Stream.js +163 -0
  119. package/framework/src/Token.js +37 -0
  120. package/framework/src/Validator.js +271 -0
  121. package/framework/src/Var.js +211 -0
  122. package/framework/src/View/EarlyHints.js +190 -0
  123. package/framework/src/View/Form.js +600 -0
  124. package/framework/src/View.js +513 -0
  125. package/framework/web/candy.js +838 -0
  126. package/jest.config.js +22 -0
  127. package/locale/de-DE.json +80 -0
  128. package/locale/en-US.json +79 -0
  129. package/locale/es-ES.json +80 -0
  130. package/locale/fr-FR.json +80 -0
  131. package/locale/pt-BR.json +80 -0
  132. package/locale/ru-RU.json +80 -0
  133. package/locale/tr-TR.json +85 -0
  134. package/locale/zh-CN.json +80 -0
  135. package/package.json +86 -0
  136. package/server/index.js +5 -0
  137. package/server/src/Api.js +88 -0
  138. package/server/src/DNS.js +940 -0
  139. package/server/src/Hub.js +535 -0
  140. package/server/src/Mail.js +571 -0
  141. package/server/src/SSL.js +180 -0
  142. package/server/src/Server.js +27 -0
  143. package/server/src/Service.js +248 -0
  144. package/server/src/Subdomain.js +64 -0
  145. package/server/src/Web/Firewall.js +170 -0
  146. package/server/src/Web/Proxy.js +134 -0
  147. package/server/src/Web.js +451 -0
  148. package/server/src/mail/imap.js +1091 -0
  149. package/server/src/mail/server.js +32 -0
  150. package/server/src/mail/smtp.js +786 -0
  151. package/test/cli/Cli.test.js +36 -0
  152. package/test/core/Candy.test.js +234 -0
  153. package/test/core/Commands.test.js +538 -0
  154. package/test/core/Config.test.js +1435 -0
  155. package/test/core/Lang.test.js +250 -0
  156. package/test/core/Process.test.js +156 -0
  157. package/test/framework/Route.test.js +239 -0
  158. package/test/framework/View/EarlyHints.test.js +282 -0
  159. package/test/scripts/check-coverage.js +132 -0
  160. package/test/server/Api.test.js +647 -0
  161. package/test/server/Client.test.js +338 -0
  162. package/test/server/DNS.test.js +2050 -0
  163. package/test/server/DNS.test.js.bak +2084 -0
  164. package/test/server/Log.test.js +73 -0
  165. package/test/server/Mail.account.test_.js +460 -0
  166. package/test/server/Mail.init.test_.js +411 -0
  167. package/test/server/Mail.test_.js +1340 -0
  168. package/test/server/SSL.test_.js +1491 -0
  169. package/test/server/Server.test.js +765 -0
  170. package/test/server/Service.test_.js +1127 -0
  171. package/test/server/Subdomain.test.js +440 -0
  172. package/test/server/Web/Firewall.test.js +175 -0
  173. package/test/server/Web.test_.js +1562 -0
  174. package/test/server/__mocks__/acme-client.js +17 -0
  175. package/test/server/__mocks__/bcrypt.js +50 -0
  176. package/test/server/__mocks__/child_process.js +389 -0
  177. package/test/server/__mocks__/crypto.js +432 -0
  178. package/test/server/__mocks__/fs.js +450 -0
  179. package/test/server/__mocks__/globalCandy.js +227 -0
  180. package/test/server/__mocks__/http-proxy.js +105 -0
  181. package/test/server/__mocks__/http.js +575 -0
  182. package/test/server/__mocks__/https.js +272 -0
  183. package/test/server/__mocks__/index.js +249 -0
  184. package/test/server/__mocks__/mail/server.js +100 -0
  185. package/test/server/__mocks__/mail/smtp.js +31 -0
  186. package/test/server/__mocks__/mailparser.js +81 -0
  187. package/test/server/__mocks__/net.js +369 -0
  188. package/test/server/__mocks__/node-forge.js +328 -0
  189. package/test/server/__mocks__/os.js +320 -0
  190. package/test/server/__mocks__/path.js +291 -0
  191. package/test/server/__mocks__/selfsigned.js +8 -0
  192. package/test/server/__mocks__/server/src/mail/server.js +100 -0
  193. package/test/server/__mocks__/server/src/mail/smtp.js +31 -0
  194. package/test/server/__mocks__/smtp-server.js +106 -0
  195. package/test/server/__mocks__/sqlite3.js +394 -0
  196. package/test/server/__mocks__/testFactories.js +299 -0
  197. package/test/server/__mocks__/testHelpers.js +363 -0
  198. package/test/server/__mocks__/tls.js +229 -0
  199. package/watchdog/index.js +3 -0
  200. package/watchdog/src/Watchdog.js +156 -0
  201. package/web/config.json +5 -0
  202. package/web/controller/page/about.js +27 -0
  203. package/web/controller/page/index.js +34 -0
  204. package/web/package.json +18 -0
  205. package/web/public/assets/css/style.css +1835 -0
  206. package/web/public/assets/js/app.js +96 -0
  207. package/web/route/www.js +19 -0
  208. package/web/skeleton/main.html +22 -0
  209. package/web/view/content/about.html +65 -0
  210. package/web/view/content/home.html +205 -0
  211. package/web/view/footer/main.html +11 -0
  212. package/web/view/head/main.html +5 -0
  213. package/web/view/header/main.html +14 -0
@@ -0,0 +1,676 @@
1
+ # Candy Register Forms
2
+
3
+ The `<candy:register>` component provides a zero-configuration way to create secure registration forms. Simply write HTML, and CandyPack handles validation, security, database operations, and auto-login automatically.
4
+
5
+ ## Quick Start
6
+
7
+ ### 1. Configure Database (config.json)
8
+
9
+ ```json
10
+ {
11
+ "mysql": {
12
+ "host": "localhost",
13
+ "user": "root",
14
+ "password": "",
15
+ "database": "your_database"
16
+ }
17
+ }
18
+ ```
19
+
20
+ That's all you need! The `auth` configuration is optional.
21
+
22
+ ### 2. Create Your Form (view/content/register.html)
23
+
24
+ ```html
25
+ <candy:register redirect="/dashboard">
26
+ <candy:field name="email" type="email" placeholder="Email" unique>
27
+ <candy:validate rule="required|email" message="Please enter a valid email"/>
28
+ </candy:field>
29
+
30
+ <candy:field name="username" type="text" placeholder="Username" unique>
31
+ <candy:validate rule="required|minlen:4" message="Username must be at least 4 characters"/>
32
+ </candy:field>
33
+
34
+ <candy:field name="password" type="password" placeholder="Password">
35
+ <candy:validate rule="required|minlen:8" message="Password must be at least 8 characters"/>
36
+ </candy:field>
37
+
38
+ <candy:submit>Create Account</candy:submit>
39
+ </candy:register>
40
+ ```
41
+
42
+ That's it! No JavaScript, no controller code, no SQL needed. The form automatically:
43
+ - Creates the database table (if it doesn't exist)
44
+ - Validates input (client-side and server-side)
45
+ - Checks for unique email/username
46
+ - Hashes passwords with bcrypt
47
+ - Creates the user account
48
+ - Logs in the user
49
+ - Redirects to dashboard
50
+
51
+ ### 3. Optional: Customize Auth Configuration
52
+
53
+ If you want to customize table names or primary key:
54
+
55
+ ```json
56
+ {
57
+ "mysql": {
58
+ "host": "localhost",
59
+ "user": "root",
60
+ "password": "",
61
+ "database": "your_database"
62
+ },
63
+ "auth": {
64
+ "table": "users", // Optional: User table name (default: "users")
65
+ "key": "id", // Optional: Primary key (default: "id")
66
+ "token": "candy_auth" // Optional: Token table (default: "candy_auth")
67
+ }
68
+ }
69
+ ```
70
+
71
+ **If you don't specify `auth` config:**
72
+ - Table name defaults to `users`
73
+ - Primary key defaults to `id`
74
+ - Token table defaults to `candy_auth`
75
+ - Table is created automatically based on your form fields
76
+
77
+ ## Form Attributes
78
+
79
+ ### `<candy:register>`
80
+
81
+ Main form container with configuration options:
82
+
83
+ ```html
84
+ <candy:register
85
+ redirect="/dashboard" <!-- Redirect URL after successful registration -->
86
+ autologin="true"> <!-- Auto-login after registration (default: true) -->
87
+ <!-- fields here -->
88
+ </candy:register>
89
+ ```
90
+
91
+ **Attributes:**
92
+ - `redirect` - URL to redirect after successful registration
93
+ - `autologin` - Whether to automatically log in the user (default: `true`)
94
+
95
+ ## Field Types
96
+
97
+ ### `<candy:field>`
98
+
99
+ Defines an input field with validation rules:
100
+
101
+ ```html
102
+ <candy:field
103
+ name="email" <!-- Field name (required) -->
104
+ type="email" <!-- Input type (default: text) -->
105
+ placeholder="Email" <!-- Placeholder text -->
106
+ label="Email Address" <!-- Label text (optional) -->
107
+ unique> <!-- Check uniqueness in database -->
108
+
109
+ <candy:validate rule="required|email" message="Valid email required"/>
110
+ </candy:field>
111
+ ```
112
+
113
+ **Attributes:**
114
+ - `name` - Field name (required)
115
+ - `type` - Input type: text, email, password, number, checkbox, textarea
116
+ - `placeholder` - Placeholder text
117
+ - `label` - Label text (for checkbox or explicit labels)
118
+ - `unique` - Check if value already exists in database
119
+ - `skip` - Validate field but don't save to database (useful for password confirmation, terms acceptance)
120
+
121
+ **Supported Input Types:**
122
+ - `text` - Text input
123
+ - `email` - Email input (with HTML5 validation)
124
+ - `password` - Password input
125
+ - `number` - Number input
126
+ - `checkbox` - Checkbox input
127
+ - `textarea` - Textarea
128
+
129
+ ### Skip Attribute
130
+
131
+ Use the `skip` attribute for fields that should be validated but not saved to the database:
132
+
133
+ ```html
134
+ <!-- Password confirmation - validate but don't save -->
135
+ <candy:field name="confirm_password" type="password" placeholder="Confirm Password" skip>
136
+ <candy:validate rule="required|same:password" message="Passwords must match"/>
137
+ </candy:field>
138
+
139
+ <!-- Terms acceptance - validate but don't save -->
140
+ <candy:field name="terms" type="checkbox" label="I accept the terms" skip>
141
+ <candy:validate rule="accepted" message="You must accept the terms"/>
142
+ </candy:field>
143
+
144
+ <!-- Captcha verification - validate but don't save -->
145
+ <candy:field name="captcha" type="text" placeholder="Enter captcha" skip>
146
+ <candy:validate rule="required" message="Please complete the captcha"/>
147
+ </candy:field>
148
+ ```
149
+
150
+ **Common Use Cases:**
151
+ - Password confirmation fields
152
+ - Terms and conditions checkboxes
153
+ - Privacy policy acceptance
154
+ - Captcha verification
155
+ - Temporary validation fields
156
+
157
+ ## Validation Rules
158
+
159
+ ### `<candy:validate>`
160
+
161
+ Defines validation rules for a field:
162
+
163
+ ```html
164
+ <candy:validate
165
+ rule="required|minlen:4|alphanumeric"
166
+ message="Username must be 4+ alphanumeric characters"/>
167
+ ```
168
+
169
+ **Attributes:**
170
+ - `rule` - Validation rules (pipe-separated)
171
+ - `message` - Error message to display
172
+
173
+ ### Available Rules
174
+
175
+ **Basic Rules:**
176
+ - `required` - Field is required
177
+ - `email` - Valid email format
178
+ - `url` - Valid URL format
179
+ - `numeric` - Only numbers
180
+ - `alpha` - Only letters
181
+ - `alphanumeric` - Letters and numbers only
182
+ - `alphaspace` - Letters and spaces only
183
+ - `alphanumericspace` - Letters, numbers, and spaces
184
+ - `accepted` - Must be accepted (for checkboxes)
185
+
186
+ **Length Rules:**
187
+ - `minlen:X` - Minimum length
188
+ - `maxlen:X` - Maximum length
189
+ - `len:X` - Exact length
190
+
191
+ **Number Rules:**
192
+ - `min:X` - Minimum value
193
+ - `max:X` - Maximum value
194
+
195
+ **Comparison Rules:**
196
+ - `same:field` - Must match another field
197
+ - `different:field` - Must be different from another field
198
+ - `equal:value` - Must equal specific value
199
+ - `not:value` - Must not equal specific value
200
+
201
+ **Pattern Rules:**
202
+ - `regex:pattern` - Custom regex pattern
203
+ - `domain` - Valid domain name
204
+ - `ip` - Valid IP address
205
+ - `mac` - Valid MAC address
206
+
207
+ **Special Rules:**
208
+ - `unique` - Check uniqueness in database (use with `unique` attribute on field)
209
+ - `xss` - Check for XSS attempts
210
+
211
+ ### Multiple Validation Rules
212
+
213
+ You can add multiple `<candy:validate>` tags for different error messages:
214
+
215
+ ```html
216
+ <candy:field name="username" type="text" unique>
217
+ <candy:validate rule="required" message="Username is required"/>
218
+ <candy:validate rule="minlen:4" message="Username must be at least {min} characters"/>
219
+ <candy:validate rule="maxlen:20" message="Username cannot exceed {max} characters"/>
220
+ <candy:validate rule="alphanumeric" message="Username can only contain letters and numbers"/>
221
+ <candy:validate rule="unique" message="Username '{value}' is already taken"/>
222
+ </candy:field>
223
+ ```
224
+
225
+ Or combine rules in a single tag:
226
+
227
+ ```html
228
+ <candy:field name="username" type="text" unique>
229
+ <candy:validate
230
+ rule="required|minlen:4|maxlen:20|alphanumeric"
231
+ message="Username must be 4-20 alphanumeric characters"/>
232
+ <candy:validate rule="unique" message="Username '{value}' is already taken"/>
233
+ </candy:field>
234
+ ```
235
+
236
+ ## Message Placeholders
237
+
238
+ Use placeholders in error messages for dynamic values:
239
+
240
+ ```html
241
+ <candy:field name="username" type="text">
242
+ <candy:validate
243
+ rule="minlen:4"
244
+ message="Username '{value}' is too short. Minimum {min} characters required"/>
245
+ </candy:field>
246
+
247
+ <candy:field name="age" type="number">
248
+ <candy:validate
249
+ rule="min:18|max:120"
250
+ message="Age must be between {min} and {max} years"/>
251
+ </candy:field>
252
+ ```
253
+
254
+ **Available Placeholders:**
255
+ - `{value}` - User's input value
256
+ - `{field}` - Field name
257
+ - `{label}` - Field label or placeholder
258
+ - `{min}` - Minimum value (for minlen, min rules)
259
+ - `{max}` - Maximum value (for maxlen, max rules)
260
+ - `{len}` - Required length (for len rule)
261
+ - `{other}` - Other field name (for same, different rules)
262
+
263
+ ## Backend-Only Values
264
+
265
+ ### `<candy:set>`
266
+
267
+ Set values that are processed only on the backend (not visible in HTML):
268
+
269
+ ```html
270
+ <candy:register redirect="/dashboard">
271
+ <!-- User input fields -->
272
+ <candy:field name="email" type="email" unique>
273
+ <candy:validate rule="required|email"/>
274
+ </candy:field>
275
+
276
+ <!-- Backend-only values -->
277
+ <candy:set name="role" value="user"/>
278
+ <candy:set name="status" value="pending"/>
279
+ <candy:set name="registered_at" compute="now"/>
280
+ <candy:set name="ip_address" compute="ip"/>
281
+
282
+ <candy:submit>Register</candy:submit>
283
+ </candy:register>
284
+ ```
285
+
286
+ **Attributes:**
287
+ - `name` - Field name (required)
288
+ - `value` - Static value
289
+ - `compute` - Computed value (see below)
290
+ - `callback` - Custom callback function
291
+ - `if-empty` - Only set if user didn't provide a value
292
+
293
+ ### Computed Values
294
+
295
+ Use `compute` attribute for dynamic values:
296
+
297
+ ```html
298
+ <candy:set name="registered_at" compute="now"/> <!-- Unix timestamp -->
299
+ <candy:set name="date" compute="date"/> <!-- 2025-01-20 -->
300
+ <candy:set name="datetime" compute="datetime"/> <!-- ISO 8601 -->
301
+ <candy:set name="timestamp" compute="timestamp"/> <!-- Milliseconds -->
302
+ <candy:set name="ip_address" compute="ip"/> <!-- User's IP -->
303
+ <candy:set name="user_agent" compute="user_agent"/> <!-- Browser info -->
304
+ <candy:set name="uuid" compute="uuid"/> <!-- UUID v4 -->
305
+ ```
306
+
307
+ ### Conditional Values
308
+
309
+ Use `if-empty` to set a default only if the user didn't provide a value:
310
+
311
+ ```html
312
+ <candy:field name="country" type="text" placeholder="Country (optional)">
313
+ <!-- User can optionally fill this -->
314
+ </candy:field>
315
+
316
+ <candy:set name="country" value="TR" if-empty/>
317
+ <!-- If user leaves it empty, set to "TR" -->
318
+ ```
319
+
320
+ ## Submit Button
321
+
322
+ ### `<candy:submit>`
323
+
324
+ Defines the submit button:
325
+
326
+ ```html
327
+ <candy:submit
328
+ text="Create Account" <!-- Button text -->
329
+ loading="Creating account..."> <!-- Loading state text -->
330
+ </candy:submit>
331
+ ```
332
+
333
+ Or use content as button text:
334
+
335
+ ```html
336
+ <candy:submit>Create Account</candy:submit>
337
+ ```
338
+
339
+ ## Complete Example
340
+
341
+ ```html
342
+ <candy:register redirect="/dashboard" autologin="true">
343
+
344
+ <!-- Email Field -->
345
+ <candy:field name="email" type="email" placeholder="Email Address" unique>
346
+ <candy:validate rule="required" message="Email is required"/>
347
+ <candy:validate rule="email" message="Please enter a valid email address"/>
348
+ <candy:validate rule="unique" message="The email '{value}' is already registered"/>
349
+ </candy:field>
350
+
351
+ <!-- Username Field -->
352
+ <candy:field name="username" type="text" placeholder="Username" unique>
353
+ <candy:validate rule="required" message="Username is required"/>
354
+ <candy:validate rule="minlen:4" message="Username must be at least {min} characters"/>
355
+ <candy:validate rule="maxlen:20" message="Username cannot exceed {max} characters"/>
356
+ <candy:validate rule="alphanumeric" message="Only letters and numbers allowed"/>
357
+ <candy:validate rule="unique" message="Username '{value}' is already taken"/>
358
+ </candy:field>
359
+
360
+ <!-- Password Field -->
361
+ <candy:field name="password" type="password" placeholder="Password">
362
+ <candy:validate rule="required" message="Password is required"/>
363
+ <candy:validate rule="minlen:8" message="Password must be at least {min} characters"/>
364
+ </candy:field>
365
+
366
+ <!-- Password Confirmation -->
367
+ <candy:field name="password_confirm" type="password" placeholder="Confirm Password" skip>
368
+ <candy:validate rule="required" message="Please confirm your password"/>
369
+ <candy:validate rule="same:password" message="Passwords do not match"/>
370
+ </candy:field>
371
+
372
+ <!-- Full Name -->
373
+ <candy:field name="name" type="text" placeholder="Full Name">
374
+ <candy:validate rule="required" message="Name is required"/>
375
+ <candy:validate rule="alphaspace" message="Name can only contain letters and spaces"/>
376
+ <candy:validate rule="minlen:3" message="Name must be at least {min} characters"/>
377
+ </candy:field>
378
+
379
+ <!-- Age -->
380
+ <candy:field name="age" type="number" placeholder="Age">
381
+ <candy:validate rule="required" message="Age is required"/>
382
+ <candy:validate rule="min:18" message="You must be at least {min} years old"/>
383
+ <candy:validate rule="max:120" message="Please enter a valid age"/>
384
+ </candy:field>
385
+
386
+ <!-- Terms Checkbox -->
387
+ <candy:field name="terms" type="checkbox" label="I agree to the terms and conditions" skip>
388
+ <candy:validate rule="accepted" message="You must accept the terms to continue"/>
389
+ </candy:field>
390
+
391
+ <!-- Backend-only values -->
392
+ <candy:set name="role" value="user"/>
393
+ <candy:set name="status" value="active"/>
394
+ <candy:set name="registered_at" compute="now"/>
395
+ <candy:set name="ip_address" compute="ip"/>
396
+ <candy:set name="user_agent" compute="user_agent"/>
397
+
398
+ <!-- Submit Button -->
399
+ <candy:submit text="Create Account" loading="Creating your account..."/>
400
+
401
+ </candy:register>
402
+ ```
403
+
404
+ ## Security Features
405
+
406
+ ### Automatic Security
407
+
408
+ CandyPack automatically handles:
409
+
410
+ 1. **CSRF Protection** - Form tokens prevent cross-site attacks
411
+ 2. **Password Hashing** - Passwords are hashed with bcrypt
412
+ 3. **SQL Injection Prevention** - All queries are parameterized
413
+ 4. **XSS Protection** - Input is sanitized
414
+ 5. **Field Whitelisting** - Only defined fields are processed
415
+ 6. **Token Expiration** - Form tokens expire after 30 minutes
416
+
417
+ ### Token System
418
+
419
+ Each form gets a unique token when rendered:
420
+ - Token is stored server-side with field whitelist
421
+ - Token expires after 30 minutes
422
+ - Only fields defined in the view are accepted
423
+ - Backend-only values (`<candy:set>`) are never exposed to HTML
424
+
425
+ ### Unique Field Checking
426
+
427
+ Fields marked with `unique` attribute are checked against the database:
428
+
429
+ ```html
430
+ <candy:field name="email" type="email" unique>
431
+ <candy:validate rule="unique" message="Email already exists"/>
432
+ </candy:field>
433
+ ```
434
+
435
+ The system automatically queries the auth table to check for duplicates.
436
+
437
+ ## HTML5 Validation
438
+
439
+ CandyPack automatically adds HTML5 validation attributes for better UX:
440
+
441
+ ```html
442
+ <!-- This field -->
443
+ <candy:field name="username" type="text">
444
+ <candy:validate rule="required|minlen:4|maxlen:20|alphanumeric"/>
445
+ </candy:field>
446
+
447
+ <!-- Generates this HTML -->
448
+ <input
449
+ type="text"
450
+ name="username"
451
+ required
452
+ minlength="4"
453
+ maxlength="20"
454
+ pattern="[a-zA-Z0-9]+">
455
+ ```
456
+
457
+ **Automatic HTML5 Attributes:**
458
+ - `required` - For required fields
459
+ - `minlength` / `maxlength` - For length validation
460
+ - `min` / `max` - For number validation
461
+ - `pattern` - For alphanumeric, numeric, alpha rules
462
+ - `type="email"` - Native email validation
463
+ - `type="url"` - Native URL validation
464
+
465
+ This provides instant feedback to users before form submission.
466
+
467
+ ## Configuration Reference
468
+
469
+ ### Required Configuration
470
+
471
+ Only MySQL configuration is required:
472
+
473
+ ```json
474
+ {
475
+ "mysql": {
476
+ "host": "localhost",
477
+ "user": "root",
478
+ "password": "",
479
+ "database": "your_database"
480
+ }
481
+ }
482
+ ```
483
+
484
+ ### Optional Auth Configuration
485
+
486
+ Customize table names and primary key if needed:
487
+
488
+ ```json
489
+ {
490
+ "auth": {
491
+ "table": "users", // User table name (default: "users")
492
+ "key": "id", // Primary key column (default: "id")
493
+ "token": "candy_auth" // Session token table (default: "candy_auth")
494
+ }
495
+ }
496
+ ```
497
+
498
+ **Default Values:**
499
+ - If `auth` is not specified, defaults are used
500
+ - Table: `users`
501
+ - Primary key: `id`
502
+ - Token table: `candy_auth`
503
+ - All tables are created automatically if they don't exist
504
+
505
+ ### Database Schema
506
+
507
+ **Auto-Creation (Recommended):**
508
+
509
+ The users table is created automatically on first registration! CandyPack analyzes your form fields and creates the appropriate table structure:
510
+
511
+ - Fields with `unique` attribute → `VARCHAR(255) NOT NULL UNIQUE`
512
+ - Password field → `VARCHAR(255) NOT NULL` (for bcrypt hashes)
513
+ - Number fields → `INT` or `BIGINT`
514
+ - Text fields → `VARCHAR(255)` or `TEXT` (if > 255 chars)
515
+ - Boolean fields → `TINYINT(1)`
516
+ - Timestamps → `created_at` and `updated_at` added automatically
517
+
518
+ **Manual Creation (Optional):**
519
+
520
+ If you prefer to create the table manually:
521
+
522
+ ```sql
523
+ CREATE TABLE `users` (
524
+ `id` INT NOT NULL AUTO_INCREMENT,
525
+ `email` VARCHAR(255) NOT NULL UNIQUE,
526
+ `username` VARCHAR(255) NOT NULL UNIQUE,
527
+ `password` VARCHAR(255) NOT NULL,
528
+ `name` VARCHAR(255) NULL,
529
+ `role` VARCHAR(50) DEFAULT 'user',
530
+ `status` VARCHAR(50) DEFAULT 'active',
531
+ `registered_at` INT NULL,
532
+ `ip_address` VARCHAR(45) NULL,
533
+ `user_agent` TEXT NULL,
534
+ `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
535
+ `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
536
+ PRIMARY KEY (`id`)
537
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
538
+ ```
539
+
540
+ **Important:**
541
+ - Password field must be `VARCHAR(255)` to store bcrypt hashes (60 chars + future-proofing)
542
+ - Fields marked with `unique` attribute should have `UNIQUE` constraint
543
+ - Auto-creation uses `utf8mb4_unicode_ci` collation for full Unicode support
544
+
545
+ ### Token Table
546
+
547
+ The token table is created automatically on first login, but you can create it manually:
548
+
549
+ ```sql
550
+ CREATE TABLE `candy_auth` (
551
+ `id` INT NOT NULL AUTO_INCREMENT,
552
+ `user` INT NOT NULL,
553
+ `token_x` VARCHAR(255) NOT NULL,
554
+ `token_y` VARCHAR(255) NOT NULL,
555
+ `browser` VARCHAR(255) NOT NULL,
556
+ `ip` VARCHAR(255) NOT NULL,
557
+ `date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
558
+ `active` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
559
+ PRIMARY KEY (`id`)
560
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
561
+ ```
562
+
563
+ ## Error Handling
564
+
565
+ ### Display Errors
566
+
567
+ Error messages are automatically displayed in `<span>` elements with `candy-form-error` attribute:
568
+
569
+ ```html
570
+ <!-- Errors appear here automatically -->
571
+ <span class="candy-form-error" candy-form-error="email" style="display:none;"></span>
572
+ ```
573
+
574
+ ### Success Messages
575
+
576
+ Success messages appear in elements with `candy-form-success` class:
577
+
578
+ ```html
579
+ <!-- Success message appears here -->
580
+ <span class="candy-form-success" style="display:none;"></span>
581
+ ```
582
+
583
+ ### Custom Styling
584
+
585
+ Style error and success messages with CSS:
586
+
587
+ ```css
588
+ .candy-form-error {
589
+ color: red;
590
+ font-size: 0.875rem;
591
+ margin-top: 0.25rem;
592
+ }
593
+
594
+ .candy-form-success {
595
+ color: green;
596
+ font-size: 1rem;
597
+ padding: 1rem;
598
+ background: #d4edda;
599
+ border: 1px solid #c3e6cb;
600
+ border-radius: 0.25rem;
601
+ }
602
+
603
+ .candy-field {
604
+ margin-bottom: 1rem;
605
+ }
606
+
607
+ input._candy_error {
608
+ border-color: red;
609
+ }
610
+ ```
611
+
612
+ ## Advanced Usage
613
+
614
+ ### Custom Callbacks
615
+
616
+ You can define custom callbacks for computed values:
617
+
618
+ ```javascript
619
+ // In your page controller or global script
620
+ Candy.fn.generateReferralCode = async (Candy) => {
621
+ return Math.random().toString(36).substring(2, 10).toUpperCase()
622
+ }
623
+ ```
624
+
625
+ ```html
626
+ <candy:set name="referral_code" callback="generateReferralCode"/>
627
+ ```
628
+
629
+ ### Conditional Registration
630
+
631
+ Disable auto-login and handle redirect manually:
632
+
633
+ ```html
634
+ <candy:register autologin="false">
635
+ <!-- fields -->
636
+ </candy:register>
637
+ ```
638
+
639
+ Then handle the response in JavaScript if needed (though not required for basic usage).
640
+
641
+ ## Best Practices
642
+
643
+ 1. **Always validate on both client and server** - CandyPack does this automatically
644
+ 2. **Use unique attribute for email/username** - Prevents duplicate accounts
645
+ 3. **Set minimum password length** - Use `minlen:8` or higher
646
+ 4. **Use password confirmation** - Add a `password_confirm` field with `same:password` rule
647
+ 5. **Add terms checkbox** - Use `accepted` rule for legal compliance
648
+ 6. **Use backend-only values** - Store metadata with `<candy:set>`
649
+ 7. **Provide clear error messages** - Use placeholders for dynamic values
650
+ 8. **Test form expiration** - Forms expire after 30 minutes
651
+
652
+ ## Troubleshooting
653
+
654
+ ### Form Not Submitting
655
+
656
+ - Check that `config.json` has auth configuration
657
+ - Verify database table exists
658
+ - Check browser console for JavaScript errors
659
+
660
+ ### Validation Not Working
661
+
662
+ - Ensure validation rules are spelled correctly
663
+ - Check that field names match between `<candy:field>` and validation
664
+ - Verify HTML5 validation isn't blocking submission
665
+
666
+ ### Unique Check Failing
667
+
668
+ - Verify `unique` attribute is on the field
669
+ - Check that auth table name in config matches your database
670
+ - Ensure the field exists in your database table
671
+
672
+ ### Token Expired
673
+
674
+ - Forms expire after 30 minutes
675
+ - User needs to refresh the page to get a new token
676
+ - Consider adding a message about session expiration