nextjs-cms 0.5.90 → 0.5.91
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/api/index.d.ts +57 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/lib/serverActions.d.ts +2 -1
- package/dist/api/lib/serverActions.d.ts.map +1 -1
- package/dist/api/lib/serverActions.js +49 -15
- package/dist/api/root.d.ts +114 -0
- package/dist/api/root.d.ts.map +1 -1
- package/dist/api/root.js +2 -0
- package/dist/api/routers/accountSettings.d.ts.map +1 -1
- package/dist/api/routers/accountSettings.js +65 -3
- package/dist/api/routers/admins.d.ts.map +1 -1
- package/dist/api/routers/admins.js +54 -2
- package/dist/api/routers/auth.d.ts.map +1 -1
- package/dist/api/routers/auth.js +27 -2
- package/dist/api/routers/categorySection.d.ts.map +1 -1
- package/dist/api/routers/categorySection.js +3 -1
- package/dist/api/routers/hasItemsSection.d.ts.map +1 -1
- package/dist/api/routers/hasItemsSection.js +3 -1
- package/dist/api/routers/logs.d.ts +59 -0
- package/dist/api/routers/logs.d.ts.map +1 -0
- package/dist/api/routers/logs.js +75 -0
- package/dist/core/fields/photo.d.ts +6 -6
- package/dist/core/fields/richText.d.ts +9 -9
- package/dist/core/fields/select.d.ts +1 -1
- package/dist/core/sections/category.d.ts +6 -6
- package/dist/core/sections/hasItems.d.ts +12 -12
- package/dist/core/sections/section.d.ts +3 -3
- package/dist/core/sections/simple.d.ts +4 -4
- package/dist/core/submit/ItemEditSubmit.d.ts +7 -0
- package/dist/core/submit/ItemEditSubmit.d.ts.map +1 -1
- package/dist/core/submit/ItemEditSubmit.js +32 -0
- package/dist/core/submit/NewItemSubmit.d.ts +2 -0
- package/dist/core/submit/NewItemSubmit.d.ts.map +1 -1
- package/dist/core/submit/NewItemSubmit.js +3 -0
- package/dist/core/submit/submit.d.ts +8 -4
- package/dist/core/submit/submit.d.ts.map +1 -1
- package/dist/core/submit/submit.js +58 -8
- package/dist/db/schema.d.ts +231 -0
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/schema.js +25 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/logging/audit.d.ts +20 -0
- package/dist/logging/audit.d.ts.map +1 -0
- package/dist/logging/audit.js +48 -0
- package/dist/logging/index.d.ts +2 -0
- package/dist/logging/index.d.ts.map +1 -0
- package/dist/logging/index.js +1 -0
- package/dist/logging/log.d.ts +20 -0
- package/dist/logging/log.d.ts.map +1 -0
- package/dist/logging/log.js +48 -0
- package/dist/translations/dictionaries/ar.json +6 -0
- package/dist/translations/dictionaries/en.json +6 -0
- package/package.json +5 -1
package/dist/api/index.d.ts
CHANGED
|
@@ -732,6 +732,63 @@ declare const createCaller: import("@trpc/server").TRPCRouterCaller<{
|
|
|
732
732
|
meta: object;
|
|
733
733
|
}>;
|
|
734
734
|
}>>;
|
|
735
|
+
logs: import("@trpc/server").TRPCBuiltRouter<{
|
|
736
|
+
ctx: {
|
|
737
|
+
headers: Headers;
|
|
738
|
+
db: import("drizzle-orm/mysql2").MySql2Database<typeof import("../db/schema.js")> & {
|
|
739
|
+
$client: import("mysql2/promise").Pool;
|
|
740
|
+
};
|
|
741
|
+
session: import("../index.js").Session | null;
|
|
742
|
+
};
|
|
743
|
+
meta: object;
|
|
744
|
+
errorShape: {
|
|
745
|
+
data: {
|
|
746
|
+
zodError: import("zod").ZodFlattenedError<unknown, string> | null;
|
|
747
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
|
|
748
|
+
httpStatus: number;
|
|
749
|
+
path?: string;
|
|
750
|
+
stack?: string;
|
|
751
|
+
};
|
|
752
|
+
message: string;
|
|
753
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_NUMBER;
|
|
754
|
+
};
|
|
755
|
+
transformer: true;
|
|
756
|
+
}, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
|
|
757
|
+
list: import("@trpc/server").TRPCQueryProcedure<{
|
|
758
|
+
input: {
|
|
759
|
+
limit?: number | undefined;
|
|
760
|
+
offset?: number | undefined;
|
|
761
|
+
eventType?: string | undefined;
|
|
762
|
+
actorId?: string | undefined;
|
|
763
|
+
sectionName?: string | undefined;
|
|
764
|
+
entityType?: string | undefined;
|
|
765
|
+
entityId?: string | undefined;
|
|
766
|
+
from?: string | undefined;
|
|
767
|
+
to?: string | undefined;
|
|
768
|
+
} | undefined;
|
|
769
|
+
output: {
|
|
770
|
+
items: {
|
|
771
|
+
id: number;
|
|
772
|
+
eventType: string;
|
|
773
|
+
actorId: string | null;
|
|
774
|
+
actorUsername: string | null;
|
|
775
|
+
entityType: string | null;
|
|
776
|
+
entityId: string | null;
|
|
777
|
+
entityLabel: string | null;
|
|
778
|
+
sectionName: string | null;
|
|
779
|
+
metadata: string | null;
|
|
780
|
+
ipAddress: string | null;
|
|
781
|
+
userAgent: string | null;
|
|
782
|
+
source: string | null;
|
|
783
|
+
createdAt: Date;
|
|
784
|
+
}[];
|
|
785
|
+
total: number;
|
|
786
|
+
limit: number;
|
|
787
|
+
offset: number;
|
|
788
|
+
};
|
|
789
|
+
meta: object;
|
|
790
|
+
}>;
|
|
791
|
+
}>>;
|
|
735
792
|
plugins: import("@trpc/server").TRPCBuiltRouter<{
|
|
736
793
|
ctx: {
|
|
737
794
|
headers: Headers;
|
package/dist/api/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAEzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAC1C,OAAO,EAAE,SAAS,EAAE,uBAAuB,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAC5E,OAAO,EAEH,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,MAAM,EACN,eAAe,EAClB,MAAM,WAAW,CAAA;AAElB;;;;;;GAMG;AACH,QAAA,MAAM,YAAY
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAEzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAC1C,OAAO,EAAE,SAAS,EAAE,uBAAuB,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAC5E,OAAO,EAEH,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,MAAM,EACN,eAAe,EAClB,MAAM,WAAW,CAAA;AAElB;;;;;;GAMG;AACH,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAAiC,CAAA;AAEnD;;;;;IAKI;AACJ,KAAK,YAAY,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAA;AAEhD;;;;;IAKI;AACJ,KAAK,aAAa,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAA;AAElD,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,YAAY,EAAE,uBAAuB,EAAE,YAAY,EAAE,CAAA;AAC5F,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,gBAAgB,EAAE,eAAe,EAAE,CAAA;AACrE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,CAAA;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Session } from '../../auth/index.js';
|
|
2
|
+
import { type RequestMetadata } from '../../logging/index.js';
|
|
2
3
|
export declare const isAccessAllowed: ({ sectionName, role, userId, }: {
|
|
3
4
|
sectionName: string;
|
|
4
5
|
role?: "C" | "U" | "D";
|
|
@@ -88,7 +89,7 @@ export declare const createSimpleSectionPage: (session: Session, sectionName: st
|
|
|
88
89
|
}[] | undefined;
|
|
89
90
|
error?: undefined;
|
|
90
91
|
}>;
|
|
91
|
-
export declare const deleteSectionItem: (session: Session, sectionName: string, sectionItemId: string | number, recursive?: boolean) => Promise<true | {
|
|
92
|
+
export declare const deleteSectionItem: (session: Session, sectionName: string, sectionItemId: string | number, recursive?: boolean, requestMetadata?: RequestMetadata) => Promise<true | {
|
|
92
93
|
error: {
|
|
93
94
|
message: string;
|
|
94
95
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serverActions.d.ts","sourceRoot":"","sources":["../../../src/api/lib/serverActions.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"serverActions.d.ts","sourceRoot":"","sources":["../../../src/api/lib/serverActions.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,6 +15,7 @@ import { fileTypeFromBuffer } from 'file-type';
|
|
|
15
15
|
import { getCMSConfig } from '../../core/config/index.js';
|
|
16
16
|
import { getPluginRoutes } from '../../plugins/loader.js';
|
|
17
17
|
import through2 from 'through2';
|
|
18
|
+
import { recordLog } from '../../logging/index.js';
|
|
18
19
|
export const isAccessAllowed = async ({ sectionName, role, userId, }) => {
|
|
19
20
|
/**
|
|
20
21
|
* Check admin privileges
|
|
@@ -56,6 +57,12 @@ export const getDocument = async (session, input) => {
|
|
|
56
57
|
});
|
|
57
58
|
}
|
|
58
59
|
const fieldConfig = section.fields.find((field) => field.name === fieldName);
|
|
60
|
+
if (!fieldConfig || typeof fieldConfig.build !== 'function') {
|
|
61
|
+
throw new TRPCError({
|
|
62
|
+
code: 'BAD_REQUEST',
|
|
63
|
+
message: 'Invalid request',
|
|
64
|
+
});
|
|
65
|
+
}
|
|
59
66
|
const field = fieldConfig.build();
|
|
60
67
|
/**
|
|
61
68
|
* If field is not found, throw an error
|
|
@@ -341,7 +348,7 @@ export const createSimpleSectionPage = async (session, sectionName) => {
|
|
|
341
348
|
};
|
|
342
349
|
}
|
|
343
350
|
};
|
|
344
|
-
export const deleteSectionItem = async (session, sectionName, sectionItemId, recursive) => {
|
|
351
|
+
export const deleteSectionItem = async (session, sectionName, sectionItemId, recursive, requestMetadata) => {
|
|
345
352
|
/**
|
|
346
353
|
* Convert the section item id to string
|
|
347
354
|
*/
|
|
@@ -388,21 +395,29 @@ export const deleteSectionItem = async (session, sectionName, sectionItemId, rec
|
|
|
388
395
|
*/
|
|
389
396
|
const fileFieldConfigs = section.fieldConfigs.filter((fieldConfig) => fieldConfig.type === 'document' || fieldConfig.type === 'photo' || fieldConfig.type === 'video');
|
|
390
397
|
const uploadsFolder = (await getCMSConfig()).media.upload.path;
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
if (
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
398
|
+
if (sectionItemRow) {
|
|
399
|
+
for (const field of fileFieldConfigs) {
|
|
400
|
+
// @ts-ignore
|
|
401
|
+
const value = sectionItemRow[field.name];
|
|
402
|
+
if (value) {
|
|
403
|
+
if (field.type === 'document') {
|
|
404
|
+
try {
|
|
405
|
+
await fs.promises.unlink(path.join(uploadsFolder, '.documents', section.name, value));
|
|
406
|
+
}
|
|
407
|
+
catch (error) {
|
|
408
|
+
// Log but continue - file may not exist or already deleted
|
|
409
|
+
console.error('Error deleting document', error);
|
|
410
|
+
}
|
|
402
411
|
}
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
412
|
+
else {
|
|
413
|
+
try {
|
|
414
|
+
await fs.promises.unlink(path.join(uploadsFolder, '.photos', section.name, value));
|
|
415
|
+
await fs.promises.unlink(path.join(uploadsFolder, '.thumbs', section.name, value));
|
|
416
|
+
}
|
|
417
|
+
catch (error) {
|
|
418
|
+
// Log but continue - file may not exist or already deleted
|
|
419
|
+
console.error('Error deleting photo', error);
|
|
420
|
+
}
|
|
406
421
|
}
|
|
407
422
|
}
|
|
408
423
|
}
|
|
@@ -496,6 +511,25 @@ export const deleteSectionItem = async (session, sectionName, sectionItemId, rec
|
|
|
496
511
|
console.error('onDelete hook failed:', error);
|
|
497
512
|
}
|
|
498
513
|
}
|
|
514
|
+
const headingFieldName = section.headingField.name;
|
|
515
|
+
const entityLabel = headingFieldName && sectionItemRow
|
|
516
|
+
// @ts-ignore
|
|
517
|
+
? String(sectionItemRow[headingFieldName] ?? '')
|
|
518
|
+
: null;
|
|
519
|
+
await recordLog({
|
|
520
|
+
eventType: 'section.item.delete',
|
|
521
|
+
actorId: session.user.id,
|
|
522
|
+
actorUsername: session.user.name,
|
|
523
|
+
entityType: 'section_item',
|
|
524
|
+
entityId: sectionItemId,
|
|
525
|
+
entityLabel: entityLabel?.trim() ? entityLabel : null,
|
|
526
|
+
sectionName: section.name,
|
|
527
|
+
metadata: {
|
|
528
|
+
sectionType: section.type,
|
|
529
|
+
recursive: Boolean(recursive),
|
|
530
|
+
},
|
|
531
|
+
requestMetadata,
|
|
532
|
+
});
|
|
499
533
|
return true;
|
|
500
534
|
}
|
|
501
535
|
catch (err) {
|
package/dist/api/root.d.ts
CHANGED
|
@@ -723,6 +723,63 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
723
723
|
meta: object;
|
|
724
724
|
}>;
|
|
725
725
|
}>>;
|
|
726
|
+
logs: import("@trpc/server").TRPCBuiltRouter<{
|
|
727
|
+
ctx: {
|
|
728
|
+
headers: Headers;
|
|
729
|
+
db: import("drizzle-orm/mysql2").MySql2Database<typeof import("../db/schema.js")> & {
|
|
730
|
+
$client: import("mysql2/promise").Pool;
|
|
731
|
+
};
|
|
732
|
+
session: import("../index.js").Session | null;
|
|
733
|
+
};
|
|
734
|
+
meta: object;
|
|
735
|
+
errorShape: {
|
|
736
|
+
data: {
|
|
737
|
+
zodError: z.core.$ZodFlattenedError<unknown, string> | null;
|
|
738
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
|
|
739
|
+
httpStatus: number;
|
|
740
|
+
path?: string;
|
|
741
|
+
stack?: string;
|
|
742
|
+
};
|
|
743
|
+
message: string;
|
|
744
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_NUMBER;
|
|
745
|
+
};
|
|
746
|
+
transformer: true;
|
|
747
|
+
}, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
|
|
748
|
+
list: import("@trpc/server").TRPCQueryProcedure<{
|
|
749
|
+
input: {
|
|
750
|
+
limit?: number | undefined;
|
|
751
|
+
offset?: number | undefined;
|
|
752
|
+
eventType?: string | undefined;
|
|
753
|
+
actorId?: string | undefined;
|
|
754
|
+
sectionName?: string | undefined;
|
|
755
|
+
entityType?: string | undefined;
|
|
756
|
+
entityId?: string | undefined;
|
|
757
|
+
from?: string | undefined;
|
|
758
|
+
to?: string | undefined;
|
|
759
|
+
} | undefined;
|
|
760
|
+
output: {
|
|
761
|
+
items: {
|
|
762
|
+
id: number;
|
|
763
|
+
eventType: string;
|
|
764
|
+
actorId: string | null;
|
|
765
|
+
actorUsername: string | null;
|
|
766
|
+
entityType: string | null;
|
|
767
|
+
entityId: string | null;
|
|
768
|
+
entityLabel: string | null;
|
|
769
|
+
sectionName: string | null;
|
|
770
|
+
metadata: string | null;
|
|
771
|
+
ipAddress: string | null;
|
|
772
|
+
userAgent: string | null;
|
|
773
|
+
source: string | null;
|
|
774
|
+
createdAt: Date;
|
|
775
|
+
}[];
|
|
776
|
+
total: number;
|
|
777
|
+
limit: number;
|
|
778
|
+
offset: number;
|
|
779
|
+
};
|
|
780
|
+
meta: object;
|
|
781
|
+
}>;
|
|
782
|
+
}>>;
|
|
726
783
|
plugins: import("@trpc/server").TRPCBuiltRouter<{
|
|
727
784
|
ctx: {
|
|
728
785
|
headers: Headers;
|
|
@@ -1501,6 +1558,63 @@ export declare const createCaller: import("@trpc/server").TRPCRouterCaller<{
|
|
|
1501
1558
|
meta: object;
|
|
1502
1559
|
}>;
|
|
1503
1560
|
}>>;
|
|
1561
|
+
logs: import("@trpc/server").TRPCBuiltRouter<{
|
|
1562
|
+
ctx: {
|
|
1563
|
+
headers: Headers;
|
|
1564
|
+
db: import("drizzle-orm/mysql2").MySql2Database<typeof import("../db/schema.js")> & {
|
|
1565
|
+
$client: import("mysql2/promise").Pool;
|
|
1566
|
+
};
|
|
1567
|
+
session: import("../index.js").Session | null;
|
|
1568
|
+
};
|
|
1569
|
+
meta: object;
|
|
1570
|
+
errorShape: {
|
|
1571
|
+
data: {
|
|
1572
|
+
zodError: z.core.$ZodFlattenedError<unknown, string> | null;
|
|
1573
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
|
|
1574
|
+
httpStatus: number;
|
|
1575
|
+
path?: string;
|
|
1576
|
+
stack?: string;
|
|
1577
|
+
};
|
|
1578
|
+
message: string;
|
|
1579
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_NUMBER;
|
|
1580
|
+
};
|
|
1581
|
+
transformer: true;
|
|
1582
|
+
}, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
|
|
1583
|
+
list: import("@trpc/server").TRPCQueryProcedure<{
|
|
1584
|
+
input: {
|
|
1585
|
+
limit?: number | undefined;
|
|
1586
|
+
offset?: number | undefined;
|
|
1587
|
+
eventType?: string | undefined;
|
|
1588
|
+
actorId?: string | undefined;
|
|
1589
|
+
sectionName?: string | undefined;
|
|
1590
|
+
entityType?: string | undefined;
|
|
1591
|
+
entityId?: string | undefined;
|
|
1592
|
+
from?: string | undefined;
|
|
1593
|
+
to?: string | undefined;
|
|
1594
|
+
} | undefined;
|
|
1595
|
+
output: {
|
|
1596
|
+
items: {
|
|
1597
|
+
id: number;
|
|
1598
|
+
eventType: string;
|
|
1599
|
+
actorId: string | null;
|
|
1600
|
+
actorUsername: string | null;
|
|
1601
|
+
entityType: string | null;
|
|
1602
|
+
entityId: string | null;
|
|
1603
|
+
entityLabel: string | null;
|
|
1604
|
+
sectionName: string | null;
|
|
1605
|
+
metadata: string | null;
|
|
1606
|
+
ipAddress: string | null;
|
|
1607
|
+
userAgent: string | null;
|
|
1608
|
+
source: string | null;
|
|
1609
|
+
createdAt: Date;
|
|
1610
|
+
}[];
|
|
1611
|
+
total: number;
|
|
1612
|
+
limit: number;
|
|
1613
|
+
offset: number;
|
|
1614
|
+
};
|
|
1615
|
+
meta: object;
|
|
1616
|
+
}>;
|
|
1617
|
+
}>>;
|
|
1504
1618
|
plugins: import("@trpc/server").TRPCBuiltRouter<{
|
|
1505
1619
|
ctx: {
|
|
1506
1620
|
headers: Headers;
|
package/dist/api/root.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"root.d.ts","sourceRoot":"","sources":["../../src/api/root.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"root.d.ts","sourceRoot":"","sources":["../../src/api/root.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAc5C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AA4FvB,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAAsB,CAAA;AAU5C,wBAAsB,YAAY;;;;;;;;;;;;;;;;;;;;;4GAEjC;AAED,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,WAAW,4LAG7D;AAGD,MAAM,MAAM,SAAS,GAAG,OAAO,SAAS,CAAA;AAGxC,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAAiC,CAAA"}
|
package/dist/api/root.js
CHANGED
|
@@ -8,6 +8,7 @@ import { simpleSectionRouter } from './routers/simpleSection.js';
|
|
|
8
8
|
import { categorySectionRouter } from './routers/categorySection.js';
|
|
9
9
|
import { accountSettings } from './routers/accountSettings.js';
|
|
10
10
|
import { galleryRouter } from './routers/gallery.js';
|
|
11
|
+
import { logsRouter } from './routers/logs.js';
|
|
11
12
|
import { getConfigImportVersion } from '../core/config/index.js';
|
|
12
13
|
import { getPluginRoutes, loadPlugins } from '../plugins/loader.js';
|
|
13
14
|
import { z } from 'zod';
|
|
@@ -47,6 +48,7 @@ const coreRouters = {
|
|
|
47
48
|
gallery: galleryRouter,
|
|
48
49
|
navigation: navRouter,
|
|
49
50
|
accountSettings: accountSettings,
|
|
51
|
+
logs: logsRouter,
|
|
50
52
|
plugins: pluginsRouter,
|
|
51
53
|
};
|
|
52
54
|
// Lazy router creation - cache the result
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accountSettings.d.ts","sourceRoot":"","sources":["../../../src/api/routers/accountSettings.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAA;
|
|
1
|
+
{"version":3,"file":"accountSettings.d.ts","sourceRoot":"","sources":["../../../src/api/routers/accountSettings.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAA;AAKxB,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAkBxB;;;OAGG;;;;;;;;;;;;;;;;;;;GAsKL,CAAA"}
|
|
@@ -5,6 +5,7 @@ import { eq } from 'drizzle-orm';
|
|
|
5
5
|
import * as z from 'zod';
|
|
6
6
|
import bcrypt from 'bcrypt';
|
|
7
7
|
import { TRPCError } from '@trpc/server';
|
|
8
|
+
import { getRequestMetadataFromHeaders, recordLog } from '../../logging/index.js';
|
|
8
9
|
export const accountSettings = router({
|
|
9
10
|
get: privateProcedure.query(async ({ ctx }) => {
|
|
10
11
|
const admin = await db
|
|
@@ -32,15 +33,61 @@ export const accountSettings = router({
|
|
|
32
33
|
phoneNumber: z.string(),
|
|
33
34
|
}))
|
|
34
35
|
.mutation(async ({ ctx, input }) => {
|
|
36
|
+
const requestMetadata = getRequestMetadataFromHeaders(ctx.headers);
|
|
37
|
+
const existing = await db
|
|
38
|
+
.select({
|
|
39
|
+
emailAddress: AdminsTable.emailAddress,
|
|
40
|
+
fullName: AdminsTable.fullName,
|
|
41
|
+
phoneNumber: AdminsTable.phoneNumber,
|
|
42
|
+
username: AdminsTable.user,
|
|
43
|
+
})
|
|
44
|
+
.from(AdminsTable)
|
|
45
|
+
.where(eq(AdminsTable.id, ctx.session.user.id))
|
|
46
|
+
.limit(1);
|
|
47
|
+
const admin = existing[0];
|
|
48
|
+
if (!admin) {
|
|
49
|
+
throw new TRPCError({
|
|
50
|
+
code: 'NOT_FOUND',
|
|
51
|
+
message: 'Admin not found',
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
const updates = {};
|
|
55
|
+
const changedFields = [];
|
|
56
|
+
if (admin.emailAddress !== input.emailAddress) {
|
|
57
|
+
updates.emailAddress = input.emailAddress;
|
|
58
|
+
changedFields.push('emailAddress');
|
|
59
|
+
}
|
|
60
|
+
if (admin.fullName !== input.fullName) {
|
|
61
|
+
updates.fullName = input.fullName;
|
|
62
|
+
changedFields.push('fullName');
|
|
63
|
+
}
|
|
64
|
+
if (admin.phoneNumber !== input.phoneNumber) {
|
|
65
|
+
updates.phoneNumber = input.phoneNumber;
|
|
66
|
+
changedFields.push('phoneNumber');
|
|
67
|
+
}
|
|
68
|
+
if (changedFields.length === 0) {
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
35
71
|
await db
|
|
36
72
|
.update(AdminsTable)
|
|
37
73
|
.set({
|
|
38
|
-
|
|
39
|
-
fullName: input.fullName,
|
|
40
|
-
phoneNumber: input.phoneNumber,
|
|
74
|
+
...updates,
|
|
41
75
|
})
|
|
42
76
|
.where(eq(AdminsTable.id, ctx.session.user.id))
|
|
43
77
|
.execute();
|
|
78
|
+
await recordLog({
|
|
79
|
+
eventType: 'admin.settings.change',
|
|
80
|
+
actorId: ctx.session.user.id,
|
|
81
|
+
actorUsername: ctx.session.user.name ?? admin.username ?? null,
|
|
82
|
+
entityType: 'admin',
|
|
83
|
+
entityId: ctx.session.user.id,
|
|
84
|
+
entityLabel: admin.username ?? null,
|
|
85
|
+
sectionName: 'settings',
|
|
86
|
+
metadata: {
|
|
87
|
+
fields: changedFields,
|
|
88
|
+
},
|
|
89
|
+
requestMetadata,
|
|
90
|
+
});
|
|
44
91
|
return true;
|
|
45
92
|
}),
|
|
46
93
|
changePassword: privateProcedure
|
|
@@ -50,12 +97,14 @@ export const accountSettings = router({
|
|
|
50
97
|
confirmPassword: z.string(),
|
|
51
98
|
}))
|
|
52
99
|
.mutation(async ({ ctx, input }) => {
|
|
100
|
+
const requestMetadata = getRequestMetadataFromHeaders(ctx.headers);
|
|
53
101
|
/**
|
|
54
102
|
* Check if old password is correct
|
|
55
103
|
*/
|
|
56
104
|
const result = await db
|
|
57
105
|
.select({
|
|
58
106
|
password: AdminsTable.pass,
|
|
107
|
+
username: AdminsTable.user,
|
|
59
108
|
})
|
|
60
109
|
.from(AdminsTable)
|
|
61
110
|
.where(eq(AdminsTable.id, ctx.session.user.id))
|
|
@@ -103,6 +152,19 @@ export const accountSettings = router({
|
|
|
103
152
|
})
|
|
104
153
|
.where(eq(AdminsTable.id, ctx.session.user.id))
|
|
105
154
|
.execute();
|
|
155
|
+
await recordLog({
|
|
156
|
+
eventType: 'admin.settings.change',
|
|
157
|
+
actorId: ctx.session.user.id,
|
|
158
|
+
actorUsername: ctx.session.user.name ?? admin.username ?? null,
|
|
159
|
+
entityType: 'admin',
|
|
160
|
+
entityId: ctx.session.user.id,
|
|
161
|
+
entityLabel: admin.username ?? null,
|
|
162
|
+
sectionName: 'settings',
|
|
163
|
+
metadata: {
|
|
164
|
+
fields: ['password'],
|
|
165
|
+
},
|
|
166
|
+
requestMetadata,
|
|
167
|
+
});
|
|
106
168
|
return true;
|
|
107
169
|
}),
|
|
108
170
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admins.d.ts","sourceRoot":"","sources":["../../../src/api/routers/admins.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAA;
|
|
1
|
+
{"version":3,"file":"admins.d.ts","sourceRoot":"","sources":["../../../src/api/routers/admins.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAA;AAcxB,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyVvB,CAAA"}
|
|
@@ -11,6 +11,7 @@ import getString from '../../translations/index.js';
|
|
|
11
11
|
import path from 'path';
|
|
12
12
|
import fs from 'fs';
|
|
13
13
|
import { getCMSConfig } from '../../core/config/index.js';
|
|
14
|
+
import { getRequestMetadataFromHeaders, recordLog } from '../../logging/index.js';
|
|
14
15
|
export const adminsRouter = router({
|
|
15
16
|
list: privateProcedure.query(async ({ ctx }) => {
|
|
16
17
|
const accessAllowed = await isAccessAllowed({
|
|
@@ -88,6 +89,7 @@ export const adminsRouter = router({
|
|
|
88
89
|
})),
|
|
89
90
|
}))
|
|
90
91
|
.mutation(async ({ ctx, input }) => {
|
|
92
|
+
const requestMetadata = getRequestMetadataFromHeaders(ctx.headers);
|
|
91
93
|
const accessAllowed = await isAccessAllowed({
|
|
92
94
|
sectionName: 'admins',
|
|
93
95
|
userId: ctx.session.user.id,
|
|
@@ -147,6 +149,23 @@ export const adminsRouter = router({
|
|
|
147
149
|
* Insert the privileges into the admin_privileges table
|
|
148
150
|
*/
|
|
149
151
|
await db.insert(AdminPrivilegesTable).values(rows);
|
|
152
|
+
await recordLog({
|
|
153
|
+
eventType: 'admin.section.create',
|
|
154
|
+
actorId: ctx.session.user.id,
|
|
155
|
+
actorUsername: ctx.session.user.name ?? null,
|
|
156
|
+
entityType: 'admin',
|
|
157
|
+
entityId: id,
|
|
158
|
+
entityLabel: input.username,
|
|
159
|
+
sectionName: 'admins',
|
|
160
|
+
metadata: {
|
|
161
|
+
privileges: rows.map((privilege) => ({
|
|
162
|
+
sectionName: privilege.sectionName,
|
|
163
|
+
operations: privilege.operations,
|
|
164
|
+
publisher: privilege.publisher,
|
|
165
|
+
})),
|
|
166
|
+
},
|
|
167
|
+
requestMetadata,
|
|
168
|
+
});
|
|
150
169
|
return {
|
|
151
170
|
status: 'success',
|
|
152
171
|
};
|
|
@@ -161,6 +180,7 @@ export const adminsRouter = router({
|
|
|
161
180
|
})),
|
|
162
181
|
}))
|
|
163
182
|
.mutation(async ({ ctx, input }) => {
|
|
183
|
+
const requestMetadata = getRequestMetadataFromHeaders(ctx.headers);
|
|
164
184
|
const accessAllowed = await isAccessAllowed({
|
|
165
185
|
sectionName: 'admins',
|
|
166
186
|
userId: ctx.session.user.id,
|
|
@@ -174,11 +194,12 @@ export const adminsRouter = router({
|
|
|
174
194
|
/**
|
|
175
195
|
* First, let's check if the admin exists
|
|
176
196
|
*/
|
|
177
|
-
const
|
|
197
|
+
const adminRows = await db.select().from(AdminsTable).where(eq(AdminsTable.id, input.id));
|
|
198
|
+
const admin = adminRows[0];
|
|
178
199
|
/**
|
|
179
200
|
* If the admin doens't exist, throw an error
|
|
180
201
|
*/
|
|
181
|
-
if (
|
|
202
|
+
if (!admin) {
|
|
182
203
|
throw new TRPCError({
|
|
183
204
|
code: 'BAD_REQUEST',
|
|
184
205
|
message: getString('adminDoesNotExist'),
|
|
@@ -211,6 +232,23 @@ export const adminsRouter = router({
|
|
|
211
232
|
*/
|
|
212
233
|
await db.delete(AdminPrivilegesTable).where(eq(AdminPrivilegesTable.adminId, input.id));
|
|
213
234
|
await db.insert(AdminPrivilegesTable).values(rows);
|
|
235
|
+
await recordLog({
|
|
236
|
+
eventType: 'admin.section.update',
|
|
237
|
+
actorId: ctx.session.user.id,
|
|
238
|
+
actorUsername: ctx.session.user.name ?? null,
|
|
239
|
+
entityType: 'admin',
|
|
240
|
+
entityId: input.id,
|
|
241
|
+
entityLabel: admin.user ?? null,
|
|
242
|
+
sectionName: 'admins',
|
|
243
|
+
metadata: {
|
|
244
|
+
privileges: rows.map((privilege) => ({
|
|
245
|
+
sectionName: privilege.sectionName,
|
|
246
|
+
operations: privilege.operations,
|
|
247
|
+
publisher: privilege.publisher,
|
|
248
|
+
})),
|
|
249
|
+
},
|
|
250
|
+
requestMetadata,
|
|
251
|
+
});
|
|
214
252
|
return {
|
|
215
253
|
status: 'success',
|
|
216
254
|
};
|
|
@@ -220,6 +258,7 @@ export const adminsRouter = router({
|
|
|
220
258
|
id: z.string(),
|
|
221
259
|
}))
|
|
222
260
|
.mutation(async ({ ctx, input }) => {
|
|
261
|
+
const requestMetadata = getRequestMetadataFromHeaders(ctx.headers);
|
|
223
262
|
const accessAllowed = await isAccessAllowed({
|
|
224
263
|
sectionName: 'admins',
|
|
225
264
|
userId: ctx.session.user.id,
|
|
@@ -265,6 +304,19 @@ export const adminsRouter = router({
|
|
|
265
304
|
if (admin.coverphoto) {
|
|
266
305
|
await fs.promises.unlink(path.join(uploadsFolder, '.thumbs', 'admins', admin.coverphoto));
|
|
267
306
|
}
|
|
307
|
+
await recordLog({
|
|
308
|
+
eventType: 'admin.section.delete',
|
|
309
|
+
actorId: ctx.session.user.id,
|
|
310
|
+
actorUsername: ctx.session.user.name ?? null,
|
|
311
|
+
entityType: 'admin',
|
|
312
|
+
entityId: input.id,
|
|
313
|
+
entityLabel: admin.user ?? null,
|
|
314
|
+
sectionName: 'admins',
|
|
315
|
+
metadata: {
|
|
316
|
+
hadAvatar: Boolean(admin.coverphoto),
|
|
317
|
+
},
|
|
318
|
+
requestMetadata,
|
|
319
|
+
});
|
|
268
320
|
return true;
|
|
269
321
|
}),
|
|
270
322
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/api/routers/auth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAA;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/api/routers/auth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAA;AAKxB,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDrB,CAAA"}
|
package/dist/api/routers/auth.js
CHANGED
|
@@ -2,6 +2,7 @@ import { privateProcedure, publicProcedure, router } from '../trpc.js';
|
|
|
2
2
|
import * as z from 'zod';
|
|
3
3
|
import { TRPCError } from '@trpc/server';
|
|
4
4
|
import { deleteSession, login } from '../../auth/lib/index.js';
|
|
5
|
+
import { getRequestMetadataFromHeaders, recordLog } from '../../logging/index.js';
|
|
5
6
|
export const authRouter = router({
|
|
6
7
|
login: publicProcedure
|
|
7
8
|
.input(z.object({
|
|
@@ -10,7 +11,19 @@ export const authRouter = router({
|
|
|
10
11
|
}))
|
|
11
12
|
.mutation(async (opts) => {
|
|
12
13
|
try {
|
|
13
|
-
|
|
14
|
+
const requestMetadata = getRequestMetadataFromHeaders(opts.ctx.headers);
|
|
15
|
+
const result = await login(opts.input);
|
|
16
|
+
await recordLog({
|
|
17
|
+
eventType: 'auth.login',
|
|
18
|
+
actorId: result.user?.id ?? null,
|
|
19
|
+
actorUsername: result.user?.username ?? null,
|
|
20
|
+
entityType: 'admin',
|
|
21
|
+
entityId: result.user?.id ?? null,
|
|
22
|
+
entityLabel: result.user?.username ?? null,
|
|
23
|
+
sectionName: 'auth',
|
|
24
|
+
requestMetadata,
|
|
25
|
+
});
|
|
26
|
+
return result;
|
|
14
27
|
}
|
|
15
28
|
catch (error) {
|
|
16
29
|
throw new TRPCError({
|
|
@@ -20,6 +33,18 @@ export const authRouter = router({
|
|
|
20
33
|
}
|
|
21
34
|
}),
|
|
22
35
|
logout: privateProcedure.mutation(async (opts) => {
|
|
23
|
-
|
|
36
|
+
const requestMetadata = getRequestMetadataFromHeaders(opts.ctx.headers);
|
|
37
|
+
const result = await deleteSession(opts.ctx.session);
|
|
38
|
+
await recordLog({
|
|
39
|
+
eventType: 'auth.logout',
|
|
40
|
+
actorId: opts.ctx.session.user.id,
|
|
41
|
+
actorUsername: opts.ctx.session.user.name ?? null,
|
|
42
|
+
entityType: 'admin',
|
|
43
|
+
entityId: opts.ctx.session.user.id,
|
|
44
|
+
entityLabel: opts.ctx.session.user.name ?? null,
|
|
45
|
+
sectionName: 'auth',
|
|
46
|
+
requestMetadata,
|
|
47
|
+
});
|
|
48
|
+
return result;
|
|
24
49
|
}),
|
|
25
50
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"categorySection.d.ts","sourceRoot":"","sources":["../../../src/api/routers/categorySection.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAA;
|
|
1
|
+
{"version":3,"file":"categorySection.d.ts","sourceRoot":"","sources":["../../../src/api/routers/categorySection.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAA;AAIxB,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDhC,CAAA"}
|