Browse Source

fix: validate pk value before query execution (#8640)

pull/8645/head
Pranav C 7 months ago committed by GitHub
parent
commit
2759f1982a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      packages/nocodb-sdk/src/lib/globals.ts
  2. 23
      packages/nocodb/src/db/BaseModelSqlv2.ts
  3. 12
      packages/nocodb/src/helpers/catchError.ts

1
packages/nocodb-sdk/src/lib/globals.ts

@ -146,6 +146,7 @@ export enum NcErrorType {
DATABASE_ERROR = 'DATABASE_ERROR',
UNKNOWN_ERROR = 'UNKNOWN_ERROR',
BAD_JSON = 'BAD_JSON',
INVALID_PK_VALUE = 'INVALID_PK_VALUE',
}
type Roles = OrgUserRoles | ProjectRoles | WorkspaceUserRoles;

23
packages/nocodb/src/db/BaseModelSqlv2.ts

@ -3007,9 +3007,9 @@ class BaseModelSqlv2 {
}
}
async _wherePk(id, skipGetColumns = false) {
async _wherePk(id, skipGetColumns = false, skipPkValidation = false) {
if (!skipGetColumns) await this.model.getColumns();
return _wherePk(this.model.primaryKeys, id);
return _wherePk(this.model.primaryKeys, id, skipPkValidation);
}
comparePks(pk1, pk2) {
@ -6894,24 +6894,35 @@ function applyPaginate(
return query;
}
export function _wherePk(primaryKeys: Column[], id: unknown | unknown[]) {
export function _wherePk(
primaryKeys: Column[],
id: unknown | unknown[],
skipPkValidation = false,
) {
const where = {};
// if id object is provided use as it is
if (id && typeof id === 'object' && !Array.isArray(id)) {
// verify all pk columns are present in id object
for (const pk of primaryKeys) {
let key: string;
if (pk.id in id) {
where[pk.column_name] = id[pk.id];
key = pk.id;
} else if (pk.title in id) {
where[pk.column_name] = id[pk.title];
key = pk.title;
} else if (pk.column_name in id) {
where[pk.column_name] = id[pk.column_name];
key = pk.column_name;
} else {
NcError.badRequest(
`Primary key column ${pk.title} not found in id object`,
);
}
where[pk.column_name] = id[key];
// validate value if auto-increment column
// todo: add more validation based on column constraints
if (!skipPkValidation && pk.ai && !/^\d+$/.test(id[key])) {
NcError.invalidPrimaryKey(id[key], pk.title);
}
}
return where;

12
packages/nocodb/src/helpers/catchError.ts

@ -520,6 +520,11 @@ const errorHelpers: {
message: (offset: string) => `Offset value '${offset}' is invalid`,
code: 422,
},
[NcErrorType.INVALID_PK_VALUE]: {
message: (value: any, pkColumn: string) =>
`Primary key value '${value}' is invalid for column '${pkColumn}'`,
code: 422,
},
[NcErrorType.INVALID_LIMIT_VALUE]: {
message: `Limit value should be between ${defaultLimitConfig.limitMin} and ${defaultLimitConfig.limitMax}`,
code: 422,
@ -681,6 +686,13 @@ export class NcError {
});
}
static invalidPrimaryKey(value: any, pkColumn: string, args?: NcErrorArgs) {
throw new NcBaseErrorv2(NcErrorType.INVALID_PK_VALUE, {
params: [value, pkColumn],
...args,
});
}
static invalidLimitValue(args?: NcErrorArgs) {
throw new NcBaseErrorv2(NcErrorType.INVALID_LIMIT_VALUE, {
...args,

Loading…
Cancel
Save