mirror of
https://gitlab.com/PronounsPage/PronounsPage.git
synced 2025-09-22 20:24:18 -04:00
161 lines
4.0 KiB
TypeScript
161 lines
4.0 KiB
TypeScript
import type { CustomEvent } from './calendar/helpers.ts';
|
|
import type { Opinion } from './opinions.ts';
|
|
import type { User } from './user.ts';
|
|
|
|
import type { VoiceKey } from '#shared/pronunciation/voices.ts';
|
|
import type { LocaleCode } from '~~/locale/locales.ts';
|
|
|
|
export interface UserWithProfiles {
|
|
id: string;
|
|
username: string;
|
|
email: string;
|
|
avatarSource: string | null;
|
|
bannedReason: string | null;
|
|
bannedTerms: string | null;
|
|
bannedBy: string | null;
|
|
team: string;
|
|
profiles: Record<string, Profile>;
|
|
personally: string | null;
|
|
}
|
|
|
|
export interface Profile {
|
|
id: string;
|
|
names: NameOpinion[];
|
|
pronouns: ValueOpinion[];
|
|
description: string;
|
|
age?: number | null;
|
|
/**
|
|
* @format date
|
|
*/
|
|
birthday: string | null;
|
|
timezone: Timezone | null;
|
|
links: string[];
|
|
linksMetadata: Record<string, LinkMetadata>;
|
|
verifiedLinks: Record<string, string>;
|
|
flags: string[];
|
|
customFlags: CustomFlag[];
|
|
words: WordCategory[];
|
|
teamName: string | null;
|
|
footerName: string | null;
|
|
footerAreas: string[];
|
|
credentials: string[];
|
|
credentialsLevel: number | null;
|
|
credentialsName: string | null;
|
|
card: string | null;
|
|
cardDark: string | null;
|
|
opinions: Record<string, Opinion & { description: string }>;
|
|
circle: RelatedPerson[];
|
|
sensitive: string[];
|
|
markdown: boolean;
|
|
events: string[];
|
|
customEvents: CustomEvent[];
|
|
visibility: ProfileVisibility;
|
|
access: boolean;
|
|
/**
|
|
* @format ulid
|
|
*/
|
|
lastUpdate: string | null;
|
|
}
|
|
|
|
export interface ValueOpinion {
|
|
value: string;
|
|
opinion: string;
|
|
}
|
|
|
|
export interface NameOpinion extends ValueOpinion {
|
|
pronunciation: string;
|
|
voice: VoiceKey | null;
|
|
}
|
|
|
|
export interface Timezone {
|
|
tz: string;
|
|
area: boolean;
|
|
loc: boolean;
|
|
}
|
|
|
|
export interface LinkMetadata {
|
|
favicon: string | null;
|
|
relMe: string[];
|
|
nodeinfo: unknown | null;
|
|
}
|
|
|
|
export interface WordCategory {
|
|
header: string | null;
|
|
values: ValueOpinion[];
|
|
}
|
|
|
|
export interface CustomFlag {
|
|
value: string;
|
|
name: string;
|
|
description: string | null;
|
|
alt: string | null;
|
|
link: string | null;
|
|
}
|
|
|
|
export interface RelatedPerson {
|
|
avatar: string;
|
|
circleMutual: boolean;
|
|
locale: LocaleCode;
|
|
relationship: string;
|
|
username: string;
|
|
}
|
|
|
|
export interface ProfileV1 extends Omit<Profile, 'names' | 'pronouns' | 'words' | 'customFlags'> {
|
|
names: Record<string, number>;
|
|
pronouns: Record<string, number>;
|
|
words: Record<string, number>[];
|
|
customFlags: Record<string, string>;
|
|
}
|
|
|
|
export interface SaveProfilePayload extends Omit<Profile, 'linksMetadata' | 'verifiedLinks' | 'opinions'
|
|
| 'card' | 'cardDark' | 'lastUpdate' | 'id' | 'access'> {
|
|
username: string;
|
|
opinions: OpinionFormValue[];
|
|
propagate: string[];
|
|
}
|
|
|
|
export interface OpinionFormValue {
|
|
key: string;
|
|
icon: string;
|
|
description: string;
|
|
colour: string;
|
|
style: string;
|
|
}
|
|
|
|
export enum ProfileVisibility {
|
|
Public = 0,
|
|
InternalBots = 1,
|
|
Internal = 2,
|
|
}
|
|
|
|
const denyAccessToProfile = (profile: Partial<Profile>): Partial<Profile> => {
|
|
return Object.fromEntries(Object.entries(profile).map(([key, value]) => {
|
|
if (key === 'access') {
|
|
return ['access', false];
|
|
}
|
|
if (['opinions', 'pronouns', 'visibility'].includes(key)) {
|
|
return [key, value];
|
|
}
|
|
return [key, undefined];
|
|
}));
|
|
};
|
|
|
|
export const applyProfileVisibilityRules = (visitor: User | null, profile: Partial<Profile>, allowBots: boolean): Partial<Profile> => {
|
|
if (visitor) {
|
|
return profile;
|
|
}
|
|
|
|
switch (profile.visibility) {
|
|
case ProfileVisibility.Internal:
|
|
return denyAccessToProfile(profile);
|
|
case ProfileVisibility.InternalBots:
|
|
return allowBots
|
|
? profile
|
|
: denyAccessToProfile(profile);
|
|
case ProfileVisibility.Public:
|
|
return profile;
|
|
default:
|
|
throw new Error(`Unknown visibility value: ${profile.visibility}`);
|
|
}
|
|
};
|