TTime/frontend/src/API/API.ts

392 lines
11 KiB
TypeScript

import {
NewWeeklyReport,
NewUser,
User,
Project,
NewProject,
WeeklyReport,
} from "../Types/goTypes";
// This type of pattern should be hard to misuse
export interface APIResponse<T> {
success: boolean;
message?: string;
data?: T;
}
// Note that all protected routes also require a token
// Defines all the methods that an instance of the API must implement
interface API {
/** Register a new user */
registerUser(user: NewUser): Promise<APIResponse<User>>;
/** Remove a user */
removeUser(username: string, token: string): Promise<APIResponse<User>>;
/** Check if user is project manager */
checkIfProjectManager(
username: string,
projectName: string,
token: string,
): Promise<APIResponse<boolean>>;
/** Login */
login(NewUser: NewUser): Promise<APIResponse<string>>;
/** Renew the token */
renewToken(token: string): Promise<APIResponse<string>>;
/** Promote user to admin */
/** Create a project */
createProject(
project: NewProject,
token: string,
): Promise<APIResponse<Project>>;
/** Submit a weekly report */
submitWeeklyReport(
project: NewWeeklyReport,
token: string,
): Promise<APIResponse<NewWeeklyReport>>;
/**Gets a weekly report*/
getWeeklyReport(
username: string,
projectName: string,
week: string,
token: string,
): Promise<APIResponse<WeeklyReport>>;
/**
* Returns all the weekly reports for a user in a particular project
* The username is derived from the token
*
* @param {string} projectName The name of the project
* @param {string} token The token of the user
* @returns {APIResponse<WeeklyReport[]>} A list of weekly reports
*/
getWeeklyReportsForUser(
projectName: string,
token: string,
): Promise<APIResponse<WeeklyReport[]>>;
/** Gets all the projects of a user*/
getUserProjects(token: string): Promise<APIResponse<Project[]>>;
/** Gets a project from id*/
getProject(id: number): Promise<APIResponse<Project>>;
/** Gets a project from id*/
getAllUsers(token: string): Promise<APIResponse<string[]>>;
}
// Export an instance of the API
export const api: API = {
async registerUser(user: NewUser): Promise<APIResponse<User>> {
try {
const response = await fetch("/api/register", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(user),
});
if (!response.ok) {
return {
success: false,
message: "Failed to register user: " + response.status,
};
} else {
// const data = (await response.json()) as User; // The API does not currently return the user
return { success: true };
}
} catch (e) {
return {
success: false,
message: "Unknown error while registering user",
};
}
},
async removeUser(
username: string,
token: string,
): Promise<APIResponse<User>> {
try {
const response = await fetch(`/api/userdelete/${username}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + token,
},
body: JSON.stringify(username),
});
if (!response.ok) {
return { success: false, message: "Failed to remove user" };
} else {
const data = (await response.json()) as User;
return { success: true, data };
}
} catch (e) {
return { success: false, message: "Failed to remove user" };
}
},
async checkIfProjectManager(
username: string,
projectName: string,
token: string,
): Promise<APIResponse<boolean>> {
try {
const response = await fetch("/api/checkIfProjectManager", {
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + token,
},
body: JSON.stringify({ username, projectName }),
});
if (!response.ok) {
return {
success: false,
message: "Failed to check if project manager",
};
} else {
const data = (await response.json()) as boolean;
return { success: true, data };
}
} catch (e) {
return { success: false, message: "fuck" };
}
},
async createProject(
project: NewProject,
token: string,
): Promise<APIResponse<Project>> {
try {
const response = await fetch("/api/project", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + token,
},
body: JSON.stringify(project),
});
if (!response.ok) {
return { success: false, message: "Failed to create project" };
} else {
const data = (await response.json()) as Project;
return { success: true, data };
}
} catch (e) {
return { success: false, message: "Failed to create project" };
}
},
async renewToken(token: string): Promise<APIResponse<string>> {
try {
const response = await fetch("/api/loginrenew", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + token,
},
});
if (!response.ok) {
return { success: false, message: "Failed to renew token" };
} else {
const data = (await response.json()) as string;
return { success: true, data };
}
} catch (e) {
return { success: false, message: "Failed to renew token" };
}
},
async getUserProjects(token: string): Promise<APIResponse<Project[]>> {
try {
const response = await fetch("/api/getUserProjects", {
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + token,
},
});
if (!response.ok) {
return Promise.resolve({
success: false,
message: "Failed to get user projects",
});
} else {
const data = (await response.json()) as Project[];
return Promise.resolve({ success: true, data });
}
} catch (e) {
return Promise.resolve({
success: false,
message: "API fucked",
});
}
},
async submitWeeklyReport(
weeklyReport: NewWeeklyReport,
token: string,
): Promise<APIResponse<NewWeeklyReport>> {
try {
const response = await fetch("/api/submitWeeklyReport", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + token,
},
body: JSON.stringify(weeklyReport),
});
if (!response.ok) {
return {
success: false,
message: "Failed to submit weekly report",
};
}
const data = (await response.json()) as NewWeeklyReport;
return { success: true, data };
} catch (e) {
return {
success: false,
message: "Failed to submit weekly report",
};
}
},
async getWeeklyReport(
username: string,
projectName: string,
week: string,
token: string,
): Promise<APIResponse<WeeklyReport>> {
try {
const response = await fetch("/api/getWeeklyReport", {
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + token,
},
body: JSON.stringify({ username, projectName, week }),
});
if (!response.ok) {
return { success: false, message: "Failed to get weekly report" };
} else {
const data = (await response.json()) as WeeklyReport;
return { success: true, data };
}
} catch (e) {
return { success: false, message: "Failed to get weekly report" };
}
},
async getWeeklyReportsForUser(
projectName: string,
token: string,
): Promise<APIResponse<WeeklyReport[]>> {
try {
const response = await fetch(`/api/getWeeklyReportsUser/${projectName}`, {
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + token,
},
});
if (!response.ok) {
return {
success: false,
message:
"Failed to get weekly reports for project: Response code " +
response.status,
};
} else {
const data = (await response.json()) as WeeklyReport[];
return { success: true, data };
}
} catch (e) {
return {
success: false,
message: "Failed to get weekly reports for project, unknown error",
};
}
},
async login(NewUser: NewUser): Promise<APIResponse<string>> {
try {
const response = await fetch("/api/login", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(NewUser),
});
if (!response.ok) {
return { success: false, message: "Failed to login" };
} else {
const data = (await response.json()) as { token: string }; // Update the type of 'data'
return { success: true, data: data.token };
}
} catch (e) {
return Promise.resolve({ success: false, message: "Failed to login" });
}
},
// Gets a projet by id, currently untested since we have no javascript-based tests
async getProject(id: number): Promise<APIResponse<Project>> {
try {
const response = await fetch(`/api/project/${id}`, {
method: "GET",
});
if (!response.ok) {
return {
success: false,
message: "Failed to get project: Response code " + response.status,
};
} else {
const data = (await response.json()) as Project;
return { success: true, data };
}
// The code below is garbage but satisfies the linter
// This needs fixing, do not copy this pattern
} catch (e: unknown) {
return {
success: false,
message: "Failed to get project: " + (e as Error).toString(),
};
}
},
// Gets all users
async getAllUsers(token: string): Promise<APIResponse<string[]>> {
try {
const response = await fetch("/api/users/all", {
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + token,
},
});
if (!response.ok) {
return Promise.resolve({
success: false,
message: "Failed to get users",
});
} else {
const data = (await response.json()) as string[];
return Promise.resolve({ success: true, data });
}
} catch (e) {
return Promise.resolve({
success: false,
message: "API is not ok",
});
}
},
};