Skip to content

Commit

Permalink
feat: update iron-session to v8, update session to only store userId (#…
Browse files Browse the repository at this point in the history
…237)

* feat: update iron-session to v8

* feat: store only userId in session

* fix: incorrect session access

* fix: use toEqual instead of toMatch
  • Loading branch information
karrui authored Dec 13, 2023
1 parent ac5fc48 commit b8aa804
Show file tree
Hide file tree
Showing 18 changed files with 293 additions and 541 deletions.
526 changes: 121 additions & 405 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
"@types/validator": "^13.11.1",
"date-fns": "^2.29.3",
"date-fns-tz": "^2.0.0",
"iron-session": "^6.3.1",
"iron-session": "^8.0.1",
"jotai": "^2.2.0",
"lodash": "^4.17.21",
"nanoid": "^4.0.2",
Expand Down
12 changes: 0 additions & 12 deletions src/lib/types/iron-session.d.ts

This file was deleted.

12 changes: 12 additions & 0 deletions src/lib/types/session.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { type User } from '@prisma/client'
import { type IronSession } from 'iron-session'

export type SessionData = {
userId?: User['id']
sgidSessionState?: {
codeVerifier: string
nonce?: string
}
}

export type Session = IronSession<SessionData>
14 changes: 11 additions & 3 deletions src/server/context.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import type * as trpc from '@trpc/server'
import type { CreateNextContextOptions } from '@trpc/server/adapters/next'
import { getIronSession, type IronSession } from 'iron-session'
import { getIronSession } from 'iron-session'
import { prisma } from './prisma'
import { sessionOptions } from './modules/auth/session'
import { type SessionData, type Session } from '~/lib/types/session'
import { type User } from '@prisma/client'
import { type defaultMeSelect } from './modules/me/me.select'

interface CreateContextOptions {
session?: IronSession
session?: Session
user?: Pick<User, keyof typeof defaultMeSelect>
}

/**
Expand All @@ -24,7 +28,11 @@ export async function createContextInner(opts: CreateContextOptions) {
* @link https://trpc.io/docs/context
*/
export const createContext = async (opts: CreateNextContextOptions) => {
const session = await getIronSession(opts.req, opts.res, sessionOptions)
const session = await getIronSession<SessionData>(
opts.req,
opts.res,
sessionOptions
)

const innerContext = await createContextInner({
session,
Expand Down
2 changes: 1 addition & 1 deletion src/server/modules/auth/auth.router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export const authRouter = router({
email: emailSessionRouter,
sgid: sgidRouter,
logout: publicProcedure.mutation(async ({ ctx }) => {
ctx.session?.destroy()
ctx.session.destroy()
return { isLoggedIn: false }
}),
})
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ describe('auth.email', async () => {
// Should return logged in user.
await expect(result).resolves.toMatchObject(expectedUser)
// Session should have been set with logged in user.
expect(session.user).toMatchObject(expectedUser)
expect(session.userId).toEqual(expectedUser.id)
})

it('should throw if OTP is not found', async () => {
Expand Down
9 changes: 2 additions & 7 deletions src/server/modules/auth/email/email.router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { getBaseUrl } from '~/utils/getBaseUrl'
import { createTokenHash, createVfnPrefix, createVfnToken } from '../auth.util'
import { verifyToken } from '../auth.service'
import { VerificationError } from '../auth.error'
import { set } from 'lodash'
import { env } from '~/env.mjs'
import { formatInTimeZone } from 'date-fns-tz'
import { defaultMeSelect } from '../../me/me.select'
Expand Down Expand Up @@ -94,12 +93,8 @@ export const emailSessionRouter = router({
select: defaultMeSelect,
})

// TODO: Should only store user id in session.
// The rest of user details should be fetched from db in protectedProcedure.
// Sign user in.
set(ctx, 'session.user', user)

await ctx.session?.save()
ctx.session.userId = user.id
await ctx.session.save()
return user
}),
})
4 changes: 2 additions & 2 deletions src/server/modules/auth/session.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { type IronSessionOptions } from 'iron-session'
import { type SessionOptions } from 'iron-session'
import { env } from '~/env.mjs'

export const sessionOptions: IronSessionOptions = {
export const sessionOptions: SessionOptions = {
password: {
'1': env.SESSION_SECRET,
},
Expand Down
4 changes: 2 additions & 2 deletions src/server/modules/auth/sgid/sgid.router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export const sgidRouter = router({
message: 'SGID is not enabled',
})
}
if (!ctx.session?.sgidSessionState) {
if (!ctx.session.sgidSessionState) {
throw new TRPCError({
code: 'BAD_REQUEST',
message: 'Invalid login flow',
Expand Down Expand Up @@ -175,7 +175,7 @@ export const sgidRouter = router({
}

ctx.session.destroy()
ctx.session.user = user
ctx.session.userId = user.id
await ctx.session.save()

return {
Expand Down
10 changes: 5 additions & 5 deletions src/server/modules/me/me.router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { defaultMeSelect } from './me.select'
export const meRouter = router({
get: protectedProcedure.query(async ({ ctx }) => {
return await ctx.prisma.user.findUniqueOrThrow({
where: { id: ctx.session.user.id },
where: { id: ctx.user.id },
select: defaultMeSelect,
})
}),
Expand All @@ -25,7 +25,7 @@ export const meRouter = router({
)
.mutation(async ({ ctx, input }) => {
return await ctx.prisma.user.update({
where: { id: ctx.session.user.id },
where: { id: ctx.user.id },
data: {
image: `https://${env.R2_PUBLIC_HOSTNAME}/${input.imageKey}`,
},
Expand All @@ -37,17 +37,17 @@ export const meRouter = router({
.mutation(async ({ ctx, input }) => {
try {
return await ctx.prisma.user.update({
where: { id: ctx.session.user.id },
where: { id: ctx.user.id },
data: input,
select: defaultMeSelect,
})
} catch (e) {
if (e instanceof Prisma.PrismaClientKnownRequestError) {
if (e.code === 'P2002') {
ctx.logger.info('Username conflict', {
userId: ctx.session.user.id,
userId: ctx.user.id,
chosen: input.username,
current: ctx.session.user.username,
current: ctx.user.username,
})

throw new TRPCError({
Expand Down
1 change: 1 addition & 0 deletions src/server/modules/post/__tests__/post.router.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ describe('post.add', async () => {
it('post should be retrievable after creation', async () => {
const defaultUser: User = {
email: '[email protected]',
username: 'test-user',
name: 'Test User',
id: 'test-user-id',
bio: null,
Expand Down
Loading

1 comment on commit b8aa804

@vercel
Copy link

@vercel vercel bot commented on b8aa804 Dec 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.