nuxt-auto-crud 1.14.1 → 1.15.2

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/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nuxt-auto-crud",
3
3
  "configKey": "autoCrud",
4
- "version": "1.14.1",
4
+ "version": "1.15.2",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
@@ -3,6 +3,7 @@ import { eq } from "drizzle-orm";
3
3
  import { getTableForModel } from "../../utils/modelMapper.js";
4
4
  import { useDrizzle } from "#site/drizzle";
5
5
  import { ensureResourceAccess, formatResourceResult } from "../../utils/handler.js";
6
+ import { checkAdminAccess } from "../../utils/auth.js";
6
7
  export default eventHandler(async (event) => {
7
8
  const { model, id } = getRouterParams(event);
8
9
  const isAdmin = await ensureResourceAccess(event, model, "read");
@@ -14,5 +15,14 @@ export default eventHandler(async (event) => {
14
15
  message: "Record not found"
15
16
  });
16
17
  }
18
+ if ("status" in record && record.status !== "active") {
19
+ const canListAll = await checkAdminAccess(event, model, "list_all");
20
+ if (!canListAll) {
21
+ throw createError({
22
+ statusCode: 404,
23
+ message: "Record not found"
24
+ });
25
+ }
26
+ }
17
27
  return formatResourceResult(model, record, isAdmin);
18
28
  });
@@ -1,13 +1,25 @@
1
1
  import { eventHandler, getRouterParams } from "h3";
2
2
  import { getTableForModel } from "../../utils/modelMapper.js";
3
3
  import { useDrizzle } from "#site/drizzle";
4
- import { desc } from "drizzle-orm";
4
+ import { desc, getTableColumns, eq } from "drizzle-orm";
5
5
  import { ensureResourceAccess, formatResourceResult } from "../../utils/handler.js";
6
+ import { checkAdminAccess } from "../../utils/auth.js";
6
7
  export default eventHandler(async (event) => {
7
8
  console.log("[GET] Request received", event.path);
8
9
  const { model } = getRouterParams(event);
9
10
  const isAdmin = await ensureResourceAccess(event, model, "list");
11
+ let canListAll = false;
12
+ try {
13
+ canListAll = await checkAdminAccess(event, model, "list_all");
14
+ } catch {
15
+ canListAll = false;
16
+ }
10
17
  const table = getTableForModel(model);
11
- const results = await useDrizzle().select().from(table).orderBy(desc(table.id)).all();
18
+ const columns = getTableColumns(table);
19
+ let query = useDrizzle().select().from(table);
20
+ if (!canListAll && "status" in columns) {
21
+ query = query.where(eq(table.status, "active"));
22
+ }
23
+ const results = await query.orderBy(desc(table.id)).all();
12
24
  return results.map((item) => formatResourceResult(model, item, isAdmin));
13
25
  });
@@ -1,5 +1,5 @@
1
1
  import { createError } from "h3";
2
- import { requireUserSession, allows, getUserSession, abilities as globalAbility } from "#imports";
2
+ import { requireUserSession, allows, getUserSession, abilities as globalAbility, abilityLogic } from "#imports";
3
3
  import { useAutoCrudConfig } from "./config.js";
4
4
  import { verifyJwtToken } from "./jwt.js";
