feat(center): POST /auth/resolve-names
Resolve display names/emails to userIds within a guild node's active members (api-key auth). Used by guild for <@user.name:NAME> translation. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -240,6 +240,33 @@ export class AuthService {
|
||||
.filter((x) => !!x.email);
|
||||
}
|
||||
|
||||
// Resolve display names (or emails) to userIds, scoped to a guild node's
|
||||
// active members. Called by guild nodes (api-key auth). Unresolved names
|
||||
// are omitted from the result.
|
||||
async resolveNames(
|
||||
guildNodeId: string,
|
||||
names: string[],
|
||||
): Promise<{ resolved: Record<string, string> }> {
|
||||
const wanted = [...new Set(names.map((n) => String(n ?? '').trim()).filter(Boolean))];
|
||||
if (!guildNodeId || !wanted.length) return { resolved: {} };
|
||||
|
||||
const members = await this.guildUserRepo.find({ where: { guildNodeId, status: 'active' } });
|
||||
const userIds = [...new Set(members.map((m) => m.userId))];
|
||||
if (!userIds.length) return { resolved: {} };
|
||||
|
||||
const users = await this.userRepo
|
||||
.createQueryBuilder('u')
|
||||
.where('u.id IN (:...userIds)', { userIds })
|
||||
.getMany();
|
||||
|
||||
const resolved: Record<string, string> = {};
|
||||
for (const name of wanted) {
|
||||
const hit = users.find((u) => u.name === name) ?? users.find((u) => u.email === name);
|
||||
if (hit) resolved[name] = hit.id;
|
||||
}
|
||||
return { resolved };
|
||||
}
|
||||
|
||||
verifyCenterAccessToken(accessToken: string): jwt.JwtPayload {
|
||||
try {
|
||||
const payload = jwt.verify(accessToken, process.env.FABRIC_BACKEND_CENTER_JWT_ACCESS_SECRET as string) as jwt.JwtPayload;
|
||||
|
||||
Reference in New Issue
Block a user