Skip to content
This repository has been archived by the owner on Sep 12, 2023. It is now read-only.

#730 add user settings #757

Merged
merged 44 commits into from
Jul 27, 2022
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
83067b8
#730 - fix incorrect importing user from Prisma client
jamescd18 Jun 25, 2022
306a4f1
#730 - added user settings to prisma w/ migration
jamescd18 Jun 25, 2022
0a9250b
#730 - create user settings on user creation
jamescd18 Jun 26, 2022
3a2c5e2
#730 - migrate back-end login endpoint to dedicated authenticated use…
jamescd18 Jun 26, 2022
530e186
#730 - merge main into branch to bring it up to date
jamescd18 Jun 27, 2022
5e7c143
Merge branch 'main' into #730-add-user-settings
jamescd18 Jun 30, 2022
6bc1bc7
#698 - fix project risks seed data
jamescd18 Jun 30, 2022
f15bad4
#730 - update services to use AuthenticatedUser interface
jamescd18 Jul 1, 2022
b64aec7
#730 - add get settings back-end route
jamescd18 Jul 1, 2022
0c75dae
#730 - add services for getting user settings
jamescd18 Jul 1, 2022
b99596c
#730 - add user settings to settings page
jamescd18 Jul 1, 2022
3d3bea8
#730 - rename theme provided object to theme utility
jamescd18 Jul 1, 2022
6b2e043
#730 - rename utils theme to theme name
jamescd18 Jul 1, 2022
e6c57da
#730 - rename theme back from theme utility
jamescd18 Jul 1, 2022
b96d5c9
#730 - strict theme name usage
jamescd18 Jul 1, 2022
b261687
#730 - fix theme name usage
jamescd18 Jul 1, 2022
6c2cad8
#730 - add set theme on login, update components
jamescd18 Jul 1, 2022
04c2c0f
#730 - fix wrong user import
jamescd18 Jul 1, 2022
8f8a602
#730 - refactor out into user settings view component
jamescd18 Jul 1, 2022
3980719
#730 - add update user settings endpoint
jamescd18 Jul 1, 2022
903aa8a
#730 - shrink formatting
jamescd18 Jul 1, 2022
63b60e9
#730 - create services for updating user settings
jamescd18 Jul 2, 2022
b4f02d8
#730 - move container into user settings view
jamescd18 Jul 2, 2022
ac440c1
#730 - base update user settings form working
jamescd18 Jul 2, 2022
7e627e1
#730 - shrink button choices
jamescd18 Jul 2, 2022
f3e387c
#730 - improve buttons to simplify form
jamescd18 Jul 2, 2022
1c4cee5
#730 - replace edit button with pencil icon
jamescd18 Jul 2, 2022
6376c8d
#730 - collaspe vairables into output jsx
jamescd18 Jul 2, 2022
a294e86
#730 - simplify on submit wrapper
jamescd18 Jul 2, 2022
011702c
#730 - clean imports
jamescd18 Jul 2, 2022
98177e7
#730 - more import cleaning
jamescd18 Jul 2, 2022
c937057
#730 - nest pencil icon in div for accessibility
jamescd18 Jul 2, 2022
2669131
#730 - enhance user settings component tests
jamescd18 Jul 2, 2022
19f525c
#730 - add tests for user settings edit component
jamescd18 Jul 2, 2022
1a95434
#730 - fix user settings database setup
jamescd18 Jul 13, 2022
f3cca5a
#730 - separate name and className in themes
jamescd18 Jul 14, 2022
f183f33
#730 - remove theme toggle in top bar
jamescd18 Jul 14, 2022
9daf697
#730 - auto-create user settings if user doesn't have one
jamescd18 Jul 14, 2022
40dca05
#730 - should use chosen theme from settings now
anthonybernardi Jul 16, 2022
b8a754f
#730 - tests
anthonybernardi Jul 16, 2022
4254ca8
#730 - switch to upsert
jamescd18 Jul 17, 2022
01b48f4
#730 - remove post-login theme toggle
jamescd18 Jul 18, 2022
55f9d60
#730 - revert to post-login theme toggle
jamescd18 Jul 27, 2022
80b5803
Merge branch 'main' into #730-add-user-settings
jamescd18 Jul 27, 2022
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
37 changes: 32 additions & 5 deletions src/backend/functions/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,33 @@ import {
buildNotFoundResponse,
buildSuccessResponse,
routeMatcher,
User
User,
AuthenticatedUser
} from 'utils';

