Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 41 additions & 27 deletions packages/frontend/src/actors/TokenActor.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,50 @@
import { Unit, unit, minutes } from "itu-utils";
// packages/frontend/src/actors/TokenActor.ts

import { Unit, unit } from "itu-utils";
import { Actor, ActorRef, ActorSystem } from "ts-actors";
import Axios from "axios";
import { cookie } from "../utils";

const updateToken = () => {
const hasToken = !!cookie("bearer");
if (hasToken) {
Axios.get(import.meta.env.VITE_BACKEND_URI + "/auth/refresh", { withCredentials: true }).catch(() => {
alert(
"Could not refresh token. Presumeably the authentication server is unavailable. Please report this error if it happens repeatedly."
);
window.location.href = "/";
});
}
};

export class TokenActor extends Actor<unknown, Unit> {
public interval: any;
public interval: any;
private expiresAt: Date;

public constructor(name: string, system: ActorSystem) {
super(name, system);
this.expiresAt = new Date(); // Initialize with a default value
}

public override async afterStart(): Promise<void> {
this.updateToken();
}

public constructor(name: string, system: ActorSystem) {
super(name, system);
}
public override async beforeShutdown(): Promise<void> {
clearTimeout(this.interval);
}

public override async afterStart(): Promise<void> {
this.interval = setInterval(updateToken, minutes(import.meta.env.VITE_INACTIVITY_LIMIT).valueOf());
}
private updateToken = () => {
const hasToken = !!cookie("bearer");
if (hasToken) {
Axios.get(import.meta.env.VITE_BACKEND_URI + "/auth/refresh", { withCredentials: true })
.then(response => {
this.expiresAt = new Date(response.data.expires_at);
this.scheduleNextUpdate();
})
.catch(error => {
console.error("Failed to refresh token:", error);
setTimeout(this.updateToken, 5000); // Retry after 5 seconds
});
}
};

public override async beforeShutdown(): Promise<void> {
clearInterval(this.interval);
}
private scheduleNextUpdate = () => {
const buffer = 30000; // 30 seconds before expiry
const delay = this.expiresAt.getTime() - Date.now() - buffer;
clearTimeout(this.interval); // Clear previous timeout
this.interval = setTimeout(this.updateToken, delay);
};

public async receive(_from: ActorRef, _message: unknown): Promise<Unit> {
return unit();
}
}
public async receive(_from: ActorRef, _message: unknown): Promise<Unit> {
return unit();
}
}