fix: resolve login failure after batch import of username and password (#7076)

This commit is contained in:
ajie 2025-06-19 09:26:16 +08:00 committed by GitHub
parent aa0699c4a8
commit 0cbcd03390
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 90 additions and 10 deletions

View File

@ -40,4 +40,25 @@ describe('password field', () => {
user = await User.model.findOne();
expect(await pwd.verify('654321', user.password)).toBeTruthy();
});
it('should be encrypted when adding password fields in batches', async () => {
const User = db.collection({
name: 'users',
fields: [
{ type: 'string', name: 'name' },
{ type: 'password', name: 'password' },
],
});
await db.sync();
const instances = await User.model.bulkCreate([
{
password: '123456',
name: 'zhangsan',
},
]);
const pwd = User.getField<PasswordField>('password');
expect(await pwd.verify('123456', instances[0].password)).toBeTruthy();
const user = await User.model.findOne({ where: { name: 'zhangsan' } });
expect(await pwd.verify('123456', user.password)).toBeTruthy();
});
});

View File

@ -56,16 +56,19 @@ export class PasswordField extends Field {
init() {
const { name } = this.options;
this.listener = async (model: Model) => {
if (!model.changed(name as any)) {
return;
}
const value = model.get(name) as string;
if (value) {
const hash = await this.hash(value);
model.set(name, hash);
} else {
model.set(name, model.previous(name));
this.listener = async (instances: Model[]) => {
instances = Array.isArray(instances) ? instances : [instances];
for (const instance of instances) {
if (!instance.changed(name as any)) {
continue;
}
const value = instance.get(name) as string;
if (value) {
const hash = await this.hash(value);
instance.set(name, hash);
} else {
instance.set(name, instance.previous(name));
}
}
};
}
@ -73,12 +76,14 @@ export class PasswordField extends Field {
bind() {
super.bind();
this.on('beforeCreate', this.listener);
this.on('beforeBulkCreate', this.listener);
this.on('beforeUpdate', this.listener);
}
unbind() {
super.unbind();
this.off('beforeCreate', this.listener);
this.off('beforeBulkCreate', this.listener);
this.off('beforeUpdate', this.listener);
}
}

View File

@ -13,6 +13,7 @@ import { XlsxImporter } from '../services/xlsx-importer';
import XLSX from 'xlsx';
import * as process from 'node:process';
import moment from 'moment';
import { PasswordField } from '@nocobase/database';
describe('xlsx importer', () => {
let app: MockServer;
@ -2322,4 +2323,57 @@ describe('xlsx importer', () => {
expect(importer.run()).rejects.toThrow();
});
it('should import password field, insert data is encrypt', async () => {
const User = app.db.collection({
name: 'users',
fields: [
{ type: 'string', name: 'name' },
{ type: 'password', name: 'password' },
],
});
await app.db.sync();
const templateCreator = new TemplateCreator({
collection: User,
columns: [
{
dataIndex: ['name'],
defaultTitle: '姓名',
},
{
dataIndex: ['password'],
defaultTitle: '密码',
},
],
});
const template = (await templateCreator.run({ returnXLSXWorkbook: true })) as XLSX.WorkBook;
const worksheet = template.Sheets[template.SheetNames[0]];
XLSX.utils.sheet_add_aoa(worksheet, [['zhangsan', '123456']], {
origin: 'A2',
});
const importer = new XlsxImporter({
collectionManager: app.mainDataSource.collectionManager,
collection: User,
columns: [
{
dataIndex: ['name'],
defaultTitle: '姓名',
},
{
dataIndex: ['password'],
defaultTitle: '密码',
},
],
workbook: template,
});
await importer.run();
const pwd = User.getField<PasswordField>('password');
const user = await User.model.findOne({ where: { name: 'zhangsan' } });
expect(await pwd.verify('123456', user.password)).toBeTruthy();
});
});