Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crossfeed Registration and Approval Process #2401

Merged
merged 70 commits into from
Dec 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
49e6497
Add base Registration dialog and update login page
nickviola Nov 2, 2023
1c4f476
Update user schema backend/frontend
nickviola Nov 2, 2023
c26df4d
Remove old registration page route
nickviola Nov 2, 2023
c9a6154
Update User and Organization schema and update test-utils
nickviola Nov 8, 2023
c76f9d2
Add new package mui/x-data-grid to package.json
ameliav Nov 9, 2023
52e45c5
Update formatting for RegisterForm.tsx
ameliav Nov 9, 2023
1b0bcbc
Update formatting on AuthLogin.tsx
ameliav Nov 9, 2023
c415b85
Add Dialog folder with ConfirmDialog and InfoDialog components
ameliav Nov 9, 2023
f2a1b35
Update user and organization types in types folder
ameliav Nov 9, 2023
861fcdc
Add RegionUsers folder with files for Region Admin dashboard
ameliav Nov 9, 2023
6125b64
Update App.tsx and pages/index.ts to include RegionUsers
ameliav Nov 9, 2023
843a593
Remove unneeded comments in RegionUsers.tsx
ameliav Nov 9, 2023
79c388a
Add endpoints for user and organization by regionId and state
nickviola Nov 9, 2023
557192d
Fix eslint errors in frontend/src
nickviola Nov 13, 2023
11723de
Run npm audit fix package-lock.json
ameliav Nov 13, 2023
e550381
Add new v2 endpoint for organizations for modifying registration and …
nickviola Nov 13, 2023
a90edf7
Adding new organizations api endpoint for updating in frontend
nickviola Nov 13, 2023
8de8a7a
Add regionId to organization schema and update isRegionalAdmin permis…
nickviola Nov 13, 2023
e8867aa
Add regionId and state to validate body function
nickviola Nov 13, 2023
9f3fbb1
Add build and rebuild scripts to save time in rebuilding backend changes
nickviola Nov 14, 2023
f0c7a1d
Add HTML email delivery function to helpers.ts
JCantu248 Nov 14, 2023
156afb6
Replace orgs test data with API data in RegionUsers.tsx
ameliav Nov 14, 2023
0c89ec1
Update test organiation data to include regionId and state
nickviola Nov 14, 2023
9f16a3d
Add new v2 endpoints for orgs and users and add query filters for new…
nickviola Nov 14, 2023
90b3a64
Add sendNotificationEmail() to helpers.tst.
JCantu248 Nov 14, 2023
09b539a
Add user register endpoint for new user registrations.
nickviola Nov 15, 2023
66208c9
Fix compile errors in helpers.ts, add new dependencies.
JCantu248 Nov 15, 2023
27a0f60
Merge branch 'issue-2315/create-registration-page-and-process' into i…
JCantu248 Nov 15, 2023
d23ad7a
Add new endpoint for adding user to organization
nickviola Nov 16, 2023
7129544
Replace users test data with API data in RegionUsers.tsx
ameliav Nov 16, 2023
c3f47db
Add transformData func and update col widths in RegionUsers.tsx
ameliav Nov 17, 2023
e772e45
Modify helpers.ts, add html email template and image files.
JCantu248 Nov 20, 2023
41970ad
Add templates for user approval and denial, modifications to helpers.…
JCantu248 Nov 21, 2023
a6b8ec0
Merge branch 'issue-2315/create-registration-page-and-process' into i…
JCantu248 Nov 21, 2023
8e6004c
Add post and put API call frontend logic to RegionUsers.tsx
ameliav Nov 21, 2023
0237cae
Add POST and PUT frontend error handling in RegionUsers.tsx
ameliav Nov 21, 2023
0c94c4b
Update display heights and add regionId parameter in RegionUsers.tsx
ameliav Nov 22, 2023
8eb6960
Add delete user api frontend logic to RegionUsers.tsx
ameliav Nov 22, 2023
fc7bbcb
Update callback function name in RegionUsers.tsx
ameliav Nov 22, 2023
6ffc5c2
Add backend and frontend changes for registration of new user
nickviola Nov 27, 2023
1ff9196
Add email delivery to users.ts.
JCantu248 Nov 27, 2023
2020d4b
Merge branch 'issue-2315/create-registration-page-and-process' of git…
JCantu248 Nov 27, 2023
bcd845f
Remove usernames from list of arguments to handlebars.compile.
JCantu248 Nov 27, 2023
ed67b73
Update Register button with link in AuthLogin.tsx
ameliav Nov 28, 2023
efe0942
Add user approval and denial backend api endpoints
nickviola Nov 29, 2023
613d744
Adding frontend /registration route to complete user registration pro…
nickviola Nov 29, 2023
99c8127
Add call to approval backend api on successfully approved registration
nickviola Nov 29, 2023
587efda
Merge branch 'issue-2315/create-registration-page-and-process' into i…
JCantu248 Nov 29, 2023
b6fc48a
Add additional AuthLogin component for registration completion which …
nickviola Nov 30, 2023
6109541
Add changes to users.ts.
JCantu248 Nov 30, 2023
083dbe4
Merge branch 'issue-2315/create-registration-page-and-process' into i…
JCantu248 Nov 30, 2023
bc1a2db
Update Docker mapping and getting ready for redeployment.
JCantu248 Nov 30, 2023
33e3f7c
Update attachment image filepaths to Docker mapped location.
JCantu248 Nov 30, 2023
ecb0680
Fix yaml formatting for organizations swagger api header
nickviola Nov 30, 2023
c00eed7
Resolve merge conflicts package versions and platform outage notifica…
nickviola Nov 30, 2023
7c6359a
Fix linter issues
nickviola Nov 30, 2023
245a7cf
Fix test data linter issues
nickviola Nov 30, 2023
485b054
Fix linter issues
nickviola Nov 30, 2023
ef0c80f
Fix linter issues
nickviola Nov 30, 2023
7bfef58
Fix linter issues
nickviola Nov 30, 2023
5f6f992
Fix linter issues
nickviola Dec 1, 2023
451592e
Fix linter issues
nickviola Dec 1, 2023
aae3a91
Fix linter issues
nickviola Dec 1, 2023
bc9359a
Fix linter issues
nickviola Dec 1, 2023
1a5911f
Fix linter issues
nickviola Dec 1, 2023
a0a3747
Fix linter issues
nickviola Dec 1, 2023
a3427db
Fix linter issues
nickviola Dec 1, 2023
3f44fb8
Fix tests for 403 output
nickviola Dec 1, 2023
2db0501
Move backend/email_templates to backend/src/email_templates.
JCantu248 Dec 1, 2023
1c115d8
Fix tests linter error
nickviola Dec 1, 2023
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
1,637 changes: 1,303 additions & 334 deletions backend/package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"express": "^4.18.1",
"global-agent": "^2.2.0",
"got": "^11.8.5",
"handlebars": "^4.7.8",
"helmet": "^4.1.1",
"http-proxy-middleware": "^2.0.6",
"jsdom": "^22.1",
Expand Down
51 changes: 51 additions & 0 deletions backend/src/api/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ app.use(cookieParser());
app.get('/', handlerToExpress(healthcheck));
app.post('/auth/login', handlerToExpress(auth.login));
app.post('/auth/callback', handlerToExpress(auth.callback));
app.post('/users/register', handlerToExpress(users.register));

