mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
Verify api key for routers too
This commit is contained in:
parent
6e16631f3b
commit
c0bb67a6b5
4 changed files with 42 additions and 27 deletions
|
|
@ -5,7 +5,7 @@
|
|||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
/* eslint-disable @typescript-eslint/require-await */
|
||||
import { ContextFunction } from 'apollo-server-core'
|
||||
import { Claims, ClaimsToSet, ResolverContext } from './resolvers/types'
|
||||
import { ClaimsToSet, ResolverContext } from './resolvers/types'
|
||||
import { SetClaimsRole } from './utils/dictionary'
|
||||
import Knex, { Transaction } from 'knex'
|
||||
import { ExpressContext } from 'apollo-server-express/dist/ApolloServer'
|
||||
|
|
@ -24,7 +24,7 @@ import ScalarResolvers from './scalars'
|
|||
import * as Sentry from '@sentry/node'
|
||||
import { createPubSubClient } from './datalayer/pubsub'
|
||||
import { initModels } from './server'
|
||||
import { claimsFromApiKey } from './utils/auth'
|
||||
import { getClaimsByToken } from './utils/auth'
|
||||
|
||||
const signToken = promisify(jwt.sign)
|
||||
const logger = buildLogger('app.dispatch')
|
||||
|
|
@ -39,28 +39,13 @@ const contextFunc: ContextFunction<ExpressContext, ResolverContext> = async ({
|
|||
req,
|
||||
res,
|
||||
}) => {
|
||||
let claims: Claims | undefined
|
||||
|
||||
const token = req?.cookies?.auth || req?.headers?.authorization
|
||||
|
||||
logger.info(`handling gql request`, {
|
||||
query: req.body.query,
|
||||
variables: req.body.variables,
|
||||
})
|
||||
|
||||
if (token) {
|
||||
try {
|
||||
jwt.verify(token, env.server.jwtSecret) &&
|
||||
(claims = jwt.decode(token) as Claims)
|
||||
} catch (e) {
|
||||
if (e instanceof jwt.JsonWebTokenError) {
|
||||
logger.info(`not a jwt token, checking api key`, { token })
|
||||
claims = await claimsFromApiKey(token)
|
||||
} else {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
const token = req?.cookies?.auth || req?.headers?.authorization
|
||||
const claims = await getClaimsByToken(token)
|
||||
|
||||
async function setClaims(
|
||||
tx: Transaction,
|
||||
|
|
|
|||
|
|
@ -6,13 +6,12 @@ import express from 'express'
|
|||
import { CreateArticleErrorCode } from './../generated/graphql'
|
||||
import { isSiteBlockedForParse } from './../utils/blocked'
|
||||
import cors from 'cors'
|
||||
import { env } from './../env'
|
||||
import { buildLogger } from './../utils/logger'
|
||||
import * as jwt from 'jsonwebtoken'
|
||||
import { corsConfig } from '../utils/corsConfig'
|
||||
import { createPageSaveRequest } from '../services/create_page_save_request'
|
||||
import { initModels } from '../server'
|
||||
import { kx } from '../datalayer/knex_config'
|
||||
import { getClaimsByToken } from '../utils/auth'
|
||||
|
||||
const logger = buildLogger('app.dispatch')
|
||||
|
||||
|
|
@ -26,11 +25,12 @@ export function articleRouter() {
|
|||
}
|
||||
|
||||
const token = req?.cookies?.auth || req?.headers?.authorization
|
||||
if (!token || !jwt.verify(token, env.server.jwtSecret)) {
|
||||
return res.status(401).send({ errorCode: 'UNAUTHORIZED' })
|
||||
const claims = await getClaimsByToken(token)
|
||||
if (!claims) {
|
||||
return res.status(401).send('UNAUTHORIZED')
|
||||
}
|
||||
|
||||
const { uid } = (jwt.decode(token) || {}) as { uid: string }
|
||||
const { uid } = claims
|
||||
|
||||
logger.info('Article saving request', {
|
||||
body: req.body,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import express from 'express'
|
||||
import { env } from '../../env'
|
||||
import * as jwt from 'jsonwebtoken'
|
||||
import { PageType, UploadFileStatus } from '../../generated/graphql'
|
||||
import {
|
||||
generateUploadFilePathName,
|
||||
|
|
@ -17,6 +16,7 @@ import { generateSlug } from '../../utils/helpers'
|
|||
import { createPubSubClient } from '../../datalayer/pubsub'
|
||||
import { ArticleSavingRequestStatus, Page } from '../../elastic/types'
|
||||
import { createPage } from '../../elastic/pages'
|
||||
import { getClaimsByToken } from '../../utils/auth'
|
||||
|
||||
export function pdfAttachmentsRouter() {
|
||||
const router = express.Router()
|
||||
|
|
@ -31,7 +31,7 @@ export function pdfAttachmentsRouter() {
|
|||
}
|
||||
|
||||
const token = req?.headers?.authorization
|
||||
if (!token || !jwt.verify(token, env.server.jwtSecret)) {
|
||||
if (!(await getClaimsByToken(token))) {
|
||||
return res.status(401).send('UNAUTHORIZED')
|
||||
}
|
||||
|
||||
|
|
@ -94,7 +94,7 @@ export function pdfAttachmentsRouter() {
|
|||
}
|
||||
|
||||
const token = req?.headers?.authorization
|
||||
if (!token || !jwt.verify(token, env.server.jwtSecret)) {
|
||||
if (!(await getClaimsByToken(token))) {
|
||||
return res.status(401).send('UNAUTHORIZED')
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ import { Claims } from '../resolvers/types'
|
|||
import { getRepository } from '../entity/utils'
|
||||
import { ApiKey } from '../entity/api_key'
|
||||
import crypto from 'crypto'
|
||||
import * as jwt from 'jsonwebtoken'
|
||||
import { env } from '../env'
|
||||
|
||||
export const hashPassword = async (password: string, salt = 10) => {
|
||||
return bcrypt.hash(password, salt)
|
||||
|
|
@ -49,3 +51,31 @@ export const claimsFromApiKey = async (key: string): Promise<Claims> => {
|
|||
exp,
|
||||
}
|
||||
}
|
||||
|
||||
// verify jwt token first
|
||||
// if valid then decode and return claims
|
||||
// if expired then throw error
|
||||
// if not valid then verify api key
|
||||
export const getClaimsByToken = async (
|
||||
token: string | undefined
|
||||
): Promise<Claims | undefined> => {
|
||||
let claims: Claims | undefined
|
||||
|
||||
if (!token) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
try {
|
||||
jwt.verify(token, env.server.jwtSecret) &&
|
||||
(claims = jwt.decode(token) as Claims)
|
||||
} catch (e) {
|
||||
if (e instanceof jwt.JsonWebTokenError) {
|
||||
console.log(`not a jwt token, checking api key`, { token })
|
||||
claims = await claimsFromApiKey(token)
|
||||
} else {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
return claims
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue