@helyx/bot 1.6.0 → 1.7.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/CHANGELOG.md +6 -0
- package/command-root-catalogue.json +13 -5
- package/dist/cloud-connector.js +2 -0
- package/dist/cloud-control-dispatcher.js +20 -0
- package/dist/command-registration-policy.js +1 -0
- package/dist/control-directory-contracts.d.ts +50 -0
- package/dist/control-directory-contracts.js +2 -0
- package/dist/control-server-schemas.d.ts +3 -3
- package/dist/control-server.d.ts +10 -46
- package/dist/control-server.js +50 -3
- package/dist/creator-invite-service.d.ts +7 -0
- package/dist/creator-invite-service.js +17 -0
- package/dist/discord-guild-health.d.ts +2 -2
- package/dist/events.d.ts +1 -0
- package/dist/events.js +2 -0
- package/dist/help-credentials.d.ts +25 -0
- package/dist/help-credentials.js +149 -0
- package/dist/help-module.d.ts +27 -0
- package/dist/help-module.js +288 -0
- package/dist/help-runtime.d.ts +3 -0
- package/dist/help-runtime.js +42 -0
- package/dist/help-transport.d.ts +53 -0
- package/dist/help-transport.js +267 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +6 -0
- package/dist/interactions.js +10 -6
- package/dist/server-overview-control.d.ts +35 -0
- package/dist/server-overview-control.js +362 -0
- package/dist/server-overview-discord.d.ts +33 -0
- package/dist/server-overview-discord.js +212 -0
- package/dist/server-overview-profile.d.ts +8 -0
- package/dist/server-overview-profile.js +62 -0
- package/dist/server-overview-routes.d.ts +4 -0
- package/dist/server-overview-routes.js +41 -0
- package/dist/shard-contracts.d.ts +66 -0
- package/dist/shard-contracts.js +23 -0
- package/dist/shard-coordinator.d.ts +1 -1
- package/dist/shard-router.d.ts +9 -0
- package/dist/shard-router.js +6 -0
- package/dist/shard-supervisor.d.ts +1 -1
- package/dist/shard-supervisor.js +4 -0
- package/dist/shard-worker.d.ts +1 -1
- package/dist/shard-worker.js +4 -0
- package/dist/verification-service.d.ts +4 -0
- package/dist/verification-service.js +10 -0
- package/documentation/README.md +1 -0
- package/documentation/guides/help-command.md +62 -0
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.7.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Add the built-in private /help command with module selection, reviewed answer choices and local self-host fallback. Keep question selection and its answer in the same private message, show the original question above choices, and use a compact FAQ ID footer. Add opt-in encrypted online Help enrolment and fail closed for unavailable hosted publication state. Integrate authenticated Server Overview reads, bounded Discord profiles and protected invite provenance across direct, Cloud Connect and sharded runtimes.
|
|
8
|
+
|
|
3
9
|
## 1.6.0
|
|
4
10
|
|
|
5
11
|
### Minor Changes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"revision":
|
|
3
|
+
"revision": 6,
|
|
4
4
|
"roots": [
|
|
5
5
|
{ "name": "access", "type": 1, "ownerModuleId": "helyx.account-gate" },
|
|
6
6
|
{ "name": "access", "type": 1, "ownerModuleId": "helyx.verification" },
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
{ "name": "games", "type": 1, "ownerModuleId": "helyx.counting" },
|
|
18
18
|
{ "name": "games", "type": 1, "ownerModuleId": "helyx.trivia" },
|
|
19
19
|
{ "name": "giveaway", "type": 1, "ownerModuleId": "helyx.giveaways" },
|
|
20
|
+
{ "name": "help", "type": 1, "ownerModuleId": "helyx.help" },
|
|
20
21
|
{ "name": "helyx", "type": 1, "ownerModuleId": "helyx.cloud-connect" },
|
|
21
22
|
{ "name": "helyx", "type": 1, "ownerModuleId": "helyx.management" },
|
|
22
23
|
{ "name": "helyx", "type": 1, "ownerModuleId": "helyx.oauth" },
|
|
@@ -62,6 +63,13 @@
|
|
|
62
63
|
"sourcePath": "apps/bot/src/diagnostic-command.ts",
|
|
63
64
|
"version": "0.1.0"
|
|
64
65
|
},
|
|
66
|
+
{
|
|
67
|
+
"commands": ["help"],
|
|
68
|
+
"moduleId": "helyx.help",
|
|
69
|
+
"releaseStatus": "live",
|
|
70
|
+
"sourcePath": "apps/bot/src/help-module.ts",
|
|
71
|
+
"version": "0.1.0"
|
|
72
|
+
},
|
|
65
73
|
{
|
|
66
74
|
"commands": ["helyx.modules"],
|
|
67
75
|
"moduleId": "helyx.management",
|
|
@@ -124,7 +132,7 @@
|
|
|
124
132
|
"moduleId": "helyx.account-gate",
|
|
125
133
|
"packageName": "@helyx/module-account-gate",
|
|
126
134
|
"releaseStatus": "live",
|
|
127
|
-
"version": "2.1.
|
|
135
|
+
"version": "2.1.3"
|
|
128
136
|
},
|
|
129
137
|
{
|
|
130
138
|
"commands": [
|
|
@@ -135,7 +143,7 @@
|
|
|
135
143
|
"moduleId": "helyx.achievements",
|
|
136
144
|
"packageName": "@helyx/module-achievements",
|
|
137
145
|
"releaseStatus": "live",
|
|
138
|
-
"version": "2.1.
|
|
146
|
+
"version": "2.1.4"
|
|
139
147
|
},
|
|
140
148
|
{
|
|
141
149
|
"commands": ["afk"],
|
|
@@ -284,7 +292,7 @@
|
|
|
284
292
|
"moduleId": "helyx.reactionroles",
|
|
285
293
|
"packageName": "@helyx/module-reactionroles",
|
|
286
294
|
"releaseStatus": "live",
|
|
287
|
-
"version": "1.1.
|
|
295
|
+
"version": "1.1.3"
|
|
288
296
|
},
|
|
289
297
|
{
|
|
290
298
|
"commands": [],
|
|
@@ -456,5 +464,5 @@
|
|
|
456
464
|
}
|
|
457
465
|
]
|
|
458
466
|
},
|
|
459
|
-
"fingerprint": "
|
|
467
|
+
"fingerprint": "9bd09abbfbaaac0ddb932b6e25911b9a2eb8a3dd5febe92f5862ef903534b2e5"
|
|
460
468
|
}
|
package/dist/cloud-connector.js
CHANGED
|
@@ -904,6 +904,8 @@ function connectorCapabilities() {
|
|
|
904
904
|
"installation.health.read.v1",
|
|
905
905
|
"guild.state.read.v1",
|
|
906
906
|
"guild.user-identities.read.v1",
|
|
907
|
+
"guild.overview.read.v1",
|
|
908
|
+
"guild.overview.invite.revoke.v1",
|
|
907
909
|
"guild.dashboard.access.read.v1",
|
|
908
910
|
"guild.access-policy.read.v1",
|
|
909
911
|
"guild.access-policy.write.v1",
|
|
@@ -18,6 +18,26 @@ export class CloudControlDispatcher {
|
|
|
18
18
|
: undefined;
|
|
19
19
|
let result;
|
|
20
20
|
switch (request.operation) {
|
|
21
|
+
case "guild.overview.read.v1": {
|
|
22
|
+
const input = parseOperationInput(request.operation, request.input);
|
|
23
|
+
if (!this.control.readServerOverview)
|
|
24
|
+
throw new Error("Overview is unavailable");
|
|
25
|
+
result = await this.control.readServerOverview({
|
|
26
|
+
...input,
|
|
27
|
+
actorUserId: requiredActor(actorUserId),
|
|
28
|
+
});
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
31
|
+
case "guild.overview.invite.revoke.v1": {
|
|
32
|
+
const input = parseOperationInput(request.operation, request.input);
|
|
33
|
+
if (!this.control.revokeServerOverviewInvite)
|
|
34
|
+
throw new Error("Invite management is unavailable");
|
|
35
|
+
result = await this.control.revokeServerOverviewInvite({
|
|
36
|
+
...input,
|
|
37
|
+
actorUserId: requiredActor(actorUserId),
|
|
38
|
+
});
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
21
41
|
case "installation.health.read.v1":
|
|
22
42
|
parseOperationInput(request.operation, request.input);
|
|
23
43
|
result = {
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { DiscordUserIdentityControl } from "@helyx/control-protocol/discord-user-identities";
|
|
2
|
+
import type { MessageResponse, PermissionActor, PublicAchievementProjectionPage } from "@helyx/sdk";
|
|
3
|
+
import type { OverviewDiscordDirectory } from "./server-overview-discord.js";
|
|
4
|
+
export interface BotControlGuildResources {
|
|
5
|
+
botGuildPermissions?: string[];
|
|
6
|
+
channels: Array<{
|
|
7
|
+
id: string;
|
|
8
|
+
name: string;
|
|
9
|
+
type: "guild_text" | "guild_announcement" | "guild_category" | "guild_forum" | "guild_media";
|
|
10
|
+
}>;
|
|
11
|
+
roles: Array<{
|
|
12
|
+
id: string;
|
|
13
|
+
name: string;
|
|
14
|
+
colour: string;
|
|
15
|
+
position: number;
|
|
16
|
+
}>;
|
|
17
|
+
}
|
|
18
|
+
export interface BotPublicModuleProjection {
|
|
19
|
+
server: {
|
|
20
|
+
id: string;
|
|
21
|
+
name: string;
|
|
22
|
+
memberCount: number;
|
|
23
|
+
};
|
|
24
|
+
projection: PublicAchievementProjectionPage;
|
|
25
|
+
}
|
|
26
|
+
export type BotGuildPresenceState = "installed" | "not_installed" | "unknown" | "unavailable";
|
|
27
|
+
export interface BotGuildPresenceObservation {
|
|
28
|
+
guildId: string;
|
|
29
|
+
state: BotGuildPresenceState;
|
|
30
|
+
observedAt: string;
|
|
31
|
+
}
|
|
32
|
+
export interface BotControlGuildResourceDirectory extends DiscordUserIdentityControl {
|
|
33
|
+
overview?: OverviewDiscordDirectory;
|
|
34
|
+
listGuildPresence(guildIds: readonly string[]): Promise<BotGuildPresenceObservation[]>;
|
|
35
|
+
getGuildResources(guildId: string): Promise<BotControlGuildResources>;
|
|
36
|
+
getGuildPublicSummary(guildId: string): Promise<{
|
|
37
|
+
id: string;
|
|
38
|
+
name: string;
|
|
39
|
+
memberCount: number;
|
|
40
|
+
}>;
|
|
41
|
+
sendToChannel(channelId: string, response: MessageResponse): Promise<{
|
|
42
|
+
messageId: string;
|
|
43
|
+
}>;
|
|
44
|
+
deleteChannelMessage(channelId: string, messageId: string): Promise<void>;
|
|
45
|
+
editChannelMessage(channelId: string, messageId: string, response: MessageResponse): Promise<void>;
|
|
46
|
+
addChannelMessageReaction(channelId: string, messageId: string, emojiIdentifier: string): Promise<void>;
|
|
47
|
+
resolveActor(guildId: string, actorUserId: string): Promise<PermissionActor>;
|
|
48
|
+
sendPrivateSupportNotification?(guildId: string, channelId: string, response: MessageResponse, notificationId: string): Promise<void>;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=control-directory-contracts.d.ts.map
|
|
@@ -8,9 +8,9 @@ export declare const permissionState: z.ZodObject<{
|
|
|
8
8
|
module: z.ZodObject<{
|
|
9
9
|
preset: z.ZodEnum<{
|
|
10
10
|
everyone: "everyone";
|
|
11
|
+
custom: "custom";
|
|
11
12
|
moderators: "moderators";
|
|
12
13
|
administrators: "administrators";
|
|
13
|
-
custom: "custom";
|
|
14
14
|
}>;
|
|
15
15
|
allowedRoleIds: z.ZodArray<z.ZodString>;
|
|
16
16
|
deniedRoleIds: z.ZodArray<z.ZodString>;
|
|
@@ -22,9 +22,9 @@ export declare const permissionState: z.ZodObject<{
|
|
|
22
22
|
policy: z.ZodObject<{
|
|
23
23
|
preset: z.ZodEnum<{
|
|
24
24
|
everyone: "everyone";
|
|
25
|
+
custom: "custom";
|
|
25
26
|
moderators: "moderators";
|
|
26
27
|
administrators: "administrators";
|
|
27
|
-
custom: "custom";
|
|
28
28
|
}>;
|
|
29
29
|
allowedRoleIds: z.ZodArray<z.ZodString>;
|
|
30
30
|
deniedRoleIds: z.ZodArray<z.ZodString>;
|
|
@@ -59,8 +59,8 @@ export declare const managedResourceDetailSchema: z.ZodObject<{
|
|
|
59
59
|
availableActionIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
60
60
|
notices: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
61
61
|
kind: z.ZodEnum<{
|
|
62
|
-
info: "info";
|
|
63
62
|
warning: "warning";
|
|
63
|
+
info: "info";
|
|
64
64
|
}>;
|
|
65
65
|
message: z.ZodString;
|
|
66
66
|
}, z.core.$strict>>>;
|
package/dist/control-server.d.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
+
import type { BotControlGuildResources, BotPublicModuleProjection, BotGuildPresenceObservation, BotControlGuildResourceDirectory } from "./control-directory-contracts.js";
|
|
2
|
+
export type { BotControlGuildResources, BotPublicModuleProjection, BotGuildPresenceState, BotGuildPresenceObservation, BotControlGuildResourceDirectory, } from "./control-directory-contracts.js";
|
|
1
3
|
import { type DiscordUserIdentityControl, type DiscordUserIdentityRequest } from "@helyx/control-protocol/discord-user-identities";
|
|
4
|
+
import type { ServerOverviewControl } from "@helyx/control-protocol";
|
|
5
|
+
import { type OverviewDiscordDirectory } from "./server-overview-discord.js";
|
|
2
6
|
import { AuditRepository, GuildAccessPolicyRepository, InstallationRepository, ModuleLoggingPolicyRepository, PermissionPolicyRepository, type DatabasePool, type GuildShardOwnership } from "@helyx/database";
|
|
3
7
|
import type { MysqlPool } from "@helyx/database-mysql";
|
|
4
8
|
import type { CreatorOnboardingRequest, CreatorOnboardingResponse } from "@helyx/sdk";
|
|
5
9
|
export { mapBotControlError, safeBotControlFieldError, } from "./control-error-mapping.js";
|
|
6
|
-
import { type DashboardActionInspection, type DashboardActionResult, type FeatureAccessDecision, type GuildAccessPolicy, type ManagedResourceCreationIntent, type ManagedResourceDetail, type ManagedResourcePage, type ManagedResourceRelationPage, type ManagedResourceValue, type MessageResponse, type ModuleDefinition, type OAuthConsumerCleanupResult, type PermissionActor, type PrivacyCapturePage, type PrivacyErasePage, type PrivacyProviderExecutor, type
|
|
10
|
+
import { type DashboardActionInspection, type DashboardActionResult, type FeatureAccessDecision, type GuildAccessPolicy, type ManagedResourceCreationIntent, type ManagedResourceDetail, type ManagedResourcePage, type ManagedResourceRelationPage, type ManagedResourceValue, type MessageResponse, type ModuleDefinition, type OAuthConsumerCleanupResult, type PermissionActor, type PrivacyCapturePage, type PrivacyErasePage, type PrivacyProviderExecutor, type ServiceAccess } from "@helyx/sdk";
|
|
7
11
|
import { type ActionReceipt, type SignedAssessmentEnvelope } from "@helyx/verification-contracts";
|
|
8
12
|
import { type Client } from "discord.js";
|
|
9
13
|
import { type FastifyInstance } from "fastify";
|
|
@@ -29,53 +33,10 @@ interface DashboardLoggingPolicy {
|
|
|
29
33
|
enabled: boolean;
|
|
30
34
|
version: number;
|
|
31
35
|
}
|
|
32
|
-
export interface BotControlGuildResources {
|
|
33
|
-
channels: Array<{
|
|
34
|
-
id: string;
|
|
35
|
-
name: string;
|
|
36
|
-
type: "guild_text" | "guild_announcement" | "guild_category" | "guild_forum" | "guild_media";
|
|
37
|
-
}>;
|
|
38
|
-
roles: Array<{
|
|
39
|
-
id: string;
|
|
40
|
-
name: string;
|
|
41
|
-
colour: string;
|
|
42
|
-
position: number;
|
|
43
|
-
}>;
|
|
44
|
-
}
|
|
45
|
-
export interface BotPublicModuleProjection {
|
|
46
|
-
server: {
|
|
47
|
-
id: string;
|
|
48
|
-
name: string;
|
|
49
|
-
memberCount: number;
|
|
50
|
-
};
|
|
51
|
-
projection: PublicAchievementProjectionPage;
|
|
52
|
-
}
|
|
53
|
-
export type BotGuildPresenceState = "installed" | "not_installed" | "unknown" | "unavailable";
|
|
54
|
-
export interface BotGuildPresenceObservation {
|
|
55
|
-
guildId: string;
|
|
56
|
-
state: BotGuildPresenceState;
|
|
57
|
-
observedAt: string;
|
|
58
|
-
}
|
|
59
|
-
export interface BotControlGuildResourceDirectory extends DiscordUserIdentityControl {
|
|
60
|
-
listGuildPresence(guildIds: readonly string[]): Promise<BotGuildPresenceObservation[]>;
|
|
61
|
-
getGuildResources(guildId: string): Promise<BotControlGuildResources>;
|
|
62
|
-
getGuildPublicSummary(guildId: string): Promise<{
|
|
63
|
-
id: string;
|
|
64
|
-
name: string;
|
|
65
|
-
memberCount: number;
|
|
66
|
-
}>;
|
|
67
|
-
sendToChannel(channelId: string, response: MessageResponse): Promise<{
|
|
68
|
-
messageId: string;
|
|
69
|
-
}>;
|
|
70
|
-
deleteChannelMessage(channelId: string, messageId: string): Promise<void>;
|
|
71
|
-
editChannelMessage(channelId: string, messageId: string, response: MessageResponse): Promise<void>;
|
|
72
|
-
addChannelMessageReaction(channelId: string, messageId: string, emojiIdentifier: string): Promise<void>;
|
|
73
|
-
resolveActor(guildId: string, actorUserId: string): Promise<PermissionActor>;
|
|
74
|
-
sendPrivateSupportNotification?(guildId: string, channelId: string, response: MessageResponse, notificationId: string): Promise<void>;
|
|
75
|
-
}
|
|
76
36
|
export declare class DiscordGuildResourceDirectory implements BotControlGuildResourceDirectory {
|
|
77
37
|
#private;
|
|
78
38
|
private readonly client;
|
|
39
|
+
readonly overview: OverviewDiscordDirectory;
|
|
79
40
|
constructor(client: Client);
|
|
80
41
|
resolveDiscordUserIdentities(input: DiscordUserIdentityRequest): Promise<{
|
|
81
42
|
guildId: string;
|
|
@@ -110,6 +71,7 @@ export interface SupportNotificationInput {
|
|
|
110
71
|
source: "dashboard_bug" | "dashboard_support" | "dashboard_security" | "discord_command";
|
|
111
72
|
}
|
|
112
73
|
export interface BotControlState {
|
|
74
|
+
botGuildPermissions?: string[];
|
|
113
75
|
discordCapabilities?: {
|
|
114
76
|
messageContent: boolean;
|
|
115
77
|
};
|
|
@@ -134,7 +96,7 @@ export interface DashboardGuildAccessState extends GuildAccessPolicy {
|
|
|
134
96
|
actorHighestRolePosition: number | null;
|
|
135
97
|
updatedAt: string | null;
|
|
136
98
|
}
|
|
137
|
-
export interface BotControlHandler extends FirstTimeCommandSetupHandler, DashboardActionHandler, ManagedResourceCreateDefaultsControl, ChannelAuditControl, DiscordUserIdentityControl {
|
|
99
|
+
export interface BotControlHandler extends ServerOverviewControl, FirstTimeCommandSetupHandler, DashboardActionHandler, ManagedResourceCreateDefaultsControl, ChannelAuditControl, DiscordUserIdentityControl {
|
|
138
100
|
creatorOnboarding?(input: CreatorOnboardingRequest): Promise<CreatorOnboardingResponse>;
|
|
139
101
|
cleanupOAuthConsumer(input: {
|
|
140
102
|
consumerBindingId: string;
|
|
@@ -363,6 +325,8 @@ export declare class BotControlService implements BotControlHandler {
|
|
|
363
325
|
private readonly supportNotifications?;
|
|
364
326
|
private readonly presenceOwnership?;
|
|
365
327
|
private readonly presenceShardCount?;
|
|
328
|
+
readonly readServerOverview: NonNullable<ServerOverviewControl["readServerOverview"]>;
|
|
329
|
+
readonly revokeServerOverviewInvite: NonNullable<ServerOverviewControl["revokeServerOverviewInvite"]>;
|
|
366
330
|
readonly readChannelAuditConfiguration: Required<ChannelAuditControl>["readChannelAuditConfiguration"];
|
|
367
331
|
readonly checkChannelAudit: Required<ChannelAuditControl>["checkChannelAudit"];
|
|
368
332
|
constructor(databaseOrPersistence: DatabasePool | BotControlPersistence, modules: readonly ModuleDefinition[], resources: BotControlGuildResourceDirectory, services: ServiceAccess, privacyExecutor?: PrivacyProviderExecutor, supportNotifications?: {
|
package/dist/control-server.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
import { overviewReadContext } from "./server-overview-profile.js";
|
|
1
2
|
import { discordUserIdentityRequestSchema, } from "@helyx/control-protocol/discord-user-identities";
|
|
3
|
+
import { createServerOverviewControl } from "./server-overview-control.js";
|
|
4
|
+
import { createOverviewDiscordDirectory, } from "./server-overview-discord.js";
|
|
5
|
+
import { registerServerOverviewControlRoutes } from "./server-overview-routes.js";
|
|
2
6
|
import { createDiscordUserIdentityLookup, } from "./discord-user-identities.js";
|
|
3
7
|
import { AuditRepository, GuildAccessPolicyRepository, InstallationRepository, ModuleLoggingPolicyRepository, OptimisticConcurrencyError, PermissionPolicyRepository, withTransaction, } from "@helyx/database";
|
|
4
8
|
import { safeError } from "@helyx/core";
|
|
@@ -44,9 +48,11 @@ import { validateDiscordUserSettingSelections, validateDiscordSettingSelections,
|
|
|
44
48
|
import { configurationValue, guildAccessPolicy, managedResourceDeleteResultSchema, managedResourceDetailSchema, managedResourceFilters, managedResourceObject, managedResourcePageSchema, managedResourceRelationPageSchema, moduleId, mutationContext, permissionState, resourceActionId, resourceCursor, resourceId, snowflake, } from "./control-server-schemas.js";
|
|
45
49
|
export class DiscordGuildResourceDirectory {
|
|
46
50
|
client;
|
|
51
|
+
overview;
|
|
47
52
|
#identities;
|
|
48
53
|
constructor(client) {
|
|
49
54
|
this.client = client;
|
|
55
|
+
this.overview = createOverviewDiscordDirectory(client);
|
|
50
56
|
this.#identities = createDiscordUserIdentityLookup(client);
|
|
51
57
|
}
|
|
52
58
|
resolveDiscordUserIdentities(input) {
|
|
@@ -107,6 +113,9 @@ export class DiscordGuildResourceDirectory {
|
|
|
107
113
|
colour: role.hexColor,
|
|
108
114
|
position: role.position,
|
|
109
115
|
})),
|
|
116
|
+
...(guild.members?.me
|
|
117
|
+
? { botGuildPermissions: guild.members.me.permissions.toArray() }
|
|
118
|
+
: {}),
|
|
110
119
|
};
|
|
111
120
|
}
|
|
112
121
|
catch (error) {
|
|
@@ -242,6 +251,9 @@ export class BotControlService {
|
|
|
242
251
|
#services;
|
|
243
252
|
#privacyProviders;
|
|
244
253
|
#persistence;
|
|
254
|
+
#overview;
|
|
255
|
+
readServerOverview;
|
|
256
|
+
revokeServerOverviewInvite;
|
|
245
257
|
readChannelAuditConfiguration;
|
|
246
258
|
checkChannelAudit;
|
|
247
259
|
constructor(databaseOrPersistence, modules, resources, services, privacyExecutor, supportNotifications, presenceOwnership, presenceShardCount, statusModules) {
|
|
@@ -276,6 +288,33 @@ export class BotControlService {
|
|
|
276
288
|
});
|
|
277
289
|
this.readChannelAuditConfiguration = audit.readChannelAuditConfiguration;
|
|
278
290
|
this.checkChannelAudit = audit.checkChannelAudit;
|
|
291
|
+
this.#overview = createServerOverviewControl({
|
|
292
|
+
modules: this.#modules,
|
|
293
|
+
services: this.#services,
|
|
294
|
+
permissions: this.#permissions,
|
|
295
|
+
directory: resources.overview,
|
|
296
|
+
auditInviteRevoke: async (input) => {
|
|
297
|
+
await this.#persistence.repositories.audit.append({
|
|
298
|
+
guildId: input.guildId,
|
|
299
|
+
actorUserId: input.actorUserId,
|
|
300
|
+
action: `server.invite.${input.outcome}`,
|
|
301
|
+
source: "dashboard",
|
|
302
|
+
correlationId: input.correlationId,
|
|
303
|
+
targetType: "discord-invite",
|
|
304
|
+
targetId: createHash("sha256")
|
|
305
|
+
.update(`${input.guildId}:${input.code}`)
|
|
306
|
+
.digest("hex"),
|
|
307
|
+
});
|
|
308
|
+
},
|
|
309
|
+
resolveActor: (guildId, actorUserId) => resources.resolveActor(guildId, actorUserId),
|
|
310
|
+
readGuildPolicy: (guildId) => this.#readGuildAccessPolicy(guildId),
|
|
311
|
+
listModules: (guildId) => this.#persistence.repositories.installations.listModules(guildId),
|
|
312
|
+
requireAccessible: (guildId, moduleId) => this.#requireModuleAccessible(guildId, moduleId),
|
|
313
|
+
context: (guildId, actor) => overviewReadContext(guildId, actor, this.#services),
|
|
314
|
+
});
|
|
315
|
+
this.readServerOverview = this.#overview.readServerOverview.bind(this.#overview);
|
|
316
|
+
this.revokeServerOverviewInvite =
|
|
317
|
+
this.#overview.revokeServerOverviewInvite.bind(this.#overview);
|
|
279
318
|
}
|
|
280
319
|
async creatorOnboarding(input) {
|
|
281
320
|
return executeCreatorOnboarding(input, {
|
|
@@ -994,7 +1033,9 @@ export class BotControlService {
|
|
|
994
1033
|
const declaredIntents = declaration?.creationIntents ?? ["publish"];
|
|
995
1034
|
if (!declaredIntents.includes(input.intent))
|
|
996
1035
|
throw new DashboardActionValidationError("This creation intent is not declared by the module.");
|
|
997
|
-
|
|
1036
|
+
const result = normalizeManagedResourceDetail(managedResourceDetailSchema.parse(await resource.create(context, input.value, input.intent)), managedResourceColumnKeys(module, input.resourceType));
|
|
1037
|
+
this.#overview.invalidate(input.guildId);
|
|
1038
|
+
return result;
|
|
998
1039
|
}
|
|
999
1040
|
async updateManagedResource(input) {
|
|
1000
1041
|
await this.#requireModuleAccessible(input.guildId, input.moduleId);
|
|
@@ -1005,11 +1046,13 @@ export class BotControlService {
|
|
|
1005
1046
|
declaration?.featureId,
|
|
1006
1047
|
...resourceFieldFeatureIds(declaration?.fields ?? [], input.value),
|
|
1007
1048
|
]);
|
|
1008
|
-
|
|
1049
|
+
const result = normalizeManagedResourceDetail(managedResourceDetailSchema.parse(await resource.update(await this.#managedResourceContext(input, module, "update"), {
|
|
1009
1050
|
resourceId: input.resourceId,
|
|
1010
1051
|
expectedRevision: input.expectedRevision,
|
|
1011
1052
|
value: input.value,
|
|
1012
1053
|
})), managedResourceColumnKeys(module, input.resourceType));
|
|
1054
|
+
this.#overview.invalidate(input.guildId);
|
|
1055
|
+
return result;
|
|
1013
1056
|
}
|
|
1014
1057
|
async deleteManagedResource(input) {
|
|
1015
1058
|
await this.#requireModuleAccessible(input.guildId, input.moduleId);
|
|
@@ -1017,10 +1060,12 @@ export class BotControlService {
|
|
|
1017
1060
|
this.#requireManagedResourceOperation(module, input.resourceType, "delete");
|
|
1018
1061
|
const declaration = module.manifest.dashboard?.resources?.find(({ id }) => id === input.resourceType);
|
|
1019
1062
|
await requireDashboardFeatures(this.#services, input.guildId, input.moduleId, [declaration?.featureId]);
|
|
1020
|
-
|
|
1063
|
+
const result = managedResourceDeleteResultSchema.parse(await resource.delete(await this.#managedResourceContext(input, module, "delete"), {
|
|
1021
1064
|
resourceId: input.resourceId,
|
|
1022
1065
|
expectedRevision: input.expectedRevision,
|
|
1023
1066
|
}));
|
|
1067
|
+
this.#overview.invalidate(input.guildId);
|
|
1068
|
+
return result;
|
|
1024
1069
|
}
|
|
1025
1070
|
async executeManagedResourceAction(input) {
|
|
1026
1071
|
await this.#requireModuleAccessible(input.guildId, input.moduleId);
|
|
@@ -1046,6 +1091,7 @@ export class BotControlService {
|
|
|
1046
1091
|
expectedRevision: input.expectedRevision,
|
|
1047
1092
|
value: input.value,
|
|
1048
1093
|
});
|
|
1094
|
+
this.#overview.invalidate(input.guildId);
|
|
1049
1095
|
return result === null
|
|
1050
1096
|
? null
|
|
1051
1097
|
: normalizeManagedResourceDetail(managedResourceDetailSchema.parse(result), managedResourceColumnKeys(module, input.resourceType));
|
|
@@ -1523,6 +1569,7 @@ export async function createBotControlServer(input) {
|
|
|
1523
1569
|
return input.service.setModuleStatus({ ...params, ...body });
|
|
1524
1570
|
});
|
|
1525
1571
|
registerDashboardActionRoutes(server, input.service);
|
|
1572
|
+
registerServerOverviewControlRoutes(server, input.service);
|
|
1526
1573
|
registerChannelAuditRoutes(server, input.service);
|
|
1527
1574
|
server.get("/v1/guilds/:guildId/modules/:moduleId/resources/:resourceType", async (request) => {
|
|
1528
1575
|
const params = z
|
|
@@ -8,6 +8,13 @@ export declare class DiscordCreatorInviteService implements CreatorInviteService
|
|
|
8
8
|
private readonly repository;
|
|
9
9
|
private readonly services;
|
|
10
10
|
private readonly module;
|
|
11
|
+
identifyInvites(input: {
|
|
12
|
+
guildId: string;
|
|
13
|
+
codes: readonly string[];
|
|
14
|
+
}): Promise<readonly {
|
|
15
|
+
code: string;
|
|
16
|
+
reference: string;
|
|
17
|
+
}[]>;
|
|
11
18
|
constructor(client: Client, repository: CreatorInviteRepository, services: ServiceAccess, module: ModuleDefinition | undefined, encryption: string | {
|
|
12
19
|
inviteEncryptionKey: string;
|
|
13
20
|
});
|
|
@@ -16,6 +16,23 @@ export class DiscordCreatorInviteService {
|
|
|
16
16
|
repository;
|
|
17
17
|
services;
|
|
18
18
|
module;
|
|
19
|
+
async identifyInvites(input) {
|
|
20
|
+
validateId(input.guildId);
|
|
21
|
+
if (input.codes.length > 15 ||
|
|
22
|
+
input.codes.some((code) => !/^[A-Za-z0-9_-]{1,100}$/u.test(code)))
|
|
23
|
+
throw new CreatorInviteOperationError("unavailable");
|
|
24
|
+
this.#ownedGuild(input.guildId);
|
|
25
|
+
if (!(await this.repository.isInstalled()))
|
|
26
|
+
return [];
|
|
27
|
+
const requested = new Set(input.codes);
|
|
28
|
+
const found = [];
|
|
29
|
+
for (const record of await this.repository.listOwnedForGuild(input.guildId)) {
|
|
30
|
+
const code = this.#decrypt(record);
|
|
31
|
+
if (requested.has(code))
|
|
32
|
+
found.push({ code, reference: record.reference });
|
|
33
|
+
}
|
|
34
|
+
return found;
|
|
35
|
+
}
|
|
19
36
|
#key;
|
|
20
37
|
#rest = null;
|
|
21
38
|
#cleanupCursor;
|
|
@@ -163,8 +163,8 @@ export declare class DiscordGuildHealthInspection implements DiscordGuildHealthI
|
|
|
163
163
|
resourceValidationValid: boolean | null;
|
|
164
164
|
activationValid: boolean | null;
|
|
165
165
|
catalogueMatches: boolean;
|
|
166
|
-
requiredCapabilities: readonly ("
|
|
167
|
-
missingCapabilities: ("
|
|
166
|
+
requiredCapabilities: readonly ("guild-members" | "message-content")[];
|
|
167
|
+
missingCapabilities: ("guild-members" | "message-content")[];
|
|
168
168
|
missingPermissions: string[];
|
|
169
169
|
healthStatus: "healthy" | "degraded" | "unhealthy";
|
|
170
170
|
healthMessage: string | null;
|
package/dist/events.d.ts
CHANGED
package/dist/events.js
CHANGED
|
@@ -1802,6 +1802,7 @@ export class DiscordResourceInspection {
|
|
|
1802
1802
|
const member = members.get(userId) ?? null;
|
|
1803
1803
|
const cachedUser = this.client.users?.cache?.get(userId);
|
|
1804
1804
|
const avatarUrl = memberAvatarUrl(member);
|
|
1805
|
+
const isBot = member?.user?.bot ?? cachedUser?.bot;
|
|
1805
1806
|
return {
|
|
1806
1807
|
userId,
|
|
1807
1808
|
displayName: member?.displayName ??
|
|
@@ -1809,6 +1810,7 @@ export class DiscordResourceInspection {
|
|
|
1809
1810
|
cachedUser?.username ??
|
|
1810
1811
|
null,
|
|
1811
1812
|
...(avatarUrl ? { avatarUrl } : {}),
|
|
1813
|
+
...(typeof isBot === "boolean" ? { isBot } : {}),
|
|
1812
1814
|
};
|
|
1813
1815
|
});
|
|
1814
1816
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const HELP_API_ORIGIN = "https://api.helyx.gg";
|
|
3
|
+
declare const credentialSchema: z.ZodObject<{
|
|
4
|
+
installationId: z.ZodString;
|
|
5
|
+
token: z.ZodString;
|
|
6
|
+
expiresAt: z.ZodString;
|
|
7
|
+
}, z.core.$strict>;
|
|
8
|
+
export type HelpCredential = z.infer<typeof credentialSchema>;
|
|
9
|
+
export declare const parseHelpCredential: (value: unknown) => HelpCredential;
|
|
10
|
+
export declare class HelpCredentialError extends Error {
|
|
11
|
+
constructor();
|
|
12
|
+
}
|
|
13
|
+
/** Encrypted, opt-in file; separate from Cloud Connect and every provider secret. */
|
|
14
|
+
export declare class HelpCredentialStore {
|
|
15
|
+
readonly path: string;
|
|
16
|
+
private readonly key;
|
|
17
|
+
constructor(directory: string, dataKey: string);
|
|
18
|
+
private aad;
|
|
19
|
+
private checkDirectory;
|
|
20
|
+
read(): Promise<HelpCredential | null>;
|
|
21
|
+
save(input: HelpCredential): Promise<void>;
|
|
22
|
+
remove(): Promise<void>;
|
|
23
|
+
}
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=help-credentials.d.ts.map
|