mirror of
https://github.com/farcasclaudiu/Flowise.git
synced 2026-06-22 07:01:07 +03:00
feature/cli-reset-password (#4585)
* feat: add cli to reset password * chore: add information for password reset command * fix: add information for password reset command
This commit is contained in:
@@ -20,6 +20,9 @@
|
||||
"start-worker": "run-script-os",
|
||||
"start-worker:windows": "cd packages/server/bin && run worker",
|
||||
"start-worker:default": "cd packages/server/bin && ./run worker",
|
||||
"user": "run-script-os",
|
||||
"user:windows": "cd packages/server/bin && run user",
|
||||
"user:default": "cd packages/server/bin && ./run user",
|
||||
"test": "turbo run test",
|
||||
"clean": "pnpm --filter \"./packages/**\" clean",
|
||||
"nuke": "pnpm --filter \"./packages/**\" nuke && rimraf node_modules .turbo",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Command, Flags } from '@oclif/core'
|
||||
import path from 'path'
|
||||
import dotenv from 'dotenv'
|
||||
import path from 'path'
|
||||
import logger from '../utils/logger'
|
||||
|
||||
dotenv.config({ path: path.join(__dirname, '..', '..', '.env'), override: true })
|
||||
@@ -120,7 +120,7 @@ export abstract class BaseCommand extends Command {
|
||||
logger.error('unhandledRejection: ', err)
|
||||
})
|
||||
|
||||
const { flags } = await this.parse(BaseCommand)
|
||||
const { flags } = await this.parse(this.constructor as any)
|
||||
if (flags.PORT) process.env.PORT = flags.PORT
|
||||
if (flags.CORS_ORIGINS) process.env.CORS_ORIGINS = flags.CORS_ORIGINS
|
||||
if (flags.IFRAME_ORIGINS) process.env.IFRAME_ORIGINS = flags.IFRAME_ORIGINS
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
import { Args } from '@oclif/core'
|
||||
import { QueryRunner } from 'typeorm'
|
||||
import * as DataSource from '../DataSource'
|
||||
import { User } from '../enterprise/database/entities/user.entity'
|
||||
import { getHash } from '../enterprise/utils/encryption.util'
|
||||
import { isInvalidPassword } from '../enterprise/utils/validation.util'
|
||||
import logger from '../utils/logger'
|
||||
import { BaseCommand } from './base'
|
||||
|
||||
export default class user extends BaseCommand {
|
||||
static args = {
|
||||
email: Args.string({
|
||||
description: 'Email address to search for in the user database'
|
||||
}),
|
||||
password: Args.string({
|
||||
description: 'New password for that user'
|
||||
})
|
||||
}
|
||||
|
||||
async run(): Promise<void> {
|
||||
const { args } = await this.parse(user)
|
||||
|
||||
let queryRunner: QueryRunner | undefined
|
||||
try {
|
||||
logger.info('Initializing DataSource')
|
||||
const dataSource = await DataSource.getDataSource()
|
||||
await dataSource.initialize()
|
||||
|
||||
queryRunner = dataSource.createQueryRunner()
|
||||
await queryRunner.connect()
|
||||
|
||||
if (args.email && args.password) {
|
||||
logger.info('Running resetPassword')
|
||||
await this.resetPassword(queryRunner, args.email, args.password)
|
||||
} else {
|
||||
logger.info('Running listUserEmails')
|
||||
await this.listUserEmails(queryRunner)
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error(error)
|
||||
} finally {
|
||||
if (queryRunner && !queryRunner.isReleased) await queryRunner.release()
|
||||
await this.gracefullyExit()
|
||||
}
|
||||
}
|
||||
|
||||
async listUserEmails(queryRunner: QueryRunner) {
|
||||
logger.info('Listing all user emails')
|
||||
const users = await queryRunner.manager.find(User, {
|
||||
select: ['email']
|
||||
})
|
||||
|
||||
const emails = users.map((user) => user.email)
|
||||
logger.info(`Email addresses: ${emails.join(', ')}`)
|
||||
logger.info(`Email count: ${emails.length}`)
|
||||
logger.info('To reset user password, run the following command: pnpm user --email "myEmail" --password "myPassword"')
|
||||
}
|
||||
|
||||
async resetPassword(queryRunner: QueryRunner, email: string, password: string) {
|
||||
logger.info(`Finding user by email: ${email}`)
|
||||
const user = await queryRunner.manager.findOne(User, {
|
||||
where: { email }
|
||||
})
|
||||
if (!user) throw new Error(`User not found with email: ${email}`)
|
||||
|
||||
if (isInvalidPassword(password)) {
|
||||
const errors = []
|
||||
if (!/(?=.*[a-z])/.test(password)) errors.push('at least one lowercase letter')
|
||||
if (!/(?=.*[A-Z])/.test(password)) errors.push('at least one uppercase letter')
|
||||
if (!/(?=.*\d)/.test(password)) errors.push('at least one number')
|
||||
if (!/(?=.*[^a-zA-Z0-9])/.test(password)) errors.push('at least one special character')
|
||||
if (password.length < 8) errors.push('minimum length of 8 characters')
|
||||
throw new Error(`Invalid password: Must contain ${errors.join(', ')}`)
|
||||
}
|
||||
|
||||
user.credential = getHash(password)
|
||||
await queryRunner.manager.save(user)
|
||||
logger.info(`Password reset for user: ${email}`)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user