Compare commits

..

1 Commits

Author SHA1 Message Date
mubbsharanwar
3fcf7dea07 fix: password reset redirection
fix authenticated user redirects to 404 if token is invalide for password reset
VAN-2052
2024-08-23 11:40:29 +05:00
22 changed files with 10368 additions and 4207 deletions

1
.github/CODEOWNERS vendored
View File

@@ -1 +0,0 @@
* @openedx/2U-infinity

View File

@@ -25,5 +25,5 @@ Include a link to the sandbox for design changes or screenshot for before and af
#### Post-merge Checklist
* [ ] Deploy the changes to prod after verifying on stage or ask **@openedx/2u-infinity** to do it.
* [ ] Deploy the changes to prod after verifying on stage or ask **@openedx/2u-vanguards** to do it.
* [ ] 🎉 🙌 Celebrate! Thanks for your contribution.

View File

@@ -11,17 +11,16 @@ on:
jobs:
tests:
runs-on: ubuntu-20.04
strategy:
matrix:
node: [18, 20]
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Nodejs Env
run: echo "NODE_VER=`cat .nvmrc`" >> $GITHUB_ENV
- name: Setup Nodejs
uses: actions/setup-node@v4
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
node-version: ${{ env.NODE_VER }}
- name: Install Dependencies
run: npm ci
@@ -42,7 +41,4 @@ jobs:
run: npm run build
- name: Run Code Coverage
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: true
uses: codecov/codecov-action@v3

View File

@@ -10,4 +10,4 @@ on:
jobs:
version-check:
uses: openedx/.github/.github/workflows/lockfileversion-check-v3.yml@master
uses: openedx/.github/.github/workflows/lockfile-check.yml@master

2
.nvmrc
View File

@@ -1 +1 @@
20
18

View File

@@ -1,2 +1,2 @@
# The following users are the owners of all frontend-app-authn files
* @openedx/2u-infinity
* @openedx/2u-vanguards

View File

@@ -187,7 +187,7 @@ All community members are expected to follow the `Open edX Code of Conduct <http
People
======
The assigned maintainers for this component and other project details may be
found in `Backstage <https://backstage.openedx.org/catalog/default/group/2u-infinity>`_. Backstage pulls this data from the ``catalog-info.yaml``
found in `Backstage <https://backstage.openedx.org/catalog/default/group/2u-vanguards>`_. Backstage pulls this data from the ``catalog-info.yaml``
file in this repo.
Reporting Security Issues

View File

@@ -13,6 +13,6 @@ metadata:
annotations:
openedx.org/arch-interest-groups: ""
spec:
owner: group:2u-infinity
owner: group:2u-vanguards
type: 'service'
lifecycle: 'production'

View File

@@ -3,6 +3,6 @@
nick: Authn MFE
oeps: {}
owner: openedx/2u-infinity
owner: openedx/2u-vanguards
openedx-release:
ref: master

