import Model from "wms-core/db/Model"; import AuthProof from "wms-core/auth/AuthProof"; import UserEmail from "wms-core/auth/models/UserEmail"; import User from "wms-core/auth/models/User"; import Validator from "wms-core/db/Validator"; import {cryptoRandomDictionary} from "wms-core/Utils"; export default class AuthToken extends Model implements AuthProof { protected readonly user_id!: number; protected readonly secret!: string; protected created_at?: Date; protected used_at?: Date; protected readonly ttl!: number; constructor(props: any) { super(props); if (!this.secret) { this.secret = cryptoRandomDictionary(64, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_'); } } protected init() { this.addProperty('user_id', new Validator().defined().exists(User, 'id')); this.addProperty('secret', new Validator().defined().between(32, 64)); this.addProperty('created_at', new Validator()); this.addProperty('used_at', new Validator()); this.addProperty('ttl', new Validator().defined().min(1).max(5 * 365 * 24 * 3600)); // max 5 years } public use() { this.used_at = new Date(); } public canDelete(user_id: number) { return this.user_id === user_id; } public getExpirationDate(): Date { if (!this.created_at) return new Date(); return new Date(this.created_at.getTime() + this.ttl * 1000); } public async getEmail(): Promise { let userEmail = await UserEmail.select().where('user_id', this.user_id).first(); if (!userEmail) throw new Error("Cannot find main user email for user " + this.user_id); return userEmail.email; } public async getUser(): Promise { return await User.getById(this.user_id); } public async isAuthorized(): Promise { return true; } public async isOwnedBy(userId: number): Promise { return this.user_id === userId; } public async isValid(): Promise { return new Date().getTime() < this.getExpirationDate().getTime(); } public async revoke(session: Express.Session): Promise { await this.delete(); } }