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

View File

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

View File

@ -8,14 +8,46 @@
* */ * */
import Sequelize from 'sequelize'; import Sequelize from 'sequelize';
import redis from '../redis'; import redis from './redis';
import logger from '../../core/logger'; import logger from '../core/logger';
import Model from '../sequelize'; import Model from './sequelize';
import { getIPv6Subnet } from '../../utils/ip'; import { RegUser, Channel, UserBlock } from './models';
import { ADMIN_IDS } from '../../core/config'; 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 { class User {
id: string; id: string;
ip: string; ip: string;
@ -30,16 +62,35 @@ class User {
*/ */
userlvl: number; userlvl: number;
constructor(id: string = null, ip: string = '127.0.0.1') { constructor() {
// id should stay null if unregistered // if id = null -> unregistered
this.id = id; this.id = null;
this.ip = ip; this.regUser = null;
this.ip = '127.0.0.1';
this.ipSub = this.ip;
this.channels = {}; this.channels = {};
this.blocked = []; this.blocked = [];
this.userlvl = 0; 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) { static async name2Id(name: string) {

View File

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

View File

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

View File

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