128 lines
3.8 KiB
TypeScript
128 lines
3.8 KiB
TypeScript
export interface UserRecord {
|
|
id: string;
|
|
username: string;
|
|
displayName: string;
|
|
roles: string[];
|
|
sanctions: UserSanctions;
|
|
oauthType: 'NONE' | 'KAKAO';
|
|
oauthId?: string;
|
|
email?: string;
|
|
oauthInfo?: UserOAuthInfo;
|
|
picture: string;
|
|
imageServer: number;
|
|
iconUpdatedAt?: string;
|
|
iconRevision?: string;
|
|
profileIconResetAt?: string;
|
|
thirdPartyUse: boolean;
|
|
termsAcceptedAt?: string;
|
|
privacyAcceptedAt?: string;
|
|
kakaoVerifiedAt?: string;
|
|
kakaoGraceStartedAt: string;
|
|
deleteAfter?: string;
|
|
passwordHash: string;
|
|
passwordSalt: string;
|
|
createdAt: string;
|
|
legacyMemberNo?: number;
|
|
legacyGrade?: number;
|
|
}
|
|
|
|
export interface PublicUser {
|
|
id: string;
|
|
username: string;
|
|
displayName: string;
|
|
roles: string[];
|
|
picture: string;
|
|
kakaoVerified: boolean;
|
|
kakaoGraceStartedAt: string;
|
|
createdAt: string;
|
|
}
|
|
|
|
export interface UserSanctions {
|
|
bannedUntil?: string;
|
|
mutedUntil?: string;
|
|
suspendedUntil?: string;
|
|
warningCount?: number;
|
|
flags?: string[];
|
|
notes?: string;
|
|
serverRestrictions?: Record<string, UserServerRestriction>;
|
|
legacyPenalty?: Record<string, unknown>;
|
|
}
|
|
|
|
export interface UserServerRestriction {
|
|
blockedFeatures?: string[];
|
|
until?: string;
|
|
reason?: string;
|
|
notes?: string;
|
|
}
|
|
|
|
export const toPublicUser = (user: UserRecord): PublicUser => ({
|
|
id: user.id,
|
|
username: user.username,
|
|
displayName: user.displayName,
|
|
roles: user.roles,
|
|
picture: user.picture,
|
|
kakaoVerified: user.oauthType === 'KAKAO' && Boolean(user.kakaoVerifiedAt),
|
|
kakaoGraceStartedAt: user.kakaoGraceStartedAt,
|
|
createdAt: user.createdAt,
|
|
});
|
|
|
|
export interface CreateUserInput {
|
|
username: string;
|
|
password: string;
|
|
displayName?: string;
|
|
termsAcceptedAt?: Date;
|
|
privacyAcceptedAt?: Date;
|
|
thirdPartyUse?: boolean;
|
|
oauth?: {
|
|
type: 'KAKAO';
|
|
id: string;
|
|
email: string;
|
|
info: UserOAuthInfo;
|
|
};
|
|
}
|
|
|
|
export interface UserRepository {
|
|
findById(id: string): Promise<UserRecord | null>;
|
|
findByIds(ids: string[]): Promise<UserRecord[]>;
|
|
findByUsername(username: string): Promise<UserRecord | null>;
|
|
findByDisplayName(displayName: string): Promise<UserRecord | null>;
|
|
findByOauthId(type: 'KAKAO', oauthId: string): Promise<UserRecord | null>;
|
|
findByEmail(email: string): Promise<UserRecord | null>;
|
|
createUser(input: CreateUserInput): Promise<UserRecord>;
|
|
verifyPassword(user: UserRecord, password: string): Promise<boolean>;
|
|
updatePassword(userId: string, password: string): Promise<void>;
|
|
updateOAuthInfo(userId: string, oauthInfo: UserOAuthInfo): Promise<void>;
|
|
linkKakao(
|
|
userId: string,
|
|
input: {
|
|
oauthId: string;
|
|
email: string;
|
|
oauthInfo: UserOAuthInfo;
|
|
verifiedAt: Date;
|
|
}
|
|
): Promise<UserRecord>;
|
|
updateRoles(userId: string, roles: string[]): Promise<void>;
|
|
updateSanctions(userId: string, sanctions: UserSanctions): Promise<void>;
|
|
updateIcon(userId: string, picture: string, imageServer: number, updatedAt: Date): Promise<void>;
|
|
updateIconForDay(
|
|
userId: string,
|
|
picture: string,
|
|
imageServer: number,
|
|
updatedAt: Date,
|
|
dayStart: Date,
|
|
consumeDailyQuota: boolean
|
|
): Promise<string | null>;
|
|
resetProfileIcon(userId: string, requestedAt: Date): Promise<string | null>;
|
|
setThirdPartyUse(userId: string, allowed: boolean): Promise<void>;
|
|
scheduleDeletion(userId: string, deleteAfter: Date): Promise<void>;
|
|
deleteUser(userId: string): Promise<void>;
|
|
}
|
|
|
|
export interface UserOAuthInfo {
|
|
accessToken?: string;
|
|
refreshToken?: string;
|
|
accessTokenValidUntil?: string;
|
|
refreshTokenValidUntil?: string;
|
|
nextPasswordChange?: string;
|
|
}
|