mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-25 04:34:06 -08:00
fix: Fix typeorm .save usage (no-changelog) (#8678)
This commit is contained in:
parent
afd2eb1f4a
commit
05e13a68ea
|
@ -216,10 +216,13 @@ export const processUsers = async (
|
|||
export const saveLdapSynchronization = async (
|
||||
data: Omit<AuthProviderSyncHistory, 'id' | 'providerType'>,
|
||||
): Promise<void> => {
|
||||
await Container.get(AuthProviderSyncHistoryRepository).save({
|
||||
...data,
|
||||
providerType: 'ldap',
|
||||
});
|
||||
await Container.get(AuthProviderSyncHistoryRepository).save(
|
||||
{
|
||||
...data,
|
||||
providerType: 'ldap',
|
||||
},
|
||||
{ transaction: false },
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -257,15 +260,20 @@ export const getMappingAttributes = (ldapConfig: LdapConfig): string[] => {
|
|||
};
|
||||
|
||||
export const createLdapAuthIdentity = async (user: User, ldapId: string) => {
|
||||
return await Container.get(AuthIdentityRepository).save(AuthIdentity.create(user, ldapId));
|
||||
return await Container.get(AuthIdentityRepository).save(AuthIdentity.create(user, ldapId), {
|
||||
transaction: false,
|
||||
});
|
||||
};
|
||||
|
||||
export const createLdapUserOnLocalDb = async (data: Partial<User>, ldapId: string) => {
|
||||
const user = await Container.get(UserRepository).save({
|
||||
password: randomPassword(),
|
||||
role: 'global:member',
|
||||
...data,
|
||||
});
|
||||
const user = await Container.get(UserRepository).save(
|
||||
{
|
||||
password: randomPassword(),
|
||||
role: 'global:member',
|
||||
...data,
|
||||
},
|
||||
{ transaction: false },
|
||||
);
|
||||
await createLdapAuthIdentity(user, ldapId);
|
||||
return user;
|
||||
};
|
||||
|
|
|
@ -163,7 +163,7 @@ export class InvitationController {
|
|||
invitee.lastName = lastName;
|
||||
invitee.password = await this.passwordUtility.hash(validPassword);
|
||||
|
||||
const updatedUser = await this.userRepository.save(invitee);
|
||||
const updatedUser = await this.userRepository.save(invitee, { transaction: false });
|
||||
|
||||
await issueCookie(res, updatedUser);
|
||||
|
||||
|
|
|
@ -104,12 +104,13 @@ export class MeController {
|
|||
*/
|
||||
@Patch('/password')
|
||||
async updatePassword(req: MeRequest.Password, res: Response) {
|
||||
const { user } = req;
|
||||
const { currentPassword, newPassword } = req.body;
|
||||
|
||||
// If SAML is enabled, we don't allow the user to change their email address
|
||||
if (isSamlLicensedAndEnabled()) {
|
||||
this.logger.debug('Attempted to change password for user, while SAML is enabled', {
|
||||
userId: req.user?.id,
|
||||
userId: user.id,
|
||||
});
|
||||
throw new BadRequestError(
|
||||
'With SAML enabled, users need to use their SAML provider to change passwords',
|
||||
|
@ -120,33 +121,30 @@ export class MeController {
|
|||
throw new BadRequestError('Invalid payload.');
|
||||
}
|
||||
|
||||
if (!req.user.password) {
|
||||
if (!user.password) {
|
||||
throw new BadRequestError('Requesting user not set up.');
|
||||
}
|
||||
|
||||
const isCurrentPwCorrect = await this.passwordUtility.compare(
|
||||
currentPassword,
|
||||
req.user.password,
|
||||
);
|
||||
const isCurrentPwCorrect = await this.passwordUtility.compare(currentPassword, user.password);
|
||||
if (!isCurrentPwCorrect) {
|
||||
throw new BadRequestError('Provided current password is incorrect.');
|
||||
}
|
||||
|
||||
const validPassword = this.passwordUtility.validate(newPassword);
|
||||
|
||||
req.user.password = await this.passwordUtility.hash(validPassword);
|
||||
user.password = await this.passwordUtility.hash(validPassword);
|
||||
|
||||
const user = await this.userRepository.save(req.user);
|
||||
const updatedUser = await this.userRepository.save(user, { transaction: false });
|
||||
this.logger.info('Password updated successfully', { userId: user.id });
|
||||
|
||||
await issueCookie(res, user);
|
||||
await issueCookie(res, updatedUser);
|
||||
|
||||
void this.internalHooks.onUserUpdate({
|
||||
user,
|
||||
user: updatedUser,
|
||||
fields_changed: ['password'],
|
||||
});
|
||||
|
||||
await this.externalHooks.run('user.password.update', [user.email, req.user.password]);
|
||||
await this.externalHooks.run('user.password.update', [updatedUser.email, updatedUser.password]);
|
||||
|
||||
return { success: true };
|
||||
}
|
||||
|
@ -168,11 +166,13 @@ export class MeController {
|
|||
throw new BadRequestError('Personalization answers are mandatory');
|
||||
}
|
||||
|
||||
await this.userRepository.save({
|
||||
id: req.user.id,
|
||||
// @ts-ignore
|
||||
personalizationAnswers,
|
||||
});
|
||||
await this.userRepository.save(
|
||||
{
|
||||
id: req.user.id,
|
||||
personalizationAnswers,
|
||||
},
|
||||
{ transaction: false },
|
||||
);
|
||||
|
||||
this.logger.info('User survey updated successfully', { userId: req.user.id });
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ export class OwnerController {
|
|||
|
||||
await validateEntity(owner);
|
||||
|
||||
owner = await this.userRepository.save(owner);
|
||||
owner = await this.userRepository.save(owner, { transaction: false });
|
||||
|
||||
this.logger.info('Owner was set up successfully', { userId });
|
||||
|
||||
|
|
|
@ -12,7 +12,11 @@ export class SettingsRepository extends Repository<Settings> {
|
|||
}
|
||||
|
||||
async getEncryptedSecretsProviderSettings(): Promise<string | null> {
|
||||
return (await this.findOne({ where: { key: EXTERNAL_SECRETS_DB_KEY } }))?.value ?? null;
|
||||
return (await this.findByKey(EXTERNAL_SECRETS_DB_KEY))?.value ?? null;
|
||||
}
|
||||
|
||||
async findByKey(key: string): Promise<Settings | null> {
|
||||
return await this.findOneBy({ key });
|
||||
}
|
||||
|
||||
async saveEncryptedSecretsProviderSettings(data: string): Promise<void> {
|
||||
|
@ -38,7 +42,7 @@ export class SettingsRepository extends Repository<Settings> {
|
|||
await this.update({ key }, { value, loadOnStartup: true });
|
||||
} else {
|
||||
value = JSON.stringify([bannerName]);
|
||||
await this.save({ key, value, loadOnStartup: true });
|
||||
await this.save({ key, value, loadOnStartup: true }, { transaction: false });
|
||||
}
|
||||
config.set(key, value);
|
||||
return { success: true };
|
||||
|
|
|
@ -492,7 +492,7 @@ export class SourceControlImportService {
|
|||
key,
|
||||
value: valueOverrides[key],
|
||||
});
|
||||
await Container.get(VariablesRepository).save(newVariable);
|
||||
await Container.get(VariablesRepository).save(newVariable, { transaction: false });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -173,11 +173,14 @@ export class SourceControlPreferencesService {
|
|||
if (saveToDb) {
|
||||
const settingsValue = JSON.stringify(this._sourceControlPreferences);
|
||||
try {
|
||||
await Container.get(SettingsRepository).save({
|
||||
key: SOURCE_CONTROL_PREFERENCES_DB_KEY,
|
||||
value: settingsValue,
|
||||
loadOnStartup: true,
|
||||
});
|
||||
await Container.get(SettingsRepository).save(
|
||||
{
|
||||
key: SOURCE_CONTROL_PREFERENCES_DB_KEY,
|
||||
value: settingsValue,
|
||||
loadOnStartup: true,
|
||||
},
|
||||
{ transaction: false },
|
||||
);
|
||||
} catch (error) {
|
||||
throw new ApplicationError('Failed to save source control preferences', { cause: error });
|
||||
}
|
||||
|
|
|
@ -71,10 +71,13 @@ export class VariablesService {
|
|||
this.validateVariable(variable);
|
||||
|
||||
void Container.get(InternalHooks).onVariableCreated({ variable_type: variable.type });
|
||||
const saveResult = await this.variablesRepository.save({
|
||||
...variable,
|
||||
id: generateNanoId(),
|
||||
});
|
||||
const saveResult = await this.variablesRepository.save(
|
||||
{
|
||||
...variable,
|
||||
id: generateNanoId(),
|
||||
},
|
||||
{ transaction: false },
|
||||
);
|
||||
await this.updateCache();
|
||||
return saveResult;
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ export class TagService {
|
|||
|
||||
await this.externalHooks.run(`tag.before${action}`, [tag]);
|
||||
|
||||
const savedTag = this.tagRepository.save(tag);
|
||||
const savedTag = this.tagRepository.save(tag, { transaction: false });
|
||||
|
||||
await this.externalHooks.run(`tag.after${action}`, [tag]);
|
||||
|
||||
|
|
|
@ -287,13 +287,18 @@ export class SamlService {
|
|||
let result: Settings;
|
||||
if (samlPreferences) {
|
||||
samlPreferences.value = settingsValue;
|
||||
result = await Container.get(SettingsRepository).save(samlPreferences);
|
||||
} else {
|
||||
result = await Container.get(SettingsRepository).save({
|
||||
key: SAML_PREFERENCES_DB_KEY,
|
||||
value: settingsValue,
|
||||
loadOnStartup: true,
|
||||
result = await Container.get(SettingsRepository).save(samlPreferences, {
|
||||
transaction: false,
|
||||
});
|
||||
} else {
|
||||
result = await Container.get(SettingsRepository).save(
|
||||
{
|
||||
key: SAML_PREFERENCES_DB_KEY,
|
||||
value: settingsValue,
|
||||
loadOnStartup: true,
|
||||
},
|
||||
{ transaction: false },
|
||||
);
|
||||
}
|
||||
if (result) return jsonParse<SamlPreferences>(result.value);
|
||||
return;
|
||||
|
|
|
@ -109,10 +109,12 @@ export async function createUserFromSamlAttributes(attributes: SamlUserAttribute
|
|||
authIdentity.providerId = attributes.userPrincipalName;
|
||||
authIdentity.providerType = 'saml';
|
||||
authIdentity.user = user;
|
||||
const resultAuthIdentity = await Container.get(AuthIdentityRepository).save(authIdentity);
|
||||
const resultAuthIdentity = await Container.get(AuthIdentityRepository).save(authIdentity, {
|
||||
transaction: false,
|
||||
});
|
||||
if (!resultAuthIdentity) throw new AuthError('Could not create AuthIdentity');
|
||||
user.authIdentities = [authIdentity];
|
||||
const resultUser = await Container.get(UserRepository).save(user);
|
||||
const resultUser = await Container.get(UserRepository).save(user, { transaction: false });
|
||||
if (!resultUser) throw new AuthError('Could not create User');
|
||||
return resultUser;
|
||||
}
|
||||
|
@ -133,10 +135,10 @@ export async function updateUserFromSamlAttributes(
|
|||
} else {
|
||||
samlAuthIdentity.providerId = attributes.userPrincipalName;
|
||||
}
|
||||
await Container.get(AuthIdentityRepository).save(samlAuthIdentity);
|
||||
await Container.get(AuthIdentityRepository).save(samlAuthIdentity, { transaction: false });
|
||||
user.firstName = attributes.firstName;
|
||||
user.lastName = attributes.lastName;
|
||||
const resultUser = await Container.get(UserRepository).save(user);
|
||||
const resultUser = await Container.get(UserRepository).save(user, { transaction: false });
|
||||
if (!resultUser) throw new AuthError('Could not create User');
|
||||
return resultUser;
|
||||
}
|
||||
|
|
|
@ -13,11 +13,14 @@ export async function setCurrentAuthenticationMethod(
|
|||
authenticationMethod: AuthProviderType,
|
||||
): Promise<void> {
|
||||
config.set('userManagement.authenticationMethod', authenticationMethod);
|
||||
await Container.get(SettingsRepository).save({
|
||||
key: 'userManagement.authenticationMethod',
|
||||
value: authenticationMethod,
|
||||
loadOnStartup: true,
|
||||
});
|
||||
await Container.get(SettingsRepository).save(
|
||||
{
|
||||
key: 'userManagement.authenticationMethod',
|
||||
value: authenticationMethod,
|
||||
loadOnStartup: true,
|
||||
},
|
||||
{ transaction: false },
|
||||
);
|
||||
}
|
||||
|
||||
export function getCurrentAuthenticationMethod(): AuthProviderType {
|
||||
|
|
|
@ -192,6 +192,17 @@ describe('MeController', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('storeSurveyAnswers', () => {
|
||||
it('should throw BadRequestError if answers are missing in the payload', async () => {
|
||||
const req = mock<MeRequest.SurveyAnswers>({
|
||||
body: undefined,
|
||||
});
|
||||
await expect(controller.storeSurveyAnswers(req)).rejects.toThrowError(
|
||||
new BadRequestError('Personalization answers are mandatory'),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('API Key methods', () => {
|
||||
let req: AuthenticatedRequest;
|
||||
beforeAll(() => {
|
||||
|
|
|
@ -95,7 +95,7 @@ describe('OwnerController', () => {
|
|||
|
||||
await controller.setupOwner(req, res);
|
||||
|
||||
expect(userRepository.save).toHaveBeenCalledWith(user);
|
||||
expect(userRepository.save).toHaveBeenCalledWith(user, { transaction: false });
|
||||
|
||||
const cookieOptions = captor<CookieOptions>();
|
||||
expect(res.cookie).toHaveBeenCalledWith(AUTH_COOKIE_NAME, 'signed-token', cookieOptions);
|
||||
|
|
Loading…
Reference in a new issue