Fix some model refactor usages

This commit is contained in:
Alice Gaudon 2020-07-26 11:37:01 +02:00
parent a79e2292d7
commit 21b7def9e4
12 changed files with 53 additions and 21 deletions

View File

@ -80,7 +80,8 @@ export default class Logger {
const logID = Buffer.alloc(16);
uuid({}, logID);
if (shouldSaveToDB) output += `${logID} - `;
let strLogID = bufferToUUID(logID);
if (shouldSaveToDB) output += `${strLogID} - `;
output += computedMsg.replace(/\n/g, '\n' + ' '.repeat(pad));
@ -116,7 +117,7 @@ export default class Logger {
}
});
}
return bufferToUUID(logID);
return strLogID;
}
return null;
}

View File

@ -47,3 +47,13 @@ export function bufferToUUID(buffer: Buffer): string {
}
return out;
}
export function getMethods<T>(obj: T): (string)[] {
let properties = new Set()
let currentObj = obj
do {
Object.getOwnPropertyNames(currentObj).map(item => properties.add(item))
} while ((currentObj = Object.getPrototypeOf(currentObj)))
// @ts-ignore
return [...properties.keys()].filter(item => typeof obj[item] === 'function')
}

View File

@ -7,6 +7,7 @@ import {PENDING_ACCOUNT_REVIEW_MAIL_TEMPLATE} from "../Mails";
import Mail from "../Mail";
import Controller from "../Controller";
import config from "config";
import ModelFactory from "../db/ModelFactory";
export default abstract class AuthGuard<P extends AuthProof<User>> {
public abstract async getProofForSession(session: Express.Session): Promise<P | null>;
@ -31,12 +32,11 @@ export default abstract class AuthGuard<P extends AuthProof<User>> {
const callbacks: RegisterCallback[] = [];
await MysqlConnectionManager.wrapTransaction(async connection => {
user = new User({});
await user.save(connection, c => callbacks.push(c));
user = ModelFactory.get(User).make({});
if (onRegister) {
(await onRegister(connection, user)).forEach(c => callbacks.push(c));
}
await user.save(connection, c => callbacks.push(c));
});
for (const callback of callbacks) {

View File

@ -9,6 +9,7 @@ import {AuthError, PendingApprovalAuthError, RegisterCallback} from "../AuthGuar
import geoip from "geoip-lite";
import AuthController from "../AuthController";
import NunjucksComponent from "../../components/NunjucksComponent";
import ModelFactory from "../../db/ModelFactory";
export default abstract class MagicLinkAuthController extends AuthController {
@ -22,7 +23,7 @@ export default abstract class MagicLinkAuthController extends AuthController {
await req.authGuard.authenticateOrRegister(req.session!, magicLink, undefined, async (connection, user) => {
const callbacks: RegisterCallback[] = [];
const userEmail = new UserEmail({
const userEmail = ModelFactory.get(UserEmail).make({
user_id: user.id,
email: magicLink.getEmail(),
});
@ -83,7 +84,7 @@ export default abstract class MagicLinkAuthController extends AuthController {
if (!userEmail) {
isRegistration = true;
userEmail = new UserEmail({
userEmail = ModelFactory.get(UserEmail).make({
email: email,
main: true,
});

View File

@ -6,6 +6,7 @@ import Throttler from "../../Throttler";
import Mail, {MailTemplate} from "../../Mail";
import MagicLink from "../models/MagicLink";
import config from "config";
import ModelFactory from "../../db/ModelFactory";
export default abstract class MagicLinkController extends Controller {
public static async sendMagicLink(sessionID: string, actionType: string, original_url: string, email: string, mailTemplate: MailTemplate, data: object): Promise<void> {
@ -13,7 +14,7 @@ export default abstract class MagicLinkController extends Controller {
Throttler.throttle('magic_link', 1, MagicLink.validityPeriod(), email, 0, 0);
const link = await MagicLink.bySessionID(sessionID, actionType) ||
new MagicLink({
ModelFactory.get(MagicLink).make({
session_id: sessionID,
action_type: actionType,
original_url: original_url,

View File

@ -6,6 +6,7 @@ import User from "./User";
import argon2 from "argon2";
import {WhereTest} from "../../db/ModelQuery";
import UserEmail from "./UserEmail";
import ModelFactory from "../../db/ModelFactory";
export default class MagicLink extends Model implements AuthProof<User> {
public static async bySessionID(sessionID: string, actionType?: string | string[]): Promise<MagicLink | null> {
@ -33,10 +34,8 @@ export default class MagicLink extends Model implements AuthProof<User> {
private generated_at?: Date = undefined;
private authorized: boolean = false;
constructor(data: any) {
super(data);
if (this.action_type === undefined) throw new Error('Action type must always be defined.');
if (this.original_url === undefined) throw new Error('Origin url must always be defined.');
constructor(factory: ModelFactory<MagicLink>) {
super(factory);
}
protected init(): void {

View File

@ -25,8 +25,8 @@ export default class User extends Model {
public readonly mainEmail = this.emails.cloneReduceToOne().constraint(q => q.where('id', this.main_email_id));
public constructor(data: any) {
super(data);
public constructor(factory: ModelFactory<User>) {
super(factory);
}
protected init(): void {

View File

@ -3,4 +3,7 @@ import User from "./User";
export default class UserApprovedComponent extends ModelComponent<User> {
public approved: boolean = false;
protected init(): void {
}
}

View File

@ -1,7 +1,5 @@
import User from "./User";
import {Connection} from "mysql";
import Model, {EMAIL_REGEX} from "../../db/Model";
import {query} from "../../db/MysqlConnectionManager";
import {OneModelRelation} from "../../db/ModelRelation";
import ModelFactory from "../../db/ModelFactory";
@ -16,8 +14,8 @@ export default class UserEmail extends Model {
foreignKey: 'id'
});
constructor(data: any) {
super(data);
constructor(factory: ModelFactory<UserEmail>) {
super(factory);
}
protected init(): void {

View File

@ -50,7 +50,7 @@ export default abstract class Model {
}
public addComponent(modelComponent: ModelComponent<this>): void {
modelComponent.init();
modelComponent.applyToModel();
this._components.push(modelComponent);
}
@ -179,7 +179,9 @@ export default abstract class Model {
private get _properties(): string[] {
return Object.getOwnPropertyNames(this).filter(p => {
return !p.startsWith('_') && !(this[p] instanceof ModelRelation);
return !p.startsWith('_') &&
typeof this[p] !== 'function' &&
!(this[p] instanceof ModelRelation);
});
}
}

View File

@ -1,5 +1,6 @@
import Model from "./Model";
import Validator from "./Validator";
import {getMethods} from "../Utils";
export default abstract class ModelComponent<T extends Model> {
protected readonly _model: T;
@ -11,14 +12,28 @@ export default abstract class ModelComponent<T extends Model> {
this._model = model;
}
public init(): void {
public applyToModel(): void {
this.init();
for (const property of this._properties) {
if (!property.startsWith('_')) {
(this._model as Model)[property] = this[property];
}
}
for (const method of getMethods(this)) {
// @ts-ignore
if (!method.startsWith('_') &&
['init', 'setValidation'].indexOf(method) < 0 &&
this._model[method] === undefined) {
// @ts-ignore
this._model[method] = this[method];
}
}
}
protected abstract init(): void;
protected setValidation<V>(propertyName: keyof this): Validator<V> {
const validator = new Validator<V>();
this._validators[propertyName as string] = validator;

View File

@ -192,7 +192,9 @@ export default class MysqlConnectionManager {
]);
});
}
}
for (const migration of this.migrations) {
migration.registerModels();
}
}