create-mercato-app 0.6.5-develop.4964.1.ae0edca575 → 0.6.5-develop.5048.1.fd82f4ae17
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/package.json
CHANGED
|
@@ -21,9 +21,21 @@ import { applicationLifecycleEvents, type ApplicationLifecycleEventId } from '@o
|
|
|
21
21
|
bootstrap()
|
|
22
22
|
registerApiRouteManifests(apiRoutes)
|
|
23
23
|
|
|
24
|
+
const warnedDeprecatedRequireRoles = new Set<string>()
|
|
25
|
+
|
|
26
|
+
function warnDeprecatedRequireRoles(pathname: string, method: HttpMethod): void {
|
|
27
|
+
const warnKey = `${method} ${pathname}`
|
|
28
|
+
if (warnedDeprecatedRequireRoles.has(warnKey)) return
|
|
29
|
+
warnedDeprecatedRequireRoles.add(warnKey)
|
|
30
|
+
console.warn(
|
|
31
|
+
'[api] Ignoring deprecated `requireRoles` guard — role names are mutable and spoofable, so they no longer authorize requests. Migrate to `requireFeatures` with immutable acl.ts feature IDs.',
|
|
32
|
+
{ path: pathname, method },
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
|
|
24
36
|
type MethodMetadata = {
|
|
25
37
|
requireAuth?: boolean
|
|
26
|
-
/** @deprecated
|
|
38
|
+
/** @deprecated Ignored at runtime — role names are mutable and can be spoofed. Use `requireFeatures` instead. */
|
|
27
39
|
requireRoles?: string[]
|
|
28
40
|
requireFeatures?: string[]
|
|
29
41
|
rateLimit?: RateLimitConfig
|
|
@@ -138,14 +150,14 @@ async function checkAuthorization(
|
|
|
138
150
|
return NextResponse.json({ error: t('api.errors.unauthorized', 'Unauthorized') }, { status: 401 })
|
|
139
151
|
}
|
|
140
152
|
|
|
141
|
-
const requiredRoles = methodMetadata?.requireRoles ?? []
|
|
142
153
|
const requiredFeatures = methodMetadata?.requireFeatures ?? []
|
|
143
154
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
155
|
+
// `requireRoles` is deprecated and intentionally NOT enforced: role names are
|
|
156
|
+
// tenant-mutable and spoofable, so honoring them would let a tenant admin create
|
|
157
|
+
// or rename a role to satisfy the guard. Authorization decisions must use
|
|
158
|
+
// immutable feature IDs via `requireFeatures`. We warn so operators migrate.
|
|
159
|
+
if (methodMetadata?.requireRoles?.length) {
|
|
160
|
+
warnDeprecatedRequireRoles(req.nextUrl.pathname, req.method.toUpperCase() as HttpMethod)
|
|
149
161
|
}
|
|
150
162
|
|
|
151
163
|
let container: Awaited<ReturnType<typeof createRequestContainer>> | null = null
|
|
@@ -236,7 +248,7 @@ function sanitizeTenantCandidate(candidate: unknown): unknown {
|
|
|
236
248
|
return candidate
|
|
237
249
|
}
|
|
238
250
|
|
|
239
|
-
async function extractTenantCandidate(req: NextRequest): Promise<unknown> {
|
|
251
|
+
export async function extractTenantCandidate(req: NextRequest): Promise<unknown> {
|
|
240
252
|
const tenantParams = req.nextUrl?.searchParams?.getAll?.('tenantId') ?? []
|
|
241
253
|
if (tenantParams.length > 0) {
|
|
242
254
|
return tenantParams[tenantParams.length - 1]
|
|
@@ -261,7 +273,7 @@ async function extractTenantCandidate(req: NextRequest): Promise<unknown> {
|
|
|
261
273
|
const form = await req.clone().formData()
|
|
262
274
|
if (form.has('tenantId')) {
|
|
263
275
|
const value = form.get('tenantId')
|
|
264
|
-
if (value instanceof File) return
|
|
276
|
+
if (value instanceof File) return undefined
|
|
265
277
|
return value
|
|
266
278
|
}
|
|
267
279
|
}
|