@dyrected/core 2.5.24 → 2.5.26

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 (169) hide show
  1. package/dist/__tests__/app.test.d.ts +2 -0
  2. package/dist/__tests__/app.test.d.ts.map +1 -0
  3. package/dist/__tests__/app.test.js +27 -0
  4. package/dist/__tests__/app.test.js.map +1 -0
  5. package/dist/__tests__/config.test.d.ts +2 -0
  6. package/dist/__tests__/config.test.d.ts.map +1 -0
  7. package/dist/__tests__/config.test.js +34 -0
  8. package/dist/__tests__/config.test.js.map +1 -0
  9. package/dist/__tests__/deleteMany.test.d.ts +2 -0
  10. package/dist/__tests__/deleteMany.test.d.ts.map +1 -0
  11. package/dist/__tests__/deleteMany.test.js +75 -0
  12. package/dist/__tests__/deleteMany.test.js.map +1 -0
  13. package/dist/__tests__/depth.test.d.ts +2 -0
  14. package/dist/__tests__/depth.test.d.ts.map +1 -0
  15. package/dist/__tests__/depth.test.js +81 -0
  16. package/dist/__tests__/depth.test.js.map +1 -0
  17. package/dist/__tests__/dynamic-options.test.d.ts +2 -0
  18. package/dist/__tests__/dynamic-options.test.d.ts.map +1 -0
  19. package/dist/__tests__/dynamic-options.test.js +132 -0
  20. package/dist/__tests__/dynamic-options.test.js.map +1 -0
  21. package/dist/__tests__/field-inference.test-types.d.ts +24 -0
  22. package/dist/__tests__/field-inference.test-types.d.ts.map +1 -0
  23. package/dist/__tests__/field-inference.test-types.js +87 -0
  24. package/dist/__tests__/field-inference.test-types.js.map +1 -0
  25. package/dist/__tests__/hooks.test.d.ts +2 -0
  26. package/dist/__tests__/hooks.test.d.ts.map +1 -0
  27. package/dist/__tests__/hooks.test.js +320 -0
  28. package/dist/__tests__/hooks.test.js.map +1 -0
  29. package/dist/__tests__/mocks.d.ts +68 -0
  30. package/dist/__tests__/mocks.d.ts.map +1 -0
  31. package/dist/__tests__/mocks.js +151 -0
  32. package/dist/__tests__/mocks.js.map +1 -0
  33. package/dist/__tests__/router.test.d.ts +2 -0
  34. package/dist/__tests__/router.test.d.ts.map +1 -0
  35. package/dist/__tests__/router.test.js +48 -0
  36. package/dist/__tests__/router.test.js.map +1 -0
  37. package/dist/__tests__/where.test.d.ts +2 -0
  38. package/dist/__tests__/where.test.d.ts.map +1 -0
  39. package/dist/__tests__/where.test.js +97 -0
  40. package/dist/__tests__/where.test.js.map +1 -0
  41. package/dist/app-BOrsS7Tz.d.cts +1771 -0
  42. package/dist/app-BOrsS7Tz.d.ts +1771 -0
  43. package/dist/app-BibuoHQG.d.cts +1764 -0
  44. package/dist/app-BibuoHQG.d.ts +1764 -0
  45. package/dist/app-aW2FMuYM.d.cts +1759 -0
  46. package/dist/app-aW2FMuYM.d.ts +1759 -0
  47. package/dist/app.d.ts +21 -0
  48. package/dist/app.d.ts.map +1 -0
  49. package/dist/app.js +56 -0
  50. package/dist/app.js.map +1 -0
  51. package/dist/auth/jexl.d.ts +10 -0
  52. package/dist/auth/jexl.d.ts.map +1 -0
  53. package/dist/auth/jexl.js +22 -0
  54. package/dist/auth/jexl.js.map +1 -0
  55. package/dist/auth/password.d.ts +10 -0
  56. package/dist/auth/password.d.ts.map +1 -0
  57. package/dist/auth/password.js +28 -0
  58. package/dist/auth/password.js.map +1 -0
  59. package/dist/auth/token.d.ts +20 -0
  60. package/dist/auth/token.d.ts.map +1 -0
  61. package/dist/auth/token.js +40 -0
  62. package/dist/auth/token.js.map +1 -0
  63. package/dist/chunk-4EDMZAM5.js +2692 -0
  64. package/dist/chunk-FDQYPPG3.js +2698 -0
  65. package/dist/chunk-NKDX67AW.js +2698 -0
  66. package/dist/chunk-SUGK7UYL.js +311 -0
  67. package/dist/chunk-ZFAOBRHT.js +2709 -0
  68. package/dist/controllers/auth.controller.d.ts +125 -0
  69. package/dist/controllers/auth.controller.d.ts.map +1 -0
  70. package/dist/controllers/auth.controller.js +323 -0
  71. package/dist/controllers/auth.controller.js.map +1 -0
  72. package/dist/controllers/collection.controller.d.ts +88 -0
  73. package/dist/controllers/collection.controller.d.ts.map +1 -0
  74. package/dist/controllers/collection.controller.js +554 -0
  75. package/dist/controllers/collection.controller.js.map +1 -0
  76. package/dist/controllers/global.controller.d.ts +17 -0
  77. package/dist/controllers/global.controller.d.ts.map +1 -0
  78. package/dist/controllers/global.controller.js +116 -0
  79. package/dist/controllers/global.controller.js.map +1 -0
  80. package/dist/controllers/media.controller.d.ts +36 -0
  81. package/dist/controllers/media.controller.d.ts.map +1 -0
  82. package/dist/controllers/media.controller.js +155 -0
  83. package/dist/controllers/media.controller.js.map +1 -0
  84. package/dist/controllers/preview.controller.d.ts +37 -0
  85. package/dist/controllers/preview.controller.d.ts.map +1 -0
  86. package/dist/controllers/preview.controller.js +48 -0
  87. package/dist/controllers/preview.controller.js.map +1 -0
  88. package/dist/index-Bp7PDOYG.d.cts +1750 -0
  89. package/dist/index-Bp7PDOYG.d.ts +1750 -0
  90. package/dist/index-DfAmTZXk.d.cts +1749 -0
  91. package/dist/index-DfAmTZXk.d.ts +1749 -0
  92. package/dist/index.cjs +19 -2324
  93. package/dist/index.d.cts +5 -6
  94. package/dist/index.d.ts +5 -6
  95. package/dist/index.d.ts.map +1 -0
  96. package/dist/index.js +3 -5
  97. package/dist/index.js.map +1 -0
  98. package/dist/middleware/auth.d.ts +18 -0
  99. package/dist/middleware/auth.d.ts.map +1 -0
  100. package/dist/middleware/auth.js +45 -0
  101. package/dist/middleware/auth.js.map +1 -0
  102. package/dist/router.d.ts +8 -0
  103. package/dist/router.d.ts.map +1 -0
  104. package/dist/router.js +463 -0
  105. package/dist/router.js.map +1 -0
  106. package/dist/server.cjs +237 -45
  107. package/dist/server.d.cts +22 -4
  108. package/dist/server.d.ts +22 -4
  109. package/dist/server.d.ts.map +1 -0
  110. package/dist/server.js +2429 -8
  111. package/dist/server.js.map +1 -0
  112. package/dist/services/audit.service.d.ts +23 -0
  113. package/dist/services/audit.service.d.ts.map +1 -0
  114. package/dist/services/audit.service.js +28 -0
  115. package/dist/services/audit.service.js.map +1 -0
  116. package/dist/services/defaults.service.d.ts +8 -0
  117. package/dist/services/defaults.service.d.ts.map +1 -0
  118. package/dist/services/defaults.service.js +55 -0
  119. package/dist/services/defaults.service.js.map +1 -0
  120. package/dist/services/email.service.d.ts +33 -0
  121. package/dist/services/email.service.d.ts.map +1 -0
  122. package/dist/services/email.service.js +219 -0
  123. package/dist/services/email.service.js.map +1 -0
  124. package/dist/services/media.service.d.ts +20 -0
  125. package/dist/services/media.service.d.ts.map +1 -0
  126. package/dist/services/media.service.js +49 -0
  127. package/dist/services/media.service.js.map +1 -0
  128. package/dist/services/population.service.d.ts +20 -0
  129. package/dist/services/population.service.d.ts.map +1 -0
  130. package/dist/services/population.service.js +168 -0
  131. package/dist/services/population.service.js.map +1 -0
  132. package/dist/types/index.d.ts +1749 -0
  133. package/dist/types/index.d.ts.map +1 -0
  134. package/dist/types/index.js +3 -0
  135. package/dist/types/index.js.map +1 -0
  136. package/dist/utils/config.d.ts +8 -0
  137. package/dist/utils/config.d.ts.map +1 -0
  138. package/dist/utils/config.js +153 -0
  139. package/dist/utils/config.js.map +1 -0
  140. package/dist/utils/hooks.d.ts +41 -0
  141. package/dist/utils/hooks.d.ts.map +1 -0
  142. package/dist/utils/hooks.js +169 -0
  143. package/dist/utils/hooks.js.map +1 -0
  144. package/dist/utils/openapi.d.ts +6 -0
  145. package/dist/utils/openapi.d.ts.map +1 -0
  146. package/dist/utils/openapi.js +331 -0
  147. package/dist/utils/openapi.js.map +1 -0
  148. package/dist/utils/parse-where.d.ts +63 -0
  149. package/dist/utils/parse-where.d.ts.map +1 -0
  150. package/dist/utils/parse-where.js +196 -0
  151. package/dist/utils/parse-where.js.map +1 -0
  152. package/dist/utils/readonly-db.d.ts +9 -0
  153. package/dist/utils/readonly-db.d.ts.map +1 -0
  154. package/dist/utils/readonly-db.js +21 -0
  155. package/dist/utils/readonly-db.js.map +1 -0
  156. package/dist/utils/setup-prompt.d.ts +11 -0
  157. package/dist/utils/setup-prompt.d.ts.map +1 -0
  158. package/dist/utils/setup-prompt.js +863 -0
  159. package/dist/utils/setup-prompt.js.map +1 -0
  160. package/dist/utils/swagger.d.ts +5 -0
  161. package/dist/utils/swagger.d.ts.map +1 -0
  162. package/dist/utils/swagger.js +51 -0
  163. package/dist/utils/swagger.js.map +1 -0
  164. package/dist/utils/where-sanitizer.d.ts +10 -0
  165. package/dist/utils/where-sanitizer.d.ts.map +1 -0
  166. package/dist/utils/where-sanitizer.js +63 -0
  167. package/dist/utils/where-sanitizer.js.map +1 -0
  168. package/dist/where-sanitizer-DQIWTQZW.js +50 -0
  169. package/package.json +1 -1
