Bug fixes and app settings
This commit is contained in:
parent
10257b8294
commit
b043513fe8
@ -1,4 +1,8 @@
|
|||||||
export default {
|
export default {
|
||||||
|
app: {
|
||||||
|
name: 'Example App',
|
||||||
|
contact_email: 'noreply@example.net'
|
||||||
|
},
|
||||||
log_level: "DEV",
|
log_level: "DEV",
|
||||||
db_log_level: "ERROR",
|
db_log_level: "ERROR",
|
||||||
public_url: "http://localhost:4899",
|
public_url: "http://localhost:4899",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "wms-core",
|
"name": "wms-core",
|
||||||
"version": "0.10.2",
|
"version": "0.10.16",
|
||||||
"description": "Node web framework",
|
"description": "Node web framework",
|
||||||
"repository": "git@gitlab.com:ArisuOngaku/wms-core.git",
|
"repository": "git@gitlab.com:ArisuOngaku/wms-core.git",
|
||||||
"author": "Alice Gaudon <alice@gaudon.pro>",
|
"author": "Alice Gaudon <alice@gaudon.pro>",
|
||||||
|
@ -11,6 +11,7 @@ import {Type} from "./Utils";
|
|||||||
import LogRequestsComponent from "./components/LogRequestsComponent";
|
import LogRequestsComponent from "./components/LogRequestsComponent";
|
||||||
import {ValidationBag} from "./db/Validator";
|
import {ValidationBag} from "./db/Validator";
|
||||||
import TemplateError = lib.TemplateError;
|
import TemplateError = lib.TemplateError;
|
||||||
|
import config from "config";
|
||||||
|
|
||||||
export default abstract class Application {
|
export default abstract class Application {
|
||||||
private readonly version: string;
|
private readonly version: string;
|
||||||
@ -42,7 +43,7 @@ export default abstract class Application {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async start(): Promise<void> {
|
public async start(): Promise<void> {
|
||||||
Logger.info(`${this.constructor.name} v${this.version} - hi`);
|
Logger.info(`${config.get('app.name')} v${this.version} - hi`);
|
||||||
process.once('SIGINT', () => {
|
process.once('SIGINT', () => {
|
||||||
this.stop().catch(console.error);
|
this.stop().catch(console.error);
|
||||||
});
|
});
|
||||||
|
@ -11,13 +11,33 @@ import geoip from "geoip-lite";
|
|||||||
|
|
||||||
|
|
||||||
export default abstract class MagicLinkAuthController extends Controller {
|
export default abstract class MagicLinkAuthController extends Controller {
|
||||||
public static async checkAndAuth(req: Request, magicLink: MagicLink): Promise<void> {
|
public static async checkAndAuth(req: Request, res: Response, magicLink: MagicLink): Promise<void> {
|
||||||
if (magicLink.getSessionID() !== req.sessionID!) throw new BadOwnerMagicLink();
|
if (magicLink.getSessionID() !== req.sessionID!) throw new BadOwnerMagicLink();
|
||||||
if (!await magicLink.isAuthorized()) throw new UnauthorizedMagicLink();
|
if (!await magicLink.isAuthorized()) throw new UnauthorizedMagicLink();
|
||||||
if (!await magicLink.isValid()) throw new InvalidMagicLink();
|
if (!await magicLink.isValid()) throw new InvalidMagicLink();
|
||||||
|
|
||||||
// Auth
|
// Auth
|
||||||
await req.authGuard.authenticateOrRegister(req.session!, magicLink);
|
try {
|
||||||
|
await req.authGuard.authenticateOrRegister(req.session!, magicLink);
|
||||||
|
} catch (e) {
|
||||||
|
if (e instanceof PendingApprovalAuthError) {
|
||||||
|
res.format({
|
||||||
|
json: () => {
|
||||||
|
res.json({
|
||||||
|
'status': 'warning',
|
||||||
|
'message': `Your account is pending review. You'll receive an email once you're approved.`
|
||||||
|
});
|
||||||
|
},
|
||||||
|
html: () => {
|
||||||
|
req.flash('warning', `Your account is pending review. You'll receive an email once you're approved.`);
|
||||||
|
res.redirectBack('/');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected readonly loginMagicLinkActionType: string = 'Login';
|
protected readonly loginMagicLinkActionType: string = 'Login';
|
||||||
@ -114,27 +134,7 @@ export default abstract class MagicLinkAuthController extends Controller {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
await MagicLinkAuthController.checkAndAuth(req, res, magicLink);
|
||||||
await MagicLinkAuthController.checkAndAuth(req, magicLink);
|
|
||||||
} catch (e) {
|
|
||||||
if (e instanceof PendingApprovalAuthError) {
|
|
||||||
res.format({
|
|
||||||
json: () => {
|
|
||||||
res.json({
|
|
||||||
'status': 'warning',
|
|
||||||
'message': `Your account is pending review. You'll receive an email once you're approved.`
|
|
||||||
});
|
|
||||||
},
|
|
||||||
default: () => {
|
|
||||||
req.flash('warning', `Your account is pending review. You'll receive an email once you're approved.`);
|
|
||||||
res.redirectBack('/');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Auth success
|
// Auth success
|
||||||
const username = req.models.user?.name;
|
const username = req.models.user?.name;
|
||||||
|
@ -12,8 +12,8 @@ export default class User extends Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public name?: string;
|
public name?: string;
|
||||||
public approved: boolean = false;
|
public approved!: boolean;
|
||||||
public is_admin: boolean = false;
|
public is_admin!: boolean;
|
||||||
public created_at?: Date;
|
public created_at?: Date;
|
||||||
public updated_at?: Date;
|
public updated_at?: Date;
|
||||||
|
|
||||||
@ -24,6 +24,12 @@ export default class User extends Model {
|
|||||||
|
|
||||||
public readonly mainEmail = this.emails.cloneReduceToOne().constraint(q => q.where('main', true));
|
public readonly mainEmail = this.emails.cloneReduceToOne().constraint(q => q.where('main', true));
|
||||||
|
|
||||||
|
constructor(data: any) {
|
||||||
|
super(data);
|
||||||
|
if (this.approved === undefined) this.approved = false;
|
||||||
|
if (this.is_admin === undefined) this.is_admin = false;
|
||||||
|
}
|
||||||
|
|
||||||
protected init(): void {
|
protected init(): void {
|
||||||
this.addProperty<string>('name', new Validator().acceptUndefined().between(3, 64));
|
this.addProperty<string>('name', new Validator().acceptUndefined().between(3, 64));
|
||||||
if (User.isApprovalMode()) this.addProperty<boolean>('approved', new Validator().defined());
|
if (User.isApprovalMode()) this.addProperty<boolean>('approved', new Validator().defined());
|
||||||
|
@ -29,6 +29,9 @@ export default class NunjucksComponent extends ApplicationComponent<void> {
|
|||||||
req.env = env;
|
req.env = env;
|
||||||
res.locals.url = req.url;
|
res.locals.url = req.url;
|
||||||
res.locals.params = () => req.params;
|
res.locals.params = () => req.params;
|
||||||
|
|
||||||
|
res.locals.app = config.get('app');
|
||||||
|
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -224,7 +224,7 @@ export default abstract class Model {
|
|||||||
for (const indexField of this.getPrimaryKeyFields()) {
|
for (const indexField of this.getPrimaryKeyFields()) {
|
||||||
query = query.where(indexField, this[indexField]);
|
query = query.where(indexField, this[indexField]);
|
||||||
}
|
}
|
||||||
return typeof (await query.first()) !== 'undefined';
|
return (await query.limit(1).execute()).results.length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async delete(): Promise<void> {
|
public async delete(): Promise<void> {
|
||||||
|
@ -190,8 +190,10 @@ export default class ModelQuery<M extends Model> {
|
|||||||
// Eager loading execute
|
// Eager loading execute
|
||||||
for (const relationName of this.relations) {
|
for (const relationName of this.relations) {
|
||||||
const relations = relationMap[relationName];
|
const relations = relationMap[relationName];
|
||||||
const allModels = await relations[0].eagerLoad(relations);
|
if (relations.length > 0) {
|
||||||
await Promise.all(relations.map(r => r.populate(allModels)));
|
const allModels = await relations[0].eagerLoad(relations);
|
||||||
|
await Promise.all(relations.map(r => r.populate(allModels)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return models;
|
return models;
|
||||||
|
@ -31,6 +31,11 @@ export default abstract class ModelRelation<S extends Model, O extends Model, R
|
|||||||
return this.cachedModels;
|
return this.cachedModels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getOrFail(): R {
|
||||||
|
if (!this.cachedModels) throw new Error('Models were not fetched');
|
||||||
|
return this.cachedModels;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract async eagerLoad(relations: ModelRelation<S, O, R>[]): Promise<ModelQueryResult<O>>;
|
public abstract async eagerLoad(relations: ModelRelation<S, O, R>[]): Promise<ModelQueryResult<O>>;
|
||||||
|
|
||||||
public abstract async populate(models: ModelQueryResult<O>): Promise<void>;
|
public abstract async populate(models: ModelQueryResult<O>): Promise<void>;
|
||||||
|
Loading…
Reference in New Issue
Block a user