-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
224 additions
and
228 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | ||
} |
Oops, something went wrong.