@@ -0,0 +1,125 @@
1
+ import type { Context } from "hono";
2
+ import type { DyrectedContext } from "../app.js";
3
+ import type { CollectionConfig } from "../types/index.js";
4
+ /**
5
+ * Handles auth endpoints for collections with `auth: true`.
6
+ *
7
+ * Routes registered (relative to `/api/collections/:slug`):
8
+ * POST /login
9
+ * POST /logout (stateless — client drops the token)
10
+ * GET /me
11
+ * POST /refresh-token
12
+ * POST /forgot-password
13
+ * POST /reset-password
14
+ * POST /invite
15
+ * POST /accept-invite
16
+ */
17
+ export declare class AuthController {
18
+ private collection;
19
+ constructor(collection: CollectionConfig);
20
+ init(c: Context<DyrectedContext>): Promise<(Response & import("hono").TypedResponse<{
21
+ message: string;
22
+ }, 500, "json">) | (Response & import("hono").TypedResponse<{
23
+ initialized: boolean;
24
+ }, import("hono/utils/http-status").ContentfulStatusCode, "json">)>;
25
+ registerFirstUser(c: Context<DyrectedContext>): Promise<(Response & import("hono").TypedResponse<{
26
+ message: string;
27
+ }, 500, "json">) | (Response & import("hono").TypedResponse<{
28
+ error: true;
29
+ message: string;
30
+ }, 403, "json">) | (Response & import("hono").TypedResponse<{
31
+ error: true;
32
+ message: string;
33
+ }, 400, "json">) | (Response & import("hono").TypedResponse<{
34
+ token: string;
35
+ user: {
36
+ [x: string]: any;
37
+ id: string;
38
+ };
39
+ }, import("hono/utils/http-status").ContentfulStatusCode, "json">)>;
40
+ login(c: Context<DyrectedContext>): Promise<(Response & import("hono").TypedResponse<{
41
+ message: string;
42
+ }, 500, "json">) | (Response & import("hono").TypedResponse<{
43
+ error: true;
44
+ message: string;
45
+ }, 400, "json">) | (Response & import("hono").TypedResponse<{
46
+ error: true;
47
+ message: string;
48
+ }, 401, "json">) | (Response & import("hono").TypedResponse<{
49
+ token: string;
50
+ user: {
51
+ [x: string]: any;
52
+ };
53
+ }, import("hono/utils/http-status").ContentfulStatusCode, "json">)>;
54
+ logout(c: Context<DyrectedContext>): Promise<Response & import("hono").TypedResponse<{
55
+ success: true;
56
+ message: string;
57
+ }, import("hono/utils/http-status").ContentfulStatusCode, "json">>;
58
+ me(c: Context<DyrectedContext>): Promise<(Response & import("hono").TypedResponse<{
59
+ message: string;
60
+ }, 500, "json">) | (Response & import("hono").TypedResponse<{
61
+ error: true;
62
+ message: string;
63
+ }, 401, "json">) | (Response & import("hono").TypedResponse<{
64
+ error: true;
65
+ message: string;
66
+ }, 404, "json">) | (Response & import("hono").TypedResponse<{
67
+ [x: string]: any;
68
+ id: string;
69
+ }, import("hono/utils/http-status").ContentfulStatusCode, "json">)>;
70
+ refreshToken(c: Context<DyrectedContext>): Promise<(Response & import("hono").TypedResponse<{
71
+ error: true;
72
+ message: string;
73
+ }, 401, "json">) | (Response & import("hono").TypedResponse<{
74
+ token: string;
75
+ }, import("hono/utils/http-status").ContentfulStatusCode, "json">)>;
76
+ forgotPassword(c: Context<DyrectedContext>): Promise<(Response & import("hono").TypedResponse<{
77
+ message: string;
78
+ }, 500, "json">) | (Response & import("hono").TypedResponse<{
79
+ error: true;
80
+ message: string;
81
+ }, 400, "json">) | (Response & import("hono").TypedResponse<{
82
+ success: true;
83
+ message: string;
84
+ }, import("hono/utils/http-status").ContentfulStatusCode, "json">)>;
85
+ resetPassword(c: Context<DyrectedContext>): Promise<(Response & import("hono").TypedResponse<{
86
+ message: string;
87
+ }, 500, "json">) | (Response & import("hono").TypedResponse<{
88
+ error: true;
89
+ message: string;
90
+ }, 400, "json">) | (Response & import("hono").TypedResponse<{
91
+ success: true;
92
+ message: string;
93
+ }, import("hono/utils/http-status").ContentfulStatusCode, "json">)>;
94
+ invite(c: Context<DyrectedContext>): Promise<(Response & import("hono").TypedResponse<{
95
+ message: string;
96
+ }, 500, "json">) | (Response & import("hono").TypedResponse<{
97
+ error: true;
98
+ message: string;
99
+ }, 401, "json">) | (Response & import("hono").TypedResponse<{
100
+ error: true;
101
+ message: string;
102
+ }, 400, "json">) | (Response & import("hono").TypedResponse<{
103
+ error: true;
104
+ message: string;
105
+ }, 409, "json">) | (Response & import("hono").TypedResponse<{
106
+ success: true;
107
+ message: string;
108
+ }, import("hono/utils/http-status").ContentfulStatusCode, "json">)>;
109
+ acceptInvite(c: Context<DyrectedContext>): Promise<(Response & import("hono").TypedResponse<{
110
+ message: string;
111
+ }, 500, "json">) | (Response & import("hono").TypedResponse<{
112
+ error: true;
113
+ message: string;
114
+ }, 400, "json">) | (Response & import("hono").TypedResponse<{
115
+ error: true;
116
+ message: string;
117
+ }, 409, "json">) | (Response & import("hono").TypedResponse<{
118
+ token: string;
119
+ user: {
120
+ [x: string]: any;
121
+ id: string;
122
+ };
123
+ }, 201, "json">)>;
124
+ }
125
+ //# sourceMappingURL=auth.controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.controller.d.ts","sourceRoot":"","sources":["../../src/controllers/auth.controller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAW1D;;;;;;;;;;;;GAYG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,UAAU,CAAmB;gBAEzB,UAAU,EAAE,gBAAgB;IAQlC,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;;;;;IAkBhC,iBAAiB,CAAC,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;;;;;;;;;;;;;;;IAmD7C,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;;;;;;;;;;;;;;IA0CjC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;;;;IAOlC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;;;;;;;;;;;;IAqB9B,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;;;;;;IAoBxC,cAAc,CAAC,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;;;;;;;;;IAgD1C,aAAa,CAAC,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;;;;;;;;;IA0CzC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;;;;;;;;;;;;;;;IAiDlC,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;;;;;;;;;;;;;;;CAwD/C"}
@@ -0,0 +1,323 @@
1
+ import { hashPassword, verifyPassword } from "../auth/password.js";
2
+ import { signCollectionToken, verifyCollectionToken } from "../auth/token.js";
3
+ import { sendEmail, buildWelcomeEmail, buildInviteEmail, buildResetPasswordEmail, buildPasswordChangedEmail, } from "../services/email.service.js";
4
+ /**
5
+ * Handles auth endpoints for collections with `auth: true`.
6
+ *
7
+ * Routes registered (relative to `/api/collections/:slug`):
8
+ * POST /login
9
+ * POST /logout (stateless — client drops the token)
10
+ * GET /me
11
+ * POST /refresh-token
12
+ * POST /forgot-password
13
+ * POST /reset-password
14
+ * POST /invite
15
+ * POST /accept-invite
16
+ */
17
+ export class AuthController {
18
+ collection;
19
+ constructor(collection) {
20
+ this.collection = collection;
21
+ }
22
+ // ---------------------------------------------------------------------------
23
+ // GET /init
24
+ // Checks if the first user needs to be created.
25
+ // ---------------------------------------------------------------------------
26
+ async init(c) {
27
+ const db = c.get("config").db;
28
+ if (!db)
29
+ return c.json({ message: "Database not configured" }, 500);
30
+ const result = await db.find({
31
+ collection: this.collection.slug,
32
+ limit: 1,
33
+ });
34
+ return c.json({
35
+ initialized: result.total > 0,
36
+ });
37
+ }
38
+ // ---------------------------------------------------------------------------
39
+ // POST /first-user
40
+ // Creates the first user if none exist.
41
+ // ---------------------------------------------------------------------------
42
+ async registerFirstUser(c) {
43
+ const config = c.get("config");
44
+ const db = config.db;
45
+ if (!db)
46
+ return c.json({ message: "Database not configured" }, 500);
47
+ // 1. Check if users already exist
48
+ const check = await db.find({
49
+ collection: this.collection.slug,
50
+ limit: 1,
51
+ });
52
+ if (check.total > 0) {
53
+ return c.json({ error: true, message: "Initial user already exists." }, 403);
54
+ }
55
+ const body = await c.req.json().catch(() => null);
56
+ if (!body?.email || !body?.password) {
57
+ return c.json({ error: true, message: "email and password are required." }, 400);
58
+ }
59
+ // 2. Create the user
60
+ const hashedPassword = await hashPassword(body.password);
61
+ const user = await db.create({
62
+ collection: this.collection.slug,
63
+ data: {
64
+ ...body,
65
+ password: hashedPassword,
66
+ roles: ["admin"], // Default first user to admin
67
+ },
68
+ });
69
+ // 3. Log them in immediately
70
+ const token = await signCollectionToken({
71
+ sub: user.id,
72
+ email: user.email,
73
+ collection: this.collection.slug,
74
+ });
75
+ // Send welcome email (best-effort — never block login)
76
+ const { subject, html } = buildWelcomeEmail(config, { email: body.email });
77
+ sendEmail(config, { to: body.email, subject, html }).catch((err) => console.error("[dyrected/core] Failed to send welcome email:", err));
78
+ const { password: _, ...safeUser } = user;
79
+ return c.json({ token, user: safeUser });
80
+ }
81
+ // ---------------------------------------------------------------------------
82
+ // POST /login
83
+ // ---------------------------------------------------------------------------
84
+ async login(c) {
85
+ const db = c.get("config").db;
86
+ if (!db)
87
+ return c.json({ message: "Database not configured" }, 500);
88
+ const body = await c.req.json().catch(() => null);
89
+ if (!body?.email || !body?.password) {
90
+ return c.json({ error: true, message: "email and password are required." }, 400);
91
+ }
92
+ const result = await db.find({
93
+ collection: this.collection.slug,
94
+ where: { email: body.email },
95
+ limit: 1,
96
+ });
97
+ const user = result.docs[0];
98
+ if (!user) {
99
+ return c.json({ error: true, message: "Invalid email or password." }, 401);
100
+ }
101
+ const valid = await verifyPassword(body.password, user.password);
102
+ if (!valid) {
103
+ return c.json({ error: true, message: "Invalid email or password." }, 401);
104
+ }
105
+ const token = await signCollectionToken({
106
+ sub: user.id,
107
+ email: user.email,
108
+ collection: this.collection.slug,
109
+ });
110
+ // Strip password before returning
111
+ const { password: _, ...safeUser } = user;
112
+ return c.json({ token, user: safeUser });
113
+ }
114
+ // ---------------------------------------------------------------------------
115
+ // POST /logout
116
+ // Auth collections use stateless JWTs — logout is handled client-side.
117
+ // This endpoint exists so clients have a consistent API surface.
118
+ // ---------------------------------------------------------------------------
119
+ async logout(c) {
120
+ return c.json({ success: true, message: "Logged out. Discard your token." });
121
+ }
122
+ // ---------------------------------------------------------------------------
123
+ // GET /me
124
+ // ---------------------------------------------------------------------------
125
+ async me(c) {
126
+ const db = c.get("config").db;
127
+ if (!db)
128
+ return c.json({ message: "Database not configured" }, 500);
129
+ const requestUser = c.get("user");
130
+ if (!requestUser) {
131
+ return c.json({ error: true, message: "Authentication required." }, 401);
132
+ }
133
+ const user = await db.findOne({ collection: this.collection.slug, id: requestUser.sub });
134
+ if (!user) {
135
+ return c.json({ error: true, message: "User not found." }, 404);
136
+ }
137
+ const { password: _, ...safeUser } = user;
138
+ return c.json(safeUser);
139
+ }
140
+ // ---------------------------------------------------------------------------
141
+ // POST /refresh-token
142
+ // ---------------------------------------------------------------------------
143
+ async refreshToken(c) {
144
+ const requestUser = c.get("user");
145
+ if (!requestUser) {
146
+ return c.json({ error: true, message: "Authentication required." }, 401);
147
+ }
148
+ const token = await signCollectionToken({
149
+ sub: requestUser.sub,
150
+ email: requestUser.email,
151
+ collection: this.collection.slug,
152
+ });
153
+ return c.json({ token });
154
+ }
155
+ // ---------------------------------------------------------------------------
156
+ // POST /forgot-password
157
+ // Requires config.email to be set. Silently succeeds if email not found
158
+ // to prevent email enumeration.
159
+ // ---------------------------------------------------------------------------
160
+ async forgotPassword(c) {
161
+ const config = c.get("config");
162
+ const db = config.db;
163
+ if (!db)
164
+ return c.json({ message: "Database not configured" }, 500);
165
+ const body = await c.req.json().catch(() => null);
166
+ if (!body?.email) {
167
+ return c.json({ error: true, message: "email is required." }, 400);
168
+ }
169
+ const result = await db.find({
170
+ collection: this.collection.slug,
171
+ where: { email: body.email },
172
+ limit: 1,
173
+ });
174
+ const user = result.docs[0];
175
+ if (user) {
176
+ // Issue a short-lived reset token (1-hour)
177
+ const resetToken = await signCollectionToken({ sub: user.id, email: user.email, collection: this.collection.slug, purpose: "reset" }, "1h");
178
+ // Append token to resetUrl if provided
179
+ const resetUrl = body?.resetUrl;
180
+ const url = resetUrl ? `${resetUrl}${resetUrl.includes("?") ? "&" : "?"}token=${encodeURIComponent(resetToken)}` : undefined;
181
+ try {
182
+ const { subject, html } = buildResetPasswordEmail(config, { token: resetToken, url });
183
+ await sendEmail(config, { to: user.email, subject, html });
184
+ }
185
+ catch (err) {
186
+ console.error("[dyrected/core] Failed to send password reset email:", err);
187
+ }
188
+ }
189
+ return c.json({
190
+ success: true,
191
+ message: "If an account with that email exists, a reset link has been sent.",
192
+ });
193
+ }
194
+ // ---------------------------------------------------------------------------
195
+ // POST /reset-password
196
+ // Expects { token: string, password: string } in body.
197
+ // The token is the reset JWT issued by /forgot-password.
198
+ // ---------------------------------------------------------------------------
199
+ async resetPassword(c) {
200
+ const config = c.get("config");
201
+ const db = config.db;
202
+ if (!db)
203
+ return c.json({ message: "Database not configured" }, 500);
204
+ const body = await c.req.json().catch(() => null);
205
+ if (!body?.token || !body?.password) {
206
+ return c.json({ error: true, message: "token and password are required." }, 400);
207
+ }
208
+ // Verify the reset token
209
+ let payload;
210
+ try {
211
+ payload = await verifyCollectionToken(body.token);
212
+ }
213
+ catch {
214
+ return c.json({ error: true, message: "Reset token is invalid or has expired." }, 400);
215
+ }
216
+ if (payload.collection !== this.collection.slug || payload.purpose !== "reset") {
217
+ return c.json({ error: true, message: "Reset token is invalid or has expired." }, 400);
218
+ }
219
+ const hashedPassword = await hashPassword(body.password);
220
+ await db.update({
221
+ collection: this.collection.slug,
222
+ id: payload.sub,
223
+ data: { password: hashedPassword },
224
+ });
225
+ // Notify the user their password was changed (security alert)
226
+ const { subject, html } = buildPasswordChangedEmail(config, { email: payload.email });
227
+ sendEmail(config, { to: payload.email, subject, html }).catch((err) => console.error("[dyrected/core] Failed to send password-changed email:", err));
228
+ return c.json({ success: true, message: "Password has been reset. You can now log in." });
229
+ }
230
+ // ---------------------------------------------------------------------------
231
+ // POST /invite
232
+ // Requires auth. Issues a signed invite token and emails it to the invitee.
233
+ // ---------------------------------------------------------------------------
234
+ async invite(c) {
235
+ const config = c.get("config");
236
+ const db = config.db;
237
+ if (!db)
238
+ return c.json({ message: "Database not configured" }, 500);
239
+ const requestUser = c.get("user");
240
+ if (!requestUser) {
241
+ return c.json({ error: true, message: "Authentication required." }, 401);
242
+ }
243
+ const body = await c.req.json().catch(() => null);
244
+ if (!body?.email) {
245
+ return c.json({ error: true, message: "email is required." }, 400);
246
+ }
247
+ // Prevent inviting an email that already has an account
248
+ const existing = await db.find({
249
+ collection: this.collection.slug,
250
+ where: { email: body.email },
251
+ limit: 1,
252
+ });
253
+ if (existing.total > 0) {
254
+ return c.json({ error: true, message: "An account with that email already exists." }, 409);
255
+ }
256
+ // sub = invitee email (no user doc yet); purpose = 'invite'
257
+ const inviteToken = await signCollectionToken({ sub: body.email, email: body.email, collection: this.collection.slug, purpose: "invite" }, "7d");
258
+ try {
259
+ const { subject, html } = buildInviteEmail(config, {
260
+ token: inviteToken,
261
+ invitedByEmail: requestUser.email,
262
+ });
263
+ await sendEmail(config, { to: body.email, subject, html });
264
+ }
265
+ catch (err) {
266
+ console.error("[dyrected/core] Failed to send invite email:", err);
267
+ }
268
+ return c.json({ success: true, message: `Invite sent to ${body.email}.` });
269
+ }
270
+ // ---------------------------------------------------------------------------
271
+ // POST /accept-invite
272
+ // Public. Validates the invite token and creates the user account.
273
+ // Body: { token, password, ...extraFields }
274
+ // ---------------------------------------------------------------------------
275
+ async acceptInvite(c) {
276
+ const config = c.get("config");
277
+ const db = config.db;
278
+ if (!db)
279
+ return c.json({ message: "Database not configured" }, 500);
280
+ const body = await c.req.json().catch(() => null);
281
+ if (!body?.token || !body?.password) {
282
+ return c.json({ error: true, message: "token and password are required." }, 400);
283
+ }
284
+ let payload;
285
+ try {
286
+ payload = await verifyCollectionToken(body.token);
287
+ }
288
+ catch {
289
+ return c.json({ error: true, message: "Invite token is invalid or has expired." }, 400);
290
+ }
291
+ if (payload.collection !== this.collection.slug || payload.purpose !== "invite") {
292
+ return c.json({ error: true, message: "Invite token is invalid or has expired." }, 400);
293
+ }
294
+ const inviteeEmail = payload.sub;
295
+ // Guard against double-accept
296
+ const existing = await db.find({
297
+ collection: this.collection.slug,
298
+ where: { email: inviteeEmail },
299
+ limit: 1,
300
+ });
301
+ if (existing.total > 0) {
302
+ return c.json({ error: true, message: "An account with that email already exists." }, 409);
303
+ }
304
+ const { token: _t, password: _p, ...extraFields } = body;
305
+ const hashedPassword = await hashPassword(body.password);
306
+ const user = await db.create({
307
+ collection: this.collection.slug,
308
+ data: { ...extraFields, email: inviteeEmail, password: hashedPassword },
309
+ });
310
+ // Log them in immediately
311
+ const sessionToken = await signCollectionToken({
312
+ sub: user.id,
313
+ email: inviteeEmail,
314
+ collection: this.collection.slug,
315
+ });
316
+ // Send welcome email (best-effort)
317
+ const { subject, html } = buildWelcomeEmail(config, { email: inviteeEmail });
318
+ sendEmail(config, { to: inviteeEmail, subject, html }).catch((err) => console.error("[dyrected/core] Failed to send welcome email:", err));
319
+ const { password: _, ...safeUser } = user;
320
+ return c.json({ token: sessionToken, user: safeUser }, 201);
321
+ }
322
+ }
323
+ //# sourceMappingURL=auth.controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.controller.js","sourceRoot":"","sources":["../../src/controllers/auth.controller.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,88 @@
1
+ import type { Context } from 'hono';
2
+ import type { CollectionConfig } from '../types/index.js';
3
+ import type { DyrectedContext } from '../app.js';
4
+ export declare class CollectionController {
5
+ private collection;
6
+ constructor(collection: CollectionConfig);
7
+ find(c: Context<DyrectedContext>): Promise<(Response & import("hono").TypedResponse<{
8
+ message: string;
9
+ }, 500, "json">) | (Response & import("hono").TypedResponse<{
10
+ docs: {
11
+ [x: string]: any;
12
+ }[];
13
+ total: number;
14
+ limit: number;
15
+ page: number;
16
+ totalPages: number;
17
+ hasNextPage: boolean;
18
+ hasPrevPage: boolean;
19
+ }, import("hono/utils/http-status").ContentfulStatusCode, "json">)>;
20
+ findOne(c: Context<DyrectedContext>): Promise<Response & import("hono").TypedResponse<any, import("hono/utils/http-status").ContentfulStatusCode, "json">>;
21
+ create(c: Context<DyrectedContext>): Promise<(Response & import("hono").TypedResponse<{
22
+ message: string;
23
+ }, 500, "json">) | (Response & import("hono").TypedResponse<{
24
+ message: string;
25
+ }, 400, "json">) | (Response & import("hono").TypedResponse<{
26
+ [x: string]: import("hono/utils/types").JSONValue;
27
+ }, 201, "json">)>;
28
+ upload(c: Context<DyrectedContext>): Promise<(Response & import("hono").TypedResponse<{
29
+ message: string;
30
+ }, 500, "json">) | (Response & import("hono").TypedResponse<{
31
+ message: string;
32
+ }, 400, "json">) | (Response & import("hono").TypedResponse<{
33
+ [x: string]: import("hono/utils/types").JSONValue;
34
+ }, 201, "json">)>;
35
+ update(c: Context<DyrectedContext>): Promise<(Response & import("hono").TypedResponse<{
36
+ [x: string]: import("hono/utils/types").JSONValue;
37
+ }, import("hono/utils/http-status").ContentfulStatusCode, "json">) | (Response & import("hono").TypedResponse<{
38
+ message: string;
39
+ }, 500, "json">) | (Response & import("hono").TypedResponse<{
40
+ message: string;
41
+ }, 400, "json">) | (Response & import("hono").TypedResponse<{
42
+ message: string;
43
+ }, 404, "json">)>;
44
+ /**
45
+ * POST /api/collections/:slug/:id/change-password
46
+ *
47
+ * Dedicated endpoint for password changes. Requires the caller to supply:
48
+ * { oldPassword, newPassword, confirmPassword }
49
+ *
50
+ * Rules:
51
+ * - Only the account owner or an admin may change the password.
52
+ * - Non-admin callers MUST provide a valid oldPassword.
53
+ * - newPassword and confirmPassword must match.
54
+ */
55
+ changePassword(c: Context<DyrectedContext>): Promise<(Response & import("hono").TypedResponse<{
56
+ message: string;
57
+ }, 500, "json">) | (Response & import("hono").TypedResponse<{
58
+ message: string;
59
+ }, 400, "json">) | (Response & import("hono").TypedResponse<{
60
+ message: string;
61
+ }, 401, "json">) | (Response & import("hono").TypedResponse<{
62
+ message: string;
63
+ }, 403, "json">) | (Response & import("hono").TypedResponse<{
64
+ message: string;
65
+ }, 404, "json">) | (Response & import("hono").TypedResponse<{
66
+ success: true;
67
+ message: string;
68
+ }, import("hono/utils/http-status").ContentfulStatusCode, "json">)>;
69
+ delete(c: Context<DyrectedContext>): Promise<Response & import("hono").TypedResponse<{
70
+ message: string;
71
+ }, import("hono/utils/http-status").ContentfulStatusCode, "json">>;
72
+ deleteMany(c: Context<DyrectedContext>): Promise<(Response & import("hono").TypedResponse<{
73
+ message: string;
74
+ }, 500, "json">) | (Response & import("hono").TypedResponse<{
75
+ message: string;
76
+ }, 400, "json">) | (Response & import("hono").TypedResponse<{
77
+ failed?: {
78
+ id: string;
79
+ error: string;
80
+ }[] | undefined;
81
+ message: string;
82
+ deleted: string[];
83
+ }, import("hono/utils/http-status").ContentfulStatusCode, "json">)>;
84
+ seed(c: Context<DyrectedContext>): Promise<Response & import("hono").TypedResponse<{
85
+ message: string;
86
+ }, import("hono/utils/http-status").ContentfulStatusCode, "json">>;
87
+ }
88
+ //# sourceMappingURL=collection.controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collection.controller.d.ts","sourceRoot":"","sources":["../../src/controllers/collection.controller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAQjD,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,UAAU,CAAmB;gBAEzB,UAAU,EAAE,gBAAgB;IAIlC,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;;;;;;;;;;;;;IA8FhC,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;IAuCnC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;;;;;;;IAwElC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;;;;;;;IAgFlC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;;;;;;;;;IA+ExC;;;;;;;;;;OAUG;IACG,cAAc,CAAC,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;;;;;;;;;;;;;;IA2E1C,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;;;IAqDlC,UAAU,CAAC,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;;;;;;gBA2BtB,MAAM;mBAAS,MAAM;;;;;IA0DrC,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;;;CA0BvC"}