odac 0.9.0 → 1.0.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 (208) hide show
  1. package/.github/workflows/auto-pr-description.yml +0 -2
  2. package/.github/workflows/codeql.yml +46 -0
  3. package/.github/workflows/release.yml +13 -6
  4. package/.github/workflows/test-coverage.yml +10 -9
  5. package/.releaserc.js +9 -6
  6. package/CHANGELOG.md +62 -150
  7. package/CODE_OF_CONDUCT.md +1 -1
  8. package/CONTRIBUTING.md +8 -8
  9. package/LICENSE +21 -661
  10. package/README.md +12 -12
  11. package/SECURITY.md +4 -4
  12. package/bin/odac.js +101 -0
  13. package/{framework/web/candy.js → client/odac.js} +310 -44
  14. package/docs/backend/01-overview/{01-whats-in-the-candy-box.md → 01-whats-in-the-odac-box.md} +4 -2
  15. package/docs/backend/01-overview/02-super-handy-helper-functions.md +29 -1
  16. package/docs/backend/01-overview/03-development-server.md +11 -11
  17. package/docs/backend/02-structure/01-typical-project-layout.md +4 -4
  18. package/docs/backend/03-config/00-configuration-overview.md +6 -6
  19. package/docs/backend/03-config/01-database-connection.md +1 -1
  20. package/docs/backend/03-config/02-static-route-mapping-optional.md +4 -4
  21. package/docs/backend/03-config/04-environment-variables.md +20 -20
  22. package/docs/backend/03-config/05-early-hints.md +4 -4
  23. package/docs/backend/04-routing/01-basic-page-routes.md +4 -4
  24. package/docs/backend/04-routing/02-controller-less-view-routes.md +5 -5
  25. package/docs/backend/04-routing/03-api-and-data-routes.md +3 -3
  26. package/docs/backend/04-routing/04-authentication-aware-routes.md +5 -5
  27. package/docs/backend/04-routing/05-advanced-routing.md +3 -3
  28. package/docs/backend/04-routing/06-error-pages.md +17 -17
  29. package/docs/backend/04-routing/07-cron-jobs.md +13 -13
  30. package/docs/backend/04-routing/08-middleware.md +214 -0
  31. package/docs/backend/04-routing/09-websocket-auth-middleware.md +292 -0
  32. package/docs/backend/04-routing/09-websocket-examples.md +381 -0
  33. package/docs/backend/04-routing/09-websocket-quick-reference.md +211 -0
  34. package/docs/backend/04-routing/09-websocket.md +298 -0
  35. package/docs/backend/05-controllers/01-how-to-build-a-controller.md +3 -3
  36. package/docs/backend/05-controllers/02-your-trusty-odac-assistant.md +41 -0
  37. package/docs/backend/05-controllers/03-controller-classes.md +19 -19
  38. package/docs/backend/05-forms/01-custom-forms.md +114 -114
  39. package/docs/backend/05-forms/02-automatic-database-insert.md +82 -82
  40. package/docs/backend/06-request-and-response/01-the-request-object-what-is-the-user-asking-for.md +26 -26
  41. package/docs/backend/06-request-and-response/02-sending-a-response-replying-to-the-user.md +10 -10
  42. package/docs/backend/07-views/01-the-view-directory.md +1 -1
  43. package/docs/backend/07-views/02-rendering-a-view.md +22 -22
  44. package/docs/backend/07-views/03-template-syntax.md +52 -52
  45. package/docs/backend/07-views/03-variables.md +84 -84
  46. package/docs/backend/07-views/04-request-data.md +57 -57
  47. package/docs/backend/07-views/05-conditionals.md +78 -78
  48. package/docs/backend/07-views/06-loops.md +114 -114
  49. package/docs/backend/07-views/07-translations.md +66 -66
  50. package/docs/backend/07-views/08-backend-javascript.md +103 -103
  51. package/docs/backend/07-views/09-comments.md +71 -71
  52. package/docs/backend/08-database/01-database-connection.md +8 -8
  53. package/docs/backend/08-database/02-using-mysql.md +49 -49
  54. package/docs/backend/09-validation/01-the-validator-service.md +38 -38
  55. package/docs/backend/10-authentication/01-user-logins-with-authjs.md +15 -15
  56. package/docs/backend/10-authentication/02-foiling-villains-with-csrf-protection.md +10 -10
  57. package/docs/backend/10-authentication/03-register.md +12 -12
  58. package/docs/backend/10-authentication/{04-candy-register-forms.md → 04-odac-register-forms.md} +141 -141
  59. package/docs/backend/10-authentication/05-session-management.md +10 -10
  60. package/docs/backend/10-authentication/{06-candy-login-forms.md → 06-odac-login-forms.md} +125 -125
  61. package/docs/backend/11-mail/01-the-mail-service.md +5 -5
  62. package/docs/backend/12-streaming/01-streaming-overview.md +96 -54
  63. package/docs/backend/13-utilities/{01-candy-var.md → 01-odac-var.md} +109 -109
  64. package/docs/frontend/01-overview/01-introduction.md +30 -30
  65. package/docs/frontend/02-ajax-navigation/01-quick-start.md +45 -45
  66. package/docs/frontend/02-ajax-navigation/02-configuration.md +14 -14
  67. package/docs/frontend/02-ajax-navigation/03-advanced-usage.md +36 -36
  68. package/docs/frontend/03-forms/01-form-handling.md +32 -32
  69. package/docs/frontend/04-api-requests/01-get-post.md +33 -33
  70. package/docs/frontend/05-streaming/01-client-streaming.md +15 -15
  71. package/docs/frontend/06-websocket/00-overview.md +76 -0
  72. package/docs/frontend/06-websocket/01-websocket-client.md +139 -0
  73. package/docs/frontend/06-websocket/02-shared-websocket.md +149 -0
  74. package/docs/index.json +49 -11
  75. package/eslint.config.mjs +6 -6
  76. package/{framework/index.js → index.js} +1 -1
  77. package/package.json +14 -39
  78. package/{framework/src → src}/Auth.js +59 -59
  79. package/{framework/src → src}/Config.js +3 -3
  80. package/{framework/src → src}/Lang.js +7 -7
  81. package/{framework/src → src}/Mail.js +5 -5
  82. package/{framework/src → src}/Mysql.js +42 -42
  83. package/src/Odac.js +112 -0
  84. package/{framework/src → src}/Request.js +38 -36
  85. package/{framework/src → src}/Route/Internal.js +116 -116
  86. package/src/Route/Middleware.js +75 -0
  87. package/src/Route.js +621 -0
  88. package/src/Server.js +22 -0
  89. package/{framework/src → src}/Stream.js +11 -3
  90. package/{framework/src → src}/Validator.js +21 -21
  91. package/{framework/src → src}/Var.js +5 -5
  92. package/{framework/src → src}/View/EarlyHints.js +1 -1
  93. package/{framework/src → src}/View/Form.js +69 -69
  94. package/{framework/src → src}/View.js +78 -81
  95. package/src/WebSocket.js +403 -0
  96. package/template/config.json +5 -0
  97. package/{web → template}/controller/page/about.js +6 -6
  98. package/{web → template}/controller/page/index.js +9 -9
  99. package/{web → template}/package.json +4 -5
  100. package/{web → template}/public/assets/css/style.css +4 -4
  101. package/{web → template}/public/assets/js/app.js +6 -6
  102. package/{web → template}/route/www.js +6 -6
  103. package/{web → template}/skeleton/main.html +1 -1
  104. package/{web → template}/view/content/about.html +5 -5
  105. package/{web → template}/view/content/home.html +12 -12
  106. package/template/view/footer/main.html +11 -0
  107. package/{web → template}/view/head/main.html +1 -1
  108. package/{web → template}/view/header/main.html +2 -2
  109. package/test/core/Candy.test.js +58 -58
  110. package/test/core/Commands.test.js +7 -7
  111. package/test/core/Config.test.js +82 -85
  112. package/test/core/Lang.test.js +2 -2
  113. package/test/core/Process.test.js +6 -6
  114. package/test/framework/Route.test.js +56 -37
  115. package/test/framework/View/EarlyHints.test.js +2 -2
  116. package/test/framework/WebSocket.test.js +100 -0
  117. package/test/framework/middleware.test.js +85 -0
  118. package/test/server/Api.test.js +31 -31
  119. package/test/server/DNS.test.js +11 -11
  120. package/test/server/Hub.test.js +497 -0
  121. package/test/server/Mail.account.test_.js +3 -3
  122. package/test/server/Mail.init.test_.js +10 -10
  123. package/test/server/Mail.test_.js +20 -20
  124. package/test/server/SSL.test_.js +54 -54
  125. package/test/server/Server.test.js +39 -39
  126. package/test/server/Service.test_.js +7 -7
  127. package/test/server/Subdomain.test.js +7 -7
  128. package/test/server/Web/Firewall.test.js +87 -87
  129. package/test/server/Web/Proxy.test.js +397 -0
  130. package/test/server/{Web.test_.js → Web.test.js} +137 -205
  131. package/test/server/__mocks__/fs.js +2 -2
  132. package/test/server/__mocks__/{globalCandy.js → globalOdac.js} +5 -5
  133. package/test/server/__mocks__/index.js +6 -6
  134. package/test/server/__mocks__/testFactories.js +1 -1
  135. package/test/server/__mocks__/testHelpers.js +7 -7
  136. package/.husky/pre-commit +0 -2
  137. package/.kiro/steering/code-style.md +0 -56
  138. package/.kiro/steering/product.md +0 -20
  139. package/.kiro/steering/structure.md +0 -77
  140. package/.kiro/steering/tech.md +0 -87
  141. package/AGENTS.md +0 -84
  142. package/bin/candy +0 -10
  143. package/bin/candypack +0 -10
  144. package/cli/index.js +0 -3
  145. package/cli/src/Cli.js +0 -348
  146. package/cli/src/Connector.js +0 -93
  147. package/cli/src/Monitor.js +0 -416
  148. package/core/Candy.js +0 -87
  149. package/core/Commands.js +0 -239
  150. package/core/Config.js +0 -1094
  151. package/core/Lang.js +0 -52
  152. package/core/Log.js +0 -43
  153. package/core/Process.js +0 -26
  154. package/docs/backend/05-controllers/02-your-trusty-candy-assistant.md +0 -20
  155. package/docs/server/01-installation/01-quick-install.md +0 -19
  156. package/docs/server/01-installation/02-manual-installation-via-npm.md +0 -9
  157. package/docs/server/02-get-started/01-core-concepts.md +0 -7
  158. package/docs/server/02-get-started/02-basic-commands.md +0 -57
  159. package/docs/server/02-get-started/03-cli-reference.md +0 -276
  160. package/docs/server/02-get-started/04-cli-quick-reference.md +0 -102
  161. package/docs/server/03-service/01-start-a-new-service.md +0 -57
  162. package/docs/server/03-service/02-delete-a-service.md +0 -48
  163. package/docs/server/04-web/01-create-a-website.md +0 -36
  164. package/docs/server/04-web/02-list-websites.md +0 -9
  165. package/docs/server/04-web/03-delete-a-website.md +0 -29
  166. package/docs/server/05-subdomain/01-create-a-subdomain.md +0 -32
  167. package/docs/server/05-subdomain/02-list-subdomains.md +0 -33
  168. package/docs/server/05-subdomain/03-delete-a-subdomain.md +0 -41
  169. package/docs/server/06-ssl/01-renew-an-ssl-certificate.md +0 -34
  170. package/docs/server/07-mail/01-create-a-mail-account.md +0 -23
  171. package/docs/server/07-mail/02-delete-a-mail-account.md +0 -20
  172. package/docs/server/07-mail/03-list-mail-accounts.md +0 -20
  173. package/docs/server/07-mail/04-change-account-password.md +0 -23
  174. package/framework/src/Candy.js +0 -81
  175. package/framework/src/Route.js +0 -455
  176. package/framework/src/Server.js +0 -15
  177. package/locale/de-DE.json +0 -80
  178. package/locale/en-US.json +0 -79
  179. package/locale/es-ES.json +0 -80
  180. package/locale/fr-FR.json +0 -80
  181. package/locale/pt-BR.json +0 -80
  182. package/locale/ru-RU.json +0 -80
  183. package/locale/tr-TR.json +0 -85
  184. package/locale/zh-CN.json +0 -80
  185. package/server/index.js +0 -5
  186. package/server/src/Api.js +0 -88
  187. package/server/src/DNS.js +0 -940
  188. package/server/src/Hub.js +0 -535
  189. package/server/src/Mail.js +0 -571
  190. package/server/src/SSL.js +0 -180
  191. package/server/src/Server.js +0 -27
  192. package/server/src/Service.js +0 -248
  193. package/server/src/Subdomain.js +0 -64
  194. package/server/src/Web/Firewall.js +0 -170
  195. package/server/src/Web/Proxy.js +0 -134
  196. package/server/src/Web.js +0 -451
  197. package/server/src/mail/imap.js +0 -1091
  198. package/server/src/mail/server.js +0 -32
  199. package/server/src/mail/smtp.js +0 -786
  200. package/test/server/Client.test.js +0 -338
  201. package/test/server/__mocks__/http-proxy.js +0 -105
  202. package/watchdog/index.js +0 -3
  203. package/watchdog/src/Watchdog.js +0 -156
  204. package/web/config.json +0 -5
  205. package/web/view/footer/main.html +0 -11
  206. /package/{framework/src → src}/Env.js +0 -0
  207. /package/{framework/src → src}/Route/Cron.js +0 -0
  208. /package/{framework/src → src}/Token.js +0 -0
