chore: some strictNullChecks mitigation (#9528)

This commit is contained in:
Elliot DeNolf
2024-11-26 09:04:06 -05:00
committed by GitHub
parent 71c2f63722
commit 4c4eb2ae2b
19 changed files with 41 additions and 55 deletions

View File

@@ -1,19 +1,13 @@
import type { GenericLanguages, I18n, I18nClient } from '@payloadcms/translations' import type { GenericLanguages, I18n } from '@payloadcms/translations'
import type { JSONSchema4 } from 'json-schema' import type { JSONSchema4 } from 'json-schema'
import type { ImportMap } from '../bin/generateImportMap/index.js'
import type { SanitizedCollectionConfig, TypeWithID } from '../collections/config/types.js' import type { SanitizedCollectionConfig, TypeWithID } from '../collections/config/types.js'
import type { Config, PayloadComponent, SanitizedConfig } from '../config/types.js' import type { Config, PayloadComponent, SanitizedConfig } from '../config/types.js'
import type { ValidationFieldError } from '../errors/ValidationError.js' import type { ValidationFieldError } from '../errors/ValidationError.js'
import type { import type { FieldAffectingData, RichTextField, Validate } from '../fields/config/types.js'
FieldAffectingData,
RichTextField,
RichTextFieldClient,
Validate,
} from '../fields/config/types.js'
import type { SanitizedGlobalConfig } from '../globals/config/types.js' import type { SanitizedGlobalConfig } from '../globals/config/types.js'
import type { RequestContext } from '../index.js' import type { RequestContext } from '../index.js'
import type { JsonObject, Payload, PayloadRequest, PopulateType } from '../types/index.js' import type { JsonObject, PayloadRequest, PopulateType } from '../types/index.js'
import type { RichTextFieldClientProps } from './fields/RichText.js' import type { RichTextFieldClientProps } from './fields/RichText.js'
import type { FieldSchemaMap } from './types.js' import type { FieldSchemaMap } from './types.js'

View File

@@ -42,13 +42,13 @@ export const apiKeyFields = [
hooks: { hooks: {
beforeValidate: [ beforeValidate: [
({ data, req, value }) => { ({ data, req, value }) => {
if (data.apiKey === false || data.apiKey === null) { if (data?.apiKey === false || data?.apiKey === null) {
return null return null
} }
if (data.enableAPIKey === false || data.enableAPIKey === null) { if (data?.enableAPIKey === false || data?.enableAPIKey === null) {
return null return null
} }
if (data.apiKey) { if (data?.apiKey) {
return crypto return crypto
.createHmac('sha1', req.payload.secret) .createHmac('sha1', req.payload.secret)
.update(data.apiKey as string) .update(data.apiKey as string)

View File

@@ -22,7 +22,7 @@ type CookieObject = {
path?: string path?: string
sameSite?: 'Lax' | 'None' | 'Strict' sameSite?: 'Lax' | 'None' | 'Strict'
secure?: boolean secure?: boolean
value: string value: string | undefined
} }
export const generateCookie = <ReturnCookieAsObject = boolean>( export const generateCookie = <ReturnCookieAsObject = boolean>(
@@ -191,13 +191,13 @@ export const parseCookies = (headers: Request['headers']): Map<string, string> =
if (cookie) { if (cookie) {
cookie.split(';').forEach((cookie) => { cookie.split(';').forEach((cookie) => {
const parts = cookie.split('=') const parts = cookie.split('=')
const key = parts.shift().trim() const key = parts.shift()?.trim()
const encodedValue = parts.join('=') const encodedValue = parts.join('=')
try { try {
const decodedValue = decodeURI(encodedValue) const decodedValue = decodeURI(encodedValue)
cookieMap.set(key, decodedValue) cookieMap.set(key, decodedValue)
} catch (e) { } catch (ignore) {
return null return null
} }
}) })

View File

@@ -19,7 +19,7 @@ export async function getAccessResults({
? payload.config.collections.find((collection) => collection.slug === user.collection) ? payload.config.collections.find((collection) => collection.slug === user.collection)
: null : null
if (userCollectionConfig && payload.config.admin.user === user.collection) { if (userCollectionConfig && payload.config.admin.user === user?.collection) {
results.canAccessAdmin = userCollectionConfig.access.admin results.canAccessAdmin = userCollectionConfig.access.admin
? await userCollectionConfig.access.admin({ req }) ? await userCollectionConfig.access.admin({ req })
: isLoggedIn : isLoggedIn

View File

@@ -42,7 +42,7 @@ export const getBaseAuthFields = (authConfig: IncomingAuthType): Field[] => {
authFields.push(...verificationFields) authFields.push(...verificationFields)
} }
if (authConfig.maxLoginAttempts > 0) { if (authConfig?.maxLoginAttempts && authConfig.maxLoginAttempts > 0) {
authFields.push(...accountLockFields) authFields.push(...accountLockFields)
} }
} }

View File

@@ -109,7 +109,7 @@ export const getFieldsToSign = (args: {
const { collectionConfig, email, user } = args const { collectionConfig, email, user } = args
const result: Record<string, unknown> = { const result: Record<string, unknown> = {
id: user.id, id: user?.id,
collection: collectionConfig.slug, collection: collectionConfig.slug,
email, email,
} }

View File

@@ -153,7 +153,7 @@ export const forgotPasswordOperation = async <TSlug extends CollectionSlug>(
<a href="${serverURL}${config.routes.admin}${config.admin.routes.reset}/${token}">${serverURL}${config.routes.admin}${config.admin.routes.reset}/${token}</a> <a href="${serverURL}${config.routes.admin}${config.admin.routes.reset}/${token}">${serverURL}${config.routes.admin}${config.admin.routes.reset}/${token}</a>
${req.t('authentication:youDidNotRequestPassword')}` ${req.t('authentication:youDidNotRequestPassword')}`
if (typeof collectionConfig.auth.forgotPassword.generateEmailHTML === 'function') { if (typeof collectionConfig.auth.forgotPassword?.generateEmailHTML === 'function') {
html = await collectionConfig.auth.forgotPassword.generateEmailHTML({ html = await collectionConfig.auth.forgotPassword.generateEmailHTML({
req, req,
token, token,
@@ -163,7 +163,7 @@ export const forgotPasswordOperation = async <TSlug extends CollectionSlug>(
let subject = req.t('authentication:resetYourPassword') let subject = req.t('authentication:resetYourPassword')
if (typeof collectionConfig.auth.forgotPassword.generateEmailSubject === 'function') { if (typeof collectionConfig.auth.forgotPassword?.generateEmailSubject === 'function') {
subject = await collectionConfig.auth.forgotPassword.generateEmailSubject({ subject = await collectionConfig.auth.forgotPassword.generateEmailSubject({
req, req,
token, token,

View File

@@ -42,4 +42,4 @@ async function localForgotPassword<T extends CollectionSlug>(
}) })
} }
export default localForgotPassword export const forgotPassword = localForgotPassword

View File

@@ -1,15 +1,8 @@
import { auth } from './auth.js' import { auth } from './auth.js'
import forgotPassword from './forgotPassword.js' import { forgotPassword } from './forgotPassword.js'
import login from './login.js' import { login } from './login.js'
import resetPassword from './resetPassword.js' import { resetPassword } from './resetPassword.js'
import unlock from './unlock.js' import { unlock } from './unlock.js'
import verifyEmail from './verifyEmail.js' import { verifyEmail } from './verifyEmail.js'
export default { export { auth, forgotPassword, login, resetPassword, unlock, verifyEmail }
auth,
forgotPassword,
login,
resetPassword,
unlock,
verifyEmail,
}

View File

@@ -24,7 +24,7 @@ export type Options<TSlug extends CollectionSlug> = {
showHiddenFields?: boolean showHiddenFields?: boolean
} }
async function localLogin<TSlug extends CollectionSlug>( export async function localLogin<TSlug extends CollectionSlug>(
payload: Payload, payload: Payload,
options: Options<TSlug>, options: Options<TSlug>,
): Promise<{ user: DataFromCollectionSlug<TSlug> } & Result> { ): Promise<{ user: DataFromCollectionSlug<TSlug> } & Result> {
@@ -62,4 +62,4 @@ async function localLogin<TSlug extends CollectionSlug>(
return result return result
} }
export default localLogin export const login = localLogin

View File

@@ -47,4 +47,4 @@ async function localResetPassword<T extends CollectionSlug>(
return result return result
} }
export default localResetPassword export const resetPassword = localResetPassword

View File

@@ -40,4 +40,4 @@ async function localUnlock<TSlug extends CollectionSlug>(
}) })
} }
export default localUnlock export const unlock = localUnlock

View File

@@ -33,4 +33,4 @@ async function localVerifyEmail<T extends CollectionSlug>(
}) })
} }
export default localVerifyEmail export const verifyEmail = localVerifyEmail

View File

@@ -34,13 +34,13 @@ async function autoLogin({
or: [], or: [],
} }
if (payload.config.admin?.autoLogin.email) { if (payload.config.admin?.autoLogin.email) {
where.or.push({ where.or?.push({
email: { email: {
equals: payload.config.admin?.autoLogin.email, equals: payload.config.admin?.autoLogin.email,
}, },
}) })
} else if (payload.config.admin?.autoLogin.username) { } else if (payload.config.admin?.autoLogin.username) {
where.or.push({ where.or?.push({
username: { username: {
equals: payload.config.admin?.autoLogin.username, equals: payload.config.admin?.autoLogin.username,
}, },
@@ -103,7 +103,7 @@ export const JWTAuthentication: AuthStrategyFunction = async ({
} }
return { user: null } return { user: null }
} }
} catch (error) { } catch (ignore) {
if (headers.get('DisableAutologin') !== 'true') { if (headers.get('DisableAutologin') !== 'true') {
return await autoLogin({ isGraphQL, payload }) return await autoLogin({ isGraphQL, payload })
} }

View File

@@ -38,7 +38,7 @@ export const registerLocalStrategy = async ({
} }
if (doc.email) { if (doc.email) {
whereConstraint.or.push({ whereConstraint.or?.push({
email: { email: {
equals: doc.email, equals: doc.email,
}, },
@@ -46,7 +46,7 @@ export const registerLocalStrategy = async ({
} }
if (doc.username) { if (doc.username) {
whereConstraint.or.push({ whereConstraint.or?.push({
username: { username: {
equals: doc.username, equals: doc.username,
}, },

View File

@@ -36,7 +36,7 @@ export const sanitizeCollection = async (
// Sanitize fields // Sanitize fields
// ///////////////////////////////// // /////////////////////////////////
const validRelationships = config.collections.reduce( const validRelationships = (config.collections || []).reduce(
(acc, c) => { (acc, c) => {
acc.push(c.slug) acc.push(c.slug)
return acc return acc
@@ -57,8 +57,8 @@ export const sanitizeCollection = async (
if (sanitized.timestamps !== false) { if (sanitized.timestamps !== false) {
// add default timestamps fields only as needed // add default timestamps fields only as needed
let hasUpdatedAt = null let hasUpdatedAt: boolean | null = null
let hasCreatedAt = null let hasCreatedAt: boolean | null = null
sanitized.fields.some((field) => { sanitized.fields.some((field) => {
if (fieldAffectsData(field)) { if (fieldAffectsData(field)) {
if (field.name === 'updatedAt') { if (field.name === 'updatedAt') {
@@ -144,7 +144,7 @@ export const sanitizeCollection = async (
sanitized.upload.bulkUpload = sanitized.upload?.bulkUpload ?? true sanitized.upload.bulkUpload = sanitized.upload?.bulkUpload ?? true
sanitized.upload.staticDir = sanitized.upload.staticDir || sanitized.slug sanitized.upload.staticDir = sanitized.upload.staticDir || sanitized.slug
sanitized.admin.useAsTitle = sanitized.admin.useAsTitle =
sanitized.admin.useAsTitle && sanitized.admin.useAsTitle !== 'id' sanitized.admin?.useAsTitle && sanitized.admin.useAsTitle !== 'id'
? sanitized.admin.useAsTitle ? sanitized.admin.useAsTitle
: 'filename' : 'filename'

View File

@@ -8,7 +8,7 @@ import flattenFields from '../../utilities/flattenTopLevelFields.js'
* Validate useAsTitle for collections. * Validate useAsTitle for collections.
*/ */
export const validateUseAsTitle = (config: CollectionConfig) => { export const validateUseAsTitle = (config: CollectionConfig) => {
if (config.admin.useAsTitle.includes('.')) { if (config.admin?.useAsTitle?.includes('.')) {
throw new InvalidConfiguration( throw new InvalidConfiguration(
`"useAsTitle" cannot be a nested field. Please specify a top-level field in the collection "${config.slug}"`, `"useAsTitle" cannot be a nested field. Please specify a top-level field in the collection "${config.slug}"`,
) )

View File

@@ -1,5 +1,5 @@
/* eslint-disable no-restricted-exports */ /* eslint-disable no-restricted-exports */
import auth from '../../../auth/operations/local/index.js' import * as auth from '../../../auth/operations/local/index.js'
import count from './count.js' import count from './count.js'
import countVersions from './countVersions.js' import countVersions from './countVersions.js'
import create from './create.js' import create from './create.js'

View File

@@ -167,16 +167,15 @@ export const saveVersion = async ({
} }
} }
} catch (err) { } catch (err) {
let errorMessage: string let errorMessage: string | undefined
if (collection) { if (collection) {
errorMessage = `There was an error while saving a version for the ${collection.labels.singular} with ID ${id}.` errorMessage = `There was an error while saving a version for the ${typeof collection.labels.singular === 'string' ? collection.labels.singular : collection.slug} with ID ${id}.`
} }
if (global) { if (global) {
errorMessage = `There was an error while saving a version for the global ${global.label}.` errorMessage = `There was an error while saving a version for the global ${typeof global.label === 'string' ? global.label : global.slug}.`
} }
payload.logger.error(errorMessage) payload.logger.error({ err, msg: errorMessage })
payload.logger.error(err)
return return
} }