web/back.ts
import { GetServerSidePropsResult } from 'next';
import { getCookieFromReq } from 'front'
import { AUTH_COOKIE_NAME } from 'front/js'
import { verify } from './jwt'
export async function findSynonymOr404(
sequelize,
slugString: string,
routeCb: (string) => string
): Promise<GetServerSidePropsResult<{ [key: string]: any; }>> {
const { Article } = sequelize.models
const redirects = await Article.findRedirects([slugString], { limit: 1 })
const newSlug = redirects[slugString]
if (newSlug) {
return {
redirect: {
destination: routeCb(newSlug),
permanent: true,
},
}
} else {
return {
notFound: true
}
}
}
export async function getLoggedInUser(req, res, loggedInUser?) {
if (loggedInUser !== undefined) {
return loggedInUser
} else {
const authCookie = getCookieFromReq(req, AUTH_COOKIE_NAME)
let verifiedUser
if (authCookie) {
try {
verifiedUser = verify(authCookie)
} catch (e) {
return null
}
} else {
return null
}
const sequelize = req.sequelize
const User = sequelize.models.User
const user = await User.findByPk(
verifiedUser.id,
// Get the new upvote count for the logged in user.
// This was the slowest DB query as of commit 96c73b204ba498699bc241f61b78c441cd9885bf + 1.
// at around 20ms locally for /cirosantilli on localhost. The total query time was 200-300 ms
// however, so I was lazy to optimize it. This query is efficient, optimizing it further would
// require storing the target article user ID on UserLikeArticle as a cache and indexing by it.
// Definitely doable.
{
attributes: {
include: [
[
sequelize.fn(
'count',
sequelize.col('articles->likes.articleId')
),
'scoreDelta'
],
],
},
group: ['User.id'],
include: [{
model: sequelize.models.Article,
as: 'articles',
required: false,
subQuery: false,
attributes: [],
include: [{
model: sequelize.models.UserLikeArticle,
as: 'likes',
attributes: [],
required: false,
subQuery: false,
where: { createdAt: { [sequelize.Sequelize.Op.gt]: sequelize.col('User.newScoreLastCheck')} },
}]
}]
}
)
if (user === null) {
res.clearCookie(AUTH_COOKIE_NAME)
} else {
user.scoreDelta = Number(user.get('scoreDelta'))
}
return user
}
}