Switching from .toString to .toSQL().toNative() for sql injection protection.
This commit is contained in:
parent
20d7d36a16
commit
738b5af4c0
|
@ -47,7 +47,7 @@ function addFilters(query, filters) {
|
||||||
function buildCreate(knex, json) {
|
function buildCreate(knex, json) {
|
||||||
const { endpoint, body } = json
|
const { endpoint, body } = json
|
||||||
let query = knex(endpoint.entityId)
|
let query = knex(endpoint.entityId)
|
||||||
return query.insert(body).toString()
|
return query.insert(body)
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildRead(knex, json, limit) {
|
function buildRead(knex, json, limit) {
|
||||||
|
@ -78,21 +78,21 @@ function buildRead(knex, json, limit) {
|
||||||
} else {
|
} else {
|
||||||
query.limit(limit)
|
query.limit(limit)
|
||||||
}
|
}
|
||||||
return query.toString()
|
return query
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildUpdate(knex, json) {
|
function buildUpdate(knex, json) {
|
||||||
const { endpoint, body, filters } = json
|
const { endpoint, body, filters } = json
|
||||||
let query = knex(endpoint.entityId)
|
let query = knex(endpoint.entityId)
|
||||||
query = addFilters(query, filters)
|
query = addFilters(query, filters)
|
||||||
return query.update(body).toString()
|
return query.update(body)
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildDelete(knex, json) {
|
function buildDelete(knex, json) {
|
||||||
const { endpoint, filters } = json
|
const { endpoint, filters } = json
|
||||||
let query = knex(endpoint.entityId)
|
let query = knex(endpoint.entityId)
|
||||||
query = addFilters(query, filters)
|
query = addFilters(query, filters)
|
||||||
return query.delete().toString()
|
return query.delete()
|
||||||
}
|
}
|
||||||
|
|
||||||
class SqlQueryBuilder {
|
class SqlQueryBuilder {
|
||||||
|
@ -102,22 +102,28 @@ class SqlQueryBuilder {
|
||||||
this._limit = limit
|
this._limit = limit
|
||||||
}
|
}
|
||||||
|
|
||||||
query(json) {
|
_query(json) {
|
||||||
const { endpoint } = json
|
const { endpoint } = json
|
||||||
const knex = require("knex")({ client: this._client })
|
const knex = require("knex")({ client: this._client })
|
||||||
const operation = endpoint.operation
|
const operation = endpoint.operation
|
||||||
|
let query
|
||||||
switch (operation) {
|
switch (operation) {
|
||||||
case Operation.CREATE:
|
case Operation.CREATE:
|
||||||
return buildCreate(knex, json)
|
query = buildCreate(knex, json)
|
||||||
|
break
|
||||||
case Operation.READ:
|
case Operation.READ:
|
||||||
return buildRead(knex, json, this._limit)
|
query = buildRead(knex, json, this._limit)
|
||||||
|
break
|
||||||
case Operation.UPDATE:
|
case Operation.UPDATE:
|
||||||
return buildUpdate(knex, json)
|
query = buildUpdate(knex, json)
|
||||||
|
break
|
||||||
case Operation.DELETE:
|
case Operation.DELETE:
|
||||||
return buildDelete(knex, json)
|
query = buildDelete(knex, json)
|
||||||
|
break
|
||||||
default:
|
default:
|
||||||
throw `Operation ${operation} type is not supported by SQL query builder`
|
throw `Operation ${operation} type is not supported by SQL query builder`
|
||||||
}
|
}
|
||||||
|
return query.toSQL().toNative()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,30 +54,39 @@ describe("SQL query builder", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should test a basic read", () => {
|
it("should test a basic read", () => {
|
||||||
const query = sql.query(generateReadJson())
|
const query = sql._query(generateReadJson())
|
||||||
expect(query).toEqual(`select * from "${TABLE_NAME}" limit ${limit}`)
|
expect(query).toEqual({
|
||||||
|
bindings: [limit],
|
||||||
|
sql: `select * from "${TABLE_NAME}" limit $1`
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should test a read with specific columns", () => {
|
it("should test a read with specific columns", () => {
|
||||||
const query = sql.query(generateReadJson({
|
const query = sql._query(generateReadJson({
|
||||||
fields: ["name", "age"]
|
fields: ["name", "age"]
|
||||||
}))
|
}))
|
||||||
expect(query).toEqual(`select "name", "age" from "${TABLE_NAME}" limit ${limit}`)
|
expect(query).toEqual({
|
||||||
|
bindings: [limit],
|
||||||
|
sql: `select "name", "age" from "${TABLE_NAME}" limit $1`
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should test a where string starts with read", () => {
|
it("should test a where string starts with read", () => {
|
||||||
const query = sql.query(generateReadJson({
|
const query = sql._query(generateReadJson({
|
||||||
filters: {
|
filters: {
|
||||||
string: {
|
string: {
|
||||||
name: "John",
|
name: "John",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
expect(query).toEqual(`select * from "${TABLE_NAME}" where "name" like 'John%' limit ${limit}`)
|
expect(query).toEqual({
|
||||||
|
bindings: ["John%", limit],
|
||||||
|
sql: `select * from "${TABLE_NAME}" where "name" like $1 limit $2`
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should test a where range read", () => {
|
it("should test a where range read", () => {
|
||||||
const query = sql.query(generateReadJson({
|
const query = sql._query(generateReadJson({
|
||||||
filters: {
|
filters: {
|
||||||
range: {
|
range: {
|
||||||
age: {
|
age: {
|
||||||
|
@ -87,44 +96,62 @@ describe("SQL query builder", () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
expect(query).toEqual(`select * from "${TABLE_NAME}" where "age" between 2 and 10 limit ${limit}`)
|
expect(query).toEqual({
|
||||||
|
bindings: [2, 10, limit],
|
||||||
|
sql: `select * from "${TABLE_NAME}" where "age" between $1 and $2 limit $3`
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should test an create statement", () => {
|
it("should test an create statement", () => {
|
||||||
const query = sql.query(generateCreateJson(TABLE_NAME, {
|
const query = sql._query(generateCreateJson(TABLE_NAME, {
|
||||||
name: "Michael",
|
name: "Michael",
|
||||||
age: 45,
|
age: 45,
|
||||||
}))
|
}))
|
||||||
expect(query).toEqual(`insert into "${TABLE_NAME}" ("age", "name") values (45, 'Michael')`)
|
expect(query).toEqual({
|
||||||
|
bindings: [45, "Michael"],
|
||||||
|
sql: `insert into "${TABLE_NAME}" ("age", "name") values ($1, $2)`
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should test an update statement", () => {
|
it("should test an update statement", () => {
|
||||||
const query = sql.query(generateUpdateJson(TABLE_NAME, {
|
const query = sql._query(generateUpdateJson(TABLE_NAME, {
|
||||||
name: "John"
|
name: "John"
|
||||||
}, {
|
}, {
|
||||||
equal: {
|
equal: {
|
||||||
id: 1001,
|
id: 1001,
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
expect(query).toEqual(`update "${TABLE_NAME}" set "name" = 'John' where "id" = 1001`)
|
expect(query).toEqual({
|
||||||
|
bindings: ["John", 1001],
|
||||||
|
sql: `update "${TABLE_NAME}" set "name" = $1 where "id" = $2`
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should test a delete statement", () => {
|
it("should test a delete statement", () => {
|
||||||
const query = sql.query(generateDeleteJson(TABLE_NAME, {
|
const query = sql._query(generateDeleteJson(TABLE_NAME, {
|
||||||
equal: {
|
equal: {
|
||||||
id: 1001,
|
id: 1001,
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
expect(query).toEqual(`delete from "${TABLE_NAME}" where "id" = 1001`)
|
expect(query).toEqual({
|
||||||
|
bindings: [1001],
|
||||||
|
sql: `delete from "${TABLE_NAME}" where "id" = $1`
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should work with MS-SQL", () => {
|
it("should work with MS-SQL", () => {
|
||||||
const query = new Sql("mssql", 10).query(generateReadJson())
|
const query = new Sql("mssql", 10)._query(generateReadJson())
|
||||||
expect(query).toEqual(`select top (10) * from [${TABLE_NAME}]`)
|
expect(query).toEqual({
|
||||||
|
bindings: [10],
|
||||||
|
sql: `select top (@p0) * from [${TABLE_NAME}]`
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should work with mySQL", () => {
|
it("should work with mySQL", () => {
|
||||||
const query = new Sql("mysql", 10).query(generateReadJson())
|
const query = new Sql("mysql", 10)._query(generateReadJson())
|
||||||
expect(query).toEqual(`select * from \`${TABLE_NAME}\` limit 10`)
|
expect(query).toEqual({
|
||||||
|
bindings: [10],
|
||||||
|
sql: `select * from \`${TABLE_NAME}\` limit ?`
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue