Fix account switching anon login (#1618)

* Always switch to user we just logged in as

If we're logged in and switch to anon and then use login to get into our previous account instead of using 'switch accounts', we only updated the JWT but we didn't switch to the user.

* Fix getToken unaware of multi-auth middleware

If we use login with new credentials while switched to anon (multi_auth.user-id === 'anonymous'), we updated the pubkey because getToken wasn't aware of the switch and thus believed we're logged in as a user.

This is fixed by applying the middleware before calling getToken.
This commit is contained in:
ekzyis 2024-11-20 14:05:42 +01:00 committed by GitHub
parent 82fead60f1
commit 6bae1f1a89
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 6 additions and 4 deletions

View File

@ -14,6 +14,7 @@ import { schnorr } from '@noble/curves/secp256k1'
import { notifyReferral } from '@/lib/webPush' import { notifyReferral } from '@/lib/webPush'
import { hashEmail } from '@/lib/crypto' import { hashEmail } from '@/lib/crypto'
import * as cookie from 'cookie' import * as cookie from 'cookie'
import { multiAuthMiddleware } from '@/pages/api/graphql'
/** /**
* Stores userIds in user table * Stores userIds in user table
@ -132,6 +133,9 @@ function setMultiAuthCookies (req, res, { id, jwt, name, photoId }) {
// add JWT to **httpOnly** cookie // add JWT to **httpOnly** cookie
res.appendHeader('Set-Cookie', cookie.serialize(`multi_auth.${id}`, jwt, cookieOptions)) res.appendHeader('Set-Cookie', cookie.serialize(`multi_auth.${id}`, jwt, cookieOptions))
// switch to user we just added
res.appendHeader('Set-Cookie', cookie.serialize('multi_auth.user-id', id, { ...cookieOptions, httpOnly: false }))
let newMultiAuth = [{ id, name, photoId }] let newMultiAuth = [{ id, name, photoId }]
if (req.cookies.multi_auth) { if (req.cookies.multi_auth) {
const oldMultiAuth = b64Decode(req.cookies.multi_auth) const oldMultiAuth = b64Decode(req.cookies.multi_auth)
@ -140,9 +144,6 @@ function setMultiAuthCookies (req, res, { id, jwt, name, photoId }) {
newMultiAuth = [...oldMultiAuth, ...newMultiAuth] newMultiAuth = [...oldMultiAuth, ...newMultiAuth]
} }
res.appendHeader('Set-Cookie', cookie.serialize('multi_auth', b64Encode(newMultiAuth), { ...cookieOptions, httpOnly: false })) res.appendHeader('Set-Cookie', cookie.serialize('multi_auth', b64Encode(newMultiAuth), { ...cookieOptions, httpOnly: false }))
// switch to user we just added
res.appendHeader('Set-Cookie', cookie.serialize('multi_auth.user-id', id, { ...cookieOptions, httpOnly: false }))
} }
async function pubkeyAuth (credentials, req, res, pubkeyColumnName) { async function pubkeyAuth (credentials, req, res, pubkeyColumnName) {
@ -165,6 +166,7 @@ async function pubkeyAuth (credentials, req, res, pubkeyColumnName) {
let user = await prisma.user.findUnique({ where: { [pubkeyColumnName]: pubkey } }) let user = await prisma.user.findUnique({ where: { [pubkeyColumnName]: pubkey } })
// get token if it exists // get token if it exists
req = multiAuthMiddleware(req)
const token = await getToken({ req }) const token = await getToken({ req })
if (!user) { if (!user) {
// we have not seen this pubkey before // we have not seen this pubkey before

View File

@ -82,7 +82,7 @@ export default startServerAndCreateNextHandler(apolloServer, {
} }
}) })
function multiAuthMiddleware (request) { export function multiAuthMiddleware (request) {
// switch next-auth session cookie with multi_auth cookie if cookie pointer present // switch next-auth session cookie with multi_auth cookie if cookie pointer present
// is there a cookie pointer? // is there a cookie pointer?