ily.li/src/models/AuthToken.ts

73 lines
2.1 KiB
TypeScript

import {Request} from "express";
import {nanoid} from "nanoid";
import AuthProof from "swaf/auth/AuthProof";
import User from "swaf/auth/models/User";
import Model from "swaf/db/Model";
import {ModelQueryResult} from "swaf/db/ModelQuery";
export default class AuthToken extends Model implements AuthProof<User> {
public static async paginateForUser(
req: Request,
perPage: number,
user_id: number,
): Promise<ModelQueryResult<AuthToken>> {
req.params.sortBy = 'created_at';
req.params.sortDirection = 'DESC';
return await this.paginate(req, perPage, this.select().where('user_id', user_id));
}
public id?: number = undefined;
protected readonly user_id?: number = undefined;
private secret?: string = undefined;
public created_at?: Date = undefined;
public used_at?: Date = undefined;
protected readonly ttl?: number = undefined;
protected init(): void {
this.setValidation('user_id').defined().exists(User, 'id');
this.setValidation('secret').defined().between(32, 64);
this.setValidation('ttl').defined().min(1).max(5 * 365 * 24 * 3600 /* 5 years */);
}
protected async autoFill(): Promise<void> {
if (!this.secret) {
this.secret = nanoid(64);
}
}
public async use(): Promise<void> {
this.used_at = new Date();
await this.save();
}
public canDelete(user_id: number): boolean {
return this.user_id === user_id;
}
public getExpirationDate(): Date {
if (!this.created_at) return new Date();
return new Date(this.created_at.getTime() + this.getOrFail('ttl') * 1000);
}
public async getResource(): Promise<User | null> {
return await User.getById<User>(this.user_id);
}
public async isAuthorized(): Promise<boolean> {
return true;
}
public async isValid(): Promise<boolean> {
return new Date().getTime() < this.getExpirationDate().getTime();
}
public async revoke(): Promise<void> {
await this.delete();
}
protected getSecret(): string | undefined {
return this.secret;
}
}