14360
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -33,12 +33,12 @@
},
"dependencies": {
"@edx/brand": "npm:@openedx/brand-openedx@^1.2.2",
"@edx/frontend-platform": "^8.0.0",
"@edx/frontend-platform": "7.1.3",
"@edx/openedx-atlas": "^0.6.0",
"@fortawesome/fontawesome-svg-core": "6.6.0",
"@fortawesome/free-brands-svg-icons": "6.6.0",
"@fortawesome/free-solid-svg-icons": "6.6.0",
"@fortawesome/react-fontawesome": "0.2.2",
"@fortawesome/fontawesome-svg-core": "6.5.2",
"@fortawesome/free-brands-svg-icons": "6.5.2",
"@fortawesome/free-solid-svg-icons": "6.5.2",
"@fortawesome/react-fontawesome": "0.2.0",
"@openedx/paragon": "^22.1.1",
"@optimizely/react-sdk": "^2.9.1",
"@redux-devtools/extension": "3.3.0",
@@ -47,9 +47,9 @@
"algoliasearch": "^4.14.3",
"algoliasearch-helper": "^3.14.0",
"classnames": "2.5.1",
"core-js": "3.38.1",
"core-js": "3.36.1",
"fastest-levenshtein": "1.0.16",
"form-urlencoded": "6.1.5",
"form-urlencoded": "6.1.4",
"prop-types": "15.8.1",
"query-string": "7.1.3",
"react": "^17.0.2",
@@ -58,10 +58,10 @@
"react-loading-skeleton": "3.4.0",
"react-redux": "7.2.9",
"react-responsive": "8.2.0",
"react-router": "6.26.1",
"react-router-dom": "6.26.1",
"react-router": "6.22.3",
"react-router-dom": "6.22.3",
"react-zendesk": "^0.1.13",
"redux": "4.2.1",
"redux": "4.2.0",
"redux-logger": "3.0.6",
"redux-mock-store": "1.5.4",
"redux-saga": "1.3.0",
@@ -73,8 +73,8 @@
"devDependencies": {
"@edx/browserslist-config": "^1.1.1",
"@edx/reactifex": "1.1.0",
"@openedx/frontend-build": "^14.0.3",
"babel-plugin-formatjs": "10.5.16",
"@openedx/frontend-build": "13.1.4",
"babel-plugin-formatjs": "10.5.14",
"eslint-plugin-import": "2.29.1",
"glob": "7.2.3",
"history": "5.3.0",

View File

@@ -5,8 +5,8 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="<%=htmlWebpackPlugin.options.FAVICON_URL%>" type="image/x-icon"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/4.4.4/iframeResizer.contentWindow.min.js"
integrity="sha512-IWwZFBvHzN41wNI6etRLLuLrDDj/6AwJcPt7cmKJAzluYTIHHQ1PF8wh0rSy05jxEvvjflVvH2MxeV6riyEEXg=="
<script src="https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/4.3.9/iframeResizer.contentWindow.min.js"
integrity="sha512-mdT/HQRzoRP4laVz49Mndx6rcCGA3IhuyhP3gaY0E9sZPkwbtDk9ttQIq9o8qGCf5VvJv1Xsy3k2yTjfUoczqw=="
crossorigin="anonymous"
referrerpolicy="no-referrer">
</script>

View File

@@ -5,13 +5,14 @@ import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { render } from '@testing-library/react';
import { act } from 'react-dom/test-utils';
import {
MemoryRouter, Route, BrowserRouter as Router, Routes,
} from 'react-router-dom';
import { PAGE_NOT_FOUND, REGISTER_EMBEDDED_PAGE } from '../../data/constants';
import EmbeddedRegistrationRoute from '../EmbeddedRegistrationRoute';
import {
MemoryRouter, Route, BrowserRouter as Router, Routes,
} from 'react-router-dom';
const RRD = require('react-router-dom');
// Just render plain div with its children
// eslint-disable-next-line react/prop-types

View File

@@ -5,13 +5,14 @@ import React from 'react';
import { fetchAuthenticatedUser, getAuthenticatedUser } from '@edx/frontend-platform/auth';
import { render } from '@testing-library/react';
import { act } from 'react-dom/test-utils';
import {
MemoryRouter, Route, BrowserRouter as Router, Routes,
} from 'react-router-dom';
import { UnAuthOnlyRoute } from '..';
import { REGISTER_PAGE } from '../../data/constants';
import {
MemoryRouter, Route, BrowserRouter as Router, Routes,
} from 'react-router-dom';
jest.mock('@edx/frontend-platform/auth', () => ({
getAuthenticatedUser: jest.fn(),
fetchAuthenticatedUser: jest.fn(),

View File

@@ -66,14 +66,14 @@ exports[`SocialAuthProviders should match social auth provider with iconClass sn
data-prefix="fab"
focusable="false"
role="img"
style={{}}
style={Object {}}
viewBox="0 0 488 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M488 261.8C488 403.3 391.1 504 248 504 110.8 504 0 393.2 0 256S110.8 8 248 8c66.8 0 123 24.5 166.3 64.9l-67.5 64.9C258.5 52.6 94.3 116.6 94.3 256c0 86.5 69.1 156.6 153.7 156.6 98.2 0 135-70.4 140.8-106.9H248v-85.3h236.1c2.3 12.7 3.9 24.9 3.9 41.4z"
fill="currentColor"
style={{}}
style={Object {}}
/>
</svg>
</div>
@@ -93,7 +93,7 @@ exports[`SocialAuthProviders should match social auth provider with iconClass sn
`;
exports[`SocialAuthProviders should match social auth provider with iconImage snapshot 1`] = `
[
Array [
<button
className="btn-social btn-oa2-apple-id mr-3"
data-provider-url="/auth/login/apple-id/?auth_entry=login&next=/dashboard"

View File

@@ -21,7 +21,7 @@ exports[`ThirdPartyAuthAlert should match login page third party auth alert mess
`;
exports[`ThirdPartyAuthAlert should match register page third party auth alert message snapshot 1`] = `
[
Array [
<div
className="fade alert-content alert-success mt-n2 mb-5 alert show"
id="tpa-alert"

View File

@@ -5,23 +5,23 @@ exports[`Zendesk Help should match login page third party auth alert message sna
cookies={true}
defer={true}
webWidget={
{
"answerBot": {
"avatar": {
"name": {
Object {
"answerBot": Object {
"avatar": Object {
"name": Object {
"*": "edX Support",
},
"url": undefined,
},
"contactOnlyAfterQuery": true,
"suppress": false,
"title": {
"title": Object {
"*": "edX Support",
},
},
"chat": {
"departments": {
"enabled": [
"chat": Object {
"departments": Object {
"enabled": Array [
"account settings",
"billing and payments",
"certificates",
@@ -33,17 +33,17 @@ exports[`Zendesk Help should match login page third party auth alert message sna
},
"suppress": false,
},
"contactForm": {
"contactForm": Object {
"attachments": true,
"selectTicketForm": {
"selectTicketForm": Object {
"*": "Please choose your request type:",
},
"ticketForms": [
{
"fields": [
{
"ticketForms": Array [
Object {
"fields": Array [
Object {
"id": "description",
"prefill": {
"prefill": Object {
"*": "",
},
},
@@ -53,10 +53,10 @@ exports[`Zendesk Help should match login page third party auth alert message sna
},
],
},
"contactOptions": {
"contactOptions": Object {
"enabled": false,
},
"helpCenter": {
"helpCenter": Object {
"originalArticleButton": true,
},
}

View File

@@ -188,7 +188,7 @@ describe('RegistrationPage', () => {
password: 'password1',
country: 'Pakistan',
honor_code: true,
total_registration_time: 0,
totalRegistrationTime: 0,
next: '/course/demo-course-url',
app_name: APP_NAME,
};
@@ -212,7 +212,7 @@ describe('RegistrationPage', () => {
country: 'Pakistan',
honor_code: true,
social_auth_provider: 'Apple',
total_registration_time: 0,
totalRegistrationTime: 0,
app_name: APP_NAME,
};
@@ -246,7 +246,7 @@ describe('RegistrationPage', () => {
password: 'password1',
country: 'Ukraine',
honor_code: true,
total_registration_time: 0,
totalRegistrationTime: 0,
};
store.dispatch = jest.fn(store.dispatch);
@@ -271,7 +271,7 @@ describe('RegistrationPage', () => {
password: 'password1',
country: 'Ukraine',
honor_code: true,
total_registration_time: 0,
totalRegistrationTime: 0,
};
store.dispatch = jest.fn(store.dispatch);
@@ -297,7 +297,7 @@ describe('RegistrationPage', () => {
password: 'password1',
country: 'Pakistan',
honor_code: true,
total_registration_time: 0,
totalRegistrationTime: 0,
marketing_emails_opt_in: true,
app_name: APP_NAME,
};
@@ -325,7 +325,7 @@ describe('RegistrationPage', () => {
password: 'password1',
country: 'Pakistan',
honor_code: true,
total_registration_time: 0,
totalRegistrationTime: 0,
app_name: APP_NAME,
};
@@ -891,7 +891,7 @@ describe('RegistrationPage', () => {
email: 'john.doe@example.com',
country: 'PK',
social_auth_provider: 'Apple',
total_registration_time: 0,
totalRegistrationTime: 0,
app_name: APP_NAME,
}));
});

View File

@@ -40,10 +40,7 @@ const ConfigurableRegistrationForm = (props) => {
States' instead of 'United States of America' which does not exist in country dropdown list and gets the user
confused and unable to create an account. So we added the United States entry in the dropdown list.
*/
const countryList = useMemo(() => (
getCountryList(getLocale()).concat([{ code: 'US', name: 'United States' }]).filter(country => country.code !== 'RU')
), []);
const countryList = useMemo(() => getCountryList(getLocale()).concat([{ code: 'US', name: 'United States' }]), []);
let showTermsOfServiceAndHonorCode = false;
let showCountryField = false;

View File

@@ -251,7 +251,7 @@ describe('ConfigurableRegistrationForm', () => {
country: 'Pakistan',
honor_code: true,
profession: 'Engineer',
total_registration_time: 0,
totalRegistrationTime: 0,
};
store.dispatch = jest.fn(store.dispatch);
@@ -362,7 +362,7 @@ describe('ConfigurableRegistrationForm', () => {
password: 'password1',
country: 'Ukraine',
honor_code: true,
total_registration_time: 0,
totalRegistrationTime: 0,
};
store = mockStore({

View File

@@ -1,77 +0,0 @@
import { isFormValid } from '../utils';
describe('Payload validation', () => {
let formatMessage;
let configurableFormFields;
let fieldDescriptions;
beforeEach(() => {
formatMessage = jest.fn(msg => msg);
configurableFormFields = {
confirm_email: true,
};
fieldDescriptions = {};
});
test('validates name field correctly', () => {
const payload = { name: ' ' };
const errors = {};
const { isValid, fieldErrors } = isFormValid(
payload,
errors,
configurableFormFields,
fieldDescriptions,
formatMessage);
expect(fieldErrors.name).toBeDefined();
expect(isValid).toBe(false);
});
test('validates email field correctly', () => {
const payload = { email: 'invalid-email' };
const errors = {};
const { isValid, fieldErrors } = isFormValid(
payload, errors, configurableFormFields, fieldDescriptions, formatMessage);
expect(fieldErrors.email).toBeDefined();
expect(isValid).toBe(false);
});
test('validates username field correctly', () => {
const payload = { username: 'invalid username' };
const errors = {};
const { isValid, fieldErrors } = isFormValid(
payload, errors, configurableFormFields, fieldDescriptions, formatMessage);
expect(fieldErrors.username).toBeDefined();
expect(isValid).toBe(false);
});
test('validates password field correctly', () => {
const payload = { password: 'short' };
const errors = {};
const { isValid, fieldErrors } = isFormValid(
payload, errors, configurableFormFields, fieldDescriptions, formatMessage);
expect(fieldErrors.password).toBeDefined();
expect(isValid).toBe(false);
});
test('validates multiple fields correctly', () => {
const payload = {
name: 'InvalidName!',
email: 'invalid-email',
username: 'invalid username',
password: 'short',
};
const errors = {};
const { isValid, fieldErrors } = isFormValid(
payload, errors, configurableFormFields, fieldDescriptions, formatMessage);
expect(fieldErrors.name).toBeDefined();
expect(fieldErrors.email).toBeDefined();
expect(fieldErrors.username).toBeDefined();
expect(fieldErrors.password).toBeDefined();
expect(isValid).toBe(false);
});
});

View File

@@ -126,8 +126,8 @@ export const prepareRegistrationPayload = (
delete payload.marketingEmailsOptIn;
}
payload.totalRegistrationTime = totalRegistrationTime;
payload = snakeCaseObject(payload);
payload.totalRegistrationTime = totalRegistrationTime;
// add query params to the payload
payload = { ...payload, ...queryParams };