@beechcms/api 0.4.0 → 0.4.1
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/assets/dashboard/assets/index-CH13idU1.js +554 -0
- package/assets/dashboard/index.html +1 -1
- package/package.json +2 -2
- package/src/auth/bcrypt-hash-provider.ts +20 -0
- package/src/auth/constants.ts +3 -3
- package/src/auth/generate-refresh-token.test.ts +19 -0
- package/src/auth/hash-provider.test.ts +46 -0
- package/src/auth/in-memory-hash-provider.ts +13 -0
- package/src/auth/jose-token-service.ts +55 -0
- package/src/auth/login.test.ts +92 -0
- package/src/auth/login.ts +15 -32
- package/src/auth/refresh.ts +0 -122
- package/src/auth/static-token-service.ts +18 -0
- package/src/auth/token-service.test.ts +82 -0
- package/src/factory.ts +70 -78
- package/src/features/content/handlers/create.ts +14 -10
- package/src/features/content/handlers/delete.ts +13 -9
- package/src/features/content/handlers/update.ts +13 -9
- package/src/features/draft/draft.handler.ts +23 -12
- package/src/features/notifications/notifications.handler.ts +25 -54
- package/src/features/password-reset/request.ts +17 -41
- package/src/features/password-reset/reset.ts +18 -54
- package/src/features/rotate-field/rotate-field.handler.ts +15 -19
- package/src/features/schema/schema.handler.ts +1 -1
- package/src/features/settings/settings.handler.ts +62 -175
- package/src/features/setup/index.ts +12 -17
- package/src/features/stats/stats.handler.ts +110 -138
- package/src/middleware/auth-providers.middleware.ts +32 -0
- package/src/middleware/observability.middleware.ts +52 -0
- package/src/middleware/rate-limit.middleware.ts +41 -0
- package/src/middleware/repository.middleware.ts +41 -5
- package/src/middleware.ts +15 -35
- package/src/public/public-add.ts +5 -15
- package/src/public/public-edit.ts +4 -3
- package/src/public/public-read.ts +3 -3
- package/src/public/public-routes.ts +2 -2
- package/src/public/query-builder.test.ts +220 -0
- package/src/public/rate-limit-middleware.ts +7 -19
- package/src/rate-limit/cloudflare-rate-limiter.test.ts +26 -0
- package/src/rate-limit/cloudflare-rate-limiter.ts +11 -0
- package/src/rate-limit/in-memory-rate-limiter.test.ts +33 -0
- package/src/rate-limit/in-memory-rate-limiter.ts +13 -0
- package/src/rate-limit/no-op-rate-limiter.test.ts +18 -0
- package/src/rate-limit/no-op-rate-limiter.ts +7 -0
- package/src/search-utils.test.ts +207 -0
- package/src/search-utils.ts +18 -1
- package/src/search.ts +24 -35
- package/src/shared/apply-policies.test.ts +77 -0
- package/src/shared/background-notification-service.test.ts +58 -0
- package/src/shared/background-notification-service.ts +48 -0
- package/src/shared/content-utils.test.ts +161 -0
- package/src/shared/content.repository.d1.test.ts +312 -0
- package/src/shared/d1-activity-log.repository.test.ts +136 -0
- package/src/shared/d1-activity-log.repository.ts +101 -0
- package/src/shared/d1-activity-logger.test.ts +82 -0
- package/src/shared/d1-activity-logger.ts +63 -0
- package/src/shared/d1-analytics.repository.test.ts +74 -0
- package/src/shared/d1-analytics.repository.ts +81 -0
- package/src/shared/d1-content-scan.repository.ts +29 -0
- package/src/shared/d1-notification.repository.test.ts +124 -0
- package/src/shared/d1-notification.repository.ts +114 -0
- package/src/shared/d1-password-reset-token.repository.test.ts +77 -0
- package/src/shared/d1-password-reset-token.repository.ts +52 -0
- package/src/shared/d1-search.repository.test.ts +83 -0
- package/src/shared/d1-search.repository.ts +84 -0
- package/src/shared/d1-session.repository.test.ts +121 -0
- package/src/shared/d1-session.repository.ts +98 -0
- package/src/shared/d1-user.repository.test.ts +147 -0
- package/src/shared/d1-user.repository.ts +109 -0
- package/src/shared/d1-widget.repository.test.ts +217 -0
- package/src/shared/d1-widget.repository.ts +337 -0
- package/src/shared/fixed-clock.ts +21 -0
- package/src/shared/idempotency.repository.d1.test.ts +79 -0
- package/src/shared/in-memory-activity-logger.ts +15 -0
- package/src/shared/in-memory-notification-service.ts +15 -0
- package/src/shared/media.repository.d1.test.ts +103 -0
- package/src/shared/media.repository.d1.ts +1 -1
- package/src/shared/request-utils.ts +22 -0
- package/src/shared/sequential-id-generator.ts +22 -0
- package/src/shared/system-stats.repository.d1.test.ts +54 -0
- package/src/types.ts +20 -3
- package/src/upload.ts +14 -7
- package/src/widget.ts +112 -253
- package/assets/dashboard/assets/index-FQ6JhvRH.js +0 -554
- package/src/shared/activity-logger.ts +0 -79
- package/src/shared/notification-service.ts +0 -56
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import { Context } from 'hono'
|
|
2
|
-
|
|
3
|
-
export type ActivityAction = 'create' | 'update' | 'delete' | 'upload'
|
|
4
|
-
export type EntityType = 'content' | 'media'
|
|
5
|
-
|
|
6
|
-
export interface ActivityLogParams {
|
|
7
|
-
action: ActivityAction
|
|
8
|
-
entityType: EntityType
|
|
9
|
-
entityId: string
|
|
10
|
-
entitySlug?: string
|
|
11
|
-
details?: Record<string, any>
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Logga un'azione utente asincronamente nel database D1.
|
|
16
|
-
* Estrae le info dell'utente dal JWT payload presente nel contesto Hono.
|
|
17
|
-
*/
|
|
18
|
-
export function logActivity(
|
|
19
|
-
c: Context<any>,
|
|
20
|
-
params: ActivityLogParams
|
|
21
|
-
): void {
|
|
22
|
-
const db = c.env.DB as D1Database
|
|
23
|
-
const user = c.get('jwtPayload') as { sub: string; email: string; name?: string } | undefined
|
|
24
|
-
|
|
25
|
-
if (!db || !user) return
|
|
26
|
-
|
|
27
|
-
const { action, entityType, entityId, entitySlug, details } = params
|
|
28
|
-
const id = crypto.randomUUID()
|
|
29
|
-
|
|
30
|
-
// Usa waitUntil per non bloccare la risposta al client
|
|
31
|
-
let executionCtx: { waitUntil: (p: Promise<any>) => void } | undefined
|
|
32
|
-
try {
|
|
33
|
-
executionCtx = c.executionCtx
|
|
34
|
-
} catch {
|
|
35
|
-
// In ambiente di test Hono lancia se non presente
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if (executionCtx) {
|
|
39
|
-
executionCtx.waitUntil((async () => {
|
|
40
|
-
try {
|
|
41
|
-
await db.prepare(
|
|
42
|
-
`INSERT INTO activity_logs (id, user_id, user_email, user_name, action, entity_type, entity_id, entity_slug, details)
|
|
43
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`
|
|
44
|
-
).bind(
|
|
45
|
-
id,
|
|
46
|
-
user.sub,
|
|
47
|
-
user.email || 'unknown',
|
|
48
|
-
user.name || null,
|
|
49
|
-
action,
|
|
50
|
-
entityType,
|
|
51
|
-
entityId,
|
|
52
|
-
entitySlug || null,
|
|
53
|
-
details ? JSON.stringify(details) : null
|
|
54
|
-
).run()
|
|
55
|
-
} catch (err) {
|
|
56
|
-
console.error('Failed to log activity:', err)
|
|
57
|
-
}
|
|
58
|
-
})())
|
|
59
|
-
} else {
|
|
60
|
-
try {
|
|
61
|
-
db.prepare(
|
|
62
|
-
`INSERT INTO activity_logs (id, user_id, user_email, user_name, action, entity_type, entity_id, entity_slug, details)
|
|
63
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`
|
|
64
|
-
).bind(
|
|
65
|
-
id,
|
|
66
|
-
user.sub,
|
|
67
|
-
user.email || 'unknown',
|
|
68
|
-
user.name || null,
|
|
69
|
-
action,
|
|
70
|
-
entityType,
|
|
71
|
-
entityId,
|
|
72
|
-
entitySlug || null,
|
|
73
|
-
details ? JSON.stringify(details) : null
|
|
74
|
-
).run().catch(err => console.error('Failed to log activity (sync fallback):', err))
|
|
75
|
-
} catch (err) {
|
|
76
|
-
console.error('Failed to log activity (sync fallback):', err)
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { Context } from 'hono'
|
|
2
|
-
|
|
3
|
-
export interface NotificationParams {
|
|
4
|
-
title: string
|
|
5
|
-
message: string
|
|
6
|
-
type?: 'info' | 'success' | 'warning' | 'error'
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Crea una notifica persistente nel database D1.
|
|
11
|
-
* Usata principalmente per segnalare azioni provenienti dalle Public API.
|
|
12
|
-
*/
|
|
13
|
-
export async function createNotification(
|
|
14
|
-
c: Context<any>,
|
|
15
|
-
params: NotificationParams
|
|
16
|
-
): Promise<void> {
|
|
17
|
-
const db = c.env.DB as D1Database
|
|
18
|
-
if (!db) return
|
|
19
|
-
|
|
20
|
-
const { title, message, type = 'info' } = params
|
|
21
|
-
const id = crypto.randomUUID()
|
|
22
|
-
|
|
23
|
-
// Usiamo waitUntil per non bloccare la richiesta dell'utente esterno
|
|
24
|
-
let executionCtx: { waitUntil: (p: Promise<any>) => void } | undefined
|
|
25
|
-
try {
|
|
26
|
-
executionCtx = c.executionCtx
|
|
27
|
-
} catch {
|
|
28
|
-
// In ambiente di test Hono lancia se non presente
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
if (executionCtx) {
|
|
32
|
-
executionCtx.waitUntil((async () => {
|
|
33
|
-
try {
|
|
34
|
-
await db.prepare(
|
|
35
|
-
`INSERT INTO notifications (id, title, message, type)
|
|
36
|
-
VALUES (?, ?, ?, ?)`
|
|
37
|
-
).bind(id, title, message, type).run()
|
|
38
|
-
} catch (err) {
|
|
39
|
-
console.error('Failed to create notification:', err)
|
|
40
|
-
}
|
|
41
|
-
})())
|
|
42
|
-
} else {
|
|
43
|
-
// Fallback sync per test o ambienti senza executionCtx (se vogliamo che le notifiche siano create)
|
|
44
|
-
// Oppure semplicemente ignoriamo. In questo caso, per i test, meglio tentare di crearle
|
|
45
|
-
// ma dato che è un'azione opzionale "background", in test possiamo saltarla o farla sync.
|
|
46
|
-
// Facciamola sync se non c'è executionCtx per garantire che i test che verificano le notifiche (se ce ne sono) passino.
|
|
47
|
-
try {
|
|
48
|
-
await db.prepare(
|
|
49
|
-
`INSERT INTO notifications (id, title, message, type)
|
|
50
|
-
VALUES (?, ?, ?, ?)`
|
|
51
|
-
).bind(id, title, message, type).run()
|
|
52
|
-
} catch (err) {
|
|
53
|
-
console.error('Failed to create notification (sync fallback):', err)
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|