@leemour/cli-messaging 0.86.0 → 0.88.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/README.md +1 -0
- package/dist/background/index.d.ts +5 -0
- package/dist/background/index.d.ts.map +1 -0
- package/dist/background/index.js +5 -0
- package/dist/background/index.js.map +1 -0
- package/dist/background/lock.d.ts +17 -0
- package/dist/background/lock.d.ts.map +1 -0
- package/dist/background/lock.js +34 -0
- package/dist/background/lock.js.map +1 -0
- package/dist/background/processes.d.ts.map +1 -0
- package/dist/background/processes.js.map +1 -0
- package/dist/background/system.d.ts +20 -0
- package/dist/background/system.d.ts.map +1 -0
- package/dist/background/system.js +39 -0
- package/dist/background/system.js.map +1 -0
- package/dist/background/units.d.ts +42 -0
- package/dist/background/units.d.ts.map +1 -0
- package/dist/background/units.js +178 -0
- package/dist/background/units.js.map +1 -0
- package/dist/cli/config-command.d.ts.map +1 -1
- package/dist/cli/config-command.js +17 -5
- package/dist/cli/config-command.js.map +1 -1
- package/dist/cli/context.d.ts +3 -0
- package/dist/cli/context.d.ts.map +1 -1
- package/dist/cli/context.js.map +1 -1
- package/dist/cli/index.d.ts +5 -3
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +4 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/messenger/account-command.d.ts +0 -3
- package/dist/cli/messenger/account-command.d.ts.map +1 -1
- package/dist/cli/messenger/account-command.js +20 -2
- package/dist/cli/messenger/account-command.js.map +1 -1
- package/dist/cli/messenger/account-sessions-command.d.ts.map +1 -1
- package/dist/cli/messenger/account-sessions-command.js +13 -0
- package/dist/cli/messenger/account-sessions-command.js.map +1 -1
- package/dist/cli/messenger/admin-moderation-command.d.ts +11 -0
- package/dist/cli/messenger/admin-moderation-command.d.ts.map +1 -0
- package/dist/cli/messenger/admin-moderation-command.js +83 -0
- package/dist/cli/messenger/admin-moderation-command.js.map +1 -0
- package/dist/cli/messenger/after.d.ts +2 -0
- package/dist/cli/messenger/after.d.ts.map +1 -1
- package/dist/cli/messenger/after.js +23 -2
- package/dist/cli/messenger/after.js.map +1 -1
- package/dist/cli/messenger/archive-commands.d.ts.map +1 -1
- package/dist/cli/messenger/archive-commands.js +4 -4
- package/dist/cli/messenger/archive-commands.js.map +1 -1
- package/dist/cli/messenger/ask.d.ts +2 -0
- package/dist/cli/messenger/ask.d.ts.map +1 -1
- package/dist/cli/messenger/ask.js +7 -0
- package/dist/cli/messenger/ask.js.map +1 -1
- package/dist/cli/messenger/backfill-command.d.ts +1 -1
- package/dist/cli/messenger/backfill-command.d.ts.map +1 -1
- package/dist/cli/messenger/backfill-command.js +27 -18
- package/dist/cli/messenger/backfill-command.js.map +1 -1
- package/dist/cli/messenger/backfill-jobs.d.ts +3 -2
- package/dist/cli/messenger/backfill-jobs.d.ts.map +1 -1
- package/dist/cli/messenger/backfill-jobs.js +1 -1
- package/dist/cli/messenger/backfill-jobs.js.map +1 -1
- package/dist/cli/messenger/chats-command.d.ts +0 -3
- package/dist/cli/messenger/chats-command.d.ts.map +1 -1
- package/dist/cli/messenger/chats-command.js +12 -25
- package/dist/cli/messenger/chats-command.js.map +1 -1
- package/dist/cli/messenger/context.d.ts +6 -1
- package/dist/cli/messenger/context.d.ts.map +1 -1
- package/dist/cli/messenger/context.js +3 -0
- package/dist/cli/messenger/context.js.map +1 -1
- package/dist/cli/messenger/download-command.js +6 -6
- package/dist/cli/messenger/download-command.js.map +1 -1
- package/dist/cli/messenger/hearing-command.d.ts +0 -2
- package/dist/cli/messenger/hearing-command.d.ts.map +1 -1
- package/dist/cli/messenger/hearing-command.js +4 -9
- package/dist/cli/messenger/hearing-command.js.map +1 -1
- package/dist/cli/messenger/inbox.d.ts +1 -8
- package/dist/cli/messenger/inbox.d.ts.map +1 -1
- package/dist/cli/messenger/inbox.js +8 -28
- package/dist/cli/messenger/inbox.js.map +1 -1
- package/dist/cli/messenger/messages-command.d.ts.map +1 -1
- package/dist/cli/messenger/messages-command.js +20 -13
- package/dist/cli/messenger/messages-command.js.map +1 -1
- package/dist/cli/messenger/port.d.ts +21 -2
- package/dist/cli/messenger/port.d.ts.map +1 -1
- package/dist/cli/messenger/port.js.map +1 -1
- package/dist/cli/messenger/review.d.ts +0 -4
- package/dist/cli/messenger/review.d.ts.map +1 -1
- package/dist/cli/messenger/review.js +8 -11
- package/dist/cli/messenger/review.js.map +1 -1
- package/dist/cli/messenger/serve-command.d.ts +1 -13
- package/dist/cli/messenger/serve-command.d.ts.map +1 -1
- package/dist/cli/messenger/serve-command.js +7 -32
- package/dist/cli/messenger/serve-command.js.map +1 -1
- package/dist/cli/messenger/server-command.d.ts +1 -17
- package/dist/cli/messenger/server-command.d.ts.map +1 -1
- package/dist/cli/messenger/server-command.js +6 -213
- package/dist/cli/messenger/server-command.js.map +1 -1
- package/dist/cli/messenger/store-maintenance-command.d.ts.map +1 -1
- package/dist/cli/messenger/store-maintenance-command.js +1 -1
- package/dist/cli/messenger/store-maintenance-command.js.map +1 -1
- package/dist/cli/messenger/transcribe-command.d.ts.map +1 -1
- package/dist/cli/messenger/transcribe-command.js +4 -1
- package/dist/cli/messenger/transcribe-command.js.map +1 -1
- package/dist/cli/settings.d.ts +25 -1
- package/dist/cli/settings.d.ts.map +1 -1
- package/dist/cli/settings.js +108 -34
- package/dist/cli/settings.js.map +1 -1
- package/dist/domain/models.d.ts +2 -0
- package/dist/domain/models.d.ts.map +1 -1
- package/dist/domain/send-time.d.ts +1 -1
- package/dist/domain/send-time.js +4 -4
- package/dist/domain/send-time.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.d.ts +4 -3
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools/account.d.ts.map +1 -1
- package/dist/mcp/tools/account.js +1 -1
- package/dist/mcp/tools/account.js.map +1 -1
- package/dist/mcp/tools/chats.d.ts.map +1 -1
- package/dist/mcp/tools/chats.js +2 -2
- package/dist/mcp/tools/chats.js.map +1 -1
- package/dist/mcp/tools/contacts-write.d.ts +1 -1
- package/dist/mcp/tools/contacts-write.d.ts.map +1 -1
- package/dist/mcp/tools/contacts-write.js +19 -1
- package/dist/mcp/tools/contacts-write.js.map +1 -1
- package/dist/mcp/tools/inbox.d.ts.map +1 -1
- package/dist/mcp/tools/inbox.js +2 -3
- package/dist/mcp/tools/inbox.js.map +1 -1
- package/dist/mcp/tools/messages.d.ts.map +1 -1
- package/dist/mcp/tools/messages.js +1 -2
- package/dist/mcp/tools/messages.js.map +1 -1
- package/dist/mcp/tools/moderation.d.ts +8 -0
- package/dist/mcp/tools/moderation.d.ts.map +1 -0
- package/dist/mcp/tools/moderation.js +36 -0
- package/dist/mcp/tools/moderation.js.map +1 -0
- package/dist/mcp/tools/review.d.ts.map +1 -1
- package/dist/mcp/tools/review.js +3 -4
- package/dist/mcp/tools/review.js.map +1 -1
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +2 -0
- package/dist/mcp/tools.js.map +1 -1
- package/dist/moderation/check.d.ts +83 -0
- package/dist/moderation/check.d.ts.map +1 -0
- package/dist/moderation/check.js +227 -0
- package/dist/moderation/check.js.map +1 -0
- package/dist/moderation/rules.d.ts +105 -0
- package/dist/moderation/rules.d.ts.map +1 -0
- package/dist/moderation/rules.js +158 -0
- package/dist/moderation/rules.js.map +1 -0
- package/dist/resolve.d.ts +1 -0
- package/dist/resolve.d.ts.map +1 -1
- package/dist/resolve.js +5 -5
- package/dist/resolve.js.map +1 -1
- package/dist/sends/permissions.d.ts +5 -3
- package/dist/sends/permissions.d.ts.map +1 -1
- package/dist/sends/permissions.js +29 -5
- package/dist/sends/permissions.js.map +1 -1
- package/dist/services/account.d.ts +17 -0
- package/dist/services/account.d.ts.map +1 -0
- package/dist/services/account.js +33 -0
- package/dist/services/account.js.map +1 -0
- package/dist/services/archive.d.ts +6 -3
- package/dist/services/archive.d.ts.map +1 -1
- package/dist/services/archive.js +10 -8
- package/dist/services/archive.js.map +1 -1
- package/dist/services/chats.d.ts +4 -1
- package/dist/services/chats.d.ts.map +1 -1
- package/dist/services/chats.js +15 -0
- package/dist/services/chats.js.map +1 -1
- package/dist/services/deps.d.ts +7 -1
- package/dist/services/deps.d.ts.map +1 -1
- package/dist/services/deps.js +2 -1
- package/dist/services/deps.js.map +1 -1
- package/dist/services/inbox.d.ts +4 -0
- package/dist/services/inbox.d.ts.map +1 -1
- package/dist/services/inbox.js +4 -0
- package/dist/services/inbox.js.map +1 -1
- package/dist/services/index.d.ts +8 -0
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +6 -0
- package/dist/services/index.js.map +1 -1
- package/dist/services/messages.d.ts +2 -0
- package/dist/services/messages.d.ts.map +1 -1
- package/dist/services/messages.js +11 -2
- package/dist/services/messages.js.map +1 -1
- package/dist/services/moderation.d.ts +33 -0
- package/dist/services/moderation.d.ts.map +1 -0
- package/dist/services/moderation.js +99 -0
- package/dist/services/moderation.js.map +1 -0
- package/dist/services/moment.d.ts +8 -0
- package/dist/services/moment.d.ts.map +1 -0
- package/dist/services/moment.js +24 -0
- package/dist/services/moment.js.map +1 -0
- package/dist/services/people.d.ts +3 -1
- package/dist/services/people.d.ts.map +1 -1
- package/dist/services/people.js +2 -0
- package/dist/services/people.js.map +1 -1
- package/dist/speech/hearing.d.ts +2 -0
- package/dist/speech/hearing.d.ts.map +1 -1
- package/dist/speech/hearing.js +8 -0
- package/dist/speech/hearing.js.map +1 -1
- package/dist/speech/transcribe.d.ts +5 -1
- package/dist/speech/transcribe.d.ts.map +1 -1
- package/dist/speech/transcribe.js +2 -2
- package/dist/speech/transcribe.js.map +1 -1
- package/dist/store/sqlite/drizzle/bun.js +1 -1
- package/dist/store/sqlite/drizzle/core.d.ts +1 -1
- package/dist/store/sqlite/drizzle/core.d.ts.map +1 -1
- package/dist/store/sqlite/drizzle/core.js +5 -3
- package/dist/store/sqlite/drizzle/core.js.map +1 -1
- package/dist/store/sqlite/drizzle/node.js +1 -1
- package/dist/store/sqlite/drizzle/{shared-JAIU3GYB.js → shared-VIVPOB3Q.js} +5 -1
- package/dist/store/sqlite/drizzle/{shared-JAIU3GYB.js.map → shared-VIVPOB3Q.js.map} +1 -1
- package/dist/store/sqlite/manifest.d.ts.map +1 -1
- package/dist/store/sqlite/manifest.js +1 -0
- package/dist/store/sqlite/manifest.js.map +1 -1
- package/dist/store/sqlite/migrations.generated.d.ts.map +1 -1
- package/dist/store/sqlite/migrations.generated.js +15 -0
- package/dist/store/sqlite/migrations.generated.js.map +1 -1
- package/dist/store/sqlite/schema.d.ts +494 -0
- package/dist/store/sqlite/schema.d.ts.map +1 -1
- package/dist/store/sqlite/schema.js +78 -1
- package/dist/store/sqlite/schema.js.map +1 -1
- package/package.json +5 -1
- package/parity.json +191 -65
- package/dist/cli/messenger/processes.d.ts.map +0 -1
- package/dist/cli/messenger/processes.js.map +0 -1
- /package/dist/{cli/messenger → background}/processes.d.ts +0 -0
- /package/dist/{cli/messenger → background}/processes.js +0 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import * as v from "valibot";
|
|
2
|
+
import type { AppIdentity } from "../cli/app.js";
|
|
3
|
+
import type { Id } from "../domain/models.js";
|
|
4
|
+
/** What a rule does with what it finds; nothing but `report` acts until the group's level lets it. */
|
|
5
|
+
export declare const RULE_ACTIONS: readonly ["report", "delete", "remove"];
|
|
6
|
+
/** `requests` and `consent.accept|decline` were for join requests (max-cli `FIND-249`); a file with them loads and drops them. */
|
|
7
|
+
declare const groupRules: v.SchemaWithPipe<readonly [v.StrictObjectSchema<{
|
|
8
|
+
readonly title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
9
|
+
readonly trusted: v.ArraySchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a person id is digits">]>, undefined>;
|
|
10
|
+
readonly blocked: v.ArraySchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a person id is digits">]>, undefined>;
|
|
11
|
+
readonly blockedNames: v.ArraySchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>;
|
|
12
|
+
readonly links: v.PicklistSchema<readonly ["report", "delete", "remove"], undefined>;
|
|
13
|
+
readonly invites: v.PicklistSchema<readonly ["report", "delete", "remove"], undefined>;
|
|
14
|
+
readonly forwards: v.PicklistSchema<readonly ["report", "delete", "remove"], undefined>;
|
|
15
|
+
readonly blockedPeople: v.PicklistSchema<readonly ["report", "delete", "remove"], undefined>;
|
|
16
|
+
readonly flood: v.StrictObjectSchema<{
|
|
17
|
+
readonly messages: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, number, undefined>]>;
|
|
18
|
+
readonly minutes: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, number, undefined>]>;
|
|
19
|
+
readonly action: v.PicklistSchema<readonly ["report", "delete", "remove"], undefined>;
|
|
20
|
+
}, undefined>;
|
|
21
|
+
/** 0 days turns the rule off. */
|
|
22
|
+
readonly newAccount: v.StrictObjectSchema<{
|
|
23
|
+
readonly days: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, number, undefined>]>;
|
|
24
|
+
readonly action: v.PicklistSchema<["report", "remove"], undefined>;
|
|
25
|
+
}, undefined>;
|
|
26
|
+
readonly requests: v.OptionalSchema<v.UnknownSchema, undefined>;
|
|
27
|
+
readonly consent: v.StrictObjectSchema<{
|
|
28
|
+
readonly delete: v.SchemaWithPipe<readonly [v.PicklistSchema<["deny", "readonly", "ask", "allow", ...string[]], undefined>, v.TransformAction<string, "allow" | "ask" | "deny" | "readonly">]>;
|
|
29
|
+
readonly remove: v.SchemaWithPipe<readonly [v.PicklistSchema<["deny", "readonly", "ask", "allow", ...string[]], undefined>, v.TransformAction<string, "allow" | "ask" | "deny" | "readonly">]>;
|
|
30
|
+
readonly accept: v.OptionalSchema<v.UnknownSchema, undefined>;
|
|
31
|
+
readonly decline: v.OptionalSchema<v.UnknownSchema, undefined>;
|
|
32
|
+
}, undefined>;
|
|
33
|
+
}, undefined>, v.TransformAction<{
|
|
34
|
+
title: string | null;
|
|
35
|
+
trusted: string[];
|
|
36
|
+
blocked: string[];
|
|
37
|
+
blockedNames: string[];
|
|
38
|
+
links: "delete" | "remove" | "report";
|
|
39
|
+
invites: "delete" | "remove" | "report";
|
|
40
|
+
forwards: "delete" | "remove" | "report";
|
|
41
|
+
blockedPeople: "delete" | "remove" | "report";
|
|
42
|
+
flood: {
|
|
43
|
+
messages: number;
|
|
44
|
+
minutes: number;
|
|
45
|
+
action: "delete" | "remove" | "report";
|
|
46
|
+
};
|
|
47
|
+
newAccount: {
|
|
48
|
+
days: number;
|
|
49
|
+
action: "remove" | "report";
|
|
50
|
+
};
|
|
51
|
+
requests?: unknown;
|
|
52
|
+
consent: {
|
|
53
|
+
delete: "allow" | "ask" | "deny" | "readonly";
|
|
54
|
+
remove: "allow" | "ask" | "deny" | "readonly";
|
|
55
|
+
accept?: unknown;
|
|
56
|
+
decline?: unknown;
|
|
57
|
+
};
|
|
58
|
+
}, {
|
|
59
|
+
title: string | null;
|
|
60
|
+
trusted: string[];
|
|
61
|
+
blocked: string[];
|
|
62
|
+
blockedNames: string[];
|
|
63
|
+
links: "delete" | "remove" | "report";
|
|
64
|
+
invites: "delete" | "remove" | "report";
|
|
65
|
+
forwards: "delete" | "remove" | "report";
|
|
66
|
+
blockedPeople: "delete" | "remove" | "report";
|
|
67
|
+
flood: {
|
|
68
|
+
messages: number;
|
|
69
|
+
minutes: number;
|
|
70
|
+
action: "delete" | "remove" | "report";
|
|
71
|
+
};
|
|
72
|
+
newAccount: {
|
|
73
|
+
days: number;
|
|
74
|
+
action: "remove" | "report";
|
|
75
|
+
};
|
|
76
|
+
consent: {
|
|
77
|
+
delete: "allow" | "ask" | "deny" | "readonly";
|
|
78
|
+
remove: "allow" | "ask" | "deny" | "readonly";
|
|
79
|
+
};
|
|
80
|
+
}>]>;
|
|
81
|
+
export type GroupRules = v.InferOutput<typeof groupRules>;
|
|
82
|
+
/** Every key written out, so the file shows all there is to set (max-cli `NEED-314`). Nothing here acts. */
|
|
83
|
+
export declare const defaultRules: (title: string | null) => GroupRules;
|
|
84
|
+
export declare const RULE_KEYS: string[];
|
|
85
|
+
export declare const moderationPathFor: (app: AppIdentity, profile: string, env?: NodeJS.ProcessEnv) => string;
|
|
86
|
+
/**
|
|
87
|
+
* The rules of each group this profile moderates, one file per profile beside the recipient list —
|
|
88
|
+
* the path max-cli used, so its rules carry over. May be edited by hand; a file that does not check
|
|
89
|
+
* out refuses rather than being guessed at.
|
|
90
|
+
*/
|
|
91
|
+
export declare class ModerationRules {
|
|
92
|
+
#private;
|
|
93
|
+
readonly path: string;
|
|
94
|
+
constructor(path: string);
|
|
95
|
+
/** `undefined` when this group has no section yet. */
|
|
96
|
+
read(chatId: Id): GroupRules | undefined;
|
|
97
|
+
/** Writes the group's whole section — the defaults first, if it had none — with one key changed. */
|
|
98
|
+
set(chatId: Id, title: string | null, key: string, value: string): GroupRules;
|
|
99
|
+
/** Puts one key back to its default. */
|
|
100
|
+
unset(chatId: Id, title: string | null, key: string): GroupRules;
|
|
101
|
+
checkedUntil(chatId: Id): string | undefined;
|
|
102
|
+
markChecked(chatId: Id, at: string): void;
|
|
103
|
+
}
|
|
104
|
+
export {};
|
|
105
|
+
//# sourceMappingURL=rules.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../src/moderation/rules.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAC5B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,qBAAqB,CAAA;AAG7C,sGAAsG;AACtG,eAAO,MAAM,YAAY,YAAI,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAU,CAAA;AAgBnE,kIAAkI;AAClI,QAAA,MAAM,UAAU;;;;;;;;;;;;;;IAWZ,iCAAiC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAcpC,CAAA;AAED,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,UAAU,CAAC,CAAA;AAQzD,4GAA4G;AAC5G,eAAO,MAAM,YAAY,UAAW,MAAM,GAAG,IAAI,KAAG,UAYlD,CAAA;AA4BF,eAAO,MAAM,SAAS,UAAoB,CAAA;AAE1C,eAAO,MAAM,iBAAiB,QAAS,WAAW,WAAW,MAAM,QAAO,MAAM,CAAC,UAAU,KAAiB,MAKzG,CAAA;AAEH;;;;GAIG;AACH,qBAAa,eAAe;;IACd,QAAQ,CAAC,IAAI,EAAE,MAAM;IAAjC,YAAqB,IAAI,EAAE,MAAM,EAAI;IAErC,sDAAsD;IACtD,IAAI,CAAC,MAAM,EAAE,EAAE,GAAG,UAAU,GAAG,SAAS,CAEvC;IAED,oGAAoG;IACpG,GAAG,CAAC,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,UAAU,CAS5E;IAED,wCAAwC;IACxC,KAAK,CAAC,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,UAAU,CAO/D;IAED,YAAY,CAAC,MAAM,EAAE,EAAE,GAAG,MAAM,GAAG,SAAS,CAE3C;IAED,WAAW,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAGxC;CAqBF"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { CliError, resolvePaths, writeSecurely } from "@leemour/cli-core";
|
|
4
|
+
import * as v from "valibot";
|
|
5
|
+
import { LEVELS } from "../sends/permissions.js";
|
|
6
|
+
/** What a rule does with what it finds; nothing but `report` acts until the group's level lets it. */
|
|
7
|
+
export const RULE_ACTIONS = ["report", "delete", "remove"];
|
|
8
|
+
/**
|
|
9
|
+
* max-cli's first words for a group's consent (`NEED-308`), read as the profile's levels
|
|
10
|
+
* (`NEED-462` B): `flag` and `confirm` both ask, `forbid` denies.
|
|
11
|
+
*/
|
|
12
|
+
const OLD_LEVELS = { forbid: "deny", flag: "ask", confirm: "ask", allow: "allow" };
|
|
13
|
+
const level = v.pipe(v.picklist([...LEVELS, ...Object.keys(OLD_LEVELS)]), v.transform((typed) => (OLD_LEVELS[typed] ?? typed)));
|
|
14
|
+
const action = v.picklist(RULE_ACTIONS);
|
|
15
|
+
const personIds = v.array(v.pipe(v.string(), v.regex(/^-?\d+$/, "a person id is digits")));
|
|
16
|
+
const atLeast = (min) => v.pipe(v.number(), v.integer(), v.minValue(min));
|
|
17
|
+
/** `requests` and `consent.accept|decline` were for join requests (max-cli `FIND-249`); a file with them loads and drops them. */
|
|
18
|
+
const groupRules = v.pipe(v.strictObject({
|
|
19
|
+
title: v.nullable(v.string()),
|
|
20
|
+
trusted: personIds,
|
|
21
|
+
blocked: personIds,
|
|
22
|
+
blockedNames: v.array(v.pipe(v.string(), v.minLength(1))),
|
|
23
|
+
links: action,
|
|
24
|
+
invites: action,
|
|
25
|
+
forwards: action,
|
|
26
|
+
blockedPeople: action,
|
|
27
|
+
flood: v.strictObject({ messages: atLeast(1), minutes: atLeast(1), action }),
|
|
28
|
+
/** 0 days turns the rule off. */
|
|
29
|
+
newAccount: v.strictObject({ days: atLeast(0), action: v.picklist(["report", "remove"]) }),
|
|
30
|
+
requests: v.optional(v.unknown()),
|
|
31
|
+
consent: v.strictObject({
|
|
32
|
+
delete: level,
|
|
33
|
+
remove: level,
|
|
34
|
+
accept: v.optional(v.unknown()),
|
|
35
|
+
decline: v.optional(v.unknown()),
|
|
36
|
+
}),
|
|
37
|
+
}), v.transform(({ requests: _, consent: { accept: _accept, decline: _decline, ...consent }, ...rules }) => ({
|
|
38
|
+
...rules,
|
|
39
|
+
consent,
|
|
40
|
+
})));
|
|
41
|
+
const file = v.strictObject({
|
|
42
|
+
groups: v.record(v.string(), groupRules),
|
|
43
|
+
/** Where each group's next `chats moderate` starts, ISO 8601. */
|
|
44
|
+
checkedUntil: v.optional(v.record(v.string(), v.string())),
|
|
45
|
+
});
|
|
46
|
+
/** Every key written out, so the file shows all there is to set (max-cli `NEED-314`). Nothing here acts. */
|
|
47
|
+
export const defaultRules = (title) => ({
|
|
48
|
+
title,
|
|
49
|
+
trusted: [],
|
|
50
|
+
blocked: [],
|
|
51
|
+
blockedNames: [],
|
|
52
|
+
links: "report",
|
|
53
|
+
invites: "report",
|
|
54
|
+
forwards: "report",
|
|
55
|
+
blockedPeople: "report",
|
|
56
|
+
flood: { messages: 5, minutes: 1, action: "report" },
|
|
57
|
+
newAccount: { days: 7, action: "report" },
|
|
58
|
+
consent: { delete: "ask", remove: "ask" },
|
|
59
|
+
});
|
|
60
|
+
const list = (value) => value
|
|
61
|
+
.split(",")
|
|
62
|
+
.map((item) => item.trim())
|
|
63
|
+
.filter(Boolean);
|
|
64
|
+
const whole = (value) => (/^\d+$/.test(value.trim()) ? Number(value) : Number.NaN);
|
|
65
|
+
/** What `chats rules set` accepts, and how its text becomes the stored value. */
|
|
66
|
+
const KEYS = {
|
|
67
|
+
trusted: { help: "person ids, comma-separated; never acted on", parse: list },
|
|
68
|
+
blocked: { help: "person ids, comma-separated", parse: list },
|
|
69
|
+
blockedNames: { help: "parts of a name, comma-separated, any case", parse: list },
|
|
70
|
+
links: { help: RULE_ACTIONS.join("|"), parse: String },
|
|
71
|
+
invites: { help: RULE_ACTIONS.join("|"), parse: String },
|
|
72
|
+
forwards: { help: RULE_ACTIONS.join("|"), parse: String },
|
|
73
|
+
blockedPeople: { help: RULE_ACTIONS.join("|"), parse: String },
|
|
74
|
+
"flood.messages": { help: "a whole number, 1 or more", parse: whole },
|
|
75
|
+
"flood.minutes": { help: "a whole number, 1 or more", parse: whole },
|
|
76
|
+
"flood.action": { help: RULE_ACTIONS.join("|"), parse: String },
|
|
77
|
+
"newAccount.days": { help: "a whole number; 0 turns it off", parse: whole },
|
|
78
|
+
"newAccount.action": { help: "report|remove", parse: String },
|
|
79
|
+
"consent.delete": { help: LEVELS.join("|"), parse: String },
|
|
80
|
+
"consent.remove": { help: LEVELS.join("|"), parse: String },
|
|
81
|
+
};
|
|
82
|
+
export const RULE_KEYS = Object.keys(KEYS);
|
|
83
|
+
export const moderationPathFor = (app, profile, env = process.env) => join(resolvePaths({ appName: app.appName, prefix: app.envPrefix, env }).state, "profiles", `${profile}.moderation.json`);
|
|
84
|
+
/**
|
|
85
|
+
* The rules of each group this profile moderates, one file per profile beside the recipient list —
|
|
86
|
+
* the path max-cli used, so its rules carry over. May be edited by hand; a file that does not check
|
|
87
|
+
* out refuses rather than being guessed at.
|
|
88
|
+
*/
|
|
89
|
+
export class ModerationRules {
|
|
90
|
+
path;
|
|
91
|
+
constructor(path) {
|
|
92
|
+
this.path = path;
|
|
93
|
+
}
|
|
94
|
+
/** `undefined` when this group has no section yet. */
|
|
95
|
+
read(chatId) {
|
|
96
|
+
return this.#file().groups[chatId];
|
|
97
|
+
}
|
|
98
|
+
/** Writes the group's whole section — the defaults first, if it had none — with one key changed. */
|
|
99
|
+
set(chatId, title, key, value) {
|
|
100
|
+
const known = KEYS[key];
|
|
101
|
+
if (!known)
|
|
102
|
+
throw invalid(`no rule ${key} — one of: ${RULE_KEYS.join(", ")}`);
|
|
103
|
+
const current = this.read(chatId) ?? defaultRules(title);
|
|
104
|
+
const checked = v.safeParse(groupRules, assign(current, key, known.parse(value)));
|
|
105
|
+
if (!checked.success)
|
|
106
|
+
throw invalid(`${key} ${JSON.stringify(value)} is not valid — ${known.help}`);
|
|
107
|
+
const saved = this.#file();
|
|
108
|
+
this.#write({ ...saved, groups: { ...saved.groups, [chatId]: checked.output } });
|
|
109
|
+
return checked.output;
|
|
110
|
+
}
|
|
111
|
+
/** Puts one key back to its default. */
|
|
112
|
+
unset(chatId, title, key) {
|
|
113
|
+
if (!KEYS[key])
|
|
114
|
+
throw invalid(`no rule ${key} — one of: ${RULE_KEYS.join(", ")}`);
|
|
115
|
+
const current = this.read(chatId) ?? defaultRules(title);
|
|
116
|
+
const changed = assign(current, key, lookup(defaultRules(title), key));
|
|
117
|
+
const saved = this.#file();
|
|
118
|
+
this.#write({ ...saved, groups: { ...saved.groups, [chatId]: changed } });
|
|
119
|
+
return changed;
|
|
120
|
+
}
|
|
121
|
+
checkedUntil(chatId) {
|
|
122
|
+
return this.#file().checkedUntil?.[chatId];
|
|
123
|
+
}
|
|
124
|
+
markChecked(chatId, at) {
|
|
125
|
+
const saved = this.#file();
|
|
126
|
+
this.#write({ ...saved, checkedUntil: { ...saved.checkedUntil, [chatId]: at } });
|
|
127
|
+
}
|
|
128
|
+
#file() {
|
|
129
|
+
if (!existsSync(this.path))
|
|
130
|
+
return { groups: {} };
|
|
131
|
+
let parsed;
|
|
132
|
+
try {
|
|
133
|
+
parsed = JSON.parse(readFileSync(this.path, "utf8"));
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
throw broken(this.path, error instanceof Error ? error.message : String(error));
|
|
137
|
+
}
|
|
138
|
+
const checked = v.safeParse(file, parsed);
|
|
139
|
+
if (!checked.success) {
|
|
140
|
+
const problems = checked.issues.map((issue) => `${v.getDotPath(issue) ?? "file"}: ${issue.message}`);
|
|
141
|
+
throw broken(this.path, problems.join("; "));
|
|
142
|
+
}
|
|
143
|
+
return checked.output;
|
|
144
|
+
}
|
|
145
|
+
#write(content) {
|
|
146
|
+
writeSecurely(this.path, `${JSON.stringify(content, null, 2)}\n`, 0o600);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
const invalid = (message) => new CliError("validation_error", message);
|
|
150
|
+
const broken = (path, why) => new CliError("configuration_error", `the moderation rules ${path} cannot be read (${why}) — fix the file`);
|
|
151
|
+
const lookup = (rules, key) => key.split(".").reduce((value, part) => value[part], rules);
|
|
152
|
+
const assign = (rules, key, value) => {
|
|
153
|
+
const [head, tail] = key.split(".");
|
|
154
|
+
if (tail === undefined)
|
|
155
|
+
return { ...rules, [head]: value };
|
|
156
|
+
return { ...rules, [head]: { ...rules[head], [tail]: value } };
|
|
157
|
+
};
|
|
158
|
+
//# sourceMappingURL=rules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules.js","sourceRoot":"","sources":["../../src/moderation/rules.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACzE,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAG5B,OAAO,EAAE,MAAM,EAAc,MAAM,yBAAyB,CAAA;AAE5D,sGAAsG;AACtG,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAU,CAAA;AAEnE;;;GAGG;AACH,MAAM,UAAU,GAA0B,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAA;AAEzG,MAAM,KAAK,GAAG,CAAC,CAAC,IAAI,CAClB,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EACnD,CAAC,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,KAAK,CAAU,CAAC,CAC9D,CAAA;AACD,MAAM,MAAM,GAAG,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAA;AACvC,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,SAAS,EAAE,uBAAuB,CAAC,CAAC,CAAC,CAAA;AAC1F,MAAM,OAAO,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAA;AAEjF,kIAAkI;AAClI,MAAM,UAAU,GAAG,CAAC,CAAC,IAAI,CACvB,CAAC,CAAC,YAAY,CAAC;IACb,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAC7B,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,SAAS;IAClB,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IACzD,KAAK,EAAE,MAAM;IACb,OAAO,EAAE,MAAM;IACf,QAAQ,EAAE,MAAM;IAChB,aAAa,EAAE,MAAM;IACrB,KAAK,EAAE,CAAC,CAAC,YAAY,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5E,iCAAiC;IACjC,UAAU,EAAE,CAAC,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC;IAC1F,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;IACjC,OAAO,EAAE,CAAC,CAAC,YAAY,CAAC;QACtB,MAAM,EAAE,KAAK;QACb,MAAM,EAAE,KAAK;QACb,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;QAC/B,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;KACjC,CAAC;CACH,CAAC,EACF,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,OAAO,EAAE,EAAE,GAAG,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;IACvG,GAAG,KAAK;IACR,OAAO;CACR,CAAC,CAAC,CACJ,CAAA;AAID,MAAM,IAAI,GAAG,CAAC,CAAC,YAAY,CAAC;IAC1B,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,UAAU,CAAC;IACxC,iEAAiE;IACjE,YAAY,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;CAC3D,CAAC,CAAA;AAEF,4GAA4G;AAC5G,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,KAAoB,EAAc,EAAE,CAAC,CAAC;IACjE,KAAK;IACL,OAAO,EAAE,EAAE;IACX,OAAO,EAAE,EAAE;IACX,YAAY,EAAE,EAAE;IAChB,KAAK,EAAE,QAAQ;IACf,OAAO,EAAE,QAAQ;IACjB,QAAQ,EAAE,QAAQ;IAClB,aAAa,EAAE,QAAQ;IACvB,KAAK,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE;IACpD,UAAU,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE;IACzC,OAAO,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE;CAC1C,CAAC,CAAA;AAEF,MAAM,IAAI,GAAG,CAAC,KAAa,EAAY,EAAE,CACvC,KAAK;KACF,KAAK,CAAC,GAAG,CAAC;KACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;KAC1B,MAAM,CAAC,OAAO,CAAC,CAAA;AAEpB,MAAM,KAAK,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;AAElG,iFAAiF;AACjF,MAAM,IAAI,GAAwE;IAChF,OAAO,EAAE,EAAE,IAAI,EAAE,6CAA6C,EAAE,KAAK,EAAE,IAAI,EAAE;IAC7E,OAAO,EAAE,EAAE,IAAI,EAAE,6BAA6B,EAAE,KAAK,EAAE,IAAI,EAAE;IAC7D,YAAY,EAAE,EAAE,IAAI,EAAE,4CAA4C,EAAE,KAAK,EAAE,IAAI,EAAE;IACjF,KAAK,EAAE,EAAE,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE;IACtD,OAAO,EAAE,EAAE,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE;IACxD,QAAQ,EAAE,EAAE,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE;IACzD,aAAa,EAAE,EAAE,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE;IAC9D,gBAAgB,EAAE,EAAE,IAAI,EAAE,2BAA2B,EAAE,KAAK,EAAE,KAAK,EAAE;IACrE,eAAe,EAAE,EAAE,IAAI,EAAE,2BAA2B,EAAE,KAAK,EAAE,KAAK,EAAE;IACpE,cAAc,EAAE,EAAE,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE;IAC/D,iBAAiB,EAAE,EAAE,IAAI,EAAE,gCAAgC,EAAE,KAAK,EAAE,KAAK,EAAE;IAC3E,mBAAmB,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,EAAE;IAC7D,gBAAgB,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE;IAC3D,gBAAgB,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE;CAC5D,CAAA;AAED,MAAM,CAAC,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAE1C,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,GAAgB,EAAE,OAAe,EAAE,GAAG,GAAsB,OAAO,CAAC,GAAG,EAAU,EAAE,CACnH,IAAI,CACF,YAAY,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC,KAAK,EACxE,UAAU,EACV,GAAG,OAAO,kBAAkB,CAC7B,CAAA;AAEH;;;;GAIG;AACH,MAAM,OAAO,eAAe;IACL,IAAI;IAAzB,YAAqB,IAAY;oBAAZ,IAAI;IAAW,CAAC;IAErC,sDAAsD;IACtD,IAAI,CAAC,MAAU;QACb,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IACpC,CAAC;IAED,oGAAoG;IACpG,GAAG,CAAC,MAAU,EAAE,KAAoB,EAAE,GAAW,EAAE,KAAa;QAC9D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAA;QACvB,IAAI,CAAC,KAAK;YAAE,MAAM,OAAO,CAAC,WAAW,GAAG,cAAc,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAC7E,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,YAAY,CAAC,KAAK,CAAC,CAAA;QACxD,MAAM,OAAO,GAAG,CAAC,CAAC,SAAS,CAAC,UAAU,EAAE,MAAM,CAAC,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QACjF,IAAI,CAAC,OAAO,CAAC,OAAO;YAAE,MAAM,OAAO,CAAC,GAAG,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,mBAAmB,KAAK,CAAC,IAAI,EAAE,CAAC,CAAA;QACnG,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,CAAA;QAC1B,IAAI,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;QAChF,OAAO,OAAO,CAAC,MAAM,CAAA;IACvB,CAAC;IAED,wCAAwC;IACxC,KAAK,CAAC,MAAU,EAAE,KAAoB,EAAE,GAAW;QACjD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;YAAE,MAAM,OAAO,CAAC,WAAW,GAAG,cAAc,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACjF,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,YAAY,CAAC,KAAK,CAAC,CAAA;QACxD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAA;QACtE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,CAAA;QAC1B,IAAI,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,CAAA;QACzE,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,YAAY,CAAC,MAAU;QACrB,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,YAAY,EAAE,CAAC,MAAM,CAAC,CAAA;IAC5C,CAAC;IAED,WAAW,CAAC,MAAU,EAAE,EAAU;QAChC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,CAAA;QAC1B,IAAI,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,EAAE,YAAY,EAAE,EAAE,GAAG,KAAK,CAAC,YAAY,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAA;IAClF,CAAC;IAED,KAAK;QACH,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,CAAA;QACjD,IAAI,MAAe,CAAA;QACnB,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAA;QACtD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;QACjF,CAAC;QACD,MAAM,OAAO,GAAG,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;QACzC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YACrB,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,MAAM,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;YACpG,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;QAC9C,CAAC;QACD,OAAO,OAAO,CAAC,MAAM,CAAA;IACvB,CAAC;IAED,MAAM,CAAC,OAAmC;QACxC,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;IAC1E,CAAC;CACF;AAED,MAAM,OAAO,GAAG,CAAC,OAAe,EAAE,EAAE,CAAC,IAAI,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAAC,CAAA;AAE9E,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,GAAW,EAAE,EAAE,CAC3C,IAAI,QAAQ,CAAC,qBAAqB,EAAE,wBAAwB,IAAI,oBAAoB,GAAG,kBAAkB,CAAC,CAAA;AAE5G,MAAM,MAAM,GAAG,CAAC,KAAiB,EAAE,GAAW,EAAW,EAAE,CACzD,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAU,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAE,KAAiC,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,CAAA;AAElG,MAAM,MAAM,GAAG,CAAC,KAAiB,EAAE,GAAW,EAAE,KAAc,EAAc,EAAE;IAC5E,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAA2C,CAAA;IAC7E,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,EAAE,GAAG,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAA;IAC1D,OAAO,EAAE,GAAG,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,GAAI,KAAK,CAAC,IAAI,CAAY,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,CAAA;AAC5E,CAAC,CAAA"}
|
package/dist/resolve.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export interface PeopleLookup {
|
|
|
5
5
|
/** Everyone known, in any order. */
|
|
6
6
|
all(): Contact[];
|
|
7
7
|
}
|
|
8
|
+
/** Shaped like a Telegram or MAX id. Another messenger's ids may be any string, so a miss here is not "not an id". */
|
|
8
9
|
export declare const isId: (reference: string) => boolean;
|
|
9
10
|
/**
|
|
10
11
|
* A name matched as a fragment — and **an ambiguous one is an error, not a guess**: sending to the
|
package/dist/resolve.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAA;AAE3D,mDAAmD;AACnD,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,GAAG,SAAS,CAAA;IAChC,oCAAoC;IACpC,GAAG,IAAI,OAAO,EAAE,CAAA;CACjB;AAED,eAAO,MAAM,IAAI,cAAe,MAAM,KAAG,OAA2C,CAAA;AAEpF;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,cAAe,MAAM,SAAS,IAAI,EAAE,KAAG,IAY3D,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,UAAU,cAAe,MAAM,UAAU,YAAY,KAAG,
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAA;AAE3D,mDAAmD;AACnD,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,GAAG,SAAS,CAAA;IAChC,oCAAoC;IACpC,GAAG,IAAI,OAAO,EAAE,CAAA;CACjB;AAED,sHAAsH;AACtH,eAAO,MAAM,IAAI,cAAe,MAAM,KAAG,OAA2C,CAAA;AAEpF;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,cAAe,MAAM,SAAS,IAAI,EAAE,KAAG,IAY3D,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,UAAU,cAAe,MAAM,UAAU,YAAY,KAAG,OAsBpE,CAAA"}
|
package/dist/resolve.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CliError, singleLine } from "@leemour/cli-core";
|
|
2
|
+
/** Shaped like a Telegram or MAX id. Another messenger's ids may be any string, so a miss here is not "not an id". */
|
|
2
3
|
export const isId = (reference) => /^-?\d+$/.test(reference.trim());
|
|
3
4
|
/**
|
|
4
5
|
* A name matched as a fragment — and **an ambiguous one is an error, not a guess**: sending to the
|
|
@@ -21,12 +22,11 @@ export const pickChat = (reference, chats) => {
|
|
|
21
22
|
*/
|
|
22
23
|
export const pickPerson = (reference, people) => {
|
|
23
24
|
const trimmed = reference.trim();
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if (!known)
|
|
27
|
-
throw new CliError("not_found", `no person ${trimmed} in what this account has seen`);
|
|
25
|
+
const known = people.get(trimmed);
|
|
26
|
+
if (known)
|
|
28
27
|
return known;
|
|
29
|
-
|
|
28
|
+
if (isId(trimmed))
|
|
29
|
+
throw new CliError("not_found", `no person ${trimmed} in what this account has seen`);
|
|
30
30
|
const wanted = trimmed.replace(/^@/, "").toLowerCase();
|
|
31
31
|
const everyone = people.all().toSorted((a, b) => (a.name ?? "").localeCompare(b.name ?? ""));
|
|
32
32
|
const fields = (person) => [person.name, person.username].filter(isPresent).map((one) => one.toLowerCase());
|
package/dist/resolve.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAUxD,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,SAAiB,EAAW,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAA;AAEpF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,SAAiB,EAAE,KAAa,EAAQ,EAAE;IACjE,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;IAC7C,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAA;IAElF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC;QAAE,OAAO,OAAO,CAAC,CAAC,CAAC,CAAA;IACzD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,QAAQ,CAAC,WAAW,EAAE,oBAAoB,SAAS,GAAG,CAAC,CAAA;IAC3F,MAAM,SAAS,CACb,SAAS,EACT,OAAO,EACP,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,EAC3D,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CACzC,CAAA;AACH,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,SAAiB,EAAE,MAAoB,EAAW,EAAE;IAC7E,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,EAAE,CAAA;IAChC,
|
|
1
|
+
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,11 +16,13 @@ export type PermissionKey = string;
|
|
|
16
16
|
/** Only what cannot be undone asks; the tool is meant to work without questions (owner, NEED-460). */
|
|
17
17
|
export declare const DEFAULT_PERMISSIONS: Readonly<Record<PermissionKey, Level>>;
|
|
18
18
|
/** The resources at the top of the command tree, which `readOnly` and `allow` turn read-only as a whole. */
|
|
19
|
-
export declare const RESOURCES: readonly ["messages", "reactions", "polls", "topics", "chats", "contacts", "account"];
|
|
19
|
+
export declare const RESOURCES: readonly ["messages", "reactions", "polls", "topics", "chats", "contacts", "account", "bot"];
|
|
20
20
|
/** The command path an old `allow` word stood for, as one key — what an MCP tool's `permission` is checked against. */
|
|
21
21
|
export declare const keyOfWord: (word: Permission) => PermissionKey;
|
|
22
|
-
/** `
|
|
23
|
-
export declare const fromOldSettings: (readOnly: boolean, allow: readonly Permission[] | undefined
|
|
22
|
+
/** `bot` translates a bot's `readOnly` and `allow`, which only ever covered the bot. */
|
|
23
|
+
export declare const fromOldSettings: (readOnly: boolean, allow: readonly Permission[] | undefined, { bot }?: {
|
|
24
|
+
bot?: boolean;
|
|
25
|
+
}) => Record<PermissionKey, Level>;
|
|
24
26
|
/**
|
|
25
27
|
* The most specific key the owner set wins. A built-in default (`DEFAULT_PERMISSIONS`) only ever
|
|
26
28
|
* tightens: against a broader key of the owner's, the stricter of the two holds — so
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/sends/permissions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,QAAQ,EAAE,MAAM,cAAc,CAAA;AAE3D;;;;;GAKG;AACH,eAAO,MAAM,WAAW,YACtB,MAAM,EACN,SAAS,EACT,UAAU,EACV,MAAM,EACN,KAAK,EACL,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,SAAS,EACT,SAAS,EACT,UAAU,CACF,CAAA;AAEV,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAA;AAgBrD,eAAO,MAAM,aAAa,SAAU,QAAQ,WAAW,MAAM,KAAG,UAc/D,CAAA;AAED,kFAAkF;AAClF,eAAO,MAAM,MAAM,YAAI,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,CAAU,CAAA;AAEnE,MAAM,MAAM,KAAK,GAAG,CAAC,OAAO,MAAM,CAAC,CAAC,MAAM,CAAC,CAAA;AAE3C,qFAAqF;AACrF,MAAM,MAAM,aAAa,GAAG,MAAM,CAAA;AAElC,sGAAsG;AACtG,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,MAAM,CAAC,aAAa,EAAE,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/sends/permissions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,QAAQ,EAAE,MAAM,cAAc,CAAA;AAE3D;;;;;GAKG;AACH,eAAO,MAAM,WAAW,YACtB,MAAM,EACN,SAAS,EACT,UAAU,EACV,MAAM,EACN,KAAK,EACL,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,SAAS,EACT,SAAS,EACT,UAAU,CACF,CAAA;AAEV,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAA;AAgBrD,eAAO,MAAM,aAAa,SAAU,QAAQ,WAAW,MAAM,KAAG,UAc/D,CAAA;AAED,kFAAkF;AAClF,eAAO,MAAM,MAAM,YAAI,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,CAAU,CAAA;AAEnE,MAAM,MAAM,KAAK,GAAG,CAAC,OAAO,MAAM,CAAC,CAAC,MAAM,CAAC,CAAA;AAE3C,qFAAqF;AACrF,MAAM,MAAM,aAAa,GAAG,MAAM,CAAA;AAElC,sGAAsG;AACtG,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,MAAM,CAAC,aAAa,EAAE,KAAK,CAAC,CAItE,CAAA;AAED,4GAA4G;AAC5G,eAAO,MAAM,SAAS,YAAI,UAAU,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,CAAU,CAAA;AA2BrH,uHAAuH;AACvH,eAAO,MAAM,SAAS,SAAU,UAAU,KAAG,aAAoD,CAAA;AAajG,wFAAwF;AACxF,eAAO,MAAM,eAAe,aAChB,OAAO,SACV,SAAS,UAAU,EAAE,GAAG,SAAS,YACvB;IAAE,GAAG,CAAC,EAAE,OAAO,CAAA;CAAE,KACjC,MAAM,CAAC,aAAa,EAAE,KAAK,CAW7B,CAAA;AAeD;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,gBACN,QAAQ,CAAC,MAAM,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC,OAC9C,aAAa,aACR,QAAQ,CAAC,MAAM,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC,KAC/C;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAAA;CAM3C,CAAA;AA4BD,oFAAoF;AACpF,eAAO,MAAM,WAAW,SAAU,QAAQ,WAAW,MAAM,KAAG,aAQ7D,CAAA;AA2BD;;;GAGG;AACH,eAAO,MAAM,aAAa,SAAU,SAAS,MAAM,EAAE,KAAG,aAAa,GAAG,IAAI,GAAG,SAY9E,CAAA"}
|
|
@@ -53,9 +53,10 @@ export const LEVELS = ["deny", "readonly", "ask", "allow"];
|
|
|
53
53
|
export const DEFAULT_PERMISSIONS = {
|
|
54
54
|
"messages.delete": "ask",
|
|
55
55
|
"account.sessions.end": "ask",
|
|
56
|
+
"bot.messages.delete": "ask",
|
|
56
57
|
};
|
|
57
58
|
/** The resources at the top of the command tree, which `readOnly` and `allow` turn read-only as a whole. */
|
|
58
|
-
export const RESOURCES = ["messages", "reactions", "polls", "topics", "chats", "contacts", "account"];
|
|
59
|
+
export const RESOURCES = ["messages", "reactions", "polls", "topics", "chats", "contacts", "account", "bot"];
|
|
59
60
|
const OLD_WORDS = {
|
|
60
61
|
send: ["messages.send", "polls.create"],
|
|
61
62
|
forward: ["messages.forward"],
|
|
@@ -83,16 +84,31 @@ const OLD_WORDS = {
|
|
|
83
84
|
/** The command path an old `allow` word stood for, as one key — what an MCP tool's `permission` is checked against. */
|
|
84
85
|
export const keyOfWord = (word) => OLD_WORDS[word][0];
|
|
85
86
|
/** `readOnly` and `allow` as levels, so a file written before `permissions` keeps meaning what it meant. */
|
|
86
|
-
|
|
87
|
+
/**
|
|
88
|
+
* A bot's old words meant its own writes: `profile` was its command menu, and `read` was taking
|
|
89
|
+
* updates, which every level but `deny` allows now.
|
|
90
|
+
*/
|
|
91
|
+
const botKeysOf = (word) => {
|
|
92
|
+
if (word === "profile")
|
|
93
|
+
return ["bot.commands"];
|
|
94
|
+
if (word === "read")
|
|
95
|
+
return [];
|
|
96
|
+
return OLD_WORDS[word].map((key) => `bot.${key}`);
|
|
97
|
+
};
|
|
98
|
+
/** `bot` translates a bot's `readOnly` and `allow`, which only ever covered the bot. */
|
|
99
|
+
export const fromOldSettings = (readOnly, allow, { bot = false } = {}) => {
|
|
87
100
|
if (!readOnly && allow === undefined)
|
|
88
101
|
return {};
|
|
89
|
-
const levels =
|
|
102
|
+
const levels = bot
|
|
103
|
+
? { bot: "readonly" }
|
|
104
|
+
: Object.fromEntries(RESOURCES.filter((resource) => resource !== "bot").map((resource) => [resource, "readonly"]));
|
|
90
105
|
if (readOnly)
|
|
91
106
|
return levels;
|
|
92
107
|
// A deletion needed its flag whatever `allow` said, so it keeps asking.
|
|
93
|
-
for (const word of allow ?? [])
|
|
94
|
-
for (const key of OLD_WORDS[word])
|
|
108
|
+
for (const word of allow ?? []) {
|
|
109
|
+
for (const key of bot ? botKeysOf(word) : OLD_WORDS[word])
|
|
95
110
|
levels[key] = DEFAULT_PERMISSIONS[key] ?? "allow";
|
|
111
|
+
}
|
|
96
112
|
return levels;
|
|
97
113
|
};
|
|
98
114
|
const ALLOWED = { level: "allow", key: null };
|
|
@@ -172,6 +188,8 @@ const HOUSEKEEPING = new Set([
|
|
|
172
188
|
"recipients",
|
|
173
189
|
"mcp",
|
|
174
190
|
]);
|
|
191
|
+
/** Under `bot`: its token, its names, its lists and its MCP server. */
|
|
192
|
+
const BOT_HOUSEKEEPING = new Set(["auth", "list", "sends", "recipients", "mcp"]);
|
|
175
193
|
const STORE_MAINTENANCE = new Set(["info", "check", "migrate", "backup", "restore"]);
|
|
176
194
|
/** Commands outside `messages` that print what people wrote, so `deny messages` reaches them too. */
|
|
177
195
|
const SHOW_MESSAGES = new Set(["inbox", "review", "watch", "serve", "store"]);
|
|
@@ -181,6 +199,12 @@ const SHOW_MESSAGES = new Set(["inbox", "review", "watch", "serve", "store"]);
|
|
|
181
199
|
*/
|
|
182
200
|
export const keyForCommand = (path) => {
|
|
183
201
|
const [top, next] = path;
|
|
202
|
+
if (top === "bot") {
|
|
203
|
+
if (next === undefined || BOT_HOUSEKEEPING.has(next))
|
|
204
|
+
return null;
|
|
205
|
+
const inner = keyForCommand(path.slice(1));
|
|
206
|
+
return `bot.${inner ?? path.slice(1).join(".")}`;
|
|
207
|
+
}
|
|
184
208
|
if (top === undefined || HOUSEKEEPING.has(top))
|
|
185
209
|
return null;
|
|
186
210
|
if (top === "store" && next !== undefined && STORE_MAINTENANCE.has(next))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../src/sends/permissions.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,MAAM;IACN,SAAS;IACT,UAAU;IACV,MAAM;IACN,KAAK;IACL,MAAM;IACN,QAAQ;IACR,QAAQ;IACR,UAAU;IACV,SAAS;IACT,SAAS;IACT,UAAU;CACF,CAAA;AAIV,MAAM,OAAO,GAAsC;IACjD,aAAa,EAAE,UAAU;IACzB,gBAAgB,EAAE,UAAU;IAC5B,gBAAgB,EAAE,UAAU;IAC5B,gBAAgB,EAAE,UAAU;IAC5B,eAAe,EAAE,UAAU;IAC3B,iBAAiB,EAAE,UAAU;IAC7B,OAAO,EAAE,SAAS;IAClB,eAAe,EAAE,SAAS;IAC1B,eAAe,EAAE,SAAS;IAC1B,eAAe,EAAE,SAAS;IAC1B,cAAc,EAAE,UAAU;CAC3B,CAAA;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,IAAc,EAAE,MAAe,EAAc,EAAE;IAC3E,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,SAAS;YACZ,OAAO,MAAM,CAAA;QACf,KAAK,MAAM;YACT,OAAO,QAAQ,CAAA;QACjB,KAAK,SAAS,EAAE,CAAC;YACf,MAAM,UAAU,GAAG,OAAO,CAAC,MAAuB,CAAC,CAAA;YACnD,IAAI,CAAC,UAAU;gBAAE,MAAM,IAAI,KAAK,CAAC,6CAA6C,MAAM,EAAE,CAAC,CAAA;YACvF,OAAO,UAAU,CAAA;QACnB,CAAC;QACD;YACE,OAAO,IAAI,CAAA;IACf,CAAC;AACH,CAAC,CAAA;AAED,kFAAkF;AAClF,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,CAAU,CAAA;AAOnE,sGAAsG;AACtG,MAAM,CAAC,MAAM,mBAAmB,GAA2C;IACzE,iBAAiB,EAAE,KAAK;IACxB,sBAAsB,EAAE,KAAK;
|
|
1
|
+
{"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../src/sends/permissions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type ProfileChange } from "../cli/messenger/port.js";
|
|
2
|
+
import type { Account, AccountSession } from "../domain/models.js";
|
|
3
|
+
import { type Operated } from "../sends/guarded.js";
|
|
4
|
+
import type { ServiceDeps } from "./deps.js";
|
|
5
|
+
/** The owner's own profile and logins. */
|
|
6
|
+
export interface AccountService {
|
|
7
|
+
/** The account as it now stands, its phone masked as `account show` masks it. */
|
|
8
|
+
update(change: ProfileChange): Promise<Operated<{
|
|
9
|
+
account: Account;
|
|
10
|
+
}>>;
|
|
11
|
+
/** Logs the owner out of every other device, the phone included. */
|
|
12
|
+
endOtherSessions(): Promise<Operated<{
|
|
13
|
+
sessions: AccountSession[];
|
|
14
|
+
}>>;
|
|
15
|
+
}
|
|
16
|
+
export declare const accountService: (deps: ServiceDeps) => AccountService;
|
|
17
|
+
//# sourceMappingURL=account.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account.d.ts","sourceRoot":"","sources":["../../src/services/account.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAA;AACzE,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAClE,OAAO,EAAgB,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAEjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAG5C,0CAA0C;AAC1C,MAAM,WAAW,cAAc;IAC7B,iFAAiF;IACjF,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,QAAQ,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC,CAAA;IACtE,oEAAoE;IACpE,gBAAgB,IAAI,OAAO,CAAC,QAAQ,CAAC;QAAE,QAAQ,EAAE,cAAc,EAAE,CAAA;KAAE,CAAC,CAAC,CAAA;CACtE;AAED,eAAO,MAAM,cAAc,SAAU,WAAW,KAAG,cAkClD,CAAA"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { CliError } from "@leemour/cli-core";
|
|
2
|
+
import { capability } from "../cli/messenger/port.js";
|
|
3
|
+
import { guardedWrite } from "../sends/guarded.js";
|
|
4
|
+
import { newOperationId } from "../sends/send-id.js";
|
|
5
|
+
import { maskedAccount } from "./people.js";
|
|
6
|
+
export const accountService = (deps) => {
|
|
7
|
+
const online = async (command) => {
|
|
8
|
+
if (deps.offline)
|
|
9
|
+
throw new CliError("validation_error", `\`${command}\` changes the account; not with --offline`);
|
|
10
|
+
return deps.connection();
|
|
11
|
+
};
|
|
12
|
+
return {
|
|
13
|
+
update: async (change) => {
|
|
14
|
+
if (Object.values(change).every((value) => value === undefined)) {
|
|
15
|
+
throw new CliError("validation_error", "nothing to change — give a name, a description or a photo");
|
|
16
|
+
}
|
|
17
|
+
if (change.firstName !== undefined && change.firstName.trim() === "") {
|
|
18
|
+
throw new CliError("validation_error", "a first name cannot be empty");
|
|
19
|
+
}
|
|
20
|
+
const update = capability(await online("account update"), "updateProfile", "change the profile");
|
|
21
|
+
const operationId = newOperationId();
|
|
22
|
+
const account = await guardedWrite(deps.guard, { operationId, chatId: null, kind: "account", action: "profile" }, () => update(change));
|
|
23
|
+
return { operationId, account: maskedAccount(account) };
|
|
24
|
+
},
|
|
25
|
+
endOtherSessions: async () => {
|
|
26
|
+
const end = capability(await online("account sessions end"), "endOtherSessions", "end other sessions");
|
|
27
|
+
const operationId = newOperationId();
|
|
28
|
+
const sessions = await guardedWrite(deps.guard, { operationId, chatId: null, kind: "account", action: "sessions-end" }, () => end());
|
|
29
|
+
return { operationId, sessions };
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=account.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account.js","sourceRoot":"","sources":["../../src/services/account.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC5C,OAAO,EAAE,UAAU,EAAsB,MAAM,0BAA0B,CAAA;AAEzE,OAAO,EAAE,YAAY,EAAiB,MAAM,qBAAqB,CAAA;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEpD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAU3C,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,IAAiB,EAAkB,EAAE;IAClE,MAAM,MAAM,GAAG,KAAK,EAAE,OAAe,EAAE,EAAE;QACvC,IAAI,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,QAAQ,CAAC,kBAAkB,EAAE,KAAK,OAAO,4CAA4C,CAAC,CAAA;QAClH,OAAO,IAAI,CAAC,UAAU,EAAE,CAAA;IAC1B,CAAC,CAAA;IACD,OAAO;QACL,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YACvB,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,EAAE,CAAC;gBAChE,MAAM,IAAI,QAAQ,CAAC,kBAAkB,EAAE,2DAA2D,CAAC,CAAA;YACrG,CAAC;YACD,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS,IAAI,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;gBACrE,MAAM,IAAI,QAAQ,CAAC,kBAAkB,EAAE,8BAA8B,CAAC,CAAA;YACxE,CAAC;YACD,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,MAAM,CAAC,gBAAgB,CAAC,EAAE,eAAe,EAAE,oBAAoB,CAAC,CAAA;YAChG,MAAM,WAAW,GAAG,cAAc,EAAE,CAAA;YACpC,MAAM,OAAO,GAAG,MAAM,YAAY,CAChC,IAAI,CAAC,KAAK,EACV,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,EACjE,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CACrB,CAAA;YACD,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,EAAE,CAAA;QACzD,CAAC;QAED,gBAAgB,EAAE,KAAK,IAAI,EAAE;YAC3B,MAAM,GAAG,GAAG,UAAU,CAAC,MAAM,MAAM,CAAC,sBAAsB,CAAC,EAAE,kBAAkB,EAAE,oBAAoB,CAAC,CAAA;YACtG,MAAM,WAAW,GAAG,cAAc,EAAE,CAAA;YACpC,MAAM,QAAQ,GAAG,MAAM,YAAY,CACjC,IAAI,CAAC,KAAK,EACV,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,EACtE,GAAG,EAAE,CAAC,GAAG,EAAE,CACZ,CAAA;YACD,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAA;QAClC,CAAC;KACF,CAAA;AACH,CAAC,CAAA"}
|
|
@@ -8,8 +8,10 @@ export declare const PAGE = 100;
|
|
|
8
8
|
/** How `store fetch` reads a messenger's history, where it says nothing of its own. */
|
|
9
9
|
export declare const FETCHING: Fetching;
|
|
10
10
|
export interface FetchOptions {
|
|
11
|
-
/**
|
|
12
|
-
|
|
11
|
+
/** Messages in this run. */
|
|
12
|
+
limit: number;
|
|
13
|
+
/** Messages per request. */
|
|
14
|
+
pageSize: number;
|
|
13
15
|
pauseMs: number;
|
|
14
16
|
/** Stop after the page that reaches a message older than this, epoch milliseconds. */
|
|
15
17
|
sinceMs?: number;
|
|
@@ -51,7 +53,8 @@ export interface ArchiveService {
|
|
|
51
53
|
}>;
|
|
52
54
|
/** What a full fetch would still cost, from the store alone. */
|
|
53
55
|
estimate(chat: string, options: {
|
|
54
|
-
|
|
56
|
+
limit: number;
|
|
57
|
+
pageSize: number;
|
|
55
58
|
pauseMs: number;
|
|
56
59
|
}): Promise<Estimate & {
|
|
57
60
|
chat: Id;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../../src/services/archive.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAA;AAC3D,OAAO,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,KAAK,EAAc,SAAS,EAAgB,KAAK,EAAE,MAAM,mBAAmB,CAAA;AACnF,OAAO,EAAE,KAAK,QAAQ,EAAoB,MAAM,wBAAwB,CAAA;AACxE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAI5C,mFAAmF;AACnF,eAAO,MAAM,IAAI,MAAM,CAAA;AAEvB,uFAAuF;AACvF,eAAO,MAAM,QAAQ,EAAE,QAAmE,CAAA;AAE1F,MAAM,WAAW,YAAY;IAC3B,
|
|
1
|
+
{"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../../src/services/archive.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAA;AAC3D,OAAO,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,KAAK,EAAc,SAAS,EAAgB,KAAK,EAAE,MAAM,mBAAmB,CAAA;AACnF,OAAO,EAAE,KAAK,QAAQ,EAAoB,MAAM,wBAAwB,CAAA;AACxE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAI5C,mFAAmF;AACnF,eAAO,MAAM,IAAI,MAAM,CAAA;AAEvB,uFAAuF;AACvF,eAAO,MAAM,QAAQ,EAAE,QAAmE,CAAA;AAE1F,MAAM,WAAW,YAAY;IAC3B,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,sFAAsF;IACtF,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,yEAAyE;IACzE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IAC/B,IAAI,EAAE,WAAW,CAAA;IACjB,MAAM,EAAE,CAAC,QAAQ,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;CAChF;AAED,kEAAkE;AAClE,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,EAAE,EAAE,GAAG,IAAI,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,KAAK,EAAE,CAAA;IACf,YAAY,CAAC,EAAE,IAAI,CAAA;IACnB,WAAW,CAAC,EAAE,IAAI,CAAA;IAClB,OAAO,CAAC,EAAE,IAAI,CAAA;CACf,CAAA;AAED,qGAAqG;AACrG,MAAM,WAAW,cAAc;IAC7B,qGAAqG;IACrG,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,SAAS,GAAG;QAAE,IAAI,EAAE,KAAK,EAAE,CAAA;KAAE,CAAC,EAAE,CAAC,CAAA;IACjE,wDAAwD;IACxD,IAAI,CAAC,MAAM,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,CAAA;IAClC,+DAA+D;IAC/D,gEAAgE;IAChE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,EAAE,CAAA;KAAE,CAAC,CAAA;IACnG,gEAAgE;IAChE,QAAQ,CACN,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAC5D,OAAO,CAAC,QAAQ,GAAG;QAAE,IAAI,EAAE,EAAE,CAAA;KAAE,CAAC,CAAA;IACnC;;;;OAIG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CAC7D;AAED,eAAO,MAAM,cAAc,SAAU,WAAW,KAAG,cAqIlD,CAAA"}
|
package/dist/services/archive.js
CHANGED
|
@@ -30,7 +30,7 @@ export const archiveService = (deps) => {
|
|
|
30
30
|
messages: (await store.messages(account, chatId, window)).items,
|
|
31
31
|
};
|
|
32
32
|
},
|
|
33
|
-
estimate: async (chat, {
|
|
33
|
+
estimate: async (chat, { limit, pageSize, pauseMs }) => {
|
|
34
34
|
const fetching = deps.messenger.fetching ?? FETCHING;
|
|
35
35
|
if (fetching.orderBy === "time") {
|
|
36
36
|
throw new CliError("validation_error", "--estimate counts the message ids missing between what is held; this messenger's ids do not count messages");
|
|
@@ -43,13 +43,13 @@ export const archiveService = (deps) => {
|
|
|
43
43
|
ranges: await store.ranges(account, chatId),
|
|
44
44
|
held: (await store.chatStats(account, chatId))[0]?.messages ?? 0,
|
|
45
45
|
newest: Number.isSafeInteger(newest) ? newest : undefined,
|
|
46
|
-
page:
|
|
47
|
-
maxPages,
|
|
46
|
+
page: pageSize,
|
|
47
|
+
maxPages: Math.ceil(limit / pageSize),
|
|
48
48
|
pauseMs,
|
|
49
49
|
}),
|
|
50
50
|
};
|
|
51
51
|
},
|
|
52
|
-
fetch: async (chat, {
|
|
52
|
+
fetch: async (chat, { limit, pageSize, pauseMs, sinceMs, last, note, stop, onPage }) => {
|
|
53
53
|
const fetching = deps.messenger.fetching ?? FETCHING;
|
|
54
54
|
const byTime = fetching.orderBy === "time";
|
|
55
55
|
const keyOf = (message) => (byTime ? Date.parse(message.timestamp) : Number(message.id));
|
|
@@ -63,12 +63,15 @@ export const archiveService = (deps) => {
|
|
|
63
63
|
let chatId;
|
|
64
64
|
let top;
|
|
65
65
|
let fetched = 0;
|
|
66
|
-
let pages = 0;
|
|
67
66
|
let reachedStart = false;
|
|
68
67
|
let reachedSince = false;
|
|
69
68
|
let reachedLast = false;
|
|
70
|
-
while (
|
|
71
|
-
const page = await patiently(() => connection.history(chat, {
|
|
69
|
+
while (fetched < limit && !stop.aborted) {
|
|
70
|
+
const page = await patiently(() => connection.history(chat, {
|
|
71
|
+
limit: Math.min(pageSize, limit - fetched),
|
|
72
|
+
reactions: false,
|
|
73
|
+
...(before ? { before } : {}),
|
|
74
|
+
}), note, stop);
|
|
72
75
|
const first = page.items[0];
|
|
73
76
|
if (!first) {
|
|
74
77
|
reachedStart = true;
|
|
@@ -81,7 +84,6 @@ export const archiveService = (deps) => {
|
|
|
81
84
|
}
|
|
82
85
|
const low = Math.min(...keys);
|
|
83
86
|
top ??= Math.max(...keys);
|
|
84
|
-
pages += 1;
|
|
85
87
|
fetched += page.items.length;
|
|
86
88
|
// This run's pages are contiguous, so everything from `low` to its first message is held.
|
|
87
89
|
const held = await store.markRange(account, chatId, low, top);
|