const prisma = new PrismaClient();

const authUserQueryArgs = Prisma.validator<Prisma.UserArgs>()({
include: {
userSettings: true
}
});

const authenticatedUserTransformer = (
user: Prisma.UserGetPayload<typeof authUserQueryArgs>
): AuthenticatedUser => {
return {
userId: user.userId,
firstName: user.firstName,
lastName: user.lastName,
googleAuthId: user.googleAuthId,
email: user.email,
emailId: user.emailId,
role: user.role,
defaultTheme: user.userSettings?.defaultTheme
};
};

const usersTransformer = (user: Prisma.UserGetPayload<null>): User => {
if (user === null) throw new TypeError('User not found');

Expand Down Expand Up @@ -70,7 +92,10 @@ const logUserIn: ApiRouteFunction = async (_params, event) => {
if (!payload) throw new Error('Auth server response payload invalid');
const { sub: userId } = payload; // google user id
// check if user is already in the database via Google ID
let user = await prisma.user.findUnique({ where: { googleAuthId: userId } });
let user = await prisma.user.findUnique({
where: { googleAuthId: userId },
...authUserQueryArgs
});

// if not in database, create user in database
if (user === null) {
Expand All @@ -83,8 +108,10 @@ const logUserIn: ApiRouteFunction = async (_params, event) => {
lastName: payload['family_name']!,
googleAuthId: userId,
email: payload['email']!,
emailId
}
emailId,
userSettings: { create: {} }
},
...authUserQueryArgs
});
user = createdUser;
}
Expand All @@ -97,7 +124,7 @@ const logUserIn: ApiRouteFunction = async (_params, event) => {
}
});

return buildSuccessResponse(usersTransformer(user));
return buildSuccessResponse(authenticatedUserTransformer(user));
};

// Define all valid routes for the endpoint
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
Warnings:

- A unique constraint covering the columns `[userSettingsId]` on the table `User` will be added. If there are existing duplicate values, this will fail.

*/
-- CreateEnum
CREATE TYPE "Theme" AS ENUM ('LIGHT', 'DARK');

-- AlterTable
ALTER TABLE "User" ADD COLUMN "userSettingsId" TEXT;

-- CreateTable
CREATE TABLE "UserSettings" (
"id" TEXT NOT NULL,
"defaultTheme" "Theme" NOT NULL DEFAULT E'DARK',

PRIMARY KEY ("id")
);

-- CreateIndex
CREATE UNIQUE INDEX "User.userSettingsId_unique" ON "User"("userSettingsId");

-- AddForeignKey
ALTER TABLE "User" ADD FOREIGN KEY ("userSettingsId") REFERENCES "UserSettings"("id") ON DELETE SET NULL ON UPDATE CASCADE;
14 changes: 14 additions & 0 deletions src/backend/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ enum Role {
GUEST
}

enum Theme {
LIGHT
DARK
}

