forked from Echo-Mirror-Butler/echomirror-sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprivacy.ts
More file actions
110 lines (95 loc) · 2.98 KB
/
Copy pathprivacy.ts
File metadata and controls
110 lines (95 loc) · 2.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import type { JsonValue, MoodCategory, MoodLoggedProperties } from './types.js'
const SENSITIVE_KEYS = new Set([
'address',
'content',
'displayname',
'email',
'fullname',
'message',
'name',
'note',
'notes',
'phone',
'prompt',
'reflection',
'tag',
'tags',
'walletaddress',
])
function normalizedKey(key: string): string {
return key.replace(/[^a-z0-9]/gi, '').toLowerCase()
}
function toJsonValue(
value: unknown,
seen: WeakSet<object>,
allowSensitiveProperties: boolean,
): JsonValue | undefined {
if (value === null || typeof value === 'string' || typeof value === 'boolean') {
return value
}
if (typeof value === 'number') {
return Number.isFinite(value) ? value : undefined
}
if (value instanceof Date) return value.toISOString()
if (Array.isArray(value)) {
if (seen.has(value)) return undefined
seen.add(value)
const result = value
.map((item) => toJsonValue(item, seen, allowSensitiveProperties))
.filter((item): item is JsonValue => item !== undefined)
seen.delete(value)
return result
}
if (typeof value === 'object') {
if (seen.has(value)) return undefined
seen.add(value)
const result: Record<string, JsonValue> = {}
for (const [key, child] of Object.entries(value)) {
if (!allowSensitiveProperties && SENSITIVE_KEYS.has(normalizedKey(key))) continue
const json = toJsonValue(child, seen, allowSensitiveProperties)
if (json !== undefined) result[key] = json
}
seen.delete(value)
return result
}
return undefined
}
function sanitizeObject(
properties: Record<string, unknown>,
allowSensitiveProperties: boolean,
): Record<string, JsonValue> {
const result: Record<string, JsonValue> = {}
const seen = new WeakSet<object>()
for (const [key, value] of Object.entries(properties)) {
if (!allowSensitiveProperties && SENSITIVE_KEYS.has(normalizedKey(key))) continue
const json = toJsonValue(value, seen, allowSensitiveProperties)
if (json !== undefined) result[key] = json
}
return result
}
export function moodCategory(score: number): MoodCategory {
if (score <= 2) return 'very_low'
if (score <= 4) return 'low'
if (score <= 6) return 'neutral'
if (score <= 8) return 'good'
return 'excellent'
}
export function sanitizeProperties(
eventName: string,
properties: Record<string, unknown>,
allowSensitiveProperties: boolean,
): Record<string, JsonValue> {
if (allowSensitiveProperties) return sanitizeObject(properties, true)
if (eventName === 'mood_logged') {
const mood = properties as unknown as MoodLoggedProperties
const safe = sanitizeObject(properties, false)
if (typeof mood.score === 'number' && Number.isFinite(mood.score)) {
safe.score = mood.score
safe.moodCategory = moodCategory(mood.score)
}
safe.hasNote = typeof mood.note === 'string' && mood.note.length > 0
safe.tagCount = Array.isArray(mood.tags) ? mood.tags.length : 0
return safe
}
return sanitizeObject(properties, false)
}