@open-mercato/core 0.6.8-develop.7093.1.700c5c8d96 → 0.6.8-develop.7095.1.465fbf8f80

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.
@@ -1,4 +1,4 @@
1
- [build:core] found 4346 entry points
1
+ [build:core] found 4347 entry points
2
2
  [build:core] built successfully
3
3
  [build:core:generated] found 218 entry points
4
4
  [build:core:generated] built successfully
@@ -2,6 +2,7 @@ import { NextResponse } from "next/server";
2
2
  import { z } from "zod";
3
3
  import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
4
4
  import { getAuthFromRequest } from "@open-mercato/shared/lib/auth/server";
5
+ import { resolveFeatureCheckContext } from "@open-mercato/core/modules/directory/utils/organizationScope";
5
6
  import { featureCheckRequestSchema } from "../data/validators.js";
6
7
  const metadata = {
7
8
  POST: { requireAuth: true }
@@ -31,13 +32,18 @@ async function POST(req) {
31
32
  }
32
33
  const container = await createRequestContainer();
33
34
  const rbac = container.resolve("rbacService");
34
- const ok = await rbac.userHasAllFeatures(auth.sub, features, { tenantId: auth.tenantId, organizationId: auth.orgId });
35
+ const featureContext = await resolveFeatureCheckContext({ container, auth, request: req });
36
+ const featureScope = {
37
+ tenantId: featureContext.scope.tenantId ?? auth.tenantId ?? null,
38
+ organizationId: featureContext.organizationId
39
+ };
40
+ const ok = await rbac.userHasAllFeatures(auth.sub, features, featureScope);
35
41
  if (ok) {
36
42
  return NextResponse.json({ ok: true, granted: features, userId: auth.sub });
37
43
  }
38
44
  const granted = [];
39
45
  for (const f of features) {
40
- const hasFeature = await rbac.userHasAllFeatures(auth.sub, [f], { tenantId: auth.tenantId, organizationId: auth.orgId });
46
+ const hasFeature = await rbac.userHasAllFeatures(auth.sub, [f], featureScope);
41
47
  if (hasFeature) granted.push(f);
42
48
  }
43
49
  return NextResponse.json({ ok: false, granted, userId: auth.sub });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/auth/api/feature-check.ts"],
4
- "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport type { OpenApiMethodDoc, OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { featureCheckRequestSchema } from '../data/validators'\n\nexport const metadata = {\n POST: { requireAuth: true },\n}\n\nconst featureCheckResponseSchema = z.object({\n ok: z.boolean().describe('Indicates whether all requested features are granted'),\n granted: z.array(z.string()).describe('Features the current user may access'),\n userId: z.string().describe('ID of the authenticated user'),\n})\n\nexport async function POST(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth) {\n return NextResponse.json({ ok: false, error: 'Unauthorized' }, { status: 401 })\n }\n\n let body: unknown = {}\n try {\n body = await req.json()\n } catch { /* malformed JSON \u2014 safeParse below will reject */ }\n\n const parsed = featureCheckRequestSchema.safeParse(body)\n if (!parsed.success) {\n return NextResponse.json({ ok: false, error: 'Invalid request' }, { status: 400 })\n }\n\n const features = parsed.data.features\n if (!features.length) {\n return NextResponse.json({ ok: true, granted: [], userId: auth.sub })\n }\n\n const container = await createRequestContainer()\n const rbac = (container.resolve('rbacService') as any)\n const ok = await rbac.userHasAllFeatures(auth.sub, features, { tenantId: auth.tenantId, organizationId: auth.orgId })\n if (ok) {\n return NextResponse.json({ ok: true, granted: features, userId: auth.sub })\n }\n\n // Check individually to see which features are granted\n const granted: string[] = []\n for (const f of features) {\n const hasFeature = await rbac.userHasAllFeatures(auth.sub, [f], { tenantId: auth.tenantId, organizationId: auth.orgId })\n if (hasFeature) granted.push(f)\n }\n\n return NextResponse.json({ ok: false, granted, userId: auth.sub })\n}\n\nconst featureCheckMethodDoc: OpenApiMethodDoc = {\n summary: 'Check feature grants for the current user',\n description: 'Evaluates which of the requested features are available to the signed-in user within the active tenant / organization context.',\n tags: ['Authentication & Accounts'],\n requestBody: {\n contentType: 'application/json',\n schema: featureCheckRequestSchema,\n description: 'Feature identifiers to evaluate.',\n },\n responses: [\n {\n status: 200,\n description: 'Evaluation result',\n schema: featureCheckResponseSchema,\n },\n ],\n errors: [\n {\n status: 400,\n description: 'Invalid request \u2014 features array missing, too large, or contains invalid entries',\n schema: z.object({ ok: z.literal(false), error: z.string() }),\n },\n {\n status: 401,\n description: 'Authentication required',\n schema: z.object({ ok: z.literal(false), error: z.string() }),\n },\n ],\n}\n\nexport const openApi: OpenApiRouteDoc = {\n summary: 'Check feature grants for the current user',\n methods: {\n POST: featureCheckMethodDoc,\n },\n}\n"],
5
- "mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,SAAS;AAElB,SAAS,8BAA8B;AACvC,SAAS,0BAA0B;AACnC,SAAS,iCAAiC;AAEnC,MAAM,WAAW;AAAA,EACtB,MAAM,EAAE,aAAa,KAAK;AAC5B;AAEA,MAAM,6BAA6B,EAAE,OAAO;AAAA,EAC1C,IAAI,EAAE,QAAQ,EAAE,SAAS,sDAAsD;AAAA,EAC/E,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,sCAAsC;AAAA,EAC5E,QAAQ,EAAE,OAAO,EAAE,SAAS,8BAA8B;AAC5D,CAAC;AAED,eAAsB,KAAK,KAAc;AACvC,QAAM,OAAO,MAAM,mBAAmB,GAAG;AACzC,MAAI,CAAC,MAAM;AACT,WAAO,aAAa,KAAK,EAAE,IAAI,OAAO,OAAO,eAAe,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EAChF;AAEA,MAAI,OAAgB,CAAC;AACrB,MAAI;AACF,WAAO,MAAM,IAAI,KAAK;AAAA,EACxB,QAAQ;AAAA,EAAqD;AAE7D,QAAM,SAAS,0BAA0B,UAAU,IAAI;AACvD,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO,aAAa,KAAK,EAAE,IAAI,OAAO,OAAO,kBAAkB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACnF;AAEA,QAAM,WAAW,OAAO,KAAK;AAC7B,MAAI,CAAC,SAAS,QAAQ;AACpB,WAAO,aAAa,KAAK,EAAE,IAAI,MAAM,SAAS,CAAC,GAAG,QAAQ,KAAK,IAAI,CAAC;AAAA,EACtE;AAEA,QAAM,YAAY,MAAM,uBAAuB;AAC/C,QAAM,OAAQ,UAAU,QAAQ,aAAa;AAC7C,QAAM,KAAK,MAAM,KAAK,mBAAmB,KAAK,KAAK,UAAU,EAAE,UAAU,KAAK,UAAU,gBAAgB,KAAK,MAAM,CAAC;AACpH,MAAI,IAAI;AACN,WAAO,aAAa,KAAK,EAAE,IAAI,MAAM,SAAS,UAAU,QAAQ,KAAK,IAAI,CAAC;AAAA,EAC5E;AAGA,QAAM,UAAoB,CAAC;AAC3B,aAAW,KAAK,UAAU;AACxB,UAAM,aAAa,MAAM,KAAK,mBAAmB,KAAK,KAAK,CAAC,CAAC,GAAG,EAAE,UAAU,KAAK,UAAU,gBAAgB,KAAK,MAAM,CAAC;AACvH,QAAI,WAAY,SAAQ,KAAK,CAAC;AAAA,EAChC;AAEA,SAAO,aAAa,KAAK,EAAE,IAAI,OAAO,SAAS,QAAQ,KAAK,IAAI,CAAC;AACnE;AAEA,MAAM,wBAA0C;AAAA,EAC9C,SAAS;AAAA,EACT,aAAa;AAAA,EACb,MAAM,CAAC,2BAA2B;AAAA,EAClC,aAAa;AAAA,IACX,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,aAAa;AAAA,EACf;AAAA,EACA,WAAW;AAAA,IACT;AAAA,MACE,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,QAAQ;AAAA,IACV;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN;AAAA,MACE,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,KAAK,GAAG,OAAO,EAAE,OAAO,EAAE,CAAC;AAAA,IAC9D;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,KAAK,GAAG,OAAO,EAAE,OAAO,EAAE,CAAC;AAAA,IAC9D;AAAA,EACF;AACF;AAEO,MAAM,UAA2B;AAAA,EACtC,SAAS;AAAA,EACT,SAAS;AAAA,IACP,MAAM;AAAA,EACR;AACF;",
4
+ "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport type { OpenApiMethodDoc, OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport type { RbacService } from '@open-mercato/core/modules/auth/services/rbacService'\nimport { resolveFeatureCheckContext } from '@open-mercato/core/modules/directory/utils/organizationScope'\nimport { featureCheckRequestSchema } from '../data/validators'\n\nexport const metadata = {\n POST: { requireAuth: true },\n}\n\nconst featureCheckResponseSchema = z.object({\n ok: z.boolean().describe('Indicates whether all requested features are granted'),\n granted: z.array(z.string()).describe('Features the current user may access'),\n userId: z.string().describe('ID of the authenticated user'),\n})\n\nexport async function POST(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth) {\n return NextResponse.json({ ok: false, error: 'Unauthorized' }, { status: 401 })\n }\n\n let body: unknown = {}\n try {\n body = await req.json()\n } catch { /* malformed JSON \u2014 safeParse below will reject */ }\n\n const parsed = featureCheckRequestSchema.safeParse(body)\n if (!parsed.success) {\n return NextResponse.json({ ok: false, error: 'Invalid request' }, { status: 400 })\n }\n\n const features = parsed.data.features\n if (!features.length) {\n return NextResponse.json({ ok: true, granted: [], userId: auth.sub })\n }\n\n const container = await createRequestContainer()\n const rbac = container.resolve<RbacService>('rbacService')\n const featureContext = await resolveFeatureCheckContext({ container, auth, request: req })\n const featureScope = {\n tenantId: featureContext.scope.tenantId ?? auth.tenantId ?? null,\n organizationId: featureContext.organizationId,\n }\n const ok = await rbac.userHasAllFeatures(auth.sub, features, featureScope)\n if (ok) {\n return NextResponse.json({ ok: true, granted: features, userId: auth.sub })\n }\n\n // Check individually to see which features are granted\n const granted: string[] = []\n for (const f of features) {\n const hasFeature = await rbac.userHasAllFeatures(auth.sub, [f], featureScope)\n if (hasFeature) granted.push(f)\n }\n\n return NextResponse.json({ ok: false, granted, userId: auth.sub })\n}\n\nconst featureCheckMethodDoc: OpenApiMethodDoc = {\n summary: 'Check feature grants for the current user',\n description: 'Evaluates which of the requested features are available to the signed-in user within the active tenant / organization context.',\n tags: ['Authentication & Accounts'],\n requestBody: {\n contentType: 'application/json',\n schema: featureCheckRequestSchema,\n description: 'Feature identifiers to evaluate.',\n },\n responses: [\n {\n status: 200,\n description: 'Evaluation result',\n schema: featureCheckResponseSchema,\n },\n ],\n errors: [\n {\n status: 400,\n description: 'Invalid request \u2014 features array missing, too large, or contains invalid entries',\n schema: z.object({ ok: z.literal(false), error: z.string() }),\n },\n {\n status: 401,\n description: 'Authentication required',\n schema: z.object({ ok: z.literal(false), error: z.string() }),\n },\n ],\n}\n\nexport const openApi: OpenApiRouteDoc = {\n summary: 'Check feature grants for the current user',\n methods: {\n POST: featureCheckMethodDoc,\n },\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-mercato/core",
3
- "version": "0.6.8-develop.7093.1.700c5c8d96",
3
+ "version": "0.6.8-develop.7095.1.465fbf8f80",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -252,16 +252,16 @@
252
252
  "zod": "^4.4.3"
