mirror of
https://github.com/n8n-io/n8n.git
synced 2024-11-10 06:34:05 -08:00
test: Make oclif commands testable (#3571)
* ➕ Add `@oclif/core` * 📦 Update `package-lock.json` * 📘 Export `Logger` for use as type * ✨ Create `BaseCommand` * 🐛 Prevent DB re-init * ♻️ Refactor `reset` command * 🧪 Fix `reset` test * 👕 Add lint exception Co-authored-by: Jan Oberhauser <janober@users.noreply.github.com>
This commit is contained in:
parent
848fcfde5d
commit
7879239e03
275
package-lock.json
generated
275
package-lock.json
generated
|
@ -18,6 +18,7 @@
|
|||
"@kafkajs/confluent-schema-registry": "1.0.6",
|
||||
"@n8n_io/riot-tmpl": "^1.0.1",
|
||||
"@oclif/command": "^1.5.18",
|
||||
"@oclif/core": "^1.9.3",
|
||||
"@oclif/dev-cli": "^1.22.2",
|
||||
"@oclif/errors": "^1.2.2",
|
||||
"@rudderstack/rudder-sdk-node": "1.0.6",
|
||||
|
@ -11404,6 +11405,160 @@
|
|||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
|
||||
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
|
||||
},
|
||||
"node_modules/@oclif/core": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/@oclif/core/-/core-1.9.3.tgz",
|
||||
"integrity": "sha512-npxWULRu+iW9AuUNoCH118MNI8cxYIkcWkknz3mCDumTo11FC+h3OY1cMtlclqZHfZcDHh4iaSkNMX/7se9GUQ==",
|
||||
"dependencies": {
|
||||
"@oclif/linewrap": "^1.0.0",
|
||||
"@oclif/screen": "^3.0.2",
|
||||
"ansi-escapes": "^4.3.2",
|
||||
"ansi-styles": "^4.3.0",
|
||||
"cardinal": "^2.1.1",
|
||||
"chalk": "^4.1.2",
|
||||
"clean-stack": "^3.0.1",
|
||||
"cli-progress": "^3.10.0",
|
||||
"debug": "^4.3.4",
|
||||
"ejs": "^3.1.6",
|
||||
"fs-extra": "^9.1.0",
|
||||
"get-package-type": "^0.1.0",
|
||||
"globby": "^11.1.0",
|
||||
"hyperlinker": "^1.0.0",
|
||||
"indent-string": "^4.0.0",
|
||||
"is-wsl": "^2.2.0",
|
||||
"js-yaml": "^3.14.1",
|
||||
"natural-orderby": "^2.0.3",
|
||||
"object-treeify": "^1.1.33",
|
||||
"password-prompt": "^1.1.2",
|
||||
"semver": "^7.3.7",
|
||||
"string-width": "^4.2.3",
|
||||
"strip-ansi": "^6.0.1",
|
||||
"supports-color": "^8.1.1",
|
||||
"supports-hyperlinks": "^2.2.0",
|
||||
"tslib": "^2.3.1",
|
||||
"widest-line": "^3.1.0",
|
||||
"wrap-ansi": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oclif/core/node_modules/@oclif/screen": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@oclif/screen/-/screen-3.0.2.tgz",
|
||||
"integrity": "sha512-S/SF/XYJeevwIgHFmVDAFRUvM3m+OjhvCAYMk78ZJQCYCQ5wS7j+LTt1ZEv2jpEEGg2tx/F6TYYWxddNAYHrFQ==",
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oclif/core/node_modules/chalk": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@oclif/core/node_modules/chalk/node_modules/supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||
"dependencies": {
|
||||
"has-flag": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@oclif/core/node_modules/fs-extra": {
|
||||
"version": "9.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
|
||||
"integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
|
||||
"dependencies": {
|
||||
"at-least-node": "^1.0.0",
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@oclif/core/node_modules/jsonfile": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
|
||||
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
|
||||
"dependencies": {
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"node_modules/@oclif/core/node_modules/lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||
"dependencies": {
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@oclif/core/node_modules/semver": {
|
||||
"version": "7.3.7",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
|
||||
"integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
|
||||
"dependencies": {
|
||||
"lru-cache": "^6.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@oclif/core/node_modules/supports-color": {
|
||||
"version": "8.1.1",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
|
||||
"integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
|
||||
"dependencies": {
|
||||
"has-flag": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/supports-color?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@oclif/core/node_modules/tslib": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
|
||||
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
|
||||
},
|
||||
"node_modules/@oclif/core/node_modules/universalify": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
|
||||
"integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oclif/core/node_modules/yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
},
|
||||
"node_modules/@oclif/dev-cli": {
|
||||
"version": "1.26.10",
|
||||
"resolved": "https://registry.npmjs.org/@oclif/dev-cli/-/dev-cli-1.26.10.tgz",
|
||||
|
@ -69729,6 +69884,126 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"@oclif/core": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/@oclif/core/-/core-1.9.3.tgz",
|
||||
"integrity": "sha512-npxWULRu+iW9AuUNoCH118MNI8cxYIkcWkknz3mCDumTo11FC+h3OY1cMtlclqZHfZcDHh4iaSkNMX/7se9GUQ==",
|
||||
"requires": {
|
||||
"@oclif/linewrap": "^1.0.0",
|
||||
"@oclif/screen": "^3.0.2",
|
||||
"ansi-escapes": "^4.3.2",
|
||||
"ansi-styles": "^4.3.0",
|
||||
"cardinal": "^2.1.1",
|
||||
"chalk": "^4.1.2",
|
||||
"clean-stack": "^3.0.1",
|
||||
"cli-progress": "^3.10.0",
|
||||
"debug": "^4.3.4",
|
||||
"ejs": "^3.1.6",
|
||||
"fs-extra": "^9.1.0",
|
||||
"get-package-type": "^0.1.0",
|
||||
"globby": "^11.1.0",
|
||||
"hyperlinker": "^1.0.0",
|
||||
"indent-string": "^4.0.0",
|
||||
"is-wsl": "^2.2.0",
|
||||
"js-yaml": "^3.14.1",
|
||||
"natural-orderby": "^2.0.3",
|
||||
"object-treeify": "^1.1.33",
|
||||
"password-prompt": "^1.1.2",
|
||||
"semver": "^7.3.7",
|
||||
"string-width": "^4.2.3",
|
||||
"strip-ansi": "^6.0.1",
|
||||
"supports-color": "^8.1.1",
|
||||
"supports-hyperlinks": "^2.2.0",
|
||||
"tslib": "^2.3.1",
|
||||
"widest-line": "^3.1.0",
|
||||
"wrap-ansi": "^7.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@oclif/screen": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@oclif/screen/-/screen-3.0.2.tgz",
|
||||
"integrity": "sha512-S/SF/XYJeevwIgHFmVDAFRUvM3m+OjhvCAYMk78ZJQCYCQ5wS7j+LTt1ZEv2jpEEGg2tx/F6TYYWxddNAYHrFQ=="
|
||||
},
|
||||
"chalk": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
|
||||
"requires": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||
"requires": {
|
||||
"has-flag": "^4.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"fs-extra": {
|
||||
"version": "9.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
|
||||
"integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
|
||||
"requires": {
|
||||
"at-least-node": "^1.0.0",
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"jsonfile": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
|
||||
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.6",
|
||||
"universalify": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||
"requires": {
|
||||
"yallist": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "7.3.7",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
|
||||
"integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
|
||||
"requires": {
|
||||
"lru-cache": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "8.1.1",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
|
||||
"integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
|
||||
"requires": {
|
||||
"has-flag": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"tslib": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
|
||||
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
|
||||
},
|
||||
"universalify": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
|
||||
"integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ=="
|
||||
},
|
||||
"yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@oclif/dev-cli": {
|
||||
"version": "1.26.10",
|
||||
"resolved": "https://registry.npmjs.org/@oclif/dev-cli/-/dev-cli-1.26.10.tgz",
|
||||
|
|
57
packages/cli/commands/BaseCommand.ts
Normal file
57
packages/cli/commands/BaseCommand.ts
Normal file
|
@ -0,0 +1,57 @@
|
|||
import { Command } from '@oclif/core';
|
||||
import { LoggerProxy } from 'n8n-workflow';
|
||||
import { getLogger, Logger } from '../src/Logger';
|
||||
import { User } from '../src/databases/entities/User';
|
||||
import { Db } from '../src';
|
||||
|
||||
export abstract class BaseCommand extends Command {
|
||||
logger: Logger;
|
||||
|
||||
/**
|
||||
* Lifecycle methods
|
||||
*/
|
||||
|
||||
async init(): Promise<void> {
|
||||
this.logger = getLogger();
|
||||
LoggerProxy.init(this.logger);
|
||||
|
||||
await Db.init();
|
||||
}
|
||||
|
||||
async finally(): Promise<void> {
|
||||
if (process.env.NODE_ENV === 'test') return;
|
||||
|
||||
this.exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* User Management utils
|
||||
*/
|
||||
|
||||
defaultUserProps = {
|
||||
firstName: null,
|
||||
lastName: null,
|
||||
email: null,
|
||||
password: null,
|
||||
resetPasswordToken: null,
|
||||
};
|
||||
|
||||
async getInstanceOwner(): Promise<User> {
|
||||
const globalRole = await Db.collections.Role.findOneOrFail({
|
||||
name: 'owner',
|
||||
scope: 'global',
|
||||
});
|
||||
|
||||
const owner = await Db.collections.User.findOne({ globalRole });
|
||||
|
||||
if (owner) return owner;
|
||||
|
||||
const user = new User();
|
||||
|
||||
Object.assign(user, { ...this.defaultUserProps, globalRole });
|
||||
|
||||
await Db.collections.User.save(user);
|
||||
|
||||
return Db.collections.User.findOneOrFail({ globalRole });
|
||||
}
|
||||
}
|
|
@ -1,85 +1,51 @@
|
|||
/* eslint-disable no-console */
|
||||
|
||||
import Command from '@oclif/command';
|
||||
import { Not } from 'typeorm';
|
||||
import { LoggerProxy } from 'n8n-workflow';
|
||||
import { Db } from '../../src';
|
||||
import { User } from '../../src/databases/entities/User';
|
||||
import { getLogger } from '../../src/Logger';
|
||||
import { BaseCommand } from '../BaseCommand';
|
||||
|
||||
export class Reset extends Command {
|
||||
export class Reset extends BaseCommand {
|
||||
static description = '\nResets the database to the default user state';
|
||||
|
||||
private defaultUserProps = {
|
||||
firstName: null,
|
||||
lastName: null,
|
||||
email: null,
|
||||
password: null,
|
||||
resetPasswordToken: null,
|
||||
};
|
||||
|
||||
async run(): Promise<void> {
|
||||
const logger = getLogger();
|
||||
LoggerProxy.init(logger);
|
||||
await Db.init();
|
||||
const owner = await this.getInstanceOwner();
|
||||
|
||||
try {
|
||||
const owner = await this.getInstanceOwner();
|
||||
|
||||
const ownerWorkflowRole = await Db.collections.Role.findOneOrFail({
|
||||
name: 'owner',
|
||||
scope: 'workflow',
|
||||
});
|
||||
|
||||
const ownerCredentialRole = await Db.collections.Role.findOneOrFail({
|
||||
name: 'owner',
|
||||
scope: 'credential',
|
||||
});
|
||||
|
||||
await Db.collections.SharedWorkflow.update(
|
||||
{ user: { id: Not(owner.id) }, role: ownerWorkflowRole },
|
||||
{ user: owner },
|
||||
);
|
||||
|
||||
await Db.collections.SharedCredentials.update(
|
||||
{ user: { id: Not(owner.id) }, role: ownerCredentialRole },
|
||||
{ user: owner },
|
||||
);
|
||||
await Db.collections.User.delete({ id: Not(owner.id) });
|
||||
await Db.collections.User.save(Object.assign(owner, this.defaultUserProps));
|
||||
|
||||
await Db.collections.Settings.update(
|
||||
{ key: 'userManagement.isInstanceOwnerSetUp' },
|
||||
{ value: 'false' },
|
||||
);
|
||||
await Db.collections.Settings.update(
|
||||
{ key: 'userManagement.skipInstanceOwnerSetup' },
|
||||
{ value: 'false' },
|
||||
);
|
||||
} catch (error) {
|
||||
console.error('Error resetting database. See log messages for details.');
|
||||
if (error instanceof Error) logger.error(error.message);
|
||||
this.exit(1);
|
||||
}
|
||||
|
||||
console.info('Successfully reset the database to default user state.');
|
||||
this.exit();
|
||||
}
|
||||
|
||||
private async getInstanceOwner(): Promise<User> {
|
||||
const globalRole = await Db.collections.Role.findOneOrFail({
|
||||
const ownerWorkflowRole = await Db.collections.Role.findOneOrFail({
|
||||
name: 'owner',
|
||||
scope: 'global',
|
||||
scope: 'workflow',
|
||||
});
|
||||
|
||||
const owner = await Db.collections.User.findOne({ globalRole });
|
||||
const ownerCredentialRole = await Db.collections.Role.findOneOrFail({
|
||||
name: 'owner',
|
||||
scope: 'credential',
|
||||
});
|
||||
|
||||
if (owner) return owner;
|
||||
await Db.collections.SharedWorkflow.update(
|
||||
{ user: { id: Not(owner.id) }, role: ownerWorkflowRole },
|
||||
{ user: owner },
|
||||
);
|
||||
|
||||
const user = new User();
|
||||
await Db.collections.SharedCredentials.update(
|
||||
{ user: { id: Not(owner.id) }, role: ownerCredentialRole },
|
||||
{ user: owner },
|
||||
);
|
||||
|
||||
await Db.collections.User.save(Object.assign(user, { ...this.defaultUserProps, globalRole }));
|
||||
await Db.collections.User.delete({ id: Not(owner.id) });
|
||||
await Db.collections.User.save(Object.assign(owner, this.defaultUserProps));
|
||||
|
||||
return Db.collections.User.findOneOrFail({ globalRole });
|
||||
await Db.collections.Settings.update(
|
||||
{ key: 'userManagement.isInstanceOwnerSetUp' },
|
||||
{ value: 'false' },
|
||||
);
|
||||
await Db.collections.Settings.update(
|
||||
{ key: 'userManagement.skipInstanceOwnerSetup' },
|
||||
{ value: 'false' },
|
||||
);
|
||||
|
||||
this.logger.info('Successfully reset the database to default user state.');
|
||||
}
|
||||
|
||||
async catch(error: Error): Promise<void> {
|
||||
this.logger.error('Error resetting database. See log messages for details.');
|
||||
this.logger.error(error.message);
|
||||
this.exit(1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,6 +92,7 @@
|
|||
"typescript": "~4.6.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@oclif/core": "^1.9.3",
|
||||
"@apidevtools/swagger-cli": "4.0.0",
|
||||
"@oclif/command": "^1.5.18",
|
||||
"@oclif/errors": "^1.2.2",
|
||||
|
|
|
@ -45,6 +45,8 @@ export function linkRepository<Entity>(entityClass: EntityTarget<Entity>): Repos
|
|||
export async function init(
|
||||
testConnectionOptions?: ConnectionOptions,
|
||||
): Promise<IDatabaseCollections> {
|
||||
if (isInitialized) return collections;
|
||||
|
||||
const dbType = (await GenericHelpers.getConfigValue('database.type')) as DatabaseType;
|
||||
const n8nFolder = UserSettings.getUserN8nFolderPath();
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
/* eslint-disable @typescript-eslint/no-shadow */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
||||
|
||||
import { inspect } from 'util';
|
||||
import winston from 'winston';
|
||||
|
||||
|
@ -11,7 +12,7 @@ import callsites from 'callsites';
|
|||
import { basename } from 'path';
|
||||
import config from '../config';
|
||||
|
||||
class Logger implements ILogger {
|
||||
export class Logger implements ILogger {
|
||||
private logger: winston.Logger;
|
||||
|
||||
constructor() {
|
||||
|
@ -71,7 +72,7 @@ class Logger implements ILogger {
|
|||
}
|
||||
}
|
||||
|
||||
log(type: LogTypes, message: string, meta: object = {}) {
|
||||
log(type: LogTypes, message: string, meta: object = {}): void {
|
||||
const callsite = callsites();
|
||||
// We are using the third array element as the structure is as follows:
|
||||
// [0]: this file
|
||||
|
@ -93,23 +94,23 @@ class Logger implements ILogger {
|
|||
|
||||
// Convenience methods below
|
||||
|
||||
debug(message: string, meta: object = {}) {
|
||||
debug(message: string, meta: object = {}): void {
|
||||
this.log('debug', message, meta);
|
||||
}
|
||||
|
||||
info(message: string, meta: object = {}) {
|
||||
info(message: string, meta: object = {}): void {
|
||||
this.log('info', message, meta);
|
||||
}
|
||||
|
||||
error(message: string, meta: object = {}) {
|
||||
error(message: string, meta: object = {}): void {
|
||||
this.log('error', message, meta);
|
||||
}
|
||||
|
||||
verbose(message: string, meta: object = {}) {
|
||||
verbose(message: string, meta: object = {}): void {
|
||||
this.log('verbose', message, meta);
|
||||
}
|
||||
|
||||
warn(message: string, meta: object = {}) {
|
||||
warn(message: string, meta: object = {}): void {
|
||||
this.log('warn', message, meta);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
import { execSync } from 'child_process';
|
||||
|
||||
import express from 'express';
|
||||
import path from 'path';
|
||||
|
||||
import { Db } from '../../../src';
|
||||
import { Reset } from '../../../commands/user-management/reset';
|
||||
import * as utils from '../shared/utils';
|
||||
import type { Role } from '../../../src/databases/entities/Role';
|
||||
import * as testDb from '../shared/testDb';
|
||||
import { randomEmail, randomName, randomValidPassword } from '../shared/random';
|
||||
import type { Role } from '../../../src/databases/entities/Role';
|
||||
|
||||
let app: express.Application;
|
||||
let testDbName = '';
|
||||
|
@ -21,6 +18,10 @@ beforeAll(async () => {
|
|||
globalOwnerRole = await testDb.getGlobalOwnerRole();
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await testDb.truncate(['User'], testDbName);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await testDb.terminate(testDbName);
|
||||
});
|
||||
|
@ -28,17 +29,19 @@ afterAll(async () => {
|
|||
test('user-management:reset should reset DB to default user state', async () => {
|
||||
await testDb.createUser({ globalRole: globalOwnerRole });
|
||||
|
||||
const command = [path.join('bin', 'n8n'), 'user-management:reset'].join(' ');
|
||||
await Reset.run();
|
||||
|
||||
execSync(command);
|
||||
const user = await Db.collections.User.findOne({ globalRole: globalOwnerRole });
|
||||
|
||||
const user = await Db.collections.User.findOne();
|
||||
if (!user) {
|
||||
fail('No owner found after DB reset to default user state');
|
||||
}
|
||||
|
||||
expect(user?.email).toBeNull();
|
||||
expect(user?.firstName).toBeNull();
|
||||
expect(user?.lastName).toBeNull();
|
||||
expect(user?.password).toBeNull();
|
||||
expect(user?.resetPasswordToken).toBeNull();
|
||||
expect(user?.resetPasswordTokenExpiration).toBeNull();
|
||||
expect(user?.personalizationAnswers).toBeNull();
|
||||
expect(user.email).toBeNull();
|
||||
expect(user.firstName).toBeNull();
|
||||
expect(user.lastName).toBeNull();
|
||||
expect(user.password).toBeNull();
|
||||
expect(user.resetPasswordToken).toBeNull();
|
||||
expect(user.resetPasswordTokenExpiration).toBeNull();
|
||||
expect(user.personalizationAnswers).toBeNull();
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue