Skip to content

Commit

Permalink
format files; fix cypress tsconfig
Browse files Browse the repository at this point in the history
  • Loading branch information
HuzzNZ committed Apr 25, 2024
1 parent c7c98b6 commit fc428f9
Show file tree
Hide file tree
Showing 10 changed files with 224 additions and 228 deletions.
2 changes: 1 addition & 1 deletion cypress/e2e/authentication.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import authSuccessResponse1 from "../fixtures/authSuccessResponse1.json";
import authSuccessResponse2 from "../fixtures/authSuccessResponse2.json";
import authSuccessRequestHeaders from "../fixtures/authSuccessRequestHeaders.json";

import { URLS } from "@/../../frontend/app/consts";
import { URLS } from "../../frontend/app/consts";

describe("Authentication", () => {
describe("login", () => {
Expand Down
77 changes: 38 additions & 39 deletions frontend/app/(cms)/(auth)/login/page.tsx
Original file line number Diff line number Diff line change
@@ -1,47 +1,46 @@
"use client";
"use client"

import { useAuth } from "@/app/cms-authentication/AuthContext";
import React, { useState } from "react";
import { useAuth } from "@/app/cms-authentication/AuthContext"
import React, { useState } from "react"

export default function Login() {
const { login } = useAuth();
const [emailInput, setEmailInput] = useState("");
const [passwordInput, setPasswordInput] = useState("");
const [errorMessage, setErrorMessage] = useState(null);
const { login } = useAuth()
const [emailInput, setEmailInput] = useState("")
const [passwordInput, setPasswordInput] = useState("")
const [errorMessage, setErrorMessage] = useState(null)

return (
<form className="flex flex-col items-start gap-4">
<label>
<span className="form-label">Email</span>
<input
className="form-input"
value={emailInput}
onChange={(e) => setEmailInput(e.target.value)}
type="text"
/>
</label>
return (
<form className="flex flex-col items-start gap-4">
<label>
<span className="form-label">Email</span>
<input
className="form-input"
value={emailInput}
onChange={(e) => setEmailInput(e.target.value)}
type="text"
/>
</label>

<label>
<span className="form-label">Password</span>
<input
className="form-input"
value={passwordInput}
onChange={(e) => setPasswordInput(e.target.value)}
type="password"
/>
</label>
<label>
<span className="form-label">Password</span>
<input
className="form-input"
value={passwordInput}
onChange={(e) => setPasswordInput(e.target.value)}
type="password"
/>
</label>

<button
className="button"
onClick={(e) => {
e.preventDefault();
<button
className="button"
onClick={(e) => {
e.preventDefault()

setErrorMessage(login(emailInput, passwordInput)); // login returns undefined or error message
}}
>
Login
</button>
{errorMessage && <p className="form-error">{errorMessage}</p>}
</form>
);
setErrorMessage(login(emailInput, passwordInput)) // login returns undefined or error message
}}>
Login
</button>
{errorMessage && <p className="form-error">{errorMessage}</p>}
</form>
)
}
44 changes: 22 additions & 22 deletions frontend/app/(cms)/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
"use client";
"use client"

import React from "react";
import AuthProvider, { useAuth } from "@/app/cms-authentication/AuthContext";
import React from "react"
import AuthProvider, { useAuth } from "@/app/cms-authentication/AuthContext"

export default function CMSLayout({ children }: { children: React.ReactNode }) {
return (
<AuthProvider>
<CMSLayoutWithAuth>{children}</CMSLayoutWithAuth>
</AuthProvider>
);
return (
<AuthProvider>
<CMSLayoutWithAuth>{children}</CMSLayoutWithAuth>
</AuthProvider>
)
}

function CMSLayoutWithAuth({ children }: { children: React.ReactNode }) {
const { currentUser, logout } = useAuth();
const { currentUser, logout } = useAuth()

return (
<div>
{currentUser && (
<>
<p>Logged in as Admin</p>
<button className="button" onClick={logout}>
Logout
</button>
</>
)}
return (
<div>
{currentUser && (
<>
<p>Logged in as Admin</p>
<button className="button" onClick={logout}>
Logout
</button>
</>
)}

{children}
</div>
);
{children}
</div>
)
}
2 changes: 1 addition & 1 deletion frontend/app/(content)/news/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import ButtonLink from "@/app/components/ButtonLink"
import { getMetadata } from "@/app/util"

// 👇 so npm run build passes (don't attempt to static render this page)
export const dynamic = "force-dynamic";
export const dynamic = "force-dynamic"

export const metadata = getMetadata("All News")

Expand Down
4 changes: 2 additions & 2 deletions frontend/app/(content)/research/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import ButtonLink from "@/app/components/ButtonLink"
import { getMetadata } from "@/app/util"

// 👇 so npm run build passes (don't attempt to static render this page)
export const dynamic = "force-dynamic";
export const dynamic = "force-dynamic"

export const metadata = getMetadata("All Research");
export const metadata = getMetadata("All Research")

export default async function AllResearchPage() {
const research = new Paginator(
Expand Down
178 changes: 83 additions & 95 deletions frontend/app/cms-authentication/AuthContext.tsx
Original file line number Diff line number Diff line change
@@ -1,112 +1,100 @@
import React, { useContext, useState, useEffect } from "react";
import React, { useContext, useState, useEffect } from "react"
import {
AuthenticationDetails,
CognitoUser,
CognitoUserPool,
CognitoUserSession,
CognitoIdToken,
} from "amazon-cognito-identity-js";
import { redirect } from "next/navigation";
import { OPEN_CMS_ROUTES, ROUTES } from "@/app/consts";
AuthenticationDetails,
CognitoUser,
CognitoUserPool,
CognitoUserSession,
CognitoIdToken,
} from "amazon-cognito-identity-js"
import { redirect } from "next/navigation"
import { OPEN_CMS_ROUTES, ROUTES } from "@/app/consts"

type AuthContextValue = {
currentUser: null | CognitoIdToken["payload"];
login: any;
logout: any;
};
currentUser: null | CognitoIdToken["payload"]
login: any
logout: any
}

// where to authenticate users from
const adminUserPool = new CognitoUserPool({
ClientId: "7dv8g7lsl2ht3uv29q9npt0a84",
UserPoolId: "us-east-1_1GuGm8wMs",
});
ClientId: "7dv8g7lsl2ht3uv29q9npt0a84",
UserPoolId: "us-east-1_1GuGm8wMs",
})

const AuthContext = React.createContext({
currentUser: null,
login: () => {},
} as AuthContextValue);
currentUser: null,
login: () => {},
} as AuthContextValue)

