diff --git a/src/auth/crypto.ts b/src/auth/crypto.ts index fc37f9858b..4488e28a12 100644 --- a/src/auth/crypto.ts +++ b/src/auth/crypto.ts @@ -2,7 +2,7 @@ import crypto from 'crypto'; const algorithm = 'aes-256-ctr'; -export function encrypt(text) { +export function encrypt(text: string): string { const iv = crypto.randomBytes(16); const cipher = crypto.createCipheriv(algorithm, this.secret, iv); @@ -15,7 +15,7 @@ export function encrypt(text) { return result; } -export function decrypt(hash) { +export function decrypt(hash: string): string { const iv = hash.slice(0, 32); const content = hash.slice(32); diff --git a/src/auth/default.ts b/src/auth/defaultUser.ts similarity index 100% rename from src/auth/default.ts rename to src/auth/defaultUser.ts diff --git a/src/auth/executeAccess.ts b/src/auth/executeAccess.ts index 656cc4afc8..efaff7c169 100644 --- a/src/auth/executeAccess.ts +++ b/src/auth/executeAccess.ts @@ -1,3 +1,4 @@ +import { Access } from '../config/types'; import { Forbidden } from '../errors'; const executeAccess = async (operation, access) => { diff --git a/src/auth/getExecuteStaticAccess.ts b/src/auth/getExecuteStaticAccess.ts index 91f47a390f..3edbceb56b 100644 --- a/src/auth/getExecuteStaticAccess.ts +++ b/src/auth/getExecuteStaticAccess.ts @@ -1,7 +1,9 @@ +import { Response, NextFunction } from 'express'; import executeAccess from './executeAccess'; import { Forbidden } from '../errors'; +import { PayloadRequest } from '../express/types/payloadRequest'; -const getExecuteStaticAccess = ({ config, Model }) => async (req, res, next) => { +const getExecuteStaticAccess = ({ config, Model }) => async (req: PayloadRequest, res: Response, next: NextFunction) => { try { if (req.path) { const accessResult = await executeAccess({ req, isReadingStaticFile: true }, config.access.read); diff --git a/src/auth/getExtractJWT.ts b/src/auth/getExtractJWT.ts index 055e81093f..ca868cf942 100644 --- a/src/auth/getExtractJWT.ts +++ b/src/auth/getExtractJWT.ts @@ -1,6 +1,8 @@ +import { Request } from 'express'; +import { Config } from '../config/types'; import parseCookies from '../utilities/parseCookies'; -const getExtractJWT = (config) => (req) => { +const getExtractJWT = (config: Config) => (req: Request): string | null => { if (req && req.get) { const jwtFromHeader = req.get('Authorization'); const origin = req.get('Origin'); diff --git a/src/auth/requestHandlers/access.ts b/src/auth/requestHandlers/access.ts index d6be65d882..cea07ddea3 100644 --- a/src/auth/requestHandlers/access.ts +++ b/src/auth/requestHandlers/access.ts @@ -1,6 +1,7 @@ -const httpStatus = require('http-status'); +import { Request, Response, NextFunction } from 'express'; +import httpStatus from 'http-status'; -async function policiesHandler(req, res, next) { +export default async function policiesHandler(req: Request, res: Response, next: NextFunction): Promise { try { const accessResults = await this.operations.collections.auth.access({ req, @@ -12,5 +13,3 @@ async function policiesHandler(req, res, next) { return next(error); } } - -export default policiesHandler; diff --git a/src/auth/requestHandlers/forgotPassword.ts b/src/auth/requestHandlers/forgotPassword.ts index d5ab05f524..4af5a045e7 100644 --- a/src/auth/requestHandlers/forgotPassword.ts +++ b/src/auth/requestHandlers/forgotPassword.ts @@ -1,6 +1,7 @@ -const httpStatus = require('http-status'); +import { Request, Response, NextFunction } from 'express'; +import httpStatus from 'http-status'; -async function forgotPasswordHandler(req, res, next) { +export default async function forgotPasswordHandler(req: Request, res: Response, next: NextFunction): Promise { try { await this.operations.collections.auth.forgotPassword({ req, @@ -18,5 +19,3 @@ async function forgotPasswordHandler(req, res, next) { return next(error); } } - -export default forgotPasswordHandler; diff --git a/src/auth/requestHandlers/init.ts b/src/auth/requestHandlers/init.ts index 7acd0f6709..9c07c5007b 100644 --- a/src/auth/requestHandlers/init.ts +++ b/src/auth/requestHandlers/init.ts @@ -1,4 +1,6 @@ -async function initHandler(req, res, next) { +import { Request, Response, NextFunction } from 'express'; + +export default async function initHandler(req: Request, res: Response, next: NextFunction): Promise { try { const initialized = await this.operations.collections.auth.init({ Model: req.collection.Model }); return res.status(200).json({ initialized }); @@ -6,5 +8,3 @@ async function initHandler(req, res, next) { return next(error); } } - -export default initHandler; diff --git a/src/auth/requestHandlers/login.ts b/src/auth/requestHandlers/login.ts index 1e9fc286a4..d793e6fabb 100644 --- a/src/auth/requestHandlers/login.ts +++ b/src/auth/requestHandlers/login.ts @@ -1,6 +1,7 @@ +import { Request, Response, NextFunction } from 'express'; import httpStatus from 'http-status'; -async function loginHandler(req, res, next) { +export default async function loginHandler(req: Request, res: Response, next: NextFunction): Promise { try { const result = await this.operations.collections.auth.login({ req, @@ -21,5 +22,3 @@ async function loginHandler(req, res, next) { return next(error); } } - -export default loginHandler; diff --git a/src/auth/requestHandlers/logout.ts b/src/auth/requestHandlers/logout.ts index 5d871fe8db..7b4b6d84f6 100644 --- a/src/auth/requestHandlers/logout.ts +++ b/src/auth/requestHandlers/logout.ts @@ -1,4 +1,6 @@ -async function logoutHandler(req, res, next) { +import { Request, Response, NextFunction } from 'express'; + +export default async function logoutHandler(req: Request, res: Response, next: NextFunction) { try { const message = await this.operations.collections.auth.logout({ collection: req.collection, @@ -11,5 +13,3 @@ async function logoutHandler(req, res, next) { return next(error); } } - -export default logoutHandler; diff --git a/src/auth/requestHandlers/me.ts b/src/auth/requestHandlers/me.ts index 610460a2ff..d3fcd4bb5c 100644 --- a/src/auth/requestHandlers/me.ts +++ b/src/auth/requestHandlers/me.ts @@ -1,4 +1,6 @@ -async function me(req, res, next) { +import { NextFunction, Request, Response } from 'express'; + +export default async function me(req: Request, res: Response, next: NextFunction): Promise { try { const response = await this.operations.collections.auth.me({ req }); return res.status(200).json(response); @@ -6,5 +8,3 @@ async function me(req, res, next) { return next(err); } } - -export default me; diff --git a/src/auth/requestHandlers/refresh.ts b/src/auth/requestHandlers/refresh.ts index fa7f34d7a5..a2b21c4f5c 100644 --- a/src/auth/requestHandlers/refresh.ts +++ b/src/auth/requestHandlers/refresh.ts @@ -1,6 +1,7 @@ +import { Request, Response, NextFunction } from 'express'; import getExtractJWT from '../getExtractJWT'; -async function refreshHandler(req, res, next) { +export default async function refreshHandler(req: Request, res: Response, next: NextFunction): Promise { try { const extractJWT = getExtractJWT(this.config); const token = extractJWT(req); @@ -20,5 +21,3 @@ async function refreshHandler(req, res, next) { return next(error); } } - -export default refreshHandler; diff --git a/src/auth/requestHandlers/registerFirstUser.ts b/src/auth/requestHandlers/registerFirstUser.ts index 6593e7a22f..cce03cb6e1 100644 --- a/src/auth/requestHandlers/registerFirstUser.ts +++ b/src/auth/requestHandlers/registerFirstUser.ts @@ -1,4 +1,7 @@ -async function registerFirstUser(req, res, next) { + +import { Request, Response, NextFunction } from 'express'; + +export default async function registerFirstUser(req: Request, res: Response, next: NextFunction): Promise { try { const firstUser = await this.operations.collections.auth.registerFirstUser({ req, @@ -12,5 +15,3 @@ async function registerFirstUser(req, res, next) { return next(error); } } - -export default registerFirstUser; diff --git a/src/auth/requestHandlers/resetPassword.ts b/src/auth/requestHandlers/resetPassword.ts index 21d778e2fe..10b0bd0d79 100644 --- a/src/auth/requestHandlers/resetPassword.ts +++ b/src/auth/requestHandlers/resetPassword.ts @@ -1,6 +1,7 @@ +import { Request, Response, NextFunction } from 'express'; import httpStatus from 'http-status'; -async function resetPassword(req, res, next) { +async function resetPassword(req: Request, res: Response, next: NextFunction): Promise { try { const result = await this.operations.collections.auth.resetPassword({ req, diff --git a/src/auth/requestHandlers/unlock.ts b/src/auth/requestHandlers/unlock.ts index 1104c4216b..c167b23356 100644 --- a/src/auth/requestHandlers/unlock.ts +++ b/src/auth/requestHandlers/unlock.ts @@ -1,6 +1,7 @@ +import { Request, Response, NextFunction } from 'express'; import httpStatus from 'http-status'; -async function unlockHandler(req, res, next) { +export default async function unlockHandler(req: Request, res: Response, next: NextFunction): Promise { try { await this.operations.collections.auth.unlock({ req, @@ -16,5 +17,3 @@ async function unlockHandler(req, res, next) { return next(error); } } - -export default unlockHandler; diff --git a/src/auth/requestHandlers/verifyEmail.ts b/src/auth/requestHandlers/verifyEmail.ts index b32d5270c5..b918ee34be 100644 --- a/src/auth/requestHandlers/verifyEmail.ts +++ b/src/auth/requestHandlers/verifyEmail.ts @@ -1,6 +1,7 @@ +import { Request, Response, NextFunction } from 'express'; import httpStatus from 'http-status'; -async function verifyEmail(req, res, next) { +async function verifyEmail(req: Request, res: Response, next: NextFunction): Promise { try { await this.operations.collections.auth.verifyEmail({ collection: req.collection, diff --git a/src/config/find.ts b/src/config/find.ts index 71915c3aa6..08e2254695 100644 --- a/src/config/find.ts +++ b/src/config/find.ts @@ -1,7 +1,7 @@ import path from 'path'; import fs from 'fs'; -const findConfig = () => { +const findConfig = (): string => { // If the developer has specified a config path, // format it if relative and use it directly if absolute if (process.env.PAYLOAD_CONFIG_PATH) { diff --git a/src/config/sanitize.ts b/src/config/sanitize.ts index b276d81292..3b954c4863 100644 --- a/src/config/sanitize.ts +++ b/src/config/sanitize.ts @@ -1,5 +1,5 @@ import { Config } from './types'; -import defaultUser from '../auth/default'; +import defaultUser from '../auth/defaultUser'; import sanitizeCollection from '../collections/config/sanitize'; import { InvalidConfiguration } from '../errors'; import sanitizeGlobals from '../globals/config/sanitize'; diff --git a/src/config/types.ts b/src/config/types.ts index 84fa32f599..98d568007c 100644 --- a/src/config/types.ts +++ b/src/config/types.ts @@ -60,7 +60,7 @@ export type Config = { cookiePrefix?: string; csrf?: string[]; cors?: string[]; - publicENV: { [key: string]: string }; + publicENV?: { [key: string]: string }; routes?: { api?: string; admin?: string; @@ -102,7 +102,7 @@ export type Config = { maxComplexity?: number; disablePlaygroundInProduction?: boolean; }; - components: { [key: string]: JSX.Element | (() => JSX.Element) }; + components?: { [key: string]: JSX.Element | (() => JSX.Element) }; paths?: { [key: string]: string }; hooks?: { afterError?: () => void; diff --git a/src/email/types.ts b/src/email/types.ts index dbc81ccce9..d25abd6e89 100644 --- a/src/email/types.ts +++ b/src/email/types.ts @@ -9,11 +9,10 @@ export type Message = { html: string } +export type MockEmailHandler = { account: TestAccount; transport: Transporter }; export type BuildEmailResult = Promise<{ transport: Mail, transportOptions?: SMTPConnection.Options, fromName: string, fromAddress: string, -}> - -export type MockEmailHandler = { account: TestAccount; transport: Transporter }; +} | MockEmailHandler> diff --git a/src/express/types/payloadRequest.ts b/src/express/types/payloadRequest.ts new file mode 100644 index 0000000000..dd08c7eb6b --- /dev/null +++ b/src/express/types/payloadRequest.ts @@ -0,0 +1,9 @@ +import { Request } from 'express'; +import { Payload } from '../../index'; + + +export type PayloadRequest = Request & { + payload: Payload; + locale?: string; + // user: User +}; diff --git a/src/index.ts b/src/index.ts index ea94c2ab8b..6265b4580d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,9 +1,10 @@ -import express, { Express, Router } from 'express'; +import express, { Express, Request, Router } from 'express'; import crypto from 'crypto'; import { TestAccount } from 'nodemailer'; import { Config, + EmailOptions, InitOptions, } from './config/types'; import { @@ -18,7 +19,7 @@ import { UpdateOptions, DeleteOptions, } from './types'; -import Logger from './utilities/logger'; +import Logger, { PayloadLogger } from './utilities/logger'; import bindOperations from './init/bindOperations'; import bindRequestHandlers from './init/bindRequestHandlers'; import bindResolvers from './init/bindResolvers'; @@ -41,21 +42,22 @@ import localOperations from './collections/operations/local'; import localGlobalOperations from './globals/operations/local'; import { encrypt, decrypt } from './auth/crypto'; import { MockEmailHandler, BuildEmailResult, Message } from './email/types'; +import { PayloadRequest } from './express/types/payloadRequest'; require('isomorphic-fetch'); -class Payload { +export class Payload { config: Config; collections: Collection[] = []; - logger: typeof Logger; + logger: PayloadLogger; express: Express router: Router; - emailOptions: any; + emailOptions: EmailOptions; email: BuildEmailResult; @@ -84,6 +86,7 @@ class Payload { initAdmin: typeof initAdmin; performFieldOperations: typeof performFieldOperations; + // requestHandlers: { collections: { create: any; find: any; findByID: any; update: any; delete: any; auth: { access: any; forgotPassword: any; init: any; login: any; logout: any; me: any; refresh: any; registerFirstUser: any; resetPassword: any; verifyEmail: any; unlock: any; }; }; globals: { ...; }; }; init(options: InitOptions) { this.logger = Logger(); @@ -153,7 +156,7 @@ class Payload { } // Configure email service - this.email = buildEmail(this.emailOptions); + this.email = buildEmail(this.config.email); // Initialize collections & globals this.initCollections(); @@ -162,7 +165,7 @@ class Payload { // Connect to database connectMongoose(this.mongoURL); - options.express.use((req, res, next) => { + options.express.use((req: PayloadRequest, res, next) => { req.payload = this; next(); }); @@ -201,7 +204,7 @@ class Payload { if (typeof options.onInit === 'function') options.onInit(this); } - async sendEmail(message: Message) { + async sendEmail(message: Message): Promise { const email = await this.email; const result = email.transport.sendMail(message); return result; @@ -212,73 +215,73 @@ class Payload { return email.account; } - async create(options: CreateOptions) { + async create(options: CreateOptions): Promise { let { create } = localOperations; create = create.bind(this); return create(options); } - async find(options: FindOptions) { + async find(options: FindOptions): Promise { let { find } = localOperations; find = find.bind(this); return find(options); } - async findGlobal(options: FindGlobalOptions) { + async findGlobal(options: FindGlobalOptions): Promise { let { findOne } = localGlobalOperations; findOne = findOne.bind(this); return findOne(options); } - async updateGlobal(options: UpdateGlobalOptions) { + async updateGlobal(options: UpdateGlobalOptions): Promise { let { update } = localGlobalOperations; update = update.bind(this); return update(options); } - async findByID(options: FindByIDOptions) { + async findByID(options: FindByIDOptions): Promise { let { findByID } = localOperations; findByID = findByID.bind(this); return findByID(options); } - async update(options: UpdateOptions) { + async update(options: UpdateOptions): Promise { let { update } = localOperations; update = update.bind(this); return update(options); } - async delete(options: DeleteOptions) { + async delete(options: DeleteOptions): Promise { let { delete: deleteOperation } = localOperations; deleteOperation = deleteOperation.bind(this); return deleteOperation(options); } - async login(options) { + async login(options): Promise { let { login } = localOperations.auth; login = login.bind(this); return login(options); } - async forgotPassword(options) { + async forgotPassword(options): Promise { let { forgotPassword } = localOperations.auth; forgotPassword = forgotPassword.bind(this); return forgotPassword(options); } - async resetPassword(options) { + async resetPassword(options): Promise { let { resetPassword } = localOperations.auth; resetPassword = resetPassword.bind(this); return resetPassword(options); } - async unlock(options) { + async unlock(options): Promise { let { unlock } = localOperations.auth; unlock = unlock.bind(this); return unlock(options); } - async verifyEmail(options) { + async verifyEmail(options): Promise { let { verifyEmail } = localOperations.auth; verifyEmail = verifyEmail.bind(this); return verifyEmail(options); diff --git a/src/init/bindRequestHandlers.ts b/src/init/bindRequestHandlers.ts index 7533bc4a00..9c902df116 100644 --- a/src/init/bindRequestHandlers.ts +++ b/src/init/bindRequestHandlers.ts @@ -19,7 +19,7 @@ import deleteHandler from '../collections/requestHandlers/delete'; import findOne from '../globals/requestHandlers/findOne'; import globalUpdate from '../globals/requestHandlers/update'; -function bindRequestHandlers(ctx) { +function bindRequestHandlers(ctx): void { const payload = ctx; payload.requestHandlers = { diff --git a/src/utilities/logger.ts b/src/utilities/logger.ts index 99df2b98ea..382abe0cf1 100644 --- a/src/utilities/logger.ts +++ b/src/utilities/logger.ts @@ -1,7 +1,8 @@ import falsey from 'falsey'; import pino from 'pino'; import memoize from 'micro-memoize'; -import { PayloadLogger } from '../types'; + +export type PayloadLogger = pino.Logger; export default memoize((name = 'payload') => pino({ name, diff --git a/src/utilities/parseCookies.ts b/src/utilities/parseCookies.ts index 1b85505d32..a3d1949317 100644 --- a/src/utilities/parseCookies.ts +++ b/src/utilities/parseCookies.ts @@ -1,4 +1,6 @@ -function parseCookies(req) { +import { Request } from 'express'; + +export default function parseCookies(req: Request): { [key: string]: string } { const list = {}; const rc = req.headers.cookie; @@ -11,5 +13,3 @@ function parseCookies(req) { return list; } - -export default parseCookies; diff --git a/tsconfig.json b/tsconfig.json index 6bf4cbdf79..9f9f070069 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -66,7 +66,7 @@ "dist", "src/admin", "src/tests", - "src/tests/*", + "src/tests/**/*.spec.ts", // "**/*.d.ts", // "node_modules/" ]