Skip to content

Commit 04f6702

Browse files
authored
Merge branch 'main' into feature/audit-telemetry-gdpr-deletion
2 parents 018a133 + 06dc0e1 commit 04f6702

5 files changed

Lines changed: 52 additions & 19 deletions

File tree

packages/server/src/controllers/variables/index.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,12 @@ const createVariable = async (req: Request, res: Response, next: NextFunction) =
2222
throw new InternalFlowiseError(StatusCodes.NOT_FOUND, `Error: toolsController.createTool - workspace ${workspaceId} not found!`)
2323
}
2424
const body = req.body
25-
body.workspaceId = workspaceId
25+
// Explicit allowlist — id/workspaceId/timestamps must not be overrideable by client
2626
const newVariable = new Variable()
27-
Object.assign(newVariable, body)
27+
if (body.name !== undefined) newVariable.name = body.name
28+
if (body.value !== undefined) newVariable.value = body.value
29+
if (body.type !== undefined) newVariable.type = body.type
30+
newVariable.workspaceId = workspaceId
2831
const apiResponse = await variablesService.createVariable(newVariable, orgId)
2932
return res.json(apiResponse)
3033
} catch (error) {
@@ -91,8 +94,11 @@ const updateVariable = async (req: Request, res: Response, next: NextFunction) =
9194
return res.status(404).send('Variable not found in the database')
9295
}
9396
const body = req.body
97+
// Explicit allowlist — id/workspaceId/timestamps must not be overrideable by client
9498
const updatedVariable = new Variable()
95-
Object.assign(updatedVariable, body)
99+
if (body.name !== undefined) updatedVariable.name = body.name
100+
if (body.value !== undefined) updatedVariable.value = body.value
101+
if (body.type !== undefined) updatedVariable.type = body.type
96102
const apiResponse = await variablesService.updateVariable(variable, updatedVariable)
97103
return res.json(apiResponse)
98104
} catch (error) {

packages/server/src/enterprise/controllers/user.controller.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,11 @@ export class UserController {
5656
if (!currentUser) {
5757
throw new InternalFlowiseError(StatusCodes.UNAUTHORIZED, UserErrorMessage.USER_NOT_FOUND)
5858
}
59-
const { id } = req.body
59+
const { id, name, oldPassword, newPassword, confirmPassword } = req.body
6060
if (currentUser.id !== id) {
6161
throw new InternalFlowiseError(StatusCodes.FORBIDDEN, UserErrorMessage.USER_NOT_FOUND)
6262
}
63-
const user = await userService.updateUser(req.body)
63+
const user = await userService.updateUser({ id, name, updatedBy: currentUser.id, oldPassword, newPassword, confirmPassword })
6464
return res.status(StatusCodes.OK).json(user)
6565
} catch (error) {
6666
next(error)

packages/server/src/enterprise/services/user.service.ts

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -150,16 +150,10 @@ export class UserService {
150150
if (!updateUserData) throw new InternalFlowiseError(StatusCodes.NOT_FOUND, UserErrorMessage.USER_NOT_FOUND)
151151
}
152152

153-
newUserData.createdBy = oldUserData.createdBy
154-
155153
if (newUserData.name) {
156154
this.validateUserName(newUserData.name)
157155
}
158156

159-
if (newUserData.status) {
160-
this.validateUserStatus(newUserData.status)
161-
}
162-
163157
if (newUserData.oldPassword && newUserData.newPassword && newUserData.confirmPassword) {
164158
if (!oldUserData.credential) {
165159
throw new InternalFlowiseError(StatusCodes.BAD_REQUEST, UserErrorMessage.INVALID_USER_CREDENTIAL)
@@ -176,7 +170,23 @@ export class UserService {
176170
newUserData.tokenExpiry = undefined
177171
}
178172

179-
updatedUser = queryRunner.manager.merge(User, oldUserData, newUserData)
173+
const safePatch: Partial<User> = {
174+
createdBy: oldUserData.createdBy // always preserve from DB
175+
}
176+
177+
if (newUserData.name) {
178+
safePatch.name = newUserData.name
179+
}
180+
181+
safePatch.updatedBy = newUserData.updatedBy // always set (controller forces req.user.id)
182+
if (newUserData.oldPassword && newUserData.newPassword && newUserData.confirmPassword) {
183+
// credential/tempToken/tokenExpiry were set by the validated workflow above
184+
safePatch.credential = newUserData.credential
185+
safePatch.tempToken = newUserData.tempToken
186+
safePatch.tokenExpiry = newUserData.tokenExpiry
187+
}
188+
189+
updatedUser = queryRunner.manager.merge(User, oldUserData, safePatch)
180190
await queryRunner.startTransaction()
181191
await this.saveUser(updatedUser, queryRunner)
182192
await queryRunner.commitTransaction()

packages/server/src/services/variables/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,9 @@ const updateVariable = async (variable: Variable, updatedVariable: Variable) =>
103103
if (appServer.identityManager.getPlatformType() === Platform.CLOUD && updatedVariable.type === 'runtime')
104104
throw new InternalFlowiseError(StatusCodes.BAD_REQUEST, 'Cloud platform does not support runtime variables!')
105105
try {
106+
const originalWorkspaceId = variable.workspaceId
106107
const tmpUpdatedVariable = await appServer.AppDataSource.getRepository(Variable).merge(variable, updatedVariable)
108+
tmpUpdatedVariable.workspaceId = originalWorkspaceId
107109
const dbResponse = await appServer.AppDataSource.getRepository(Variable).save(tmpUpdatedVariable)
108110
return dbResponse
109111
} catch (error) {

packages/ui/src/ui-component/input/RichInput.jsx

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,19 @@ const isHtmlContent = (content) => {
2323
}
2424

2525
// define your extension array
26-
const extensions = (availableNodesForVariable, availableState, acceptNodeOutputAsVariable, nodes, nodeData, isNodeInsideInteration) => [
26+
const extensions = (
27+
availableNodesForVariable,
28+
availableState,
29+
acceptNodeOutputAsVariable,
30+
nodes,
31+
nodeData,
32+
isNodeInsideInteration,
33+
useMarkdown
34+
) => [
2735
Markdown,
2836
StarterKit.configure({
29-
codeBlock: false
37+
codeBlock: false,
38+
...(!useMarkdown && { link: false })
3039
}),
3140
CustomMention.configure({
3241
HTMLAttributes: {
@@ -103,6 +112,7 @@ const StyledEditorContent = styled(EditorContent)(({ theme, rows, disabled, isDa
103112
}))
104113

105114
export const RichInput = ({ inputParam, value, nodes, edges, nodeId, onChange, disabled = false }) => {
115+
const useMarkdown = !!inputParam?.rows
106116
const customization = useSelector((state) => state.customization)
107117
const isDarkMode = customization.isDarkMode
108118
const [availableNodesForVariable, setAvailableNodesForVariable] = useState([])
@@ -135,15 +145,20 @@ export const RichInput = ({ inputParam, value, nodes, edges, nodeId, onChange, d
135145
inputParam?.acceptNodeOutputAsVariable,
136146
nodes,
137147
nodeData,
138-
isNodeInsideInteration
148+
isNodeInsideInteration,
149+
useMarkdown
139150
),
140151
Placeholder.configure({ placeholder: inputParam?.placeholder })
141152
],
142153
content: '',
143154
onUpdate: ({ editor }) => {
144-
try {
145-
onChange(editor.getMarkdown())
146-
} catch {
155+
if (useMarkdown) {
156+
try {
157+
onChange(editor.getMarkdown())
158+
} catch {
159+
onChange(editor.getHTML())
160+
}
161+
} else {
147162
onChange(editor.getHTML())
148163
}
149164
},
@@ -155,7 +170,7 @@ export const RichInput = ({ inputParam, value, nodes, edges, nodeId, onChange, d
155170
// Load initial content after editor is ready, detecting HTML vs markdown
156171
useEffect(() => {
157172
if (editor && value) {
158-
if (isHtmlContent(value)) {
173+
if (!useMarkdown || isHtmlContent(value)) {
159174
editor.commands.setContent(value)
160175
} else {
161176
editor.commands.setContent(value, { contentType: 'markdown' })

0 commit comments

Comments
 (0)