export function useAuth() {
return useContext(AuthContext);
return useContext(AuthContext)
}

export default function AuthProvider({ children }: React.PropsWithChildren) {
const [currentUserSession, setCurrentUserSession] = useState(
null as AuthContextValue["currentUser"]
);
const [loading, setLoading] = useState(true);

useEffect(() => {
const currentUser = adminUserPool.getCurrentUser();

if (!currentUser) return setLoading(false);

currentUser.getSession(
(error: Error | null, session: CognitoUserSession | null) => {
error && console.log("Error in getting user session:", error);
session && setCurrentUserSession(session.getIdToken().payload);
setLoading(false);
}
);
}, []);

useEffect(() => {
if (loading) return; // we don't know if user is logged in or not

const currentRoute = window.location.pathname;

if (!currentUserSession && !OPEN_CMS_ROUTES.includes(currentRoute))
redirect(OPEN_CMS_ROUTES[0]);

if (currentUserSession && OPEN_CMS_ROUTES.includes(currentRoute))
redirect(ROUTES.REDIRECT_AFTER_LOGIN);
}, [currentUserSession, loading]);

// returns the error if there is one
// if login successful, returns void but sets the current user
async function login(email: string, password: string) {
const user = new CognitoUser({
Username: email,
Pool: adminUserPool,
});

const authDetails = new AuthenticationDetails({
Username: email,
Password: password,
});

try {
const result: CognitoUserSession = await new Promise(
(resolve, reject) => {
user.authenticateUser(authDetails, {
onSuccess: resolve,
onFailure: reject,
});
const [currentUserSession, setCurrentUserSession] = useState(null as AuthContextValue["currentUser"])
const [loading, setLoading] = useState(true)

useEffect(() => {
const currentUser = adminUserPool.getCurrentUser()

if (!currentUser) return setLoading(false)

currentUser.getSession((error: Error | null, session: CognitoUserSession | null) => {
error && console.log("Error in getting user session:", error)
session && setCurrentUserSession(session.getIdToken().payload)
setLoading(false)
})
}, [])

useEffect(() => {
if (loading) return // we don't know if user is logged in or not

const currentRoute = window.location.pathname

if (!currentUserSession && !OPEN_CMS_ROUTES.includes(currentRoute)) redirect(OPEN_CMS_ROUTES[0])

if (currentUserSession && OPEN_CMS_ROUTES.includes(currentRoute)) redirect(ROUTES.REDIRECT_AFTER_LOGIN)
}, [currentUserSession, loading])

// returns the error if there is one
// if login successful, returns void but sets the current user
async function login(email: string, password: string) {
const user = new CognitoUser({
Username: email,
Pool: adminUserPool,
})

const authDetails = new AuthenticationDetails({
Username: email,
Password: password,
})

try {
const result: CognitoUserSession = await new Promise((resolve, reject) => {
user.authenticateUser(authDetails, {
onSuccess: resolve,
onFailure: reject,
})
})

setCurrentUserSession(result.getIdToken().payload)
} catch (error: any) {
console.error("Login failed:", { error })
return error.message
}
);
}

setCurrentUserSession(result.getIdToken().payload);
} catch (error: any) {
console.error("Login failed:", { error });
return error.message;
function logout() {
adminUserPool.getCurrentUser()?.signOut()
setCurrentUserSession(null)
}
}

function logout() {
adminUserPool.getCurrentUser()?.signOut();
setCurrentUserSession(null);
}

// expose useful auth methods/values
const authDetails = {
currentUser: currentUserSession,
login,
logout,
};

return (
<AuthContext.Provider value={authDetails}>
{!loading && children}
</AuthContext.Provider>
);

// expose useful auth methods/values
const authDetails = {
currentUser: currentUserSession,
login,
logout,
}

return <AuthContext.Provider value={authDetails}>{!loading && children}</AuthContext.Provider>
}
Loading

0 comments on commit fc428f9

Please sign in to comment.