parent
81595c8261
commit
69233bb7e1
@ -1,4 +1,5 @@ |
|||||||
module.exports = { |
module.exports = { |
||||||
preset: 'ts-jest', |
preset: "ts-jest", |
||||||
testEnvironment: 'node', |
testEnvironment: "node", |
||||||
}; |
globalSetup: "./src/jestGlobalSetup.ts", |
||||||
|
} |
||||||
|
@ -1,49 +0,0 @@ |
|||||||
require("isomorphic-fetch") |
|
||||||
import { ApolloServer } from "apollo-server-express" |
|
||||||
import { getConnection } from "typeorm" |
|
||||||
import { bootstrap } from "./app" |
|
||||||
import { connectionOptionsforTesting } from "./app/schema" |
|
||||||
import { signToken } from "./app/userResolver/auth" |
|
||||||
import { User } from "./app/userResolver/User" |
|
||||||
|
|
||||||
let server: ApolloServer |
|
||||||
let port: number |
|
||||||
|
|
||||||
beforeAll(async () => { |
|
||||||
port = 4001 |
|
||||||
server = await bootstrap(connectionOptionsforTesting(), port) |
|
||||||
}) |
|
||||||
|
|
||||||
describe("app should", () => { |
|
||||||
it("accept auth header correctly", async () => { |
|
||||||
const user = await User.create({ |
|
||||||
email: "email@email.com", |
|
||||||
}).save() |
|
||||||
|
|
||||||
let token = signToken({ userId: user.id }) |
|
||||||
|
|
||||||
const url = `http://localhost:${port}/graphql` |
|
||||||
|
|
||||||
const rawResponse = await fetch(url, { |
|
||||||
method: "post", |
|
||||||
headers: { |
|
||||||
"content-Type": "application/json", |
|
||||||
authorization: "Bearer " + token, |
|
||||||
}, |
|
||||||
body: JSON.stringify({ |
|
||||||
query: "{me{email}}", |
|
||||||
}), |
|
||||||
}) |
|
||||||
|
|
||||||
const response = await rawResponse.json() |
|
||||||
|
|
||||||
expect(response.errors).toBeUndefined() |
|
||||||
expect(response.data).toMatchObject({ |
|
||||||
me: { email: user.email }, |
|
||||||
}) |
|
||||||
|
|
||||||
await getConnection().synchronize(true) |
|
||||||
await getConnection().close() |
|
||||||
await server.stop() |
|
||||||
}) |
|
||||||
}) |
|
@ -1,152 +0,0 @@ |
|||||||
import { gql } from "apollo-server" |
|
||||||
import { createConnection, getConnection } from "typeorm" |
|
||||||
import { callSchema, connectionOptionsforTesting } from "./schema" |
|
||||||
import { signToken, verifyToken } from "./userResolver/auth" |
|
||||||
import { LoginTokens } from "./userResolver/LoginTokens" |
|
||||||
import { User } from "./userResolver/User" |
|
||||||
|
|
||||||
beforeAll(async () => { |
|
||||||
return await createConnection(connectionOptionsforTesting()) |
|
||||||
}) |
|
||||||
|
|
||||||
afterAll(async () => { |
|
||||||
return await getConnection().close() |
|
||||||
}) |
|
||||||
|
|
||||||
afterEach(async () => { |
|
||||||
return await getConnection().synchronize(true) |
|
||||||
}) |
|
||||||
|
|
||||||
describe("resolver of user", () => { |
|
||||||
describe("createUser mutation should", () => { |
|
||||||
it("return email as it creates user with mutation", async () => { |
|
||||||
const createUserMutation = gql` |
|
||||||
mutation { |
|
||||||
createUser(email: "email@email.com", password: "password") { |
|
||||||
email |
|
||||||
} |
|
||||||
} |
|
||||||
` |
|
||||||
|
|
||||||
const response = await callSchema(createUserMutation) |
|
||||||
|
|
||||||
expect(response.errors).toBeUndefined() |
|
||||||
expect(response.data).toMatchObject({ |
|
||||||
createUser: { email: "email@email.com" }, |
|
||||||
}) |
|
||||||
}) |
|
||||||
}) |
|
||||||
|
|
||||||
describe("users query should", () => { |
|
||||||
it("return emails of registered users", async () => { |
|
||||||
const usersQuery = gql` |
|
||||||
query { |
|
||||||
users { |
|
||||||
email |
|
||||||
} |
|
||||||
} |
|
||||||
` |
|
||||||
|
|
||||||
const user = await User.create({ |
|
||||||
email: "email@email.com", |
|
||||||
}).save() |
|
||||||
|
|
||||||
const response = await callSchema(usersQuery) |
|
||||||
|
|
||||||
expect(response.errors).toBeUndefined() |
|
||||||
expect(response.data).toMatchObject({ |
|
||||||
users: [{ email: user.email }], |
|
||||||
}) |
|
||||||
}) |
|
||||||
}) |
|
||||||
|
|
||||||
describe("loginTokens query should", () => { |
|
||||||
const loginTokensQuery = gql` |
|
||||||
query { |
|
||||||
loginTokens(email: "email@email.com", password: "good-password") { |
|
||||||
accessToken |
|
||||||
} |
|
||||||
} |
|
||||||
` |
|
||||||
|
|
||||||
it("return error for non-existent user", async () => { |
|
||||||
const response = await callSchema(loginTokensQuery) |
|
||||||
|
|
||||||
expect(response.errors).not.toBeUndefined() |
|
||||||
expect(response.data).toBeNull() |
|
||||||
}) |
|
||||||
|
|
||||||
it("return error for bad password", async () => { |
|
||||||
await User.create({ |
|
||||||
email: "email@email.com", |
|
||||||
password: "BAD-password", |
|
||||||
}).save() |
|
||||||
|
|
||||||
const response = await callSchema(loginTokensQuery) |
|
||||||
|
|
||||||
expect(response.errors).not.toBeUndefined() |
|
||||||
expect(response.data).toBeNull() |
|
||||||
}) |
|
||||||
|
|
||||||
it("return a valid access token with good credentials", async () => { |
|
||||||
await User.create({ |
|
||||||
email: "email@email.com", |
|
||||||
password: "good-password", |
|
||||||
}).save() |
|
||||||
|
|
||||||
const response = await callSchema(loginTokensQuery) |
|
||||||
const accessToken = response.data!.loginTokens.accessToken |
|
||||||
const loginTokens = new LoginTokens() |
|
||||||
loginTokens.accessToken = accessToken |
|
||||||
|
|
||||||
expect(response.errors).toBeUndefined() |
|
||||||
expect(response.data).toMatchObject({ loginTokens }) |
|
||||||
expect(verifyToken(accessToken)).toBeTruthy() |
|
||||||
}) |
|
||||||
}) |
|
||||||
|
|
||||||
describe("me query should", () => { |
|
||||||
const meQuery = gql` |
|
||||||
query { |
|
||||||
me { |
|
||||||
email |
|
||||||
} |
|
||||||
} |
|
||||||
` |
|
||||||
|
|
||||||
it("return an error without a valid jwt token", async () => { |
|
||||||
const context = { |
|
||||||
req: { |
|
||||||
headers: { |
|
||||||
authorization: "Bearer INVALID-TOKEN", |
|
||||||
}, |
|
||||||
}, |
|
||||||
} |
|
||||||
const response = await callSchema(meQuery, context) |
|
||||||
|
|
||||||
expect(response.errors).not.toBeUndefined() |
|
||||||
expect(response.data).toBeNull() |
|
||||||
}) |
|
||||||
|
|
||||||
it("return an user with a valid jwt token", async () => { |
|
||||||
const user = await User.create({ |
|
||||||
email: "email@email.com", |
|
||||||
}).save() |
|
||||||
|
|
||||||
const context = { |
|
||||||
req: { |
|
||||||
headers: { |
|
||||||
authorization: "Bearer " + signToken({ userId: user.id }), |
|
||||||
}, |
|
||||||
}, |
|
||||||
} |
|
||||||
|
|
||||||
const response = await callSchema(meQuery, context) |
|
||||||
|
|
||||||
expect(response.errors).toBeUndefined() |
|
||||||
expect(response.data).toMatchObject({ |
|
||||||
me: { email: user.email }, |
|
||||||
}) |
|
||||||
}) |
|
||||||
}) |
|
||||||
}) |
|
@ -1,58 +0,0 @@ |
|||||||
import { argon2id, hash, verify as argonVerify } from "argon2" |
|
||||||
import { Request, Response } from "express" |
|
||||||
import { readFileSync } from "fs" |
|
||||||
import { sign, verify as jwtVerify } from "jsonwebtoken" |
|
||||||
import { join } from "path" |
|
||||||
import { AuthChecker } from "type-graphql" |
|
||||||
|
|
||||||
let PRIVATE_KEY: Buffer |
|
||||||
let PUBLIC_KEY: Buffer |
|
||||||
|
|
||||||
export type Payload = { |
|
||||||
userId: number |
|
||||||
} |
|
||||||
|
|
||||||
export interface MyContext { |
|
||||||
req: Request |
|
||||||
res: Response |
|
||||||
payload?: Payload |
|
||||||
} |
|
||||||
|
|
||||||
export const hashPassword = async (password: string) => |
|
||||||
await hash(password, { type: argon2id }) |
|
||||||
|
|
||||||
export const comparePassword = async (hash: string, plain: string) => |
|
||||||
await argonVerify(hash, plain, { type: argon2id }) |
|
||||||
|
|
||||||
export const signToken = (payload: Payload) => { |
|
||||||
if (!PRIVATE_KEY) { |
|
||||||
PRIVATE_KEY = readKeyFile("jwtRS256.key") |
|
||||||
} |
|
||||||
|
|
||||||
return sign(payload, PRIVATE_KEY, { algorithm: "RS256" }) |
|
||||||
} |
|
||||||
|
|
||||||
export const verifyToken = (token: string) => { |
|
||||||
if (!PUBLIC_KEY) { |
|
||||||
PUBLIC_KEY = readKeyFile("jwtRS256.key.pub") |
|
||||||
} |
|
||||||
|
|
||||||
return jwtVerify(token, PUBLIC_KEY) |
|
||||||
} |
|
||||||
|
|
||||||
export const customAuthChecker: AuthChecker<MyContext> = ({ context }) => { |
|
||||||
try { |
|
||||||
const authHeader = context.req.headers["authorization"] |
|
||||||
const accessToken = authHeader!.split(" ")[1] |
|
||||||
const payload = verifyToken(accessToken) |
|
||||||
context.payload = payload as any |
|
||||||
|
|
||||||
return true |
|
||||||
} catch (error) { |
|
||||||
throw new Error("the valid authorization header is required: " + error) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
export const contextFunction = ({ req, res }: MyContext) => ({ req, res }) |
|
||||||
|
|
||||||
const readKeyFile = (fileName: string) => readFileSync(join(__dirname, "auth", fileName)) |
|
@ -1,18 +1,10 @@ |
|||||||
require("dotenv").config() |
require("dotenv").config() |
||||||
import { ConnectionOptions } from "typeorm" |
import { createConnection } from "typeorm" |
||||||
import { bootstrap } from "./app" |
import { createServer } from "./server" |
||||||
import { User } from "./app/userResolver/User" |
import { connectionOptions } from "./server/connection" |
||||||
|
;(async () => { |
||||||
|
await createConnection(connectionOptions()) |
||||||
|
|
||||||
let connectionOptions: ConnectionOptions = { |
const port = 4000 |
||||||
type: "postgres", |
await createServer(port) |
||||||
host: process.env.DB_HOST, |
})() |
||||||
port: 5432, |
|
||||||
database: process.env.DB_NAME, |
|
||||||
username: process.env.DB_USER, |
|
||||||
password: process.env.DB_PASS, |
|
||||||
entities: [User], |
|
||||||
synchronize: true, |
|
||||||
logging: false, |
|
||||||
} |
|
||||||
|
|
||||||
bootstrap(connectionOptions, 4000) |
|
||||||
|
@ -0,0 +1,13 @@ |
|||||||
|
require("dotenv").config() |
||||||
|
import { createConnection } from "typeorm" |
||||||
|
import { testingConnectionOptions } from "./server/testing" |
||||||
|
|
||||||
|
module.exports = async function() { |
||||||
|
const connection = await createConnection({ |
||||||
|
...testingConnectionOptions(), |
||||||
|
dropSchema: true, |
||||||
|
synchronize: true, |
||||||
|
}) |
||||||
|
|
||||||
|
await connection.close() |
||||||
|
} |
@ -0,0 +1,26 @@ |
|||||||
|
import { ApolloServer } from "apollo-server-express" |
||||||
|
import { createTestClient } from "apollo-server-testing" |
||||||
|
import { createConnection, getConnection } from "typeorm" |
||||||
|
import { createServer } from "./server" |
||||||
|
import { testingConnectionOptions } from "./server/testing" |
||||||
|
import auth = require("./server/userResolver/auth") |
||||||
|
|
||||||
|
describe("app should", () => { |
||||||
|
it("call the context function on apollo server", async () => { |
||||||
|
const spy = jest.spyOn(auth, "contextFunction") |
||||||
|
await createConnection(testingConnectionOptions()) |
||||||
|
|
||||||
|
const port = 4001 |
||||||
|
const server = (await createServer(port)) as any |
||||||
|
const { query } = createTestClient(server) |
||||||
|
await query({ query: "{me{email}}" }) |
||||||
|
|
||||||
|
expect(server).toBeInstanceOf(ApolloServer) |
||||||
|
expect(spy).toHaveBeenCalledTimes(1) |
||||||
|
|
||||||
|
spy.mockRestore() |
||||||
|
|
||||||
|
await server.stop() |
||||||
|
await getConnection().close() |
||||||
|
}) |
||||||
|
}) |
@ -1,12 +1,9 @@ |
|||||||
import express = require("express") |
import express = require("express") |
||||||
import { ApolloServer } from "apollo-server-express" |
import { ApolloServer } from "apollo-server-express" |
||||||
import { ConnectionOptions, createConnection } from "typeorm" |
import { createSchema } from "./server/schema" |
||||||
import { createSchema } from "./app/schema" |
import { contextFunction } from "./server/userResolver/auth" |
||||||
import { contextFunction } from "./app/userResolver/auth" |
|
||||||
|
|
||||||
export const bootstrap = async (connectionOptions: ConnectionOptions, port: number) => { |
|
||||||
await createConnection(connectionOptions) |
|
||||||
|
|
||||||
|
export const createServer = async (port: number) => { |
||||||
const server = new ApolloServer({ |
const server = new ApolloServer({ |
||||||
schema: await createSchema(), |
schema: await createSchema(), |
||||||
playground: true, |
playground: true, |
@ -0,0 +1,178 @@ |
|||||||
|
import { gql } from "apollo-server" |
||||||
|
import { Request, Response } from "express" |
||||||
|
import { createConnection, getConnection } from "typeorm" |
||||||
|
import { |
||||||
|
initializeTransactionalContext, |
||||||
|
patchTypeORMRepositoryWithBaseRepository, |
||||||
|
} from "typeorm-transactional-cls-hooked" |
||||||
|
import { callSchema } from "./schema" |
||||||
|
import { runInTransaction, testingConnectionOptions } from "./testing" |
||||||
|
import { ContextInterface, signAccessToken, verifyAccessToken } from "./userResolver/auth" |
||||||
|
import { LoginTokens } from "./userResolver/LoginTokens" |
||||||
|
import { User } from "./userResolver/User" |
||||||
|
|
||||||
|
beforeAll(async () => { |
||||||
|
initializeTransactionalContext() |
||||||
|
patchTypeORMRepositoryWithBaseRepository() |
||||||
|
|
||||||
|
await createConnection(testingConnectionOptions()) |
||||||
|
}) |
||||||
|
|
||||||
|
afterAll(async () => { |
||||||
|
await getConnection().close() |
||||||
|
}) |
||||||
|
|
||||||
|
describe("resolver of user", () => { |
||||||
|
describe("createUser mutation should", () => { |
||||||
|
it( |
||||||
|
"return email as it creates user with mutation", |
||||||
|
runInTransaction(async () => { |
||||||
|
const createUserMutation = gql` |
||||||
|
mutation { |
||||||
|
createUser(email: "email@email.com", password: "password") { |
||||||
|
email |
||||||
|
} |
||||||
|
} |
||||||
|
` |
||||||
|
|
||||||
|
const response = await callSchema(createUserMutation) |
||||||
|
|
||||||
|
expect(response.errors).toBeUndefined() |
||||||
|
expect(response.data).toMatchObject({ |
||||||
|
createUser: { email: "email@email.com" }, |
||||||
|
}) |
||||||
|
}) |
||||||
|
) |
||||||
|
}) |
||||||
|
|
||||||
|
describe("users query should", () => { |
||||||
|
it( |
||||||
|
"return emails of registered users", |
||||||
|
runInTransaction(async () => { |
||||||
|
const usersQuery = gql` |
||||||
|
query { |
||||||
|
users { |
||||||
|
email |
||||||
|
} |
||||||
|
} |
||||||
|
` |
||||||
|
|
||||||
|
const user = await User.create({ |
||||||
|
email: "email@email.com", |
||||||
|
}).save() |
||||||
|
|
||||||
|
const response = await callSchema(usersQuery) |
||||||
|
|
||||||
|
expect(response.errors).toBeUndefined() |
||||||
|
expect(response.data).toMatchObject({ |
||||||
|
users: [{ email: user.email }], |
||||||
|
}) |
||||||
|
}) |
||||||
|
) |
||||||
|
}) |
||||||
|
|
||||||
|
describe("loginTokens query should", () => { |
||||||
|
const loginTokensQuery = gql` |
||||||
|
query { |
||||||
|
loginTokens(email: "email@email.com", password: "good-password") { |
||||||
|
accessToken |
||||||
|
} |
||||||
|
} |
||||||
|
` |
||||||
|
|
||||||
|
it( |
||||||
|
"return error for non-existent user", |
||||||
|
runInTransaction(async () => { |
||||||
|
const response = await callSchema(loginTokensQuery) |
||||||
|
|
||||||
|
expect(response.errors).not.toBeUndefined() |
||||||
|
expect(response.data).toBeNull() |
||||||
|
}) |
||||||
|
) |
||||||
|
|
||||||
|
it( |
||||||
|
"return error for bad password", |
||||||
|
runInTransaction(async () => { |
||||||
|
await User.create({ |
||||||
|
email: "email@email.com", |
||||||
|
password: "BAD-password", |
||||||
|
}).save() |
||||||
|
|
||||||
|
const response = await callSchema(loginTokensQuery) |
||||||
|
|
||||||
|
expect(response.errors).not.toBeUndefined() |
||||||
|
expect(response.data).toBeNull() |
||||||
|
}) |
||||||
|
) |
||||||
|
|
||||||
|
it( |
||||||
|
"return a valid access token with good credentials", |
||||||
|
runInTransaction(async () => { |
||||||
|
await User.create({ |
||||||
|
email: "email@email.com", |
||||||
|
password: "good-password", |
||||||
|
}).save() |
||||||
|
|
||||||
|
const response = await callSchema(loginTokensQuery) |
||||||
|
const accessToken = response.data!.loginTokens.accessToken |
||||||
|
const loginTokens = new LoginTokens() |
||||||
|
loginTokens.accessToken = accessToken |
||||||
|
|
||||||
|
expect(response.errors).toBeUndefined() |
||||||
|
expect(response.data).toMatchObject({ loginTokens }) |
||||||
|
expect(verifyAccessToken(accessToken)).toBeTruthy() |
||||||
|
}) |
||||||
|
) |
||||||
|
}) |
||||||
|
|
||||||
|
describe("me query should", () => { |
||||||
|
const meQuery = gql` |
||||||
|
query { |
||||||
|
me { |
||||||
|
email |
||||||
|
} |
||||||
|
} |
||||||
|
` |
||||||
|
|
||||||
|
it( |
||||||
|
"return an error without a valid jwt token", |
||||||
|
runInTransaction(async () => { |
||||||
|
const contextWithInvalidToken = contextWithAuthHeader( |
||||||
|
"Bearer INVALID-TOKEN" |
||||||
|
) |
||||||
|
const response = await callSchema(meQuery, contextWithInvalidToken) |
||||||
|
|
||||||
|
expect(response.errors).not.toBeUndefined() |
||||||
|
expect(response.data).toBeNull() |
||||||
|
}) |
||||||
|
) |
||||||
|
|
||||||
|
it( |
||||||
|
"return an user with a valid jwt token", |
||||||
|
runInTransaction(async () => { |
||||||
|
const user = await User.create({ |
||||||
|
email: "email@email.com", |
||||||
|
}).save() |
||||||
|
|
||||||
|
const contextWithValidToken = contextWithAuthHeader( |
||||||
|
"Bearer " + signAccessToken({ userId: user.id }) |
||||||
|
) |
||||||
|
const response = await callSchema(meQuery, contextWithValidToken) |
||||||
|
|
||||||
|
expect(response.errors).toBeUndefined() |
||||||
|
expect(response.data).toMatchObject({ |
||||||
|
me: { email: user.email }, |
||||||
|
}) |
||||||
|
}) |
||||||
|
) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
const contextWithAuthHeader = (header: string): ContextInterface => ({ |
||||||
|
req: { |
||||||
|
headers: { |
||||||
|
authorization: header, |
||||||
|
}, |
||||||
|
} as Request, |
||||||
|
res: {} as Response, |
||||||
|
}) |
@ -0,0 +1,15 @@ |
|||||||
|
import { ConnectionOptions } from "typeorm" |
||||||
|
import { User } from "./userResolver/User" |
||||||
|
|
||||||
|
export const connectionOptions = (): ConnectionOptions => ({ |
||||||
|
type: "postgres", |
||||||
|
host: process.env.DB_HOST as string, |
||||||
|
port: parseInt(process.env.DB_PORT as string), |
||||||
|
database: process.env.DB_NAME as string, |
||||||
|
username: process.env.DB_USER as string, |
||||||
|
password: process.env.DB_PASS as string, |
||||||
|
entities: [User], |
||||||
|
dropSchema: false, |
||||||
|
synchronize: false, |
||||||
|
logging: false, |
||||||
|
}) |
@ -0,0 +1,40 @@ |
|||||||
|
import { ConnectionOptions } from "typeorm" |
||||||
|
import { Propagation, Transactional } from "typeorm-transactional-cls-hooked" |
||||||
|
import { connectionOptions } from "./connection" |
||||||
|
|
||||||
|
export const testingConnectionOptions = () => { |
||||||
|
const database = process.env.DB_NAME_TESING as string |
||||||
|
|
||||||
|
return { ...connectionOptions(), database } as ConnectionOptions |
||||||
|
} |
||||||
|
|
||||||
|
type RunFunction = () => Promise<void> | void |
||||||
|
|
||||||
|
class RollbackError extends Error { |
||||||
|
constructor(message: string) { |
||||||
|
super(message) |
||||||
|
|
||||||
|
this.name = this.constructor.name |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class TransactionCreator { |
||||||
|
@Transactional({ propagation: Propagation.REQUIRED }) |
||||||
|
static async run(func: RunFunction) { |
||||||
|
await func() |
||||||
|
throw new RollbackError(`This is thrown to cause a rollback on the transaction.`) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export function runInTransaction(func: RunFunction) { |
||||||
|
return async () => { |
||||||
|
try { |
||||||
|
await TransactionCreator.run(func) |
||||||
|
} catch (e) { |
||||||
|
/* istanbul ignore next */ |
||||||
|
if (!(e instanceof RollbackError)) { |
||||||
|
throw e |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,43 @@ |
|||||||
|
import { argon2id, hash, verify as argonVerify } from "argon2" |
||||||
|
import { Request, Response } from "express" |
||||||
|
import { sign, verify as jwtVerify } from "jsonwebtoken" |
||||||
|
import { AuthChecker } from "type-graphql" |
||||||
|
|
||||||
|
export type Payload = { |
||||||
|
userId: number |
||||||
|
} |
||||||
|
|
||||||
|
export interface ContextInterface { |
||||||
|
req: Request |
||||||
|
res: Response |
||||||
|
payload?: Payload |
||||||
|
} |
||||||
|
|
||||||
|
export const hashPassword = async (password: string) => |
||||||
|
await hash(password, { type: argon2id }) |
||||||
|
|
||||||
|
export const comparePassword = async (hash: string, plain: string) => |
||||||
|
await argonVerify(hash, plain, { type: argon2id }) |
||||||
|
|
||||||
|
export const signAccessToken = (payload: Payload) => { |
||||||
|
return sign(payload, process.env.ACCESS_SECRET!) |
||||||
|
} |
||||||
|
|
||||||
|
export const verifyAccessToken = (token: string) => { |
||||||
|
return jwtVerify(token, process.env.ACCESS_SECRET!) |
||||||
|
} |
||||||
|
|
||||||
|
export const customAuthChecker: AuthChecker<ContextInterface> = ({ context }) => { |
||||||
|
try { |
||||||
|
const authHeader = context.req.headers["authorization"] |
||||||
|
const accessToken = authHeader!.split(" ")[1] |
||||||
|
const payload = verifyAccessToken(accessToken) |
||||||
|
context.payload = payload as any |
||||||
|
|
||||||
|
return true |
||||||
|
} catch (error) { |
||||||
|
throw new Error("the valid authorization header is required: " + error) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export const contextFunction = ({ req, res }: ContextInterface) => ({ req, res }) |
Loading…
Reference in new issue