fix: allow custom password field when using disableLocalStrategy: true (#11893)

Fixes https://github.com/payloadcms/payload/issues/11888

Previously, if you had `disableLocalStategy: true` and a custom
`password` field, Payload would still control it in `update.ts` by
deleting. Now, we don't do that in this case, unless we have
`disableLocalStetegy.enableFields: true`.
This commit is contained in:
Sasha
2025-04-04 20:52:10 +03:00
committed by GitHub
parent b76844dac9
commit 8ad22eb1c0
4 changed files with 89 additions and 1 deletions

View File

@@ -99,7 +99,14 @@ export const updateDocument = async <
const password = data?.password const password = data?.password
const shouldSaveDraft = const shouldSaveDraft =
Boolean(draftArg && collectionConfig.versions.drafts) && data._status !== 'published' Boolean(draftArg && collectionConfig.versions.drafts) && data._status !== 'published'
const shouldSavePassword = Boolean(password && collectionConfig.auth && !shouldSaveDraft) const shouldSavePassword = Boolean(
password &&
collectionConfig.auth &&
(!collectionConfig.auth.disableLocalStrategy ||
(typeof collectionConfig.auth.disableLocalStrategy === 'object' &&
collectionConfig.auth.disableLocalStrategy.enableFields)) &&
!shouldSaveDraft,
)
// ///////////////////////////////////// // /////////////////////////////////////
// Handle potentially locked documents // Handle potentially locked documents

View File

@@ -203,6 +203,17 @@ export default buildConfigWithDefaults({
// lock_until // lock_until
], ],
}, },
{
slug: 'disable-local-strategy-password',
auth: { disableLocalStrategy: true },
fields: [
{
name: 'password',
type: 'text',
required: true,
},
],
},
{ {
slug: apiKeysSlug, slug: apiKeysSlug,
access: { access: {

View File

@@ -786,6 +786,20 @@ describe('Auth', () => {
expect(response.status).toBe(403) expect(response.status).toBe(403)
}) })
it('should allow to use password field', async () => {
const doc = await payload.create({
collection: 'disable-local-strategy-password',
data: { password: '123' },
})
expect(doc.password).toBe('123')
const updated = await payload.update({
collection: 'disable-local-strategy-password',
data: { password: '1234' },
id: doc.id,
})
expect(updated.password).toBe('1234')
})
}) })
describe('API Key', () => { describe('API Key', () => {

View File

@@ -54,6 +54,7 @@ export type SupportedTimezones =
| 'Asia/Singapore' | 'Asia/Singapore'
| 'Asia/Tokyo' | 'Asia/Tokyo'
| 'Asia/Seoul' | 'Asia/Seoul'
| 'Australia/Brisbane'
| 'Australia/Sydney' | 'Australia/Sydney'
| 'Pacific/Guam' | 'Pacific/Guam'
| 'Pacific/Noumea' | 'Pacific/Noumea'
@@ -64,6 +65,7 @@ export interface Config {
auth: { auth: {
users: UserAuthOperations; users: UserAuthOperations;
'partial-disable-local-strategies': PartialDisableLocalStrategyAuthOperations; 'partial-disable-local-strategies': PartialDisableLocalStrategyAuthOperations;
'disable-local-strategy-password': DisableLocalStrategyPasswordAuthOperations;
'api-keys': ApiKeyAuthOperations; 'api-keys': ApiKeyAuthOperations;
'public-users': PublicUserAuthOperations; 'public-users': PublicUserAuthOperations;
}; };
@@ -71,6 +73,7 @@ export interface Config {
collections: { collections: {
users: User; users: User;
'partial-disable-local-strategies': PartialDisableLocalStrategy; 'partial-disable-local-strategies': PartialDisableLocalStrategy;
'disable-local-strategy-password': DisableLocalStrategyPassword;
'api-keys': ApiKey; 'api-keys': ApiKey;
'public-users': PublicUser; 'public-users': PublicUser;
relationsCollection: RelationsCollection; relationsCollection: RelationsCollection;
@@ -82,6 +85,7 @@ export interface Config {
collectionsSelect: { collectionsSelect: {
users: UsersSelect<false> | UsersSelect<true>; users: UsersSelect<false> | UsersSelect<true>;
'partial-disable-local-strategies': PartialDisableLocalStrategiesSelect<false> | PartialDisableLocalStrategiesSelect<true>; 'partial-disable-local-strategies': PartialDisableLocalStrategiesSelect<false> | PartialDisableLocalStrategiesSelect<true>;
'disable-local-strategy-password': DisableLocalStrategyPasswordSelect<false> | DisableLocalStrategyPasswordSelect<true>;
'api-keys': ApiKeysSelect<false> | ApiKeysSelect<true>; 'api-keys': ApiKeysSelect<false> | ApiKeysSelect<true>;
'public-users': PublicUsersSelect<false> | PublicUsersSelect<true>; 'public-users': PublicUsersSelect<false> | PublicUsersSelect<true>;
relationsCollection: RelationsCollectionSelect<false> | RelationsCollectionSelect<true>; relationsCollection: RelationsCollectionSelect<false> | RelationsCollectionSelect<true>;
@@ -102,6 +106,9 @@ export interface Config {
| (PartialDisableLocalStrategy & { | (PartialDisableLocalStrategy & {
collection: 'partial-disable-local-strategies'; collection: 'partial-disable-local-strategies';
}) })
| (DisableLocalStrategyPassword & {
collection: 'disable-local-strategy-password';
})
| (ApiKey & { | (ApiKey & {
collection: 'api-keys'; collection: 'api-keys';
}) })
@@ -149,6 +156,24 @@ export interface PartialDisableLocalStrategyAuthOperations {
password: string; password: string;
}; };
} }
export interface DisableLocalStrategyPasswordAuthOperations {
forgotPassword: {
email: string;
password: string;
};
login: {
email: string;
password: string;
};
registerFirstUser: {
email: string;
password: string;
};
unlock: {
email: string;
password: string;
};
}
export interface ApiKeyAuthOperations { export interface ApiKeyAuthOperations {
forgotPassword: { forgotPassword: {
email: string; email: string;
@@ -242,6 +267,16 @@ export interface PartialDisableLocalStrategy {
lockUntil?: string | null; lockUntil?: string | null;
password?: string | null; password?: string | null;
} }
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "disable-local-strategy-password".
*/
export interface DisableLocalStrategyPassword {
id: string;
password: string;
updatedAt: string;
createdAt: string;
}
/** /**
* This interface was referenced by `Config`'s JSON-Schema * This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "api-keys". * via the `definition` "api-keys".
@@ -299,6 +334,10 @@ export interface PayloadLockedDocument {
relationTo: 'partial-disable-local-strategies'; relationTo: 'partial-disable-local-strategies';
value: string | PartialDisableLocalStrategy; value: string | PartialDisableLocalStrategy;
} | null) } | null)
| ({
relationTo: 'disable-local-strategy-password';
value: string | DisableLocalStrategyPassword;
} | null)
| ({ | ({
relationTo: 'api-keys'; relationTo: 'api-keys';
value: string | ApiKey; value: string | ApiKey;
@@ -321,6 +360,10 @@ export interface PayloadLockedDocument {
relationTo: 'partial-disable-local-strategies'; relationTo: 'partial-disable-local-strategies';
value: string | PartialDisableLocalStrategy; value: string | PartialDisableLocalStrategy;
} }
| {
relationTo: 'disable-local-strategy-password';
value: string | DisableLocalStrategyPassword;
}
| { | {
relationTo: 'api-keys'; relationTo: 'api-keys';
value: string | ApiKey; value: string | ApiKey;
@@ -347,6 +390,10 @@ export interface PayloadPreference {
relationTo: 'partial-disable-local-strategies'; relationTo: 'partial-disable-local-strategies';
value: string | PartialDisableLocalStrategy; value: string | PartialDisableLocalStrategy;
} }
| {
relationTo: 'disable-local-strategy-password';
value: string | DisableLocalStrategyPassword;
}
| { | {
relationTo: 'api-keys'; relationTo: 'api-keys';
value: string | ApiKey; value: string | ApiKey;
@@ -440,6 +487,15 @@ export interface PartialDisableLocalStrategiesSelect<T extends boolean = true> {
loginAttempts?: T; loginAttempts?: T;
lockUntil?: T; lockUntil?: T;
} }
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "disable-local-strategy-password_select".
*/
export interface DisableLocalStrategyPasswordSelect<T extends boolean = true> {
password?: T;
updatedAt?: T;
createdAt?: T;
}
/** /**
* This interface was referenced by `Config`'s JSON-Schema * This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "api-keys_select". * via the `definition` "api-keys_select".