-
Notifications
You must be signed in to change notification settings - Fork 7.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create reset command for user management (#2698)
* ✨ Create reset command * 📌 Pin chokidar version * ⚡ Set default user name per migration * ⚡ Create owner if empty users table * 👕 Remove some lint exceptions * 🐛 Set role for reassigned workflows and creds * ✏️ Add success message * ⚡ Add access modifiers
- Loading branch information
Showing
2 changed files
with
81 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
/* eslint-disable no-console */ | ||
/* eslint-disable @typescript-eslint/no-non-null-assertion */ | ||
|
||
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'; | ||
|
||
export class Reset extends Command { | ||
static description = '\nResets the database to the default user state'; | ||
|
||
private defaultUserProps = { | ||
firstName: 'default', | ||
lastName: 'default', | ||
email: null, | ||
password: null, | ||
resetPasswordToken: null, | ||
}; | ||
|
||
async run(): Promise<void> { | ||
const logger = getLogger(); | ||
LoggerProxy.init(logger); | ||
await Db.init(); | ||
|
||
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: Not(owner) }, | ||
{ user: { ...owner, globalRole: ownerWorkflowRole } }, | ||
); | ||
|
||
await Db.collections.SharedCredentials!.update( | ||
{ user: Not(owner) }, | ||
{ user: { ...owner, globalRole: ownerCredentialRole } }, | ||
); | ||
|
||
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.hasOwner' }, { 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({ | ||
name: 'owner', | ||
scope: 'global', | ||
}); | ||
|
||
const owner = await Db.collections.User!.findOne({ globalRole }); | ||
|
||
if (owner) return owner; | ||
|
||
const user = new User(); | ||
|
||
await Db.collections.User!.save(Object.assign(user, { ...this.defaultUserProps, globalRole })); | ||
|
||
return Db.collections.User!.findOneOrFail({ globalRole }); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters