feat: User flags (#3353)

* feat: Add user flags concept, for tracking bits on a user

* feat: Example flag usage for user invite resend abuse
This commit is contained in:
Tom Moor
2022-04-11 19:42:50 -07:00
committed by GitHub
parent 11c009bdbf
commit 7f5bf6c6b3
5 changed files with 114 additions and 21 deletions

View File

@@ -40,6 +40,14 @@ import Encrypted, {
} from "./decorators/Encrypted";
import Fix from "./decorators/Fix";
/**
* Flags that are available for setting on the user.
*/
export enum UserFlag {
InviteSent = "inviteSent",
InviteReminderSent = "inviteReminderSent",
}
@Scopes(() => ({
withAuthentications: {
include: [
@@ -101,6 +109,9 @@ class User extends ParanoidModel {
@Column
suspendedAt: Date | null;
@Column(DataType.JSONB)
flags: { [key in UserFlag]?: number } | null;
@Default(process.env.DEFAULT_LANGUAGE)
@IsIn([languages])
@Column
@@ -162,6 +173,52 @@ class User extends ParanoidModel {
// instance methods
/**
* User flags are for storing information on a user record that is not visible
* to the user itself.
*
* @param flag The flag to set
* @param value Set the flag to true/false
* @returns The current user flags
*/
public setFlag = (flag: UserFlag, value = true) => {
if (!this.flags) {
this.flags = {};
}
this.flags[flag] = value ? 1 : 0;
this.changed("flags", true);
return this.flags;
};
/**
* Returns the content of the given user flag.
*
* @param flag The flag to retrieve
* @returns The flag value
*/
public getFlag = (flag: UserFlag) => {
return this.flags?.[flag] ?? 0;
};
/**
* User flags are for storing information on a user record that is not visible
* to the user itself.
*
* @param flag The flag to set
* @param value The amount to increment by, defaults to 1
* @returns The current user flags
*/
public incrementFlag = (flag: UserFlag, value = 1) => {
if (!this.flags) {
this.flags = {};
}
this.flags[flag] = (this.flags[flag] ?? 0) + value;
this.changed("flags", true);
return this.flags;
};
collectionIds = async (options = {}) => {
const collectionStubs = await Collection.scope({
method: ["withMembership", this.id],