pb refresh, profile refresh update
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
import { badgeKeys, badgeQueries } from "@/features/badges/queries";
|
||||||
import Profile from "@/features/players/components/profile";
|
import Profile from "@/features/players/components/profile";
|
||||||
import HeaderSkeleton from "@/features/players/components/profile/header-skeleton";
|
import HeaderSkeleton from "@/features/players/components/profile/header-skeleton";
|
||||||
import ProfileSkeleton from "@/features/players/components/profile/skeleton";
|
import ProfileSkeleton from "@/features/players/components/profile/skeleton";
|
||||||
@@ -24,6 +25,14 @@ export const Route = createFileRoute("/_authed/profile/$playerId")({
|
|||||||
queryClient,
|
queryClient,
|
||||||
playerQueries.matches(params.playerId)
|
playerQueries.matches(params.playerId)
|
||||||
),
|
),
|
||||||
|
prefetchServerQuery(
|
||||||
|
queryClient,
|
||||||
|
playerQueries.stats(params.playerId)
|
||||||
|
),
|
||||||
|
prefetchServerQuery(
|
||||||
|
queryClient,
|
||||||
|
badgeQueries.playerBadges(params.playerId)
|
||||||
|
),
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
loader: ({ params, context }) => ({
|
loader: ({ params, context }) => ({
|
||||||
@@ -34,7 +43,7 @@ export const Route = createFileRoute("/_authed/profile/$playerId")({
|
|||||||
context?.auth.user.id === params.playerId ? "/settings" : undefined,
|
context?.auth.user.id === params.playerId ? "/settings" : undefined,
|
||||||
},
|
},
|
||||||
withPadding: false,
|
withPadding: false,
|
||||||
refresh: [playerKeys.details(params.playerId), playerKeys.matches(params.playerId), playerKeys.stats(params.playerId)],
|
refresh: [playerKeys.details(params.playerId), playerKeys.matches(params.playerId), playerKeys.stats(params.playerId), badgeKeys.playerBadges(params.playerId)],
|
||||||
}),
|
}),
|
||||||
component: () => {
|
component: () => {
|
||||||
const { playerId } = Route.useParams();
|
const { playerId } = Route.useParams();
|
||||||
|
|||||||
@@ -12,11 +12,21 @@ dotenv.config();
|
|||||||
class PocketBaseAdminClient {
|
class PocketBaseAdminClient {
|
||||||
private pb: PocketBase;
|
private pb: PocketBase;
|
||||||
public authPromise: Promise<void>;
|
public authPromise: Promise<void>;
|
||||||
|
private refreshInterval: NodeJS.Timeout | null = null;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.pb = new PocketBase(process.env.POCKETBASE_URL);
|
this.pb = new PocketBase(process.env.POCKETBASE_URL);
|
||||||
|
|
||||||
this.pb.beforeSend = (url, options) => {
|
this.pb.beforeSend = async (url, options) => {
|
||||||
|
if (this.pb.authStore.isValid && this.isTokenExpiringSoon()) {
|
||||||
|
try {
|
||||||
|
await this.refreshAuth();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to refresh admin token, re-authenticating:', error);
|
||||||
|
await this.authenticate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
options.cache = "no-store";
|
options.cache = "no-store";
|
||||||
options.headers = {
|
options.headers = {
|
||||||
...options.headers,
|
...options.headers,
|
||||||
@@ -39,16 +49,72 @@ class PocketBaseAdminClient {
|
|||||||
Object.assign(this, createReactionsService(this.pb));
|
Object.assign(this, createReactionsService(this.pb));
|
||||||
Object.assign(this, createActivitiesService(this.pb));
|
Object.assign(this, createActivitiesService(this.pb));
|
||||||
Object.assign(this, createBadgesService(this.pb));
|
Object.assign(this, createBadgesService(this.pb));
|
||||||
|
|
||||||
|
this.startTokenRefresh();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async authenticate() {
|
private async authenticate() {
|
||||||
await this.pb
|
try {
|
||||||
.collection("_superusers")
|
await this.pb
|
||||||
.authWithPassword(
|
.collection("_superusers")
|
||||||
process.env.POCKETBASE_ADMIN_EMAIL!,
|
.authWithPassword(
|
||||||
process.env.POCKETBASE_ADMIN_PASSWORD!
|
process.env.POCKETBASE_ADMIN_EMAIL!,
|
||||||
);
|
process.env.POCKETBASE_ADMIN_PASSWORD!
|
||||||
|
);
|
||||||
|
console.log('PocketBase admin authenticated successfully');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to authenticate PocketBase admin:', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async refreshAuth() {
|
||||||
|
try {
|
||||||
|
await this.pb.collection("_superusers").authRefresh();
|
||||||
|
console.log('PocketBase admin token refreshed');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to refresh PocketBase admin token:', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private isTokenExpiringSoon(): boolean {
|
||||||
|
if (!this.pb.authStore.token) return false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const payload = JSON.parse(atob(this.pb.authStore.token.split('.')[1]));
|
||||||
|
const expiresAt = payload.exp * 1000;
|
||||||
|
const now = Date.now();
|
||||||
|
const fiveMinutes = 5 * 60 * 1000;
|
||||||
|
|
||||||
|
return expiresAt - now < fiveMinutes;
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private startTokenRefresh() {
|
||||||
|
this.refreshInterval = setInterval(async () => {
|
||||||
|
try {
|
||||||
|
await this.refreshAuth();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Periodic token refresh failed, re-authenticating:', error);
|
||||||
|
try {
|
||||||
|
await this.authenticate();
|
||||||
|
} catch (authError) {
|
||||||
|
console.error('Re-authentication failed:', authError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 10 * 60 * 1000);
|
||||||
|
|
||||||
|
if (typeof process !== 'undefined') {
|
||||||
|
process.on('beforeExit', () => {
|
||||||
|
if (this.refreshInterval) {
|
||||||
|
clearInterval(this.refreshInterval);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user