refactor User class

This commit is contained in:
HF 2022-06-19 19:47:37 +02:00
parent c975ec57bf
commit ff78373cb1
6 changed files with 102 additions and 89 deletions

View File

@ -4,7 +4,7 @@
import { Op } from 'sequelize';
import logger from './logger';
import redis from '../data/redis';
import User from '../data/models/User';
import User from '../data/User';
import RateLimiter from '../utils/RateLimiter';
import {
Channel, RegUser, UserChannel, Message,
@ -512,7 +512,7 @@ export class ChatProvider {
static async checkIfMuted(user) {
const key = `mute:${user.id}`;
const ttl: number = await redis.ttl(key);
const ttl = await redis.ttl(key);
return ttl;
}

View File

@ -15,64 +15,23 @@ import { OAuth2Strategy as GoogleStrategy } from 'passport-google-oauth';
import logger from './logger';
import { sanitizeName } from '../utils/validation';
import {
User, RegUser, Channel, UserBlock,
} from '../data/models';
import { RegUser } from '../data/models';
import User, { regUserQueryInclude as include } from '../data/User';
import { auth } from './config';
import { compareToHash } from '../utils/hash';
import { getIPFromRequest } from '../utils/ip';
const include = [{
model: Channel,
as: 'channel',
include: [{
model: RegUser,
as: 'dmu1',
foreignKey: 'dmu1id',
attributes: [
'id',
'name',
],
}, {
model: RegUser,
as: 'dmu2',
foreignKey: 'dmu2id',
attributes: [
'id',
'name',
],
}],
}, {
model: RegUser,
through: UserBlock,
as: 'blocked',
foreignKey: 'uid',
attributes: [
'id',
'name',
],
}];
passport.serializeUser((user, done) => {
done(null, user.id);
});
passport.deserializeUser(async (req, id, done) => {
const user = new User(id, getIPFromRequest(req));
if (id) {
RegUser.findByPk(id, {
include,
}).then((reguser) => {
if (reguser) {
user.setRegUser(reguser);
} else {
user.id = null;
}
done(null, user);
});
} else {
const user = new User();
try {
await user.initialize(id, getIPFromRequest(req));
done(null, user);
} catch (err) {
done(err, user);
}
});
@ -82,7 +41,7 @@ passport.deserializeUser(async (req, id, done) => {
passport.use(new JsonStrategy({
usernameProp: 'nameoremail',
passwordProp: 'password',
}, (nameoremail, password, done) => {
}, async (nameoremail, password, done) => {
try {
// Decide if email or name by the occurance of @
// this is why we don't allow @ in usernames
@ -92,21 +51,22 @@ passport.use(new JsonStrategy({
const query = (nameoremail.indexOf('@') !== -1)
? { email: nameoremail }
: { name: nameoremail };
RegUser.findOne({
const reguser = await RegUser.findOne({
include,
where: query,
}).then((reguser) => {
if (!reguser) {
return done(null, false, { message: 'Name or Email does not exist!' });
}
if (!compareToHash(password, reguser.password)) {
return done(null, false, { message: 'Incorrect password!' });
}
const user = new User(reguser.id);
user.setRegUser(reguser);
user.updateLogInTimestamp();
return done(null, user);
});
if (!reguser) {
done(null, false, { message: 'Name or Email does not exist!' });
return;
}
if (!compareToHash(password, reguser.password)) {
done(null, false, { message: 'Incorrect password!' });
return;
}
const user = new User();
await user.initialize(reguser.id, null, reguser);
user.updateLogInTimestamp();
done(null, user);
} catch (err) {
done(err);
}
@ -150,8 +110,8 @@ async function oauthLogin(email, name, discordid = null) {
if (!reguser.discordid && discordid) {
reguser.update({ discordid });
}
const user = new User(reguser.id);
user.setRegUser(reguser);
const user = new User();
await user.initialize(reguser.id, null, reguser);
return user;
}
@ -255,8 +215,8 @@ passport.use(new RedditStrategy({
redditid,
});
}
const user = new User(reguser.id);
user.setRegUser(reguser);
const user = new User();
await user.initialize(reguser.id, null, reguser);
done(null, user);
} catch (err) {
done(err);

View File

@ -8,14 +8,46 @@
* */
import Sequelize from 'sequelize';
import redis from '../redis';
import logger from '../../core/logger';
import redis from './redis';
import logger from '../core/logger';
import Model from '../sequelize';
import { getIPv6Subnet } from '../../utils/ip';
import { ADMIN_IDS } from '../../core/config';
import Model from './sequelize';
import { RegUser, Channel, UserBlock } from './models';
import { getIPv6Subnet } from '../utils/ip';
import { ADMIN_IDS } from '../core/config';
export const regUserQueryInclude = [{
model: Channel,
as: 'channel',
include: [{
model: RegUser,
as: 'dmu1',
foreignKey: 'dmu1id',
attributes: [
'id',
'name',
],
}, {
model: RegUser,
as: 'dmu2',
foreignKey: 'dmu2id',
attributes: [
'id',
'name',
],
}],
}, {
model: RegUser,
through: UserBlock,
as: 'blocked',
foreignKey: 'uid',
attributes: [
'id',
'name',
],
}];
class User {
id: string;
ip: string;
@ -30,16 +62,35 @@ class User {
*/
userlvl: number;
constructor(id: string = null, ip: string = '127.0.0.1') {
// id should stay null if unregistered
this.id = id;
this.ip = ip;
constructor() {
// if id = null -> unregistered
this.id = null;
this.regUser = null;
this.ip = '127.0.0.1';
this.ipSub = this.ip;
this.channels = {};
this.blocked = [];
this.userlvl = 0;
this.ipSub = getIPv6Subnet(ip);
// following gets populated by passport
this.regUser = null;
}
async initialize(id, ip = null, regUser = null) {
if (ip) {
this.ip = ip;
this.ipSub = getIPv6Subnet(ip);
}
if (regUser) {
this.id = regUser.id;
this.setRegUser(regUser);
}
if (id && !regUser) {
const reguser = await RegUser.findByPk(id, {
include: regUserQueryInclude,
});
if (reguser) {
this.setRegUser(reguser);
this.id = id;
}
}
}
static async name2Id(name: string) {

View File

@ -1,9 +1,6 @@
/* @flow */
import sequelize from '../sequelize';
import Blacklist from './Blacklist';
import Whitelist from './Whitelist';
import User from './User';
import RegUser from './RegUser';
import Channel from './Channel';
import UserChannel from './UserChannel';
@ -47,7 +44,6 @@ export default { sync };
export {
Whitelist,
Blacklist,
User,
RegUser,
Channel,
UserChannel,

View File

@ -3,7 +3,7 @@ import express from 'express';
import session from '../../core/session';
import passport from '../../core/passport';
import logger from '../../core/logger';
import User from '../../data/models/User';
import User from '../../data/User';
import { getIPFromRequest } from '../../utils/ip';
import me from './me';
@ -65,9 +65,10 @@ router.use('/modtools', modtools);
* create dummy user with just ip if not
* logged in
*/
router.use((req, res, next) => {
router.use(async (req, res, next) => {
if (!req.user) {
req.user = new User(null, getIPFromRequest(req));
req.user = new User();
await req.user.initialize(null, getIPFromRequest(req));
}
next();
});

View File

@ -6,7 +6,7 @@ import express from 'express';
import session from '../core/session';
import passport from '../core/passport';
import User from '../data/models/User';
import User from '../data/User';
import { expressTTag } from '../core/ttag';
import { getIPFromRequest } from '../utils/ip';
@ -26,8 +26,13 @@ function authenticateClient(req) {
router(req, {}, async () => {
const country = req.headers['cf-ipcountry'] || 'xx';
const countryCode = country.toLowerCase();
const user = (req.user) ? req.user
: new User(null, getIPFromRequest(req));
let user;
if (req.user) {
user = req.user;
} else {
user = new User();
await user.initialize(null, getIPFromRequest(req));
}
user.setCountry(countryCode);
user.ttag = req.ttag;
user.lang = req.lang;