5
5
  export async function checkAdminAccess(event, model, action) {
@@ -22,7 +22,7 @@ export async function checkAdminAccess(event, model, action) {
22
22
  }
23
23
  if (auth.authorization) {
24
24
  try {
25
- const guestCheck = !user && (typeof globalAbility === "function" ? globalAbility : null);
25
+ const guestCheck = !user && (typeof abilityLogic === "function" ? abilityLogic : typeof globalAbility === "function" ? globalAbility : null);
26
26
  const allowed = guestCheck ? await guestCheck(null, model, action) : await allows(event, globalAbility, model, action);
27
27
  if (!allowed) {
28
28
  if (user) throw createError({ statusCode: 403, message: "Forbidden" });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nuxt-auto-crud",
3
- "version": "1.14.1",
3
+ "version": "1.15.2",
4
4
  "description": "Exposes RESTful CRUD APIs for your Nuxt app based solely on your database migrations.",
5
5
  "author": "Cliford Pereira",
6
6
  "license": "MIT",
@@ -6,6 +6,7 @@ import type { TableWithId } from '../../types'
6
6
  // @ts-expect-error - #site/drizzle is an alias defined by the module
7
7
  import { useDrizzle } from '#site/drizzle'
8
8
  import { ensureResourceAccess, formatResourceResult } from '../../utils/handler'
9
+ import { checkAdminAccess } from '../../utils/auth'
9
10
 
10
11
  export default eventHandler(async (event) => {
11
12
  const { model, id } = getRouterParams(event) as { model: string, id: string }
@@ -26,5 +27,17 @@ export default eventHandler(async (event) => {
26
27
  })
27
28
  }
28
29
 
30
+ // Filter inactive rows for non-admins (or those without list_all) if status field exists
31
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
32
+ if ('status' in record && (record as any).status !== 'active') {
33
+ const canListAll = await checkAdminAccess(event, model, 'list_all')
34
+ if (!canListAll) {
35
+ throw createError({
36
+ statusCode: 404,
37
+ message: 'Record not found',
38
+ })
39
+ }
40
+ }
41
+
29
42
  return formatResourceResult(model, record as Record<string, unknown>, isAdmin)
30
43
  })
@@ -3,18 +3,38 @@ import { eventHandler, getRouterParams } from 'h3'
3
3
  import { getTableForModel } from '../../utils/modelMapper'
4
4
  // @ts-expect-error - #site/drizzle is an alias defined by the module
5
5
  import { useDrizzle } from '#site/drizzle'
6
- import { desc } from 'drizzle-orm'
6
+ import { desc, getTableColumns, eq } from 'drizzle-orm'
7
7
  import type { TableWithId } from '../../types'
8
8
  import { ensureResourceAccess, formatResourceResult } from '../../utils/handler'
9
9
 
10
+ import { checkAdminAccess } from '../../utils/auth'
11
+
10
12
  export default eventHandler(async (event) => {
11
13
  console.log('[GET] Request received', event.path)
12
14
  const { model } = getRouterParams(event) as { model: string }
13
15
  const isAdmin = await ensureResourceAccess(event, model, 'list')
14
16
 
17
+ let canListAll = false
18
+ try {
19
+ canListAll = await checkAdminAccess(event, model, 'list_all')
20
+ }
21
+ catch {
22
+ canListAll = false
23
+ }
24
+
15
25
  const table = getTableForModel(model) as TableWithId
26
+ const columns = getTableColumns(table)
27
+
28
+ let query = useDrizzle().select().from(table)
29
+
30
+ // Filter active rows for non-admins (or those without list_all) if status field exists
31
+
32
+ if (!canListAll && 'status' in columns) {
33
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
34
+ query = query.where(eq((table as any).status, 'active')) as any
35
+ }
16
36
 
17
- const results = await useDrizzle().select().from(table).orderBy(desc(table.id)).all()
37
+ const results = await query.orderBy(desc(table.id)).all()
18
38
 
19
39
  return results.map((item: Record<string, unknown>) => formatResourceResult(model, item, isAdmin))
20
40
  })
@@ -3,7 +3,7 @@
3
3
  import type { H3Event } from 'h3'
4
4
  import { createError } from 'h3'
5
5
  // @ts-expect-error - #imports is available in runtime
6
- import { requireUserSession, allows, getUserSession, abilities as globalAbility } from '#imports'
6
+ import { requireUserSession, allows, getUserSession, abilities as globalAbility, abilityLogic } from '#imports'
7
7
  import { useAutoCrudConfig } from './config'
8
8
  import { verifyJwtToken } from './jwt'
9
9
 
@@ -35,7 +35,8 @@ export async function checkAdminAccess(event: H3Event, model: string, action: st
35
35
  // Check authorization if enabled
36
36
  if (auth.authorization) {
37
37
  try {
38
- const guestCheck = !user && (typeof globalAbility === 'function' ? globalAbility : null)
38
+ const guestCheck = !user && (typeof abilityLogic === 'function' ? abilityLogic : (typeof globalAbility === 'function' ? globalAbility : null))
39
+
39
40
  const allowed = guestCheck
40
41
  ? await guestCheck(null, model, action)
41
42
  : await allows(event, globalAbility, model, action)