@meridianjs/meridian 1.19.0 → 1.21.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 (29) hide show
  1. package/dist/api/admin/issues/route.d.ts.map +1 -1
  2. package/dist/api/admin/issues/route.js +5 -38
  3. package/dist/api/admin/issues/route.js.map +1 -1
  4. package/dist/api/auth/google/callback/route.d.ts.map +1 -1
  5. package/dist/api/auth/google/callback/route.js +32 -0
  6. package/dist/api/auth/google/callback/route.js.map +1 -1
  7. package/dist/api/auth/register/_domain-check.d.ts +2 -0
  8. package/dist/api/auth/register/_domain-check.d.ts.map +1 -0
  9. package/dist/api/auth/register/_domain-check.js +9 -0
  10. package/dist/api/auth/register/_domain-check.js.map +1 -0
  11. package/dist/api/auth/register/_otp-store.d.ts +18 -0
  12. package/dist/api/auth/register/_otp-store.d.ts.map +1 -0
  13. package/dist/api/auth/register/_otp-store.js +56 -0
  14. package/dist/api/auth/register/_otp-store.js.map +1 -0
  15. package/dist/api/auth/register/route.d.ts.map +1 -1
  16. package/dist/api/auth/register/route.js +35 -7
  17. package/dist/api/auth/register/route.js.map +1 -1
  18. package/dist/api/auth/register/send-otp/route.d.ts +3 -0
  19. package/dist/api/auth/register/send-otp/route.d.ts.map +1 -0
  20. package/dist/api/auth/register/send-otp/route.js +57 -0
  21. package/dist/api/auth/register/send-otp/route.js.map +1 -0
  22. package/dist/api/auth/setup/route.d.ts.map +1 -1
  23. package/dist/api/auth/setup/route.js +9 -1
  24. package/dist/api/auth/setup/route.js.map +1 -1
  25. package/dist/subscribers/registration-otp-requested.d.ts +9 -0
  26. package/dist/subscribers/registration-otp-requested.d.ts.map +1 -0
  27. package/dist/subscribers/registration-otp-requested.js +25 -0
  28. package/dist/subscribers/registration-otp-requested.js.map +1 -0
  29. package/package.json +6 -6
