@murumets-ee/create 0.1.18 → 0.1.20
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/cli.mjs +111 -77
- package/dist/index.mjs +111 -77
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -15,9 +15,8 @@ export const allEntities = [
|
|
|
15
15
|
Ticket, TicketMessage, TicketAttachment, Department, TicketTag,
|
|
16
16
|
]
|
|
17
17
|
|
|
18
|
-
/** Taxonomy entities keyed by name */
|
|
18
|
+
/** Taxonomy entities keyed by name (only defineTaxonomy entities) */
|
|
19
19
|
export const taxonomyVocabularies = {
|
|
20
|
-
category: Category,
|
|
21
20
|
department: Department,
|
|
22
21
|
ticket_tag: TicketTag,
|
|
23
22
|
}
|
|
@@ -241,7 +240,7 @@ import { cookies, headers } from 'next/headers'
|
|
|
241
240
|
import { redirect } from 'next/navigation'
|
|
242
241
|
import { Suspense } from 'react'
|
|
243
242
|
import { allEntities } from '@/lib/admin-config'
|
|
244
|
-
import {
|
|
243
|
+
import { getAuthInstance } from '@/lib/auth'
|
|
245
244
|
import { AdminLayout } from '../../admin-layout'
|
|
246
245
|
import { ThemeToggle } from '../../theme-toggle'
|
|
247
246
|
|
|
@@ -252,6 +251,7 @@ async function DynamicShell({
|
|
|
252
251
|
children: React.ReactNode
|
|
253
252
|
interfaceLocale: string
|
|
254
253
|
}) {
|
|
254
|
+
const auth = await getAuthInstance()
|
|
255
255
|
const h = await headers()
|
|
256
256
|
const session = await auth.api.getSession({ headers: h })
|
|
257
257
|
if (!session?.user) {
|
|
@@ -294,7 +294,7 @@ export default async function ShellLayout({
|
|
|
294
294
|
}
|
|
295
295
|
`),await h(r(e,`app/[locale]/(shell)/admin/layout.tsx`),`import { headers } from 'next/headers'
|
|
296
296
|
import { redirect } from 'next/navigation'
|
|
297
|
-
import {
|
|
297
|
+
import { getAuthInstance } from '@/lib/auth'
|
|
298
298
|
|
|
299
299
|
const ALLOWED_ROLES = new Set(['admin', 'editor'])
|
|
300
300
|
|
|
@@ -306,6 +306,7 @@ export default async function AdminGuardLayout({
|
|
|
306
306
|
params: Promise<{ locale: string }>
|
|
307
307
|
}) {
|
|
308
308
|
const { locale } = await params
|
|
309
|
+
const auth = await getAuthInstance()
|
|
309
310
|
const h = await headers()
|
|
310
311
|
const session = await auth.api.getSession({ headers: h })
|
|
311
312
|
|
|
@@ -438,7 +439,7 @@ import { setRequestLocale } from 'next-intl/server'
|
|
|
438
439
|
import { GenericBlockEditor } from '@murumets-ee/admin-ui/content-editor'
|
|
439
440
|
import { GenericEntityForm } from '@murumets-ee/admin-ui/entity-form'
|
|
440
441
|
import { allEntities } from '@/lib/admin-config'
|
|
441
|
-
import {
|
|
442
|
+
import { getAuthInstance } from '@/lib/auth'
|
|
442
443
|
import { loadRoles } from '@/lib/load-roles'
|
|
443
444
|
import { withAdminContext } from '@/lib/with-admin-context'
|
|
444
445
|
|
|
@@ -485,6 +486,7 @@ export default async function EditEntityPage({ params }: EditEntityPageProps) {
|
|
|
485
486
|
}
|
|
486
487
|
}
|
|
487
488
|
|
|
489
|
+
const auth = await getAuthInstance()
|
|
488
490
|
const session = await auth.api.getSession({ headers: await headers() })
|
|
489
491
|
if (session?.user) {
|
|
490
492
|
const role = (session.user as Record<string, unknown>).role as string | undefined
|
|
@@ -884,18 +886,16 @@ export default async function ImageStylesPage({ params }: { params: Promise<{ lo
|
|
|
884
886
|
)
|
|
885
887
|
}
|
|
886
888
|
`),await h(r(e,`app/[locale]/(shell)/admin/users/page.tsx`),`import type { UsersInitialData } from '@murumets-ee/admin-ui/users'
|
|
887
|
-
import { getAuth } from '@murumets-ee/auth'
|
|
888
889
|
import { headers } from 'next/headers'
|
|
889
890
|
import { setRequestLocale } from 'next-intl/server'
|
|
890
|
-
import {
|
|
891
|
+
import { getAuthInstance } from '@/lib/auth'
|
|
891
892
|
import { UsersPage } from './users-page'
|
|
892
893
|
|
|
893
894
|
export default async function UsersAdminPage({ params }: { params: Promise<{ locale: string }> }) {
|
|
894
895
|
const { locale } = await params
|
|
895
896
|
setRequestLocale(locale)
|
|
896
897
|
|
|
897
|
-
await
|
|
898
|
-
const auth = getAuth()
|
|
898
|
+
const auth = await getAuthInstance()
|
|
899
899
|
|
|
900
900
|
const result = await auth.api.listUsers({
|
|
901
901
|
headers: await headers(),
|
|
@@ -1053,7 +1053,7 @@ export default async function ActivityPage({ params }: { params: Promise<{ local
|
|
|
1053
1053
|
import { headers } from 'next/headers'
|
|
1054
1054
|
import { setRequestLocale } from 'next-intl/server'
|
|
1055
1055
|
import { withAdminContext } from '@/lib/with-admin-context'
|
|
1056
|
-
import {
|
|
1056
|
+
import { getAuthInstance } from '@/lib/auth'
|
|
1057
1057
|
import { TicketsInboxClient } from './tickets-inbox-client'
|
|
1058
1058
|
import { fetchEntityList } from '@murumets-ee/admin-ui/server'
|
|
1059
1059
|
import type {
|
|
@@ -1070,6 +1070,7 @@ export default async function TicketsPage({ params }: TicketsPageProps) {
|
|
|
1070
1070
|
const { locale } = await params
|
|
1071
1071
|
setRequestLocale(locale)
|
|
1072
1072
|
|
|
1073
|
+
const auth = await getAuthInstance()
|
|
1073
1074
|
const h = await headers()
|
|
1074
1075
|
const session = await auth.api.getSession({ headers: h })
|
|
1075
1076
|
const currentUserId = session?.user?.id ?? ''
|
|
@@ -1238,9 +1239,8 @@ export function TicketBoardClient({
|
|
|
1238
1239
|
|
|
1239
1240
|
import { getToolkitApp } from '@/lib/app'
|
|
1240
1241
|
|
|
1241
|
-
await getToolkitApp()
|
|
1242
|
-
|
|
1243
1242
|
export async function POST(req: Request): Promise<Response> {
|
|
1243
|
+
await getToolkitApp()
|
|
1244
1244
|
const { handleInboundWebhook } = await import('@murumets-ee/ticketing')
|
|
1245
1245
|
const { QueueClient } = await import('@murumets-ee/queue/client')
|
|
1246
1246
|
const { getApp } = await import('@murumets-ee/core')
|
|
@@ -1258,9 +1258,10 @@ import { Ticket, TicketMessage, Department, TicketTag } from '@murumets-ee/ticke
|
|
|
1258
1258
|
import { headers } from 'next/headers'
|
|
1259
1259
|
import { Article, Category } from '@/entities'
|
|
1260
1260
|
import { getToolkitApp } from '@/lib/app'
|
|
1261
|
-
import {
|
|
1261
|
+
import { getAuthInstance } from '@/lib/auth'
|
|
1262
1262
|
|
|
1263
1263
|
async function requireAdmin() {
|
|
1264
|
+
const auth = await getAuthInstance()
|
|
1264
1265
|
const session = await auth.api.getSession({ headers: await headers() })
|
|
1265
1266
|
if (!session?.user) throw new Error('Unauthorized')
|
|
1266
1267
|
const role = (session.user as Record<string, unknown>).role as string | undefined
|
|
@@ -1274,15 +1275,19 @@ export async function seedContent() {
|
|
|
1274
1275
|
|
|
1275
1276
|
await requireAdmin()
|
|
1276
1277
|
const app = await getToolkitApp()
|
|
1277
|
-
const
|
|
1278
|
+
const categoryAdmin = new AdminClient({
|
|
1279
|
+
entity: Category,
|
|
1280
|
+
db: app.db.readWrite,
|
|
1281
|
+
logger: app.logger.child({ entity: 'category' }),
|
|
1282
|
+
})
|
|
1278
1283
|
const articles = new AdminClient({
|
|
1279
1284
|
entity: Article,
|
|
1280
1285
|
db: app.db.readWrite,
|
|
1281
1286
|
logger: app.logger.child({ entity: 'article' }),
|
|
1282
1287
|
})
|
|
1283
1288
|
|
|
1284
|
-
const techCat = await
|
|
1285
|
-
const newsCat = await
|
|
1289
|
+
const techCat = await categoryAdmin.create({ name: 'Technology', slug: 'technology' })
|
|
1290
|
+
const newsCat = await categoryAdmin.create({ name: 'News', slug: 'news' })
|
|
1286
1291
|
|
|
1287
1292
|
await articles.create({
|
|
1288
1293
|
title: 'Getting Started with Lumi CMS',
|
|
@@ -1502,86 +1507,115 @@ import {
|
|
|
1502
1507
|
taxonomyVocabularies,
|
|
1503
1508
|
} from '@/lib/admin-config'
|
|
1504
1509
|
import { getToolkitApp } from '@/lib/app'
|
|
1505
|
-
import {
|
|
1510
|
+
import { getAuthInstance } from '@/lib/auth'
|
|
1506
1511
|
import { loadRoles } from '@/lib/load-roles'
|
|
1507
1512
|
import { permissionSettings } from '@/settings/permissions'
|
|
1508
1513
|
import { siteSettings } from '@/settings/site'
|
|
1509
1514
|
|
|
1510
|
-
|
|
1511
|
-
|
|
1515
|
+
// Lazy init — no DB connection at import time (safe for next build)
|
|
1516
|
+
let _handler: ReturnType<typeof createAdminApiHandler> | null = null
|
|
1512
1517
|
let _auditLogger: ReturnType<typeof createAuditLogger> | null = null
|
|
1513
1518
|
let _checker: PermissionChecker | null = null
|
|
1514
1519
|
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
storageRoutes(),
|
|
1518
|
-
settingsRoutes(siteSettings),
|
|
1519
|
-
taxonomyRoutes(taxonomyVocabularies),
|
|
1520
|
-
ticketingRoutes(),
|
|
1521
|
-
logRoutes(() => new AuditLogClient(getApp().db.readWrite)),
|
|
1522
|
-
permissionRoutes({
|
|
1523
|
-
getStatements: () => buildResourceCatalog(allEntities, pluginResources),
|
|
1524
|
-
loadRoles: async () => loadRoles(getApp()),
|
|
1525
|
-
saveRoles: async (roles) => {
|
|
1526
|
-
const app = getApp()
|
|
1527
|
-
const client = createSettingsClient(permissionSettings, { app })
|
|
1528
|
-
await client.set('roles', roles)
|
|
1529
|
-
},
|
|
1530
|
-
onSave: () => {
|
|
1531
|
-
_checker = null
|
|
1532
|
-
},
|
|
1533
|
-
}),
|
|
1534
|
-
]
|
|
1520
|
+
async function getHandler() {
|
|
1521
|
+
if (_handler) return _handler
|
|
1535
1522
|
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
_checker = buildPermissionChecker(roles)
|
|
1550
|
-
return _checker
|
|
1551
|
-
},
|
|
1552
|
-
auditLogger: {
|
|
1553
|
-
log: async (entry) => {
|
|
1554
|
-
if (!_auditLogger) {
|
|
1523
|
+
await getToolkitApp()
|
|
1524
|
+
|
|
1525
|
+
const routes = [
|
|
1526
|
+
mediaRoutes(),
|
|
1527
|
+
storageRoutes(),
|
|
1528
|
+
settingsRoutes(siteSettings),
|
|
1529
|
+
taxonomyRoutes(taxonomyVocabularies),
|
|
1530
|
+
ticketingRoutes(),
|
|
1531
|
+
logRoutes(() => new AuditLogClient(getApp().db.readWrite)),
|
|
1532
|
+
permissionRoutes({
|
|
1533
|
+
getStatements: () => buildResourceCatalog(allEntities, pluginResources),
|
|
1534
|
+
loadRoles: async () => loadRoles(getApp()),
|
|
1535
|
+
saveRoles: async (roles) => {
|
|
1555
1536
|
const app = getApp()
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1537
|
+
const client = createSettingsClient(permissionSettings, { app })
|
|
1538
|
+
await client.set('roles', roles)
|
|
1539
|
+
},
|
|
1540
|
+
onSave: () => {
|
|
1541
|
+
_checker = null
|
|
1542
|
+
},
|
|
1543
|
+
}),
|
|
1544
|
+
]
|
|
1545
|
+
|
|
1546
|
+
_handler = createAdminApiHandler({
|
|
1547
|
+
authenticate: async (req) => {
|
|
1548
|
+
const auth = await getAuthInstance()
|
|
1549
|
+
const session = await auth.api.getSession({ headers: req.headers })
|
|
1550
|
+
if (!session?.user) return null
|
|
1551
|
+
const role = (session.user as Record<string, unknown>).role as string | undefined
|
|
1552
|
+
return { id: session.user.id, role, name: session.user.name, email: session.user.email }
|
|
1562
1553
|
},
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1554
|
+
defaultLocale: 'en',
|
|
1555
|
+
entities: crudEntities,
|
|
1556
|
+
routes,
|
|
1557
|
+
loadPermissions: async () => {
|
|
1558
|
+
if (_checker) return _checker
|
|
1559
|
+
const roles = await loadRoles(getApp())
|
|
1560
|
+
_checker = buildPermissionChecker(roles)
|
|
1561
|
+
return _checker
|
|
1562
|
+
},
|
|
1563
|
+
auditLogger: {
|
|
1564
|
+
log: async (entry) => {
|
|
1565
|
+
if (!_auditLogger) {
|
|
1566
|
+
const app = getApp()
|
|
1567
|
+
_auditLogger = createAuditLogger({
|
|
1568
|
+
logger: createLogger({ name: 'audit' }),
|
|
1569
|
+
dbWriter: createAuditDbWriter(app.db.readWrite),
|
|
1570
|
+
})
|
|
1571
|
+
}
|
|
1572
|
+
return _auditLogger.log(entry)
|
|
1573
|
+
},
|
|
1574
|
+
},
|
|
1575
|
+
contentClientFactory: (entity) =>
|
|
1576
|
+
new ContentClient({ entity, db: getApp().db.readWrite }),
|
|
1577
|
+
lockServiceFactory: () =>
|
|
1578
|
+
new LockService({ db: getApp().db.readWrite }),
|
|
1579
|
+
})
|
|
1569
1580
|
|
|
1570
|
-
|
|
1581
|
+
return _handler
|
|
1582
|
+
}
|
|
1583
|
+
|
|
1584
|
+
export async function GET(req: Request) { return (await getHandler()).GET(req) }
|
|
1585
|
+
export async function POST(req: Request) { return (await getHandler()).POST(req) }
|
|
1586
|
+
export async function PATCH(req: Request) { return (await getHandler()).PATCH(req) }
|
|
1587
|
+
export async function DELETE(req: Request) { return (await getHandler()).DELETE(req) }
|
|
1571
1588
|
`)}async function x(e,t){await h(r(e,`lib/auth.ts`),`import { getAuth } from '@murumets-ee/auth'
|
|
1572
1589
|
import { getToolkitApp } from './app'
|
|
1573
1590
|
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1591
|
+
/** Lazily initialize and return the auth instance. Safe for Docker builds. */
|
|
1592
|
+
export async function getAuthInstance() {
|
|
1593
|
+
await getToolkitApp()
|
|
1594
|
+
return getAuth()
|
|
1595
|
+
}
|
|
1577
1596
|
`),await h(r(e,`lib/auth-client.ts`),`import { createClient } from '@murumets-ee/auth/client'
|
|
1578
1597
|
|
|
1579
1598
|
export const authClient = createClient()
|
|
1580
1599
|
`),await h(r(e,`app/api/auth/[...all]/route.ts`),`import { toNextJsHandler } from 'better-auth/next-js'
|
|
1581
|
-
import {
|
|
1600
|
+
import { getAuthInstance } from '@/lib/auth'
|
|
1582
1601
|
|
|
1583
|
-
|
|
1584
|
-
|
|
1602
|
+
let _handler: ReturnType<typeof toNextJsHandler> | null = null
|
|
1603
|
+
|
|
1604
|
+
async function handler() {
|
|
1605
|
+
if (!_handler) {
|
|
1606
|
+
const auth = await getAuthInstance()
|
|
1607
|
+
_handler = toNextJsHandler(auth)
|
|
1608
|
+
}
|
|
1609
|
+
return _handler
|
|
1610
|
+
}
|
|
1611
|
+
|
|
1612
|
+
export async function GET(req: Request) {
|
|
1613
|
+
return (await handler()).GET(req)
|
|
1614
|
+
}
|
|
1615
|
+
|
|
1616
|
+
export async function POST(req: Request) {
|
|
1617
|
+
return (await handler()).POST(req)
|
|
1618
|
+
}
|
|
1585
1619
|
`),await h(r(e,`app/[locale]/auth/layout.tsx`),`import { AuthProviders } from './providers'
|
|
1586
1620
|
import type { ReactNode } from 'react'
|
|
1587
1621
|
|
package/dist/index.mjs
CHANGED
|
@@ -14,9 +14,8 @@ export const allEntities = [
|
|
|
14
14
|
Ticket, TicketMessage, TicketAttachment, Department, TicketTag,
|
|
15
15
|
]
|
|
16
16
|
|
|
17
|
-
/** Taxonomy entities keyed by name */
|
|
17
|
+
/** Taxonomy entities keyed by name (only defineTaxonomy entities) */
|
|
18
18
|
export const taxonomyVocabularies = {
|
|
19
|
-
category: Category,
|
|
20
19
|
department: Department,
|
|
21
20
|
ticket_tag: TicketTag,
|
|
22
21
|
}
|
|
@@ -240,7 +239,7 @@ import { cookies, headers } from 'next/headers'
|
|
|
240
239
|
import { redirect } from 'next/navigation'
|
|
241
240
|
import { Suspense } from 'react'
|
|
242
241
|
import { allEntities } from '@/lib/admin-config'
|
|
243
|
-
import {
|
|
242
|
+
import { getAuthInstance } from '@/lib/auth'
|
|
244
243
|
import { AdminLayout } from '../../admin-layout'
|
|
245
244
|
import { ThemeToggle } from '../../theme-toggle'
|
|
246
245
|
|
|
@@ -251,6 +250,7 @@ async function DynamicShell({
|
|
|
251
250
|
children: React.ReactNode
|
|
252
251
|
interfaceLocale: string
|
|
253
252
|
}) {
|
|
253
|
+
const auth = await getAuthInstance()
|
|
254
254
|
const h = await headers()
|
|
255
255
|
const session = await auth.api.getSession({ headers: h })
|
|
256
256
|
if (!session?.user) {
|
|
@@ -293,7 +293,7 @@ export default async function ShellLayout({
|
|
|
293
293
|
}
|
|
294
294
|
`),await n(a(e,`app/[locale]/(shell)/admin/layout.tsx`),`import { headers } from 'next/headers'
|
|
295
295
|
import { redirect } from 'next/navigation'
|
|
296
|
-
import {
|
|
296
|
+
import { getAuthInstance } from '@/lib/auth'
|
|
297
297
|
|
|
298
298
|
const ALLOWED_ROLES = new Set(['admin', 'editor'])
|
|
299
299
|
|
|
@@ -305,6 +305,7 @@ export default async function AdminGuardLayout({
|
|
|
305
305
|
params: Promise<{ locale: string }>
|
|
306
306
|
}) {
|
|
307
307
|
const { locale } = await params
|
|
308
|
+
const auth = await getAuthInstance()
|
|
308
309
|
const h = await headers()
|
|
309
310
|
const session = await auth.api.getSession({ headers: h })
|
|
310
311
|
|
|
@@ -437,7 +438,7 @@ import { setRequestLocale } from 'next-intl/server'
|
|
|
437
438
|
import { GenericBlockEditor } from '@murumets-ee/admin-ui/content-editor'
|
|
438
439
|
import { GenericEntityForm } from '@murumets-ee/admin-ui/entity-form'
|
|
439
440
|
import { allEntities } from '@/lib/admin-config'
|
|
440
|
-
import {
|
|
441
|
+
import { getAuthInstance } from '@/lib/auth'
|
|
441
442
|
import { loadRoles } from '@/lib/load-roles'
|
|
442
443
|
import { withAdminContext } from '@/lib/with-admin-context'
|
|
443
444
|
|
|
@@ -484,6 +485,7 @@ export default async function EditEntityPage({ params }: EditEntityPageProps) {
|
|
|
484
485
|
}
|
|
485
486
|
}
|
|
486
487
|
|
|
488
|
+
const auth = await getAuthInstance()
|
|
487
489
|
const session = await auth.api.getSession({ headers: await headers() })
|
|
488
490
|
if (session?.user) {
|
|
489
491
|
const role = (session.user as Record<string, unknown>).role as string | undefined
|
|
@@ -883,18 +885,16 @@ export default async function ImageStylesPage({ params }: { params: Promise<{ lo
|
|
|
883
885
|
)
|
|
884
886
|
}
|
|
885
887
|
`),await n(a(e,`app/[locale]/(shell)/admin/users/page.tsx`),`import type { UsersInitialData } from '@murumets-ee/admin-ui/users'
|
|
886
|
-
import { getAuth } from '@murumets-ee/auth'
|
|
887
888
|
import { headers } from 'next/headers'
|
|
888
889
|
import { setRequestLocale } from 'next-intl/server'
|
|
889
|
-
import {
|
|
890
|
+
import { getAuthInstance } from '@/lib/auth'
|
|
890
891
|
import { UsersPage } from './users-page'
|
|
891
892
|
|
|
892
893
|
export default async function UsersAdminPage({ params }: { params: Promise<{ locale: string }> }) {
|
|
893
894
|
const { locale } = await params
|
|
894
895
|
setRequestLocale(locale)
|
|
895
896
|
|
|
896
|
-
await
|
|
897
|
-
const auth = getAuth()
|
|
897
|
+
const auth = await getAuthInstance()
|
|
898
898
|
|
|
899
899
|
const result = await auth.api.listUsers({
|
|
900
900
|
headers: await headers(),
|
|
@@ -1052,7 +1052,7 @@ export default async function ActivityPage({ params }: { params: Promise<{ local
|
|
|
1052
1052
|
import { headers } from 'next/headers'
|
|
1053
1053
|
import { setRequestLocale } from 'next-intl/server'
|
|
1054
1054
|
import { withAdminContext } from '@/lib/with-admin-context'
|
|
1055
|
-
import {
|
|
1055
|
+
import { getAuthInstance } from '@/lib/auth'
|
|
1056
1056
|
import { TicketsInboxClient } from './tickets-inbox-client'
|
|
1057
1057
|
import { fetchEntityList } from '@murumets-ee/admin-ui/server'
|
|
1058
1058
|
import type {
|
|
@@ -1069,6 +1069,7 @@ export default async function TicketsPage({ params }: TicketsPageProps) {
|
|
|
1069
1069
|
const { locale } = await params
|
|
1070
1070
|
setRequestLocale(locale)
|
|
1071
1071
|
|
|
1072
|
+
const auth = await getAuthInstance()
|
|
1072
1073
|
const h = await headers()
|
|
1073
1074
|
const session = await auth.api.getSession({ headers: h })
|
|
1074
1075
|
const currentUserId = session?.user?.id ?? ''
|
|
@@ -1237,9 +1238,8 @@ export function TicketBoardClient({
|
|
|
1237
1238
|
|
|
1238
1239
|
import { getToolkitApp } from '@/lib/app'
|
|
1239
1240
|
|
|
1240
|
-
await getToolkitApp()
|
|
1241
|
-
|
|
1242
1241
|
export async function POST(req: Request): Promise<Response> {
|
|
1242
|
+
await getToolkitApp()
|
|
1243
1243
|
const { handleInboundWebhook } = await import('@murumets-ee/ticketing')
|
|
1244
1244
|
const { QueueClient } = await import('@murumets-ee/queue/client')
|
|
1245
1245
|
const { getApp } = await import('@murumets-ee/core')
|
|
@@ -1257,9 +1257,10 @@ import { Ticket, TicketMessage, Department, TicketTag } from '@murumets-ee/ticke
|
|
|
1257
1257
|
import { headers } from 'next/headers'
|
|
1258
1258
|
import { Article, Category } from '@/entities'
|
|
1259
1259
|
import { getToolkitApp } from '@/lib/app'
|
|
1260
|
-
import {
|
|
1260
|
+
import { getAuthInstance } from '@/lib/auth'
|
|
1261
1261
|
|
|
1262
1262
|
async function requireAdmin() {
|
|
1263
|
+
const auth = await getAuthInstance()
|
|
1263
1264
|
const session = await auth.api.getSession({ headers: await headers() })
|
|
1264
1265
|
if (!session?.user) throw new Error('Unauthorized')
|
|
1265
1266
|
const role = (session.user as Record<string, unknown>).role as string | undefined
|
|
@@ -1273,15 +1274,19 @@ export async function seedContent() {
|
|
|
1273
1274
|
|
|
1274
1275
|
await requireAdmin()
|
|
1275
1276
|
const app = await getToolkitApp()
|
|
1276
|
-
const
|
|
1277
|
+
const categoryAdmin = new AdminClient({
|
|
1278
|
+
entity: Category,
|
|
1279
|
+
db: app.db.readWrite,
|
|
1280
|
+
logger: app.logger.child({ entity: 'category' }),
|
|
1281
|
+
})
|
|
1277
1282
|
const articles = new AdminClient({
|
|
1278
1283
|
entity: Article,
|
|
1279
1284
|
db: app.db.readWrite,
|
|
1280
1285
|
logger: app.logger.child({ entity: 'article' }),
|
|
1281
1286
|
})
|
|
1282
1287
|
|
|
1283
|
-
const techCat = await
|
|
1284
|
-
const newsCat = await
|
|
1288
|
+
const techCat = await categoryAdmin.create({ name: 'Technology', slug: 'technology' })
|
|
1289
|
+
const newsCat = await categoryAdmin.create({ name: 'News', slug: 'news' })
|
|
1285
1290
|
|
|
1286
1291
|
await articles.create({
|
|
1287
1292
|
title: 'Getting Started with Lumi CMS',
|
|
@@ -1501,86 +1506,115 @@ import {
|
|
|
1501
1506
|
taxonomyVocabularies,
|
|
1502
1507
|
} from '@/lib/admin-config'
|
|
1503
1508
|
import { getToolkitApp } from '@/lib/app'
|
|
1504
|
-
import {
|
|
1509
|
+
import { getAuthInstance } from '@/lib/auth'
|
|
1505
1510
|
import { loadRoles } from '@/lib/load-roles'
|
|
1506
1511
|
import { permissionSettings } from '@/settings/permissions'
|
|
1507
1512
|
import { siteSettings } from '@/settings/site'
|
|
1508
1513
|
|
|
1509
|
-
|
|
1510
|
-
|
|
1514
|
+
// Lazy init — no DB connection at import time (safe for next build)
|
|
1515
|
+
let _handler: ReturnType<typeof createAdminApiHandler> | null = null
|
|
1511
1516
|
let _auditLogger: ReturnType<typeof createAuditLogger> | null = null
|
|
1512
1517
|
let _checker: PermissionChecker | null = null
|
|
1513
1518
|
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
storageRoutes(),
|
|
1517
|
-
settingsRoutes(siteSettings),
|
|
1518
|
-
taxonomyRoutes(taxonomyVocabularies),
|
|
1519
|
-
ticketingRoutes(),
|
|
1520
|
-
logRoutes(() => new AuditLogClient(getApp().db.readWrite)),
|
|
1521
|
-
permissionRoutes({
|
|
1522
|
-
getStatements: () => buildResourceCatalog(allEntities, pluginResources),
|
|
1523
|
-
loadRoles: async () => loadRoles(getApp()),
|
|
1524
|
-
saveRoles: async (roles) => {
|
|
1525
|
-
const app = getApp()
|
|
1526
|
-
const client = createSettingsClient(permissionSettings, { app })
|
|
1527
|
-
await client.set('roles', roles)
|
|
1528
|
-
},
|
|
1529
|
-
onSave: () => {
|
|
1530
|
-
_checker = null
|
|
1531
|
-
},
|
|
1532
|
-
}),
|
|
1533
|
-
]
|
|
1519
|
+
async function getHandler() {
|
|
1520
|
+
if (_handler) return _handler
|
|
1534
1521
|
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
_checker = buildPermissionChecker(roles)
|
|
1549
|
-
return _checker
|
|
1550
|
-
},
|
|
1551
|
-
auditLogger: {
|
|
1552
|
-
log: async (entry) => {
|
|
1553
|
-
if (!_auditLogger) {
|
|
1522
|
+
await getToolkitApp()
|
|
1523
|
+
|
|
1524
|
+
const routes = [
|
|
1525
|
+
mediaRoutes(),
|
|
1526
|
+
storageRoutes(),
|
|
1527
|
+
settingsRoutes(siteSettings),
|
|
1528
|
+
taxonomyRoutes(taxonomyVocabularies),
|
|
1529
|
+
ticketingRoutes(),
|
|
1530
|
+
logRoutes(() => new AuditLogClient(getApp().db.readWrite)),
|
|
1531
|
+
permissionRoutes({
|
|
1532
|
+
getStatements: () => buildResourceCatalog(allEntities, pluginResources),
|
|
1533
|
+
loadRoles: async () => loadRoles(getApp()),
|
|
1534
|
+
saveRoles: async (roles) => {
|
|
1554
1535
|
const app = getApp()
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1536
|
+
const client = createSettingsClient(permissionSettings, { app })
|
|
1537
|
+
await client.set('roles', roles)
|
|
1538
|
+
},
|
|
1539
|
+
onSave: () => {
|
|
1540
|
+
_checker = null
|
|
1541
|
+
},
|
|
1542
|
+
}),
|
|
1543
|
+
]
|
|
1544
|
+
|
|
1545
|
+
_handler = createAdminApiHandler({
|
|
1546
|
+
authenticate: async (req) => {
|
|
1547
|
+
const auth = await getAuthInstance()
|
|
1548
|
+
const session = await auth.api.getSession({ headers: req.headers })
|
|
1549
|
+
if (!session?.user) return null
|
|
1550
|
+
const role = (session.user as Record<string, unknown>).role as string | undefined
|
|
1551
|
+
return { id: session.user.id, role, name: session.user.name, email: session.user.email }
|
|
1561
1552
|
},
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1553
|
+
defaultLocale: 'en',
|
|
1554
|
+
entities: crudEntities,
|
|
1555
|
+
routes,
|
|
1556
|
+
loadPermissions: async () => {
|
|
1557
|
+
if (_checker) return _checker
|
|
1558
|
+
const roles = await loadRoles(getApp())
|
|
1559
|
+
_checker = buildPermissionChecker(roles)
|
|
1560
|
+
return _checker
|
|
1561
|
+
},
|
|
1562
|
+
auditLogger: {
|
|
1563
|
+
log: async (entry) => {
|
|
1564
|
+
if (!_auditLogger) {
|
|
1565
|
+
const app = getApp()
|
|
1566
|
+
_auditLogger = createAuditLogger({
|
|
1567
|
+
logger: createLogger({ name: 'audit' }),
|
|
1568
|
+
dbWriter: createAuditDbWriter(app.db.readWrite),
|
|
1569
|
+
})
|
|
1570
|
+
}
|
|
1571
|
+
return _auditLogger.log(entry)
|
|
1572
|
+
},
|
|
1573
|
+
},
|
|
1574
|
+
contentClientFactory: (entity) =>
|
|
1575
|
+
new ContentClient({ entity, db: getApp().db.readWrite }),
|
|
1576
|
+
lockServiceFactory: () =>
|
|
1577
|
+
new LockService({ db: getApp().db.readWrite }),
|
|
1578
|
+
})
|
|
1568
1579
|
|
|
1569
|
-
|
|
1580
|
+
return _handler
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1583
|
+
export async function GET(req: Request) { return (await getHandler()).GET(req) }
|
|
1584
|
+
export async function POST(req: Request) { return (await getHandler()).POST(req) }
|
|
1585
|
+
export async function PATCH(req: Request) { return (await getHandler()).PATCH(req) }
|
|
1586
|
+
export async function DELETE(req: Request) { return (await getHandler()).DELETE(req) }
|
|
1570
1587
|
`)}async function c(e,t){await n(a(e,`lib/auth.ts`),`import { getAuth } from '@murumets-ee/auth'
|
|
1571
1588
|
import { getToolkitApp } from './app'
|
|
1572
1589
|
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1590
|
+
/** Lazily initialize and return the auth instance. Safe for Docker builds. */
|
|
1591
|
+
export async function getAuthInstance() {
|
|
1592
|
+
await getToolkitApp()
|
|
1593
|
+
return getAuth()
|
|
1594
|
+
}
|
|
1576
1595
|
`),await n(a(e,`lib/auth-client.ts`),`import { createClient } from '@murumets-ee/auth/client'
|
|
1577
1596
|
|
|
1578
1597
|
export const authClient = createClient()
|
|
1579
1598
|
`),await n(a(e,`app/api/auth/[...all]/route.ts`),`import { toNextJsHandler } from 'better-auth/next-js'
|
|
1580
|
-
import {
|
|
1599
|
+
import { getAuthInstance } from '@/lib/auth'
|
|
1581
1600
|
|
|
1582
|
-
|
|
1583
|
-
|
|
1601
|
+
let _handler: ReturnType<typeof toNextJsHandler> | null = null
|
|
1602
|
+
|
|
1603
|
+
async function handler() {
|
|
1604
|
+
if (!_handler) {
|
|
1605
|
+
const auth = await getAuthInstance()
|
|
1606
|
+
_handler = toNextJsHandler(auth)
|
|
1607
|
+
}
|
|
1608
|
+
return _handler
|
|
1609
|
+
}
|
|
1610
|
+
|
|
1611
|
+
export async function GET(req: Request) {
|
|
1612
|
+
return (await handler()).GET(req)
|
|
1613
|
+
}
|
|
1614
|
+
|
|
1615
|
+
export async function POST(req: Request) {
|
|
1616
|
+
return (await handler()).POST(req)
|
|
1617
|
+
}
|
|
1584
1618
|
`),await n(a(e,`app/[locale]/auth/layout.tsx`),`import { AuthProviders } from './providers'
|
|
1585
1619
|
import type { ReactNode } from 'react'
|
|
1586
1620
|
|