73 lines
2.3 KiB
TypeScript
73 lines
2.3 KiB
TypeScript
import { NewsData, NewsFeed } from "../pages/feed/news";
|
|
import { NewsItem } from "../pages/feed/news-item";
|
|
|
|
type EndpointURL = "" | `http${'s' | ''}://${string}`;
|
|
|
|
interface ErrorDetails {
|
|
code: string,
|
|
message: string,
|
|
}
|
|
|
|
interface APIResponse<T> {
|
|
response ?: T;
|
|
error ?: ErrorDetails;
|
|
}
|
|
|
|
let newsFeed : NewsFeed | null = null;
|
|
|
|
class ErrorAPI extends Error {}
|
|
|
|
export class ControllerAPI {
|
|
protected endpoint: EndpointURL;
|
|
constructor(endpoint: EndpointURL = "") {
|
|
this.endpoint = endpoint;
|
|
}
|
|
|
|
protected async request<T>(path: string, options: RequestInit = {}): Promise<T> {
|
|
const url = new URL(path, this.endpoint || window.location.origin).href;
|
|
|
|
const response = await fetch(url, options);
|
|
const result: APIResponse<T> = await response.json();
|
|
if (result.error) throw new ErrorAPI(result.error.message);
|
|
if (result.response === undefined) throw new ErrorAPI("Missing response from API");
|
|
return result.response;
|
|
}
|
|
|
|
protected checkFirstAuth(): boolean {
|
|
// Implement your authentication logic here, e.g., check for a valid token in localStorage
|
|
//const token = localStorage.getItem('authToken');
|
|
//return !!token; // Returns true if token exists and is not empty
|
|
return true;
|
|
}
|
|
|
|
protected throwIfUnauthed(): void {
|
|
// Let's redirect to /auth if not authed
|
|
if (!this.checkFirstAuth()) {
|
|
window.location.href = '/auth';
|
|
}
|
|
}
|
|
|
|
async isAuthenticated(): Promise<boolean> {
|
|
if (!this.checkFirstAuth()) return false;
|
|
|
|
const result = await this.request<boolean>('/api/isAuthenticated', {
|
|
method: 'GET',
|
|
credentials: 'include' // Include cookies for authentication
|
|
});
|
|
return result;
|
|
}
|
|
|
|
async getNews(returnElement: boolean = false) : Promise<NewsFeed | NewsData[]> {
|
|
this.throwIfUnauthed();
|
|
|
|
const result = await this.request<NewsData[]>('/api/news', {
|
|
method: 'GET',
|
|
credentials: 'include' // Include cookies for authentication
|
|
});
|
|
if (!returnElement)
|
|
return result;
|
|
if (!newsFeed)
|
|
newsFeed = new NewsFeed(result.map(x => new NewsItem(x.title, new Date(x.publishedAt), x.content)));
|
|
return newsFeed;
|
|
}
|
|
} |