Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/api/endpoints/apiService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ export const getVariants = async (group: string, term: string) => {
};

export const getVersions = async (group: string, term: string) => {
return createGetRequest<any, any>(`/${group}/versions/${term}`, "application/json")();
return createGetRequest<any, any>(`/${group}/${term}/versions`, "application/json")();
};

export const getTermDiscussions = async (group: string, variantID: string) => {
Expand Down
101 changes: 74 additions & 27 deletions src/components/Auth/Login.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,19 @@ const Login = () => {
let eventer = window[eventMethod];
let messageEvent = eventMethod === "attachEvent" ? "onmessage" : "message";
eventer(messageEvent, async function (e) {
if (!e.data || !e.data.orcid_meta) return;
const { code, cookies, groupname } = e.data;
if (code === 200 || code === 302) {
if (e.data?.source === "react-devtools-bridge") return; // Ignore messages from React DevTools
if (!(e.data?.orcid_meta || e.data?.redirect || e.data?.interlex)) return;
const { cookies } = e.data;
const { code, errors, redirect, groupname } = e.data.interlex;

if (cookies) {
const _cookies = JSON.parse(cookies);
const sessionCookie = _cookies && Object.prototype.hasOwnProperty.call(_cookies, 'session') ? _cookies['session'] : undefined;
let expires = new Date()
if (sessionCookie && (existingCookies['session'] === undefined)) {
if (sessionCookie) {
if (existingCookies['session']) {
removeCookie('session', { path: '/' });
}
expires.setTime(expires.getTime() + (2 * 24 * 60 * 60 * 1000)); // 2 days
setCookie(
'session',
Expand All @@ -65,24 +71,24 @@ const Login = () => {
}
);
}
// Check if the session cookie is present
if (!sessionCookie) {
setErrors((prev) => ({
...prev,
auth: "Session cookie not found. Please try again",
}));
return;
}
localStorage.setItem(API_CONFIG.SESSION_DATA.COOKIE, JSON.stringify({
name: 'session',
value: sessionCookie,
expires: expires
}));
localStorage.setItem("token", sessionCookie)
}

if (redirect) {
handleRedirectInPopup(redirect);
return;
}

if (code === 200 || code === 302) {
// Retrieve user settings
try {
const userData = await requestUserSettings(groupname);
localStorage.setItem(API_CONFIG.SESSION_DATA.SETTINGS, JSON.stringify(userData));
localStorage.setItem(API_CONFIG.SESSION_DATA.COOKIE, JSON.stringify({
name: 'session',
value: sessionCookie,
expires: expires
}));
localStorage.setItem("token", sessionCookie)
setUserData({
name: userData['groupname'],
id: userData['orcid'],
Expand All @@ -100,11 +106,16 @@ const Login = () => {
auth: "Failed to fetch user settings. Please try again",
}));
}
} else if (code === 401) {
setErrors((prev) => ({
...prev,
auth: "Invalid username or password. Please try again",
}));
} else if (code > 400 && code < 500) {
let errorMessage = '';
const keys = Object.keys(errors);
if (keys.length > 0) {
errorMessage = String(keys[0]) + ' ' + errors[keys[0]];
}
setErrors((prev) => ({
...prev,
auth: errorMessage || "Invalid username or password. Please try again",
}));
} else {
setErrors((prev) => ({
...prev,
Expand All @@ -116,6 +127,22 @@ const Login = () => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isLoading]);

const handleRedirectInPopup = (url) => {
setErrors({})
setIsLoading(true);
const popup = window.open(url.includes('?') ? url + "&aspopup=true" : url + "?aspopup=true", "postPopup", "width=600,height=600");
if (popup) {
// dataForm.submit();
popup.focus();
} else {
alert("Popup blocked. Please allow popups for this site.");
setErrors((prev) => ({
...prev,
auth: "Popup blocked. Please allow popups for this site.",
}));
}
}

const handleInputChange = (e) => {
const { name, value } = e.target;
setFormData((prev) => ({ ...prev, [name]: value }));
Expand All @@ -129,10 +156,30 @@ const Login = () => {

const result = await login({ username: formData.username, password: formData.password })
if (!result.data || !result.data?.orcid_meta) {
setErrors((prev) => ({
...prev,
auth: "Interlex API is not returning the user information, reminder to ask Tom to send the groupname back so that we can query the priv/setting endpoint to get the rest of the info required",
}));
// setErrors((prev) => ({
// ...prev,
// auth: "Interlex API is not returning the user information, reminder to ask Tom to send the groupname back so that we can query the priv/setting endpoint to get the rest of the info required",
// }));
try {
const userData = await requestUserSettings(formData.username);
localStorage.setItem(API_CONFIG.SESSION_DATA.SETTINGS, JSON.stringify(userData));
setUserData({
name: userData['groupname'],
id: userData['orcid'],
email: userData?.emails[0]?.email,
role: userData['own-role'],
groupname: userData['groupname'],
settings: userData
});
navigate("/")
} catch (error) {
console.error("Error fetching user settings:", error);
removeCookie('session', { path: '/' });
setErrors((prev) => ({
...prev,
auth: "Failed to fetch user settings. Please try again",
}));
}
} else {
const { code, orcid_meta } = result.data;
if (code === 200 || code === 302) {
Expand Down
82 changes: 76 additions & 6 deletions src/components/Auth/Register.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
import * as yup from "yup";
import FormField from "./UI/Formfield";
import { API_CONFIG } from "../../config";
import { useCookies } from 'react-cookie';
import PasswordField from "./UI/PasswordField";
import { ArrowBack } from "@mui/icons-material";
import { Link, useNavigate } from "react-router-dom";
Expand All @@ -22,35 +23,73 @@ const schema = yup.object().shape({
email: yup.string().email().required(),
username: yup.string().required().min(3),
password: yup.string().required().min(10),
confirmPassword: yup.string()
.required('Please confirm your password')
.oneOf([yup.ref('password'), null], 'Passwords must match'),
});

const Register = () => {
const [formData, setFormData] = React.useState({
username: "",
email: "",
password: "",
confirmPassword: "",
});

const [errors, setErrors] = React.useState({});
const [isLoading, setIsLoading] = React.useState(false);
const { setUserData } = React.useContext(GlobalDataContext);
const [existingCookies, setCookie, removeCookie] = useCookies(['session']);
const navigate = useNavigate();

React.useEffect(() => {
let eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
let eventer = window[eventMethod];
let messageEvent = eventMethod === "attachEvent" ? "onmessage" : "message";
eventer(messageEvent, function (e) {
if (!e.data || !e.data.orcid_meta) return;
const { code, orcid_meta } = e.data;
if (!(e.data?.orcid_meta || e.data?.redirect || e.data?.interlex)) return;
const { cookies } = e.data;
const { code, orcid_meta, errors, redirect } = e.data.interlex;

if (cookies) {
const _cookies = JSON.parse(cookies);
const sessionCookie = _cookies && Object.prototype.hasOwnProperty.call(_cookies, 'session') ? _cookies['session'] : undefined;
let expires = new Date()
if (sessionCookie) {
if (existingCookies['session']) {
removeCookie('session', { path: '/' });
}
expires.setTime(expires.getTime() + (2 * 24 * 60 * 60 * 1000)); // 2 days
setCookie(
'session',
sessionCookie,
{
path: '/',
secure: false,
sameSite: false,
httpOnly: false
}
);
}
}

if (redirect) {
handleRedirectInPopup(redirect);
return;
}

if (code === 200 || code === 302) {
setUserData({ name: orcid_meta.name, id: orcid_meta.orcid });
navigate("/")
} else if (code === 401) {
} else if (code > 400 && code < 500) {
let errorMessage = '';
const keys = Object.keys(errors);
if (keys.length > 0) {
errorMessage = String(keys[0]) + ' ' + errors[keys[0]];
}
setErrors((prev) => ({
...prev,
auth: "Invalid username or password. Please try again",
auth: errorMessage || "Invalid username or password. Please try again",
}));
} else {
setErrors((prev) => ({
Expand All @@ -64,6 +103,22 @@ const Register = () => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isLoading]);

const handleRedirectInPopup = (url) => {
setErrors({})
setIsLoading(true);
const popup = window.open(url.includes('?') ? url + "&aspopup=true" : url + "?aspopup=true", "postPopup", "width=600,height=600");
if (popup) {
// dataForm.submit();
popup.focus();
} else {
alert("Popup blocked. Please allow popups for this site.");
setErrors((prev) => ({
...prev,
auth: "Popup blocked. Please allow popups for this site.",
}));
}
}

const registerUser = async () => {
try {
await schema.validate(formData, { abortEarly: false })
Expand All @@ -72,7 +127,7 @@ const Register = () => {

// send a POST request to the server with the form data in a popup window
const dataForm = document.createElement("form");
dataForm.action = `${API_CONFIG.REAL_API.NEWUSER_ILX}`;
dataForm.action = `${API_CONFIG.REAL_API.NEWUSER_ILX}?from=orcid-login&aspopup=true`;
dataForm.method = "POST";
dataForm.style.display = "none";
dataForm.target = "postPopup";
Expand Down Expand Up @@ -161,9 +216,24 @@ const Register = () => {
errorMessage={errors.password}
helperText="Required"
/>
<PasswordField
label="Confirm Password"
placeholder="Re-enter your password"
value={formData.confirmPassword}
onChange={(e) =>
setFormData({ ...formData, confirmPassword: e.target.value })
}
errorMessage={errors.confirmPassword}
helperText="Passwords must match"
/>
<Grid item xs={12}>
<FormControl>
<Button variant="contained" color="primary" onClick={registerUser}>
<Button
variant="contained"
color="primary"
onClick={registerUser}
disabled={formData.password !== formData.confirmPassword || !formData.password || !formData.confirmPassword}
>
Register
</Button>
</FormControl>
Expand Down
Loading