Skip to content

Commit

Permalink
Merge branch 'master' into Jimmy/isUnusedAttendanceCode-ignore-past-e…
Browse files Browse the repository at this point in the history
…vents
  • Loading branch information
yimmyj authored Apr 3, 2024
2 parents 927bd66 + c3d599c commit b409da0
Show file tree
Hide file tree
Showing 82 changed files with 3,770 additions and 329 deletions.
24 changes: 23 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,17 @@ jobs:
GIT_HASH=$(echo $CIRCLE_SHA1 | cut -c -7)
docker run caprover/cli-caprover:v2.1.1 caprover deploy --caproverUrl https://captain.caprover.acmucsd.com --caproverPassword $CAPROVER_PASS --caproverApp membership-portal-api-testing --imageName acmucsd/membership-portal-api:$GIT_HASH
docker run caprover/cli-caprover:v2.1.1 caprover deploy --caproverUrl https://captain.caprover.acmucsd.com --caproverPassword $CAPROVER_PASS --caproverApp membership-portal-api --imageName acmucsd/membership-portal-api:$GIT_HASH
deploy_staging:
environment:
GIT_HASH: $(echo $CIRCLE_SHA1 | cut -c -7)
machine:
enabled: true
steps:
- checkout
- run:
command: |
GIT_HASH=$(echo $CIRCLE_SHA1 | cut -c -7)
docker run caprover/cli-caprover:v2.1.1 caprover deploy --caproverUrl https://captain.caprover.acmucsd.com --caproverPassword $CAPROVER_PASS --caproverApp membership-portal-api-testing --imageName acmucsd/membership-portal-api:$GIT_HASH
workflows:
test_and_deploy:
Expand All @@ -133,7 +144,9 @@ workflows:
- test
filters:
branches:
only: master
only:
- master
- staging
- deploy:
requires:
- build
Expand All @@ -143,3 +156,12 @@ workflows:
filters:
branches:
only: master
- deploy_staging:
requires:
- build
- lint
- test
- image
filters:
branches:
only: staging
4 changes: 2 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ CLIENT=localhost:8000
MAX_EVENT_COVER_FILE_SIZE=
MAX_PROFILE_PICTURE_FILE_SIZE=
MAX_BANNER_FILE_SIZE=
MAX_MERCH_ITEM_PICTURE_FILE_SIZE=
MAX_MERCH_PHOTO_FILE_SIZE=
MAX_RESUME_FILE_SIZE=

PROFILE_PICTURE_UPLOAD_PATH=
EVENT_COVER_UPLOAD_PATH=
BANNER_UPLOAD_PATH=
MERCH_ITEM_PICTURE_UPLOAD_PATH=
MERCH_PHOTO_UPLOAD_PATH=
RESUME_UPLOAD_PATH=

BASE_UPLOAD_PATH=
Expand Down
2 changes: 2 additions & 0 deletions .eslintrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ env:
node: true
jest: true
rules:
"@typescript-eslint/no-misused-promises":
- "error"
"@typescript-eslint/no-unused-vars":
- "error"
- argsIgnorePattern: "type|_*"
Expand Down
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -1 +1 @@
* @sumeet-bansal @shravanhariharan2 @dowhep
* @sumeet-bansal @shravanhariharan2 @dowhep @nik-dange
47 changes: 46 additions & 1 deletion .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1 +1,46 @@
Closes #[ISSUE-NUM].
# Info

Closes **[ISSUE NUMBER]**. (If there is no issue for this pull request yet, please create one or
delete this line if the pull request is for a very minor tweak).

# Description

What changes did you make? List all distinct problems that this PR addresses. Explain any relevant
motivation or context.

[description]

## Changes

- [Fill in here]

# Type of Change

- [ ] Patch (non-breaking change/bugfix)
- [ ] Minor (non-breaking change which adds functionality)
- [ ] Major (fix or feature that would cause existing functionality to not work as
expected)
- [ ] Documentation (A change to a README/description)
- [ ] Continuous Integration/DevOps Change (Related to deployment steps, continuous integration
workflows, linting, etc.)
- [ ] Other: (Fill In) <!-- Edit this type of change if you select this -->

If you've selected Patch, Minor, or Major as your change type, **make sure to bump the version before merging in `package.json`!**
# Testing

I have tested that my changes fully resolve the linked issue ...

