64 lines
2.2 KiB
JavaScript
64 lines
2.2 KiB
JavaScript
import cookie from 'cookie'
|
|
import { datePivot } from '../../lib/time'
|
|
|
|
/**
|
|
* @param {NextApiRequest} req
|
|
* @param {NextApiResponse} res
|
|
* @return {void}
|
|
*/
|
|
export default (req, res) => {
|
|
// is there a cookie pointer?
|
|
const cookiePointerName = 'multi_auth.user-id'
|
|
const userId = req.cookies[cookiePointerName]
|
|
|
|
const secure = process.env.NODE_ENV === 'production'
|
|
|
|
// is there a session?
|
|
const sessionCookieName = secure ? '__Secure-next-auth.session-token' : 'next-auth.session-token'
|
|
const sessionJWT = req.cookies[sessionCookieName]
|
|
|
|
if (!userId && !sessionJWT) {
|
|
// no cookie pointer and no session cookie present. nothing to do.
|
|
res.status(404).end()
|
|
return
|
|
}
|
|
|
|
const cookies = []
|
|
|
|
const cookieOptions = {
|
|
path: '/',
|
|
secure,
|
|
httpOnly: true,
|
|
sameSite: 'lax',
|
|
expires: datePivot(new Date(), { months: 1 })
|
|
}
|
|
// remove JWT pointed to by cookie pointer
|
|
cookies.push(cookie.serialize(`multi_auth.${userId}`, '', { ...cookieOptions, expires: 0, maxAge: 0 }))
|
|
|
|
// update multi_auth cookie and check if there are more accounts available
|
|
const oldMultiAuth = b64Decode(req.cookies.multi_auth)
|
|
const newMultiAuth = oldMultiAuth.filter(({ id }) => id !== Number(userId))
|
|
if (newMultiAuth.length === 0) {
|
|
// no next account available. cleanup: remove multi_auth + pointer cookie
|
|
cookies.push(cookie.serialize('multi_auth', '', { ...cookieOptions, httpOnly: false, expires: 0, maxAge: 0 }))
|
|
cookies.push(cookie.serialize('multi_auth.user-id', '', { ...cookieOptions, httpOnly: false, expires: 0, maxAge: 0 }))
|
|
res.setHeader('Set-Cookie', cookies)
|
|
res.status(204).end()
|
|
return
|
|
}
|
|
cookies.push(cookie.serialize('multi_auth', b64Encode(newMultiAuth), { ...cookieOptions, httpOnly: false }))
|
|
|
|
const newUserId = newMultiAuth[0].id
|
|
const newUserJWT = req.cookies[`multi_auth.${newUserId}`]
|
|
res.setHeader('Set-Cookie', [
|
|
...cookies,
|
|
cookie.serialize(cookiePointerName, newUserId, { ...cookieOptions, httpOnly: false }),
|
|
cookie.serialize(sessionCookieName, newUserJWT, cookieOptions)
|
|
])
|
|
|
|
res.status(302).end()
|
|
}
|
|
|
|
const b64Encode = obj => Buffer.from(JSON.stringify(obj)).toString('base64')
|
|
const b64Decode = s => JSON.parse(Buffer.from(s, 'base64'))
|