Skip to content

Commit

Permalink
be better about anonymizing users
Browse files Browse the repository at this point in the history
  • Loading branch information
3vorp committed Feb 20, 2024
1 parent ee769f7 commit da440bc
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 44 deletions.
17 changes: 15 additions & 2 deletions src/v2/controller/user.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,31 @@ import cache from "../tools/cache";
export class UserController extends Controller {
private readonly userService = new UserService();

/**
* Get user information using authentication parameters
* @param request
*/
@Get("profile")
@Security("discord", [])
public getProfile(@Request() request: any): Promise<User> {
return this.userService.getUserById(request.user);
}

/**
* Update a user's profile
* @param body New data
* @param request
*/
@Post("profile")
@Security("discord", [])
public async setProfile(@Body() body: UserProfile, @Request() request: any): Promise<void> {
await this.userService.setProfileById(request.user, body);
}

/**
* Create a new blank user profile
* @param request
*/
@Post("newprofile")
@Security("discord", [])
public async createProfile(@Request() request: any): Promise<User> {
Expand All @@ -71,7 +84,7 @@ export class UserController extends Controller {
}

/**
* Get all usernames the database has
* Get all usernames, UUIDs, and IDs
*/
@Get("names")
public async getNames(): Promise<Usernames> {
Expand All @@ -96,7 +109,7 @@ export class UserController extends Controller {
}

/**
* Get users that have a specific role
* Get users that have a specific role and username
* @param role Role name
* @param username Discord user username
*/
Expand Down
64 changes: 24 additions & 40 deletions src/v2/repository/user.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,13 @@ import {
} from "../interfaces";
import { selectDistinct } from "../tools/firestorm";

// eslint-disable-next-line no-underscore-dangle
const __transformUser = (user: Partial<User>): User => ({
// falsy checking
// you can get a discord username from a discord id but to my knowledge they aren't shown anywhere on the frontend
const anonymizeUser = (user: Partial<User>): User => ({
id: user.id,
username: user.username || "",
uuid: user.uuid || "",
roles: user.roles || [],
media: user.media,
username: user.anonymous ? user.username : null,
uuid: user.anonymous ? user.uuid : null,
roles: user.anonymous ? user.roles || [] : null,
media: user.anonymous ? user.media : null,
anonymous: user.anonymous || false,
});

Expand All @@ -34,14 +33,7 @@ export default class UserFirestormRepository implements UserRepository {
}

getRaw(): Promise<Record<string, User>> {
return (
users
.readRaw()
.then(Object.entries)
// convert to entries to map, convert back to object after mapping done
.then((arr: [string, User][]) => arr.map(([key, el]) => [key, __transformUser(el)]))
.then(Object.fromEntries)
);
return users.readRaw(); // protected endpoint, no need to anonymize
}

getNames(): Promise<Usernames> {
Expand All @@ -63,7 +55,7 @@ export default class UserFirestormRepository implements UserRepository {
getUserById(id: string): Promise<User> {
return users
.get(id)
.then((u) => __transformUser(u))
.then(anonymizeUser)
.catch((err) => {
if (err.isAxiosError && err.response && err.response.statusCode === 404) {
const formattedError: any = new Error("User not found");
Expand All @@ -78,17 +70,16 @@ export default class UserFirestormRepository implements UserRepository {

getProfileOrCreate(id: string): Promise<User> {
return users
.get(id)
.then((u) => __transformUser(u))
.get(id) // protected endpoint
.catch((err) => {
if (err.isAxiosError && err.response && err.response.statusCode === 404) {
const empty: User = {
anonymous: false,
id,
roles: [],
username: "",
uuid: "",
id,
media: [],
anonymous: false,
};
return users.set(id, empty).then(() => this.getUserById(id));
}
Expand All @@ -98,23 +89,25 @@ export default class UserFirestormRepository implements UserRepository {
}

getUsersByName(name: string): Promise<Users> {
if (!name || name.length < 3)
return Promise.reject(new Error("User search requires at least 3 letters"));

return users
.search([
{
field: "username",
criteria: "includes",
criteria: name.length < 3 ? "==" : "includes",
value: name,
ignoreCase: true,
},
])
.then((arr: Users) => arr.map(__transformUser));
.then((arr) => arr.map(anonymizeUser));
}

getUsersFromRole(role: string, username?: string): Promise<Users> {
if (role === "all" && !username) return users.readRaw().then(Object.values);
if (role === "all" && !username)
return users
.readRaw()
.then(Object.values)
.then((arr) => arr.map(anonymizeUser));

const options = [];

if (role !== "all")
Expand All @@ -133,7 +126,7 @@ export default class UserFirestormRepository implements UserRepository {
ignoreCase: true,
});

return users.search(options).then((arr: Users) => arr.map((el) => __transformUser(el)));
return users.search(options).then((arr) => arr.map(anonymizeUser));
}

getRoles(): Promise<Array<string>> {
Expand All @@ -149,10 +142,9 @@ export default class UserFirestormRepository implements UserRepository {
}

getAddonsApprovedById(id: string): Promise<Addons> {
return users
.get(id)
.then((u) => u.addons())
.then((arr) => arr.filter((el) => el.approval.status === "approved"));
return this.getAddonsById(id).then((arr) =>
arr.filter((el) => el.approval.status === "approved"),
);
}

update(id: string, user: UserCreationParams): Promise<User> {
Expand All @@ -164,14 +156,6 @@ export default class UserFirestormRepository implements UserRepository {
}

getUserProfiles(searchedUsers: string[]): Promise<UserProfile[]> {
return users.searchKeys(searchedUsers).then((u) =>
u.map((el) => ({
id: el.id,
username: el.anonymous ? undefined : el.username,
// ensure anonymous stays anonymous
uuid: el.anonymous ? undefined : el.uuid || undefined,
media: el.anonymous ? undefined : el.media || [],
})),
);
return users.searchKeys(searchedUsers).then((u) => u.map(anonymizeUser));
}
}
2 changes: 0 additions & 2 deletions src/v2/service/user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,6 @@ export class UserService {
await this.update(id, user);
}

//! We don't make verifications here, it's in the controllers

public async setRoles(id: string, roles: string[]): Promise<User> {
const user = await this.getUserById(id);
user.roles = roles;
Expand Down

0 comments on commit da440bc

Please sign in to comment.