- [ ] locally.
- [ ] on the testing API/testing database.
- [ ] with appropriate Postman routes. Screenshots are included below.

# Checklist

- [ ] I have performed a self-review of my own code.
- [ ] I have followed the style guidelines of this project.
- [ ] I have appropriately edited the API version in the `package.json` file.
- [ ] My changes produce no new warnings.

# Screenshots

Please include a screenshot of your Postman testing passing successfully.
4 changes: 2 additions & 2 deletions .github/workflows/auto-comment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ jobs:
run:
runs-on: ubuntu-latest
steps:
- uses: bubkoo/auto-comment@v1.0.7
- uses: wow-actions/auto-comment@v1
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
pullRequestOpened: >
pullRequestOpened: |
Thanks for contributing!
If you've made changes to the API's functionality, please make sure to bump the package
version&mdash;see [this guide to semantic versioning](https://semver.org/) for details&mdash;and
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ FROM node:14.15.3-alpine
WORKDIR /app
COPY --from=build /app /app
EXPOSE 3000
CMD ["yarn", "start"]
CMD ["yarn", "release"]
22 changes: 21 additions & 1 deletion api/controllers/AdminController.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { JsonController, Post, UploadedFile, UseBefore, ForbiddenError, Body, Get } from 'routing-controllers';
import { JsonController, Post, Patch, UploadedFile, UseBefore, ForbiddenError, Body, Get } from 'routing-controllers';
import { UserAuthentication } from '../middleware/UserAuthentication';
import {
CreateBonusRequest,
CreateMilestoneRequest,
SubmitAttendanceForUsersRequest,
ModifyUserAccessLevelRequest,
} from '../validators/AdminControllerRequests';
import {
File,
Expand All @@ -13,6 +14,8 @@ import {
UploadBannerResponse,
GetAllEmailsResponse,
SubmitAttendanceForUsersResponse,
ModifyUserAccessLevelResponse,
GetAllUserAccessLevelsResponse,
} from '../../types';
import { AuthenticatedUser } from '../decorators/AuthenticatedUser';
import UserAccountService from '../../services/UserAccountService';
Expand Down Expand Up @@ -79,4 +82,21 @@ export class AdminController {
const attendances = await this.attendanceService.submitAttendanceForUsers(emails, event, asStaff, currentUser);
return { error: null, attendances };
}

@Patch('/access')
async updateUserAccessLevel(@Body() modifyUserAccessLevelRequest: ModifyUserAccessLevelRequest,
@AuthenticatedUser() currentUser: UserModel): Promise<ModifyUserAccessLevelResponse> {
if (!PermissionsService.canModifyUserAccessLevel(currentUser)) throw new ForbiddenError();
const { accessUpdates } = modifyUserAccessLevelRequest;
const emails = accessUpdates.map((e) => e.user.toLowerCase());
const updatedUsers = await this.userAccountService.updateUserAccessLevels(accessUpdates, emails, currentUser);
return { error: null, updatedUsers };
}

@Get('/access')
async getAllUsersWithAccessLevels(@AuthenticatedUser() user: UserModel): Promise<GetAllUserAccessLevelsResponse> {
if (!PermissionsService.canSeeAllUserAccessLevels(user)) throw new ForbiddenError();
const users = await this.userAccountService.getAllFullUserProfiles();
return { error: null, users };
}
}
34 changes: 30 additions & 4 deletions api/controllers/AttendanceController.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
import { JsonController, Get, Post, UseBefore, Params, ForbiddenError, Body } from 'routing-controllers';
import EmailService from '../../services/EmailService';
import { UserAuthentication } from '../middleware/UserAuthentication';
import { AuthenticatedUser } from '../decorators/AuthenticatedUser';
import { AttendEventRequest } from '../validators/AttendanceControllerRequests';
import { AttendEventRequest, AttendViaExpressCheckinRequest } from '../validators/AttendanceControllerRequests';
import { UserModel } from '../../models/UserModel';
import AttendanceService from '../../services/AttendanceService';
import PermissionsService from '../../services/PermissionsService';
import { GetAttendancesForEventResponse, GetAttendancesForUserResponse, AttendEventResponse } from '../../types';
import { UuidParam } from '../validators/GenericRequests';

@UseBefore(UserAuthentication)
@JsonController('/attendance')
export class AttendanceController {
private attendanceService: AttendanceService;

constructor(attendanceService: AttendanceService) {
private emailService: EmailService;

constructor(attendanceService: AttendanceService, emailService: EmailService) {
this.attendanceService = attendanceService;
this.emailService = emailService;
}

@UseBefore(UserAuthentication)
@Get('/:uuid')
async getAttendancesForEvent(@Params() params: UuidParam,
@AuthenticatedUser() user: UserModel): Promise<GetAttendancesForEventResponse> {
Expand All @@ -25,16 +29,38 @@ export class AttendanceController {
return { error: null, attendances };
}

@UseBefore(UserAuthentication)
@Get()
async getAttendancesForCurrentUser(@AuthenticatedUser() user: UserModel): Promise<GetAttendancesForUserResponse> {
const attendances = await this.attendanceService.getAttendancesForUser(user);
const attendances = await this.attendanceService.getAttendancesForCurrentUser(user);
return { error: null, attendances };
}

@UseBefore(UserAuthentication)
@Get('/user/:uuid')
async getAttendancesForUser(@Params() params: UuidParam,
@AuthenticatedUser() currentUser: UserModel): Promise<GetAttendancesForEventResponse> {
if (params.uuid === currentUser.uuid) {
return this.getAttendancesForCurrentUser(currentUser);
}
const attendances = await this.attendanceService.getAttendancesForUser(params.uuid);
return { error: null, attendances };
}

@UseBefore(UserAuthentication)
@Post()
async attendEvent(@Body() body: AttendEventRequest,
@AuthenticatedUser() user: UserModel): Promise<AttendEventResponse> {
const { event } = await this.attendanceService.attendEvent(user, body.attendanceCode, body.asStaff);
return { error: null, event };
}

@Post('/expressCheckin')
async attendViaExpressCheckin(@Body() body: AttendViaExpressCheckinRequest): Promise<AttendEventResponse> {
body.email = body.email.toLowerCase();
const { email, attendanceCode } = body;
const { event } = await this.attendanceService.attendViaExpressCheckin(attendanceCode, email);
await this.emailService.sendExpressCheckinConfirmation(email, event.title, event.pointValue);
return { error: null, event };
}
}
13 changes: 8 additions & 5 deletions api/controllers/FeedbackController.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Body, ForbiddenError, Get, JsonController, Params, Patch, Post, UseBefore } from 'routing-controllers';
import { Body, ForbiddenError, Get, JsonController, Params,
Patch, Post, UseBefore, QueryParams } from 'routing-controllers';
import { AuthenticatedUser } from '../decorators/AuthenticatedUser';
import { UserModel } from '../../models/UserModel';
import PermissionsService from '../../services/PermissionsService';
Expand All @@ -9,6 +10,7 @@ import { UserAuthentication } from '../middleware/UserAuthentication';
import {
SubmitFeedbackRequest,
UpdateFeedbackStatusRequest,
FeedbackSearchOptions,
} from '../validators/FeedbackControllerRequests';

@UseBefore(UserAuthentication)
Expand All @@ -21,9 +23,10 @@ export class FeedbackController {
}

@Get()
async getFeedback(@AuthenticatedUser() user: UserModel): Promise<GetFeedbackResponse> {
const canSeeAllFeedback = PermissionsService.canRespondToFeedback(user);
const feedback = await this.feedbackService.getFeedback(canSeeAllFeedback, user);
async getFeedback(@QueryParams() options: FeedbackSearchOptions,
@AuthenticatedUser() user: UserModel): Promise<GetFeedbackResponse> {
const canSeeAllFeedback = PermissionsService.canSeeAllFeedback(user);
const feedback = await this.feedbackService.getFeedback(canSeeAllFeedback, user, options);
return { error: null, feedback };
}

Expand All @@ -39,7 +42,7 @@ export class FeedbackController {
async updateFeedbackStatus(@Params() params: UuidParam,
@Body() updateFeedbackStatusRequest: UpdateFeedbackStatusRequest,
@AuthenticatedUser() user: UserModel): Promise<UpdateFeedbackStatusResponse> {
if (!PermissionsService.canRespondToFeedback(user)) throw new ForbiddenError();
if (!PermissionsService.canSeeAllFeedback(user)) throw new ForbiddenError();
const feedback = await this.feedbackService.updateFeedbackStatus(params.uuid, updateFeedbackStatusRequest.status);
return { error: null, feedback };
}
Expand Down
Loading

0 comments on commit b409da0

Please sign in to comment.