Skip to content

Commit

Permalink
7.0 RC: Remove hardcoded check for session.id (#10013)
Browse files Browse the repository at this point in the history
Fixes bug when User table had a primary key other than `id`. Shout out
to @will-ks for finding this!

### Impact 

For apps which had a primary key other than `id`, all users will be
logged out on their next request after this is deployed.

Not sure if we consider that breaking? But it is 7.0 so anything goes!

Closes #10005
  • Loading branch information
cannikin committed Feb 14, 2024
1 parent ff138d1 commit 8b499f9
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 9 deletions.
18 changes: 9 additions & 9 deletions packages/auth-providers/dbAuth/api/src/DbAuthHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -295,15 +295,12 @@ type Params = AuthenticationResponseJSON &
transports?: string // used by webAuthN for something
}

interface DbAuthSession<TIdType> {
id: TIdType
}
type DbAuthSession = Record<string, unknown>

const DEFAULT_ALLOWED_USER_FIELDS = ['id', 'email']

export class DbAuthHandler<
TUser extends UserType,
TIdType = any,
TUserAttributes = Record<string, unknown>
> {
event: Request | APIGatewayProxyEvent
Expand All @@ -316,7 +313,7 @@ export class DbAuthHandler<
dbCredentialAccessor: any
allowedUserFields: string[]
hasInvalidSession: boolean
session: DbAuthSession<TIdType> | undefined
session: DbAuthSession | undefined
sessionCsrfToken: string | undefined
corsContext: CorsContext | undefined
sessionExpiresDate: string
Expand Down Expand Up @@ -1208,8 +1205,8 @@ export class DbAuthHandler<

// returns the set-cookie header to be returned in the request (effectively
// creates the session)
_createSessionHeader<TIdType = any>(
data: DbAuthSession<TIdType>,
_createSessionHeader(
data: DbAuthSession,
csrfToken: string
): SetCookieHeader {
const session = JSON.stringify(data) + ';' + csrfToken
Expand Down Expand Up @@ -1384,7 +1381,7 @@ export class DbAuthHandler<

// gets the user from the database and returns only its ID
async _getCurrentUser() {
if (!this.session?.id) {
if (!this.session?.[this.options.authFields.id]) {
throw new DbAuthError.NotLoggedInError()
}

Expand All @@ -1401,7 +1398,10 @@ export class DbAuthHandler<

try {
user = await this.dbAccessor.findUnique({
where: { [this.options.authFields.id]: this.session?.id },
where: {
[this.options.authFields.id]:
this.session?.[this.options.authFields.id],
},
select,
})
} catch (e: any) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2944,6 +2944,48 @@ describe('dbAuth', () => {

expect(user.id).toEqual(dbUser.id)
})

it('returns the user when id field is other than `id`', async () => {
const randomId = Math.floor(Math.random() * 1000000)
const dbUser = await createDbUser({ userId: randomId })
const options = {
authFields: {
id: 'userId',
},
authModelAccessor: 'user',
db: db,
forgotPassword: {
handler: () => {},
},
login: {
handler: () => {},
expires: 1,
},
resetPassword: {
handler: () => {},
},
signup: {
handler: () => {},
},
}
const headers = {
cookie: encryptToCookie(
JSON.stringify({ userId: dbUser.userId }) + ';' + 'token'
),
}

const req = new Request('http://localhost:8910/_rw_mw', {
method: 'POST',
headers,
})

const dbAuth = new DbAuthHandler(req, context, options)
await dbAuth.init()

const user = await dbAuth._getCurrentUser()

expect(user.userId).toEqual(dbUser.userId)
})
})

describe('_createUser()', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2651,6 +2651,46 @@ describe('dbAuth', () => {

expect(user.id).toEqual(dbUser.id)
})

it('returns the user when id field is other than `id`', async () => {
const randomId = Math.floor(Math.random() * 1000000)
const dbUser = await createDbUser({ userId: randomId })

const event = {
headers: {
cookie: encryptToCookie(
JSON.stringify({ userId: dbUser.userId }) + ';' + 'token'
),
},
}
const context = { foo: 'bar' }
const options = {
authFields: {
id: 'userId',
},
authModelAccessor: 'user',
db: db,
forgotPassword: {
handler: () => {},
},
login: {
handler: () => {},
expires: 1,
},
resetPassword: {
handler: () => {},
},
signup: {
handler: () => {},
},
}
const dbAuth = new DbAuthHandler(event, context, options)
await dbAuth.init()

const user = await dbAuth._getCurrentUser()

expect(user.userId).toEqual(dbUser.userId)
})
})

describe('_createUser()', () => {
Expand Down

0 comments on commit 8b499f9

Please sign in to comment.