Skip to content

Commit eb6bbd1

Browse files
committed
fix: minor bugs
1 parent 6a29e15 commit eb6bbd1

File tree

5 files changed

+25
-7
lines changed

5 files changed

+25
-7
lines changed

client/app/pages/[...collection]/index.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,9 @@ const filtered = computed(() => {
107107
return documents.value
108108
return documents.value.filter((document: any) => {
109109
for (const field of fields.value) {
110-
if (document[field].toString().toLowerCase().includes(search.value.toLowerCase()))
110+
// Add null/undefined check to prevent crashes
111+
const value = document[field]
112+
if (value != null && value.toString().toLowerCase().includes(search.value.toLowerCase()))
111113
return true
112114
}
113115
return false

src/rpc/database.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,10 @@ export function setupDatabaseRPC({}: DevtoolsServerContext) {
115115
if (!db) {
116116
return createError(new Error('Database not connected'))
117117
}
118+
// Validate ObjectId format
119+
if (!mongoose.Types.ObjectId.isValid(id)) {
120+
return createError(new Error('Invalid ObjectId format'))
121+
}
118122
return await db.collection(collection).findOne({ _id: new mongoose.Types.ObjectId(id) })
119123
}
120124
catch (error) {
@@ -128,6 +132,10 @@ export function setupDatabaseRPC({}: DevtoolsServerContext) {
128132
if (!db) {
129133
return createError(new Error('Database not connected'))
130134
}
135+
// Validate ObjectId format
136+
if (!mongoose.Types.ObjectId.isValid(_id)) {
137+
return createError(new Error('Invalid ObjectId format'))
138+
}
131139
return await db.collection(collection).updateOne({ _id: new mongoose.Types.ObjectId(_id) }, { $set: rest })
132140
}
133141
catch (error) {
@@ -140,6 +148,10 @@ export function setupDatabaseRPC({}: DevtoolsServerContext) {
140148
if (!db) {
141149
return createError(new Error('Database not connected'))
142150
}
151+
// Validate ObjectId format
152+
if (!mongoose.Types.ObjectId.isValid(id)) {
153+
return createError(new Error('Invalid ObjectId format'))
154+
}
143155
return await db.collection(collection).deleteOne({ _id: new mongoose.Types.ObjectId(id) })
144156
}
145157
catch (error) {

src/rpc/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ export function setupRPC(ctx: DevtoolsServerContext): ServerFunctions {
1111
logger.warn('MongoDB autoconnect is disabled, configure `uri` to enable.')
1212
}
1313
else {
14-
mongoose.connect(ctx.options.uri, ctx.options.options)
14+
mongoose.connect(ctx.options.uri, ctx.options.options).catch((err) => {
15+
logger.error('Failed to connect to MongoDB:', err)
16+
})
1517
}
1618

1719
return {

src/rpc/resource.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import fs from 'fs-extra'
22
import { join } from 'pathe'
33
import mongoose from 'mongoose'
4-
import type { Collection, DevtoolsServerContext, Resource, ServerFunctions } from '../types'
4+
import type { CollectionDefinition, DevtoolsServerContext, Resource, ServerFunctions } from '../types'
55
import { capitalize, generateApiRoute, generateSchemaFile, pluralize, singularize } from '../utils'
66

77
export function setupResourceRPC({ nuxt }: DevtoolsServerContext): any {
88
const config = nuxt.options.runtimeConfig.mongoose
99

1010
return {
11-
async generateResource(collection: Collection, resources: Resource[]) {
11+
async generateResource(collection: CollectionDefinition, resources: Resource[]) {
1212
const singular = singularize(collection.name).toLowerCase()
1313
const plural = pluralize(collection.name).toLowerCase()
1414
const dbName = capitalize(singular)
@@ -56,7 +56,9 @@ export function setupResourceRPC({ nuxt }: DevtoolsServerContext): any {
5656
const content = fs.readFileSync(schemaPath, 'utf-8').match(/schema: \{(.|\n)*\}/g)
5757
if (content) {
5858
const schemaString = content[0].replace('schema: ', '').slice(0, -3)
59-
const schema = eval(`(${schemaString})`)
59+
// SECURITY FIX: Use Function constructor instead of eval
60+
// eslint-disable-next-line no-new-func
61+
const schema = new Function(`return ${schemaString}`)()
6062
return schema
6163
}
6264
}

src/types/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export interface ServerFunctions {
3131
deleteDocument(collection: string, id: string): Promise<RPCResult<DeleteResult>>
3232

3333
// Resource - api-routes & models
34-
generateResource(collection: MCollection, resources: Resource[]): Promise<any>
34+
generateResource(collection: CollectionDefinition, resources: Resource[]): Promise<any>
3535
resourceSchema(collection: string): Promise<any>
3636
getCollectionSchema(collection: string): Promise<RPCResult<Record<string, { type: string }>>>
3737

@@ -48,7 +48,7 @@ export interface DevtoolsServerContext {
4848
wsServer: Promise<WebSocketServer>
4949
}
5050

51-
export interface Collection {
51+
export interface CollectionDefinition {
5252
name: string
5353
fields?: object[]
5454
}

0 commit comments

Comments
 (0)