60 lines
1.8 KiB
TypeScript
60 lines
1.8 KiB
TypeScript
import Model from "swaf/db/Model";
|
|
import AuthProof from "swaf/auth/AuthProof";
|
|
import User from "swaf/auth/models/User";
|
|
import {cryptoRandomDictionary} from "swaf/Utils";
|
|
|
|
export default class AuthToken extends Model implements AuthProof<User> {
|
|
public id?: number = undefined;
|
|
protected readonly user_id?: number = undefined;
|
|
private secret?: string = undefined;
|
|
protected created_at?: Date = undefined;
|
|
protected 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 = cryptoRandomDictionary(64, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_');
|
|
}
|
|
}
|
|
|
|
public use(): void {
|
|
this.used_at = new Date();
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|