Skip to content

Commit

Permalink
Merge pull request #21
Browse files Browse the repository at this point in the history
create calendar view in user profile
  • Loading branch information
rokartur authored May 24, 2024
2 parents 7d2c5c3 + a5786fc commit d1351ef
Show file tree
Hide file tree
Showing 35 changed files with 3,163 additions and 456 deletions.
Binary file modified backend/bun.lockb
Binary file not shown.
1,531 changes: 1,531 additions & 0 deletions backend/package-lock.json

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,12 @@
"pg": "^8.11.5",
"postgres": "^3.4.4",
"react": "^18.3.1",
"studio": "^0.13.5"
"studio": "^0.13.5",
"uuid": "^9.0.1"
},
"devDependencies": {
"@types/pg": "^8.11.5",
"@types/uuid": "^9.0.8",
"bun-types": "latest",
"drizzle-kit": "^0.20.17",
"prettier": "^3.2.5",
Expand Down
2 changes: 1 addition & 1 deletion backend/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const app = new Elysia()
.use(Logestic.preset('common'))
.use(cors())
.use(swagger({
path: '/docs',
path: '/api/docs',
documentation: {
info: {
title: 'FitPlan Connect API Documentation',
Expand Down
4 changes: 2 additions & 2 deletions backend/src/db/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,6 @@ export const meetings = dbSchema.table('meetings', {
id: text('id').primaryKey(),
userId: text('user_id').notNull().references(() => users.id),
trainerID: text('trainer_id').notNull().references(() => trainers.id),
startTime: timestamp('start_time', { withTimezone: true }).notNull(),
endTime: timestamp('end_time', { withTimezone: true }).notNull(),
startTime: timestamp('start_time', { withTimezone: true, mode: 'date' }).notNull(),
endTime: timestamp('end_time', { withTimezone: true, mode: 'date' }).notNull(),
})
3 changes: 0 additions & 3 deletions backend/src/routes/admin/index.ts

This file was deleted.

6 changes: 0 additions & 6 deletions backend/src/routes/admin/users/index.ts

This file was deleted.

68 changes: 68 additions & 0 deletions backend/src/routes/meetings/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { ElysiaApp } from '@/app'
import { db } from '@/utils/db'
import { eq } from 'drizzle-orm'
import { meetings, sessions, users } from '@/db/schema'
import { t } from 'elysia'
import { v4 as uuid } from 'uuid'
import { validateRequest } from '@/utils/validateRequest'

export default (app: ElysiaApp) =>
app
.get('/', async ({ set, cookie: { auth_session } }) => {
const userSession = await db.query.sessions.findFirst({ where: eq(sessions.id, auth_session.value) })
const { user, session } = await validateRequest(auth_session)

if (user && session && userSession) {
const userData = await db.query.users.findFirst({ where: eq(users.id, userSession.userId) })

if (userData?.accessToken) {
const data = await db.select().from(meetings)
set.status = 200
return data
}

if (!userData) {
set.status = 401
return { message: 'unauthorized' }
}
} else {
set.status = 401
return { message: 'unauthorized' }
}
})
.post(
'/',
async ({ set, body: { userId, trainerID, startTime, endTime }, cookie: { auth_session } }) => {
const userSession = await db.query.sessions.findFirst({ where: eq(sessions.id, auth_session.value) })

if (userSession) {
const userData = await db.query.users.findFirst({ where: eq(users.id, userSession.userId) })

if (userData?.accessToken) {
const id = uuid()
type NewMeeting = typeof meetings.$inferInsert
const newMeeting: NewMeeting = { id, userId, trainerID, startTime, endTime }
const meetingID = await db.insert(meetings).values(newMeeting).returning({ id: meetings.id })

set.status = 200
return meetingID
}

if (!userData) {
set.status = 401
return { message: 'unauthorized' }
}
} else {
set.status = 401
return { message: 'unauthorized' }
}
},
{
body: t.Object({
userId: t.String(),
trainerID: t.String(),
startTime: t.Date(),
endTime: t.Date(),
}),
},
)
71 changes: 5 additions & 66 deletions backend/src/routes/oauth/logout/index.ts
Original file line number Diff line number Diff line change
@@ -1,80 +1,19 @@
import 'dotenv/config'
import { ElysiaApp } from '@/app'
import { db } from '@/utils/db'
import { meetings, sessions, users } from '@/db/schema'
import { sessions } from '@/db/schema'
import { eq } from 'drizzle-orm'
import user from '@/routes/user'
import { lucia } from '@/utils/lucia'
import { validateRequest } from '@/utils/validateRequest'
import { clearAuthCookies } from '@/utils/clearAuthCookies'

export default (app: ElysiaApp) => app
.get('/', async ({ set, cookie: { github_oauth_state, auth_session } }) => {
try {
const validateRequest = async () => {
const sessionId = auth_session?.value ?? null

if (!sessionId)
return {
user: null,
session: null,
}

const { user, session } = await lucia.validateSession(sessionId)
try {
if (session && session.fresh) {
const sessionCookie = lucia.createSessionCookie(session.id)
auth_session.set({
value: sessionCookie.value,
httpOnly: sessionCookie.attributes.httpOnly,
secure: sessionCookie.attributes.secure,
sameSite: sessionCookie.attributes.sameSite,
path: sessionCookie.attributes.path,
maxAge: sessionCookie.attributes.maxAge,
})
}
if (!session) {
const sessionCookie = lucia.createBlankSessionCookie()
auth_session.set({
value: sessionCookie.value,
httpOnly: sessionCookie.attributes.httpOnly,
secure: sessionCookie.attributes.secure,
sameSite: sessionCookie.attributes.sameSite,
path: sessionCookie.attributes.path,
maxAge: sessionCookie.attributes.maxAge,
})
}
} catch (error: any) {
console.log(error)
}

return {
user,
session,
}
}

const userSession = await db.query.sessions.findFirst({ where: eq(sessions.id, auth_session.value) })

const { user, session } = await validateRequest()
const { user, session } = await validateRequest(auth_session)

if (user && session && userSession) {
github_oauth_state.set({
value: '',
httpOnly: true,
secure: true,
sameSite: 'strict',
path: '/',
maxAge: 0,
})

auth_session.set({
value: '',
httpOnly: true,
secure: true,
sameSite: 'strict',
path: '/',
maxAge: 0,
})

clearAuthCookies(github_oauth_state, auth_session)
await db.delete(sessions).where(eq(sessions.userId, user.id)).returning()
set.status = 200
set.headers.location = '/'
Expand Down
35 changes: 35 additions & 0 deletions backend/src/routes/trainers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { ElysiaApp } from '@/app'
import { db } from '@/utils/db'
import { eq } from 'drizzle-orm'
import { sessions, trainers, users } from '@/db/schema'
import { validateRequest } from '@/utils/validateRequest'

export default (app: ElysiaApp) =>
app.get('/', async ({ set, cookie: { auth_session } }) => {
const userSession = await db.query.sessions.findFirst({ where: eq(sessions.id, auth_session.value) })
const { user, session } = await validateRequest(auth_session)

if (user && session && userSession) {
const userData = await db.query.users.findFirst({ where: eq(users.id, userSession.userId) })

if (userData?.accessToken) {
const data = await db.select({
id: trainers.id,
name: trainers.name,
username: trainers.username,
email: trainers.email,
profilePicture: trainers.profilePictureUrl,
}).from(trainers)
set.status = 200
return data
}

if (!userData) {
set.status = 401
return { message: 'unauthorized' }
}
} else {
set.status = 401
return { message: 'unauthorized' }
}
})
68 changes: 4 additions & 64 deletions backend/src/routes/user/delete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,76 +2,16 @@ import { ElysiaApp } from '@/app'
import { db } from '@/utils/db'
import { eq } from 'drizzle-orm'
import { meetings, sessions, users } from '@/db/schema'
import { lucia } from '@/utils/lucia'
import { validateRequest } from '@/utils/validateRequest'
import { clearAuthCookies } from '@/utils/clearAuthCookies'

export default (app: ElysiaApp) =>
app.get('/', async ({ set, cookie: { github_oauth_state, auth_session } }) => {
const validateRequest = async () => {
const sessionId = auth_session?.value ?? null

if (!sessionId)
return {
user: null,
session: null,
}

const { user, session } = await lucia.validateSession(sessionId)
try {
if (session && session.fresh) {
const sessionCookie = lucia.createSessionCookie(session.id)
auth_session.set({
value: sessionCookie.value,
httpOnly: sessionCookie.attributes.httpOnly,
secure: sessionCookie.attributes.secure,
sameSite: sessionCookie.attributes.sameSite,
path: sessionCookie.attributes.path,
maxAge: sessionCookie.attributes.maxAge,
})
}
if (!session) {
const sessionCookie = lucia.createBlankSessionCookie()
auth_session.set({
value: sessionCookie.value,
httpOnly: sessionCookie.attributes.httpOnly,
secure: sessionCookie.attributes.secure,
sameSite: sessionCookie.attributes.sameSite,
path: sessionCookie.attributes.path,
maxAge: sessionCookie.attributes.maxAge,
})
}
} catch (error: any) {
console.log(error)
}

return {
user,
session,
}
}

const userSession = await db.query.sessions.findFirst({ where: eq(sessions.id, auth_session.value) })

const { user, session } = await validateRequest()
const { user, session } = await validateRequest(auth_session)

if (user && session && userSession) {
github_oauth_state.set({
value: '',
httpOnly: true,
secure: true,
sameSite: 'strict',
path: '/',
maxAge: 0,
})

auth_session.set({
value: '',
httpOnly: true,
secure: true,
sameSite: 'strict',
path: '/',
maxAge: 0,
})

clearAuthCookies(github_oauth_state, auth_session)
await db.delete(meetings).where(eq(meetings.userId, user.id)).returning()
await db.delete(sessions).where(eq(sessions.userId, user.id)).returning()
await db.delete(users).where(eq(users.id, user.id)).returning()
Expand Down
Loading

0 comments on commit d1351ef

Please sign in to comment.