@meridianjs/auth 1.10.0 → 1.12.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.
package/dist/index.d.mts CHANGED
@@ -8,7 +8,12 @@ interface RegisterInput {
8
8
  password: string;
9
9
  first_name?: string;
10
10
  last_name?: string;
11
- role?: UserRole;
11
+ /**
12
+ * @internal — Only used by the invite flow. Public registration always
13
+ * derives the role automatically (first user → super-admin, else member).
14
+ * Callers must never expose this to untrusted input.
15
+ */
16
+ _inviteRole?: UserRole;
12
17
  }
13
18
  interface LoginInput {
14
19
  email: string;
@@ -130,10 +135,13 @@ declare function requirePermission(...permissions: string[]): (req: any, res: Re
130
135
  * param, body field, or URL path param (:id on /workspaces/:id sub-routes)
131
136
  * does not match the authenticated user's workspace.
132
137
  *
133
- * Allows the request through when no workspace identifier is present (so
134
- * general listing endpoints that omit workspace_id are not blocked).
138
+ * **WARNING:** This guard is currently inert because JWTs are always issued
139
+ * with `workspaceId: null` (multi-workspace users don't have a single
140
+ * workspace in their token). Workspace isolation is enforced per-route
141
+ * via `assertWorkspaceAccess` helpers instead. This function is kept for
142
+ * backwards compatibility but should not be relied upon.
135
143
  *
136
- * Must be used after `authenticateJWT`.
144
+ * @deprecated Use per-route `assertWorkspaceAccess` instead.
137
145
  */
138
146
  declare function requireWorkspace(req: any, res: Response, next: NextFunction): Response<any, Record<string, any>> | undefined;
139
147
 
package/dist/index.d.ts CHANGED
@@ -8,7 +8,12 @@ interface RegisterInput {
8
8
  password: string;
9
9
  first_name?: string;
10
10
  last_name?: string;
11
- role?: UserRole;
11
+ /**
12
+ * @internal — Only used by the invite flow. Public registration always
13
+ * derives the role automatically (first user → super-admin, else member).
14
+ * Callers must never expose this to untrusted input.
15
+ */
16
+ _inviteRole?: UserRole;
12
17
  }
13
18
  interface LoginInput {
14
19
  email: string;
@@ -130,10 +135,13 @@ declare function requirePermission(...permissions: string[]): (req: any, res: Re
130
135
  * param, body field, or URL path param (:id on /workspaces/:id sub-routes)
131
136
  * does not match the authenticated user's workspace.
132
137
  *
133
- * Allows the request through when no workspace identifier is present (so
134
- * general listing endpoints that omit workspace_id are not blocked).
138
+ * **WARNING:** This guard is currently inert because JWTs are always issued
139
+ * with `workspaceId: null` (multi-workspace users don't have a single
140
+ * workspace in their token). Workspace isolation is enforced per-route
141
+ * via `assertWorkspaceAccess` helpers instead. This function is kept for
142
+ * backwards compatibility but should not be relied upon.
135
143
  *
136
- * Must be used after `authenticateJWT`.
144
+ * @deprecated Use per-route `assertWorkspaceAccess` instead.
137
145
  */
138
146
  declare function requireWorkspace(req: any, res: Response, next: NextFunction): Response<any, Record<string, any>> | undefined;
139
147
 
package/dist/index.js CHANGED
@@ -65,8 +65,10 @@ var AuthModuleService = class extends (0, import_framework_utils.MeridianService
65
65
  throw Object.assign(new Error("Email already registered"), { status: 409 });
66
66
  }
67
67
  const password_hash = await import_bcrypt.default.hash(input.password, BCRYPT_ROUNDS);
68
- let role = input.role ?? "member";
69
- if (!input.role) {
68
+ let role = "member";
69
+ if (input._inviteRole) {
70
+ role = input._inviteRole;
71
+ } else {
70
72
  const [, userCount] = await userService.listAndCountUsers({}, { limit: 1 });
71
73
  if (userCount === 0) role = "super-admin";
72
74
  }
@@ -222,12 +224,14 @@ var AuthModuleService = class extends (0, import_framework_utils.MeridianService
222
224
  async restoreFromInvite(userId, input) {
223
225
  const userService = this.container.resolve("userModuleService");
224
226
  const config = this.container.resolve("config");
227
+ const allowedRoles = ["super-admin", "admin", "moderator", "member"];
228
+ const role = input.role && allowedRoles.includes(input.role) ? input.role : "member";
225
229
  const password_hash = await import_bcrypt.default.hash(input.password, BCRYPT_ROUNDS);
226
230
  const user = await userService.restoreUser(userId, {
227
231
  password_hash,
228
232
  first_name: input.first_name ?? null,
229
233
  last_name: input.last_name ?? null,
230
- role: input.role ?? "member"
234
+ role
231
235
  });
232
236
  const permissions = await this.resolvePermissions(user.app_role_id);
233
237
  const { token, jti, expiresAt } = this.signToken(user.id, null, [user.role], permissions, config.projectConfig.jwtSecret);
package/dist/index.mjs CHANGED
@@ -25,8 +25,10 @@ var AuthModuleService = class extends MeridianService({}) {
25
25
  throw Object.assign(new Error("Email already registered"), { status: 409 });
26
26
  }
27
27
  const password_hash = await bcrypt.hash(input.password, BCRYPT_ROUNDS);
28
- let role = input.role ?? "member";
29
- if (!input.role) {
28
+ let role = "member";
29
+ if (input._inviteRole) {
30
+ role = input._inviteRole;
31
+ } else {
30
32
  const [, userCount] = await userService.listAndCountUsers({}, { limit: 1 });
31
33
  if (userCount === 0) role = "super-admin";
32
34
  }
@@ -182,12 +184,14 @@ var AuthModuleService = class extends MeridianService({}) {
182
184
  async restoreFromInvite(userId, input) {
183
185
  const userService = this.container.resolve("userModuleService");
184
186
  const config = this.container.resolve("config");
187
+ const allowedRoles = ["super-admin", "admin", "moderator", "member"];
188
+ const role = input.role && allowedRoles.includes(input.role) ? input.role : "member";
185
189
  const password_hash = await bcrypt.hash(input.password, BCRYPT_ROUNDS);
186
190
  const user = await userService.restoreUser(userId, {
187
191
  password_hash,
188
192
  first_name: input.first_name ?? null,
189
193
  last_name: input.last_name ?? null,
190
- role: input.role ?? "member"
194
+ role
191
195
  });
192
196
  const permissions = await this.resolvePermissions(user.app_role_id);
193
197
  const { token, jti, expiresAt } = this.signToken(user.id, null, [user.role], permissions, config.projectConfig.jwtSecret);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meridianjs/auth",
3
- "version": "1.10.0",
3
+ "version": "1.12.0",
4
4
  "description": "Meridian auth module — JWT authentication and middleware",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -26,8 +26,8 @@
26
26
  "prepublishOnly": "npm run build"
27
27
  },
28
28
  "dependencies": {
29
- "@meridianjs/types": "^1.10.0",
30
- "@meridianjs/framework-utils": "^1.10.0",
29
+ "@meridianjs/types": "^1.12.0",
30
+ "@meridianjs/framework-utils": "^1.12.0",
31
31
  "jsonwebtoken": "^9.0.2",
32
32
  "bcrypt": "^5.1.1"
33
33
  },