const checkUserLoggedIn = async (req, res, next) => {
req.requestContext = {
Expand Down Expand Up @@ -227,6 +228,7 @@ app.use(
const authenticatedNoTermsRoute = express.Router();
authenticatedNoTermsRoute.use(checkUserLoggedIn);
authenticatedNoTermsRoute.get('/users/me', handlerToExpress(users.me));
// authenticatedNoTermsRoute.post('/users/register', handlerToExpress(users.register));
authenticatedNoTermsRoute.post(
'/users/me/acceptTerms',
handlerToExpress(users.acceptTerms)
Expand Down Expand Up @@ -313,6 +315,14 @@ authenticatedRoute.get(
'/organizations/:organizationId',
handlerToExpress(organizations.get)
);
authenticatedRoute.get(
'/organizations/state/:state',
handlerToExpress(organizations.getByState)
);
authenticatedRoute.get(
'/organizations/regionId/:regionId',
handlerToExpress(organizations.getByRegionId)
);
authenticatedRoute.post(
'/organizations',
handlerToExpress(organizations.create)
Expand All @@ -325,6 +335,10 @@ authenticatedRoute.delete(
'/organizations/:organizationId',
handlerToExpress(organizations.del)
);
authenticatedRoute.post(
'/v2/organizations/:organizationId/users',
handlerToExpress(organizations.addUserV2)
);
authenticatedRoute.post(
'/organizations/:organizationId/roles/:roleId/approve',
handlerToExpress(organizations.approveRole)
Expand All @@ -349,6 +363,14 @@ authenticatedRoute.post('/stats', handlerToExpress(stats.get));
authenticatedRoute.post('/users', handlerToExpress(users.invite));
authenticatedRoute.get('/users', handlerToExpress(users.list));
authenticatedRoute.delete('/users/:userId', handlerToExpress(users.del));
authenticatedRoute.get(
'/users/state/:state',
handlerToExpress(users.getByState)
);
authenticatedRoute.get(
'/users/regionId/:regionId',
handlerToExpress(users.getByRegionId)
);
authenticatedRoute.post('/users/search', handlerToExpress(users.search));

authenticatedRoute.post(
Expand All @@ -361,6 +383,35 @@ authenticatedRoute.post(
handlerToExpress(reports.list_reports)
);

//Authenticated Registration Routes
authenticatedRoute.put(
'/users/:userId/register/approve',
handlerToExpress(users.registrationApproval)
);

authenticatedRoute.put(
'/users/:userId/register/deny',
handlerToExpress(users.registrationDenial)
);

//************* */
// V2 Routes //
//************* */

// Users
authenticatedRoute.put('/v2/users/:userId', handlerToExpress(users.updateV2));
authenticatedRoute.get('/v2/users', handlerToExpress(users.getAllV2));

// Organizations
authenticatedRoute.put(
'/v2/organizations/:organizationId',
handlerToExpress(organizations.updateV2)
);
authenticatedRoute.get(
'/v2/organizations',
handlerToExpress(organizations.getAllV2)
);

app.use(authenticatedRoute);

export default app;
9 changes: 9 additions & 0 deletions backend/src/api/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,15 @@ export const isGlobalViewAdmin = (event: APIGatewayProxyEvent) => {
: false;
};

/** Check if a user has regionalAdmin view permissions */
export const isRegionalAdmin = (event: APIGatewayProxyEvent) => {
return event.requestContext.authorizer &&
(event.requestContext.authorizer.userType === UserType.REGIONAL_ADMIN ||
event.requestContext.authorizer.userType === UserType.GLOBAL_ADMIN)
? true
: false;
};

/** Checks if the current user is allowed to access (modify) a user with id userId */
export const canAccessUser = (event: APIGatewayProxyEvent, userId?: string) => {
return userId && (userId === getUserId(event) || isGlobalWriteAdmin(event));
Expand Down
146 changes: 144 additions & 2 deletions backend/src/api/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import { ClassType } from 'class-transformer/ClassTransformer';
import { plainToClass } from 'class-transformer';
import { SES } from 'aws-sdk';
import * as nodemailer from 'nodemailer';
import * as fs from 'fs';
import * as handlebars from 'handlebars';
import * as util from 'util';

export const validateBody = async <T>(
obj: ClassType<T>,
Expand Down Expand Up @@ -71,12 +74,12 @@ export const wrapHandler: WrapHandler =

export const NotFound: APIGatewayProxyResult = {
statusCode: 404,
body: ''
body: 'Item not found. View logs for details.'
};

export const Unauthorized: APIGatewayProxyResult = {
statusCode: 403,
body: ''
body: 'Unauthorized access. View logs for details.'
};

export const sendEmail = async (
Expand All @@ -96,3 +99,142 @@ export const sendEmail = async (
replyTo: process.env.CROSSFEED_SUPPORT_EMAIL_REPLYTO!
});
};

export const sendUserNotificationEmail = async (
recepient: string,
p_subject: string,
p_firstName: string,
p_lastname: string,
template_file: string
) => {
const transporter = nodemailer.createTransport({
SES: new SES({ region: 'us-east-1' })
});

const fs = require('fs').promises;
const html = await fs.readFile(template_file, 'utf8');
const template = handlebars.compile(html);
const data = {
first_name: p_firstName,
last_name: p_lastname
};

const htmlToSend = template(data);

const mailOptions = {
from: process.env.CROSSFEED_SUPPORT_EMAIL_SENDER,
to: recepient,
subject: p_subject,
html: htmlToSend,
attachments: [
{
filename: 'banner.png',
path: '/app/src/email_templates/banner.png',
cid: 'CISA Banner'
},
{
filename: 'web.png',
path: '/app/src/email_templates/banner.png',
cid: 'CISA Web'
},
{
filename: 'email.png',
path: '/app/src/email_templates/email.png',
cid: 'CISA Email'
},
{
filename: 'linkedin.png',
path: '/app/src/email_templates/linkedin.png',
cid: 'CISA LinkedIn'
},
{
filename: 'twitter.png',
path: '/app/src/email_templates/twitter.png',
cid: 'CISA Twitter'
},
{
filename: 'facebook.png',
path: '/app/src/email_templates/facebooK.png',
cid: 'CISA Facebook'
},
{
filename: 'instagram.png',
path: '/app/src/email_templates/instagram.png',
cid: 'CISA Instagram'
}
]
};

await transporter.sendMail(mailOptions);
};

export const sendRegionalAdminNotificationEmail = async (
recepient: string,
p_subject: string,
p_firstName: string,
p_lastname: string,
p_username: string
) => {
const transporter = nodemailer.createTransport({
SES: new SES({ region: 'us-east-1' })
});

const fs = require('fs').promises;
const html = await fs.readFile(
'/app/src/email_templates/crossfeed_regional_admin_notification.html',
'utf8'
);
const template = handlebars.compile(html);
const data = {
first_name: p_firstName,
last_name: p_lastname
};

const htmlToSend = template(data);

const mailOptions = {
from: process.env.CROSSFEED_SUPPORT_EMAIL_SENDER,
to: recepient,
subject: p_subject,
html: htmlToSend,
attachments: [
{
filename: 'banner.png',
path: '/app/src/email_templates/banner.png',
cid: 'CISA Banner'
},
{
filename: 'web.png',
path: '/app/src/email_templates/banner.png',
cid: 'CISA Web'
},
{
filename: 'email.png',
path: '/app/src/email_templates/email.png',
cid: 'CISA Email'
},
{
filename: 'linkedin.png',
path: '/app/src/email_templates/linkedin.png',
cid: 'CISA LinkedIn'
},
{
filename: 'twitter.png',
path: '/app/src/email_templates/twitter.png',
cid: 'CISA Twitter'
},
{
filename: 'facebook.png',
path: '/app/src/email_templates/facebooK.png',
cid: 'CISA Facebook'
},
{
filename: 'instagram.png',
path: '/app/src/email_templates/instagram.png',
cid: 'CISA Instagram'
}
]
};

await transporter.sendMail(mailOptions);
};
Loading
Loading