@@ -1 +1 @@
1
- {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../src/api/admin/issues/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAKrD,eAAO,MAAM,GAAG,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBA6EhD,CAAA;AAED,eAAO,MAAM,IAAI,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,kBAmCrE,CAAA"}
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../src/api/admin/issues/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAKrD,eAAO,MAAM,GAAG,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAyChD,CAAA;AAED,eAAO,MAAM,IAAI,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,kBAmCrE,CAAA"}
@@ -27,24 +27,6 @@ export const GET = async (req, res) => {
27
27
  filters.task_list_id = null;
28
28
  else if (req.query.task_list_id)
29
29
  filters.task_list_id = req.query.task_list_id;
30
- // parent_id filter: "none" = top-level only, else filter by specific parent
31
- if (req.query.parent_id === "none")
32
- filters.parent_id = null;
33
- else if (req.query.parent_id)
34
- filters.parent_id = req.query.parent_id;
35
- // assignee_id — filter using raw SQL on the jsonb column
36
- if (req.query.assignee_id) {
37
- const aid = req.query.assignee_id;
38
- filters.assignee_ids = { $contains: aid };
39
- }
40
- // search — text search on title and identifier
41
- if (req.query.search) {
42
- const term = `%${req.query.search}%`;
43
- filters.$or = [
44
- { title: { $ilike: term } },
45
- { identifier: { $ilike: term } },
46
- ];
47
- }
48
30
  // When scoped to a project, verify the caller has access to that project
49
31
  if (req.query.project_id) {
50
32
  const projectService = req.scope.resolve("projectModuleService");
@@ -58,26 +40,11 @@ export const GET = async (req, res) => {
58
40
  return;
59
41
  }
60
42
  }
61
- // sort_by + sort_order
62
- const allowedSortColumns = ["created_at", "updated_at", "title", "priority", "due_date", "number"];
63
- const sortBy = allowedSortColumns.includes(req.query.sort_by) ? req.query.sort_by : "created_at";
64
- const sortOrder = req.query.sort_order === "desc" ? "DESC" : "ASC";
65
- const [issues, count] = await issueService.listAndCountIssues(filters, { limit, offset, orderBy: { [sortBy]: sortOrder } });
66
- // When fetching top-level issues, enrich with child_count so the UI
67
- // knows which rows have expandable children without a separate request.
68
- if (req.query.parent_id === "none" && issues.length > 0) {
69
- const issueIds = issues.map((i) => i.id);
70
- const [children] = await issueService.listAndCountIssues({ parent_id: { $in: issueIds } }, { limit: 10000 });
71
- const childCountMap = {};
72
- for (const child of children) {
73
- const pid = child.parent_id;
74
- if (pid)
75
- childCountMap[pid] = (childCountMap[pid] ?? 0) + 1;
76
- }
77
- for (const issue of issues) {
78
- ;
79
- issue.child_count = childCountMap[issue.id] ?? 0;
80
- }
43
+ let [issues, count] = await issueService.listAndCountIssues(filters, { limit, offset, orderBy: { created_at: "ASC" } });
44
+ if (req.query.assignee_id) {
45
+ const id = req.query.assignee_id;
46
+ issues = issues.filter((i) => (i.assignee_ids ?? []).includes(id));
47
+ count = issues.length;
81
48
  }
82
49
  res.json({ issues, count, limit, offset });
83
50
  };
@@ -1 +1 @@
1
- {"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../src/api/admin/issues/route.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../src/api/admin/issues/route.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../src/api/auth/google/callback/route.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAGvC;;;GAGG;AACH,eAAO,MAAM,GAAG,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAoKhD,CAAA"}
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../src/api/auth/google/callback/route.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAIvC;;;GAGG;AACH,eAAO,MAAM,GAAG,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAmMhD,CAAA"}
@@ -1,6 +1,7 @@
1
1
  import jwt from "jsonwebtoken";
2
2
  import { randomBytes } from "node:crypto";
3
3
  import { storeExchangeCode } from "../_exchange-store.js";
4
+ import { validateEmailDomain } from "../../register/_domain-check.js";
4
5
  /**
5
6
  * GET /auth/google/callback?code=...&state=...
6
7
  * Handles the Google OAuth redirect. Absent googleOAuthService → 501.
@@ -108,6 +109,25 @@ export const GET = async (req, res) => {
108
109
  return;
109
110
  }
110
111
  }
112
+ // For register flow (non-invite), check if open registration is enabled before exchanging code
113
+ let regConfig;
114
+ let registerUserCount = 0;
115
+ if (flow === "register" && !inviteRecord) {
116
+ const cfg = req.scope.resolve("config");
117
+ regConfig = cfg?.projectConfig?.registration;
118
+ try {
119
+ const userService = req.scope.resolve("userModuleService");
120
+ const [, count] = await userService.listAndCountUsers({}, { limit: 1 });
121
+ registerUserCount = count;
122
+ }
123
+ catch {
124
+ // assume not first setup
125
+ }
126
+ if (registerUserCount > 0 && !regConfig?.enabled) {
127
+ errorRedirect("Registration is not open. Contact an admin for an invitation.");
128
+ return;
129
+ }
130
+ }
111
131
  // Exchange code for Google profile
112
132
  let profile;
113
133
  try {
@@ -117,12 +137,23 @@ export const GET = async (req, res) => {
117
137
  errorRedirect(err.message ?? "Failed to authenticate with Google");
118
138
  return;
119
139
  }
140
+ // Domain check for open registration (after we have the profile email)
141
+ if (flow === "register" && !inviteRecord && registerUserCount > 0 && regConfig?.enabled) {
142
+ try {
143
+ validateEmailDomain(profile.email, regConfig.allowedDomains);
144
+ }
145
+ catch {
146
+ errorRedirect("Your email domain is not allowed to register.");
147
+ return;
148
+ }
149
+ }
120
150
  // Verify invite email matches Google email (if invite has a locked email)
121
151
  if (inviteRecord?.email && profile.email.toLowerCase() !== inviteRecord.email.toLowerCase()) {
122
152
  errorRedirect(`This invitation was sent to ${inviteRecord.email}. Please sign in with that Google account.`);
123
153
  return;
124
154
  }
125
155
  // Perform login / register
156
+ const autoRegister = flow === "register" && !inviteRecord;
126
157
  let authResult;
127
158
  try {
128
159
  const authService = req.scope.resolve("authModuleService");
@@ -133,6 +164,7 @@ export const GET = async (req, res) => {
133
164
  lastName: profile.lastName,
134
165
  picture: profile.picture,
135
166
  inviteRecord,
167
+ autoRegister,
136
168
  });
137
169
  }
138
170
  catch (err) {
@@ -1 +1 @@
1
- {"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../../src/api/auth/google/callback/route.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../../src/api/auth/google/callback/route.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function validateEmailDomain(email: string, allowedDomains: string[]): void;
2
+ //# sourceMappingURL=_domain-check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_domain-check.d.ts","sourceRoot":"","sources":["../../../../src/api/auth/register/_domain-check.ts"],"names":[],"mappings":"AAAA,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,IAAI,CASjF"}
@@ -0,0 +1,9 @@
1
+ export function validateEmailDomain(email, allowedDomains) {
2
+ if (allowedDomains.includes("*"))
3
+ return;
4
+ const domain = email.split("@")[1]?.toLowerCase();
5
+ if (!domain || !allowedDomains.map(d => d.toLowerCase()).includes(domain)) {
6
+ throw Object.assign(new Error(`Email domain not allowed. Allowed: ${allowedDomains.join(", ")}`), { status: 422 });
7
+ }
8
+ }
9
+ //# sourceMappingURL=_domain-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_domain-check.js","sourceRoot":"","sources":["../../../../src/api/auth/register/_domain-check.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,mBAAmB,CAAC,KAAa,EAAE,cAAwB;IACzE,IAAI,cAAc,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAM;IACxC,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAA;IACjD,IAAI,CAAC,MAAM,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1E,MAAM,MAAM,CAAC,MAAM,CACjB,IAAI,KAAK,CAAC,sCAAsC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAC5E,EAAE,MAAM,EAAE,GAAG,EAAE,CAChB,CAAA;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * In-memory OTP store for registration email verification flow.
3
+ *
4
+ * One active OTP per email address. 6-digit numeric code, 10-minute TTL.
5
+ * Rate-limited: rejects re-sends within 60 seconds.
6
+ *
7
+ * Uses globalThis to guarantee a single shared Map even when route files
8
+ * are loaded via separate dynamic import() calls by the route scanner.
9
+ */
10
+ /** Generate and store a 6-digit OTP for an email address. Throws if rate-limited. */
11
+ export declare function generateAndStoreOtp(email: string): string;
12
+ /**
13
+ * Consume an OTP. Returns true if the code matches and is not expired.
14
+ * Tracks failed attempts — after MAX_ATTEMPTS failures the entry is invalidated.
15
+ * On success the entry is deleted (single-use).
16
+ */
17
+ export declare function consumeOtp(email: string, otp: string): boolean;
18
+ //# sourceMappingURL=_otp-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_otp-store.d.ts","sourceRoot":"","sources":["../../../../src/api/auth/register/_otp-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAuBH,qFAAqF;AACrF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAUzD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAiB9D"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * In-memory OTP store for registration email verification flow.
3
+ *
4
+ * One active OTP per email address. 6-digit numeric code, 10-minute TTL.
5
+ * Rate-limited: rejects re-sends within 60 seconds.
6
+ *
7
+ * Uses globalThis to guarantee a single shared Map even when route files
8
+ * are loaded via separate dynamic import() calls by the route scanner.
9
+ */
10
+ import { randomInt } from "crypto";
11
+ const STORE_KEY = "__meridian_registration_otp_store__";
12
+ const OTP_TTL_MS = 10 * 60 * 1000; // 10 minutes
13
+ const RESEND_COOLDOWN_MS = 60 * 1000; // 60 seconds
14
+ const MAX_ATTEMPTS = 5;
15
+ function getStore() {
16
+ if (!globalThis[STORE_KEY]) {
17
+ ;
18
+ globalThis[STORE_KEY] = new Map();
19
+ }
20
+ return globalThis[STORE_KEY];
21
+ }
22
+ /** Generate and store a 6-digit OTP for an email address. Throws if rate-limited. */
23
+ export function generateAndStoreOtp(email) {
24
+ const store = getStore();
25
+ const existing = store.get(email);
26
+ if (existing && Date.now() - existing.sentAt < RESEND_COOLDOWN_MS) {
27
+ throw Object.assign(new Error("Please wait before requesting a new code"), { status: 429 });
28
+ }
29
+ const otp = String(randomInt(100000, 999999));
30
+ store.set(email, { otp, expiresAt: Date.now() + OTP_TTL_MS, sentAt: Date.now(), attempts: 0 });
31
+ return otp;
32
+ }
33
+ /**
34
+ * Consume an OTP. Returns true if the code matches and is not expired.
35
+ * Tracks failed attempts — after MAX_ATTEMPTS failures the entry is invalidated.
36
+ * On success the entry is deleted (single-use).
37
+ */
38
+ export function consumeOtp(email, otp) {
39
+ const store = getStore();
40
+ const entry = store.get(email);
41
+ if (!entry || entry.expiresAt < Date.now()) {
42
+ store.delete(email);
43
+ return false;
44
+ }
45
+ if (entry.otp === otp) {
46
+ store.delete(email);
47
+ return true;
48
+ }
49
+ // Wrong code — increment attempt counter
50
+ entry.attempts += 1;
51
+ if (entry.attempts >= MAX_ATTEMPTS) {
52
+ store.delete(email);
53
+ }
54
+ return false;
55
+ }
56
+ //# sourceMappingURL=_otp-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_otp-store.js","sourceRoot":"","sources":["../../../../src/api/auth/register/_otp-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AASlC,MAAM,SAAS,GAAG,qCAAqC,CAAA;AACvD,MAAM,UAAU,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA,CAAE,aAAa;AAChD,MAAM,kBAAkB,GAAG,EAAE,GAAG,IAAI,CAAA,CAAC,aAAa;AAClD,MAAM,YAAY,GAAG,CAAC,CAAA;AAEtB,SAAS,QAAQ;IACf,IAAI,CAAE,UAAkB,CAAC,SAAS,CAAC,EAAE,CAAC;QACpC,CAAC;QAAC,UAAkB,CAAC,SAAS,CAAC,GAAG,IAAI,GAAG,EAAoB,CAAA;IAC/D,CAAC;IACD,OAAQ,UAAkB,CAAC,SAAS,CAAC,CAAA;AACvC,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAC/C,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAA;IACxB,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;IACjC,IAAI,QAAQ,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC,MAAM,GAAG,kBAAkB,EAAE,CAAC;QAClE,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,0CAA0C,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;IAC7F,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IAC7C,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAA;IAC9F,OAAO,GAAG,CAAA;AACZ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,KAAa,EAAE,GAAW;IACnD,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAA;IACxB,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;IAC9B,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;QAC3C,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QACnB,OAAO,KAAK,CAAA;IACd,CAAC;IACD,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;QACtB,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QACnB,OAAO,IAAI,CAAA;IACb,CAAC;IACD,yCAAyC;IACzC,KAAK,CAAC,QAAQ,IAAI,CAAC,CAAA;IACnB,IAAI,KAAK,CAAC,QAAQ,IAAI,YAAY,EAAE,CAAC;QACnC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IACrB,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../src/api/auth/register/route.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AASvC,eAAO,MAAM,IAAI,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAoBjD,CAAA"}
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../src/api/auth/register/route.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAYvC,eAAO,MAAM,IAAI,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAiDjD,CAAA"}
@@ -1,26 +1,54 @@
1
1
  import { z } from "zod";
2
+ import { consumeOtp } from "./_otp-store.js";
3
+ import { validateEmailDomain } from "./_domain-check.js";
2
4
  const registerSchema = z.object({
3
5
  email: z.string().email(),
4
6
  password: z.string().min(8, "Password must be at least 8 characters"),
5
7
  first_name: z.string().optional(),
6
8
  last_name: z.string().optional(),
9
+ otp: z.string().length(6).optional(),
7
10
  });
8
11
  export const POST = async (req, res) => {
9
- // Registration is only open for the very first user (super-admin setup).
10
- // All subsequent accounts must be created via an invitation link.
11
12
  const userService = req.scope.resolve("userModuleService");
12
13
  const [, userCount] = await userService.listAndCountUsers({}, { limit: 1 });
13
- if (userCount > 0) {
14
- res.status(403).json({
15
- error: { message: "Registration is closed. Ask an admin to send you an invitation link." },
16
- });
17
- return;
14
+ const isFirstSetup = userCount === 0;
15
+ if (!isFirstSetup) {
16
+ const config = req.scope.resolve("config");
17
+ const regConfig = config?.projectConfig?.registration;
18
+ if (!regConfig?.enabled) {
19
+ res.status(403).json({
20
+ error: { message: "Registration is closed. Ask an admin to send you an invitation link." },
21
+ });
22
+ return;
23
+ }
24
+ // Validate domain before parsing full body (fast rejection)
25
+ const emailRaw = req.body?.email;
26
+ if (emailRaw) {
27
+ try {
28
+ validateEmailDomain(emailRaw, regConfig.allowedDomains);
29
+ }
30
+ catch (err) {
31
+ res.status(err.status ?? 422).json({ error: { message: err.message } });
32
+ return;
33
+ }
34
+ }
35
+ if (!req.body?.otp) {
36
+ res.status(400).json({ error: { message: "Verification code is required" } });
37
+ return;
38
+ }
18
39
  }
19
40
  const result = registerSchema.safeParse(req.body);
20
41
  if (!result.success) {
21
42
  res.status(400).json({ error: { message: "Validation error", details: result.error.flatten().fieldErrors } });
22
43
  return;
23
44
  }
45
+ if (!isFirstSetup) {
46
+ const valid = consumeOtp(result.data.email.toLowerCase().trim(), result.data.otp);
47
+ if (!valid) {
48
+ res.status(400).json({ error: { message: "Invalid or expired verification code" } });
49
+ return;
50
+ }
51
+ }
24
52
  const authService = req.scope.resolve("authModuleService");
25
53
  const response = await authService.register(result.data);
26
54
  res.status(201).json(response);
@@ -1 +1 @@
1
- {"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../src/api/auth/register/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE;IACzB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,wCAAwC,CAAC;IACrE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACjC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACjC,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,IAAI,GAAG,KAAK,EAAE,GAAQ,EAAE,GAAa,EAAE,EAAE;IACpD,yEAAyE;IACzE,kEAAkE;IAClE,MAAM,WAAW,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,mBAAmB,CAAQ,CAAA;IACjE,MAAM,CAAC,EAAE,SAAS,CAAC,GAAG,MAAM,WAAW,CAAC,iBAAiB,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAA;IAC3E,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;QAClB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,KAAK,EAAE,EAAE,OAAO,EAAE,sEAAsE,EAAE;SAC3F,CAAC,CAAA;QACF,OAAM;IACR,CAAC;IAED,MAAM,MAAM,GAAG,cAAc,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IACjD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,kBAAkB,EAAE,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAA;QAC7G,OAAM;IACR,CAAC;IACD,MAAM,WAAW,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,mBAAmB,CAAQ,CAAA;IACjE,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACxD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;AAChC,CAAC,CAAA"}
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../src/api/auth/register/route.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Response } from "express";
2
+ export declare const POST: (req: any, res: Response) => Promise<void>;
3
+ //# sourceMappingURL=route.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../src/api/auth/register/send-otp/route.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAQvC,eAAO,MAAM,IAAI,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAqDjD,CAAA"}
@@ -0,0 +1,57 @@
1
+ import { z } from "zod";
2
+ import { generateAndStoreOtp } from "../_otp-store.js";
3
+ import { validateEmailDomain } from "../_domain-check.js";
4
+ const schema = z.object({
5
+ email: z.string().email(),
6
+ });
7
+ export const POST = async (req, res) => {
8
+ const config = req.scope.resolve("config");
9
+ const regConfig = config?.projectConfig?.registration;
10
+ if (!regConfig?.enabled) {
11
+ res.status(403).json({ error: { message: "Registration is closed." } });
12
+ return;
13
+ }
14
+ const result = schema.safeParse(req.body);
15
+ if (!result.success) {
16
+ res.status(400).json({ error: { message: "Invalid email address" } });
17
+ return;
18
+ }
19
+ const { email } = result.data;
20
+ try {
21
+ validateEmailDomain(email, regConfig.allowedDomains);
22
+ }
23
+ catch (err) {
24
+ res.status(err.status ?? 422).json({ error: { message: err.message } });
25
+ return;
26
+ }
27
+ // If user already exists, return 200 silently (no enumeration)
28
+ try {
29
+ const userService = req.scope.resolve("userModuleService");
30
+ const existing = await userService.retrieveUserByEmail(email.toLowerCase().trim());
31
+ if (existing) {
32
+ res.json({ ok: true });
33
+ return;
34
+ }
35
+ }
36
+ catch {
37
+ // user service error — fall through to OTP generation
38
+ }
39
+ let otp;
40
+ try {
41
+ otp = generateAndStoreOtp(email.toLowerCase().trim());
42
+ }
43
+ catch {
44
+ // Rate limited — still return 200 to avoid timing-based enumeration
45
+ res.json({ ok: true });
46
+ return;
47
+ }
48
+ try {
49
+ const eventBus = req.scope.resolve("eventBus");
50
+ await eventBus.emit({ name: "registration.otp_requested", data: { email, otp } });
51
+ }
52
+ catch {
53
+ // Non-fatal — OTP is stored, email may not send
54
+ }
55
+ res.json({ ok: true });
56
+ };
57
+ //# sourceMappingURL=route.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../../src/api/auth/register/send-otp/route.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../src/api/auth/setup/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,QAAQ,EAAE,MAAM,SAAS,CAAA;AAEhD;;;;GAIG;AACH,eAAO,MAAM,GAAG,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAmBhD,CAAA"}
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../src/api/auth/setup/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,QAAQ,EAAE,MAAM,SAAS,CAAA;AAEhD;;;;GAIG;AACH,eAAO,MAAM,GAAG,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBA2BhD,CAAA"}
@@ -21,6 +21,14 @@ export const GET = async (req, res) => {
21
21
  catch {
22
22
  // googleOAuthService not registered — feature disabled
23
23
  }
24
- res.json({ needsSetup, googleOAuthEnabled });
24
+ let registrationEnabled = false;
25
+ try {
26
+ const config = req.scope.resolve("config");
27
+ registrationEnabled = config?.projectConfig?.registration?.enabled === true;
28
+ }
29
+ catch {
30
+ // config not available — default false
31
+ }
32
+ res.json({ needsSetup, googleOAuthEnabled, registrationEnabled });
25
33
  };
26
34
  //# sourceMappingURL=route.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../src/api/auth/setup/route.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,CAAC,MAAM,GAAG,GAAG,KAAK,EAAE,GAAQ,EAAE,GAAa,EAAE,EAAE;IACnD,IAAI,UAAU,GAAG,KAAK,CAAA;IACtB,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,mBAAmB,CAAQ,CAAA;QACjE,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,UAAU,EAAE,CAAA;QAC5C,UAAU,GAAG,KAAK,KAAK,CAAC,CAAA;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,6DAA6D;IAC/D,CAAC;IAED,IAAI,kBAAkB,GAAG,KAAK,CAAA;IAC9B,IAAI,CAAC;QACH,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAA;QACvC,kBAAkB,GAAG,IAAI,CAAA;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,uDAAuD;IACzD,CAAC;IAED,GAAG,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,kBAAkB,EAAE,CAAC,CAAA;AAC9C,CAAC,CAAA"}
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../src/api/auth/setup/route.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,CAAC,MAAM,GAAG,GAAG,KAAK,EAAE,GAAQ,EAAE,GAAa,EAAE,EAAE;IACnD,IAAI,UAAU,GAAG,KAAK,CAAA;IACtB,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,mBAAmB,CAAQ,CAAA;QACjE,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,UAAU,EAAE,CAAA;QAC5C,UAAU,GAAG,KAAK,KAAK,CAAC,CAAA;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,6DAA6D;IAC/D,CAAC;IAED,IAAI,kBAAkB,GAAG,KAAK,CAAA;IAC9B,IAAI,CAAC;QACH,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAA;QACvC,kBAAkB,GAAG,IAAI,CAAA;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,uDAAuD;IACzD,CAAC;IAED,IAAI,mBAAmB,GAAG,KAAK,CAAA;IAC/B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAQ,CAAA;QACjD,mBAAmB,GAAG,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,OAAO,KAAK,IAAI,CAAA;IAC7E,CAAC;IAAC,MAAM,CAAC;QACP,uCAAuC;IACzC,CAAC;IAED,GAAG,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,CAAC,CAAA;AACnE,CAAC,CAAA"}
@@ -0,0 +1,9 @@
1
+ import type { SubscriberArgs, SubscriberConfig } from "@meridianjs/types";
2
+ interface RegistrationOtpRequestedData {
3
+ email: string;
4
+ otp: string;
5
+ }
6
+ export default function handler({ event, container }: SubscriberArgs<RegistrationOtpRequestedData>): Promise<void>;
7
+ export declare const config: SubscriberConfig;
8
+ export {};
9
+ //# sourceMappingURL=registration-otp-requested.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registration-otp-requested.d.ts","sourceRoot":"","sources":["../../src/subscribers/registration-otp-requested.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAGzE,UAAU,4BAA4B;IACpC,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;CACZ;AAED,wBAA8B,OAAO,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,cAAc,CAAC,4BAA4B,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAyBvH;AAED,eAAO,MAAM,MAAM,EAAE,gBAA0D,CAAA"}
@@ -0,0 +1,25 @@
1
+ import { emailHtml, resolveTemplate } from "./_email-helper.js";
2
+ export default async function handler({ event, container }) {
3
+ const data = event.data;
4
+ try {
5
+ const emailService = container.resolve("emailService");
6
+ const tpl = resolveTemplate(container, "registration.otp_requested", {
7
+ email: data.email,
8
+ otp: data.otp,
9
+ });
10
+ await emailService.send({
11
+ to: data.email,
12
+ subject: tpl?.subject ?? "Your Meridian verification code",
13
+ text: tpl?.text ?? `Your verification code is: ${data.otp}\n\nThis code expires in 10 minutes. If you didn't request this, you can safely ignore this email.`,
14
+ html: tpl?.html ?? emailHtml(`Your verification code is:<br/><br/>` +
15
+ `<div style="font-size:32px;font-weight:700;letter-spacing:8px;text-align:center;padding:16px 0;font-family:monospace;color:#4f46e5">${data.otp}</div><br/>` +
16
+ `This code expires in 10 minutes. If you didn't request this, you can safely ignore this email.`),
17
+ });
18
+ }
19
+ catch (err) {
20
+ const logger = container.resolve("logger");
21
+ logger.error(`[email] registration.otp_requested: ${err instanceof Error ? err.message : String(err)}`);
22
+ }
23
+ }
24
+ export const config = { event: "registration.otp_requested" };
25
+ //# sourceMappingURL=registration-otp-requested.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registration-otp-requested.js","sourceRoot":"","sources":["../../src/subscribers/registration-otp-requested.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAO/D,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,OAAO,CAAC,EAAE,KAAK,EAAE,SAAS,EAAgD;IACtG,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAA;IAEvB,IAAI,CAAC;QACH,MAAM,YAAY,GAAG,SAAS,CAAC,OAAO,CAAC,cAAc,CAAQ,CAAA;QAE7D,MAAM,GAAG,GAAG,eAAe,CAAC,SAAS,EAAE,4BAA4B,EAAE;YACnE,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,GAAG,EAAE,IAAI,CAAC,GAAG;SACd,CAAC,CAAA;QAEF,MAAM,YAAY,CAAC,IAAI,CAAC;YACtB,EAAE,EAAE,IAAI,CAAC,KAAK;YACd,OAAO,EAAE,GAAG,EAAE,OAAO,IAAI,iCAAiC;YAC1D,IAAI,EAAE,GAAG,EAAE,IAAI,IAAI,8BAA8B,IAAI,CAAC,GAAG,oGAAoG;YAC7J,IAAI,EAAE,GAAG,EAAE,IAAI,IAAI,SAAS,CAC1B,sCAAsC;gBACtC,uIAAuI,IAAI,CAAC,GAAG,aAAa;gBAC5J,gGAAgG,CACjG;SACF,CAAC,CAAA;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAQ,CAAA;QACjD,MAAM,CAAC,KAAK,CAAC,uCAAuC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACzG,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAqB,EAAE,KAAK,EAAE,4BAA4B,EAAE,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meridianjs/meridian",
3
- "version": "1.19.0",
3
+ "version": "1.21.0",
4
4
  "description": "Default API routes, workflows, links, and subscribers for Meridian applications",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -20,13 +20,13 @@
20
20
  "prepublishOnly": "cd ../.. && npm run check:routes && cd packages/meridian && npm run build"
21
21
  },
22
22
  "dependencies": {
23
- "@meridianjs/framework": "^1.19.0",
24
- "@meridianjs/framework-utils": "^1.19.0",
25
- "@meridianjs/workflow-engine": "^1.19.0",
26
- "@meridianjs/types": "^1.19.0",
23
+ "@meridianjs/framework": "^1.21.0",
24
+ "@meridianjs/framework-utils": "^1.21.0",
25
+ "@meridianjs/workflow-engine": "^1.21.0",
26
+ "@meridianjs/types": "^1.21.0",
27
27
  "@meridianjs/user": "^1.0.0",
28
28
  "@meridianjs/workspace": "^1.2.0",
29
- "@meridianjs/auth": "^1.19.0",
29
+ "@meridianjs/auth": "^1.21.0",
30
30
  "@meridianjs/project": "^1.1.0",
31
31
  "@meridianjs/issue": "^1.3.0",
32
32
  "@meridianjs/sprint": "^1.0.0",