next/models/user.ts

290 lines
5.0 KiB
TypeScript

import mongoose, { Document, Model, PopulatedDoc } from "mongoose";
import SequenceFactory from "mongoose-sequence";
import bcrypt from "bcryptjs";
import md5 from "blueimp-md5";
import jwt from "jsonwebtoken";
import { hasMigrated } from "@dbconfig";
import { IBand } from "./band";
import { IStory } from "./stories/index";
import { QuickMenuItem, QuickMenuSchema } from "./quickMenu";
// import { FilterPick, PopulatedDocKeys, PopulatedPick } from "~/utils/filter";
const AutoIncrement = SequenceFactory(mongoose);
interface IIPLogEntry {
lastAccess: Date;
ip: string;
}
export interface IUser extends Document {
_id?: number;
username: string;
email: string;
password: string;
auth: {
emailVerified: boolean;
activationKey: string | null;
passwordResetToken: string | null;
};
ts: {
created: Date;
updated: Date;
};
ipLog: IIPLogEntry[];
lastLogin: Date;
lastVisit: Date;
profile: {
avatar?: string;
isAdmin: boolean;
nightMode: boolean;
bio: string;
location: string;
occupation: string;
website: string;
blog: string;
views: number;
lastWhere: string | null;
hidden: boolean;
disclaimer: string;
showEmail: boolean;
};
biffno: {
years: string[];
wins: number;
};
favs: {
authors: PopulatedDoc<IUser & Document>[];
stories: PopulatedDoc<IStory & Document>[];
};
subscriptions: {
authors: PopulatedDoc<IUser & Document>[];
bands: PopulatedDoc<IBand & Document>[];
stories: PopulatedDoc<IStory & Document>[];
};
//@ts-ignore SHUT UP
hiddenAuthors: PopulatedDoc<IUser & Document>[];
hiddenBands: PopulatedDoc<IBand & Document>[];
//@ts-ignore SHUT UP
blocked: PopulatedDoc<IUser & Document>[];
sessionId: string | null;
banned: boolean;
quickMenuConfig: QuickMenuItem[];
notifyOnReviewReply?: boolean;
validPassword(password: string): boolean;
generateRefreshToken(jwtSecret: string): string;
generateAccessToken(jwtSecret: string): string;
}
// type iut = IUser;
interface UModel extends Model<IUser> {
generateHash(pwd: string): string;
}
const UserSchema = new mongoose.Schema<IUser>({
_id: {
type: Number,
},
username: {
type: String,
},
email: {
type: String,
},
password: {
type: String,
},
auth: {
emailVerified: {
type: Boolean,
default: false,
},
activationKey: {
type: String,
},
passwordResetToken: {
type: String,
default: null,
},
},
ts: {
created: {
type: Date,
default: new Date(),
},
updated: {
type: Date,
default: new Date(),
},
},
ipLog: [
{
ip: {
type: String,
},
lastAccess: {
type: Date,
default: new Date(),
},
},
],
lastLogin: {
type: Date,
default: null,
},
lastVisit: {
type: Date,
default: null,
},
profile: {
avatar: {
type: String,
default: "",
},
isAdmin: {
type: Boolean,
default: false,
},
nightMode: {
type: Boolean,
default: false,
},
bio: {
type: String,
default: "",
},
location: {
type: String,
default: "",
},
occupation: {
type: String,
default: "",
},
website: {
type: String,
default: "",
},
blog: {
type: String,
default: "",
},
views: {
type: Number,
min: 0,
default: 0,
},
lastWhere: {
type: String,
default: null,
},
hidden: {
type: Boolean,
default: false,
},
disclaimer: {
type: String,
default: "",
},
showEmail: {
type: Boolean,
default: false,
},
},
biffno: {
years: [
{
type: String,
},
],
wins: {
type: Number,
default: 0,
},
},
favs: {
authors: [
{
type: Number,
ref: "User",
},
],
stories: [
{
type: Number,
ref: "Story",
},
],
},
subscriptions: {
authors: [
{
type: Number,
ref: "User",
},
],
stories: [
{
type: Number,
ref: "Story",
},
],
bands: [
{
type: Number,
ref: "Band",
},
],
},
hiddenBands: [
{
type: Number,
ref: "Band",
},
],
hiddenAuthors: [
{
type: Number,
ref: "User",
},
],
notifyOnReviewReply: {
type: Boolean,
default: true,
},
blocked: [
{
type: Number,
ref: "User",
},
],
sessionId: {
type: String,
default: null,
},
banned: {
type: Boolean,
default: false,
},
quickMenuConfig: [QuickMenuSchema],
});
UserSchema.static("generateHash", function (password: string): string {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8));
});
UserSchema.methods.validPassword = function (password: string): boolean {
return md5(password) === this.password || bcrypt.compareSync(password, this.password) || false;
};
UserSchema.methods.generateRefreshToken = function (jwtKey: string): string {
return jwt.sign({ id: this._id, isAdmin: this.profile.isAdmin }, jwtKey, {
expiresIn: "14 days",
});
};
UserSchema.methods.generateAccessToken = function (jwtKey: string): string {
return jwt.sign({ id: this._id, isAdmin: this.profile.isAdmin }, jwtKey, {
expiresIn: "15m",
});
};
hasMigrated && !mongoose.models.User && UserSchema.plugin(AutoIncrement, { id: "userid", inc_field: "_id" });
export const User = mongoose.model<IUser, UModel>("User", UserSchema, "users");