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 { public static async getBySecret(secret: string): Promise { const models = await this.models(this.select().where('secret', secret).first()); return models.length > 0 ? models[0] : null; } public static async getForUser(user_id: number): Promise { return await this.models(this.select().where('user_id', user_id)); } 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 defineProperties() { this.defineProperty('user_id', new Validator().defined().exists(User, 'id')); this.defineProperty('secret', new Validator().defined().between(32, 64)); this.defineProperty('created_at', new Validator()); this.defineProperty('used_at', new Validator()); this.defineProperty('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.getMainFromUser(this.user_id); 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(); } }