Skip to content

Commit e14a19c

Browse files
committed
roles assignment refactor
1 parent 7341760 commit e14a19c

File tree

19 files changed

+304
-921
lines changed

19 files changed

+304
-921
lines changed

tooling/sparta/packages/discord/src/services/discord-service.ts

Lines changed: 41 additions & 209 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@
77
import { getDiscordInstance } from "../clients/discord";
88
import { logger } from "@sparta/utils";
99
import { PassportRoles } from "../types";
10-
import type { Guild, Role, GuildMember } from "discord.js";
10+
import type { Guild, GuildMember, Role as DiscordRole } from "discord.js";
1111
import { REST } from "@discordjs/rest";
1212
import { Routes } from "discord-api-types/v10";
1313
import type { ApiProvider } from "../api/apiProvider";
1414
import type { Client as ApiClient } from "@sparta/utils/openapi/types";
15+
import type { Role } from "@sparta/utils/const/roles";
1516

1617
/**
1718
* Discord service class for role management and user operations
@@ -67,7 +68,7 @@ export class DiscordService {
6768
isValid: boolean;
6869
message: string;
6970
guild?: Guild;
70-
role?: Role;
71+
role?: DiscordRole;
7172
member?: GuildMember;
7273
}> {
7374
try {
@@ -91,7 +92,9 @@ export class DiscordService {
9192
}
9293

9394
// Find the role
94-
const role = guild.roles.cache.find((r) => r.name === roleName);
95+
const role: DiscordRole | undefined = guild.roles.cache.find(
96+
(r) => r.name === roleName
97+
);
9598
if (!role) {
9699
return {
97100
isValid: false,
@@ -139,32 +142,21 @@ export class DiscordService {
139142
}
140143
}
141144

145+
public async assignRoles(userId: string, roles: Role[]): Promise<boolean> {
146+
for (const role of roles) {
147+
await this.assignRole(userId, role.name);
148+
}
149+
return true;
150+
}
151+
142152
/**
143153
* Assigns a role to a Discord user
144154
* @param userId The Discord user ID
145155
* @param roleName The name of the role to assign
146156
*/
147-
public async assignRole(userId: string, roleName: string): Promise<boolean>;
148-
149-
/**
150-
* Assigns a role to a Discord user using pre-validated data
151-
* @param validatedData The validated data from validateRoleAssignment
152-
*/
153-
public async assignRole(validatedData: {
154-
member: GuildMember;
155-
role: Role;
156-
}): Promise<boolean>;
157-
158-
/**
159-
* Assigns a role based on user score
160-
* @param userId The Discord user ID
161-
* @param score The user's passport score
162-
*/
163-
public async assignRole(userId: string, score: number): Promise<boolean>;
164-
165157
public async assignRole(
166-
arg1: string | { member: GuildMember; role: Role },
167-
arg2?: string | number
158+
userId: string,
159+
roleName: string
168160
): Promise<boolean> {
169161
// Ensure API client is initialized
170162
if (!this.apiClient) {
@@ -175,198 +167,38 @@ export class DiscordService {
175167
}
176168
}
177169

178-
try {
179-
// Check if this is the userId + score version
180-
if (typeof arg1 === "string" && typeof arg2 === "number") {
181-
const userId = arg1;
182-
const score = arg2;
183-
const minimumScore = parseInt(process.env.MINIMUM_SCORE || "0");
184-
185-
const validationResult = await this.validateRoleAssignment(
186-
userId,
187-
PassportRoles.Verified
188-
);
189-
190-
if (!validationResult.isValid || !validationResult.member) {
191-
logger.error(
192-
{
193-
userId,
194-
score,
195-
error: validationResult.message,
196-
},
197-
"Validation failed before score-based role assignment/removal."
198-
);
199-
return false;
200-
}
201-
202-
const { member, guild } = validationResult;
203-
if (!guild) {
204-
logger.error(
205-
{ userId },
206-
"Guild not found in validation result"
207-
);
208-
return false;
209-
}
210-
const verifiedRole = guild.roles.cache.find(
211-
(r) => r.name === PassportRoles.Verified
212-
);
213-
214-
if (!verifiedRole) {
215-
logger.error(
216-
{
217-
userId,
218-
roleName: PassportRoles.Verified,
219-
guildId: guild.id,
220-
},
221-
"Verified role not found in guild during score-based assignment."
222-
);
223-
return false;
224-
}
225-
226-
// Assign or remove role based on score
227-
if (score >= minimumScore) {
228-
// Add role if user meets minimum score
229-
await member.roles.add(verifiedRole);
230-
logger.info(
231-
{ userId, score, minimum: minimumScore },
232-
"Added verified role based on score"
233-
);
234-
235-
// Update user in API with new role info
236-
try {
237-
await this.apiClient.updateUser(
238-
{ discordUserId: userId },
239-
{
240-
role: PassportRoles.Verified,
241-
humanPassport: {
242-
status: "verification_complete",
243-
score,
244-
lastVerificationTime: Date.now(),
245-
},
246-
}
247-
);
248-
} catch (apiError) {
249-
logger.error(
250-
{ error: apiError, userId },
251-
"Failed to update user role in API"
252-
);
253-
// Continue since Discord role was already assigned
254-
}
255-
256-
return true;
257-
} else {
258-
// Remove role if user doesn't meet minimum score
259-
if (member.roles.cache.has(verifiedRole.id)) {
260-
await member.roles.remove(verifiedRole);
261-
logger.info(
262-
{ userId, roleName: verifiedRole.name },
263-
"Successfully removed role due to low score."
264-
);
170+
const validationResult = await this.validateRoleAssignment(
171+
userId,
172+
roleName
173+
);
265174

266-
// Update user in API with role removal
267-
try {
268-
await this.apiClient.updateUser(
269-
{ discordUserId: userId },
270-
{
271-
role: undefined,
272-
humanPassport: {
273-
status: "verification_failed",
274-
score,
275-
lastVerificationTime: Date.now(),
276-
},
277-
}
278-
);
279-
} catch (apiError) {
280-
logger.error(
281-
{ error: apiError, userId },
282-
"Failed to update user role in API"
283-
);
284-
// Continue since Discord role was already removed
285-
}
286-
}
287-
return true;
288-
}
289-
}
290-
291-
// Handle normal role assignment (userId + roleName)
292-
if (typeof arg1 === "string" && typeof arg2 === "string") {
293-
const userId = arg1;
294-
const roleName = arg2;
295-
296-
const validationResult = await this.validateRoleAssignment(
297-
userId,
298-
roleName
299-
);
300-
301-
if (!validationResult.isValid) {
302-
logger.error(
303-
{ userId, roleName, error: validationResult.message },
304-
"Role assignment validation failed"
305-
);
306-
return false;
307-
}
308-
309-
const { member, role } = validationResult;
310-
await member!.roles.add(role!);
311-
logger.info({ userId, roleName }, "Role assigned successfully");
312-
313-
// Update user role in API
314-
try {
315-
await this.apiClient.updateUser(
316-
{ discordUserId: userId },
317-
{ role: roleName }
318-
);
319-
} catch (apiError) {
320-
logger.error(
321-
{ error: apiError, userId, roleName },
322-
"Failed to update user role in API"
323-
);
324-
// Continue since Discord role was already assigned
325-
}
326-
327-
return true;
328-
}
329-
330-
// Handle pre-validated data
331-
if (typeof arg1 === "object") {
332-
const { member, role } = arg1;
333-
await member.roles.add(role);
334-
logger.info(
335-
{ userId: member.id, roleName: role.name },
336-
"Role assigned from validated data"
337-
);
338-
339-
// Update user role in API
340-
try {
341-
await this.apiClient.updateUser(
342-
{ discordUserId: member.id },
343-
{ role: role.name }
344-
);
345-
} catch (apiError) {
346-
logger.error(
347-
{
348-
error: apiError,
349-
userId: member.id,
350-
roleName: role.name,
351-
},
352-
"Failed to update user role in API"
353-
);
354-
// Continue since Discord role was already assigned
355-
}
175+
if (!validationResult.isValid) {
176+
logger.error(
177+
{ userId, roleName, error: validationResult.message },
178+
"Role assignment validation failed"
179+
);
180+
return false;
181+
}
356182

357-
return true;
358-
}
183+
const { member, role } = validationResult;
184+
await member!.roles.add(role!);
185+
logger.info({ userId, roleName }, "Role assigned successfully");
359186

360-
// If we get here, something's wrong with the arguments
187+
// Update user role in API
188+
try {
189+
await this.apiClient.updateUser(
190+
{ discordUserId: userId },
191+
{ role: roleName }
192+
);
193+
} catch (apiError) {
361194
logger.error(
362-
{ arg1, arg2 },
363-
"Invalid arguments for role assignment"
195+
{ error: apiError, userId, roleName },
196+
"Failed to update user role in API"
364197
);
365-
return false;
366-
} catch (error) {
367-
logger.error({ error }, "Error assigning role");
368-
return false;
198+
// Continue since Discord role was already assigned
369199
}
200+
201+
return true;
370202
}
371203

372204
/**

tooling/sparta/packages/discord/src/slashCommands/humans/verify.ts

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ import {
1515
} from "discord.js";
1616
import { logger } from "@sparta/utils";
1717
import { randomUUID } from "crypto";
18-
import { VERIFICATION_STATUS } from "@sparta/utils/const";
19-
import { getDiscordInstance } from "../../clients/discord";
2018
import { HumanSubcommands } from "../../types.js";
2119
import { clientPromise } from "../../api/axios";
2220

@@ -62,9 +60,7 @@ export async function handleVerifyCommand(
6260
{ discordUserId: userId },
6361
{
6462
humanPassport: {
65-
status:
66-
data.user.humanPassport?.status ||
67-
VERIFICATION_STATUS.NOT_VERIFIED,
63+
status: data.user.humanPassport?.status || false,
6864
verificationId,
6965
interactionToken,
7066
},
@@ -78,16 +74,13 @@ export async function handleVerifyCommand(
7874
} else {
7975
logger.info("User not found, creating new user");
8076

81-
// Create a new user
82-
const timestamp = Date.now();
83-
8477
logger.debug({
8578
discordUserId: userId,
8679
discordUsername,
8780
walletAddress: undefined,
8881
role: undefined,
8982
humanPassport: {
90-
status: VERIFICATION_STATUS.NOT_VERIFIED,
83+
status: false,
9184
verificationId,
9285
interactionToken,
9386
lastVerificationTime: null,
@@ -103,8 +96,7 @@ export async function handleVerifyCommand(
10396
walletAddress: undefined,
10497
role: undefined,
10598
humanPassport: {
106-
//@ts-ignore
107-
status: VERIFICATION_STATUS.NOT_VERIFIED,
99+
status: false,
108100
verificationId,
109101
interactionToken,
110102
lastVerificationTime: null,
@@ -126,18 +118,10 @@ export async function handleVerifyCommand(
126118
.setDescription(
127119
"To verify your identity and unlock roles, click the button below to connect your wallet and complete the verification process."
128120
)
129-
.addFields(
130-
{
131-
name: "What is Human Passport?",
132-
value: "Human Passport is a sybil resistance tool that verifies you're a unique human.",
133-
},
134-
{
135-
name: "Passport Status",
136-
value: `You'll need a score of at least ${
137-
process.env.MINIMUM_SCORE || "0"
138-
} to verify.`,
139-
}
140-
)
121+
.addFields({
122+
name: "What is Human Passport?",
123+
value: "Human Passport is a sybil resistance tool that verifies you're a unique human.",
124+
})
141125
.setFooter({
142126
text: "This verification link will expire in 30 minutes.",
143127
});

tooling/sparta/packages/discord/src/slashCommands/moderators/help.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,8 @@
77
import { ChatInputCommandInteraction, EmbedBuilder } from "discord.js";
88
import { logger } from "@sparta/utils";
99
import { ModeratorSubcommands } from "../../types.js";
10-
import {
11-
MODERATOR_ROLES,
12-
CHANNELS,
13-
getAllowedChannelsText,
14-
} from "../../utils/index.js";
15-
10+
import { CHANNELS, getAllowedChannelsText } from "../../utils/index.js";
11+
import { MODERATOR_ROLES } from "@sparta/utils/const/roles.js";
1612
/**
1713
* Display help information for all moderator commands
1814
*/

0 commit comments

Comments
 (0)