@character-foundry/character-foundry 0.4.3 → 0.5.0
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/app-framework.cjs +12 -3
- package/dist/app-framework.cjs.map +1 -1
- package/dist/app-framework.d.cts +9 -1
- package/dist/app-framework.d.ts +9 -1
- package/dist/app-framework.js +12 -3
- package/dist/app-framework.js.map +1 -1
- package/dist/charx.cjs +85 -52
- package/dist/charx.cjs.map +1 -1
- package/dist/charx.d.cts +22 -22
- package/dist/charx.d.ts +22 -22
- package/dist/charx.js +85 -52
- package/dist/charx.js.map +1 -1
- package/dist/exporter.cjs +104 -54
- package/dist/exporter.cjs.map +1 -1
- package/dist/exporter.d.cts +19 -19
- package/dist/exporter.d.ts +19 -19
- package/dist/exporter.js +104 -54
- package/dist/exporter.js.map +1 -1
- package/dist/federation.cjs +104 -36
- package/dist/federation.cjs.map +1 -1
- package/dist/federation.d.cts +54 -19
- package/dist/federation.d.ts +54 -19
- package/dist/federation.js +104 -36
- package/dist/federation.js.map +1 -1
- package/dist/index.cjs +104 -54
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -29
- package/dist/index.d.ts +29 -29
- package/dist/index.js +104 -54
- package/dist/index.js.map +1 -1
- package/dist/loader.cjs +171 -31
- package/dist/loader.cjs.map +1 -1
- package/dist/loader.d.cts +37 -23
- package/dist/loader.d.ts +37 -23
- package/dist/loader.js +171 -31
- package/dist/loader.js.map +1 -1
- package/dist/lorebook.d.cts +23 -23
- package/dist/lorebook.d.ts +23 -23
- package/dist/normalizer.cjs +72 -18
- package/dist/normalizer.cjs.map +1 -1
- package/dist/normalizer.d.cts +37 -37
- package/dist/normalizer.d.ts +37 -37
- package/dist/normalizer.js +72 -18
- package/dist/normalizer.js.map +1 -1
- package/dist/png.cjs +72 -18
- package/dist/png.cjs.map +1 -1
- package/dist/png.d.cts +25 -25
- package/dist/png.d.ts +25 -25
- package/dist/png.js +72 -18
- package/dist/png.js.map +1 -1
- package/dist/schemas.cjs +80 -23
- package/dist/schemas.cjs.map +1 -1
- package/dist/schemas.d.cts +85 -67
- package/dist/schemas.d.ts +85 -67
- package/dist/schemas.js +80 -23
- package/dist/schemas.js.map +1 -1
- package/dist/voxta.cjs +91 -20
- package/dist/voxta.cjs.map +1 -1
- package/dist/voxta.d.cts +23 -23
- package/dist/voxta.d.ts +23 -23
- package/dist/voxta.js +91 -20
- package/dist/voxta.js.map +1 -1
- package/package.json +24 -24
package/dist/federation.d.cts
CHANGED
|
@@ -21,8 +21,8 @@ declare const CCv3DataSchema: z.ZodObject<{
|
|
|
21
21
|
character_book: z.ZodNullable<z.ZodOptional<z.ZodObject<{
|
|
22
22
|
name: z.ZodOptional<z.ZodString>;
|
|
23
23
|
description: z.ZodOptional<z.ZodString>;
|
|
24
|
-
scan_depth: z.ZodOptional<z.ZodNumber>;
|
|
25
|
-
token_budget: z.ZodOptional<z.ZodNumber>;
|
|
24
|
+
scan_depth: z.ZodEffects<z.ZodOptional<z.ZodNumber>, number | undefined, unknown>;
|
|
25
|
+
token_budget: z.ZodEffects<z.ZodOptional<z.ZodNumber>, number | undefined, unknown>;
|
|
26
26
|
recursive_scanning: z.ZodOptional<z.ZodBoolean>;
|
|
27
27
|
extensions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
28
28
|
entries: z.ZodArray<z.ZodObject<{
|
|
@@ -258,14 +258,14 @@ declare const CCv3DataSchema: z.ZodObject<{
|
|
|
258
258
|
}, z.ZodTypeAny, "passthrough">[];
|
|
259
259
|
name?: string | undefined;
|
|
260
260
|
description?: string | undefined;
|
|
261
|
-
scan_depth?:
|
|
262
|
-
token_budget?:
|
|
261
|
+
scan_depth?: unknown;
|
|
262
|
+
token_budget?: unknown;
|
|
263
263
|
recursive_scanning?: boolean | undefined;
|
|
264
264
|
extensions?: Record<string, unknown> | undefined;
|
|
265
265
|
}>>>;
|
|
266
266
|
extensions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
267
267
|
assets: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
268
|
-
type: z.ZodEnum<[
|
|
268
|
+
type: z.ZodEffects<z.ZodEnum<[
|
|
269
269
|
"icon",
|
|
270
270
|
"background",
|
|
271
271
|
"emotion",
|
|
@@ -274,7 +274,7 @@ declare const CCv3DataSchema: z.ZodObject<{
|
|
|
274
274
|
"video",
|
|
275
275
|
"custom",
|
|
276
276
|
"x-risu-asset"
|
|
277
|
-
]>;
|
|
277
|
+
]>, "custom" | "icon" | "background" | "emotion" | "user_icon" | "sound" | "video" | "x-risu-asset", unknown>;
|
|
278
278
|
uri: z.ZodString;
|
|
279
279
|
name: z.ZodString;
|
|
280
280
|
ext: z.ZodString;
|
|
@@ -285,15 +285,15 @@ declare const CCv3DataSchema: z.ZodObject<{
|
|
|
285
285
|
ext: string;
|
|
286
286
|
}, {
|
|
287
287
|
name: string;
|
|
288
|
-
type: "custom" | "icon" | "background" | "emotion" | "user_icon" | "sound" | "video" | "x-risu-asset";
|
|
289
288
|
uri: string;
|
|
290
289
|
ext: string;
|
|
290
|
+
type?: unknown;
|
|
291
291
|
}>, "many">>;
|
|
292
292
|
nickname: z.ZodOptional<z.ZodString>;
|
|
293
293
|
creator_notes_multilingual: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
294
294
|
source: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
295
|
-
creation_date: z.ZodOptional<z.ZodNumber>;
|
|
296
|
-
modification_date: z.ZodOptional<z.ZodNumber>;
|
|
295
|
+
creation_date: z.ZodEffects<z.ZodOptional<z.ZodNumber>, number | undefined, unknown>;
|
|
296
|
+
modification_date: z.ZodEffects<z.ZodOptional<z.ZodNumber>, number | undefined, unknown>;
|
|
297
297
|
}, "strip", z.ZodTypeAny, {
|
|
298
298
|
name: string;
|
|
299
299
|
description: string;
|
|
@@ -434,8 +434,8 @@ declare const CCv3DataSchema: z.ZodObject<{
|
|
|
434
434
|
}, z.ZodTypeAny, "passthrough">[];
|
|
435
435
|
name?: string | undefined;
|
|
436
436
|
description?: string | undefined;
|
|
437
|
-
scan_depth?:
|
|
438
|
-
token_budget?:
|
|
437
|
+
scan_depth?: unknown;
|
|
438
|
+
token_budget?: unknown;
|
|
439
439
|
recursive_scanning?: boolean | undefined;
|
|
440
440
|
extensions?: Record<string, unknown> | undefined;
|
|
441
441
|
} | null | undefined;
|
|
@@ -445,15 +445,15 @@ declare const CCv3DataSchema: z.ZodObject<{
|
|
|
445
445
|
group_only_greetings?: string[] | undefined;
|
|
446
446
|
assets?: {
|
|
447
447
|
name: string;
|
|
448
|
-
type: "custom" | "icon" | "background" | "emotion" | "user_icon" | "sound" | "video" | "x-risu-asset";
|
|
449
448
|
uri: string;
|
|
450
449
|
ext: string;
|
|
450
|
+
type?: unknown;
|
|
451
451
|
}[] | undefined;
|
|
452
452
|
nickname?: string | undefined;
|
|
453
453
|
creator_notes_multilingual?: Record<string, string> | undefined;
|
|
454
454
|
source?: string[] | undefined;
|
|
455
|
-
creation_date?:
|
|
456
|
-
modification_date?:
|
|
455
|
+
creation_date?: unknown;
|
|
456
|
+
modification_date?: unknown;
|
|
457
457
|
}>;
|
|
458
458
|
}, "strip", z.ZodTypeAny, {
|
|
459
459
|
data: {
|
|
@@ -600,8 +600,8 @@ declare const CCv3DataSchema: z.ZodObject<{
|
|
|
600
600
|
}, z.ZodTypeAny, "passthrough">[];
|
|
601
601
|
name?: string | undefined;
|
|
602
602
|
description?: string | undefined;
|
|
603
|
-
scan_depth?:
|
|
604
|
-
token_budget?:
|
|
603
|
+
scan_depth?: unknown;
|
|
604
|
+
token_budget?: unknown;
|
|
605
605
|
recursive_scanning?: boolean | undefined;
|
|
606
606
|
extensions?: Record<string, unknown> | undefined;
|
|
607
607
|
} | null | undefined;
|
|
@@ -611,15 +611,15 @@ declare const CCv3DataSchema: z.ZodObject<{
|
|
|
611
611
|
group_only_greetings?: string[] | undefined;
|
|
612
612
|
assets?: {
|
|
613
613
|
name: string;
|
|
614
|
-
type: "custom" | "icon" | "background" | "emotion" | "user_icon" | "sound" | "video" | "x-risu-asset";
|
|
615
614
|
uri: string;
|
|
616
615
|
ext: string;
|
|
616
|
+
type?: unknown;
|
|
617
617
|
}[] | undefined;
|
|
618
618
|
nickname?: string | undefined;
|
|
619
619
|
creator_notes_multilingual?: Record<string, string> | undefined;
|
|
620
620
|
source?: string[] | undefined;
|
|
621
|
-
creation_date?:
|
|
622
|
-
modification_date?:
|
|
621
|
+
creation_date?: unknown;
|
|
622
|
+
modification_date?: unknown;
|
|
623
623
|
};
|
|
624
624
|
spec: "chara_card_v3";
|
|
625
625
|
spec_version: "3.0";
|
|
@@ -628,6 +628,23 @@ declare const CCv3DataSchema: z.ZodObject<{
|
|
|
628
628
|
* Character Card v3 full structure
|
|
629
629
|
*/
|
|
630
630
|
export type CCv3Data = z.infer<typeof CCv3DataSchema>;
|
|
631
|
+
/**
|
|
632
|
+
* Federation Logger
|
|
633
|
+
*
|
|
634
|
+
* Lightweight logger with configurable verbosity and a safe default (warn).
|
|
635
|
+
* No external dependencies.
|
|
636
|
+
*/
|
|
637
|
+
export type LogLevel = "silent" | "error" | "warn" | "info" | "debug";
|
|
638
|
+
export interface Logger {
|
|
639
|
+
debug: (...args: unknown[]) => void;
|
|
640
|
+
info: (...args: unknown[]) => void;
|
|
641
|
+
warn: (...args: unknown[]) => void;
|
|
642
|
+
error: (...args: unknown[]) => void;
|
|
643
|
+
}
|
|
644
|
+
export declare function createConsoleLogger(level?: LogLevel): Logger;
|
|
645
|
+
declare function getLogger(): Logger;
|
|
646
|
+
declare function setLogger(logger: Logger): void;
|
|
647
|
+
declare function setLogLevel(level: LogLevel): void;
|
|
631
648
|
/**
|
|
632
649
|
* Federation Types
|
|
633
650
|
*
|
|
@@ -987,6 +1004,17 @@ export interface InboxHandlerOptions {
|
|
|
987
1004
|
strictMode?: boolean;
|
|
988
1005
|
/** Maximum age for signatures in seconds (default 300) */
|
|
989
1006
|
maxAge?: number;
|
|
1007
|
+
/**
|
|
1008
|
+
* Optional shared network key for internal-only federation.
|
|
1009
|
+
*
|
|
1010
|
+
* When set, incoming requests must include a matching network key header.
|
|
1011
|
+
* In strictMode, the header must also be included in the signed header list.
|
|
1012
|
+
*/
|
|
1013
|
+
networkKey?: string;
|
|
1014
|
+
/**
|
|
1015
|
+
* Header name for the shared network key (default: X-Foundry-Network-Key)
|
|
1016
|
+
*/
|
|
1017
|
+
networkKeyHeader?: string;
|
|
990
1018
|
}
|
|
991
1019
|
/**
|
|
992
1020
|
* ActivityPub Utilities
|
|
@@ -3107,6 +3135,10 @@ export declare class RateLimiter {
|
|
|
3107
3135
|
*/
|
|
3108
3136
|
export declare function enableFederation(options?: {
|
|
3109
3137
|
skipEnvCheck?: boolean;
|
|
3138
|
+
/** Optional logger override */
|
|
3139
|
+
logger?: Logger;
|
|
3140
|
+
/** Optional log level (used when logger is not provided). Default: warn */
|
|
3141
|
+
logLevel?: LogLevel;
|
|
3110
3142
|
}): void;
|
|
3111
3143
|
/**
|
|
3112
3144
|
* Check if federation is enabled
|
|
@@ -3122,6 +3154,9 @@ export declare function isFederationEnabled(): boolean;
|
|
|
3122
3154
|
export declare function assertFederationEnabled(feature: string): void;
|
|
3123
3155
|
|
|
3124
3156
|
export {
|
|
3157
|
+
getLogger as getFederationLogger,
|
|
3158
|
+
setLogLevel as setFederationLogLevel,
|
|
3159
|
+
setLogger as setFederationLogger,
|
|
3125
3160
|
validateActivitySignature as validateHttpSignature,
|
|
3126
3161
|
validateBlockActivity as validateBlockActivityFields,
|
|
3127
3162
|
validateFlagActivity as validateFlagActivityFields,
|
package/dist/federation.d.ts
CHANGED
|
@@ -21,8 +21,8 @@ declare const CCv3DataSchema: z.ZodObject<{
|
|
|
21
21
|
character_book: z.ZodNullable<z.ZodOptional<z.ZodObject<{
|
|
22
22
|
name: z.ZodOptional<z.ZodString>;
|
|
23
23
|
description: z.ZodOptional<z.ZodString>;
|
|
24
|
-
scan_depth: z.ZodOptional<z.ZodNumber>;
|
|
25
|
-
token_budget: z.ZodOptional<z.ZodNumber>;
|
|
24
|
+
scan_depth: z.ZodEffects<z.ZodOptional<z.ZodNumber>, number | undefined, unknown>;
|
|
25
|
+
token_budget: z.ZodEffects<z.ZodOptional<z.ZodNumber>, number | undefined, unknown>;
|
|
26
26
|
recursive_scanning: z.ZodOptional<z.ZodBoolean>;
|
|
27
27
|
extensions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
28
28
|
entries: z.ZodArray<z.ZodObject<{
|
|
@@ -258,14 +258,14 @@ declare const CCv3DataSchema: z.ZodObject<{
|
|
|
258
258
|
}, z.ZodTypeAny, "passthrough">[];
|
|
259
259
|
name?: string | undefined;
|
|
260
260
|
description?: string | undefined;
|
|
261
|
-
scan_depth?:
|
|
262
|
-
token_budget?:
|
|
261
|
+
scan_depth?: unknown;
|
|
262
|
+
token_budget?: unknown;
|
|
263
263
|
recursive_scanning?: boolean | undefined;
|
|
264
264
|
extensions?: Record<string, unknown> | undefined;
|
|
265
265
|
}>>>;
|
|
266
266
|
extensions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
267
267
|
assets: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
268
|
-
type: z.ZodEnum<[
|
|
268
|
+
type: z.ZodEffects<z.ZodEnum<[
|
|
269
269
|
"icon",
|
|
270
270
|
"background",
|
|
271
271
|
"emotion",
|
|
@@ -274,7 +274,7 @@ declare const CCv3DataSchema: z.ZodObject<{
|
|
|
274
274
|
"video",
|
|
275
275
|
"custom",
|
|
276
276
|
"x-risu-asset"
|
|
277
|
-
]>;
|
|
277
|
+
]>, "custom" | "icon" | "background" | "emotion" | "user_icon" | "sound" | "video" | "x-risu-asset", unknown>;
|
|
278
278
|
uri: z.ZodString;
|
|
279
279
|
name: z.ZodString;
|
|
280
280
|
ext: z.ZodString;
|
|
@@ -285,15 +285,15 @@ declare const CCv3DataSchema: z.ZodObject<{
|
|
|
285
285
|
ext: string;
|
|
286
286
|
}, {
|
|
287
287
|
name: string;
|
|
288
|
-
type: "custom" | "icon" | "background" | "emotion" | "user_icon" | "sound" | "video" | "x-risu-asset";
|
|
289
288
|
uri: string;
|
|
290
289
|
ext: string;
|
|
290
|
+
type?: unknown;
|
|
291
291
|
}>, "many">>;
|
|
292
292
|
nickname: z.ZodOptional<z.ZodString>;
|
|
293
293
|
creator_notes_multilingual: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
294
294
|
source: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
295
|
-
creation_date: z.ZodOptional<z.ZodNumber>;
|
|
296
|
-
modification_date: z.ZodOptional<z.ZodNumber>;
|
|
295
|
+
creation_date: z.ZodEffects<z.ZodOptional<z.ZodNumber>, number | undefined, unknown>;
|
|
296
|
+
modification_date: z.ZodEffects<z.ZodOptional<z.ZodNumber>, number | undefined, unknown>;
|
|
297
297
|
}, "strip", z.ZodTypeAny, {
|
|
298
298
|
name: string;
|
|
299
299
|
description: string;
|
|
@@ -434,8 +434,8 @@ declare const CCv3DataSchema: z.ZodObject<{
|
|
|
434
434
|
}, z.ZodTypeAny, "passthrough">[];
|
|
435
435
|
name?: string | undefined;
|
|
436
436
|
description?: string | undefined;
|
|
437
|
-
scan_depth?:
|
|
438
|
-
token_budget?:
|
|
437
|
+
scan_depth?: unknown;
|
|
438
|
+
token_budget?: unknown;
|
|
439
439
|
recursive_scanning?: boolean | undefined;
|
|
440
440
|
extensions?: Record<string, unknown> | undefined;
|
|
441
441
|
} | null | undefined;
|
|
@@ -445,15 +445,15 @@ declare const CCv3DataSchema: z.ZodObject<{
|
|
|
445
445
|
group_only_greetings?: string[] | undefined;
|
|
446
446
|
assets?: {
|
|
447
447
|
name: string;
|
|
448
|
-
type: "custom" | "icon" | "background" | "emotion" | "user_icon" | "sound" | "video" | "x-risu-asset";
|
|
449
448
|
uri: string;
|
|
450
449
|
ext: string;
|
|
450
|
+
type?: unknown;
|
|
451
451
|
}[] | undefined;
|
|
452
452
|
nickname?: string | undefined;
|
|
453
453
|
creator_notes_multilingual?: Record<string, string> | undefined;
|
|
454
454
|
source?: string[] | undefined;
|
|
455
|
-
creation_date?:
|
|
456
|
-
modification_date?:
|
|
455
|
+
creation_date?: unknown;
|
|
456
|
+
modification_date?: unknown;
|
|
457
457
|
}>;
|
|
458
458
|
}, "strip", z.ZodTypeAny, {
|
|
459
459
|
data: {
|
|
@@ -600,8 +600,8 @@ declare const CCv3DataSchema: z.ZodObject<{
|
|
|
600
600
|
}, z.ZodTypeAny, "passthrough">[];
|
|
601
601
|
name?: string | undefined;
|
|
602
602
|
description?: string | undefined;
|
|
603
|
-
scan_depth?:
|
|
604
|
-
token_budget?:
|
|
603
|
+
scan_depth?: unknown;
|
|
604
|
+
token_budget?: unknown;
|
|
605
605
|
recursive_scanning?: boolean | undefined;
|
|
606
606
|
extensions?: Record<string, unknown> | undefined;
|
|
607
607
|
} | null | undefined;
|
|
@@ -611,15 +611,15 @@ declare const CCv3DataSchema: z.ZodObject<{
|
|
|
611
611
|
group_only_greetings?: string[] | undefined;
|
|
612
612
|
assets?: {
|
|
613
613
|
name: string;
|
|
614
|
-
type: "custom" | "icon" | "background" | "emotion" | "user_icon" | "sound" | "video" | "x-risu-asset";
|
|
615
614
|
uri: string;
|
|
616
615
|
ext: string;
|
|
616
|
+
type?: unknown;
|
|
617
617
|
}[] | undefined;
|
|
618
618
|
nickname?: string | undefined;
|
|
619
619
|
creator_notes_multilingual?: Record<string, string> | undefined;
|
|
620
620
|
source?: string[] | undefined;
|
|
621
|
-
creation_date?:
|
|
622
|
-
modification_date?:
|
|
621
|
+
creation_date?: unknown;
|
|
622
|
+
modification_date?: unknown;
|
|
623
623
|
};
|
|
624
624
|
spec: "chara_card_v3";
|
|
625
625
|
spec_version: "3.0";
|
|
@@ -628,6 +628,23 @@ declare const CCv3DataSchema: z.ZodObject<{
|
|
|
628
628
|
* Character Card v3 full structure
|
|
629
629
|
*/
|
|
630
630
|
export type CCv3Data = z.infer<typeof CCv3DataSchema>;
|
|
631
|
+
/**
|
|
632
|
+
* Federation Logger
|
|
633
|
+
*
|
|
634
|
+
* Lightweight logger with configurable verbosity and a safe default (warn).
|
|
635
|
+
* No external dependencies.
|
|
636
|
+
*/
|
|
637
|
+
export type LogLevel = "silent" | "error" | "warn" | "info" | "debug";
|
|
638
|
+
export interface Logger {
|
|
639
|
+
debug: (...args: unknown[]) => void;
|
|
640
|
+
info: (...args: unknown[]) => void;
|
|
641
|
+
warn: (...args: unknown[]) => void;
|
|
642
|
+
error: (...args: unknown[]) => void;
|
|
643
|
+
}
|
|
644
|
+
export declare function createConsoleLogger(level?: LogLevel): Logger;
|
|
645
|
+
declare function getLogger(): Logger;
|
|
646
|
+
declare function setLogger(logger: Logger): void;
|
|
647
|
+
declare function setLogLevel(level: LogLevel): void;
|
|
631
648
|
/**
|
|
632
649
|
* Federation Types
|
|
633
650
|
*
|
|
@@ -987,6 +1004,17 @@ export interface InboxHandlerOptions {
|
|
|
987
1004
|
strictMode?: boolean;
|
|
988
1005
|
/** Maximum age for signatures in seconds (default 300) */
|
|
989
1006
|
maxAge?: number;
|
|
1007
|
+
/**
|
|
1008
|
+
* Optional shared network key for internal-only federation.
|
|
1009
|
+
*
|
|
1010
|
+
* When set, incoming requests must include a matching network key header.
|
|
1011
|
+
* In strictMode, the header must also be included in the signed header list.
|
|
1012
|
+
*/
|
|
1013
|
+
networkKey?: string;
|
|
1014
|
+
/**
|
|
1015
|
+
* Header name for the shared network key (default: X-Foundry-Network-Key)
|
|
1016
|
+
*/
|
|
1017
|
+
networkKeyHeader?: string;
|
|
990
1018
|
}
|
|
991
1019
|
/**
|
|
992
1020
|
* ActivityPub Utilities
|
|
@@ -3107,6 +3135,10 @@ export declare class RateLimiter {
|
|
|
3107
3135
|
*/
|
|
3108
3136
|
export declare function enableFederation(options?: {
|
|
3109
3137
|
skipEnvCheck?: boolean;
|
|
3138
|
+
/** Optional logger override */
|
|
3139
|
+
logger?: Logger;
|
|
3140
|
+
/** Optional log level (used when logger is not provided). Default: warn */
|
|
3141
|
+
logLevel?: LogLevel;
|
|
3110
3142
|
}): void;
|
|
3111
3143
|
/**
|
|
3112
3144
|
* Check if federation is enabled
|
|
@@ -3122,6 +3154,9 @@ export declare function isFederationEnabled(): boolean;
|
|
|
3122
3154
|
export declare function assertFederationEnabled(feature: string): void;
|
|
3123
3155
|
|
|
3124
3156
|
export {
|
|
3157
|
+
getLogger as getFederationLogger,
|
|
3158
|
+
setLogLevel as setFederationLogLevel,
|
|
3159
|
+
setLogger as setFederationLogger,
|
|
3125
3160
|
validateActivitySignature as validateHttpSignature,
|
|
3126
3161
|
validateBlockActivity as validateBlockActivityFields,
|
|
3127
3162
|
validateFlagActivity as validateFlagActivityFields,
|
package/dist/federation.js
CHANGED
|
@@ -44,6 +44,50 @@ function generateUUID() {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
// ../federation/dist/index.js
|
|
47
|
+
var LEVELS = {
|
|
48
|
+
silent: 0,
|
|
49
|
+
error: 1,
|
|
50
|
+
warn: 2,
|
|
51
|
+
info: 3,
|
|
52
|
+
debug: 4
|
|
53
|
+
};
|
|
54
|
+
var noop = () => {
|
|
55
|
+
};
|
|
56
|
+
function createConsoleLogger(level = "warn") {
|
|
57
|
+
const severity = LEVELS[level] ?? LEVELS.warn;
|
|
58
|
+
const hasConsole = typeof console !== "undefined";
|
|
59
|
+
const c = hasConsole ? console : void 0;
|
|
60
|
+
const debugImpl = c?.debug ? c.debug.bind(c) : c?.log ? c.log.bind(c) : noop;
|
|
61
|
+
const infoImpl = c?.info ? c.info.bind(c) : c?.log ? c.log.bind(c) : noop;
|
|
62
|
+
const warnImpl = c?.warn ? c.warn.bind(c) : c?.log ? c.log.bind(c) : noop;
|
|
63
|
+
const errorImpl = c?.error ? c.error.bind(c) : c?.log ? c.log.bind(c) : noop;
|
|
64
|
+
return {
|
|
65
|
+
debug: severity >= LEVELS.debug ? debugImpl : noop,
|
|
66
|
+
info: severity >= LEVELS.info ? infoImpl : noop,
|
|
67
|
+
warn: severity >= LEVELS.warn ? warnImpl : noop,
|
|
68
|
+
error: severity >= LEVELS.error ? errorImpl : noop
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
var federationLogger = createConsoleLogger("warn");
|
|
72
|
+
function getLogger() {
|
|
73
|
+
return federationLogger;
|
|
74
|
+
}
|
|
75
|
+
function setLogger(logger) {
|
|
76
|
+
federationLogger = logger;
|
|
77
|
+
}
|
|
78
|
+
function setLogLevel(level) {
|
|
79
|
+
federationLogger = createConsoleLogger(level);
|
|
80
|
+
}
|
|
81
|
+
function configureLogger(options) {
|
|
82
|
+
if (!options) return;
|
|
83
|
+
if (options.logger) {
|
|
84
|
+
setLogger(options.logger);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (options.logLevel) {
|
|
88
|
+
setLogLevel(options.logLevel);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
47
91
|
var ACTIVITY_CONTEXT = [
|
|
48
92
|
"https://www.w3.org/ns/activitystreams",
|
|
49
93
|
{
|
|
@@ -402,7 +446,7 @@ var SyncEngine = class {
|
|
|
402
446
|
try {
|
|
403
447
|
listener(event);
|
|
404
448
|
} catch (err) {
|
|
405
|
-
|
|
449
|
+
getLogger().error("[federation] Event listener error:", err);
|
|
406
450
|
}
|
|
407
451
|
}
|
|
408
452
|
}
|
|
@@ -1531,7 +1575,7 @@ var HttpPlatformAdapter = class extends BasePlatformAdapter {
|
|
|
1531
1575
|
const data = await response.json();
|
|
1532
1576
|
return this.config.transformers?.get ? this.config.transformers.get(data) : data;
|
|
1533
1577
|
} catch (err) {
|
|
1534
|
-
|
|
1578
|
+
getLogger().error(`[federation] Failed to get card ${localId}:`, err);
|
|
1535
1579
|
return null;
|
|
1536
1580
|
}
|
|
1537
1581
|
}
|
|
@@ -2083,27 +2127,14 @@ function parseSignatureHeader(header) {
|
|
|
2083
2127
|
return {
|
|
2084
2128
|
keyId: params.keyId,
|
|
2085
2129
|
algorithm: params.algorithm || "rsa-sha256",
|
|
2086
|
-
headers: (params.headers || "(request-target) host date").split(
|
|
2130
|
+
headers: (params.headers || "(request-target) host date").trim().split(/\s+/).filter(Boolean).map((h) => h.toLowerCase()),
|
|
2087
2131
|
signature: params.signature
|
|
2088
2132
|
};
|
|
2089
2133
|
}
|
|
2090
2134
|
function buildSigningString(method, path, headers, headerNames) {
|
|
2091
2135
|
const result = buildSigningStringStrict(method, path, headers, headerNames);
|
|
2092
2136
|
if (!result.success) {
|
|
2093
|
-
|
|
2094
|
-
const lines = [];
|
|
2095
|
-
for (const name of headerNames) {
|
|
2096
|
-
if (name === "(request-target)") {
|
|
2097
|
-
lines.push(`(request-target): ${method.toLowerCase()} ${path}`);
|
|
2098
|
-
} else if (name === "(created)" || name === "(expires)") {
|
|
2099
|
-
} else {
|
|
2100
|
-
const value = headers.get(name);
|
|
2101
|
-
if (value !== null) {
|
|
2102
|
-
lines.push(`${name.toLowerCase()}: ${value}`);
|
|
2103
|
-
}
|
|
2104
|
-
}
|
|
2105
|
-
}
|
|
2106
|
-
return lines.join("\n");
|
|
2137
|
+
throw new Error(result.error);
|
|
2107
2138
|
}
|
|
2108
2139
|
return result.signingString;
|
|
2109
2140
|
}
|
|
@@ -2112,16 +2143,17 @@ function buildSigningStringStrict(method, path, headers, headerNames) {
|
|
|
2112
2143
|
const missingHeaders = [];
|
|
2113
2144
|
const syntheticHeaders = /* @__PURE__ */ new Set(["(request-target)", "(created)", "(expires)"]);
|
|
2114
2145
|
for (const name of headerNames) {
|
|
2115
|
-
|
|
2146
|
+
const normalizedName = name.toLowerCase();
|
|
2147
|
+
if (normalizedName === "(request-target)") {
|
|
2116
2148
|
lines.push(`(request-target): ${method.toLowerCase()} ${path}`);
|
|
2117
|
-
} else if (
|
|
2118
|
-
} else if (
|
|
2149
|
+
} else if (normalizedName === "(created)") {
|
|
2150
|
+
} else if (normalizedName === "(expires)") {
|
|
2119
2151
|
} else {
|
|
2120
|
-
const value = headers.get(
|
|
2152
|
+
const value = headers.get(normalizedName);
|
|
2121
2153
|
if (value !== null) {
|
|
2122
|
-
lines.push(`${
|
|
2123
|
-
} else if (!syntheticHeaders.has(
|
|
2124
|
-
missingHeaders.push(
|
|
2154
|
+
lines.push(`${normalizedName}: ${value}`);
|
|
2155
|
+
} else if (!syntheticHeaders.has(normalizedName)) {
|
|
2156
|
+
missingHeaders.push(normalizedName);
|
|
2125
2157
|
}
|
|
2126
2158
|
}
|
|
2127
2159
|
}
|
|
@@ -2142,7 +2174,7 @@ async function verifyHttpSignature(parsed, publicKeyPem, method, path, headers,
|
|
|
2142
2174
|
if (options.strictHeaders) {
|
|
2143
2175
|
const strictResult = buildSigningStringStrict(method, path, headers, parsed.headers);
|
|
2144
2176
|
if (!strictResult.success) {
|
|
2145
|
-
|
|
2177
|
+
getLogger().warn(`[federation] Strict header verification failed: ${strictResult.error}`);
|
|
2146
2178
|
return false;
|
|
2147
2179
|
}
|
|
2148
2180
|
}
|
|
@@ -2162,7 +2194,7 @@ async function verifyHttpSignature(parsed, publicKeyPem, method, path, headers,
|
|
|
2162
2194
|
data
|
|
2163
2195
|
);
|
|
2164
2196
|
} catch (error) {
|
|
2165
|
-
|
|
2197
|
+
getLogger().error("[federation] Signature verification failed:", error);
|
|
2166
2198
|
return false;
|
|
2167
2199
|
}
|
|
2168
2200
|
}
|
|
@@ -2300,7 +2332,7 @@ async function importPublicKey(pem) {
|
|
|
2300
2332
|
["verify"]
|
|
2301
2333
|
);
|
|
2302
2334
|
} catch (error) {
|
|
2303
|
-
|
|
2335
|
+
getLogger().error("[federation] Failed to import public key:", error);
|
|
2304
2336
|
return null;
|
|
2305
2337
|
}
|
|
2306
2338
|
}
|
|
@@ -2316,7 +2348,7 @@ async function importPrivateKey(pem) {
|
|
|
2316
2348
|
["sign"]
|
|
2317
2349
|
);
|
|
2318
2350
|
} catch (error) {
|
|
2319
|
-
|
|
2351
|
+
getLogger().error("[federation] Failed to import private key:", error);
|
|
2320
2352
|
return null;
|
|
2321
2353
|
}
|
|
2322
2354
|
}
|
|
@@ -2345,9 +2377,31 @@ function extractHostFromActorId(actorId) {
|
|
|
2345
2377
|
return null;
|
|
2346
2378
|
}
|
|
2347
2379
|
}
|
|
2380
|
+
function timingSafeEqualString(a, b) {
|
|
2381
|
+
let mismatch = a.length === b.length ? 0 : 1;
|
|
2382
|
+
const maxLen = Math.max(a.length, b.length);
|
|
2383
|
+
for (let i = 0; i < maxLen; i++) {
|
|
2384
|
+
const aCode = a.charCodeAt(i) || 0;
|
|
2385
|
+
const bCode = b.charCodeAt(i) || 0;
|
|
2386
|
+
mismatch |= aCode ^ bCode;
|
|
2387
|
+
}
|
|
2388
|
+
return mismatch === 0;
|
|
2389
|
+
}
|
|
2348
2390
|
async function handleInbox(body, headers, options) {
|
|
2349
2391
|
assertFederationEnabled("handleInbox");
|
|
2350
2392
|
try {
|
|
2393
|
+
const normalizedHeaders = headers instanceof Headers ? headers : new Headers(headers);
|
|
2394
|
+
const networkKey = typeof options.networkKey === "string" ? options.networkKey : void 0;
|
|
2395
|
+
const networkKeyHeader = options.networkKeyHeader ?? "X-Foundry-Network-Key";
|
|
2396
|
+
if (networkKey && networkKey.length > 0) {
|
|
2397
|
+
const provided = normalizedHeaders.get(networkKeyHeader);
|
|
2398
|
+
if (!provided || !timingSafeEqualString(provided, networkKey)) {
|
|
2399
|
+
return {
|
|
2400
|
+
accepted: false,
|
|
2401
|
+
error: "Unauthorized: invalid or missing network key"
|
|
2402
|
+
};
|
|
2403
|
+
}
|
|
2404
|
+
}
|
|
2351
2405
|
if (options.moderationStore) {
|
|
2352
2406
|
const actorId = typeof body === "object" && body !== null && "actor" in body ? String(body.actor) : null;
|
|
2353
2407
|
if (actorId) {
|
|
@@ -2370,7 +2424,7 @@ async function handleInbox(body, headers, options) {
|
|
|
2370
2424
|
};
|
|
2371
2425
|
}
|
|
2372
2426
|
if (options.strictMode) {
|
|
2373
|
-
const signatureHeader =
|
|
2427
|
+
const signatureHeader = normalizedHeaders.get("signature");
|
|
2374
2428
|
if (!signatureHeader) {
|
|
2375
2429
|
return {
|
|
2376
2430
|
accepted: false,
|
|
@@ -2384,6 +2438,15 @@ async function handleInbox(body, headers, options) {
|
|
|
2384
2438
|
error: "Invalid Signature header format"
|
|
2385
2439
|
};
|
|
2386
2440
|
}
|
|
2441
|
+
if (networkKey && networkKey.length > 0) {
|
|
2442
|
+
const requiredSigned = networkKeyHeader.toLowerCase();
|
|
2443
|
+
if (!parsedSig.headers.includes(requiredSigned)) {
|
|
2444
|
+
return {
|
|
2445
|
+
accepted: false,
|
|
2446
|
+
error: `Strict mode: signature missing required header: ${requiredSigned}`
|
|
2447
|
+
};
|
|
2448
|
+
}
|
|
2449
|
+
}
|
|
2387
2450
|
const missingSignedHeaders = REQUIRED_SIGNED_HEADERS.filter(
|
|
2388
2451
|
(h) => !parsedSig.headers.includes(h)
|
|
2389
2452
|
);
|
|
@@ -2393,14 +2456,14 @@ async function handleInbox(body, headers, options) {
|
|
|
2393
2456
|
error: `Strict mode: signature missing required headers: ${missingSignedHeaders.join(", ")}`
|
|
2394
2457
|
};
|
|
2395
2458
|
}
|
|
2396
|
-
const dateHeader =
|
|
2459
|
+
const dateHeader = normalizedHeaders.get("date");
|
|
2397
2460
|
if (!dateHeader) {
|
|
2398
2461
|
return {
|
|
2399
2462
|
accepted: false,
|
|
2400
2463
|
error: "Strict mode: Date header required"
|
|
2401
2464
|
};
|
|
2402
2465
|
}
|
|
2403
|
-
const hostHeader =
|
|
2466
|
+
const hostHeader = normalizedHeaders.get("host");
|
|
2404
2467
|
if (!hostHeader) {
|
|
2405
2468
|
return {
|
|
2406
2469
|
accepted: false,
|
|
@@ -2443,7 +2506,7 @@ async function handleInbox(body, headers, options) {
|
|
|
2443
2506
|
error: `Invalid key ID or actor URL`
|
|
2444
2507
|
};
|
|
2445
2508
|
}
|
|
2446
|
-
const digestHeader =
|
|
2509
|
+
const digestHeader = normalizedHeaders.get("digest");
|
|
2447
2510
|
if (digestHeader) {
|
|
2448
2511
|
if (!options.rawBody) {
|
|
2449
2512
|
return {
|
|
@@ -2474,13 +2537,13 @@ async function handleInbox(body, headers, options) {
|
|
|
2474
2537
|
}
|
|
2475
2538
|
const method = options.method || "POST";
|
|
2476
2539
|
const path = options.path || "/inbox";
|
|
2477
|
-
const normalizedHeaders = headers instanceof Headers ? headers : new Headers(headers);
|
|
2478
2540
|
const isValid = await verifyHttpSignature(
|
|
2479
2541
|
parsedSig,
|
|
2480
2542
|
actor.publicKey.publicKeyPem,
|
|
2481
2543
|
method,
|
|
2482
2544
|
path,
|
|
2483
|
-
normalizedHeaders
|
|
2545
|
+
normalizedHeaders,
|
|
2546
|
+
{ strictHeaders: true }
|
|
2484
2547
|
);
|
|
2485
2548
|
if (!isValid) {
|
|
2486
2549
|
return {
|
|
@@ -3559,7 +3622,7 @@ var PolicyEngine = class {
|
|
|
3559
3622
|
if (!regex) {
|
|
3560
3623
|
const safetyWarning = checkRegexSafety(rule.pattern);
|
|
3561
3624
|
if (safetyWarning) {
|
|
3562
|
-
|
|
3625
|
+
getLogger().warn(`[moderation] Rule "${rule.name}": ${safetyWarning}`);
|
|
3563
3626
|
}
|
|
3564
3627
|
try {
|
|
3565
3628
|
regex = new RegExp(rule.pattern, "i");
|
|
@@ -3799,11 +3862,12 @@ function getEnvVar(name) {
|
|
|
3799
3862
|
return void 0;
|
|
3800
3863
|
}
|
|
3801
3864
|
function enableFederation(options) {
|
|
3865
|
+
configureLogger(options);
|
|
3802
3866
|
explicitlyEnabled = true;
|
|
3803
3867
|
envCheckSkipped = options?.skipEnvCheck ?? false;
|
|
3804
3868
|
const nodeEnv = getEnvVar("NODE_ENV");
|
|
3805
3869
|
if (nodeEnv === "development" || nodeEnv === "test") {
|
|
3806
|
-
|
|
3870
|
+
getLogger().warn(
|
|
3807
3871
|
"[character-foundry/federation] Federation enabled. WARNING: Verify HTTP signatures in production. Do NOT use in production with untrusted inputs without signature validation."
|
|
3808
3872
|
);
|
|
3809
3873
|
}
|
|
@@ -3867,6 +3931,7 @@ export {
|
|
|
3867
3931
|
createAnnounceActivity,
|
|
3868
3932
|
createArchiveAdapter,
|
|
3869
3933
|
createBlockActivity,
|
|
3934
|
+
createConsoleLogger,
|
|
3870
3935
|
createCreateActivity,
|
|
3871
3936
|
createDeleteActivity,
|
|
3872
3937
|
createFlagActivity,
|
|
@@ -3881,6 +3946,7 @@ export {
|
|
|
3881
3946
|
enableFederation,
|
|
3882
3947
|
generateActivityId,
|
|
3883
3948
|
generateCardId,
|
|
3949
|
+
getLogger as getFederationLogger,
|
|
3884
3950
|
handleActor,
|
|
3885
3951
|
handleInbox,
|
|
3886
3952
|
handleNodeInfo,
|
|
@@ -3893,6 +3959,8 @@ export {
|
|
|
3893
3959
|
parseForkActivity,
|
|
3894
3960
|
parseInstallActivity,
|
|
3895
3961
|
parseSignatureHeader,
|
|
3962
|
+
setLogLevel as setFederationLogLevel,
|
|
3963
|
+
setLogger as setFederationLogger,
|
|
3896
3964
|
signRequest,
|
|
3897
3965
|
stCharacterToCCv3,
|
|
3898
3966
|
validateBlockActivity as validateBlockActivityFields,
|