enum Scope_CR_Why_Type {
ESTIMATION
SCHOOL
Expand All @@ -53,6 +58,9 @@ model User {
email String @unique
emailId String? @unique
role Role @default(GUEST)
userSettingsId String? @unique
userSettings UserSettings? @relation(fields: [userSettingsId], references: [id])
jamescd18 marked this conversation as resolved.
Show resolved Hide resolved
// Relation references
submittedChangeRequests Change_Request[] @relation(name: "submittedChangeRequests")
reviewedChangeRequests Change_Request[] @relation(name: "reviewedChangeRequests")
markedAsProjectLead Activation_CR[] @relation(name: "markAsProjectLead")
Expand All @@ -74,6 +82,12 @@ model Session {
deviceInfo String?
}

model UserSettings {
id String @id @default(uuid())
user User?
defaultTheme Theme @default(DARK)
}

model Change_Request {
crId Int @id @default(autoincrement())
submitterId Int
Expand Down
12 changes: 8 additions & 4 deletions src/backend/prisma/seed-data/risks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,18 @@

const dbSeedRisk1: any = {
projectId: 1,
detail: 'This one might be a bit too expensive',
createdByUserId: 1
createdByUserId: 1,
fields: {
detail: 'This one might be a bit too expensive'
}
};

const dbSeedRisk2: any = {
projectId: 1,
detail: 'Risky Risk 123',
createdByUserId: 1
createdByUserId: 1,
fields: {
detail: 'Risky Risk 123'
}
};

export const dbSeedAllRisks: any[] = [dbSeedRisk1, dbSeedRisk2];
4 changes: 2 additions & 2 deletions src/backend/prisma/seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const prisma = new PrismaClient();

const performSeed: () => Promise<void> = async () => {
for (const seedUser of dbSeedAllUsers) {
await prisma.user.create({ data: { ...seedUser } });
await prisma.user.create({ data: { ...seedUser, userSettings: { create: {} } } });
}

for (const seedSession of dbSeedAllSessions) {
Expand Down Expand Up @@ -44,7 +44,7 @@ const performSeed: () => Promise<void> = async () => {
data: {
createdBy: { connect: { userId: seedRisk.createdByUserId } },
project: { connect: { projectId: seedRisk.projectId } },
...seedRisk
...seedRisk.fields
}
});
}
Expand Down
4 changes: 2 additions & 2 deletions src/frontend/pages/LoginPage/login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import { useHistory } from 'react-router';
import { Role } from '@prisma/client';
import { exampleAllUsers } from '../../../test-support/test-data/users.stub';
import { useAuth } from '../../../services/auth.hooks';
import LoginPage from './login-page/login-page';
import './login.module.css';
import { routes } from '../../../shared/routes';
import LoginPage from './login-page/login-page';
import LoadingIndicator from '../../components/loading-indicator/loading-indicator';
import './login.module.css';

interface LoginProps {
postLoginRedirect: { url: string; search: string };
Expand Down
2 changes: 1 addition & 1 deletion src/services/auth.hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

import { useState, useContext } from 'react';
import { User } from '@prisma/client';
import { User } from 'utils';
import { AuthContext } from '../frontend/app/app-context-auth/app-context-auth';
import { useLogUserIn } from './users.hooks';
import { Auth } from '../shared/types';
Expand Down
3 changes: 1 addition & 2 deletions src/shared/pipes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
* See the LICENSE file in the repository root folder for details.
*/

import { User } from '@prisma/client';
import { WbsNumber } from 'utils';
import { WbsNumber, User } from 'utils';

/**
* Pipes:
Expand Down
2 changes: 1 addition & 1 deletion src/shared/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* See the LICENSE file in the repository root folder for details.
*/

import { User } from '@prisma/client';
import { User } from 'utils';
jamescd18 marked this conversation as resolved.
Show resolved Hide resolved
import { IconProp } from '@fortawesome/fontawesome-svg-core';

export interface Auth {
Expand Down
3 changes: 2 additions & 1 deletion src/test-support/test-data/users.stub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
* See the LICENSE file in the repository root folder for details.
*/

import { User, Role } from '@prisma/client';
import { User } from 'utils';
import { Role } from '@prisma/client';

export const exampleAppAdminUser: User = {
userId: 1,
Expand Down
16 changes: 16 additions & 0 deletions src/utils/src/types/user-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,19 @@ export interface User {
}

export type Role = 'APP_ADMIN' | 'ADMIN' | 'LEADERSHIP' | 'MEMBER' | 'GUEST';

export type Theme = 'DARK' | 'LIGHT';

/**
* User object used purely for authentication purposes.
*/
export interface AuthenticatedUser {
userId: number;
firstName: string;
lastName: string;
googleAuthId: string;
email: string;
emailId: string | null;
role: Role;
defaultTheme?: Theme;
}