253
253
  },
254
254
  "peerDependencies": {
255
- "@open-mercato/ai-assistant": "0.6.8-develop.7093.1.700c5c8d96",
256
- "@open-mercato/shared": "0.6.8-develop.7093.1.700c5c8d96",
257
- "@open-mercato/ui": "0.6.8-develop.7093.1.700c5c8d96",
255
+ "@open-mercato/ai-assistant": "0.6.8-develop.7095.1.465fbf8f80",
256
+ "@open-mercato/shared": "0.6.8-develop.7095.1.465fbf8f80",
257
+ "@open-mercato/ui": "0.6.8-develop.7095.1.465fbf8f80",
258
258
  "react": "^19.0.0",
259
259
  "react-dom": "^19.0.0"
260
260
  },
261
261
  "devDependencies": {
262
- "@open-mercato/ai-assistant": "0.6.8-develop.7093.1.700c5c8d96",
263
- "@open-mercato/shared": "0.6.8-develop.7093.1.700c5c8d96",
264
- "@open-mercato/ui": "0.6.8-develop.7093.1.700c5c8d96",
262
+ "@open-mercato/ai-assistant": "0.6.8-develop.7095.1.465fbf8f80",
263
+ "@open-mercato/shared": "0.6.8-develop.7095.1.465fbf8f80",
264
+ "@open-mercato/ui": "0.6.8-develop.7095.1.465fbf8f80",
265
265
  "@testing-library/dom": "^10.4.1",
266
266
  "@testing-library/jest-dom": "^7.0.0",
267
267
  "@testing-library/react": "^16.3.1",
@@ -3,6 +3,8 @@ import { z } from 'zod'
3
3
  import type { OpenApiMethodDoc, OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'
4
4
  import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
5
5
  import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
6
+ import type { RbacService } from '@open-mercato/core/modules/auth/services/rbacService'
7
+ import { resolveFeatureCheckContext } from '@open-mercato/core/modules/directory/utils/organizationScope'
6
8
  import { featureCheckRequestSchema } from '../data/validators'
7
9
 
8
10
  export const metadata = {
@@ -37,8 +39,13 @@ export async function POST(req: Request) {
37
39
  }
38
40
 
39
41
  const container = await createRequestContainer()
40
- const rbac = (container.resolve('rbacService') as any)
41
- const ok = await rbac.userHasAllFeatures(auth.sub, features, { tenantId: auth.tenantId, organizationId: auth.orgId })
42
+ const rbac = container.resolve<RbacService>('rbacService')
43
+ const featureContext = await resolveFeatureCheckContext({ container, auth, request: req })
44
+ const featureScope = {
45
+ tenantId: featureContext.scope.tenantId ?? auth.tenantId ?? null,
46
+ organizationId: featureContext.organizationId,
47
+ }
48
+ const ok = await rbac.userHasAllFeatures(auth.sub, features, featureScope)
42
49
  if (ok) {
43
50
  return NextResponse.json({ ok: true, granted: features, userId: auth.sub })
44
51
  }
@@ -46,7 +53,7 @@ export async function POST(req: Request) {
46
53
  // Check individually to see which features are granted
47
54
  const granted: string[] = []
48
55
  for (const f of features) {
49
- const hasFeature = await rbac.userHasAllFeatures(auth.sub, [f], { tenantId: auth.tenantId, organizationId: auth.orgId })
56
+ const hasFeature = await rbac.userHasAllFeatures(auth.sub, [f], featureScope)
50
57
  if (hasFeature) granted.push(f)
51
58
  }
52
59