1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-10 05:30:01 +00:00

Adding initial count validators

This commit is contained in:
Tom
2025-03-17 14:28:30 -04:00
parent 9a69d5c54e
commit cf20a83278
4 changed files with 288 additions and 0 deletions

View File

@@ -0,0 +1,44 @@
import { earnedEvent } from "../achievement-events";
import { Type } from "../data";
import {
AchievementId,
AchievementProgressEvent,
AchievementValidator,
MetricId,
UserActionEvent,
} from "../types";
export class AttachmentAddedValidator implements AchievementValidator {
base: AchievementValidator;
get achievement() {
return "item-attached" as AchievementId;
}
get name() {
return "1st attachment added to item";
}
get metric() {
// Does this need to match vault-item-created-count-validator metric id for "item-quantity"
return "item-quantity" as MetricId;
}
get validator() {
return Type.HasTag;
}
get active() {
return this.base.active;
}
get hidden() {
return false;
}
constructor() {
this.base.active = "until-earned";
}
trigger(item: UserActionEvent) {
return item.tags?.includes("with-attachment") ?? false;
}
award(_measured: AchievementProgressEvent[]) {
return [earnedEvent(this.achievement)];
}
}

View File

@@ -0,0 +1,150 @@
import { CipherType } from "../../../../vault/enums";
import { Type } from "../../data";
import { Achievement, AchievementId, MetricId } from "../../types";
/**
* Creates the ability to add configs for different achievements at
* defined thresholds for items created in the vault. Creating the config
* with no cipher type is used for validations where the type is not needed
*/
export class ItemCreatedCountConfig implements Achievement {
// Define the achievements here
// Any vault items added
static readonly ItemCreated = new ItemCreatedCountConfig(
"vault-item-created",
"1st item added",
1,
);
static readonly ItemsCreated10 = new ItemCreatedCountConfig(
"vault-items-created-ten",
"10 items created",
10,
);
static readonly ItemsCreated50 = new ItemCreatedCountConfig(
"vault-items-created-fifty",
"50 items created",
50,
);
static readonly ItemsCreated100 = new ItemCreatedCountConfig(
"vault-items-created-one-hundred",
"100 items created",
100,
);
// Login items added
static readonly LoginItemCreated = new ItemCreatedCountConfig(
"login-item-created",
"1st login item added",
1,
CipherType.Login,
);
static readonly LoginItemCreated10 = new ItemCreatedCountConfig(
"login-item-created-ten",
"10 login items added",
10,
CipherType.Login,
);
static readonly LoginItemCreated50 = new ItemCreatedCountConfig(
"login-item-created-fifty",
"50 login items added",
50,
CipherType.Login,
);
static readonly LoginItemCreated100 = new ItemCreatedCountConfig(
"login-item-created-one-hundred",
"100 login items added",
100,
CipherType.Login,
);
// Card items
static readonly CardItemCreated = new ItemCreatedCountConfig(
"card-item-created",
"1st card item added",
1,
CipherType.Card,
);
static readonly CardItemCreated10 = new ItemCreatedCountConfig(
"card-item-created-ten",
"10 card items added",
10,
CipherType.Card,
);
static readonly CardItemCreated50 = new ItemCreatedCountConfig(
"card-item-created-fifty",
"50 card items added",
50,
CipherType.Card,
);
static readonly CardItemCreated100 = new ItemCreatedCountConfig(
"card-item-created-one-hundred",
"100 card items added",
100,
CipherType.Card,
);
// Note items
static readonly NoteItemCreated = new ItemCreatedCountConfig(
"note-item-created",
"1st card item added",
1,
CipherType.SecureNote,
);
static readonly NoteItemCreated10 = new ItemCreatedCountConfig(
"note-item-created-ten",
"10 card items added",
10,
CipherType.SecureNote,
);
static readonly NoteItemCreated50 = new ItemCreatedCountConfig(
"note-item-created-fifty",
"50 card items added",
50,
CipherType.SecureNote,
);
static readonly NoteItemCreated100 = new ItemCreatedCountConfig(
"note-item-created-one-hundred",
"100 card items added",
100,
CipherType.SecureNote,
);
base: Achievement;
get achievement() {
return this.base.achievement;
}
get name() {
return this.base.name;
}
get validator() {
return this.base.validator;
}
get active() {
return this.base.active;
}
get hidden() {
return this.base.hidden;
}
cipherType: CipherType = null;
threshold: number;
private constructor(key: string, name: string, threshold: number, cipherType: CipherType = null) {
this.cipherType = cipherType;
this.threshold = threshold;
this.base = {
achievement: key as AchievementId,
name: name,
validator: Type.Threshold,
active: {
metric: `item-${cipherType ? `${CipherType[cipherType]}-` : ""}quantity` as MetricId,
low: threshold - 1,
high: threshold,
},
hidden: false,
};
}
}

View File

@@ -0,0 +1,39 @@
import { earnedEvent } from "../achievement-events";
import { Type } from "../data";
import {
AchievementId,
AchievementProgressEvent,
AchievementValidator,
UserActionEvent,
} from "../types";
export class ItemFolderAddedValidator implements AchievementValidator {
base: AchievementValidator;
get achievement() {
return "item-folder-added" as AchievementId;
}
get name() {
return "1st item added to folder";
}
get validator() {
return Type.HasTag;
}
get active() {
return this.base.active;
}
get hidden() {
return false;
}
constructor() {
this.base.active = "until-earned";
}
trigger(item: UserActionEvent) {
return item.tags?.includes("with-folder") ?? false;
}
award(_measured: AchievementProgressEvent[]) {
return [earnedEvent(this.achievement)];
}
}

View File

@@ -0,0 +1,55 @@
import { CipherType } from "../../../vault/enums";
import { EventFormat } from "../../log/ecs-format";
import { earnedEvent, progressEvent } from "../achievement-events";
import { AchievementProgressEvent, AchievementValidator, MetricId } from "../types";
import { ItemCreatedCountConfig } from "./config/item-created-count-config";
/**
* Creates a validator that will be customized to a custom count achievement
* @param config contains the information to create the validator and achievement info.
* The defined config should be input as example: ItemCreatedCountConfig.ItemCreated
*
* Will track the count achievements for all vault items and individual vault items.
*/
export class VaultItemCreatedCountValidator implements AchievementValidator {
private itemCreatedProgress: MetricId;
constructor(private config: ItemCreatedCountConfig) {
this.itemCreatedProgress =
`item-${config.cipherType ? `${CipherType[config.cipherType]}-` : ""}quantity` as MetricId;
}
base: AchievementValidator;
get achievement() {
return this.config.achievement;
}
get name() {
return this.config.name;
}
get validator() {
return this.config.validator;
}
get active() {
return this.config.active;
}
get hidden() {
return this.config.hidden;
}
trigger(item: EventFormat) {
return (
item.action ===
`vault-${this.config.cipherType ? `${CipherType[this.config.cipherType]}-` : ""}item-added`
);
}
measure(_item: EventFormat, progress: Map<MetricId, number>) {
const value = 1 + (progress.get(this.itemCreatedProgress) ?? 0);
return [progressEvent(this.itemCreatedProgress, value)];
}
award(_measured: AchievementProgressEvent[], progress: Map<MetricId, number>) {
const value = progress.get(this.itemCreatedProgress) ?? 0;
return value >= this.config.threshold ? [earnedEvent(this.achievement)] : [];
}
}