You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
78 lines
1.8 KiB
78 lines
1.8 KiB
import { TokenClaims } from "@common/TokenClaims"; |
|
import * as jwt from "jsonwebtoken"; |
|
import { computed, createAtom, IAtom, observable } from "mobx"; |
|
|
|
export class Token<TClaims extends TokenClaims = TokenClaims> { |
|
@observable |
|
token: string | null; |
|
|
|
@computed |
|
get claims(): TClaims | null { |
|
if (this.token == null) { |
|
return null; |
|
} |
|
return jwt.decode(this.token) as any; |
|
} |
|
|
|
private isExpiredAtom: IAtom; |
|
private currentTime!: number; |
|
private expirationTimer: number | undefined; |
|
|
|
constructor(token: string | null = null) { |
|
this.token = token; |
|
this.isExpiredAtom = createAtom( |
|
"Token.isExpired", |
|
this.startUpdating, |
|
this.stopUpdating |
|
); |
|
this.updateCurrentTime(); |
|
} |
|
|
|
toJSON() { |
|
return this.token; |
|
} |
|
|
|
updateCurrentTime = (reportChanged: boolean = true) => { |
|
if (reportChanged) { |
|
this.isExpiredAtom.reportChanged(); |
|
} |
|
this.currentTime = Date.now() / 1000; |
|
}; |
|
|
|
get remainingTime(): number { |
|
if (!this.isExpiredAtom.reportObserved()) { |
|
this.updateCurrentTime(false); |
|
} |
|
if (this.claims == null || this.claims.exp == null) { |
|
return Number.NEGATIVE_INFINITY; |
|
} |
|
return this.claims.exp - this.currentTime; |
|
} |
|
|
|
private startUpdating = () => { |
|
this.stopUpdating(); |
|
const remaining = this.remainingTime; |
|
if (remaining > 0) { |
|
this.expirationTimer = setTimeout( |
|
this.updateCurrentTime, |
|
this.remainingTime |
|
); |
|
} |
|
}; |
|
|
|
private stopUpdating = () => { |
|
if (this.expirationTimer != null) { |
|
clearTimeout(this.expirationTimer); |
|
this.expirationTimer = undefined; |
|
} |
|
}; |
|
|
|
get isExpired() { |
|
return this.remainingTime <= 0; |
|
} |
|
|
|
@computed |
|
get isValid() { |
|
return this.token != null && !this.isExpired; |
|
} |
|
}
|
|
|