diff --git a/client/src/App.tsx b/client/src/App.tsx
index 98af57cf1..02a315b68 100644
--- a/client/src/App.tsx
+++ b/client/src/App.tsx
@@ -1,17 +1,5 @@
import "App.css"
import Navbar from "components/composite/Navbar/Navbar"
-import Home from "pages/Home"
-import About from "pages/About"
-import Register from "pages/Register"
-import Login from "pages/Login"
-import Events from "pages/Events"
-import Contact from "pages/Contact"
-import Checkout from "pages/Checkout"
-import Booking from "pages/Booking"
-import Profile from "pages/Profile"
-import Admin from "pages/Admin"
-import Thanks from "pages/Thanks"
-import AdminBookingsDetailedView from "pages/AdminBookingsDetailedView"
import { BrowserRouter as Router, Route, Routes } from "react-router-dom"
import { ThemeProvider } from "@mui/material"
import { LocalizationProvider } from "@mui/x-date-pickers"
@@ -19,6 +7,7 @@ import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"
import queryClient from "services/QueryClient"
import theme from "theme"
import { QueryClientProvider } from "@tanstack/react-query"
+import { AllRoutes, RouteProps } from "./routes/routes"
function App() {
return (
@@ -31,21 +20,15 @@ function App() {
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- }
- />
+ {AllRoutes.map(
+ (routeDetails: RouteProps, index: number) => (
+
+ )
+ )}
diff --git a/client/src/routes/routes.tsx b/client/src/routes/routes.tsx
new file mode 100644
index 000000000..19bdf4f94
--- /dev/null
+++ b/client/src/routes/routes.tsx
@@ -0,0 +1,33 @@
+import AdminBookingDetails from "components/composite/AdminBookingDetails/AdminBookingDetails"
+import About from "pages/About"
+import Admin from "pages/Admin"
+import Booking from "pages/Booking"
+import Checkout from "pages/Checkout"
+import Contact from "pages/Contact"
+import Events from "pages/Events"
+import Home from "pages/Home"
+import Login from "pages/Login"
+import Profile from "pages/Profile"
+import Register from "pages/Register"
+import Thanks from "pages/Thanks"
+import { JSX } from "react"
+
+export interface RouteProps {
+ path: string
+ element: JSX.Element
+}
+
+export const AllRoutes: RouteProps[] = [
+ { path: "/", element: },
+ { path: "/about", element: },
+ { path: "/events", element: },
+ { path: "/contact", element: },
+ { path: "/register", element: },
+ { path: "/login", element: },
+ { path: "/checkout", element: },
+ { path: "/booking", element: },
+ { path: "/profile", element: },
+ { path: "/admin", element: },
+ { path: "/thanks", element: },
+ { path: "/admin/bookings", element: }
+]
diff --git a/server/src/business-layer/services/AuthService.test.ts b/server/src/business-layer/services/AuthService.test.ts
new file mode 100644
index 000000000..c2162df12
--- /dev/null
+++ b/server/src/business-layer/services/AuthService.test.ts
@@ -0,0 +1,39 @@
+import { auth } from "business-layer/security/Firebase"
+import AuthService from "./AuthService"
+import { UserRecord } from "firebase-admin/auth"
+
+describe("AuthService Integration Tests", () => {
+ it("deletes a user", async () => {
+ await auth.createUser({ uid: "test" })
+ new AuthService().deleteUser("test")
+ let user
+ try {
+ user = await auth.getUser("test")
+ } catch {}
+ expect(user).toBe(undefined)
+ })
+
+ it("creates a user", async () => {
+ const createdUser = await new AuthService().createUser("test@gmail.com")
+ let user
+ try {
+ user = await auth.getUser(createdUser.uid)
+ } catch {}
+ expect(createdUser).toEqual(user)
+ expect(user.email).toEqual("test@gmail.com")
+ })
+
+ it("sets custom claim on a user", async () => {
+ const authService: AuthService = new AuthService()
+ let createdUser: UserRecord = await authService.createUser("test2@mail.com")
+
+ try {
+ await authService.setCustomUserClaim(createdUser.uid, "member")
+ } catch {}
+
+ // refresh user record to get access to newly added custom claim
+ createdUser = await auth.getUser(createdUser.uid)
+
+ expect(createdUser.customClaims.member).not.toBe(undefined)
+ })
+})
diff --git a/server/src/business-layer/services/AuthService.ts b/server/src/business-layer/services/AuthService.ts
new file mode 100644
index 000000000..f60cd4f72
--- /dev/null
+++ b/server/src/business-layer/services/AuthService.ts
@@ -0,0 +1,50 @@
+import { UserRecord } from "firebase-admin/auth"
+import { auth } from "business-layer/security/Firebase"
+import { AuthServiceClaims } from "business-layer/utils/AuthServiceClaims"
+
+export default class AuthService {
+ /**
+ * Deletes a user account from the Firebase Authentication Service.
+ * @param uid
+ */
+ public async deleteUser(uid: string): Promise {
+ try {
+ await auth.deleteUser(uid)
+ } catch (err) {
+ console.error("Error deleting user", err)
+ throw err
+ }
+ }
+
+ /**
+ * Creates a new user account in the Firebase Authentication Service.
+ * @param args
+ * @param claimRole
+ */
+ public async createUser(email: string): Promise {
+ // get the user record
+ let userRecord: UserRecord
+ try {
+ userRecord = await auth.createUser({ email })
+ } catch (err) {
+ console.error("Error creating user", err)
+ throw err
+ }
+
+ return userRecord
+ }
+
+ public async setCustomUserClaim(
+ uid: string,
+ role: typeof AuthServiceClaims.MEMBER | typeof AuthServiceClaims.ADMIN
+ ) {
+ let userRecord: UserRecord
+ try {
+ userRecord = await auth.getUser(uid)
+ auth.setCustomUserClaims(userRecord.uid, { [role]: true })
+ } catch (err) {
+ console.error("Error setting custom claim on user", err)
+ throw err
+ }
+ }
+}
diff --git a/server/src/business-layer/utils/AuthServiceClaims.ts b/server/src/business-layer/utils/AuthServiceClaims.ts
new file mode 100644
index 000000000..8cc7b2b38
--- /dev/null
+++ b/server/src/business-layer/utils/AuthServiceClaims.ts
@@ -0,0 +1,4 @@
+export const AuthServiceClaims = {
+ MEMBER: "member",
+ ADMIN: "admin"
+} as const