@@ -1,13 +1,13 @@
1
1
  ## ✅ The `Validator` Service
2
2
 
3
- The Validator service provides a fluent, chainable API for validating user input. It's automatically available in your controllers through `Candy.Validator`.
3
+ The Validator service provides a fluent, chainable API for validating user input. It's automatically available in your controllers through `Odac.Validator`.
4
4
 
5
5
  #### Basic Usage
6
6
 
7
7
  The validator uses a method-chaining pattern:
8
8
 
9
9
  ```javascript
10
- const validator = Candy.Validator
10
+ const validator = Odac.Validator
11
11
  validator.post('email').check('required|email').message('Valid email required')
12
12
  validator.post('password').check('required|minlen:8').message('Password must be at least 8 characters')
13
13
 
@@ -82,8 +82,8 @@ Use `!` prefix to invert any rule: `!required`, `!email`, etc.
82
82
  #### Example: User Registration
83
83
 
84
84
  ```javascript
85
- module.exports = async function (Candy) {
86
- const validator = Candy.Validator
85
+ module.exports = async function (Odac) {
86
+ const validator = Odac.Validator
87
87
 
88
88
  validator.post('username').check('required|username|minlen:4|maxlen:20').message('Username must be 4-20 alphanumeric characters')
89
89
  validator.post('email').check('required|email').message('Valid email address required')
@@ -101,8 +101,8 @@ module.exports = async function (Candy) {
101
101
  #### Example: Login with Brute Force Protection
102
102
 
103
103
  ```javascript
104
- module.exports = async function (Candy) {
105
- const validator = Candy.Validator
104
+ module.exports = async function (Odac) {
105
+ const validator = Odac.Validator
106
106
 
107
107
  validator.post('email').check('required|email').message('Email required')
108
108
  validator.post('password').check('required').message('Password required')
@@ -119,8 +119,8 @@ module.exports = async function (Candy) {
119
119
  #### Example: Custom Variable Validation
120
120
 
121
121
  ```javascript
122
- module.exports = async function (Candy) {
123
- const validator = Candy.Validator
122
+ module.exports = async function (Odac) {
123
+ const validator = Odac.Validator
124
124
  const customValue = calculateSomething()
125
125
 
126
126
  validator.var('calculated_value', customValue).check('numeric|min:100|max:1000').message('Value must be between 100 and 1000')
@@ -138,8 +138,8 @@ module.exports = async function (Candy) {
138
138
  You can chain multiple `check()` calls for the same field, each with its own specific error message. The validator will return the first error it encounters:
139
139
 
140
140
  ```javascript
141
- module.exports = async function (Candy) {
142
- const validator = Candy.Validator
141
+ module.exports = async function (Odac) {
142
+ const validator = Odac.Validator
143
143
 
144
144
  validator
145
145
  .post('password')
@@ -160,8 +160,8 @@ module.exports = async function (Candy) {
160
160
  #### Example: Complex Form Validation
161
161
 
162
162
  ```javascript
163
- module.exports = async function (Candy) {
164
- const validator = Candy.Validator
163
+ module.exports = async function (Odac) {
164
+ const validator = Odac.Validator
165
165
 
166
166
  validator
167
167
  .post('username')
@@ -203,8 +203,8 @@ module.exports = async function (Candy) {
203
203
  #### Example: Date Range Validation
204
204
 
205
205
  ```javascript
206
- module.exports = async function (Candy) {
207
- const validator = Candy.Validator
206
+ module.exports = async function (Odac) {
207
+ const validator = Odac.Validator
208
208
 
209
209
  validator
210
210
  .post('start_date')
@@ -229,10 +229,10 @@ module.exports = async function (Candy) {
229
229
  #### Example: Conditional Validation with Custom Variables
230
230
 
231
231
  ```javascript
232
- module.exports = async function (Candy) {
233
- const validator = Candy.Validator
234
- const userRole = Candy.Auth.user('role')
235
- const userCredits = Candy.Auth.user('credits') || 0
232
+ module.exports = async function (Odac) {
233
+ const validator = Odac.Validator
234
+ const userRole = Odac.Auth.user('role')
235
+ const userCredits = Odac.Auth.user('credits') || 0
236
236
 
237
237
  validator.post('title').check('required').message('Title is required')
238
238
  validator.post('content').check('required').message('Content is required')
@@ -263,8 +263,8 @@ module.exports = async function (Candy) {
263
263
  #### Example: User Authentication Validation
264
264
 
265
265
  ```javascript
266
- module.exports = async function (Candy) {
267
- const validator = Candy.Validator
266
+ module.exports = async function (Odac) {
267
+ const validator = Odac.Validator
268
268
 
269
269
  validator
270
270
  .post('current_password')
@@ -290,9 +290,9 @@ module.exports = async function (Candy) {
290
290
  You can use boolean values directly in `check()` for custom validation logic:
291
291
 
292
292
  ```javascript
293
- module.exports = async function (Candy) {
294
- const validator = Candy.Validator
295
- const userId = await Candy.request('user_id')
293
+ module.exports = async function (Odac) {
294
+ const validator = Odac.Validator
295
+ const userId = await Odac.request('user_id')
296
296
 
297
297
  const isOwner = await checkIfUserOwnsResource(userId)
298
298
  const hasPermission = await checkUserPermission('edit')
@@ -323,8 +323,8 @@ module.exports = async function (Candy) {
323
323
  #### Example: Chained Validation (Single Statement)
324
324
 
325
325
  ```javascript
326
- module.exports = async function (Candy) {
327
- return await Candy.Validator
326
+ module.exports = async function (Odac) {
327
+ return await Odac.Validator
328
328
  .post('email').check('required').message('Email required').check('email').message('Invalid email')
329
329
  .post('password').check('required').message('Password required').check('minlen:8').message('Min 8 chars')
330
330
  .post('age').check('required').message('Age required').check('numeric').message('Must be number').check('min:18').message('Must be 18+')
@@ -335,8 +335,8 @@ module.exports = async function (Candy) {
335
335
  #### Example: Admin-Only Action with User Check
336
336
 
337
337
  ```javascript
338
- module.exports = async function (Candy) {
339
- const validator = Candy.Validator
338
+ module.exports = async function (Odac) {
339
+ const validator = Odac.Validator
340
340
 
341
341
  validator
342
342
  .var('auth_check', null)
@@ -359,39 +359,39 @@ module.exports = async function (Candy) {
359
359
 
360
360
  #### Frontend Integration
361
361
 
362
- When using `Candy.form()` on the frontend, validation errors are automatically displayed:
362
+ When using `Odac.form()` on the frontend, validation errors are automatically displayed:
363
363
 
364
364
  **Automatic Error Display:**
365
- - Each field's error message appears below the input with attribute `[candy-form-error="fieldname"]`
366
- - Invalid inputs get the `_candy_error` CSS class automatically
365
+ - Each field's error message appears below the input with attribute `[odac-form-error="fieldname"]`
366
+ - Invalid inputs get the `_odac_error` CSS class automatically
367
367
  - Errors fade out when the user focuses on the input
368
368
 
369
369
  **Success Messages:**
370
- - Success messages appear in elements with `[candy-form-success]` attribute
370
+ - Success messages appear in elements with `[odac-form-success]` attribute
371
371
  - Automatically fades in when validation passes
372
372
 
373
373
  **Auto-Redirect:**
374
- - If you pass a URL as the second parameter to `Candy.form()`, successful submissions automatically redirect:
374
+ - If you pass a URL as the second parameter to `Odac.form()`, successful submissions automatically redirect:
375
375
  ```javascript
376
- Candy.form('myForm', '/dashboard') // Redirects to /dashboard on success
376
+ Odac.form('myForm', '/dashboard') // Redirects to /dashboard on success
377
377
  ```
378
378
 
379
379
  **Example HTML:**
380
380
  ```html
381
- <form candy-form="register" action="/api/register" method="POST">
381
+ <form odac-form="register" action="/api/register" method="POST">
382
382
  <input type="email" name="email" placeholder="Email">
383
- <span candy-form-error="email"></span>
383
+ <span odac-form-error="email"></span>
384
384
 
385
385
  <input type="password" name="password" placeholder="Password">
386
- <span candy-form-error="password"></span>
386
+ <span odac-form-error="password"></span>
387
387
 
388
388
  <button type="submit">Register</button>
389
389
 
390
- <span candy-form-success></span>
390
+ <span odac-form-success></span>
391
391
  </form>
392
392
 
393
393
  <script>
394
- Candy.form('register', '/dashboard') // Auto-redirect on success
394
+ Odac.form('register', '/dashboard') // Auto-redirect on success
395
395
  </script>
396
396
  ```
397
397
 
@@ -1,10 +1,10 @@
1
1
  ## 🔐 User Logins with `Auth.js`
2
2
 
3
- The `Candy.Auth` service is your bouncer, managing who gets in and who stays out. It handles user login sessions for you.
3
+ The `Odac.Auth` service is your bouncer, managing who gets in and who stays out. It handles user login sessions for you.
4
4
 
5
5
  #### Letting a User In
6
6
 
7
- `Candy.Auth.login(userId, userData)`
7
+ `Odac.Auth.login(userId, userData)`
8
8
 
9
9
  * `userId`: A unique ID for the user (like their database ID).
10
10
  * `userData`: An object with any user info you want to remember, like their username or role.
@@ -13,41 +13,41 @@ When you call this, `Auth` creates a secure session for the user.
13
13
 
14
14
  #### Checking the Guest List
15
15
 
16
- * `Candy.Auth.isLogin()`: Is the current user logged in? Returns `true` or `false`.
17
- * `Candy.Auth.getId()`: Gets the ID of the logged-in user.
18
- * `Candy.Auth.get('some-key')`: Grabs a specific piece of info from the `userData` you stored.
16
+ * `Odac.Auth.isLogin()`: Is the current user logged in? Returns `true` or `false`.
17
+ * `Odac.Auth.getId()`: Gets the ID of the logged-in user.
18
+ * `Odac.Auth.get('some-key')`: Grabs a specific piece of info from the `userData` you stored.
19
19
 
20
20
  #### Showing a User Out
21
21
 
22
- * `Candy.Auth.logout()`: Ends the user's session and logs them out.
22
+ * `Odac.Auth.logout()`: Ends the user's session and logs them out.
23
23
 
24
24
  #### Example: A Login Flow
25
25
  ```javascript
26
26
  // Controller for your login form
27
- module.exports = async function (Candy) {
28
- const { username, password } = Candy.Request.post;
27
+ module.exports = async function (Odac) {
28
+ const { username, password } = Odac.Request.post;
29
29
 
30
30
  // IMPORTANT: You need to write your own code to find the user in your database!
31
31
  const user = await yourDatabase.findUser(username, password);
32
32
 
33
33
  if (user) {
34
34
  // User is valid! Log them in.
35
- Candy.Auth.login(user.id, { username: user.username });
36
- return Candy.direct('/dashboard'); // Send them to their dashboard
35
+ Odac.Auth.login(user.id, { username: user.username });
36
+ return Odac.direct('/dashboard'); // Send them to their dashboard
37
37
  } else {
38
38
  // Bad credentials, send them back to the login page
39
- return Candy.direct('/login?error=1');
39
+ return Odac.direct('/login?error=1');
40
40
  }
41
41
  }
42
42
 
43
43
  // A protected dashboard page
44
- module.exports = function (Candy) {
44
+ module.exports = function (Odac) {
45
45
  // If they're not logged in, kick them back to the login page.
46
- if (!Candy.Auth.isLogin()) {
47
- return Candy.direct('/login');
46
+ if (!Odac.Auth.isLogin()) {
47
+ return Odac.direct('/login');
48
48
  }
49
49
 
50
- const username = Candy.Auth.get('username');
50
+ const username = Odac.Auth.get('username');
51
51
  return `Welcome back, ${username}!`;
52
52
  }
53
53
  ```
@@ -1,6 +1,6 @@
1
1
  ## 🛡️ Foiling Villains with CSRF Protection
2
2
 
3
- Cross-Site Request Forgery (CSRF) is a scary-sounding attack where a bad guy tries to trick your users into submitting forms they didn't mean to. The `Candy.Token` service is your shield against this!
3
+ Cross-Site Request Forgery (CSRF) is a scary-sounding attack where a bad guy tries to trick your users into submitting forms they didn't mean to. The `Odac.Token` service is your shield against this!
4
4
 
5
5
  #### How it Works
6
6
 
@@ -13,8 +13,8 @@ If they don't match, it's a trap!
13
13
 
14
14
  #### Generating and Checking Tokens
15
15
 
16
- * `Candy.Token.get()`: Creates a new secret token.
17
- * `Candy.Token.check(theToken)`: Checks if `theToken` is valid.
16
+ * `Odac.Token.get()`: Creates a new secret token.
17
+ * `Odac.Token.check(theToken)`: Checks if `theToken` is valid.
18
18
 
19
19
  #### Example: Securing a Form
20
20
 
@@ -31,22 +31,22 @@ If they don't match, it's a trap!
31
31
 
32
32
  **2. Your controller that shows the form:**
33
33
  ```javascript
34
- module.exports = function (Candy) {
34
+ module.exports = function (Odac) {
35
35
  // Get a token and pass it to the view
36
- const token = Candy.Token.get();
37
- return Candy.View.render('your_form_view', { csrfToken: token });
36
+ const token = Odac.Token.get();
37
+ return Odac.View.render('your_form_view', { csrfToken: token });
38
38
  }
39
39
  ```
40
40
 
41
41
  **3. Your controller that handles the form submission:**
42
42
  ```javascript
43
- module.exports = function (Candy) {
44
- const submittedToken = Candy.Request.post.csrf_token;
43
+ module.exports = function (Odac) {
44
+ const submittedToken = Odac.Request.post.csrf_token;
45
45
 
46
46
  // Check the token!
47
- if (!Candy.Token.check(submittedToken)) {
47
+ if (!Odac.Token.check(submittedToken)) {
48
48
  // If it's bad, stop right here.
49
- return Candy.return('Invalid CSRF Token!').status(403);
49
+ return Odac.return('Invalid CSRF Token!').status(403);
50
50
  }
51
51
 
52
52
  // If we get here, the token was good!
@@ -1,12 +1,12 @@
1
1
  # User Registration
2
2
 
3
- The `Candy.Auth.register()` method provides a secure and user-friendly way to create new user accounts with automatic password hashing, duplicate checking, and optional auto-login.
3
+ The `Odac.Auth.register()` method provides a secure and user-friendly way to create new user accounts with automatic password hashing, duplicate checking, and optional auto-login.
4
4
 
5
5
  ## Basic Usage
6
6
 
7
7
  ```javascript
8
- module.exports = async function (Candy) {
9
- const result = await Candy.Auth.register({
8
+ module.exports = async function (Odac) {
9
+ const result = await Odac.Auth.register({
10
10
  email: 'user@example.com',
11
11
  username: 'johndoe',
12
12
  password: 'securePassword123',
@@ -24,7 +24,7 @@ module.exports = async function (Candy) {
24
24
  ## Advanced Options
25
25
 
26
26
  ```javascript
27
- const result = await Candy.Auth.register(
27
+ const result = await Odac.Auth.register(
28
28
  {
29
29
  email: 'user@example.com',
30
30
  username: 'johndoe',
@@ -77,8 +77,8 @@ const result = await Candy.Auth.register(
77
77
  ## Example Controller
78
78
 
79
79
  ```javascript
80
- module.exports = async function (Candy) {
81
- const validator = Candy.Validator
80
+ module.exports = async function (Odac) {
81
+ const validator = Odac.Validator
82
82
 
83
83
  // Validate input
84
84
  validator.post('email').check('required|email').message('A valid email is required')
@@ -90,20 +90,20 @@ module.exports = async function (Candy) {
90
90
  }
91
91
 
92
92
  // Get validated data
93
- const email = await Candy.request('email')
94
- const username = await Candy.request('username')
95
- const password = await Candy.request('password')
96
- const name = await Candy.request('name')
93
+ const email = await Odac.request('email')
94
+ const username = await Odac.request('username')
95
+ const password = await Odac.request('password')
96
+ const name = await Odac.request('name')
97
97
 
98
98
  // Register user
99
- const result = await Candy.Auth.register(
99
+ const result = await Odac.Auth.register(
100
100
  {email, username, password, name},
101
101
  {uniqueFields: ['email', 'username']}
102
102
  )
103
103
 
104
104
  if (result.success) {
105
105
  // User is now registered and logged in
106
- return Candy.direct('/dashboard')
106
+ return Odac.direct('/dashboard')
107
107
  } else {
108
108
  // Show error message
109
109
  return {error: result.error}