79 lines
1.8 KiB
TypeScript
Raw Normal View History

2018-08-11 20:02:16 +03:00
import { TokenClaims } from "@common/TokenClaims";
import * as jwt from "jsonwebtoken";
import { computed, createAtom, IAtom, observable } from "mobx";
2018-08-11 20:35:34 +03:00
export class Token<TClaims extends TokenClaims = TokenClaims> {
2018-09-02 02:57:55 -06:00
@observable
token: string | null;
2018-09-02 02:57:55 -06:00
@computed
get claims(): TClaims | null {
if (this.token == null) {
return null;
}
2018-09-02 02:57:55 -06:00
return jwt.decode(this.token) as any;
}
2018-09-02 02:57:55 -06:00
private isExpiredAtom: IAtom;
private currentTime!: number;
private expirationTimer: number | undefined;
2018-09-02 02:57:55 -06:00
constructor(token: string | null = null) {
this.token = token;
this.isExpiredAtom = createAtom(
"Token.isExpired",
this.startUpdating,
this.stopUpdating
);
this.updateCurrentTime();
}
2018-09-02 02:57:55 -06:00
toJSON() {
return this.token;
}
2018-09-02 02:57:55 -06:00
updateCurrentTime = (reportChanged: boolean = true) => {
if (reportChanged) {
this.isExpiredAtom.reportChanged();
}
2018-09-02 02:57:55 -06:00
this.currentTime = Date.now() / 1000;
};
2018-09-02 02:57:55 -06:00
get remainingTime(): number {
if (!this.isExpiredAtom.reportObserved()) {
this.updateCurrentTime(false);
}
2018-09-02 02:57:55 -06:00
if (this.claims == null || this.claims.exp == null) {
return Number.NEGATIVE_INFINITY;
}
2018-09-02 02:57:55 -06:00
return this.claims.exp - this.currentTime;
}
2018-09-02 02:57:55 -06:00
private startUpdating = () => {
this.stopUpdating();
const remaining = this.remainingTime;
if (remaining > 0) {
this.expirationTimer = setTimeout(
this.updateCurrentTime,
this.remainingTime
);
}
2018-09-02 02:57:55 -06:00
};
2018-09-02 02:57:55 -06:00
private stopUpdating = () => {
if (this.expirationTimer != null) {
clearTimeout(this.expirationTimer);
this.expirationTimer = undefined;
}
2018-09-02 02:57:55 -06:00
};
2018-09-02 02:57:55 -06:00
get isExpired() {
return this.remainingTime <= 0;
}
@computed
get isValid() {
return this.token != null && !this.isExpired;
}
}